From 81fc0fe6b76aa8de4bb9026b8b238e0717144fa6 Mon Sep 17 00:00:00 2001
From: Miller Puckette <msp@ucsd.edu>
Date: Fri, 3 Aug 2007 08:39:03 -0700
Subject: [PATCH] oops, see next

---
 portaudio/LICENSE.txt                         |   65 -
 portaudio/README.txt                          |   81 -
 portaudio/V19-devel-readme.txt                |  222 -
 portaudio/pa_asio/ASIO-README.txt             |  137 -
 portaudio/pa_asio/CVS/Entries                 |    8 -
 portaudio/pa_asio/CVS/Repository              |    1 -
 portaudio/pa_asio/CVS/Root                    |    1 -
 portaudio/pa_asio/CVS/Tag                     |    1 -
 portaudio/pa_asio/Callback_adaptation_.pdf    |  Bin 50527 -> 0 bytes
 portaudio/pa_asio/Pa_ASIO.pdf                 |  Bin 50778 -> 0 bytes
 portaudio/pa_asio/iasiothiscallresolver.cpp   |  563 ---
 portaudio/pa_asio/iasiothiscallresolver.h     |  197 -
 portaudio/pa_asio/pa_asio.cpp                 | 2958 -------------
 portaudio/pa_asio/pa_asio.h                   |  122 -
 portaudio/pa_common/CVS/Entries               |   22 -
 portaudio/pa_common/CVS/Repository            |    1 -
 portaudio/pa_common/CVS/Root                  |    1 -
 portaudio/pa_common/CVS/Tag                   |    1 -
 portaudio/pa_common/pa_allocation.c           |  234 --
 portaudio/pa_common/pa_allocation.h           |   95 -
 portaudio/pa_common/pa_converters.c           | 1926 ---------
 portaudio/pa_common/pa_converters.h           |  254 --
 portaudio/pa_common/pa_cpuload.c              |   96 -
 portaudio/pa_common/pa_cpuload.h              |   63 -
 portaudio/pa_common/pa_dither.c               |  204 -
 portaudio/pa_common/pa_dither.h               |   91 -
 portaudio/pa_common/pa_endianness.h           |  113 -
 portaudio/pa_common/pa_front.c                | 1981 ---------
 portaudio/pa_common/pa_hostapi.h              |  244 --
 portaudio/pa_common/pa_process.c              | 1763 --------
 portaudio/pa_common/pa_process.h              |  741 ----
 portaudio/pa_common/pa_skeleton.c             |  807 ----
 portaudio/pa_common/pa_stream.c               |  141 -
 portaudio/pa_common/pa_stream.h               |  196 -
 portaudio/pa_common/pa_trace.c                |   88 -
 portaudio/pa_common/pa_trace.h                |   70 -
 portaudio/pa_common/pa_types.h                |   65 -
 portaudio/pa_common/pa_util.h                 |  167 -
 portaudio/pa_common/portaudio.h               | 1124 -----
 portaudio/pa_dll_switch/CVS/Entries           |    6 -
 portaudio/pa_dll_switch/CVS/Repository        |    1 -
 portaudio/pa_dll_switch/CVS/Root              |    1 -
 portaudio/pa_dll_switch/CVS/Tag               |    1 -
 portaudio/pa_dll_switch/PaDllEntry.h          |  184 -
 .../pa_dll_switch/letter_from_tim_010817.txt  |  Bin 1176 -> 0 bytes
 portaudio/pa_dll_switch/loadPA_DLL.cpp        |  203 -
 portaudio/pa_dll_switch/pa_lib.c              |  827 ----
 portaudio/pa_dll_switch/portaudio.h           |  439 --
 portaudio/pa_jack/CVS/Entries                 |    2 -
 portaudio/pa_jack/CVS/Repository              |    1 -
 portaudio/pa_jack/CVS/Root                    |    1 -
 portaudio/pa_jack/CVS/Tag                     |    1 -
 portaudio/pa_jack/pa_jack.c                   | 1714 --------
 portaudio/pa_linux_alsa/CVS/Entries           |    3 -
 portaudio/pa_linux_alsa/CVS/Repository        |    1 -
 portaudio/pa_linux_alsa/CVS/Root              |    1 -
 portaudio/pa_linux_alsa/CVS/Tag               |    1 -
 portaudio/pa_linux_alsa/pa_linux_alsa.c       | 3682 -----------------
 portaudio/pa_linux_alsa/pa_linux_alsa.h       |   64 -
 portaudio/pa_mac/CVS/Entries                  |    2 -
 portaudio/pa_mac/CVS/Repository               |    1 -
 portaudio/pa_mac/CVS/Root                     |    1 -
 portaudio/pa_mac/CVS/Tag                      |    1 -
 portaudio/pa_mac/pa_mac_hostapis.c            |   79 -
 portaudio/pa_mac_core/CVS/Entries             |    6 -
 portaudio/pa_mac_core/CVS/Repository          |    1 -
 portaudio/pa_mac_core/CVS/Root                |    1 -
 portaudio/pa_mac_core/CVS/Tag                 |    1 -
 portaudio/pa_mac_core/notes.txt               |  145 -
 portaudio/pa_mac_core/pa_mac_core.c           | 2105 ----------
 portaudio/pa_mac_core/pa_mac_core.h           |   69 -
 portaudio/pa_mac_core/pa_mac_core_old.c       |  907 ----
 portaudio/pa_mac_core/pa_mac_core_utilities.c |  466 ---
 portaudio/pa_unix/CVS/Entries                 |    4 -
 portaudio/pa_unix/CVS/Repository              |    1 -
 portaudio/pa_unix/CVS/Root                    |    1 -
 portaudio/pa_unix/CVS/Tag                     |    1 -
 portaudio/pa_unix/pa_unix_hostapis.c          |   64 -
 portaudio/pa_unix/pa_unix_util.c              |  192 -
 portaudio/pa_unix/pa_unix_util.h              |   73 -
 portaudio/pa_unix_oss/CVS/Entries             |    4 -
 portaudio/pa_unix_oss/CVS/Repository          |    1 -
 portaudio/pa_unix_oss/CVS/Root                |    1 -
 portaudio/pa_unix_oss/CVS/Tag                 |    1 -
 portaudio/pa_unix_oss/low_latency_tip.txt     |  Bin 3111 -> 0 bytes
 portaudio/pa_unix_oss/pa_unix_oss.c           | 1924 ---------
 portaudio/pa_unix_oss/recplay.c               |  114 -
 portaudio/pa_win/CVS/Entries                  |    5 -
 portaudio/pa_win/CVS/Entries.Log              |    2 -
 portaudio/pa_win/CVS/Repository               |    1 -
 portaudio/pa_win/CVS/Root                     |    1 -
 portaudio/pa_win/CVS/Tag                      |    1 -
 portaudio/pa_win/dev-cpp/CVS/Entries          |    6 -
 portaudio/pa_win/dev-cpp/CVS/Repository       |    1 -
 portaudio/pa_win/dev-cpp/CVS/Root             |    1 -
 portaudio/pa_win/dev-cpp/CVS/Tag              |    1 -
 portaudio/pa_win/dev-cpp/Makefile-dll         |   78 -
 portaudio/pa_win/dev-cpp/Makefile-static      |   75 -
 portaudio/pa_win/dev-cpp/portaudio-dll.dev    |  209 -
 portaudio/pa_win/dev-cpp/portaudio-static.dev |  209 -
 portaudio/pa_win/dev-cpp/readme.txt           |   23 -
 portaudio/pa_win/msvc/CVS/Entries             |    7 -
 portaudio/pa_win/msvc/CVS/Repository          |    1 -
 portaudio/pa_win/msvc/CVS/Root                |    1 -
 portaudio/pa_win/msvc/CVS/Tag                 |    1 -
 portaudio/pa_win/msvc/Makefile.msvc           |  159 -
 portaudio/pa_win/msvc/clean.bat               |    7 -
 portaudio/pa_win/msvc/make.bat                |    8 -
 portaudio/pa_win/msvc/portaudio.def           |   43 -
 portaudio/pa_win/msvc/readme.txt              |   56 -
 portaudio/pa_win/msvc/setenv.bat              |    1 -
 portaudio/pa_win/pa_win_hostapis.c            |   86 -
 portaudio/pa_win/pa_win_util.c                |  134 -
 portaudio/pa_win/pa_x86_plain_converters.c    | 1167 ------
 portaudio/pa_win/pa_x86_plain_converters.h    |   19 -
 portaudio/pa_win_ds/CVS/Entries               |    4 -
 portaudio/pa_win_ds/CVS/Repository            |    1 -
 portaudio/pa_win_ds/CVS/Root                  |    1 -
 portaudio/pa_win_ds/CVS/Tag                   |    1 -
 portaudio/pa_win_ds/dsound_wrapper.c          |  616 ---
 portaudio/pa_win_ds/dsound_wrapper.h          |  130 -
 portaudio/pa_win_ds/pa_win_ds.c               | 1864 ---------
 portaudio/pa_win_wdmks/CVS/Entries            |    3 -
 portaudio/pa_win_wdmks/CVS/Repository         |    1 -
 portaudio/pa_win_wdmks/CVS/Root               |    1 -
 portaudio/pa_win_wdmks/CVS/Tag                |    1 -
 portaudio/pa_win_wdmks/pa_win_wdmks.c         | 3269 ---------------
 portaudio/pa_win_wdmks/readme.txt             |   82 -
 portaudio/pa_win_wmme/CVS/Entries             |    3 -
 portaudio/pa_win_wmme/CVS/Repository          |    1 -
 portaudio/pa_win_wmme/CVS/Root                |    1 -
 portaudio/pa_win_wmme/CVS/Tag                 |    1 -
 portaudio/pa_win_wmme/pa_win_wmme.c           | 3634 ----------------
 portaudio/pa_win_wmme/pa_win_wmme.h           |  160 -
 portaudio/pablio/CVS/Entries                  |   11 -
 portaudio/pablio/CVS/Repository               |    1 -
 portaudio/pablio/CVS/Root                     |    1 -
 portaudio/pablio/CVS/Tag                      |    1 -
 portaudio/pablio/README.txt                   |   39 -
 portaudio/pablio/pablio.c                     |  307 --
 portaudio/pablio/pablio.def                   |   35 -
 portaudio/pablio/pablio.h                     |  109 -
 portaudio/pablio/ringbuffer.c                 |  199 -
 portaudio/pablio/ringbuffer.h                 |  101 -
 portaudio/pablio/test_rw.c                    |   99 -
 portaudio/pablio/test_rw_echo.c               |  123 -
 portaudio/pablio/test_w_saw.c                 |  108 -
 portaudio/pablio/test_w_saw8.c                |  106 -
 portmidi/Makefile                             |   77 -
 portmidi/README.txt                           |   62 -
 portmidi/pm_common/pminternal.h               |  173 -
 portmidi/pm_common/pmutil.c                   |  132 -
 portmidi/pm_common/pmutil.h                   |   56 -
 portmidi/pm_common/portmidi.c                 |  980 -----
 portmidi/pm_common/portmidi.h                 |  692 ----
 portmidi/pm_linux/README_LINUX.txt            |   32 -
 portmidi/pm_linux/pmlinux.c                   |   51 -
 portmidi/pm_linux/pmlinux.h                   |    5 -
 portmidi/pm_linux/pmlinuxalsa.c               |  724 ----
 portmidi/pm_linux/pmlinuxalsa.h               |    6 -
 portmidi/pm_mac/pmmac.c                       |   42 -
 portmidi/pm_mac/pmmac.h                       |    4 -
 portmidi/pm_mac/pmmacosxcm.c                  |  709 ----
 portmidi/pm_mac/pmmacosxcm.h                  |    4 -
 portmidi/pm_test/latency.c                    |  278 --
 portmidi/pm_test/latency.dsp                  |  102 -
 portmidi/pm_test/midithread.c                 |  327 --
 portmidi/pm_test/midithread.dsp               |  102 -
 portmidi/pm_test/midithru.c                   |  364 --
 portmidi/pm_test/midithru.dsp                 |  102 -
 portmidi/pm_test/midithru.dsw                 |   29 -
 portmidi/pm_test/sysex.c                      |  319 --
 portmidi/pm_test/sysex.dsp                    |  102 -
 portmidi/pm_test/test.c                       |  469 ---
 portmidi/pm_test/test.dsp                     |  102 -
 portmidi/pm_test/txdata.syx                   |  257 --
 portmidi/pm_win/README_WIN.txt                |  183 -
 portmidi/pm_win/copy-dll.bat                  |   13 -
 portmidi/pm_win/debugging_dlls.txt            |  145 -
 portmidi/pm_win/pm_dll.dsp                    |  107 -
 portmidi/pm_win/pmdll.c                       |   49 -
 portmidi/pm_win/pmdll.h                       |    5 -
 portmidi/pm_win/pmwin.c                       |  113 -
 portmidi/pm_win/pmwinmm.c                     | 1547 -------
 portmidi/pm_win/pmwinmm.h                     |    5 -
 portmidi/portmidi.dsp                         |  124 -
 portmidi/portmidi.dsw                         |  158 -
 portmidi/porttime/porttime.c                  |    3 -
 portmidi/porttime/porttime.dsp                |  104 -
 portmidi/porttime/porttime.h                  |   36 -
 portmidi/porttime/ptlinux.c                   |  120 -
 portmidi/porttime/ptmacosx_cf.c               |  132 -
 portmidi/porttime/ptmacosx_mach.c             |  123 -
 portmidi/porttime/ptwinmm.c                   |   65 -
 src/s_midi_sgi.c                              |  203 -
 195 files changed, 50997 deletions(-)
 delete mode 100644 portaudio/LICENSE.txt
 delete mode 100644 portaudio/README.txt
 delete mode 100644 portaudio/V19-devel-readme.txt
 delete mode 100644 portaudio/pa_asio/ASIO-README.txt
 delete mode 100644 portaudio/pa_asio/CVS/Entries
 delete mode 100644 portaudio/pa_asio/CVS/Repository
 delete mode 100644 portaudio/pa_asio/CVS/Root
 delete mode 100644 portaudio/pa_asio/CVS/Tag
 delete mode 100644 portaudio/pa_asio/Callback_adaptation_.pdf
 delete mode 100644 portaudio/pa_asio/Pa_ASIO.pdf
 delete mode 100644 portaudio/pa_asio/iasiothiscallresolver.cpp
 delete mode 100644 portaudio/pa_asio/iasiothiscallresolver.h
 delete mode 100644 portaudio/pa_asio/pa_asio.cpp
 delete mode 100644 portaudio/pa_asio/pa_asio.h
 delete mode 100644 portaudio/pa_common/CVS/Entries
 delete mode 100644 portaudio/pa_common/CVS/Repository
 delete mode 100644 portaudio/pa_common/CVS/Root
 delete mode 100644 portaudio/pa_common/CVS/Tag
 delete mode 100644 portaudio/pa_common/pa_allocation.c
 delete mode 100644 portaudio/pa_common/pa_allocation.h
 delete mode 100644 portaudio/pa_common/pa_converters.c
 delete mode 100644 portaudio/pa_common/pa_converters.h
 delete mode 100644 portaudio/pa_common/pa_cpuload.c
 delete mode 100644 portaudio/pa_common/pa_cpuload.h
 delete mode 100644 portaudio/pa_common/pa_dither.c
 delete mode 100644 portaudio/pa_common/pa_dither.h
 delete mode 100644 portaudio/pa_common/pa_endianness.h
 delete mode 100644 portaudio/pa_common/pa_front.c
 delete mode 100644 portaudio/pa_common/pa_hostapi.h
 delete mode 100644 portaudio/pa_common/pa_process.c
 delete mode 100644 portaudio/pa_common/pa_process.h
 delete mode 100644 portaudio/pa_common/pa_skeleton.c
 delete mode 100644 portaudio/pa_common/pa_stream.c
 delete mode 100644 portaudio/pa_common/pa_stream.h
 delete mode 100644 portaudio/pa_common/pa_trace.c
 delete mode 100644 portaudio/pa_common/pa_trace.h
 delete mode 100644 portaudio/pa_common/pa_types.h
 delete mode 100644 portaudio/pa_common/pa_util.h
 delete mode 100644 portaudio/pa_common/portaudio.h
 delete mode 100644 portaudio/pa_dll_switch/CVS/Entries
 delete mode 100644 portaudio/pa_dll_switch/CVS/Repository
 delete mode 100644 portaudio/pa_dll_switch/CVS/Root
 delete mode 100644 portaudio/pa_dll_switch/CVS/Tag
 delete mode 100644 portaudio/pa_dll_switch/PaDllEntry.h
 delete mode 100644 portaudio/pa_dll_switch/letter_from_tim_010817.txt
 delete mode 100644 portaudio/pa_dll_switch/loadPA_DLL.cpp
 delete mode 100644 portaudio/pa_dll_switch/pa_lib.c
 delete mode 100644 portaudio/pa_dll_switch/portaudio.h
 delete mode 100644 portaudio/pa_jack/CVS/Entries
 delete mode 100644 portaudio/pa_jack/CVS/Repository
 delete mode 100644 portaudio/pa_jack/CVS/Root
 delete mode 100644 portaudio/pa_jack/CVS/Tag
 delete mode 100644 portaudio/pa_jack/pa_jack.c
 delete mode 100644 portaudio/pa_linux_alsa/CVS/Entries
 delete mode 100644 portaudio/pa_linux_alsa/CVS/Repository
 delete mode 100644 portaudio/pa_linux_alsa/CVS/Root
 delete mode 100644 portaudio/pa_linux_alsa/CVS/Tag
 delete mode 100644 portaudio/pa_linux_alsa/pa_linux_alsa.c
 delete mode 100644 portaudio/pa_linux_alsa/pa_linux_alsa.h
 delete mode 100644 portaudio/pa_mac/CVS/Entries
 delete mode 100644 portaudio/pa_mac/CVS/Repository
 delete mode 100644 portaudio/pa_mac/CVS/Root
 delete mode 100644 portaudio/pa_mac/CVS/Tag
 delete mode 100644 portaudio/pa_mac/pa_mac_hostapis.c
 delete mode 100644 portaudio/pa_mac_core/CVS/Entries
 delete mode 100644 portaudio/pa_mac_core/CVS/Repository
 delete mode 100644 portaudio/pa_mac_core/CVS/Root
 delete mode 100644 portaudio/pa_mac_core/CVS/Tag
 delete mode 100644 portaudio/pa_mac_core/notes.txt
 delete mode 100644 portaudio/pa_mac_core/pa_mac_core.c
 delete mode 100644 portaudio/pa_mac_core/pa_mac_core.h
 delete mode 100644 portaudio/pa_mac_core/pa_mac_core_old.c
 delete mode 100644 portaudio/pa_mac_core/pa_mac_core_utilities.c
 delete mode 100644 portaudio/pa_unix/CVS/Entries
 delete mode 100644 portaudio/pa_unix/CVS/Repository
 delete mode 100644 portaudio/pa_unix/CVS/Root
 delete mode 100644 portaudio/pa_unix/CVS/Tag
 delete mode 100644 portaudio/pa_unix/pa_unix_hostapis.c
 delete mode 100644 portaudio/pa_unix/pa_unix_util.c
 delete mode 100644 portaudio/pa_unix/pa_unix_util.h
 delete mode 100644 portaudio/pa_unix_oss/CVS/Entries
 delete mode 100644 portaudio/pa_unix_oss/CVS/Repository
 delete mode 100644 portaudio/pa_unix_oss/CVS/Root
 delete mode 100644 portaudio/pa_unix_oss/CVS/Tag
 delete mode 100644 portaudio/pa_unix_oss/low_latency_tip.txt
 delete mode 100644 portaudio/pa_unix_oss/pa_unix_oss.c
 delete mode 100644 portaudio/pa_unix_oss/recplay.c
 delete mode 100644 portaudio/pa_win/CVS/Entries
 delete mode 100644 portaudio/pa_win/CVS/Entries.Log
 delete mode 100644 portaudio/pa_win/CVS/Repository
 delete mode 100644 portaudio/pa_win/CVS/Root
 delete mode 100644 portaudio/pa_win/CVS/Tag
 delete mode 100644 portaudio/pa_win/dev-cpp/CVS/Entries
 delete mode 100644 portaudio/pa_win/dev-cpp/CVS/Repository
 delete mode 100644 portaudio/pa_win/dev-cpp/CVS/Root
 delete mode 100644 portaudio/pa_win/dev-cpp/CVS/Tag
 delete mode 100644 portaudio/pa_win/dev-cpp/Makefile-dll
 delete mode 100644 portaudio/pa_win/dev-cpp/Makefile-static
 delete mode 100644 portaudio/pa_win/dev-cpp/portaudio-dll.dev
 delete mode 100644 portaudio/pa_win/dev-cpp/portaudio-static.dev
 delete mode 100644 portaudio/pa_win/dev-cpp/readme.txt
 delete mode 100644 portaudio/pa_win/msvc/CVS/Entries
 delete mode 100644 portaudio/pa_win/msvc/CVS/Repository
 delete mode 100644 portaudio/pa_win/msvc/CVS/Root
 delete mode 100644 portaudio/pa_win/msvc/CVS/Tag
 delete mode 100644 portaudio/pa_win/msvc/Makefile.msvc
 delete mode 100755 portaudio/pa_win/msvc/clean.bat
 delete mode 100755 portaudio/pa_win/msvc/make.bat
 delete mode 100644 portaudio/pa_win/msvc/portaudio.def
 delete mode 100644 portaudio/pa_win/msvc/readme.txt
 delete mode 100755 portaudio/pa_win/msvc/setenv.bat
 delete mode 100644 portaudio/pa_win/pa_win_hostapis.c
 delete mode 100644 portaudio/pa_win/pa_win_util.c
 delete mode 100644 portaudio/pa_win/pa_x86_plain_converters.c
 delete mode 100644 portaudio/pa_win/pa_x86_plain_converters.h
 delete mode 100644 portaudio/pa_win_ds/CVS/Entries
 delete mode 100644 portaudio/pa_win_ds/CVS/Repository
 delete mode 100644 portaudio/pa_win_ds/CVS/Root
 delete mode 100644 portaudio/pa_win_ds/CVS/Tag
 delete mode 100644 portaudio/pa_win_ds/dsound_wrapper.c
 delete mode 100644 portaudio/pa_win_ds/dsound_wrapper.h
 delete mode 100644 portaudio/pa_win_ds/pa_win_ds.c
 delete mode 100644 portaudio/pa_win_wdmks/CVS/Entries
 delete mode 100644 portaudio/pa_win_wdmks/CVS/Repository
 delete mode 100644 portaudio/pa_win_wdmks/CVS/Root
 delete mode 100644 portaudio/pa_win_wdmks/CVS/Tag
 delete mode 100644 portaudio/pa_win_wdmks/pa_win_wdmks.c
 delete mode 100644 portaudio/pa_win_wdmks/readme.txt
 delete mode 100644 portaudio/pa_win_wmme/CVS/Entries
 delete mode 100644 portaudio/pa_win_wmme/CVS/Repository
 delete mode 100644 portaudio/pa_win_wmme/CVS/Root
 delete mode 100644 portaudio/pa_win_wmme/CVS/Tag
 delete mode 100644 portaudio/pa_win_wmme/pa_win_wmme.c
 delete mode 100644 portaudio/pa_win_wmme/pa_win_wmme.h
 delete mode 100644 portaudio/pablio/CVS/Entries
 delete mode 100644 portaudio/pablio/CVS/Repository
 delete mode 100644 portaudio/pablio/CVS/Root
 delete mode 100644 portaudio/pablio/CVS/Tag
 delete mode 100644 portaudio/pablio/README.txt
 delete mode 100644 portaudio/pablio/pablio.c
 delete mode 100644 portaudio/pablio/pablio.def
 delete mode 100644 portaudio/pablio/pablio.h
 delete mode 100644 portaudio/pablio/ringbuffer.c
 delete mode 100644 portaudio/pablio/ringbuffer.h
 delete mode 100644 portaudio/pablio/test_rw.c
 delete mode 100644 portaudio/pablio/test_rw_echo.c
 delete mode 100644 portaudio/pablio/test_w_saw.c
 delete mode 100644 portaudio/pablio/test_w_saw8.c
 delete mode 100644 portmidi/Makefile
 delete mode 100644 portmidi/README.txt
 delete mode 100644 portmidi/pm_common/pminternal.h
 delete mode 100644 portmidi/pm_common/pmutil.c
 delete mode 100644 portmidi/pm_common/pmutil.h
 delete mode 100644 portmidi/pm_common/portmidi.c
 delete mode 100644 portmidi/pm_common/portmidi.h
 delete mode 100644 portmidi/pm_linux/README_LINUX.txt
 delete mode 100644 portmidi/pm_linux/pmlinux.c
 delete mode 100644 portmidi/pm_linux/pmlinux.h
 delete mode 100644 portmidi/pm_linux/pmlinuxalsa.c
 delete mode 100644 portmidi/pm_linux/pmlinuxalsa.h
 delete mode 100644 portmidi/pm_mac/pmmac.c
 delete mode 100644 portmidi/pm_mac/pmmac.h
 delete mode 100644 portmidi/pm_mac/pmmacosxcm.c
 delete mode 100644 portmidi/pm_mac/pmmacosxcm.h
 delete mode 100644 portmidi/pm_test/latency.c
 delete mode 100644 portmidi/pm_test/latency.dsp
 delete mode 100644 portmidi/pm_test/midithread.c
 delete mode 100644 portmidi/pm_test/midithread.dsp
 delete mode 100644 portmidi/pm_test/midithru.c
 delete mode 100644 portmidi/pm_test/midithru.dsp
 delete mode 100644 portmidi/pm_test/midithru.dsw
 delete mode 100644 portmidi/pm_test/sysex.c
 delete mode 100644 portmidi/pm_test/sysex.dsp
 delete mode 100644 portmidi/pm_test/test.c
 delete mode 100644 portmidi/pm_test/test.dsp
 delete mode 100644 portmidi/pm_test/txdata.syx
 delete mode 100644 portmidi/pm_win/README_WIN.txt
 delete mode 100644 portmidi/pm_win/copy-dll.bat
 delete mode 100644 portmidi/pm_win/debugging_dlls.txt
 delete mode 100644 portmidi/pm_win/pm_dll.dsp
 delete mode 100644 portmidi/pm_win/pmdll.c
 delete mode 100644 portmidi/pm_win/pmdll.h
 delete mode 100644 portmidi/pm_win/pmwin.c
 delete mode 100644 portmidi/pm_win/pmwinmm.c
 delete mode 100644 portmidi/pm_win/pmwinmm.h
 delete mode 100644 portmidi/portmidi.dsp
 delete mode 100644 portmidi/portmidi.dsw
 delete mode 100644 portmidi/porttime/porttime.c
 delete mode 100644 portmidi/porttime/porttime.dsp
 delete mode 100644 portmidi/porttime/porttime.h
 delete mode 100644 portmidi/porttime/ptlinux.c
 delete mode 100644 portmidi/porttime/ptmacosx_cf.c
 delete mode 100644 portmidi/porttime/ptmacosx_mach.c
 delete mode 100644 portmidi/porttime/ptwinmm.c
 delete mode 100644 src/s_midi_sgi.c

diff --git a/portaudio/LICENSE.txt b/portaudio/LICENSE.txt
deleted file mode 100644
index 105da3f75..000000000
--- a/portaudio/LICENSE.txt
+++ /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/portaudio/README.txt b/portaudio/README.txt
deleted file mode 100644
index 4cfc6166e..000000000
--- a/portaudio/README.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-README for PortAudio
-Implementations for PC DirectSound and Mac SoundManager
-
-/*
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com//
- *
- * Copyright (c) 1999-2000 Phil Burk and Ross Bencina
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-PortAudio is a portable audio I/O library designed for cross-platform
-support of audio. It uses a callback mechanism to request audio processing.
-Audio can be generated in various formats, including 32 bit floating point,
-and will be converted to the native format internally.
-
-Documentation:
-	See "pa_common/portaudio.h" for API spec.
-	See docs folder for a tutorial.
-	Also see http://www.portaudio.com/docs/
-	And see "pa_tests/patest_saw.c" for an example.
-
-For information on compiling programs with PortAudio, please see the
-tutorial at:
-
-  http://www.portaudio.com/docs/pa_tutorial.html
-  
-Important Files and Folders:
-	pa_common/              = platform independant code
-	pa_common/portaudio.h   = header file for PortAudio API. Specifies API.
-	pa_common/pa_lib.c      = host independant code for all implementations.
-
-    pablio                  = simple blocking read/write interface
-    
-Platform Implementations
-    pa_asio                 = ASIO for Windows and Macintosh
-    pa_beos                 = BeOS
-    pa_mac_sm               = Macintosh Sound Manager for OS 8,9 and Carbon
-    pa_mac_core             = Macintosh Core Audio for OS X
-    pa_sgi                  = Silicon Graphics AL
-    pa_unix_oss             = OSS implementation for various Unixes
-    pa_win_ds               = Windows Direct Sound
-    pa_win_wmme             = Windows MME (most widely supported)
-    
-Test Programs
-	pa_tests/pa_fuzz.c = guitar fuzz box
-	pa_tests/pa_devs.c = print a list of available devices
-	pa_tests/pa_minlat.c = determine minimum latency for your machine
-	pa_tests/paqa_devs.c = self test that opens all devices
-	pa_tests/paqa_errs.c = test error detection and reporting
-	pa_tests/patest_clip.c = hear a sine wave clipped and unclipped
-	pa_tests/patest_dither.c = hear effects of dithering (extremely subtle)
-	pa_tests/patest_pink.c = fun with pink noise
-	pa_tests/patest_record.c = record and playback some audio
-	pa_tests/patest_maxsines.c = how many sine waves can we play? Tests Pa_GetCPULoad().
-	pa_tests/patest_sine.c = output a sine wave in a simple PA app
-	pa_tests/patest_sync.c = test syncronization of audio and video
-	pa_tests/patest_wire.c = pass input to output, wire simulator
diff --git a/portaudio/V19-devel-readme.txt b/portaudio/V19-devel-readme.txt
deleted file mode 100644
index ae5570eb6..000000000
--- a/portaudio/V19-devel-readme.txt
+++ /dev/null
@@ -1,222 +0,0 @@
-STATUS:
-
-MME, DirectSound and ASIO versions are more-or-less working. See FIXMEs @todos
-and the proposals matrix at portaudio.com for further status.
-
-The pa_tests directory contains tests. pa_tests/README.txt notes which tests
-currently build.  
-
-The PaUtil support code is finished enough for other implementations to be
-ported. No changes are expected to be made to the definition of the PaUtil
-functions.
-
-Note that it's not yet 100% clear how the current support functions
-will interact with blocking read/write streams.
-
-BUILD INSTRUCTIONS
-
-to build tests/patest_sine.c you will need to compile and link the following
-files (MME)
-pa_common\pa_process.c
-pa_common\pa_skeleton.c
-pa_common\pa_stream.c
-pa_common\pa_trace.c
-pa_common\pa_converters.c
-pa_common\pa_cpuload.c
-pa_common\pa_dither.c
-pa_common\pa_front.c
-pa_common\pa_allocation.h
-pa_win\pa_win_util.c
-pa_win\pa_win_hostapis.c
-pa_win_wmme\pa_win_wmme.c
-
-see below for a description of these files.
-               
-
-FILES:
-
-portaudio.h
-    public api header file
-
-pa_front.c
-    implements the interface defined in portaudio.h. manages multiple host apis.
-    validates function parameters before calling through to host apis. tracks
-    open streams and closes them at Pa_Terminate().
-
-pa_util.h 
-    declares utility functions for use my implementations. including utility
-    functions which must be implemented separately for each platform.
-
-pa_hostapi.h
-    hostapi representation structure used to interface between pa_front.c
-    and implementations
-    
-pa_stream.c/h
-    stream interface and representation structures and helper functions
-    used to interface between pa_front.c and implementations
-
-pa_cpuload.c/h
-    source and header for cpu load calculation facility
-
-pa_trace.c/h
-    source and header for debug trace log facility
-
-pa_converters.c/h
-    sample buffer conversion facility
-
-pa_dither.c/h
-    dither noise generator
-
-pa_process.c/h
-    callback buffer processing facility including interleave and block adaption
-
-pa_allocation.c/h
-    allocation context for tracking groups of allocations
-
-pa_skeleton.c
-    an skeleton implementation showing how the common code can be used.
-
-pa_win_util.c
-    Win32 implementation of platform specific PaUtil functions (memory allocation,
-    usec clock, Pa_Sleep().)  The file will be used with all Win32 host APIs.
-    
-pa_win_hostapis.c
-    contains the paHostApiInitializers array and an implementation of
-    Pa_GetDefaultHostApi() for win32 builds.
-
-pa_win_wmme.c
-    Win32 host api implementation for the windows multimedia extensions audio API.
-
-pa_win_wmme.h
-    public header file containing interfaces to mme-specific functions and the
-    deviceInfo data structure.
-
-
-CODING GUIDELINES:
-
-naming conventions:
-    #defines begin with PA_
-    #defines local to a file end with _
-    global utility variables begin with paUtil
-    global utility types begin with PaUtil  (including function types)
-    global utility functions begin with PaUtil_
-    static variables end with _
-    static constants begin with const and end with _
-    static funtions have no special prefix/suffix
-
-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 PaWinWmme_Initialize().
-
-Every host api should define an initializer which returns an error code
-and a PaHostApiInterface*. The initializer should only return an error other
-than paNoError if it encounters an unexpected and fatal error (memory allocation
-error for example). In general, there may be conditions under which it returns
-a NULL interface pointer and also returns paNoError. For example, if the ASIO
-implementation detects that ASIO is not installed, it should return a
-NULL interface, and paNoError.
-
-Platform-specific shared functions should begin with Pa<PN>_ where PN is the
-platform name. eg. PaWin_ for windows, PaUnix_ for unix.
-
-The above two conventions should also be followed whenever it is necessary to
-share functions accross multiple source files.
-
-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.
-
-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.
-
-
-TODO:
-    (this list is totally out of date)
-    
-    finish coding converter functions in pa_converters.c (anyone?)
-
-    implement block adaption in pa_process.c (phil?)
-
-    fix all current tests to work with new code. this should mostly involve
-    changing PortAudioStream to PaStream, and GetDefaultDeviceID to GetDefaultDevice etc.
-
-    write some new tests to exercise the multi-api functions
-
-    write (doxygen) documentation for pa_trace (phil?)
-
-    remove unused typeids from PaHostAPITypeID
-
-    create a global configuration file which documents which PA_ defines can be
-    used for configuration
-
-    need a coding standard for comment formatting
-
-    migrate directx (phil)
-
-    migrate asio (ross?, stephane?)
-
-    see top of pa_win_wmme.c for MME todo items (ross)
-
-    write style guide document (ross)
-    
-    
-DESIGN ISSUES:
-    (this list is totally out of date)
-    
-    consider removing Pa_ConvertHostApiDeviceIndexToGlobalDeviceIndex() from the API
-
-    switch to new latency parameter mechanism now (?)
-    
-    question: if input or outputDriverInfo structures are passed for a different
-    hostApi from the one being called, do we return an error or just ignore
-    them? (i think return error)
-
-    consider renaming PortAudioCallback to PaStreamCallback
-
-    consider renaming PaError, PaResult
-    
-
-ASSORTED DISORGANISED NOTES:
-
-    NOTE:
-        pa_lib.c performs the following validations for Pa_OpenStream() which we do not currently do:
-        - checks the device info to make sure that the device supports the requested sample rate,
-            it may also change the sample rate to the "closest available" sample rate if it
-            is within a particular error margin
-
-    rationale for breaking up internalPortAudioStream:
-        each implementation has its own requirements and behavior, and should be
-        able to choose the best way to operate without being limited by the
-        constraints imposed by a common infrastructure. in other words the
-        implementations should be able to pick and choose services from the
-        common infrastructure. currently identified services include:
-
-        - cpu load tracking
-        - buffering and conversion service (same code works for input and output)
-            - should support buffer multiplexing (non-integer length input and output buffers)
-            - in-place conversion where possible (only for callback, read/write always copies)
-            - should manage allocation of temporary buffers if necessary
-        - instrumentation (should be able to be disabled): callback count, framesProcessed
-        - common data: magic, streamInterface, callback, userdata
-
-
-- conversion functions: 
-	- should handle temp buffer allocation
-	- dithering (random number state per-stream)
-	- buffer size mismatches
-	- with new buffer slip rules, temp buffers may always be needed
-	- we should aim for in-place conversion wherever possible
-	- does phil's code support in-place conversion?  (yes)              
-
-- dicuss relationship between user and host buffer sizes
-	- completely independent.. individual implementations may constrain
-    host buffer sizes if necessary
-
-
-- discuss device capabilities:
-	- i'd like to be able to request certain information:
-	- channel count for example
-
diff --git a/portaudio/pa_asio/ASIO-README.txt b/portaudio/pa_asio/ASIO-README.txt
deleted file mode 100644
index 9fb74ae16..000000000
--- a/portaudio/pa_asio/ASIO-README.txt
+++ /dev/null
@@ -1,137 +0,0 @@
-ASIO-README.txt
-
-This document contains information to help you compile PortAudio with 
-ASIO support. If you find any omissions or errors in this document 
-please notify Ross Bencina <rossb@audiomulch.com>.
-
-
-Building PortAudio with ASIO support
-------------------------------------
-
-To build PortAudio with ASIO support you need to compile and link with
-pa_asio.c, and files from the ASIO SDK (see below), along with the common 
-files from pa_common/ and platform specific files from pa_win/ (for Win32) 
-or pa_mac/ (for Macintosh).
-
-If you are compiling with a non-Microsoft compiler on windows, also 
-compile and link with iasiothiscallresolver.cpp (see below for 
-an explanation).
-
-For some platforms (MingW, possibly Mac), you may simply
-be able to type:
-
-./configure --with-host_os=mingw --with-winapi=asio [--with-asiodir=/usr/local/asiosdk2]
-make
-
-./configure --with-host_os=darwin --with-winapi=asio [--with-asiodir=/usr/local/asiosdk2]
-make
-
-and life will be good.
-
-
-Obtaining the ASIO SDK
-----------------------
-
-In order to build PortAudio with ASIO support, you need to download 
-the ASIO SDK (version 2.0) from Steinberg. Steinberg makes the ASIO 
-SDK available to anyone free of charge, however they do not permit its 
-source code to be distributed.
-
-NOTE: In some cases the ASIO SDK may require patching, see below 
-for further details.
-
-http://www.steinberg.net/en/ps/support/3rdparty/asio_sdk/
-
-If the above link is broken search Google for:
-"download steinberg ASIO SDK"
-
-
-
-Building the ASIO SDK on Macintosh
-----------------------------------
-
-To build the ASIO SDK on Macintosh you need to compile and link with the 
-following files from the ASIO SDK:
-
-host/asiodrivers.cpp 
-host/mac/asioshlib.cpp 
-host/mac/codefragements.cpp
-
-
-
-Building the ASIO SDK on Windows
---------------------------------
-
-To build the ASIO SDK on Windows you need to compile and link with the 
-following files from the ASIO SDK:
-
-asio_sdk\common\asio.cpp
-asio_sdk\host\asiodrivers.cpp
-asio_sdk\host\pc\asiolist.cpp
-
-You may also need to adjust your include paths to support inclusion of 
-header files from the above directories.
-
-The ASIO SDK depends on the following COM API functions: 
-CoInitialize, CoUninitialize, CoCreateInstance, CLSIDFromString
-For compilation with MinGW you will need to link with -lole32, for
-Borland link with Import32.lib.
-
-
-
-Non-Microsoft (MSVC) Compilers on Windows including Borland and GCC
--------------------------------------------------------------------
-
-Steinberg did not specify a calling convention in the IASIO interface 
-definition. This causes the Microsoft compiler to use the proprietary 
-thiscall convention which is not compatible with other compilers, such 
-as compilers from Borland (BCC and C++Builder) and GNU (gcc). 
-Steinberg's ASIO SDK will compile but crash on initialization if 
-compiled with a non-Microsoft compiler on Windows.
-
-PortAudio solves this problem using the iasiothiscallresolver library 
-which is included in the distribution. When building ASIO support for
-non-Microsoft compilers, be sure to compile and link with
-iasiothiscallresolver.cpp. Note that iasiothiscallresolver includes
-conditional directives which cause it to have no effect if it is
-compiled with a Microsoft compiler, or on the Macintosh.
-
-If you use configure and make (see above), this should be handled
-automatically for you.
-
-For further information about the IASIO thiscall problem see this page:
-http://www.audiomulch.com/~rossb/code/calliasio
-
-
-
-Macintosh ASIO SDK Bug Patch
-----------------------------
-
-There is a bug in the ASIO SDK that causes the Macintosh version to 
-often fail during initialization. Below 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/portaudio/pa_asio/CVS/Entries b/portaudio/pa_asio/CVS/Entries
deleted file mode 100644
index c89cf4e65..000000000
--- a/portaudio/pa_asio/CVS/Entries
+++ /dev/null
@@ -1,8 +0,0 @@
-/ASIO-README.txt/1.1.2.4/Fri Sep 19 08:46:15 2003//Tv19-devel
-/Callback_adaptation_.pdf/1.1.1.1/Tue Jan 22 00:51:53 2002/-kb/Tv19-devel
-/Pa_ASIO.pdf/1.1.1.1/Tue Jan 22 00:51:56 2002/-kb/Tv19-devel
-/iasiothiscallresolver.cpp/1.1.2.4/Sat Jul 10 03:27:41 2004//Tv19-devel
-/iasiothiscallresolver.h/1.1.2.3/Mon Jul 12 13:35:05 2004//Tv19-devel
-/pa_asio.cpp/1.7.2.68/Mon Dec  5 04:55:28 2005//Tv19-devel
-/pa_asio.h/1.1.2.7/Sat Jan  1 19:35:33 2005//Tv19-devel
-D
diff --git a/portaudio/pa_asio/CVS/Repository b/portaudio/pa_asio/CVS/Repository
deleted file mode 100644
index 7683a07f5..000000000
--- a/portaudio/pa_asio/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_asio
diff --git a/portaudio/pa_asio/CVS/Root b/portaudio/pa_asio/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_asio/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_asio/CVS/Tag b/portaudio/pa_asio/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_asio/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_asio/Callback_adaptation_.pdf b/portaudio/pa_asio/Callback_adaptation_.pdf
deleted file mode 100644
index 76bf67863524626aa079d74629c9dd9f720b0b54..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 50527
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
F{{U7nKEVJ0

diff --git a/portaudio/pa_asio/Pa_ASIO.pdf b/portaudio/pa_asio/Pa_ASIO.pdf
deleted file mode 100644
index ac5ecadbc9c861e9fae4b77f5493951504f36f4f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 50778
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
Vb#+HAUpR1x2_s}-kylk9{6Fg**QEde

diff --git a/portaudio/pa_asio/iasiothiscallresolver.cpp b/portaudio/pa_asio/iasiothiscallresolver.cpp
deleted file mode 100644
index 8dfefbd67..000000000
--- a/portaudio/pa_asio/iasiothiscallresolver.cpp
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
-	IASIOThiscallResolver.cpp see the comments in iasiothiscallresolver.h for
-    the top level description - this comment describes the technical details of
-    the implementation.
-
-    The latest version of this file is available from:
-    http://www.audiomulch.com/~rossb/code/calliasio
-
-    please email comments to Ross Bencina <rossb@audiomulch.com>
-
-    BACKGROUND
-
-    The IASIO interface declared in the Steinberg ASIO 2 SDK declares
-    functions with no explicit calling convention. This causes MSVC++ to default
-    to using the thiscall convention, which is a proprietary convention not
-    implemented by some non-microsoft compilers - notably borland BCC,
-    C++Builder, and gcc. MSVC++ is the defacto standard compiler used by
-    Steinberg. As a result of this situation, the ASIO sdk will compile with
-    any compiler, however attempting to execute the compiled code will cause a
-    crash due to different default calling conventions on non-Microsoft
-    compilers.
-
-    IASIOThiscallResolver solves the problem by providing an adapter class that
-    delegates to the IASIO interface using the correct calling convention
-    (thiscall). Due to the lack of support for thiscall in the Borland and GCC
-    compilers, the calls have been implemented in assembly language.
-
-    A number of macros are defined for thiscall function calls with different
-    numbers of parameters, with and without return values - it may be possible
-    to modify the format of these macros to make them work with other inline
-    assemblers.
-
-
-    THISCALL DEFINITION
-
-    A number of definitions of the thiscall calling convention are floating
-    around the internet. The following definition has been validated against
-    output from the MSVC++ compiler:
-
-    For non-vararg functions, thiscall works as follows: the object (this)
-    pointer is passed in ECX. All arguments are passed on the stack in
-    right to left order. The return value is placed in EAX. The callee
-    clears the passed arguments from the stack.
-
-
-    FINDING FUNCTION POINTERS FROM AN IASIO POINTER
-
-    The first field of a COM object is a pointer to its vtble. Thus a pointer
-    to an object implementing the IASIO interface also points to a pointer to
-    that object's vtbl. The vtble is a table of function pointers for all of
-    the virtual functions exposed by the implemented interfaces.
-
-    If we consider a variable declared as a pointer to IASO:
-
-    IASIO *theAsioDriver
-
-    theAsioDriver points to:
-
-    object implementing IASIO
-    {
-        IASIOvtbl *vtbl
-        other data
-    }
-
-    in other words, theAsioDriver points to a pointer to an IASIOvtbl
-
-    vtbl points to a table of function pointers:
-
-    IASIOvtbl ( interface IASIO : public IUnknown )
-    {
-    (IUnknown functions)
-    0   virtual HRESULT STDMETHODCALLTYPE (*QueryInterface)(REFIID riid, void **ppv) = 0;
-    4   virtual ULONG STDMETHODCALLTYPE (*AddRef)() = 0;
-    8   virtual ULONG STDMETHODCALLTYPE (*Release)() = 0;      
-
-    (IASIO functions)
-    12	virtual ASIOBool (*init)(void *sysHandle) = 0;
-    16	virtual void (*getDriverName)(char *name) = 0;
-    20	virtual long (*getDriverVersion)() = 0;
-    24	virtual void (*getErrorMessage)(char *string) = 0;
-    28	virtual ASIOError (*start)() = 0;
-    32	virtual ASIOError (*stop)() = 0;
-    36	virtual ASIOError (*getChannels)(long *numInputChannels, long *numOutputChannels) = 0;
-    40	virtual ASIOError (*getLatencies)(long *inputLatency, long *outputLatency) = 0;
-    44	virtual ASIOError (*getBufferSize)(long *minSize, long *maxSize,
-            long *preferredSize, long *granularity) = 0;
-    48	virtual ASIOError (*canSampleRate)(ASIOSampleRate sampleRate) = 0;
-    52	virtual ASIOError (*getSampleRate)(ASIOSampleRate *sampleRate) = 0;
-    56	virtual ASIOError (*setSampleRate)(ASIOSampleRate sampleRate) = 0;
-    60	virtual ASIOError (*getClockSources)(ASIOClockSource *clocks, long *numSources) = 0;
-    64	virtual ASIOError (*setClockSource)(long reference) = 0;
-    68	virtual ASIOError (*getSamplePosition)(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0;
-    72	virtual ASIOError (*getChannelInfo)(ASIOChannelInfo *info) = 0;
-    76	virtual ASIOError (*createBuffers)(ASIOBufferInfo *bufferInfos, long numChannels,
-            long bufferSize, ASIOCallbacks *callbacks) = 0;
-    80	virtual ASIOError (*disposeBuffers)() = 0;
-    84	virtual ASIOError (*controlPanel)() = 0;
-    88	virtual ASIOError (*future)(long selector,void *opt) = 0;
-    92	virtual ASIOError (*outputReady)() = 0;
-    };
-
-    The numbers in the left column show the byte offset of each function ptr
-    from the beginning of the vtbl. These numbers are used in the code below
-    to select different functions.
-
-    In order to find the address of a particular function, theAsioDriver
-    must first be dereferenced to find the value of the vtbl pointer:
-
-    mov     eax, theAsioDriver
-    mov     edx, [theAsioDriver]  // edx now points to vtbl[0]
-
-    Then an offset must be added to the vtbl pointer to select a
-    particular function, for example vtbl+44 points to the slot containing
-    a pointer to the getBufferSize function.
-
-    Finally vtbl+x must be dereferenced to obtain the value of the function
-    pointer stored in that address:
-
-    call    [edx+44]    // call the function pointed to by
-                        // the value in the getBufferSize field of the vtbl
-
-
-    SEE ALSO
-
-    Martin Fay's OpenASIO DLL at http://www.martinfay.com solves the same
-    problem by providing a new COM interface which wraps IASIO with an
-    interface that uses portable calling conventions. OpenASIO must be compiled
-    with MSVC, and requires that you ship the OpenASIO DLL with your
-    application.
-
-    
-    ACKNOWLEDGEMENTS
-
-    Ross Bencina: worked out the thiscall details above, wrote the original
-    Borland asm macros, and a patch for asio.cpp (which is no longer needed).
-    Thanks to Martin Fay for introducing me to the issues discussed here,
-    and to Rene G. Ceballos for assisting with asm dumps from MSVC++.
-
-    Antti Silvast: converted the original calliasio to work with gcc and NASM
-    by implementing the asm code in a separate file.
-
-	Fraser Adams: modified the original calliasio containing the Borland inline
-    asm to add inline asm for gcc i.e. Intel syntax for Borland and AT&T syntax
-    for gcc. This seems a neater approach for gcc than to have a separate .asm
-    file and it means that we only need one version of the thiscall patch.
-
-    Fraser Adams: rewrote the original calliasio patch in the form of the
-    IASIOThiscallResolver class in order to avoid modifications to files from
-    the Steinberg SDK, which may have had potential licence issues.
-
-    Andrew Baldwin: contributed fixes for compatibility problems with more
-    recent versions of the gcc assembler.
-*/
-
-
-// We only need IASIOThiscallResolver at all if we are on Win32. For other
-// platforms we simply bypass the IASIOThiscallResolver definition to allow us
-// to be safely #include'd whatever the platform to keep client code portable
-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
-
-
-// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver
-// is not used.
-#if !defined(_MSC_VER)
-
-
-#include <new>
-#include <assert.h>
-
-// We have a mechanism in iasiothiscallresolver.h to ensure that asio.h is
-// #include'd before it in client code, we do NOT want to do this test here.
-#define iasiothiscallresolver_sourcefile 1
-#include "iasiothiscallresolver.h"
-#undef iasiothiscallresolver_sourcefile
-
-// iasiothiscallresolver.h redefines ASIOInit for clients, but we don't want
-// this macro defined in this translation unit.
-#undef ASIOInit
-
-
-// theAsioDriver is a global pointer to the current IASIO instance which the
-// ASIO SDK uses to perform all actions on the IASIO interface. We substitute
-// our own forwarding interface into this pointer.
-extern IASIO* theAsioDriver;
-
-
-// The following macros define the inline assembler for BORLAND first then gcc
-
-#if defined(__BCPLUSPLUS__) || defined(__BORLANDC__)          
-
-
-#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )\
-    void *this_ = (thisPtr);                                                \
-    __asm {                                                                 \
-        mov     ecx, this_            ;                                     \
-        mov     eax, [ecx]            ;                                     \
-        call    [eax+funcOffset]      ;                                     \
-        mov     resultName, eax       ;                                     \
-    }
-
-
-#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )\
-    void *this_ = (thisPtr);                                                \
-    __asm {                                                                 \
-        mov     eax, param1           ;                                     \
-        push    eax                   ;                                     \
-        mov     ecx, this_            ;                                     \
-        mov     eax, [ecx]            ;                                     \
-        call    [eax+funcOffset]      ;                                     \
-    }
-
-
-#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )\
-    void *this_ = (thisPtr);                                                \
-    __asm {                                                                 \
-        mov     eax, param1           ;                                     \
-        push    eax                   ;                                     \
-        mov     ecx, this_            ;                                     \
-        mov     eax, [ecx]            ;                                     \
-        call    [eax+funcOffset]      ;                                     \
-        mov     resultName, eax       ;                                     \
-    }
-
-
-#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )\
-    void *this_ = (thisPtr);                                                \
-    void *doubleParamPtr_ (&param1);                                        \
-    __asm {                                                                 \
-        mov     eax, doubleParamPtr_  ;                                     \
-        push    [eax+4]               ;                                     \
-        push    [eax]                 ;                                     \
-        mov     ecx, this_            ;                                     \
-        mov     eax, [ecx]            ;                                     \
-        call    [eax+funcOffset]      ;                                     \
-        mov     resultName, eax       ;                                     \
-    }
-
-
-#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )\
-    void *this_ = (thisPtr);                                                \
-    __asm {                                                                 \
-        mov     eax, param2           ;                                     \
-        push    eax                   ;                                     \
-        mov     eax, param1           ;                                     \
-        push    eax                   ;                                     \
-        mov     ecx, this_            ;                                     \
-        mov     eax, [ecx]            ;                                     \
-        call    [eax+funcOffset]      ;                                     \
-        mov     resultName, eax       ;                                     \
-    }
-
-
-#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\
-    void *this_ = (thisPtr);                                                \
-    __asm {                                                                 \
-        mov     eax, param4           ;                                     \
-        push    eax                   ;                                     \
-        mov     eax, param3           ;                                     \
-        push    eax                   ;                                     \
-        mov     eax, param2           ;                                     \
-        push    eax                   ;                                     \
-        mov     eax, param1           ;                                     \
-        push    eax                   ;                                     \
-        mov     ecx, this_            ;                                     \
-        mov     eax, [ecx]            ;                                     \
-        call    [eax+funcOffset]      ;                                     \
-        mov     resultName, eax       ;                                     \
-    }
-
-
-#elif defined(__GNUC__)
-
-
-#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )                  \
-    __asm__ __volatile__ ("movl (%1), %%edx\n\t"                            \
-                          "call *"#funcOffset"(%%edx)\n\t"                  \
-                          :"=a"(resultName) /* Output Operands */           \
-                          :"c"(thisPtr)     /* Input Operands */            \
-                         );                                                 \
-
-
-#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )                 \
-    __asm__ __volatile__ ("pushl %0\n\t"                                    \
-                          "movl (%1), %%edx\n\t"                            \
-                          "call *"#funcOffset"(%%edx)\n\t"                  \
-                          :                 /* Output Operands */           \
-                          :"r"(param1),     /* Input Operands */            \
-                           "c"(thisPtr)                                     \
-                         );                                                 \
-
-
-#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )          \
-    __asm__ __volatile__ ("pushl %1\n\t"                                    \
-                          "movl (%2), %%edx\n\t"                            \
-                          "call *"#funcOffset"(%%edx)\n\t"                  \
-                          :"=a"(resultName) /* Output Operands */           \
-                          :"r"(param1),     /* Input Operands */            \
-                           "c"(thisPtr)                                     \
-                          );                                                \
-
-
-#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )   \
-    __asm__ __volatile__ ("pushl 4(%1)\n\t"                                 \
-                          "pushl (%1)\n\t"                                  \
-                          "movl (%2), %%edx\n\t"                            \
-                          "call *"#funcOffset"(%%edx);\n\t"                 \
-                          :"=a"(resultName) /* Output Operands */           \
-                          :"a"(&param1),    /* Input Operands */            \
-                           /* Note: Using "r" above instead of "a" fails */ \
-                           /* when using GCC 3.3.3, and maybe later versions*/\
-                           "c"(thisPtr)                                     \
-                          );                                                \
-
-
-#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )  \
-    __asm__ __volatile__ ("pushl %1\n\t"                                    \
-                          "pushl %2\n\t"                                    \
-                          "movl (%3), %%edx\n\t"                            \
-                          "call *"#funcOffset"(%%edx)\n\t"                  \
-                          :"=a"(resultName) /* Output Operands */           \
-                          :"r"(param2),     /* Input Operands */            \
-                           "r"(param1),                                     \
-                           "c"(thisPtr)                                     \
-                          );                                                \
-
-
-#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\
-    __asm__ __volatile__ ("pushl %1\n\t"                                    \
-                          "pushl %2\n\t"                                    \
-                          "pushl %3\n\t"                                    \
-                          "pushl %4\n\t"                                    \
-                          "movl (%5), %%edx\n\t"                            \
-                          "call *"#funcOffset"(%%edx)\n\t"                  \
-                          :"=a"(resultName) /* Output Operands */           \
-                          :"r"(param4),     /* Input Operands  */           \
-                           "r"(param3),                                     \
-                           "r"(param2),                                     \
-                           "r"(param1),                                     \
-                           "c"(thisPtr)                                     \
-                          );                                                \
-
-#endif
-
-
-
-// Our static singleton instance.
-IASIOThiscallResolver IASIOThiscallResolver::instance;
-
-// Constructor called to initialize static Singleton instance above. Note that
-// it is important not to clear that_ incase it has already been set by the call
-// to placement new in ASIOInit().
-IASIOThiscallResolver::IASIOThiscallResolver()
-{
-}
-
-// Constructor called from ASIOInit() below
-IASIOThiscallResolver::IASIOThiscallResolver(IASIO* that)
-: that_( that )
-{
-}
-
-// Implement IUnknown methods as assert(false). IASIOThiscallResolver is not
-// really a COM object, just a wrapper which will work with the ASIO SDK.
-// If you wanted to use ASIO without the SDK you might want to implement COM
-// aggregation in these methods.
-HRESULT STDMETHODCALLTYPE IASIOThiscallResolver::QueryInterface(REFIID riid, void **ppv)
-{
-    (void)riid;     // suppress unused variable warning
-
-    assert( false ); // this function should never be called by the ASIO SDK.
-
-    *ppv = NULL;
-    return E_NOINTERFACE;
-}
-
-ULONG STDMETHODCALLTYPE IASIOThiscallResolver::AddRef()
-{
-    assert( false ); // this function should never be called by the ASIO SDK.
-
-    return 1;
-}
-
-ULONG STDMETHODCALLTYPE IASIOThiscallResolver::Release()
-{
-    assert( false ); // this function should never be called by the ASIO SDK.
-    
-    return 1;
-}
-
-
-// Implement the IASIO interface methods by performing the vptr manipulation
-// described above then delegating to the real implementation.
-ASIOBool IASIOThiscallResolver::init(void *sysHandle)
-{
-    ASIOBool result;
-    CALL_THISCALL_1( result, that_, 12, sysHandle );
-    return result;
-}
-
-void IASIOThiscallResolver::getDriverName(char *name)
-{
-    CALL_VOID_THISCALL_1( that_, 16, name );
-}
-
-long IASIOThiscallResolver::getDriverVersion()
-{
-    ASIOBool result;
-    CALL_THISCALL_0( result, that_, 20 );
-    return result;
-}
-
-void IASIOThiscallResolver::getErrorMessage(char *string)
-{
-     CALL_VOID_THISCALL_1( that_, 24, string );
-}
-
-ASIOError IASIOThiscallResolver::start()
-{
-    ASIOBool result;
-    CALL_THISCALL_0( result, that_, 28 );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::stop()
-{
-    ASIOBool result;
-    CALL_THISCALL_0( result, that_, 32 );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getChannels(long *numInputChannels, long *numOutputChannels)
-{
-    ASIOBool result;
-    CALL_THISCALL_2( result, that_, 36, numInputChannels, numOutputChannels );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getLatencies(long *inputLatency, long *outputLatency)
-{
-    ASIOBool result;
-    CALL_THISCALL_2( result, that_, 40, inputLatency, outputLatency );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getBufferSize(long *minSize, long *maxSize,
-        long *preferredSize, long *granularity)
-{
-    ASIOBool result;
-    CALL_THISCALL_4( result, that_, 44, minSize, maxSize, preferredSize, granularity );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::canSampleRate(ASIOSampleRate sampleRate)
-{
-    ASIOBool result;
-    CALL_THISCALL_1_DOUBLE( result, that_, 48, sampleRate );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getSampleRate(ASIOSampleRate *sampleRate)
-{
-    ASIOBool result;
-    CALL_THISCALL_1( result, that_, 52, sampleRate );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::setSampleRate(ASIOSampleRate sampleRate)
-{    
-    ASIOBool result;
-    CALL_THISCALL_1_DOUBLE( result, that_, 56, sampleRate );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getClockSources(ASIOClockSource *clocks, long *numSources)
-{
-    ASIOBool result;
-    CALL_THISCALL_2( result, that_, 60, clocks, numSources );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::setClockSource(long reference)
-{
-    ASIOBool result;
-    CALL_THISCALL_1( result, that_, 64, reference );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)
-{
-    ASIOBool result;
-    CALL_THISCALL_2( result, that_, 68, sPos, tStamp );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getChannelInfo(ASIOChannelInfo *info)
-{
-    ASIOBool result;
-    CALL_THISCALL_1( result, that_, 72, info );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::createBuffers(ASIOBufferInfo *bufferInfos,
-        long numChannels, long bufferSize, ASIOCallbacks *callbacks)
-{
-    ASIOBool result;
-    CALL_THISCALL_4( result, that_, 76, bufferInfos, numChannels, bufferSize, callbacks );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::disposeBuffers()
-{
-    ASIOBool result;
-    CALL_THISCALL_0( result, that_, 80 );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::controlPanel()
-{
-    ASIOBool result;
-    CALL_THISCALL_0( result, that_, 84 );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::future(long selector,void *opt)
-{
-    ASIOBool result;
-    CALL_THISCALL_2( result, that_, 88, selector, opt );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::outputReady()
-{
-    ASIOBool result;
-    CALL_THISCALL_0( result, that_, 92 );
-    return result;
-}
-
-
-// Implement our substitute ASIOInit() method
-ASIOError IASIOThiscallResolver::ASIOInit(ASIODriverInfo *info)
-{
-    // To ensure that our instance's vptr is correctly constructed, even if
-    // ASIOInit is called prior to main(), we explicitly call its constructor
-    // (potentially over the top of an existing instance). Note that this is
-    // pretty ugly, and is only safe because IASIOThiscallResolver has no
-    // destructor and contains no objects with destructors.
-    new((void*)&instance) IASIOThiscallResolver( theAsioDriver );
-
-    // Interpose between ASIO client code and the real driver.
-    theAsioDriver = &instance;
-
-    // Note that we never need to switch theAsioDriver back to point to the
-    // real driver because theAsioDriver is reset to zero in ASIOExit().
-
-    // Delegate to the real ASIOInit
-	return ::ASIOInit(info);
-}
-
-
-#endif /* !defined(_MSC_VER) */
-
-#endif /* Win32 */
-
diff --git a/portaudio/pa_asio/iasiothiscallresolver.h b/portaudio/pa_asio/iasiothiscallresolver.h
deleted file mode 100644
index 2ecfed799..000000000
--- a/portaudio/pa_asio/iasiothiscallresolver.h
+++ /dev/null
@@ -1,197 +0,0 @@
-// ****************************************************************************
-// File:			IASIOThiscallResolver.h
-// Description:     The IASIOThiscallResolver class implements the IASIO
-//					interface and acts as a proxy to the real IASIO interface by
-//                  calling through its vptr table using the thiscall calling
-//                  convention. To put it another way, we interpose
-//                  IASIOThiscallResolver between ASIO SDK code and the driver.
-//                  This is necessary because most non-Microsoft compilers don't
-//                  implement the thiscall calling convention used by IASIO.
-//
-//					iasiothiscallresolver.cpp contains the background of this
-//					problem plus a technical description of the vptr
-//                  manipulations.
-//
-//					In order to use this mechanism one simply has to add
-//					iasiothiscallresolver.cpp to the list of files to compile
-//                  and #include <iasiothiscallresolver.h>
-//
-//					Note that this #include must come after the other ASIO SDK
-//                  #includes, for example:
-//
-//					#include <windows.h>
-//					#include <asiosys.h>
-//					#include <asio.h>
-//					#include <asiodrivers.h>
-//					#include <iasiothiscallresolver.h>
-//
-//					Actually the important thing is to #include
-//                  <iasiothiscallresolver.h> after <asio.h>. We have
-//                  incorporated a test to enforce this ordering.
-//
-//					The code transparently takes care of the interposition by
-//                  using macro substitution to intercept calls to ASIOInit()
-//                  and ASIOExit(). We save the original ASIO global
-//                  "theAsioDriver" in our "that" variable, and then set
-//                  "theAsioDriver" to equal our IASIOThiscallResolver instance.
-//
-// 					Whilst this method of resolving the thiscall problem requires
-//					the addition of #include <iasiothiscallresolver.h> to client
-//                  code it has the advantage that it does not break the terms
-//                  of the ASIO licence by publishing it. We are NOT modifying
-//                  any Steinberg code here, we are merely implementing the IASIO
-//					interface in the same way that we would need to do if we
-//					wished to provide an open source ASIO driver.
-//
-//					For compilation with MinGW -lole32 needs to be added to the
-//                  linker options. For BORLAND, linking with Import32.lib is
-//                  sufficient.
-//
-//					The dependencies are with: CoInitialize, CoUninitialize,
-//					CoCreateInstance, CLSIDFromString - used by asiolist.cpp
-//					and are required on Windows whether ThiscallResolver is used
-//					or not.
-//
-//					Searching for the above strings in the root library path
-//					of your compiler should enable the correct libraries to be
-//					identified if they aren't immediately obvious.
-//
-//                  Note that the current implementation of IASIOThiscallResolver
-//                  is not COM compliant - it does not correctly implement the
-//                  IUnknown interface. Implementing it is not necessary because
-//                  it is not called by parts of the ASIO SDK which call through
-//                  theAsioDriver ptr. The IUnknown methods are implemented as
-//                  assert(false) to ensure that the code fails if they are
-//                  ever called.
-// Restrictions:	None. Public Domain & Open Source distribute freely
-//					You may use IASIOThiscallResolver commercially as well as
-//                  privately.
-//					You the user assume the responsibility for the use of the
-//					files, binary or text, and there is no guarantee or warranty,
-//					expressed or implied, including but not limited to the
-//					implied warranties of merchantability and fitness for a
-//					particular purpose. You assume all responsibility and agree
-//					to hold no entity, copyright holder or distributors liable
-//					for any loss of data or inaccurate representations of data
-//					as a result of using IASIOThiscallResolver.
-// Version:         1.4 Added separate macro CALL_THISCALL_1_DOUBLE from
-//                  Andrew Baldwin, and volatile for whole gcc asm blocks,
-//                  both for compatibility with newer gcc versions. Cleaned up
-//                  Borland asm to use one less register.
-//                  1.3 Switched to including assert.h for better compatibility.
-//                  Wrapped entire .h and .cpp contents with a check for
-//                  _MSC_VER to provide better compatibility with MS compilers.
-//                  Changed Singleton implementation to use static instance
-//                  instead of freestore allocated instance. Removed ASIOExit
-//                  macro as it is no longer needed.
-//                  1.2 Removed semicolons from ASIOInit and ASIOExit macros to
-//                  allow them to be embedded in expressions (if statements).
-//                  Cleaned up some comments. Removed combase.c dependency (it
-//                  doesn't compile with BCB anyway) by stubbing IUnknown.
-//                  1.1 Incorporated comments from Ross Bencina including things
-//					such as changing name from ThiscallResolver to
-//					IASIOThiscallResolver, tidying up the constructor, fixing
-//					a bug in IASIOThiscallResolver::ASIOExit() and improving
-//					portability through the use of conditional compilation
-//					1.0 Initial working version.
-// Created:			6/09/2003
-// Authors:         Fraser Adams
-//                  Ross Bencina
-//                  Rene G. Ceballos
-//                  Martin Fay
-//                  Antti Silvast
-//                  Andrew Baldwin
-//
-// ****************************************************************************
-
-
-#ifndef included_iasiothiscallresolver_h
-#define included_iasiothiscallresolver_h
-
-// We only need IASIOThiscallResolver at all if we are on Win32. For other
-// platforms we simply bypass the IASIOThiscallResolver definition to allow us
-// to be safely #include'd whatever the platform to keep client code portable
-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
-
-
-// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver
-// is not used.
-#if !defined(_MSC_VER)
-
-
-// The following is in order to ensure that this header is only included after
-// the other ASIO headers (except for the case of iasiothiscallresolver.cpp).
-// We need to do this because IASIOThiscallResolver works by eclipsing the
-// original definition of ASIOInit() with a macro (see below).
-#if !defined(iasiothiscallresolver_sourcefile)
-	#if !defined(__ASIO_H)
-	#error iasiothiscallresolver.h must be included AFTER asio.h
-	#endif
-#endif
-
-#include <windows.h>
-#include <asiodrvr.h> /* From ASIO SDK */
-
-
-class IASIOThiscallResolver : public IASIO {
-private:
-	IASIO* that_; // Points to the real IASIO
-
-	static IASIOThiscallResolver instance; // Singleton instance
-
-	// Constructors - declared private so construction is limited to
-    // our Singleton instance
-    IASIOThiscallResolver();
-	IASIOThiscallResolver(IASIO* that);
-public:
-
-    // Methods from the IUnknown interface. We don't fully implement IUnknown
-    // because the ASIO SDK never calls these methods through theAsioDriver ptr.
-    // These methods are implemented as assert(false).
-    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv);
-    virtual ULONG STDMETHODCALLTYPE AddRef();
-    virtual ULONG STDMETHODCALLTYPE Release();
-
-    // Methods from the IASIO interface, implemented as forwarning calls to that.
-	virtual ASIOBool init(void *sysHandle);
-	virtual void getDriverName(char *name);
-	virtual long getDriverVersion();
-	virtual void getErrorMessage(char *string);
-	virtual ASIOError start();
-	virtual ASIOError stop();
-	virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels);
-	virtual ASIOError getLatencies(long *inputLatency, long *outputLatency);
-	virtual ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);
-	virtual ASIOError canSampleRate(ASIOSampleRate sampleRate);
-	virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate);
-	virtual ASIOError setSampleRate(ASIOSampleRate sampleRate);
-	virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources);
-	virtual ASIOError setClockSource(long reference);
-	virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp);
-	virtual ASIOError getChannelInfo(ASIOChannelInfo *info);
-	virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks);
-	virtual ASIOError disposeBuffers();
-	virtual ASIOError controlPanel();
-	virtual ASIOError future(long selector,void *opt);
-	virtual ASIOError outputReady();
-
-    // Class method, see ASIOInit() macro below.
-    static ASIOError ASIOInit(ASIODriverInfo *info); // Delegates to ::ASIOInit
-};
-
-
-// Replace calls to ASIOInit with our interposing version.
-// This macro enables us to perform thiscall resolution simply by #including
-// <iasiothiscallresolver.h> after the asio #includes (this file _must_ be
-// included _after_ the asio #includes)
-
-#define ASIOInit(name) IASIOThiscallResolver::ASIOInit((name))
-
-
-#endif /* !defined(_MSC_VER) */
-
-#endif /* Win32 */
-
-#endif /* included_iasiothiscallresolver_h */
-
-
diff --git a/portaudio/pa_asio/pa_asio.cpp b/portaudio/pa_asio/pa_asio.cpp
deleted file mode 100644
index 21987c714..000000000
--- a/portaudio/pa_asio/pa_asio.cpp
+++ /dev/null
@@ -1,2958 +0,0 @@
-/*
- * $Id: pa_asio.cpp,v 1.7.2.68 2005/12/05 04:55:28 rossbencina Exp $
- * Portable Audio I/O Library for ASIO Drivers
- *
- * Author: Stephane Letz
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 2000-2002 Stephane Letz, Phil Burk, 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.
- */
-
-/* Modification History
-
-        08-03-01 First version : Stephane Letz
-        08-06-01 Tweaks for PC, use C++, buffer allocation, Float32 to Int32 conversion : Phil Burk
-        08-20-01 More conversion, PA_StreamTime, Pa_GetHostError : Stephane Letz
-        08-21-01 PaUInt8 bug correction, implementation of ASIOSTFloat32LSB and ASIOSTFloat32MSB native formats : Stephane Letz
-        08-24-01 MAX_INT32_FP hack, another Uint8 fix : Stephane and Phil
-        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
-        10-12-01 Correct the PaHost_CalcNumHostBuffers function: computes FramesPerHostBuffer to be the lowest that
-                 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
-        12-06-02 Rehashed into new multi-api infrastructure, added support for all ASIO sample formats : Ross Bencina
-        18-06-02 Added pa_asio.h, PaAsio_GetAvailableLatencyValues() : Ross B.
-        21-06-02 Added SelectHostBufferSize() which selects host buffer size based on user latency parameters : Ross Bencina
-        ** NOTE  maintanance history is now stored in CVS **
-*/
-
-/** @file
-
-    Note that specific support for paInputUnderflow, paOutputOverflow and
-    paNeverDropInput is not necessary or possible with this driver due to the
-    synchronous full duplex double-buffered architecture of ASIO.
-
-    @todo check that CoInitialize()/CoUninitialize() are always correctly
-        paired, even in error cases.
-
-    @todo implement host api specific extension to set i/o buffer sizes in frames
-
-    @todo implement ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable
-
-    @todo implement IsFormatSupported
-
-    @todo work out how to implement stream stoppage from callback and
-            implement IsStreamActive properly. Stream stoppage could be implemented
-            using a high-priority thread blocked on an Event which is signalled
-            by the callback. Or, we could just call ASIO stop from the callback
-            and see what happens.
-
-    @todo rigorously check asio return codes and convert to pa error codes
-
-    @todo Different channels of a multichannel stream can have different sample
-            formats, but we assume that all are the same as the first channel for now.
-            Fixing this will require the block processor to maintain per-channel
-            conversion functions - could get nasty.
-
-    @todo investigate whether the asio processNow flag needs to be honoured
-
-    @todo handle asioMessages() callbacks in a useful way, or at least document
-            what cases we don't handle.
-
-    @todo miscellaneous other FIXMEs
-
-    @todo provide an asio-specific method for setting the systems specific
-        value (aka main window handle) - check that this matches the value
-        passed to PaAsio_ShowControlPanel, or remove it entirely from
-        PaAsio_ShowControlPanel. - this would allow PaAsio_ShowControlPanel
-        to be called for the currently open stream (at present all streams
-        must be closed).
-*/
-
-
-
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-//#include <values.h>
-
-#include <windows.h>
-#include <mmsystem.h>
-
-#include "portaudio.h"
-#include "pa_asio.h"
-#include "pa_util.h"
-#include "pa_allocation.h"
-#include "pa_hostapi.h"
-#include "pa_stream.h"
-#include "pa_cpuload.h"
-#include "pa_process.h"
-
-#include "asiosys.h"
-#include "asio.h"
-#include "asiodrivers.h"
-#include "iasiothiscallresolver.h"
-
-/*
-#if MAC
-#include <Devices.h>
-#include <Timer.h>
-#include <Math64.h>
-#else
-*/
-/*
-#include <math.h>
-#include <windows.h>
-#include <mmsystem.h>
-*/
-/*
-#endif
-*/
-
-/* external references */
-extern AsioDrivers* asioDrivers ;
-bool loadAsioDriver(char *name);
-
-
-/* We are trying to be compatible with CARBON but this has not been thoroughly tested. */
-/* not tested at all since new code was introduced. */
-#define CARBON_COMPATIBLE  (0)
-
-
-
-
-/* prototypes for functions declared in this file */
-
-extern "C" PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex );
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData );
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate );
-static PaError CloseStream( PaStream* stream );
-static PaError StartStream( PaStream *stream );
-static PaError StopStream( PaStream *stream );
-static PaError AbortStream( PaStream *stream );
-static PaError IsStreamStopped( PaStream *s );
-static PaError IsStreamActive( PaStream *stream );
-static PaTime GetStreamTime( PaStream *stream );
-static double GetStreamCpuLoad( PaStream* stream );
-static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
-static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
-static signed long GetStreamReadAvailable( PaStream* stream );
-static signed long GetStreamWriteAvailable( PaStream* stream );
-
-/* our ASIO callback functions */
-
-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);
-
-static ASIOCallbacks asioCallbacks_ =
-    { bufferSwitch, sampleRateChanged, asioMessages, bufferSwitchTimeInfo };
-
-
-#define PA_ASIO_SET_LAST_HOST_ERROR( errorCode, errorText ) \
-    PaUtil_SetLastHostErrorInfo( paASIO, errorCode, errorText )
-
-
-static void PaAsio_SetLastSystemError( DWORD errorCode )
-{
-    LPVOID lpMsgBuf;
-    FormatMessage(
-        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-        NULL,
-        errorCode,
-        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-        (LPTSTR) &lpMsgBuf,
-        0,
-        NULL
-    );
-    PaUtil_SetLastHostErrorInfo( paASIO, errorCode, (const char*)lpMsgBuf );
-    LocalFree( lpMsgBuf );
-}
-
-#define PA_ASIO_SET_LAST_SYSTEM_ERROR( errorCode ) \
-    PaAsio_SetLastSystemError( errorCode )
-
-
-static const char* PaAsio_GetAsioErrorText( ASIOError asioError )
-{
-    const char *result;
-
-    switch( asioError ){
-        case ASE_OK:
-        case ASE_SUCCESS:           result = "Success"; break;
-        case ASE_NotPresent:        result = "Hardware input or output is not present or available"; break;
-        case ASE_HWMalfunction:     result = "Hardware is malfunctioning"; break;
-        case ASE_InvalidParameter:  result = "Input parameter invalid"; break;
-        case ASE_InvalidMode:       result = "Hardware is in a bad mode or used in a bad mode"; break;
-        case ASE_SPNotAdvancing:    result = "Hardware is not running when sample position is inquired"; break;
-        case ASE_NoClock:           result = "Sample clock or rate cannot be determined or is not present"; break;
-        case ASE_NoMemory:          result = "Not enough memory for completing the request"; break;
-        default:                    result = "Unknown ASIO error"; break;
-    }
-
-    return result;
-}
-
-
-#define PA_ASIO_SET_LAST_ASIO_ERROR( asioError ) \
-    PaUtil_SetLastHostErrorInfo( paASIO, asioError, PaAsio_GetAsioErrorText( asioError ) )
-
-
-
-
-// Atomic increment and decrement operations
-#if MAC
-	/* need to be implemented on Mac */
-	inline long PaAsio_AtomicIncrement(volatile long* v) {return ++(*const_cast<long*>(v));}
-	inline long PaAsio_AtomicDecrement(volatile long* v) {return --(*const_cast<long*>(v));}
-#elif WINDOWS
-	inline long PaAsio_AtomicIncrement(volatile long* v) {return InterlockedIncrement(const_cast<long*>(v));}
-	inline long PaAsio_AtomicDecrement(volatile long* v) {return InterlockedDecrement(const_cast<long*>(v));}
-#endif
-
-
-
-typedef struct PaAsioDriverInfo
-{
-    ASIODriverInfo asioDriverInfo;
-    long inputChannelCount, outputChannelCount;
-    long bufferMinSize, bufferMaxSize, bufferPreferredSize, bufferGranularity;
-    bool postOutput;
-}
-PaAsioDriverInfo;
-
-
-/* PaAsioHostApiRepresentation - host api datastructure specific to this implementation */
-
-typedef struct
-{
-    PaUtilHostApiRepresentation inheritedHostApiRep;
-    PaUtilStreamInterface callbackStreamInterface;
-    PaUtilStreamInterface blockingStreamInterface;
-
-    PaUtilAllocationGroup *allocations;
-
-    void *systemSpecific;
-    
-    /* the ASIO C API only allows one ASIO driver to be open at a time,
-        so we keep track of whether we have the driver open here, and
-        use this information to return errors from OpenStream if the
-        driver is already open.
-
-        openAsioDeviceIndex will be PaNoDevice if there is no device open
-        and a valid pa_asio (not global) device index otherwise.
-
-        openAsioDriverInfo is populated with the driver info for the
-        currently open device (if any)
-    */
-    PaDeviceIndex openAsioDeviceIndex;
-    PaAsioDriverInfo openAsioDriverInfo;
-}
-PaAsioHostApiRepresentation;
-
-
-/*
-    Retrieve <driverCount> driver names from ASIO, returned in a char**
-    allocated in <group>.
-*/
-static char **GetAsioDriverNames( PaUtilAllocationGroup *group, long driverCount )
-{
-    char **result = 0;
-    int i;
-
-    result =(char**)PaUtil_GroupAllocateMemory(
-            group, sizeof(char*) * driverCount );
-    if( !result )
-        goto error;
-
-    result[0] = (char*)PaUtil_GroupAllocateMemory(
-            group, 32 * driverCount );
-    if( !result[0] )
-        goto error;
-
-    for( i=0; i<driverCount; ++i )
-        result[i] = result[0] + (32 * i);
-
-    asioDrivers->getDriverNames( result, driverCount );
-
-error:
-    return result;
-}
-
-
-static PaSampleFormat AsioSampleTypeToPaNativeSampleFormat(ASIOSampleType type)
-{
-    switch (type) {
-        case ASIOSTInt16MSB:
-        case ASIOSTInt16LSB:
-                return paInt16;
-
-        case ASIOSTFloat32MSB:
-        case ASIOSTFloat32LSB:
-        case ASIOSTFloat64MSB:
-        case ASIOSTFloat64LSB:
-                return paFloat32;
-
-        case ASIOSTInt32MSB:
-        case ASIOSTInt32LSB:
-        case ASIOSTInt32MSB16:
-        case ASIOSTInt32LSB16:
-        case ASIOSTInt32MSB18:
-        case ASIOSTInt32MSB20:
-        case ASIOSTInt32MSB24:
-        case ASIOSTInt32LSB18:
-        case ASIOSTInt32LSB20:
-        case ASIOSTInt32LSB24:
-                return paInt32;
-
-        case ASIOSTInt24MSB:
-        case ASIOSTInt24LSB:
-                return paInt24;
-
-        default:
-                return paCustomFormat;
-    }
-}
-
-void AsioSampleTypeLOG(ASIOSampleType type)
-{
-    switch (type) {
-        case ASIOSTInt16MSB:  PA_DEBUG(("ASIOSTInt16MSB\n"));  break;
-        case ASIOSTInt16LSB:  PA_DEBUG(("ASIOSTInt16LSB\n"));  break;
-        case ASIOSTFloat32MSB:PA_DEBUG(("ASIOSTFloat32MSB\n"));break;
-        case ASIOSTFloat32LSB:PA_DEBUG(("ASIOSTFloat32LSB\n"));break;
-        case ASIOSTFloat64MSB:PA_DEBUG(("ASIOSTFloat64MSB\n"));break;
-        case ASIOSTFloat64LSB:PA_DEBUG(("ASIOSTFloat64LSB\n"));break;
-        case ASIOSTInt32MSB:  PA_DEBUG(("ASIOSTInt32MSB\n"));  break;
-        case ASIOSTInt32LSB:  PA_DEBUG(("ASIOSTInt32LSB\n"));  break;
-        case ASIOSTInt32MSB16:PA_DEBUG(("ASIOSTInt32MSB16\n"));break;
-        case ASIOSTInt32LSB16:PA_DEBUG(("ASIOSTInt32LSB16\n"));break;
-        case ASIOSTInt32MSB18:PA_DEBUG(("ASIOSTInt32MSB18\n"));break;
-        case ASIOSTInt32MSB20:PA_DEBUG(("ASIOSTInt32MSB20\n"));break;
-        case ASIOSTInt32MSB24:PA_DEBUG(("ASIOSTInt32MSB24\n"));break;
-        case ASIOSTInt32LSB18:PA_DEBUG(("ASIOSTInt32LSB18\n"));break;
-        case ASIOSTInt32LSB20:PA_DEBUG(("ASIOSTInt32LSB20\n"));break;
-        case ASIOSTInt32LSB24:PA_DEBUG(("ASIOSTInt32LSB24\n"));break;
-        case ASIOSTInt24MSB:  PA_DEBUG(("ASIOSTInt24MSB\n"));  break;
-        case ASIOSTInt24LSB:  PA_DEBUG(("ASIOSTInt24LSB\n"));  break;
-        default:              PA_DEBUG(("Custom Format%d\n",type));break;
-
-    }
-}
-
-static int BytesPerAsioSample( ASIOSampleType sampleType )
-{
-    switch (sampleType) {
-        case ASIOSTInt16MSB:
-        case ASIOSTInt16LSB:
-            return 2;
-
-        case ASIOSTFloat64MSB:
-        case ASIOSTFloat64LSB:
-            return 8;
-
-        case ASIOSTFloat32MSB:
-        case ASIOSTFloat32LSB:
-        case ASIOSTInt32MSB:
-        case ASIOSTInt32LSB:
-        case ASIOSTInt32MSB16:
-        case ASIOSTInt32LSB16:
-        case ASIOSTInt32MSB18:
-        case ASIOSTInt32MSB20:
-        case ASIOSTInt32MSB24:
-        case ASIOSTInt32LSB18:
-        case ASIOSTInt32LSB20:
-        case ASIOSTInt32LSB24:
-            return 4;
-
-        case ASIOSTInt24MSB:
-        case ASIOSTInt24LSB:
-            return 3;
-
-        default:
-            return 0;
-    }
-}
-
-
-static void Swap16( void *buffer, long shift, long count )
-{
-    unsigned short *p = (unsigned short*)buffer;
-    unsigned short temp;
-    (void) shift; /* unused parameter */
-
-    while( count-- )
-    {
-        temp = *p;
-        *p++ = (unsigned short)((temp<<8) | (temp>>8));
-    }
-}
-
-static void Swap24( void *buffer, long shift, long count )
-{
-    unsigned char *p = (unsigned char*)buffer;
-    unsigned char temp;
-    (void) shift; /* unused parameter */
-
-    while( count-- )
-    {
-        temp = *p;
-        *p = *(p+2);
-        *(p+2) = temp;
-        p += 3;
-    }
-}
-
-#define PA_SWAP32_( x ) ((x>>24) | ((x>>8)&0xFF00) | ((x<<8)&0xFF0000) | (x<<24));
-
-static void Swap32( void *buffer, long shift, long count )
-{
-    unsigned long *p = (unsigned long*)buffer;
-    unsigned long temp;
-    (void) shift; /* unused parameter */
-
-    while( count-- )
-    {
-        temp = *p;
-        *p++ = PA_SWAP32_( temp);
-    }
-}
-
-static void SwapShiftLeft32( void *buffer, long shift, long count )
-{
-    unsigned long *p = (unsigned long*)buffer;
-    unsigned long temp;
-
-    while( count-- )
-    {
-        temp = *p;
-        temp = PA_SWAP32_( temp);
-        *p++ = temp << shift;
-    }
-}
-
-static void ShiftRightSwap32( void *buffer, long shift, long count )
-{
-    unsigned long *p = (unsigned long*)buffer;
-    unsigned long temp;
-
-    while( count-- )
-    {
-        temp = *p >> shift;
-        *p++ = PA_SWAP32_( temp);
-    }
-}
-
-static void ShiftLeft32( void *buffer, long shift, long count )
-{
-    unsigned long *p = (unsigned long*)buffer;
-    unsigned long temp;
-
-    while( count-- )
-    {
-        temp = *p;
-        *p++ = temp << shift;
-    }
-}
-
-static void ShiftRight32( void *buffer, long shift, long count )
-{
-    unsigned long *p = (unsigned long*)buffer;
-    unsigned long temp;
-
-    while( count-- )
-    {
-        temp = *p;
-        *p++ = temp >> shift;
-    }
-}
-
-#define PA_SWAP_( x, y ) temp=x; x = y; y = temp;
-
-static void Swap64ConvertFloat64ToFloat32( void *buffer, long shift, long count )
-{
-    double *in = (double*)buffer;
-    float *out = (float*)buffer;
-    unsigned char *p;
-    unsigned char temp;
-    (void) shift; /* unused parameter */
-
-    while( count-- )
-    {
-        p = (unsigned char*)in;
-        PA_SWAP_( p[0], p[7] );
-        PA_SWAP_( p[1], p[6] );
-        PA_SWAP_( p[2], p[5] );
-        PA_SWAP_( p[3], p[4] );
-
-        *out++ = (float) (*in++);
-    }
-}
-
-static void ConvertFloat64ToFloat32( void *buffer, long shift, long count )
-{
-    double *in = (double*)buffer;
-    float *out = (float*)buffer;
-    (void) shift; /* unused parameter */
-
-    while( count-- )
-        *out++ = (float) (*in++);
-}
-
-static void ConvertFloat32ToFloat64Swap64( void *buffer, long shift, long count )
-{
-    float *in = ((float*)buffer) + (count-1);
-    double *out = ((double*)buffer) + (count-1);
-    unsigned char *p;
-    unsigned char temp;
-    (void) shift; /* unused parameter */
-
-    while( count-- )
-    {
-        *out = *in--;
-
-        p = (unsigned char*)out;
-        PA_SWAP_( p[0], p[7] );
-        PA_SWAP_( p[1], p[6] );
-        PA_SWAP_( p[2], p[5] );
-        PA_SWAP_( p[3], p[4] );
-
-        out--;
-    }
-}
-
-static void ConvertFloat32ToFloat64( void *buffer, long shift, long count )
-{
-    float *in = ((float*)buffer) + (count-1);
-    double *out = ((double*)buffer) + (count-1);
-    (void) shift; /* unused parameter */
-
-    while( count-- )
-        *out-- = *in--;
-}
-
-#ifdef MAC
-#define PA_MSB_IS_NATIVE_
-#undef PA_LSB_IS_NATIVE_
-#endif
-
-#ifdef WINDOWS
-#undef PA_MSB_IS_NATIVE_
-#define PA_LSB_IS_NATIVE_
-#endif
-
-typedef void PaAsioBufferConverter( void *, long, long );
-
-static void SelectAsioToPaConverter( ASIOSampleType type, PaAsioBufferConverter **converter, long *shift )
-{
-    *shift = 0;
-    *converter = 0;
-
-    switch (type) {
-        case ASIOSTInt16MSB:
-            /* dest: paInt16, no conversion necessary, possible byte swap*/
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = Swap16;
-            #endif
-            break;
-        case ASIOSTInt16LSB:
-            /* dest: paInt16, no conversion necessary, possible byte swap*/
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = Swap16;
-            #endif
-            break;
-        case ASIOSTFloat32MSB:
-            /* dest: paFloat32, no conversion necessary, possible byte swap*/
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = Swap32;
-            #endif
-            break;
-        case ASIOSTFloat32LSB:
-            /* dest: paFloat32, no conversion necessary, possible byte swap*/
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = Swap32;
-            #endif
-            break;
-        case ASIOSTFloat64MSB:
-            /* dest: paFloat32, in-place conversion to/from float32, possible byte swap*/
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = Swap64ConvertFloat64ToFloat32;
-            #else
-                *converter = ConvertFloat64ToFloat32;
-            #endif
-            break;
-        case ASIOSTFloat64LSB:
-            /* dest: paFloat32, in-place conversion to/from float32, possible byte swap*/
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = Swap64ConvertFloat64ToFloat32;
-            #else
-                *converter = ConvertFloat64ToFloat32;
-            #endif
-            break;
-        case ASIOSTInt32MSB:
-            /* dest: paInt32, no conversion necessary, possible byte swap */
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = Swap32;
-            #endif
-            break;
-        case ASIOSTInt32LSB:
-            /* dest: paInt32, no conversion necessary, possible byte swap */
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = Swap32;
-            #endif
-            break;
-        case ASIOSTInt32MSB16:
-            /* dest: paInt32, 16 bit shift, possible byte swap */
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = SwapShiftLeft32;
-            #else
-                *converter = ShiftLeft32;
-            #endif
-            *shift = 16;
-            break;
-        case ASIOSTInt32MSB18:
-            /* dest: paInt32, 14 bit shift, possible byte swap */
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = SwapShiftLeft32;
-            #else
-                *converter = ShiftLeft32;
-            #endif
-            *shift = 14;
-            break;
-        case ASIOSTInt32MSB20:
-            /* dest: paInt32, 12 bit shift, possible byte swap */
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = SwapShiftLeft32;
-            #else
-                *converter = ShiftLeft32;
-            #endif
-            *shift = 12;
-            break;
-        case ASIOSTInt32MSB24:
-            /* dest: paInt32, 8 bit shift, possible byte swap */
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = SwapShiftLeft32;
-            #else
-                *converter = ShiftLeft32;
-            #endif
-            *shift = 8;
-            break;
-        case ASIOSTInt32LSB16:
-            /* dest: paInt32, 16 bit shift, possible byte swap */
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = SwapShiftLeft32;
-            #else
-                *converter = ShiftLeft32;
-            #endif
-            *shift = 16;
-            break;
-        case ASIOSTInt32LSB18:
-            /* dest: paInt32, 14 bit shift, possible byte swap */
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = SwapShiftLeft32;
-            #else
-                *converter = ShiftLeft32;
-            #endif
-            *shift = 14;
-            break;
-        case ASIOSTInt32LSB20:
-            /* dest: paInt32, 12 bit shift, possible byte swap */
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = SwapShiftLeft32;
-            #else
-                *converter = ShiftLeft32;
-            #endif
-            *shift = 12;
-            break;
-        case ASIOSTInt32LSB24:
-            /* dest: paInt32, 8 bit shift, possible byte swap */
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = SwapShiftLeft32;
-            #else
-                *converter = ShiftLeft32;
-            #endif
-            *shift = 8;
-            break;
-        case ASIOSTInt24MSB:
-            /* dest: paInt24, no conversion necessary, possible byte swap */
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = Swap24;
-            #endif
-            break;
-        case ASIOSTInt24LSB:
-            /* dest: paInt24, no conversion necessary, possible byte swap */
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = Swap24;
-            #endif
-            break;
-    }
-}
-
-
-static void SelectPaToAsioConverter( ASIOSampleType type, PaAsioBufferConverter **converter, long *shift )
-{
-    *shift = 0;
-    *converter = 0;
-
-    switch (type) {
-        case ASIOSTInt16MSB:
-            /* src: paInt16, no conversion necessary, possible byte swap*/
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = Swap16;
-            #endif
-            break;
-        case ASIOSTInt16LSB:
-            /* src: paInt16, no conversion necessary, possible byte swap*/
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = Swap16;
-            #endif
-            break;
-        case ASIOSTFloat32MSB:
-            /* src: paFloat32, no conversion necessary, possible byte swap*/
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = Swap32;
-            #endif
-            break;
-        case ASIOSTFloat32LSB:
-            /* src: paFloat32, no conversion necessary, possible byte swap*/
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = Swap32;
-            #endif
-            break;
-        case ASIOSTFloat64MSB:
-            /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = ConvertFloat32ToFloat64Swap64;
-            #else
-                *converter = ConvertFloat32ToFloat64;
-            #endif
-            break;
-        case ASIOSTFloat64LSB:
-            /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = ConvertFloat32ToFloat64Swap64;
-            #else
-                *converter = ConvertFloat32ToFloat64;
-            #endif
-            break;
-        case ASIOSTInt32MSB:
-            /* src: paInt32, no conversion necessary, possible byte swap */
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = Swap32;
-            #endif
-            break;
-        case ASIOSTInt32LSB:
-            /* src: paInt32, no conversion necessary, possible byte swap */
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = Swap32;
-            #endif
-            break;
-        case ASIOSTInt32MSB16:
-            /* src: paInt32, 16 bit shift, possible byte swap */
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = ShiftRightSwap32;
-            #else
-                *converter = ShiftRight32;
-            #endif
-            *shift = 16;
-            break;
-        case ASIOSTInt32MSB18:
-            /* src: paInt32, 14 bit shift, possible byte swap */
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = ShiftRightSwap32;
-            #else
-                *converter = ShiftRight32;
-            #endif
-            *shift = 14;
-            break;
-        case ASIOSTInt32MSB20:
-            /* src: paInt32, 12 bit shift, possible byte swap */
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = ShiftRightSwap32;
-            #else
-                *converter = ShiftRight32;
-            #endif
-            *shift = 12;
-            break;
-        case ASIOSTInt32MSB24:
-            /* src: paInt32, 8 bit shift, possible byte swap */
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = ShiftRightSwap32;
-            #else
-                *converter = ShiftRight32;
-            #endif
-            *shift = 8;
-            break;
-        case ASIOSTInt32LSB16:
-            /* src: paInt32, 16 bit shift, possible byte swap */
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = ShiftRightSwap32;
-            #else
-                *converter = ShiftRight32;
-            #endif
-            *shift = 16;
-            break;
-        case ASIOSTInt32LSB18:
-            /* src: paInt32, 14 bit shift, possible byte swap */
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = ShiftRightSwap32;
-            #else
-                *converter = ShiftRight32;
-            #endif
-            *shift = 14;
-            break;
-        case ASIOSTInt32LSB20:
-            /* src: paInt32, 12 bit shift, possible byte swap */
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = ShiftRightSwap32;
-            #else
-                *converter = ShiftRight32;
-            #endif
-            *shift = 12;
-            break;
-        case ASIOSTInt32LSB24:
-            /* src: paInt32, 8 bit shift, possible byte swap */
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = ShiftRightSwap32;
-            #else
-                *converter = ShiftRight32;
-            #endif
-            *shift = 8;
-            break;
-        case ASIOSTInt24MSB:
-            /* src: paInt24, no conversion necessary, possible byte swap */
-            #ifdef PA_LSB_IS_NATIVE_
-                *converter = Swap24;
-            #endif
-            break;
-        case ASIOSTInt24LSB:
-            /* src: paInt24, no conversion necessary, possible byte swap */
-            #ifdef PA_MSB_IS_NATIVE_
-                *converter = Swap24;
-            #endif
-            break;
-    }
-}
-
-
-typedef struct PaAsioDeviceInfo
-{
-    PaDeviceInfo commonDeviceInfo;
-    long minBufferSize;
-    long maxBufferSize;
-    long preferredBufferSize;
-    long bufferGranularity;
-
-    ASIOChannelInfo *asioChannelInfos;
-}
-PaAsioDeviceInfo;
-
-
-PaError PaAsio_GetAvailableLatencyValues( PaDeviceIndex device,
-		long *minLatency, long *maxLatency, long *preferredLatency, long *granularity )
-{
-    PaError result;
-    PaUtilHostApiRepresentation *hostApi;
-    PaDeviceIndex hostApiDevice;
-
-    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
-
-    if( result == paNoError )
-    {
-        result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi );
-
-        if( result == paNoError )
-        {
-            PaAsioDeviceInfo *asioDeviceInfo =
-                    (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice];
-
-            *minLatency = asioDeviceInfo->minBufferSize;
-            *maxLatency = asioDeviceInfo->maxBufferSize;
-            *preferredLatency = asioDeviceInfo->preferredBufferSize;
-            *granularity = asioDeviceInfo->bufferGranularity;
-        }
-    }
-
-    return result;
-}
-
-
-
-/*
-    load the asio driver named by <driverName> and return statistics about
-    the driver in info. If no error occurred, the driver will remain open
-    and must be closed by the called by calling ASIOExit() - if an error
-    is returned the driver will already be closed.
-*/
-static PaError LoadAsioDriver( const char *driverName,
-        PaAsioDriverInfo *driverInfo, void *systemSpecific )
-{
-    PaError result = paNoError;
-    ASIOError asioError;
-    int asioIsInitialized = 0;
-
-    if( !loadAsioDriver( const_cast<char*>(driverName) ) )
-    {
-        result = paUnanticipatedHostError;
-        PA_ASIO_SET_LAST_HOST_ERROR( 0, "Failed to load ASIO driver" );
-        goto error;
-    }
-
-    memset( &driverInfo->asioDriverInfo, 0, sizeof(ASIODriverInfo) );
-    driverInfo->asioDriverInfo.asioVersion = 2;
-    driverInfo->asioDriverInfo.sysRef = systemSpecific;
-    if( (asioError = ASIOInit( &driverInfo->asioDriverInfo )) != ASE_OK )
-    {
-        result = paUnanticipatedHostError;
-        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-        goto error;
-    }
-    else
-    {
-        asioIsInitialized = 1;
-    }
-
-    if( (asioError = ASIOGetChannels(&driverInfo->inputChannelCount,
-            &driverInfo->outputChannelCount)) != ASE_OK )
-    {
-        result = paUnanticipatedHostError;
-        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-        goto error;
-    }
-
-    if( (asioError = ASIOGetBufferSize(&driverInfo->bufferMinSize,
-            &driverInfo->bufferMaxSize, &driverInfo->bufferPreferredSize,
-            &driverInfo->bufferGranularity)) != ASE_OK )
-    {
-        result = paUnanticipatedHostError;
-        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-        goto error;
-    }
-
-    if( ASIOOutputReady() == ASE_OK )
-        driverInfo->postOutput = true;
-    else
-        driverInfo->postOutput = false;
-
-    return result;
-
-error:
-    if( asioIsInitialized )
-        ASIOExit();
-
-    return result;
-}
-
-
-#define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_     13   /* must be the same number of elements as in the array below */
-static ASIOSampleRate defaultSampleRateSearchOrder_[]
-     = {44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0,
-        192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };
-
-
-PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
-{
-    PaError result = paNoError;
-    int i, driverCount;
-    PaAsioHostApiRepresentation *asioHostApi;
-    PaAsioDeviceInfo *deviceInfoArray;
-    char **names;
-    PaAsioDriverInfo paAsioDriverInfo;
-
-    asioHostApi = (PaAsioHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaAsioHostApiRepresentation) );
-    if( !asioHostApi )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    asioHostApi->allocations = PaUtil_CreateAllocationGroup();
-    if( !asioHostApi->allocations )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    asioHostApi->systemSpecific = 0;
-    asioHostApi->openAsioDeviceIndex = paNoDevice;
-
-    *hostApi = &asioHostApi->inheritedHostApiRep;
-    (*hostApi)->info.structVersion = 1;
-
-    (*hostApi)->info.type = paASIO;
-    (*hostApi)->info.name = "ASIO";
-    (*hostApi)->info.deviceCount = 0;
-
-    #ifdef WINDOWS
-        /* use desktop window as system specific ptr */
-        asioHostApi->systemSpecific = GetDesktopWindow();
-        CoInitialize(NULL);
-    #endif
-
-    /* MUST BE CHECKED : to force fragments loading on Mac */
-    loadAsioDriver( "dummy" ); 
-
-    /* driverCount is the number of installed drivers - not necessarily
-        the number of installed physical devices. */
-    #if MAC
-        driverCount = asioDrivers->getNumFragments();
-    #elif WINDOWS
-        driverCount = asioDrivers->asioGetNumDev();
-    #endif
-
-    if( driverCount > 0 )
-    {
-        names = GetAsioDriverNames( asioHostApi->allocations, driverCount );
-        if( !names )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-
-        /* allocate enough space for all drivers, even if some aren't installed */
-
-        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
-                asioHostApi->allocations, sizeof(PaDeviceInfo*) * driverCount );
-        if( !(*hostApi)->deviceInfos )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        /* allocate all device info structs in a contiguous block */
-        deviceInfoArray = (PaAsioDeviceInfo*)PaUtil_GroupAllocateMemory(
-                asioHostApi->allocations, sizeof(PaAsioDeviceInfo) * driverCount );
-        if( !deviceInfoArray )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        for( i=0; i < driverCount; ++i )
-        {
-
-            PA_DEBUG(("ASIO names[%d]:%s\n",i,names[i]));
-
-            // Since portaudio opens ALL ASIO drivers, and no one else does that,
-            // we face fact that some drivers were not meant for it, drivers which act
-            // like shells on top of REAL drivers, for instance.
-            // so we get duplicate handles, locks and other problems.
-            // so lets NOT try to load any such wrappers. 
-            // The ones i [davidv] know of so far are:
-
-            if (   strcmp (names[i],"ASIO DirectX Full Duplex Driver") == 0
-                || strcmp (names[i],"ASIO Multimedia Driver")          == 0
-                || strncmp(names[i],"Premiere",8)                      == 0   //"Premiere Elements Windows Sound 1.0"
-                || strncmp(names[i],"Adobe",5)                         == 0 ) //"Adobe Default Windows Sound 1.5"
-            {
-                PA_DEBUG(("BLACKLISTED!!!\n"));
-                continue;
-            }
-
-
-            /* Attempt to load the asio driver... */
-            if( LoadAsioDriver( names[i], &paAsioDriverInfo, asioHostApi->systemSpecific ) == paNoError )
-            {
-                PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
-                PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo;
-
-                deviceInfo->structVersion = 2;
-                deviceInfo->hostApi = hostApiIndex;
-
-                deviceInfo->name = names[i];
-                PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n",  i,deviceInfo->name));
-                PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels       = %d\n", i, paAsioDriverInfo.inputChannelCount));
-                PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels      = %d\n", i, paAsioDriverInfo.outputChannelCount));
-                PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize       = %d\n", i, paAsioDriverInfo.bufferMinSize));
-                PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize       = %d\n", i, paAsioDriverInfo.bufferMaxSize));
-                PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", i, paAsioDriverInfo.bufferPreferredSize));
-                PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity   = %d\n", i, paAsioDriverInfo.bufferGranularity));
-
-                deviceInfo->maxInputChannels  = paAsioDriverInfo.inputChannelCount;
-                deviceInfo->maxOutputChannels = paAsioDriverInfo.outputChannelCount;
-
-                deviceInfo->defaultSampleRate = 0.;
-                bool foundDefaultSampleRate = false;
-                for( int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j )
-                {
-                    ASIOError asioError = ASIOCanSampleRate( defaultSampleRateSearchOrder_[j] );
-                    if( asioError != ASE_NoClock && asioError != ASE_NotPresent )
-                    {
-                        deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[j];
-                        foundDefaultSampleRate = true;
-                        break;
-                    }
-                }
-
-                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", i, deviceInfo->defaultSampleRate));
-
-                if( foundDefaultSampleRate ){
-
-                    /* calculate default latency values from bufferPreferredSize
-                        for default low latency, and bufferPreferredSize * 3
-                        for default high latency.
-                        use the default sample rate to convert from samples to
-                        seconds. Without knowing what sample rate the user will
-                        use this is the best we can do.
-                    */
-
-                    double defaultLowLatency =
-                            paAsioDriverInfo.bufferPreferredSize / deviceInfo->defaultSampleRate;
-
-                    deviceInfo->defaultLowInputLatency = defaultLowLatency;
-                    deviceInfo->defaultLowOutputLatency = defaultLowLatency;
-
-                    long defaultHighLatencyBufferSize =
-                            paAsioDriverInfo.bufferPreferredSize * 3;
-
-                    if( defaultHighLatencyBufferSize > paAsioDriverInfo.bufferMaxSize )
-                        defaultHighLatencyBufferSize = paAsioDriverInfo.bufferMaxSize;
-
-                    double defaultHighLatency =
-                            defaultHighLatencyBufferSize / deviceInfo->defaultSampleRate;
-
-                    if( defaultHighLatency < defaultLowLatency )
-                        defaultHighLatency = defaultLowLatency; /* just incase the driver returns something strange */ 
-                            
-                    deviceInfo->defaultHighInputLatency = defaultHighLatency;
-                    deviceInfo->defaultHighOutputLatency = defaultHighLatency;
-                    
-                }else{
-
-                    deviceInfo->defaultLowInputLatency = 0.;
-                    deviceInfo->defaultLowOutputLatency = 0.;
-                    deviceInfo->defaultHighInputLatency = 0.;
-                    deviceInfo->defaultHighOutputLatency = 0.;
-                }
-
-                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowInputLatency = %f\n", i, deviceInfo->defaultLowInputLatency));
-                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowOutputLatency = %f\n", i, deviceInfo->defaultLowOutputLatency));
-                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighInputLatency = %f\n", i, deviceInfo->defaultHighInputLatency));
-                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighOutputLatency = %f\n", i, deviceInfo->defaultHighOutputLatency));
-
-                asioDeviceInfo->minBufferSize = paAsioDriverInfo.bufferMinSize;
-                asioDeviceInfo->maxBufferSize = paAsioDriverInfo.bufferMaxSize;
-                asioDeviceInfo->preferredBufferSize = paAsioDriverInfo.bufferPreferredSize;
-                asioDeviceInfo->bufferGranularity = paAsioDriverInfo.bufferGranularity;
-
-
-                asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*)PaUtil_GroupAllocateMemory(
-                        asioHostApi->allocations,
-                        sizeof(ASIOChannelInfo) * (deviceInfo->maxInputChannels
-                                + deviceInfo->maxOutputChannels) );
-                if( !asioDeviceInfo->asioChannelInfos )
-                {
-                    result = paInsufficientMemory;
-                    goto error;
-                }
-
-                int a;
-
-                for( a=0; a < deviceInfo->maxInputChannels; ++a ){
-                    asioDeviceInfo->asioChannelInfos[a].channel = a;
-                    asioDeviceInfo->asioChannelInfos[a].isInput = ASIOTrue;
-                    ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[a] );
-                    if( asioError != ASE_OK )
-                    {
-                        result = paUnanticipatedHostError;
-                        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-                        goto error;
-                    }
-                }
-
-                for( a=0; a < deviceInfo->maxOutputChannels; ++a ){
-                    int b = deviceInfo->maxInputChannels + a;
-                    asioDeviceInfo->asioChannelInfos[b].channel = a;
-                    asioDeviceInfo->asioChannelInfos[b].isInput = ASIOFalse;
-                    ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[b] );
-                    if( asioError != ASE_OK )
-                    {
-                        result = paUnanticipatedHostError;
-                        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-                        goto error;
-                    }
-                }
-
-
-                /* unload the driver */
-                ASIOExit();
-
-                (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
-                ++(*hostApi)->info.deviceCount;
-            }
-        }
-    }
-
-    if( (*hostApi)->info.deviceCount > 0 )
-    {
-        (*hostApi)->info.defaultInputDevice = 0;
-        (*hostApi)->info.defaultOutputDevice = 0;
-    }
-    else
-    {
-        (*hostApi)->info.defaultInputDevice = paNoDevice;
-        (*hostApi)->info.defaultOutputDevice = paNoDevice;
-    }
-
-
-    (*hostApi)->Terminate = Terminate;
-    (*hostApi)->OpenStream = OpenStream;
-    (*hostApi)->IsFormatSupported = IsFormatSupported;
-
-    PaUtil_InitializeStreamInterface( &asioHostApi->callbackStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, GetStreamCpuLoad,
-                                      PaUtil_DummyRead, PaUtil_DummyWrite,
-                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
-
-    PaUtil_InitializeStreamInterface( &asioHostApi->blockingStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
-                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
-
-    return result;
-
-error:
-    if( asioHostApi )
-    {
-        if( asioHostApi->allocations )
-        {
-            PaUtil_FreeAllAllocations( asioHostApi->allocations );
-            PaUtil_DestroyAllocationGroup( asioHostApi->allocations );
-        }
-
-        PaUtil_FreeMemory( asioHostApi );
-    }
-    return result;
-}
-
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
-{
-    PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
-
-    /*
-        IMPLEMENT ME:
-            - clean up any resources not handled by the allocation group
-    */
-
-    if( asioHostApi->allocations )
-    {
-        PaUtil_FreeAllAllocations( asioHostApi->allocations );
-        PaUtil_DestroyAllocationGroup( asioHostApi->allocations );
-    }
-
-    PaUtil_FreeMemory( asioHostApi );
-}
-
-
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate )
-{
-    PaError result = paNoError;
-    PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
-    PaAsioDriverInfo *driverInfo = &asioHostApi->openAsioDriverInfo;
-    int inputChannelCount, outputChannelCount;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    PaDeviceIndex asioDeviceIndex;                                  
-    ASIOError asioError;
-    
-    if( inputParameters && outputParameters )
-    {
-        /* full duplex ASIO stream must use the same device for input and output */
-
-        if( inputParameters->device != outputParameters->device )
-            return paBadIODeviceCombination;
-    }
-    
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-
-        /* all standard sample formats are supported by the buffer adapter,
-            this implementation doesn't support any custom sample formats */
-        if( inputSampleFormat & paCustomFormat )
-            return paSampleFormatNotSupported;
-            
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        asioDeviceIndex = inputParameters->device;
-
-        /* validate inputStreamInfo */
-        /** @todo do more validation here */
-        // if( inputParameters->hostApiSpecificStreamInfo )
-        //    return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        inputChannelCount = 0;
-    }
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-
-        /* all standard sample formats are supported by the buffer adapter,
-            this implementation doesn't support any custom sample formats */
-        if( outputSampleFormat & paCustomFormat )
-            return paSampleFormatNotSupported;
-            
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        asioDeviceIndex = outputParameters->device;
-
-        /* validate outputStreamInfo */
-        /** @todo do more validation here */
-        // if( outputParameters->hostApiSpecificStreamInfo )
-        //    return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        outputChannelCount = 0;
-    }
-
-
-
-    /* if an ASIO device is open we can only get format information for the currently open device */
-
-    if( asioHostApi->openAsioDeviceIndex != paNoDevice 
-			&& asioHostApi->openAsioDeviceIndex != asioDeviceIndex )
-    {
-        return paDeviceUnavailable;
-    }
-
-
-    /* NOTE: we load the driver and use its current settings
-        rather than the ones in our device info structure which may be stale */
-
-    /* open the device if it's not already open */
-    if( asioHostApi->openAsioDeviceIndex == paNoDevice )
-    {
-        result = LoadAsioDriver( asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name,
-                driverInfo, asioHostApi->systemSpecific );
-        if( result != paNoError )
-            return result;
-    }
-
-    /* check that input device can support inputChannelCount */
-    if( inputChannelCount > 0 )
-    {
-        if( inputChannelCount > driverInfo->inputChannelCount )
-        {
-            result = paInvalidChannelCount;
-            goto done;
-        }
-    }
-
-    /* check that output device can support outputChannelCount */
-    if( outputChannelCount )
-    {
-        if( outputChannelCount > driverInfo->outputChannelCount )
-        {
-            result = paInvalidChannelCount;
-            goto done;
-        }
-    }
-    
-    /* query for sample rate support */
-    asioError = ASIOCanSampleRate( sampleRate );
-    if( asioError == ASE_NoClock || asioError == ASE_NotPresent )
-    {
-        result = paInvalidSampleRate;
-        goto done;
-    }
-
-done:
-    /* close the device if it wasn't already open */
-    if( asioHostApi->openAsioDeviceIndex == paNoDevice )
-    {
-        ASIOExit(); /* not sure if we should check for errors here */
-    }
-
-    if( result == paNoError )
-        return paFormatIsSupported;
-    else
-        return result;
-}
-
-
-
-/* PaAsioStream - a stream data structure specifically for this implementation */
-
-typedef struct PaAsioStream
-{
-    PaUtilStreamRepresentation streamRepresentation;
-    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
-    PaUtilBufferProcessor bufferProcessor;
-
-    PaAsioHostApiRepresentation *asioHostApi;
-    unsigned long framesPerHostCallback;
-
-    /* ASIO driver info  - these may not be needed for the life of the stream,
-        but store them here until we work out how format conversion is going
-        to work. */
-
-    ASIOBufferInfo *asioBufferInfos;
-    ASIOChannelInfo *asioChannelInfos;
-    long inputLatency, outputLatency; // actual latencies returned by asio
-
-    long inputChannelCount, outputChannelCount;
-    bool postOutput;
-
-    void **bufferPtrs; /* this is carved up for inputBufferPtrs and outputBufferPtrs */
-    void **inputBufferPtrs[2];
-    void **outputBufferPtrs[2];
-
-    PaAsioBufferConverter *inputBufferConverter;
-    long inputShift;
-    PaAsioBufferConverter *outputBufferConverter;
-    long outputShift;
-
-    volatile bool stopProcessing;
-    int stopPlayoutCount;
-    HANDLE completedBuffersPlayedEvent;
-
-    bool streamFinishedCallbackCalled;
-    volatile int isActive;
-    volatile bool zeroOutput; /* all future calls to the callback will output silence */
-
-    volatile long reenterCount;
-    volatile long reenterError;
-
-    PaStreamCallbackFlags callbackFlags;
-}
-PaAsioStream;
-
-static PaAsioStream *theAsioStream = 0; /* due to ASIO sdk limitations there can be only one stream */
-
-
-static void ZeroOutputBuffers( PaAsioStream *stream, long index )
-{
-    int i;
-
-    for( i=0; i < stream->outputChannelCount; ++i )
-    {
-        void *buffer = stream->asioBufferInfos[ i + stream->inputChannelCount ].buffers[index];
-
-        int bytesPerSample = BytesPerAsioSample( stream->asioChannelInfos[ i + stream->inputChannelCount ].type );
-
-        memset( buffer, 0, stream->framesPerHostCallback * bytesPerSample );
-    }
-}
-
-
-static unsigned long SelectHostBufferSize( unsigned long suggestedLatencyFrames,
-        PaAsioDriverInfo *driverInfo )
-{
-    unsigned long result;
-
-    if( suggestedLatencyFrames == 0 )
-    {
-        result = driverInfo->bufferPreferredSize;
-    }
-    else{
-        if( suggestedLatencyFrames <= (unsigned long)driverInfo->bufferMinSize )
-        {
-            result = driverInfo->bufferMinSize;
-        }
-        else if( suggestedLatencyFrames >= (unsigned long)driverInfo->bufferMaxSize )
-        {
-            result = driverInfo->bufferMaxSize;
-        }
-        else
-        {
-            if( driverInfo->bufferGranularity == -1 )
-            {
-                /* power-of-two */
-                result = 2;
-
-                while( result < suggestedLatencyFrames )
-                    result *= 2;
-
-                if( result < (unsigned long)driverInfo->bufferMinSize )
-                    result = driverInfo->bufferMinSize;
-
-                if( result > (unsigned long)driverInfo->bufferMaxSize )
-                    result = driverInfo->bufferMaxSize;
-            }
-            else if( driverInfo->bufferGranularity == 0 )
-            {
-                /* the documentation states that bufferGranularity should be
-                    zero when bufferMinSize, bufferMaxSize and
-                    bufferPreferredSize are the same. We assume that is the case.
-                */
-
-                result = driverInfo->bufferPreferredSize;
-            }
-            else
-            {
-                /* modulo granularity */
-
-                unsigned long remainder =
-                        suggestedLatencyFrames % driverInfo->bufferGranularity;
-
-                if( remainder == 0 )
-                {
-                    result = suggestedLatencyFrames;
-                }
-                else
-                {
-                    result = suggestedLatencyFrames
-                            + (driverInfo->bufferGranularity - remainder);
-
-                    if( result > (unsigned long)driverInfo->bufferMaxSize )
-                        result = driverInfo->bufferMaxSize;
-                }
-            }
-        }
-    }
-
-    return result;
-}
-
-
-/* returns channelSelectors if present */
-
-static PaError ValidateAsioSpecificStreamInfo(
-        const PaStreamParameters *streamParameters,
-        const PaAsioStreamInfo *streamInfo,
-        int deviceChannelCount,
-        int **channelSelectors )
-{
-	if( streamInfo )
-	{
-	    if( streamInfo->size != sizeof( PaAsioStreamInfo )
-	            || streamInfo->version != 1 )
-	    {
-	        return paIncompatibleHostApiSpecificStreamInfo;
-	    }
-
-	    if( streamInfo->flags & paAsioUseChannelSelectors )
-            *channelSelectors = streamInfo->channelSelectors;
-
-        if( !(*channelSelectors) )
-            return paIncompatibleHostApiSpecificStreamInfo;
-
-        for( int i=0; i < streamParameters->channelCount; ++i ){
-             if( (*channelSelectors)[i] < 0
-                    || (*channelSelectors)[i] >= deviceChannelCount ){
-                return paInvalidChannelCount;
-             }           
-        }
-	}
-
-	return paNoError;
-}
-
-
-/* see pa_hostapi.h for a list of validity guarantees made about OpenStream  parameters */
-
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData )
-{
-    PaError result = paNoError;
-    PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
-    PaAsioStream *stream = 0;
-    PaAsioStreamInfo *inputStreamInfo, *outputStreamInfo;
-    unsigned long framesPerHostBuffer;
-    int inputChannelCount, outputChannelCount;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
-    unsigned long suggestedInputLatencyFrames;
-    unsigned long suggestedOutputLatencyFrames;
-    PaDeviceIndex asioDeviceIndex;
-    ASIOError asioError;
-    int asioIsInitialized = 0;
-    int asioBuffersCreated = 0;
-    int completedBuffersPlayedEventInited = 0;
-    int i;
-    PaAsioDriverInfo *driverInfo;
-    int *inputChannelSelectors = 0;
-    int *outputChannelSelectors = 0;
-
-    /* unless we move to using lower level ASIO calls, we can only have
-        one device open at a time */
-    if( asioHostApi->openAsioDeviceIndex != paNoDevice ){
-        PA_DEBUG(("OpenStream paDeviceUnavailable\n"));
-        return paDeviceUnavailable;
-    }
-
-    if( inputParameters && outputParameters )
-    {
-        /* full duplex ASIO stream must use the same device for input and output */
-
-        if( inputParameters->device != outputParameters->device ){
-            PA_DEBUG(("OpenStream paBadIODeviceCombination\n"));
-            return paBadIODeviceCombination;
-    }
-    }
-
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-        suggestedInputLatencyFrames = (unsigned long)((inputParameters->suggestedLatency * sampleRate)+0.5f);
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        asioDeviceIndex = inputParameters->device;
-
-        PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[asioDeviceIndex];
-
-        /* validate hostApiSpecificStreamInfo */
-        inputStreamInfo = (PaAsioStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
-        result = ValidateAsioSpecificStreamInfo( inputParameters, inputStreamInfo,
-            asioDeviceInfo->commonDeviceInfo.maxInputChannels,
-            &inputChannelSelectors
-        );
-        if( result != paNoError ) return result;
-    }
-    else
-    {
-        inputChannelCount = 0;
-        inputSampleFormat = 0;
-        suggestedInputLatencyFrames = 0;
-    }
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-        suggestedOutputLatencyFrames = (unsigned long)((outputParameters->suggestedLatency * sampleRate)+0.5f);
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        asioDeviceIndex = outputParameters->device;
-
-        PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[asioDeviceIndex];
-
-        /* validate hostApiSpecificStreamInfo */
-        outputStreamInfo = (PaAsioStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
-        result = ValidateAsioSpecificStreamInfo( outputParameters, outputStreamInfo,
-            asioDeviceInfo->commonDeviceInfo.maxOutputChannels,
-            &outputChannelSelectors
-        );
-        if( result != paNoError ) return result;
-    }
-    else
-    {
-        outputChannelCount = 0;
-        outputSampleFormat = 0;
-        suggestedOutputLatencyFrames = 0;
-    }
-
-    driverInfo = &asioHostApi->openAsioDriverInfo;
-
-    /* NOTE: we load the driver and use its current settings
-        rather than the ones in our device info structure which may be stale */
-
-    result = LoadAsioDriver( asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name,
-            driverInfo, asioHostApi->systemSpecific );
-    if( result == paNoError )
-        asioIsInitialized = 1;
-    else{
-        PA_DEBUG(("OpenStream ERROR1\n"));
-        goto error;
-    }
-
-    /* check that input device can support inputChannelCount */
-    if( inputChannelCount > 0 )
-    {
-        if( inputChannelCount > driverInfo->inputChannelCount )
-        {
-            result = paInvalidChannelCount;
-            PA_DEBUG(("OpenStream ERROR2\n"));
-            goto error;
-        }
-    }
-
-    /* check that output device can support outputChannelCount */
-    if( outputChannelCount )
-    {
-        if( outputChannelCount > driverInfo->outputChannelCount )
-        {
-            result = paInvalidChannelCount;
-            PA_DEBUG(("OpenStream ERROR3\n"));
-            goto error;
-        }
-    }
-
-
-    // check that the device supports the requested sample rate 
-
-    asioError = ASIOCanSampleRate( sampleRate );
-    PA_DEBUG(("ASIOCanSampleRate(%f):%d\n",sampleRate, asioError ));
-
-    if( asioError != ASE_OK )
-    {
-        result = paInvalidSampleRate;
-        PA_DEBUG(("ERROR: ASIOCanSampleRate: %s\n", PaAsio_GetAsioErrorText(asioError) ));
-        goto error;
-    }
-
-
-    // retrieve the current sample rate, we only change to the requested
-    // sample rate if the device is not already in that rate.
-
-    ASIOSampleRate oldRate;
-    asioError = ASIOGetSampleRate(&oldRate);
-    if( asioError != ASE_OK )
-    {
-        result = paInvalidSampleRate;
-        PA_DEBUG(("ERROR: ASIOGetSampleRate: %s\n", PaAsio_GetAsioErrorText(asioError) ));
-        goto error;
-    }
-    PA_DEBUG(("ASIOGetSampleRate:%f\n",oldRate));
-
-    if (oldRate != sampleRate){
-
-        PA_DEBUG(("before ASIOSetSampleRate(%f)\n",sampleRate));
-        asioError = ASIOSetSampleRate( sampleRate );
-        /* Set sample rate */
-        if( asioError != ASE_OK )
-        {
-            result = paInvalidSampleRate;
-            PA_DEBUG(("ERROR: ASIOSetSampleRate: %s\n", PaAsio_GetAsioErrorText(asioError) ));
-            goto error;
-        }
-        PA_DEBUG(("after ASIOSetSampleRate(%f)\n",sampleRate));
-    }
-    else
-    {
-        PA_DEBUG(("No Need to change SR\n"));
-    }
-
-
-    /*
-        IMPLEMENT ME:
-            - if a full duplex stream is requested, check that the combination
-                of input and output parameters is supported
-    */
-
-    /* validate platform specific flags */
-    if( (streamFlags & paPlatformSpecificFlags) != 0 ){
-        PA_DEBUG(("OpenStream invalid flags!!\n"));
-        return paInvalidFlag; /* unexpected platform specific flag */
-    }
-
-
-    stream = (PaAsioStream*)PaUtil_AllocateMemory( sizeof(PaAsioStream) );
-    if( !stream )
-    {
-        result = paInsufficientMemory;
-        PA_DEBUG(("OpenStream ERROR5\n"));
-        goto error;
-    }
-
-    stream->completedBuffersPlayedEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
-    if( stream->completedBuffersPlayedEvent == NULL )
-    {
-        result = paUnanticipatedHostError;
-        PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
-        PA_DEBUG(("OpenStream ERROR6\n"));
-        goto error;
-    }
-    completedBuffersPlayedEventInited = 1;
-
-
-    stream->asioBufferInfos = 0; /* for deallocation in error */
-    stream->asioChannelInfos = 0; /* for deallocation in error */
-    stream->bufferPtrs = 0; /* for deallocation in error */
-
-    if( streamCallback )
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &asioHostApi->callbackStreamInterface, streamCallback, userData );
-    }
-    else
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &asioHostApi->blockingStreamInterface, streamCallback, userData );
-    }
-
-
-    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
-
-
-    stream->asioBufferInfos = (ASIOBufferInfo*)PaUtil_AllocateMemory(
-            sizeof(ASIOBufferInfo) * (inputChannelCount + outputChannelCount) );
-    if( !stream->asioBufferInfos )
-    {
-        result = paInsufficientMemory;
-        PA_DEBUG(("OpenStream ERROR7\n"));
-        goto error;
-    }
-
-
-    for( i=0; i < inputChannelCount; ++i )
-    {
-        ASIOBufferInfo *info = &stream->asioBufferInfos[i];
-
-        info->isInput = ASIOTrue;
-
-        if( inputChannelSelectors ){
-            // inputChannelSelectors values have already been validated in
-            // ValidateAsioSpecificStreamInfo() above
-            info->channelNum = inputChannelSelectors[i];
-        }else{
-            info->channelNum = i;
-        }
-
-        info->buffers[0] = info->buffers[1] = 0;
-    }
-
-    for( i=0; i < outputChannelCount; ++i ){
-        ASIOBufferInfo *info = &stream->asioBufferInfos[inputChannelCount+i];
-
-        info->isInput = ASIOFalse;
-
-        if( outputChannelSelectors ){
-            // outputChannelSelectors values have already been validated in
-            // ValidateAsioSpecificStreamInfo() above
-            info->channelNum = outputChannelSelectors[i];
-        }else{
-            info->channelNum = i;
-        }
-        
-        info->buffers[0] = info->buffers[1] = 0;
-    }
-
-
-    framesPerHostBuffer = SelectHostBufferSize(
-            (( suggestedInputLatencyFrames > suggestedOutputLatencyFrames )
-                    ? suggestedInputLatencyFrames : suggestedOutputLatencyFrames),
-            driverInfo );
-
-
-	PA_DEBUG(("PaAsioOpenStream: framesPerHostBuffer :%d\n",  framesPerHostBuffer));
-
-    asioError = ASIOCreateBuffers( stream->asioBufferInfos,
-            inputChannelCount+outputChannelCount,
-            framesPerHostBuffer, &asioCallbacks_ );
-
-    if( asioError != ASE_OK
-            && framesPerHostBuffer != (unsigned long)driverInfo->bufferPreferredSize )
-    {
-        PA_DEBUG(("ERROR: ASIOCreateBuffers: %s\n", PaAsio_GetAsioErrorText(asioError) ));
-        /*
-            Some buggy drivers (like the Hoontech DSP24) give incorrect
-            [min, preferred, max] values They should work with the preferred size
-            value, thus if Pa_ASIO_CreateBuffers fails with the hostBufferSize
-            computed in SelectHostBufferSize, we try again with the preferred size.
-        */
-
-        framesPerHostBuffer = driverInfo->bufferPreferredSize;
-
-        PA_DEBUG(("PaAsioOpenStream: CORRECTED framesPerHostBuffer :%d\n",  framesPerHostBuffer));
-
-        ASIOError asioError2 = ASIOCreateBuffers( stream->asioBufferInfos,
-                inputChannelCount+outputChannelCount,
-                 framesPerHostBuffer, &asioCallbacks_ );
-        if( asioError2 == ASE_OK )
-            asioError = ASE_OK;
-    }
-
-    if( asioError != ASE_OK )
-    {
-        result = paUnanticipatedHostError;
-        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-        PA_DEBUG(("OpenStream ERROR9\n"));
-        goto error;
-    }
-
-    asioBuffersCreated = 1;
-
-    stream->asioChannelInfos = (ASIOChannelInfo*)PaUtil_AllocateMemory(
-            sizeof(ASIOChannelInfo) * (inputChannelCount + outputChannelCount) );
-    if( !stream->asioChannelInfos )
-    {
-        result = paInsufficientMemory;
-        PA_DEBUG(("OpenStream ERROR10\n"));
-        goto error;
-    }
-
-    for( i=0; i < inputChannelCount + outputChannelCount; ++i )
-    {
-        stream->asioChannelInfos[i].channel = stream->asioBufferInfos[i].channelNum;
-        stream->asioChannelInfos[i].isInput = stream->asioBufferInfos[i].isInput;
-        asioError = ASIOGetChannelInfo( &stream->asioChannelInfos[i] );
-        if( asioError != ASE_OK )
-        {
-            result = paUnanticipatedHostError;
-            PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-            PA_DEBUG(("OpenStream ERROR11\n"));
-            goto error;
-        }
-    }
-
-    stream->bufferPtrs = (void**)PaUtil_AllocateMemory(
-            2 * sizeof(void*) * (inputChannelCount + outputChannelCount) );
-    if( !stream->bufferPtrs )
-    {
-        result = paInsufficientMemory;
-        PA_DEBUG(("OpenStream ERROR12\n"));
-        goto error;
-    }
-
-    if( inputChannelCount > 0 )
-    {
-        stream->inputBufferPtrs[0] = stream-> bufferPtrs;
-        stream->inputBufferPtrs[1] = &stream->bufferPtrs[inputChannelCount];
-
-        for( i=0; i<inputChannelCount; ++i )
-        {
-            stream->inputBufferPtrs[0][i] = stream->asioBufferInfos[i].buffers[0];
-            stream->inputBufferPtrs[1][i] = stream->asioBufferInfos[i].buffers[1];
-        }
-    }
-    else
-    {
-        stream->inputBufferPtrs[0] = 0;
-        stream->inputBufferPtrs[1] = 0;
-    }
-
-    if( outputChannelCount > 0 )
-    {
-        stream->outputBufferPtrs[0] = &stream->bufferPtrs[inputChannelCount*2];
-        stream->outputBufferPtrs[1] = &stream->bufferPtrs[inputChannelCount*2 + outputChannelCount];
-
-        for( i=0; i<outputChannelCount; ++i )
-        {
-            stream->outputBufferPtrs[0][i] = stream->asioBufferInfos[inputChannelCount+i].buffers[0];
-            stream->outputBufferPtrs[1][i] = stream->asioBufferInfos[inputChannelCount+i].buffers[1];
-        }
-    }
-    else
-    {
-        stream->outputBufferPtrs[0] = 0;
-        stream->outputBufferPtrs[1] = 0;
-    }
-
-    if( inputChannelCount > 0 )
-    {
-        /* FIXME: assume all channels use the same type for now */
-        ASIOSampleType inputType = stream->asioChannelInfos[0].type;
-
-        PA_DEBUG(("ASIO Input  type:%d",inputType));
-        AsioSampleTypeLOG(inputType);
-        hostInputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( inputType );
-
-        SelectAsioToPaConverter( inputType, &stream->inputBufferConverter, &stream->inputShift );
-    }
-    else
-    {
-        hostInputSampleFormat = 0;
-        stream->inputBufferConverter = 0;
-    }
-
-    if( outputChannelCount > 0 )
-    {
-        /* FIXME: assume all channels use the same type for now */
-        ASIOSampleType outputType = stream->asioChannelInfos[inputChannelCount].type;
-
-        PA_DEBUG(("ASIO Output type:%d",outputType));
-        AsioSampleTypeLOG(outputType);
-        hostOutputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( outputType );
-
-        SelectPaToAsioConverter( outputType, &stream->outputBufferConverter, &stream->outputShift );
-    }
-    else
-    {
-        hostOutputSampleFormat = 0;
-        stream->outputBufferConverter = 0;
-    }
-
-    result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
-                    inputChannelCount, inputSampleFormat, hostInputSampleFormat,
-                    outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
-                    sampleRate, streamFlags, framesPerBuffer,
-                    framesPerHostBuffer, paUtilFixedHostBufferSize,
-                    streamCallback, userData );
-    if( result != paNoError ){
-        PA_DEBUG(("OpenStream ERROR13\n"));
-        goto error;
-    }
-
-
-    ASIOGetLatencies( &stream->inputLatency, &stream->outputLatency );
-
-    stream->streamRepresentation.streamInfo.inputLatency =
-            (double)( PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)
-                + stream->inputLatency) / sampleRate;   // seconds
-    stream->streamRepresentation.streamInfo.outputLatency =
-            (double)( PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)
-                + stream->outputLatency) / sampleRate; // seconds
-    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
-
-    // the code below prints the ASIO latency which doesn't include the
-    // buffer processor latency. it reports the added latency separately
-    PA_DEBUG(("PaAsio : ASIO InputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n",
-            stream->inputLatency,
-            (long)((stream->inputLatency*1000)/ sampleRate),  
-            PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor),
-            (long)((PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)*1000)/ sampleRate)
-            ));
-
-    PA_DEBUG(("PaAsio : ASIO OuputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n",
-            stream->outputLatency,
-            (long)((stream->outputLatency*1000)/ sampleRate), 
-            PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor),
-            (long)((PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)*1000)/ sampleRate)
-            ));
-
-    stream->asioHostApi = asioHostApi;
-    stream->framesPerHostCallback = framesPerHostBuffer;
-
-    stream->inputChannelCount = inputChannelCount;
-    stream->outputChannelCount = outputChannelCount;
-    stream->postOutput = driverInfo->postOutput;
-    stream->isActive = 0;
-
-    asioHostApi->openAsioDeviceIndex = asioDeviceIndex;
-
-    *s = (PaStream*)stream;
-
-    return result;
-
-error:
-    PA_DEBUG(("goto errored\n"));
-    if( stream )
-    {
-        if( completedBuffersPlayedEventInited )
-            CloseHandle( stream->completedBuffersPlayedEvent );
-
-        if( stream->asioBufferInfos )
-            PaUtil_FreeMemory( stream->asioBufferInfos );
-
-        if( stream->asioChannelInfos )
-            PaUtil_FreeMemory( stream->asioChannelInfos );
-
-        if( stream->bufferPtrs )
-            PaUtil_FreeMemory( stream->bufferPtrs );
-
-        PaUtil_FreeMemory( stream );
-    }
-
-    if( asioBuffersCreated )
-        ASIODisposeBuffers();
-
-    if( asioIsInitialized )
-        ASIOExit();
-
-    return result;
-}
-
-
-/*
-    When CloseStream() is called, the multi-api layer ensures that
-    the stream has already been stopped or aborted.
-*/
-static PaError CloseStream( PaStream* s )
-{
-    PaError result = paNoError;
-    PaAsioStream *stream = (PaAsioStream*)s;
-
-    /*
-        IMPLEMENT ME:
-            - additional stream closing + cleanup
-    */
-
-    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
-    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
-
-    stream->asioHostApi->openAsioDeviceIndex = paNoDevice;
-
-    CloseHandle( stream->completedBuffersPlayedEvent );
-
-    PaUtil_FreeMemory( stream->asioBufferInfos );
-    PaUtil_FreeMemory( stream->asioChannelInfos );
-    PaUtil_FreeMemory( stream->bufferPtrs );
-    PaUtil_FreeMemory( stream );
-
-    ASIODisposeBuffers();
-    ASIOExit();
-
-    return result;
-}
-
-
-static void bufferSwitch(long index, ASIOBool directProcess)
-{
-//TAKEN FROM THE ASIO SDK
-
-    // 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.
-
-    // as this is a "back door" into the bufferSwitchTimeInfo a timeInfo needs
-    // to be created though it will only set the timeInfo.samplePosition and
-    // timeInfo.systemTime fields and the according flags
-
-    ASIOTime  timeInfo;
-    memset( &timeInfo, 0, sizeof (timeInfo) );
-
-    // get the time stamp of the buffer, not necessary if no
-    // synchronization to other media is required
-    if( ASIOGetSamplePosition(&timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime) == ASE_OK)
-            timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid;
-
-    // Call the real callback
-    bufferSwitchTimeInfo( &timeInfo, index, directProcess );
-}
-
-
-// conversion from 64 bit ASIOSample/ASIOTimeStamp to double float
-#if NATIVE_INT64
-	#define ASIO64toDouble(a)  (a)
-#else
-	const double twoRaisedTo32 = 4294967296.;
-	#define ASIO64toDouble(a)  ((a).lo + (a).hi * twoRaisedTo32)
-#endif
-
-static ASIOTime *bufferSwitchTimeInfo( ASIOTime *timeInfo, long index, ASIOBool directProcess )
-{
-    // the actual processing callback.
-    // Beware that this is normally in a seperate thread, hence be sure that
-    // you take care about thread synchronization.
-
-
-    /* The SDK says the following about the directProcess flag:
-        suggests to the host whether it should immediately start processing
-        (directProcess == ASIOTrue), or whether its process should be deferred
-        because the call comes from a very low level (for instance, a high level
-        priority interrupt), and direct processing would cause timing instabilities for
-        the rest of the system. If in doubt, directProcess should be set to ASIOFalse.
-
-        We just ignore directProcess. This could cause incompatibilities with
-        drivers which really don't want the audio processing to occur in this
-        callback, but none have been identified yet.
-    */
-
-    (void) directProcess; /* suppress unused parameter warning */
-
-#if 0
-    // store the timeInfo for later use
-    asioDriverInfo.tInfo = *timeInfo;
-
-    // get the time stamp of the buffer, not necessary if no
-    // synchronization to other media is required
-
-    if (timeInfo->timeInfo.flags & kSystemTimeValid)
-            asioDriverInfo.nanoSeconds = ASIO64toDouble(timeInfo->timeInfo.systemTime);
-    else
-            asioDriverInfo.nanoSeconds = 0;
-
-    if (timeInfo->timeInfo.flags & kSamplePositionValid)
-            asioDriverInfo.samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition);
-    else
-            asioDriverInfo.samples = 0;
-
-    if (timeInfo->timeCode.flags & kTcValid)
-            asioDriverInfo.tcSamples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples);
-    else
-            asioDriverInfo.tcSamples = 0;
-
-    // get the system reference time
-    asioDriverInfo.sysRefTime = get_sys_reference_time();
-#endif
-
-#if 0
-    // a few debug messages for the Windows device driver developer
-    // tells you the time when driver got its interrupt and the delay until the app receives
-    // the event notification.
-    static double last_samples = 0;
-    char tmp[128];
-    sprintf (tmp, "diff: %d / %d ms / %d ms / %d samples                 \n", asioDriverInfo.sysRefTime - (long)(asioDriverInfo.nanoSeconds / 1000000.0), asioDriverInfo.sysRefTime, (long)(asioDriverInfo.nanoSeconds / 1000000.0), (long)(asioDriverInfo.samples - last_samples));
-    OutputDebugString (tmp);
-    last_samples = asioDriverInfo.samples;
-#endif
-
-
-    if( !theAsioStream )
-        return 0L;
-
-    // Keep sample position
-    // FIXME: asioDriverInfo.pahsc_NumFramesDone = timeInfo->timeInfo.samplePosition.lo;
-
-
-    // protect against reentrancy
-    if( PaAsio_AtomicIncrement(&theAsioStream->reenterCount) )
-    {
-        theAsioStream->reenterError++;
-        //DBUG(("bufferSwitchTimeInfo : reentrancy detection = %d\n", asioDriverInfo.reenterError));
-        return 0L;
-    }
-
-    int buffersDone = 0;
-    
-    do
-    {
-        if( buffersDone > 0 )
-        {
-            // this is a reentered buffer, we missed processing it on time
-            // set the input overflow and output underflow flags as appropriate
-            
-            if( theAsioStream->inputChannelCount > 0 )
-                theAsioStream->callbackFlags |= paInputOverflow;
-                
-            if( theAsioStream->outputChannelCount > 0 )
-                theAsioStream->callbackFlags |= paOutputUnderflow;
-        }
-        else
-        {
-            if( theAsioStream->zeroOutput )
-            {
-                ZeroOutputBuffers( theAsioStream, index );
-
-                // Finally if the driver supports the ASIOOutputReady() optimization,
-                // do it here, all data are in place
-                if( theAsioStream->postOutput )
-                    ASIOOutputReady();
-
-                if( theAsioStream->stopProcessing )
-                {
-                    if( theAsioStream->stopPlayoutCount < 2 )
-                    {
-                        ++theAsioStream->stopPlayoutCount;
-                        if( theAsioStream->stopPlayoutCount == 2 )
-                        {
-                            theAsioStream->isActive = 0;
-                            if( theAsioStream->streamRepresentation.streamFinishedCallback != 0 )
-                                theAsioStream->streamRepresentation.streamFinishedCallback( theAsioStream->streamRepresentation.userData );
-                            theAsioStream->streamFinishedCallbackCalled = true;
-                            SetEvent( theAsioStream->completedBuffersPlayedEvent );
-                        }
-                    }
-                }
-            }
-            else
-            {
-
-#if 0
-// test code to try to detect slip conditions... these may work on some systems
-// but neither of them work on the RME Digi96
-
-// check that sample delta matches buffer size (otherwise we must have skipped
-// a buffer.
-static double last_samples = -512;
-double samples;
-//if( timeInfo->timeCode.flags & kTcValid )
-//    samples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples);
-//else
-    samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition);
-int delta = samples - last_samples;
-//printf( "%d\n", delta);
-last_samples = samples;
-
-if( delta > theAsioStream->framesPerHostCallback )
-{
-    if( theAsioStream->inputChannelCount > 0 )
-        theAsioStream->callbackFlags |= paInputOverflow;
-
-    if( theAsioStream->outputChannelCount > 0 )
-        theAsioStream->callbackFlags |= paOutputUnderflow;
-}
-
-// check that the buffer index is not the previous index (which would indicate
-// that a buffer was skipped.
-static int previousIndex = 1;
-if( index == previousIndex )
-{
-    if( theAsioStream->inputChannelCount > 0 )
-        theAsioStream->callbackFlags |= paInputOverflow;
-
-    if( theAsioStream->outputChannelCount > 0 )
-        theAsioStream->callbackFlags |= paOutputUnderflow;
-}
-previousIndex = index;
-#endif
-
-                int i;
-
-                PaUtil_BeginCpuLoadMeasurement( &theAsioStream->cpuLoadMeasurer );
-
-                PaStreamCallbackTimeInfo paTimeInfo;
-
-                // asio systemTime is supposed to be measured according to the same
-                // clock as timeGetTime
-                paTimeInfo.currentTime = (ASIO64toDouble( timeInfo->timeInfo.systemTime ) * .000000001);
-
-                /* patch from Paul Boege */
-                paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime -
-                    ((double)theAsioStream->inputLatency/theAsioStream->streamRepresentation.streamInfo.sampleRate);
-
-                paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime +
-                    ((double)theAsioStream->outputLatency/theAsioStream->streamRepresentation.streamInfo.sampleRate);
-
-                /* old version is buggy because the buffer processor also adds in its latency to the time parameters
-                paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime - theAsioStream->streamRepresentation.streamInfo.inputLatency;
-                paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + theAsioStream->streamRepresentation.streamInfo.outputLatency;
-                */
-#if 1
-// detect underflows by checking inter-callback time > 2 buffer period
-static double previousTime = -1;
-if( previousTime > 0 ){
-
-    double delta = paTimeInfo.currentTime - previousTime;
-
-    if( delta >= 2. * (theAsioStream->framesPerHostCallback / theAsioStream->streamRepresentation.streamInfo.sampleRate) ){
-        if( theAsioStream->inputChannelCount > 0 )
-            theAsioStream->callbackFlags |= paInputOverflow;
-
-        if( theAsioStream->outputChannelCount > 0 )
-            theAsioStream->callbackFlags |= paOutputUnderflow;
-    }
-}
-previousTime = paTimeInfo.currentTime;
-#endif
-
-                // note that the above input and output times do not need to be
-                // adjusted for the latency of the buffer processor -- the buffer
-                // processor handles that.
-
-                if( theAsioStream->inputBufferConverter )
-                {
-                    for( i=0; i<theAsioStream->inputChannelCount; i++ )
-                    {
-                        theAsioStream->inputBufferConverter( theAsioStream->inputBufferPtrs[index][i],
-                                theAsioStream->inputShift, theAsioStream->framesPerHostCallback );
-                    }
-                }
-
-                PaUtil_BeginBufferProcessing( &theAsioStream->bufferProcessor, &paTimeInfo, theAsioStream->callbackFlags );
-
-                /* reset status flags once they've been passed to the callback */
-                theAsioStream->callbackFlags = 0;
-
-                PaUtil_SetInputFrameCount( &theAsioStream->bufferProcessor, 0 /* default to host buffer size */ );
-                for( i=0; i<theAsioStream->inputChannelCount; ++i )
-                    PaUtil_SetNonInterleavedInputChannel( &theAsioStream->bufferProcessor, i, theAsioStream->inputBufferPtrs[index][i] );
-
-                PaUtil_SetOutputFrameCount( &theAsioStream->bufferProcessor, 0 /* default to host buffer size */ );
-                for( i=0; i<theAsioStream->outputChannelCount; ++i )
-                    PaUtil_SetNonInterleavedOutputChannel( &theAsioStream->bufferProcessor, i, theAsioStream->outputBufferPtrs[index][i] );
-
-                int callbackResult;
-                if( theAsioStream->stopProcessing )
-                    callbackResult = paComplete;
-                else
-                    callbackResult = paContinue;
-                unsigned long framesProcessed = PaUtil_EndBufferProcessing( &theAsioStream->bufferProcessor, &callbackResult );
-
-                if( theAsioStream->outputBufferConverter )
-                {
-                    for( i=0; i<theAsioStream->outputChannelCount; i++ )
-                    {
-                        theAsioStream->outputBufferConverter( theAsioStream->outputBufferPtrs[index][i],
-                                theAsioStream->outputShift, theAsioStream->framesPerHostCallback );
-                    }
-                }
-
-                PaUtil_EndCpuLoadMeasurement( &theAsioStream->cpuLoadMeasurer, framesProcessed );
-
-                // Finally if the driver supports the ASIOOutputReady() optimization,
-                // do it here, all data are in place
-                if( theAsioStream->postOutput )
-                    ASIOOutputReady();
-
-                if( callbackResult == paContinue )
-                {
-                    /* nothing special to do */
-                }
-                else if( callbackResult == paAbort )
-                {
-                    /* finish playback immediately  */
-                    theAsioStream->isActive = 0;
-                    if( theAsioStream->streamRepresentation.streamFinishedCallback != 0 )
-                        theAsioStream->streamRepresentation.streamFinishedCallback( theAsioStream->streamRepresentation.userData );
-                    theAsioStream->streamFinishedCallbackCalled = true;
-                    SetEvent( theAsioStream->completedBuffersPlayedEvent );
-                    theAsioStream->zeroOutput = true;
-                }
-                else /* paComplete or other non-zero value indicating complete */
-                {
-                    /* Finish playback once currently queued audio has completed. */
-                    theAsioStream->stopProcessing = true;
-
-                    if( PaUtil_IsBufferProcessorOutputEmpty( &theAsioStream->bufferProcessor ) )
-                    {
-                        theAsioStream->zeroOutput = true;
-                        theAsioStream->stopPlayoutCount = 0;
-                    }
-                }
-            }
-        }
-        
-        ++buffersDone;
-    }while( PaAsio_AtomicDecrement(&theAsioStream->reenterCount) >= 0 );
-
-    return 0L;
-}
-
-
-static void sampleRateChanged(ASIOSampleRate sRate)
-{
-    // TAKEN FROM THE ASIO SDK
-    // do whatever you need to do if the sample rate changed
-    // usually this only happens during external sync.
-    // Audio processing is not stopped by the driver, actual sample rate
-    // might not have even changed, maybe only the sample rate status of an
-    // AES/EBU or S/PDIF digital input at the audio device.
-    // You might have to update time/sample related conversion routines, etc.
-
-    (void) sRate; /* unused parameter */
-    PA_DEBUG( ("sampleRateChanged : %d \n", sRate));
-}
-
-static long asioMessages(long selector, long value, void* message, double* opt)
-{
-// TAKEN FROM THE ASIO SDK
-    // currently the parameters "value", "message" and "opt" are not used.
-    long ret = 0;
-
-    (void) message; /* unused parameters */
-    (void) opt;
-
-    PA_DEBUG( ("asioMessages : %d , %d \n", selector, value));
-
-    switch(selector)
-    {
-        case kAsioSelectorSupported:
-            if(value == kAsioResetRequest
-            || value == kAsioEngineVersion
-            || value == kAsioResyncRequest
-            || value == kAsioLatenciesChanged
-            // the following three were added for ASIO 2.0, you don't necessarily have to support them
-            || value == kAsioSupportsTimeInfo
-            || value == kAsioSupportsTimeCode
-            || value == kAsioSupportsInputMonitor)
-                    ret = 1L;
-            break;
-
-        case kAsioBufferSizeChange:
-            //printf("kAsioBufferSizeChange \n");
-            break;
-
-        case kAsioResetRequest:
-            // defer the task and perform the reset of the driver during the next "safe" situation
-            // You cannot reset the driver right now, as this code is called from the driver.
-            // Reset the driver is done by completely destruct is. I.e. ASIOStop(), ASIODisposeBuffers(), Destruction
-            // Afterwards you initialize the driver again.
-
-            /*FIXME: commented the next line out */
-            //asioDriverInfo.stopped;  // In this sample the processing will just stop
-            ret = 1L;
-            break;
-
-        case kAsioResyncRequest:
-            // This informs the application, that the driver encountered some non fatal data loss.
-            // It is used for synchronization purposes of different media.
-            // Added mainly to work around the Win16Mutex problems in Windows 95/98 with the
-            // Windows Multimedia system, which could loose data because the Mutex was hold too long
-            // by another thread.
-            // However a driver can issue it in other situations, too.
-            ret = 1L;
-            break;
-
-        case kAsioLatenciesChanged:
-            // This will inform the host application that the drivers were latencies changed.
-            // Beware, it this does not mean that the buffer sizes have changed!
-            // You might need to update internal delay data.
-            ret = 1L;
-            //printf("kAsioLatenciesChanged \n");
-            break;
-
-        case kAsioEngineVersion:
-            // return the supported ASIO version of the host application
-            // If a host applications does not implement this selector, ASIO 1.0 is assumed
-            // by the driver
-            ret = 2L;
-            break;
-
-        case kAsioSupportsTimeInfo:
-            // informs the driver wether the asioCallbacks.bufferSwitchTimeInfo() callback
-            // is supported.
-            // For compatibility with ASIO 1.0 drivers the host application should always support
-            // the "old" bufferSwitch method, too.
-            ret = 1;
-            break;
-
-        case kAsioSupportsTimeCode:
-            // informs the driver wether application is interested in time code info.
-            // If an application does not need to know about time code, the driver has less work
-            // to do.
-            ret = 0;
-            break;
-    }
-    return ret;
-}
-
-
-static PaError StartStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaAsioStream *stream = (PaAsioStream*)s;
-    ASIOError asioError;
-
-    if( stream->outputChannelCount > 0 )
-    {
-        ZeroOutputBuffers( stream, 0 );
-        ZeroOutputBuffers( stream, 1 );
-    }
-
-    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
-    stream->stopProcessing = false;
-    stream->zeroOutput = false;
-
-    /* Reentrancy counter initialisation */
-    stream->reenterCount = -1;
-    stream->reenterError = 0;
-
-    stream->callbackFlags = 0;
-
-    if( ResetEvent( stream->completedBuffersPlayedEvent ) == 0 )
-    {
-        result = paUnanticipatedHostError;
-        PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
-    }
-
-    if( result == paNoError )
-    {
-        theAsioStream = stream;
-        asioError = ASIOStart();
-        if( asioError == ASE_OK )
-        {
-            stream->isActive = 1;
-            stream->streamFinishedCallbackCalled = false;
-        }
-        else
-        {
-            theAsioStream = 0;
-            result = paUnanticipatedHostError;
-            PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-        }
-    }
-
-    return result;
-}
-
-
-static PaError StopStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaAsioStream *stream = (PaAsioStream*)s;
-    ASIOError asioError;
-
-    if( stream->isActive )
-    {
-        stream->stopProcessing = true;
-
-        /* wait for the stream to finish playing out enqueued buffers.
-            timeout after four times the stream latency.
-
-            @todo should use a better time out value - if the user buffer
-            length is longer than the asio buffer size then that should
-            be taken into account.
-        */
-        if( WaitForSingleObject( theAsioStream->completedBuffersPlayedEvent,
-                (DWORD)(stream->streamRepresentation.streamInfo.outputLatency * 1000. * 4.) )
-                    == WAIT_TIMEOUT	 )
-        {
-            PA_DEBUG(("WaitForSingleObject() timed out in StopStream()\n" ));
-        }
-    }
-
-    asioError = ASIOStop();
-    if( asioError != ASE_OK )
-    {
-        result = paUnanticipatedHostError;
-        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-    }
-
-    theAsioStream = 0;
-    stream->isActive = 0;
-
-    if( !stream->streamFinishedCallbackCalled )
-    {
-        if( stream->streamRepresentation.streamFinishedCallback != 0 )
-            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
-    }
-
-    return result;
-}
-
-
-static PaError AbortStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaAsioStream *stream = (PaAsioStream*)s;
-    ASIOError asioError;
-
-    stream->zeroOutput = true;
-
-    asioError = ASIOStop();
-    if( asioError != ASE_OK )
-    {
-        result = paUnanticipatedHostError;
-        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-    }
-    else
-    {
-        // make sure that the callback is not still in-flight when ASIOStop()
-        // returns. This has been observed to happen on the Hoontech DSP24 for
-        // example.
-        int count = 2000;  // only wait for 2 seconds, rather than hanging.
-        while( theAsioStream->reenterCount != -1 && count > 0 )
-        {
-            Sleep(1);
-            --count;
-        }
-    }
-
-    /* it is questionable whether we should zero theAsioStream if ASIOStop()
-        returns an error, because the callback could still be active. We assume
-        not - this is based on the fact that ASIOStop is unlikely to fail
-        if the callback is running - it's more likely to fail because the
-        callback is not running. */
-        
-    theAsioStream = 0;
-    stream->isActive = 0;
-
-    if( !stream->streamFinishedCallbackCalled )
-    {
-        if( stream->streamRepresentation.streamFinishedCallback != 0 )
-            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
-    }
-
-    return result;
-}
-
-
-static PaError IsStreamStopped( PaStream *s )
-{
-    //PaAsioStream *stream = (PaAsioStream*)s;
-    (void) s; /* unused parameter */
-    return theAsioStream == 0;
-}
-
-
-static PaError IsStreamActive( PaStream *s )
-{
-    PaAsioStream *stream = (PaAsioStream*)s;
-
-    return stream->isActive;
-}
-
-
-static PaTime GetStreamTime( PaStream *s )
-{
-    (void) s; /* unused parameter */
-    return (double)timeGetTime() * .001;
-}
-
-
-static double GetStreamCpuLoad( PaStream* s )
-{
-    PaAsioStream *stream = (PaAsioStream*)s;
-
-    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
-}
-
-
-/*
-    As separate stream interfaces are used for blocking and callback
-    streams, the following functions can be guaranteed to only be called
-    for blocking streams.
-*/
-
-static PaError ReadStream( PaStream* s,
-                           void *buffer,
-                           unsigned long frames )
-{
-    PaAsioStream *stream = (PaAsioStream*)s;
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-    (void) stream; /* unused parameters */
-    (void) buffer;
-    (void) frames;
-
-    return paNoError;
-}
-
-
-static PaError WriteStream( PaStream* s,
-                            const void *buffer,
-                            unsigned long frames )
-{
-    PaAsioStream *stream = (PaAsioStream*)s;
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-    (void) stream; /* unused parameters */
-    (void) buffer;
-    (void) frames;
-
-    return paNoError;
-}
-
-
-static signed long GetStreamReadAvailable( PaStream* s )
-{
-    PaAsioStream *stream = (PaAsioStream*)s;
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-    (void) stream; /* unused parameter */
-
-    return 0;
-}
-
-
-static signed long GetStreamWriteAvailable( PaStream* s )
-{
-    PaAsioStream *stream = (PaAsioStream*)s;
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-    (void) stream; /* unused parameter */
-
-    return 0;
-}
-
-
-PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific )
-{
-	PaError result = paNoError;
-    PaUtilHostApiRepresentation *hostApi;
-    PaDeviceIndex hostApiDevice;
-    ASIODriverInfo asioDriverInfo;
-	ASIOError asioError;
-    int asioIsInitialized = 0;
-    PaAsioHostApiRepresentation *asioHostApi;
-    PaAsioDeviceInfo *asioDeviceInfo;
-
-
-    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
-    if( result != paNoError )
-        goto error;
-
-    result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi );
-    if( result != paNoError )
-        goto error;
-
-    /*
-        In theory we could proceed if the currently open device was the same
-        one for which the control panel was requested, however  because the
-        window pointer is not available until this function is called we
-        currently need to call ASIOInit() again here, which of course can't be
-        done safely while a stream is open.
-    */
-
-    asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
-    if( asioHostApi->openAsioDeviceIndex != paNoDevice )
-    {
-        result = paDeviceUnavailable;
-        goto error;
-    }
-
-    asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice];
-
-    if( !loadAsioDriver( const_cast<char*>(asioDeviceInfo->commonDeviceInfo.name) ) )
-    {
-        result = paUnanticipatedHostError;
-        goto error;
-    }
-
-    /* CRUCIAL!!! */
-    memset( &asioDriverInfo, 0, sizeof(ASIODriverInfo) );
-    asioDriverInfo.asioVersion = 2;
-    asioDriverInfo.sysRef = systemSpecific;
-    asioError = ASIOInit( &asioDriverInfo );
-    if( asioError != ASE_OK )
-    {
-        result = paUnanticipatedHostError;
-        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-        goto error;
-    }
-    else
-    {
-        asioIsInitialized = 1;
-    }
-
-PA_DEBUG(("PaAsio_ShowControlPanel: ASIOInit(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
-PA_DEBUG(("asioVersion: ASIOInit(): %ld\n",   asioDriverInfo.asioVersion )); 
-PA_DEBUG(("driverVersion: ASIOInit(): %ld\n", asioDriverInfo.driverVersion )); 
-PA_DEBUG(("Name: ASIOInit(): %s\n",           asioDriverInfo.name )); 
-PA_DEBUG(("ErrorMessage: ASIOInit(): %s\n",   asioDriverInfo.errorMessage )); 
-
-    asioError = ASIOControlPanel();
-    if( asioError != ASE_OK )
-    {
-        PA_DEBUG(("PaAsio_ShowControlPanel: ASIOControlPanel(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
-        result = paUnanticipatedHostError;
-        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-        goto error;
-    }
-
-PA_DEBUG(("PaAsio_ShowControlPanel: ASIOControlPanel(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
-
-    asioError = ASIOExit();
-    if( asioError != ASE_OK )
-    {
-        result = paUnanticipatedHostError;
-        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
-        asioIsInitialized = 0;
-        goto error;
-    }
-
-PA_DEBUG(("PaAsio_ShowControlPanel: ASIOExit(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
-
-	return result;
-
-error:
-    if( asioIsInitialized )
-        ASIOExit();
-
-	return result;
-}
-
-
-PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex,
-        const char** channelName )
-{
-    PaError result = paNoError;
-    PaUtilHostApiRepresentation *hostApi;
-    PaDeviceIndex hostApiDevice;
-    PaAsioDeviceInfo *asioDeviceInfo;
-
-
-    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
-    if( result != paNoError )
-        goto error;
-
-    result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi );
-    if( result != paNoError )
-        goto error;
-
-    asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice];
-
-    if( channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxInputChannels ){
-        result = paInvalidChannelCount;
-        goto error;
-    }
-
-    *channelName = asioDeviceInfo->asioChannelInfos[channelIndex].name;
-
-    return paNoError;
-    
-error:
-    return result;
-}
-
-
-PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex,
-        const char** channelName )
-{
-    PaError result = paNoError;
-    PaUtilHostApiRepresentation *hostApi;
-    PaDeviceIndex hostApiDevice;
-    PaAsioDeviceInfo *asioDeviceInfo;
-
-
-    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
-    if( result != paNoError )
-        goto error;
-
-    result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi );
-    if( result != paNoError )
-        goto error;
-
-    asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice];
-
-    if( channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxOutputChannels ){
-        result = paInvalidChannelCount;
-        goto error;
-    }
-
-    *channelName = asioDeviceInfo->asioChannelInfos[
-            asioDeviceInfo->commonDeviceInfo.maxInputChannels + channelIndex].name;
-
-    return paNoError;
-    
-error:
-    return result;
-}
diff --git a/portaudio/pa_asio/pa_asio.h b/portaudio/pa_asio/pa_asio.h
deleted file mode 100644
index 230fb2d85..000000000
--- a/portaudio/pa_asio/pa_asio.h
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef PA_ASIO_H
-#define PA_ASIO_H
-/*
- * $Id: pa_asio.h,v 1.1.2.7 2005/01/01 19:35:33 rossbencina Exp $
- * PortAudio Portable Real-Time Audio Library
- * ASIO specific extensions
- *
- * 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.
- *
- */
-
-/** @file
- @brief ASIO-specific PortAudio API extension header file.
-*/
-
-
-#include "portaudio.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-/** Retrieve legal latency settings for the specificed device, in samples.
-
- @param device The global index of the device about which the query is being made.
- @param minLatency A pointer to the location which will recieve the minimum latency value.
- @param maxLatency A pointer to the location which will recieve the maximum latency value.
- @param preferredLatency A pointer to the location which will recieve the preferred latency value.
- @param granularity A pointer to the location which will recieve the granularity. This value 
- determines which values between minLatency and maxLatency are available. ie the step size,
- if granularity is -1 then available latency settings are powers of two.
-
- @see ASIOGetBufferSize in the ASIO SDK.
-
- @todo This function should have a better name, any suggestions?
-*/
-PaError PaAsio_GetAvailableLatencyValues( PaDeviceIndex device,
-		long *minLatency, long *maxLatency, long *preferredLatency, long *granularity );
-
-        
-/** Display the ASIO control panel for the specified device.
-
-  @param device The global index of the device whose control panel is to be displayed.
-  @param systemSpecific On Windows, the calling application's main window handle,
-  on Macintosh this value should be zero.
-*/
-PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific );
-
-
-
-
-/** Retrieve a pointer to a string containing the name of the specified
- input channel. The string is valid until Pa_Terminate is called.
-
- The string will be no longer than 32 characters including the null terminator.
-*/
-PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex,
-        const char** channelName );
-
-        
-/** Retrieve a pointer to a string containing the name of the specified
- input channel. The string is valid until Pa_Terminate is called.
-
- The string will be no longer than 32 characters including the null terminator.
-*/
-PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex,
-        const char** channelName );
-
-
-#define paAsioUseChannelSelectors      (0x01)
-
-typedef struct PaAsioStreamInfo{
-    unsigned long size;             /**< sizeof(PaAsioStreamInfo) */
-    PaHostApiTypeId hostApiType;    /**< paASIO */
-    unsigned long version;          /**< 1 */
-
-    unsigned long flags;
-
-    /* Support for opening only specific channels of an ASIO device.
-        If the paAsioUseChannelSelectors flag is set, channelSelectors is a
-        pointer to an array of integers specifying the device channels to use.
-        When used, the length of the channelSelectors array must match the
-        corresponding channelCount parameter to Pa_OpenStream() otherwise a
-        crash may result.
-        The values in the selectors array must specify channels within the
-        range of supported channels for the device or paInvalidChannelCount will
-        result.
-    */
-    int *channelSelectors;
-}PaAsioStreamInfo;
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* PA_ASIO_H */
diff --git a/portaudio/pa_common/CVS/Entries b/portaudio/pa_common/CVS/Entries
deleted file mode 100644
index 98e8ca0c5..000000000
--- a/portaudio/pa_common/CVS/Entries
+++ /dev/null
@@ -1,22 +0,0 @@
-/pa_allocation.c/1.1.2.6/Mon Dec 20 12:07:51 2004//Tv19-devel
-/pa_allocation.h/1.1.2.4/Sat Sep 20 21:04:44 2003//Tv19-devel
-/pa_converters.c/1.1.2.27/Wed Nov  2 12:14:07 2005//Tv19-devel
-/pa_converters.h/1.1.2.9/Sat Sep 20 21:05:14 2003//Tv19-devel
-/pa_cpuload.c/1.1.2.14/Thu Jan  8 22:01:12 2004//Tv19-devel
-/pa_cpuload.h/1.1.2.10/Thu Jan  8 22:01:12 2004//Tv19-devel
-/pa_dither.c/1.1.2.6/Sat May 28 22:49:02 2005//Tv19-devel
-/pa_dither.h/1.1.2.4/Sat Sep 20 21:06:19 2003//Tv19-devel
-/pa_endianness.h/1.1.2.5/Thu Feb 16 16:26:07 2006//Tv19-devel
-/pa_front.c/1.1.2.53/Mon Mar 20 18:11:09 2006//Tv19-devel
-/pa_hostapi.h/1.1.2.14/Thu Jan  8 22:01:12 2004//Tv19-devel
-/pa_process.c/1.1.2.51/Thu Oct 27 23:28:48 2005//Tv19-devel
-/pa_process.h/1.1.2.30/Mon Dec 13 09:48:44 2004//Tv19-devel
-/pa_skeleton.c/1.1.2.39/Wed Nov 26 14:56:09 2003//Tv19-devel
-/pa_stream.c/1.1.2.12/Sat Sep 20 21:31:00 2003//Tv19-devel
-/pa_stream.h/1.1.2.13/Sat Nov  1 06:37:28 2003//Tv19-devel
-/pa_trace.c/1.1.1.1.2.4/Wed Nov  2 12:06:44 2005//Tv19-devel
-/pa_trace.h/1.1.1.1.2.3/Sat Sep 20 21:09:15 2003//Tv19-devel
-/pa_types.h/1.1.2.2/Sat Feb  5 15:52:05 2005//Tv19-devel
-/pa_util.h/1.1.2.13/Wed Nov  9 06:31:42 2005//Tv19-devel
-/portaudio.h/1.5.2.53/Mon Mar 20 17:49:38 2006//Tv19-devel
-D
diff --git a/portaudio/pa_common/CVS/Repository b/portaudio/pa_common/CVS/Repository
deleted file mode 100644
index 6c0ffe7aa..000000000
--- a/portaudio/pa_common/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_common
diff --git a/portaudio/pa_common/CVS/Root b/portaudio/pa_common/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_common/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_common/CVS/Tag b/portaudio/pa_common/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_common/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_common/pa_allocation.c b/portaudio/pa_common/pa_allocation.c
deleted file mode 100644
index 035b4d0b5..000000000
--- a/portaudio/pa_common/pa_allocation.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * $Id: pa_allocation.c,v 1.1.2.6 2004/12/20 12:07:51 rossbencina Exp $
- * Portable Audio I/O Library allocation group implementation
- * memory allocation group for tracking allocation groups
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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.
- */
-
-/** @file
- @brief Allocation Group implementation.
-*/
-
-
-#include "pa_allocation.h"
-#include "pa_util.h"
-
-
-/*
-    Maintain 3 singly linked lists...
-    linkBlocks: the buffers used to allocate the links
-    spareLinks: links available for use in the allocations list
-    allocations: the buffers currently allocated using PaUtil_ContextAllocateMemory()
-
-    Link block size is doubled every time new links are allocated.
-*/
-
-
-#define PA_INITIAL_LINK_COUNT_    16
-
-struct PaUtilAllocationGroupLink
-{
-    struct PaUtilAllocationGroupLink *next;
-    void *buffer;
-};
-
-/*
-    Allocate a block of links. The first link will have it's buffer member
-    pointing to the block, and it's next member set to <nextBlock>. The remaining
-    links will have NULL buffer members, and each link will point to
-    the next link except the last, which will point to <nextSpare>
-*/
-static struct PaUtilAllocationGroupLink *AllocateLinks( long count,
-        struct PaUtilAllocationGroupLink *nextBlock,
-        struct PaUtilAllocationGroupLink *nextSpare )
-{
-    struct PaUtilAllocationGroupLink *result;
-    int i;
-    
-    result = (struct PaUtilAllocationGroupLink *)PaUtil_AllocateMemory(
-            sizeof(struct PaUtilAllocationGroupLink) * count );
-    if( result )
-    {
-        /* the block link */
-        result[0].buffer = result;
-        result[0].next = nextBlock;
-
-        /* the spare links */
-        for( i=1; i<count; ++i )
-        {
-            result[i].buffer = 0;
-            result[i].next = &result[i+1];
-        }
-        result[count-1].next = nextSpare;
-    }
-    
-    return result;
-}
-
-
-PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void )
-{
-    PaUtilAllocationGroup* result = 0;
-    struct PaUtilAllocationGroupLink *links;
-
-
-    links = AllocateLinks( PA_INITIAL_LINK_COUNT_, 0, 0 );
-    if( links != 0 )
-    {
-        result = (PaUtilAllocationGroup*)PaUtil_AllocateMemory( sizeof(PaUtilAllocationGroup) );
-        if( result )
-        {
-            result->linkCount = PA_INITIAL_LINK_COUNT_;
-            result->linkBlocks = &links[0];
-            result->spareLinks = &links[1];
-            result->allocations = 0;
-        }
-        else
-        {
-            PaUtil_FreeMemory( links );
-        }
-    }
-
-    return result;
-}
-
-
-void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group )
-{
-    struct PaUtilAllocationGroupLink *current = group->linkBlocks;
-    struct PaUtilAllocationGroupLink *next;
-
-    while( current )
-    {
-        next = current->next;
-        PaUtil_FreeMemory( current->buffer );
-        current = next;
-    }
-
-    PaUtil_FreeMemory( group );
-}
-
-
-void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size )
-{
-    struct PaUtilAllocationGroupLink *links, *link;
-    void *result = 0;
-    
-    /* allocate more links if necessary */
-    if( !group->spareLinks )
-    {
-        /* double the link count on each block allocation */
-        links = AllocateLinks( group->linkCount, group->linkBlocks, group->spareLinks );
-        if( links )
-        {
-            group->linkCount += group->linkCount;
-            group->linkBlocks = &links[0];
-            group->spareLinks = &links[1];
-        }
-    }
-
-    if( group->spareLinks )
-    {
-        result = PaUtil_AllocateMemory( size );
-        if( result )
-        {
-            link = group->spareLinks;
-            group->spareLinks = link->next;
-
-            link->buffer = result;
-            link->next = group->allocations;
-
-            group->allocations = link;
-        }
-    }
-
-    return result;    
-}
-
-
-void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer )
-{
-    struct PaUtilAllocationGroupLink *current = group->allocations;
-    struct PaUtilAllocationGroupLink *previous = 0;
-
-    if( buffer == 0 )
-        return;
-
-    /* find the right link and remove it */
-    while( current )
-    {
-        if( current->buffer == buffer )
-        {
-            if( previous )
-            {
-                previous->next = current->next;
-            }
-            else
-            {
-                group->allocations = current->next;
-            }
-
-            current->buffer = 0;
-            current->next = group->spareLinks;
-            group->spareLinks = current;
-
-            break;
-        }
-        
-        previous = current;
-        current = current->next;
-    }
-
-    PaUtil_FreeMemory( buffer ); /* free the memory whether we found it in the list or not */
-}
-
-
-void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group )
-{
-    struct PaUtilAllocationGroupLink *current = group->allocations;
-    struct PaUtilAllocationGroupLink *previous = 0;
-
-    /* free all buffers in the allocations list */
-    while( current )
-    {
-        PaUtil_FreeMemory( current->buffer );
-        current->buffer = 0;
-
-        previous = current;
-        current = current->next;
-    }
-
-    /* link the former allocations list onto the front of the spareLinks list */
-    if( previous )
-    {
-        previous->next = group->spareLinks;
-        group->spareLinks = group->allocations;
-        group->allocations = 0;
-    }
-}
-
diff --git a/portaudio/pa_common/pa_allocation.h b/portaudio/pa_common/pa_allocation.h
deleted file mode 100644
index fb9321a01..000000000
--- a/portaudio/pa_common/pa_allocation.h
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef PA_ALLOCATION_H
-#define PA_ALLOCATION_H
-/*
- * $Id: pa_allocation.h,v 1.1.2.4 2003/09/20 21:04:44 rossbencina Exp $
- * Portable Audio I/O Library allocation context header
- * memory allocation context for tracking allocation groups
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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.
- */
-
-/** @file
- @brief Allocation Group prototypes. An Allocation Group makes it easy to
- allocate multiple blocks of memory and free them all simultanously.
- 
- An allocation group is useful for keeping track of multiple blocks
- of memory which are allocated at the same time (such as during initialization)
- and need to be deallocated at the same time. The allocation group maintains
- a list of allocated blocks, and can deallocate them all simultaneously which
- can be usefull for cleaning up after a partially initialized object fails.
-
- The allocation group implementation is built on top of the lower
- level allocation functions defined in pa_util.h
-*/
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-typedef struct
-{
-    long linkCount;
-    struct PaUtilAllocationGroupLink *linkBlocks;
-    struct PaUtilAllocationGroupLink *spareLinks;
-    struct PaUtilAllocationGroupLink *allocations;
-}PaUtilAllocationGroup;
-
-
-
-/** Create an allocation group.
-*/
-PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void );
-
-/** Destroy an allocation group, but not the memory allocated through the group.
-*/
-void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group );
-
-/** Allocate a block of memory though an allocation group.
-*/
-void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size );
-
-/** Free a block of memory that was previously allocated though an allocation
- group. Calling this function is a relatively time consuming operation.
- Under normal circumstances clients should call PaUtil_FreeAllAllocations to
- free all allocated blocks simultaneously.
- @see PaUtil_FreeAllAllocations
-*/
-void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer );
-
-/** Free all blocks of memory which have been allocated through the allocation
- group. This function doesn't destroy the group itself.
-*/
-void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group );
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PA_ALLOCATION_H */
diff --git a/portaudio/pa_common/pa_converters.c b/portaudio/pa_common/pa_converters.c
deleted file mode 100644
index a7e3a06cb..000000000
--- a/portaudio/pa_common/pa_converters.c
+++ /dev/null
@@ -1,1926 +0,0 @@
-/*
- * $Id: pa_converters.c,v 1.1.2.27 2005/11/02 12:14:07 rossbencina Exp $
- * Portable Audio I/O Library sample conversion mechanism
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Phil Burk, 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.
- */
-
-/** @file
- @brief Conversion functions implementations.
- 
- If the C9x function lrintf() is available, define PA_USE_C99_LRINTF to use it
-
- @todo Consider whether functions which dither but don't clip should exist,
- V18 automatically enabled clipping whenever dithering was selected. Perhaps
- we should do the same.
-
- @todo implement the converters marked IMPLEMENT ME: Float32_To_UInt8_Dither,
- Float32_To_UInt8_Clip, Float32_To_UInt8_DitherClip, Int32_To_Int24_Dither,
- Int32_To_UInt8_Dither, Int24_To_Int16_Dither, Int24_To_Int8_Dither, 
- Int24_To_UInt8_Dither, Int16_To_Int8_Dither, Int16_To_UInt8_Dither,
-
- @todo review the converters marked REVIEW: Float32_To_Int32,
- Float32_To_Int32_Dither, Float32_To_Int32_Clip, Float32_To_Int32_DitherClip,
- Int32_To_Int16_Dither, Int32_To_Int8_Dither, Int16_To_Int32
-*/
-
-
-#include "pa_converters.h"
-#include "pa_dither.h"
-#include "pa_endianness.h"
-#include "pa_types.h"
-
-
-PaSampleFormat PaUtil_SelectClosestAvailableFormat(
-        PaSampleFormat availableFormats, PaSampleFormat format )
-{
-    PaSampleFormat result;
-
-    format &= ~paNonInterleaved;
-    availableFormats &= ~paNonInterleaved;
-    
-    if( (format & availableFormats) == 0 )
-    {
-        /* NOTE: this code depends on the sample format constants being in
-            descending order of quality - ie best quality is 0
-            FIXME: should write an assert which checks that all of the
-            known constants conform to that requirement.
-        */
-
-        if( format != 0x01 )
-        {
-            /* scan for better formats */
-            result = format;
-            do
-            {
-                result >>= 1;
-            }
-            while( (result & availableFormats) == 0 && result != 0 );
-        }
-        else
-        {
-            result = 0;
-        }
-        
-        if( result == 0 ){
-            /* scan for worse formats */
-            result = format;
-            do
-            {
-                result <<= 1;
-            }
-            while( (result & availableFormats) == 0 && result != paCustomFormat );
-
-            if( (result & availableFormats) == 0 )
-                result = paSampleFormatNotSupported;
-        }
-        
-    }else{
-        result = format;
-    }
-
-    return result;
-}
-
-/* -------------------------------------------------------------------------- */
-
-#define PA_SELECT_FORMAT_( format, float32, int32, int24, int16, int8, uint8 ) \
-    switch( format & ~paNonInterleaved ){                                      \
-    case paFloat32:                                                            \
-        float32                                                                \
-    case paInt32:                                                              \
-        int32                                                                  \
-    case paInt24:                                                              \
-        int24                                                                  \
-    case paInt16:                                                              \
-        int16                                                                  \
-    case paInt8:                                                               \
-        int8                                                                   \
-    case paUInt8:                                                              \
-        uint8                                                                  \
-    default: return 0;                                                         \
-    }
-
-/* -------------------------------------------------------------------------- */
-
-#define PA_SELECT_CONVERTER_DITHER_CLIP_( flags, source, destination )         \
-    if( flags & paClipOff ){ /* no clip */                                     \
-        if( flags & paDitherOff ){ /* no dither */                             \
-            return paConverters. source ## _To_ ## destination;                \
-        }else{ /* dither */                                                    \
-            return paConverters. source ## _To_ ## destination ## _Dither;     \
-        }                                                                      \
-    }else{ /* clip */                                                          \
-        if( flags & paDitherOff ){ /* no dither */                             \
-            return paConverters. source ## _To_ ## destination ## _Clip;       \
-        }else{ /* dither */                                                    \
-            return paConverters. source ## _To_ ## destination ## _DitherClip; \
-        }                                                                      \
-    }
-
-/* -------------------------------------------------------------------------- */
-
-#define PA_SELECT_CONVERTER_DITHER_( flags, source, destination )              \
-    if( flags & paDitherOff ){ /* no dither */                                 \
-        return paConverters. source ## _To_ ## destination;                    \
-    }else{ /* dither */                                                        \
-        return paConverters. source ## _To_ ## destination ## _Dither;         \
-    }
-
-/* -------------------------------------------------------------------------- */
-
-#define PA_USE_CONVERTER_( source, destination )\
-    return paConverters. source ## _To_ ## destination;
-
-/* -------------------------------------------------------------------------- */
-
-#define PA_UNITY_CONVERSION_( wordlength )\
-    return paConverters. Copy_ ## wordlength ## _To_ ## wordlength;
-
-/* -------------------------------------------------------------------------- */
-
-PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat,
-        PaSampleFormat destinationFormat, PaStreamFlags flags )
-{
-    PA_SELECT_FORMAT_( sourceFormat,
-                       /* paFloat32: */
-                       PA_SELECT_FORMAT_( destinationFormat,
-                                          /* paFloat32: */        PA_UNITY_CONVERSION_( 32 ),
-                                          /* paInt32: */          PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int32 ),
-                                          /* paInt24: */          PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int24 ),
-                                          /* paInt16: */          PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int16 ),
-                                          /* paInt8: */           PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int8 ),
-                                          /* paUInt8: */          PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, UInt8 )
-                                        ),
-                       /* paInt32: */
-                       PA_SELECT_FORMAT_( destinationFormat,
-                                          /* paFloat32: */        PA_USE_CONVERTER_( Int32, Float32 ),
-                                          /* paInt32: */          PA_UNITY_CONVERSION_( 32 ),
-                                          /* paInt24: */          PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int24 ),
-                                          /* paInt16: */          PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int16 ),
-                                          /* paInt8: */           PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int8 ),
-                                          /* paUInt8: */          PA_SELECT_CONVERTER_DITHER_( flags, Int32, UInt8 )
-                                        ),
-                       /* paInt24: */
-                       PA_SELECT_FORMAT_( destinationFormat,
-                                          /* paFloat32: */        PA_USE_CONVERTER_( Int24, Float32 ),
-                                          /* paInt32: */          PA_USE_CONVERTER_( Int24, Int32 ),
-                                          /* paInt24: */          PA_UNITY_CONVERSION_( 24 ),
-                                          /* paInt16: */          PA_SELECT_CONVERTER_DITHER_( flags, Int24, Int16 ),
-                                          /* paInt8: */           PA_SELECT_CONVERTER_DITHER_( flags, Int24, Int8 ),
-                                          /* paUInt8: */          PA_SELECT_CONVERTER_DITHER_( flags, Int24, UInt8 )
-                                        ),
-                       /* paInt16: */
-                       PA_SELECT_FORMAT_( destinationFormat,
-                                          /* paFloat32: */        PA_USE_CONVERTER_( Int16, Float32 ),
-                                          /* paInt32: */          PA_USE_CONVERTER_( Int16, Int32 ),
-                                          /* paInt24: */          PA_USE_CONVERTER_( Int16, Int24 ),
-                                          /* paInt16: */          PA_UNITY_CONVERSION_( 16 ),
-                                          /* paInt8: */           PA_SELECT_CONVERTER_DITHER_( flags, Int16, Int8 ),
-                                          /* paUInt8: */          PA_SELECT_CONVERTER_DITHER_( flags, Int16, UInt8 )
-                                        ),
-                       /* paInt8: */
-                       PA_SELECT_FORMAT_( destinationFormat,
-                                          /* paFloat32: */        PA_USE_CONVERTER_( Int8, Float32 ),
-                                          /* paInt32: */          PA_USE_CONVERTER_( Int8, Int32 ),
-                                          /* paInt24: */          PA_USE_CONVERTER_( Int8, Int24 ),
-                                          /* paInt16: */          PA_USE_CONVERTER_( Int8, Int16 ),
-                                          /* paInt8: */           PA_UNITY_CONVERSION_( 8 ),
-                                          /* paUInt8: */          PA_USE_CONVERTER_( Int8, UInt8 )
-                                        ),
-                       /* paUInt8: */
-                       PA_SELECT_FORMAT_( destinationFormat,
-                                          /* paFloat32: */        PA_USE_CONVERTER_( UInt8, Float32 ),
-                                          /* paInt32: */          PA_USE_CONVERTER_( UInt8, Int32 ),
-                                          /* paInt24: */          PA_USE_CONVERTER_( UInt8, Int24 ),
-                                          /* paInt16: */          PA_USE_CONVERTER_( UInt8, Int16 ),
-                                          /* paInt8: */           PA_USE_CONVERTER_( UInt8, Int8 ),
-                                          /* paUInt8: */          PA_UNITY_CONVERSION_( 8 )
-                                        )
-                     )
-}
-
-/* -------------------------------------------------------------------------- */
-
-#ifdef PA_NO_STANDARD_CONVERTERS
-
-/* -------------------------------------------------------------------------- */
-
-PaUtilConverterTable paConverters = {
-    0, /* PaUtilConverter *Float32_To_Int32; */
-    0, /* PaUtilConverter *Float32_To_Int32_Dither; */
-    0, /* PaUtilConverter *Float32_To_Int32_Clip; */
-    0, /* PaUtilConverter *Float32_To_Int32_DitherClip; */
-
-    0, /* PaUtilConverter *Float32_To_Int24; */
-    0, /* PaUtilConverter *Float32_To_Int24_Dither; */
-    0, /* PaUtilConverter *Float32_To_Int24_Clip; */
-    0, /* PaUtilConverter *Float32_To_Int24_DitherClip; */
-
-    0, /* PaUtilConverter *Float32_To_Int16; */
-    0, /* PaUtilConverter *Float32_To_Int16_Dither; */
-    0, /* PaUtilConverter *Float32_To_Int16_Clip; */
-    0, /* PaUtilConverter *Float32_To_Int16_DitherClip; */
-
-    0, /* PaUtilConverter *Float32_To_Int8; */
-    0, /* PaUtilConverter *Float32_To_Int8_Dither; */
-    0, /* PaUtilConverter *Float32_To_Int8_Clip; */
-    0, /* PaUtilConverter *Float32_To_Int8_DitherClip; */
-
-    0, /* PaUtilConverter *Float32_To_UInt8; */
-    0, /* PaUtilConverter *Float32_To_UInt8_Dither; */
-    0, /* PaUtilConverter *Float32_To_UInt8_Clip; */
-    0, /* PaUtilConverter *Float32_To_UInt8_DitherClip; */
-
-    0, /* PaUtilConverter *Int32_To_Float32; */
-    0, /* PaUtilConverter *Int32_To_Int24; */
-    0, /* PaUtilConverter *Int32_To_Int24_Dither; */
-    0, /* PaUtilConverter *Int32_To_Int16; */
-    0, /* PaUtilConverter *Int32_To_Int16_Dither; */
-    0, /* PaUtilConverter *Int32_To_Int8; */
-    0, /* PaUtilConverter *Int32_To_Int8_Dither; */
-    0, /* PaUtilConverter *Int32_To_UInt8; */
-    0, /* PaUtilConverter *Int32_To_UInt8_Dither; */
-
-    0, /* PaUtilConverter *Int24_To_Float32; */
-    0, /* PaUtilConverter *Int24_To_Int32; */
-    0, /* PaUtilConverter *Int24_To_Int16; */
-    0, /* PaUtilConverter *Int24_To_Int16_Dither; */
-    0, /* PaUtilConverter *Int24_To_Int8; */
-    0, /* PaUtilConverter *Int24_To_Int8_Dither; */
-    0, /* PaUtilConverter *Int24_To_UInt8; */
-    0, /* PaUtilConverter *Int24_To_UInt8_Dither; */
-    
-    0, /* PaUtilConverter *Int16_To_Float32; */
-    0, /* PaUtilConverter *Int16_To_Int32; */
-    0, /* PaUtilConverter *Int16_To_Int24; */
-    0, /* PaUtilConverter *Int16_To_Int8; */
-    0, /* PaUtilConverter *Int16_To_Int8_Dither; */
-    0, /* PaUtilConverter *Int16_To_UInt8; */
-    0, /* PaUtilConverter *Int16_To_UInt8_Dither; */
-
-    0, /* PaUtilConverter *Int8_To_Float32; */
-    0, /* PaUtilConverter *Int8_To_Int32; */
-    0, /* PaUtilConverter *Int8_To_Int24 */
-    0, /* PaUtilConverter *Int8_To_Int16; */
-    0, /* PaUtilConverter *Int8_To_UInt8; */
-
-    0, /* PaUtilConverter *UInt8_To_Float32; */
-    0, /* PaUtilConverter *UInt8_To_Int32; */
-    0, /* PaUtilConverter *UInt8_To_Int24; */
-    0, /* PaUtilConverter *UInt8_To_Int16; */
-    0, /* PaUtilConverter *UInt8_To_Int8; */
-
-    0, /* PaUtilConverter *Copy_8_To_8; */
-    0, /* PaUtilConverter *Copy_16_To_16; */
-    0, /* PaUtilConverter *Copy_24_To_24; */
-    0  /* PaUtilConverter *Copy_32_To_32; */
-};
-
-/* -------------------------------------------------------------------------- */
-
-#else /* PA_NO_STANDARD_CONVERTERS is not defined */
-
-/* -------------------------------------------------------------------------- */
-
-#define PA_CLIP_( val, min, max )\
-    { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); }
-
-
-static const float const_1_div_128_ = 1.0f / 128.0f;  /* 8 bit multiplier */
-
-static const float const_1_div_32768_ = 1.0f / 32768.f; /* 16 bit multiplier */
-
-static const double const_1_div_2147483648_ = 1.0 / 2147483648.0; /* 32 bit multiplier */
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int32(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    PaInt32 *dest =  (PaInt32*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        /* REVIEW */
-#ifdef PA_USE_C99_LRINTF
-        float scaled = *src * 0x7FFFFFFF;
-        *dest = lrintf(scaled-0.5f);
-#else
-        double scaled = *src * 0x7FFFFFFF;
-        *dest = (PaInt32) scaled;        
-#endif
-        
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int32_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    PaInt32 *dest =  (PaInt32*)destinationBuffer;
-
-    while( count-- )
-    {
-        /* REVIEW */
-#ifdef PA_USE_C99_LRINTF
-        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        /* use smaller scaler to prevent overflow when we add the dither */
-        float dithered = ((float)*src * (2147483646.0f)) + dither;
-        *dest = lrintf(dithered - 0.5f);
-#else
-        double dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        /* use smaller scaler to prevent overflow when we add the dither */
-        double dithered = ((double)*src * (2147483646.0)) + dither;
-        *dest = (PaInt32) dithered;
-#endif
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int32_Clip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    PaInt32 *dest =  (PaInt32*)destinationBuffer;
-    (void) ditherGenerator; /* unused parameter */
-    
-    while( count-- )
-    {
-        /* REVIEW */
-#ifdef PA_USE_C99_LRINTF
-        float scaled = *src * 0x7FFFFFFF;
-        PA_CLIP_( scaled, -2147483648.f, 2147483647.f  );
-        *dest = lrintf(scaled-0.5f);
-#else
-        double scaled = *src * 0x7FFFFFFF;
-        PA_CLIP_( scaled, -2147483648., 2147483647.  );
-        *dest = (PaInt32) scaled;
-#endif
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int32_DitherClip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    PaInt32 *dest =  (PaInt32*)destinationBuffer;
-
-    while( count-- )
-    {
-        /* REVIEW */
-#ifdef PA_USE_C99_LRINTF
-        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        /* use smaller scaler to prevent overflow when we add the dither */
-        float dithered = ((float)*src * (2147483646.0f)) + dither;
-        PA_CLIP_( dithered, -2147483648.f, 2147483647.f  );
-        *dest = lrintf(dithered-0.5f);
-#else
-        double dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        /* use smaller scaler to prevent overflow when we add the dither */
-        double dithered = ((double)*src * (2147483646.0)) + dither;
-        PA_CLIP_( dithered, -2147483648., 2147483647.  );
-        *dest = (PaInt32) dithered;
-#endif
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int24(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-    PaInt32 temp;
-
-    (void) ditherGenerator; /* unused parameter */
-    
-    while( count-- )
-    {
-        /* convert to 32 bit and drop the low 8 bits */
-        double scaled = *src * 0x7FFFFFFF;
-        temp = (PaInt32) scaled;
-        
-#if defined(PA_LITTLE_ENDIAN)
-        dest[0] = (unsigned char)(temp >> 8);
-        dest[1] = (unsigned char)(temp >> 16);
-        dest[2] = (unsigned char)(temp >> 24);
-#elif defined(PA_BIG_ENDIAN)
-        dest[0] = (unsigned char)(temp >> 24);
-        dest[1] = (unsigned char)(temp >> 16);
-        dest[2] = (unsigned char)(temp >> 8);
-#endif
-
-        src += sourceStride;
-        dest += destinationStride * 3;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int24_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-    PaInt32 temp;
-
-    while( count-- )
-    {
-        /* convert to 32 bit and drop the low 8 bits */
-
-        double dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        /* use smaller scaler to prevent overflow when we add the dither */
-        double dithered = ((double)*src * (2147483646.0)) + dither;
-        
-        temp = (PaInt32) dithered;
-
-#if defined(PA_LITTLE_ENDIAN)
-        dest[0] = (unsigned char)(temp >> 8);
-        dest[1] = (unsigned char)(temp >> 16);
-        dest[2] = (unsigned char)(temp >> 24);
-#elif defined(PA_BIG_ENDIAN)
-        dest[0] = (unsigned char)(temp >> 24);
-        dest[1] = (unsigned char)(temp >> 16);
-        dest[2] = (unsigned char)(temp >> 8);
-#endif
-
-        src += sourceStride;
-        dest += destinationStride * 3;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int24_Clip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-    PaInt32 temp;
-
-    (void) ditherGenerator; /* unused parameter */
-    
-    while( count-- )
-    {
-        /* convert to 32 bit and drop the low 8 bits */
-        double scaled = *src * 0x7FFFFFFF;
-        PA_CLIP_( scaled, -2147483648., 2147483647.  );
-        temp = (PaInt32) scaled;
-
-#if defined(PA_LITTLE_ENDIAN)
-        dest[0] = (unsigned char)(temp >> 8);
-        dest[1] = (unsigned char)(temp >> 16);
-        dest[2] = (unsigned char)(temp >> 24);
-#elif defined(PA_BIG_ENDIAN)
-        dest[0] = (unsigned char)(temp >> 24);
-        dest[1] = (unsigned char)(temp >> 16);
-        dest[2] = (unsigned char)(temp >> 8);
-#endif
-
-        src += sourceStride;
-        dest += destinationStride * 3;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int24_DitherClip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-    PaInt32 temp;
-    
-    while( count-- )
-    {
-        /* convert to 32 bit and drop the low 8 bits */
-        
-        double dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        /* use smaller scaler to prevent overflow when we add the dither */
-        double dithered = ((double)*src * (2147483646.0)) + dither;
-        PA_CLIP_( dithered, -2147483648., 2147483647.  );
-        
-        temp = (PaInt32) dithered;
-
-#if defined(PA_LITTLE_ENDIAN)
-        dest[0] = (unsigned char)(temp >> 8);
-        dest[1] = (unsigned char)(temp >> 16);
-        dest[2] = (unsigned char)(temp >> 24);
-#elif defined(PA_BIG_ENDIAN)
-        dest[0] = (unsigned char)(temp >> 24);
-        dest[1] = (unsigned char)(temp >> 16);
-        dest[2] = (unsigned char)(temp >> 8);
-#endif
-
-        src += sourceStride;
-        dest += destinationStride * 3;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int16(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    PaInt16 *dest =  (PaInt16*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-#ifdef PA_USE_C99_LRINTF
-        float tempf = (*src * (32767.0f)) ;
-        *dest = lrintf(tempf-0.5f);
-#else
-        short samp = (short) (*src * (32767.0f));
-        *dest = samp;
-#endif
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int16_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    PaInt16 *dest = (PaInt16*)destinationBuffer;
-
-    while( count-- )
-    {
-
-        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        /* use smaller scaler to prevent overflow when we add the dither */
-        float dithered = (*src * (32766.0f)) + dither;
-
-#ifdef PA_USE_C99_LRINTF
-        *dest = lrintf(dithered-0.5f);
-#else
-        *dest = (PaInt16) dithered;
-#endif
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int16_Clip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    PaInt16 *dest =  (PaInt16*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-#ifdef PA_USE_C99_LRINTF
-        long samp = lrintf((*src * (32767.0f)) -0.5f);
-#else
-        long samp = (PaInt32) (*src * (32767.0f));
-#endif
-        PA_CLIP_( samp, -0x8000, 0x7FFF );
-        *dest = (PaInt16) samp;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int16_DitherClip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    PaInt16 *dest =  (PaInt16*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-
-        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        /* use smaller scaler to prevent overflow when we add the dither */
-        float dithered = (*src * (32766.0f)) + dither;
-        PaInt32 samp = (PaInt32) dithered;
-        PA_CLIP_( samp, -0x8000, 0x7FFF );
-#ifdef PA_USE_C99_LRINTF
-        *dest = lrintf(samp-0.5f);
-#else
-        *dest = (PaInt16) samp;
-#endif
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int8(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    signed char *dest =  (signed char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        signed char samp = (signed char) (*src * (127.0f));
-        *dest = samp;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int8_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    signed char *dest =  (signed char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        /* use smaller scaler to prevent overflow when we add the dither */
-        float dithered = (*src * (126.0f)) + dither;
-        PaInt32 samp = (PaInt32) dithered;
-        *dest = (signed char) samp;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int8_Clip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    signed char *dest =  (signed char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        PaInt32 samp = (PaInt32)(*src * (127.0f));
-        PA_CLIP_( samp, -0x80, 0x7F );
-        *dest = (signed char) samp;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int8_DitherClip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    signed char *dest =  (signed char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        /* use smaller scaler to prevent overflow when we add the dither */
-        float dithered = (*src * (126.0f)) + dither;
-        PaInt32 samp = (PaInt32) dithered;
-        PA_CLIP_( samp, -0x80, 0x7F );
-        *dest = (signed char) samp;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_UInt8(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    unsigned char *dest =  (unsigned char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        unsigned char samp = (unsigned char)(128 + ((unsigned char) (*src * (127.0f))));
-        *dest = samp;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_UInt8_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    unsigned char *dest =  (unsigned char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        /* IMPLEMENT ME */
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_UInt8_Clip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    unsigned char *dest =  (unsigned char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        /* IMPLEMENT ME */
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_UInt8_DitherClip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    float *src = (float*)sourceBuffer;
-    unsigned char *dest =  (unsigned char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        /* IMPLEMENT ME */
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int32_To_Float32(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt32 *src = (PaInt32*)sourceBuffer;
-    float *dest =  (float*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        *dest = (float) ((double)*src * const_1_div_2147483648_);
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int32_To_Int24(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt32 *src    = (PaInt32*)sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-    (void) ditherGenerator; /* unused parameter */
-    
-	while( count-- )
-    {
-		/* REVIEW */
-#if defined(PA_LITTLE_ENDIAN)
-        dest[0] = (unsigned char)(*src >> 8);
-        dest[1] = (unsigned char)(*src >> 16);
-        dest[2] = (unsigned char)(*src >> 24);
-#elif defined(PA_BIG_ENDIAN)
-        dest[0] = (unsigned char)(*src >> 24);
-        dest[1] = (unsigned char)(*src >> 16);
-        dest[2] = (unsigned char)(*src >> 8);
-#endif
-        src += sourceStride;
-        dest += destinationStride * 3;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int32_To_Int24_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    (void) destinationBuffer; /* unused parameters */
-    (void) destinationStride; /* unused parameters */
-    (void) sourceBuffer; /* unused parameters */
-    (void) sourceStride; /* unused parameters */
-    (void) count; /* unused parameters */
-    (void) ditherGenerator; /* unused parameters */
-    /* IMPLEMENT ME */
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int32_To_Int16(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt32 *src = (PaInt32*)sourceBuffer;
-    PaInt16 *dest =  (PaInt16*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        *dest = (PaInt16) ((*src) >> 16);
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int32_To_Int16_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt32 *src = (PaInt32*)sourceBuffer;
-    PaInt16 *dest =  (PaInt16*)destinationBuffer;
-    PaInt32 dither;
-
-    while( count-- )
-    {
-        /* REVIEW */
-        dither = PaUtil_Generate16BitTriangularDither( ditherGenerator );
-        *dest = (PaInt16) ((((*src)>>1) + dither) >> 15);
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int32_To_Int8(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt32 *src = (PaInt32*)sourceBuffer;
-    signed char *dest =  (signed char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        *dest = (signed char) ((*src) >> 24);
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int32_To_Int8_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt32 *src = (PaInt32*)sourceBuffer;
-    signed char *dest =  (signed char*)destinationBuffer;
-    PaInt32 dither;
-
-    while( count-- )
-    {
-        /* REVIEW */
-        dither = PaUtil_Generate16BitTriangularDither( ditherGenerator );
-        *dest = (signed char) ((((*src)>>1) + dither) >> 23);
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int32_To_UInt8(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt32 *src = (PaInt32*)sourceBuffer;
-    unsigned char *dest =  (unsigned char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-		(*dest) = (unsigned char)(((*src) >> 24) + 128); 
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int32_To_UInt8_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt32 *src = (PaInt32*)sourceBuffer;
-    unsigned char *dest =  (unsigned char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        /* IMPLEMENT ME */
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int24_To_Float32(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    unsigned char *src = (unsigned char*)sourceBuffer;
-    float *dest = (float*)destinationBuffer;
-    PaInt32 temp;
-
-    (void) ditherGenerator; /* unused parameter */
-    
-    while( count-- )
-    {
-
-#if defined(PA_LITTLE_ENDIAN)
-        temp = (((long)src[0]) << 8);  
-        temp = temp | (((long)src[1]) << 16);
-        temp = temp | (((long)src[2]) << 24);
-#elif defined(PA_BIG_ENDIAN)
-        temp = (((long)src[0]) << 24);
-        temp = temp | (((long)src[1]) << 16);
-        temp = temp | (((long)src[2]) << 8);
-#endif
-
-        *dest = (float) ((double)temp * const_1_div_2147483648_);
-
-        src += sourceStride * 3;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int24_To_Int32(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    unsigned char *src  = (unsigned char*)sourceBuffer;
-    PaInt32 *dest = (PaInt32*)  destinationBuffer;
-    PaInt32 temp;
-
-    (void) ditherGenerator; /* unused parameter */
-    
-    while( count-- )
-    {
-
-#if defined(PA_LITTLE_ENDIAN)
-        temp = (((long)src[0]) << 8);  
-        temp = temp | (((long)src[1]) << 16);
-        temp = temp | (((long)src[2]) << 24);
-#elif defined(PA_BIG_ENDIAN)
-        temp = (((long)src[0]) << 24);
-        temp = temp | (((long)src[1]) << 16);
-        temp = temp | (((long)src[2]) << 8);
-#endif
-
-        *dest = temp;
-
-        src += sourceStride * 3;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int24_To_Int16(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    unsigned char *src = (unsigned char*)sourceBuffer;
-    PaInt16 *dest = (PaInt16*)destinationBuffer;
-    
-    PaInt16 temp;
-
-    (void) ditherGenerator; /* unused parameter */
-        
-    while( count-- )
-    {
-		
-#if defined(PA_LITTLE_ENDIAN)
-		/* src[0] is discarded */
-        temp = (((PaInt16)src[1]));
-        temp = temp | (PaInt16)(((PaInt16)src[2]) << 8);
-#elif defined(PA_BIG_ENDIAN)
-		/* src[2] is discarded */
-        temp = (PaInt16)(((PaInt16)src[0]) << 8);
-        temp = temp | (((PaInt16)src[1]));
-#endif
-
-        *dest = temp;
-
-        src += sourceStride * 3;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int24_To_Int16_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    (void) destinationBuffer; /* unused parameters */
-    (void) destinationStride; /* unused parameters */
-    (void) sourceBuffer; /* unused parameters */
-    (void) sourceStride; /* unused parameters */
-    (void) count; /* unused parameters */
-    (void) ditherGenerator; /* unused parameters */
-    /* IMPLEMENT ME */
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int24_To_Int8(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    unsigned char *src = (unsigned char*)sourceBuffer;
-    signed char  *dest = (signed char*)destinationBuffer;
-    
-    (void) ditherGenerator; /* unused parameter */
-        
-    while( count-- )
-    {	
-	
-#if defined(PA_LITTLE_ENDIAN)
-		/* src[0] is discarded */
-		/* src[1] is discarded */
-        *dest = src[2];
-#elif defined(PA_BIG_ENDIAN)
-		/* src[2] is discarded */
-		/* src[1] is discarded */
-		*dest = src[0];
-#endif
-
-        src += sourceStride * 3;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int24_To_Int8_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    (void) destinationBuffer; /* unused parameters */
-    (void) destinationStride; /* unused parameters */
-    (void) sourceBuffer; /* unused parameters */
-    (void) sourceStride; /* unused parameters */
-    (void) count; /* unused parameters */
-    (void) ditherGenerator; /* unused parameters */
-    /* IMPLEMENT ME */
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int24_To_UInt8(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    unsigned char *src = (unsigned char*)sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-    
-    (void) ditherGenerator; /* unused parameter */
-        
-    while( count-- )
-    {
-		
-#if defined(PA_LITTLE_ENDIAN)
-		/* src[0] is discarded */
-		/* src[1] is discarded */
-        *dest = (unsigned char)(src[2] + 128);
-#elif defined(PA_BIG_ENDIAN)
-        *dest = (unsigned char)(src[0] + 128);
-		/* src[1] is discarded */
-		/* src[2] is discarded */		
-#endif
-
-        src += sourceStride * 3;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int24_To_UInt8_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    (void) destinationBuffer; /* unused parameters */
-    (void) destinationStride; /* unused parameters */
-    (void) sourceBuffer; /* unused parameters */
-    (void) sourceStride; /* unused parameters */
-    (void) count; /* unused parameters */
-    (void) ditherGenerator; /* unused parameters */
-    /* IMPLEMENT ME */
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int16_To_Float32(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt16 *src = (PaInt16*)sourceBuffer;
-    float *dest =  (float*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        float samp = *src * const_1_div_32768_; /* FIXME: i'm concerned about this being asymetrical with float->int16 -rb */
-        *dest = samp;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int16_To_Int32(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt16 *src = (PaInt16*)sourceBuffer;
-    PaInt32 *dest =  (PaInt32*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        /* REVIEW: we should consider something like
-            (*src << 16) | (*src & 0xFFFF)
-        */
-        
-        *dest = *src << 16;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int16_To_Int24(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt16 *src   = (PaInt16*) sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-    PaInt16 temp;
-
-    (void) ditherGenerator; /* unused parameter */
-    
-    while( count-- )
-    {
-        temp = *src;
-        
-#if defined(PA_LITTLE_ENDIAN)
-        dest[0] = 0;
-        dest[1] = (unsigned char)(temp);
-        dest[2] = (unsigned char)(temp >> 8);
-#elif defined(PA_BIG_ENDIAN)
-        dest[0] = (unsigned char)(temp >> 8);
-        dest[1] = (unsigned char)(temp);
-        dest[2] = 0;
-#endif
-
-        src += sourceStride;
-        dest += destinationStride * 3;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int16_To_Int8(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt16 *src = (PaInt16*)sourceBuffer;
-    signed char *dest =  (signed char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        (*dest) = (signed char)((*src) >> 8);
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int16_To_Int8_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt16 *src = (PaInt16*)sourceBuffer;
-    signed char *dest =  (signed char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        /* IMPLEMENT ME */
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int16_To_UInt8(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt16 *src = (PaInt16*)sourceBuffer;
-    unsigned char *dest =  (unsigned char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-		(*dest) = (unsigned char)(((*src) >> 8) + 128); 
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int16_To_UInt8_Dither(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaInt16 *src = (PaInt16*)sourceBuffer;
-    unsigned char *dest =  (unsigned char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        /* IMPLEMENT ME */
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int8_To_Float32(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    signed char *src = (signed char*)sourceBuffer;
-    float *dest =  (float*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        float samp = *src * const_1_div_128_;
-        *dest = samp;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int8_To_Int32(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    signed char *src = (signed char*)sourceBuffer;
-    PaInt32 *dest =  (PaInt32*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-		(*dest) = (*src) << 24;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int8_To_Int24(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    signed char *src = (signed char*)sourceBuffer;
-    unsigned char *dest =  (unsigned char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-
-#if defined(PA_LITTLE_ENDIAN)
-        dest[0] = 0;
-        dest[1] = 0;
-        dest[2] = (*src);
-#elif defined(PA_BIG_ENDIAN)
-        dest[0] = (*src);
-        dest[1] = 0;
-        dest[2] = 0;
-#endif
-
-        src += sourceStride;
-        dest += destinationStride * 3;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int8_To_Int16(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    signed char *src = (signed char*)sourceBuffer;
-    PaInt16 *dest =  (PaInt16*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        (*dest) = (PaInt16)((*src) << 8);
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Int8_To_UInt8(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    signed char *src = (signed char*)sourceBuffer;
-    unsigned char *dest =  (unsigned char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        (*dest) = (unsigned char)(*src + 128);
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void UInt8_To_Float32(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    unsigned char *src = (unsigned char*)sourceBuffer;
-    float *dest =  (float*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        float samp = (*src - 128) * const_1_div_128_;
-        *dest = samp;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void UInt8_To_Int32(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    unsigned char *src = (unsigned char*)sourceBuffer;
-    PaInt32 *dest = (PaInt32*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-		(*dest) = (*src - 128) << 24;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void UInt8_To_Int24(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-	unsigned char *src  = (unsigned char*)sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-    (void) ditherGenerator; /* unused parameters */
-    
-	while( count-- )
-    {
-
-#if defined(PA_LITTLE_ENDIAN)
-        dest[0] = 0;
-        dest[1] = 0;
-        dest[2] = (unsigned char)(*src - 128);
-#elif defined(PA_BIG_ENDIAN)
-        dest[0] = (unsigned char)(*src - 128);
-        dest[1] = 0;
-        dest[2] = 0;
-#endif
-		
-        src += sourceStride;
-        dest += destinationStride * 3;    
-	}
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void UInt8_To_Int16(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    unsigned char *src = (unsigned char*)sourceBuffer;
-    PaInt16 *dest =  (PaInt16*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        (*dest) = (PaInt16)((*src - 128) << 8);
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void UInt8_To_Int8(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    unsigned char *src = (unsigned char*)sourceBuffer;
-    signed char  *dest = (signed char*)destinationBuffer;
-    (void)ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        (*dest) = (signed char)(*src - 128);
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Copy_8_To_8(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    unsigned char *src = (unsigned char*)sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-                                                      
-    (void) ditherGenerator; /* unused parameter */
-
-    while( count-- )
-    {
-        *dest = *src;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Copy_16_To_16(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaUint16 *src = (PaUint16 *)sourceBuffer;
-    PaUint16 *dest = (PaUint16 *)destinationBuffer;
-                                                        
-    (void) ditherGenerator; /* unused parameter */
-    
-    while( count-- )
-    {
-        *dest = *src;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Copy_24_To_24(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    unsigned char *src = (unsigned char*)sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-
-    (void) ditherGenerator; /* unused parameter */
-    
-    while( count-- )
-    {
-        dest[0] = src[0];
-        dest[1] = src[1];
-        dest[2] = src[2];
-
-        src += sourceStride * 3;
-        dest += destinationStride * 3;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Copy_32_To_32(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    PaUint32 *dest = (PaUint32 *)destinationBuffer;
-    PaUint32 *src = (PaUint32 *)sourceBuffer;
-
-    (void) ditherGenerator; /* unused parameter */
-    
-    while( count-- )
-    {
-        *dest = *src;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-PaUtilConverterTable paConverters = {
-    Float32_To_Int32,              /* PaUtilConverter *Float32_To_Int32; */
-    Float32_To_Int32_Dither,       /* PaUtilConverter *Float32_To_Int32_Dither; */
-    Float32_To_Int32_Clip,         /* PaUtilConverter *Float32_To_Int32_Clip; */
-    Float32_To_Int32_DitherClip,   /* PaUtilConverter *Float32_To_Int32_DitherClip; */
-
-    Float32_To_Int24,              /* PaUtilConverter *Float32_To_Int24; */
-    Float32_To_Int24_Dither,       /* PaUtilConverter *Float32_To_Int24_Dither; */
-    Float32_To_Int24_Clip,         /* PaUtilConverter *Float32_To_Int24_Clip; */
-    Float32_To_Int24_DitherClip,   /* PaUtilConverter *Float32_To_Int24_DitherClip; */
-    
-    Float32_To_Int16,              /* PaUtilConverter *Float32_To_Int16; */
-    Float32_To_Int16_Dither,       /* PaUtilConverter *Float32_To_Int16_Dither; */
-    Float32_To_Int16_Clip,         /* PaUtilConverter *Float32_To_Int16_Clip; */
-    Float32_To_Int16_DitherClip,   /* PaUtilConverter *Float32_To_Int16_DitherClip; */
-
-    Float32_To_Int8,               /* PaUtilConverter *Float32_To_Int8; */
-    Float32_To_Int8_Dither,        /* PaUtilConverter *Float32_To_Int8_Dither; */
-    Float32_To_Int8_Clip,          /* PaUtilConverter *Float32_To_Int8_Clip; */
-    Float32_To_Int8_DitherClip,    /* PaUtilConverter *Float32_To_Int8_DitherClip; */
-
-    Float32_To_UInt8,              /* PaUtilConverter *Float32_To_UInt8; */
-    Float32_To_UInt8_Dither,       /* PaUtilConverter *Float32_To_UInt8_Dither; */
-    Float32_To_UInt8_Clip,         /* PaUtilConverter *Float32_To_UInt8_Clip; */
-    Float32_To_UInt8_DitherClip,   /* PaUtilConverter *Float32_To_UInt8_DitherClip; */
-
-    Int32_To_Float32,              /* PaUtilConverter *Int32_To_Float32; */
-    Int32_To_Int24,                /* PaUtilConverter *Int32_To_Int24; */
-    Int32_To_Int24_Dither,         /* PaUtilConverter *Int32_To_Int24_Dither; */
-    Int32_To_Int16,                /* PaUtilConverter *Int32_To_Int16; */
-    Int32_To_Int16_Dither,         /* PaUtilConverter *Int32_To_Int16_Dither; */
-    Int32_To_Int8,                 /* PaUtilConverter *Int32_To_Int8; */
-    Int32_To_Int8_Dither,          /* PaUtilConverter *Int32_To_Int8_Dither; */
-    Int32_To_UInt8,                /* PaUtilConverter *Int32_To_UInt8; */
-    Int32_To_UInt8_Dither,         /* PaUtilConverter *Int32_To_UInt8_Dither; */
-
-    Int24_To_Float32,              /* PaUtilConverter *Int24_To_Float32; */
-    Int24_To_Int32,                /* PaUtilConverter *Int24_To_Int32; */
-    Int24_To_Int16,                /* PaUtilConverter *Int24_To_Int16; */
-    Int24_To_Int16_Dither,         /* PaUtilConverter *Int24_To_Int16_Dither; */
-    Int24_To_Int8,                 /* PaUtilConverter *Int24_To_Int8; */
-    Int24_To_Int8_Dither,          /* PaUtilConverter *Int24_To_Int8_Dither; */
-    Int24_To_UInt8,                /* PaUtilConverter *Int24_To_UInt8; */
-    Int24_To_UInt8_Dither,         /* PaUtilConverter *Int24_To_UInt8_Dither; */
-
-    Int16_To_Float32,              /* PaUtilConverter *Int16_To_Float32; */
-    Int16_To_Int32,                /* PaUtilConverter *Int16_To_Int32; */
-    Int16_To_Int24,                /* PaUtilConverter *Int16_To_Int24; */
-    Int16_To_Int8,                 /* PaUtilConverter *Int16_To_Int8; */
-    Int16_To_Int8_Dither,          /* PaUtilConverter *Int16_To_Int8_Dither; */
-    Int16_To_UInt8,                /* PaUtilConverter *Int16_To_UInt8; */
-    Int16_To_UInt8_Dither,         /* PaUtilConverter *Int16_To_UInt8_Dither; */
-
-    Int8_To_Float32,               /* PaUtilConverter *Int8_To_Float32; */
-    Int8_To_Int32,                 /* PaUtilConverter *Int8_To_Int32; */
-    Int8_To_Int24,                 /* PaUtilConverter *Int8_To_Int24 */
-    Int8_To_Int16,                 /* PaUtilConverter *Int8_To_Int16; */
-    Int8_To_UInt8,                 /* PaUtilConverter *Int8_To_UInt8; */
-
-    UInt8_To_Float32,              /* PaUtilConverter *UInt8_To_Float32; */
-    UInt8_To_Int32,                /* PaUtilConverter *UInt8_To_Int32; */
-    UInt8_To_Int24,                /* PaUtilConverter *UInt8_To_Int24; */
-    UInt8_To_Int16,                /* PaUtilConverter *UInt8_To_Int16; */
-    UInt8_To_Int8,                 /* PaUtilConverter *UInt8_To_Int8; */
-
-    Copy_8_To_8,                   /* PaUtilConverter *Copy_8_To_8; */
-    Copy_16_To_16,                 /* PaUtilConverter *Copy_16_To_16; */
-    Copy_24_To_24,                 /* PaUtilConverter *Copy_24_To_24; */
-    Copy_32_To_32                  /* PaUtilConverter *Copy_32_To_32; */
-};
-
-/* -------------------------------------------------------------------------- */
-
-#endif /* PA_NO_STANDARD_CONVERTERS */
-
-/* -------------------------------------------------------------------------- */
-
-PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat )
-{
-    switch( destinationFormat & ~paNonInterleaved ){
-    case paFloat32:
-        return paZeroers.Zero32;
-    case paInt32:
-        return paZeroers.Zero32;
-    case paInt24:
-        return paZeroers.Zero24;
-    case paInt16:
-        return paZeroers.Zero16;
-    case paInt8:
-        return paZeroers.Zero8;
-    case paUInt8:
-        return paZeroers.ZeroU8;
-    default: return 0;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-#ifdef PA_NO_STANDARD_ZEROERS
-
-/* -------------------------------------------------------------------------- */
-
-PaUtilZeroerTable paZeroers = {
-    0,  /* PaUtilZeroer *ZeroU8; */
-    0,  /* PaUtilZeroer *Zero8; */
-    0,  /* PaUtilZeroer *Zero16; */
-    0,  /* PaUtilZeroer *Zero24; */
-    0,  /* PaUtilZeroer *Zero32; */
-};
-
-/* -------------------------------------------------------------------------- */
-
-#else /* PA_NO_STANDARD_ZEROERS is not defined */
-
-/* -------------------------------------------------------------------------- */
-
-static void ZeroU8( void *destinationBuffer, signed int destinationStride,
-        unsigned int count )
-{
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-
-    while( count-- )
-    {
-        *dest = 128;
-
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Zero8( void *destinationBuffer, signed int destinationStride,
-        unsigned int count )
-{
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-
-    while( count-- )
-    {
-        *dest = 0;
-
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Zero16( void *destinationBuffer, signed int destinationStride,
-        unsigned int count )
-{
-    PaUint16 *dest = (PaUint16 *)destinationBuffer;
-
-    while( count-- )
-    {
-        *dest = 0;
-
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Zero24( void *destinationBuffer, signed int destinationStride,
-        unsigned int count )
-{
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-
-    while( count-- )
-    {
-        dest[0] = 0;
-        dest[1] = 0;
-        dest[2] = 0;
-
-        dest += destinationStride * 3;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Zero32( void *destinationBuffer, signed int destinationStride,
-        unsigned int count )
-{
-    PaUint32 *dest = (PaUint32 *)destinationBuffer;
-
-    while( count-- )
-    {
-        *dest = 0;
-
-        dest += destinationStride;
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-PaUtilZeroerTable paZeroers = {
-    ZeroU8,  /* PaUtilZeroer *ZeroU8; */
-    Zero8,  /* PaUtilZeroer *Zero8; */
-    Zero16,  /* PaUtilZeroer *Zero16; */
-    Zero24,  /* PaUtilZeroer *Zero24; */
-    Zero32,  /* PaUtilZeroer *Zero32; */
-};
-
-/* -------------------------------------------------------------------------- */
-
-#endif /* PA_NO_STANDARD_ZEROERS */
diff --git a/portaudio/pa_common/pa_converters.h b/portaudio/pa_common/pa_converters.h
deleted file mode 100644
index 831c9c641..000000000
--- a/portaudio/pa_common/pa_converters.h
+++ /dev/null
@@ -1,254 +0,0 @@
-#ifndef PA_CONVERTERS_H
-#define PA_CONVERTERS_H
-/*
- * $Id: pa_converters.h,v 1.1.2.9 2003/09/20 21:05:14 rossbencina Exp $
- * Portable Audio I/O Library sample conversion mechanism
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Phil Burk, 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.
- */
-
-/** @file
- @brief Conversion functions used to convert buffers of samples from one
- format to another.
-*/
-
-
-#include "portaudio.h"  /* for PaSampleFormat */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-struct PaUtilTriangularDitherGenerator;
-
-
-/** Choose an available sample format which is most appropriate for
- representing the requested format. If the requested format is not available
- higher quality formats are considered before lower quality formates.
- @param availableFormats A variable containing the logical OR of all available
- formats.
- @param format The desired format.
- @return The most appropriate available format for representing the requested
- format.
-*/
-PaSampleFormat PaUtil_SelectClosestAvailableFormat(
-        PaSampleFormat availableFormats, PaSampleFormat format );
-
-
-/* high level conversions functions for use by implementations */
-
-
-/** The generic sample converter prototype. Sample converters convert count
-    samples from sourceBuffer to destinationBuffer. The actual type of the data
-    pointed to by these parameters varys for different converter functions.
-    @param destinationBuffer A pointer to the first sample of the destination.
-    @param destinationStride An offset between successive destination samples
-    expressed in samples (not bytes.) It may be negative.
-    @param sourceBuffer A pointer to the first sample of the source.
-    @param sourceStride An offset between successive source samples
-    expressed in samples (not bytes.) It may be negative.
-    @param count The number of samples to convert.
-    @param ditherState State information used to calculate dither. Converters
-    that do not perform dithering will ignore this parameter, in which case
-    NULL or invalid dither state may be passed.
-*/
-typedef void PaUtilConverter(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator );
-
-
-/** Find a sample converter function for the given source and destinations
-    formats and flags (clip and dither.)
-    @return
-    A pointer to a PaUtilConverter which will perform the requested
-    conversion, or NULL if the given format conversion is not supported.
-    For conversions where clipping or dithering is not necessary, the
-    clip and dither flags are ignored and a non-clipping or dithering
-    version is returned.
-    If the source and destination formats are the same, a function which
-    copies data of the appropriate size will be returned.
-*/
-PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat,
-        PaSampleFormat destinationFormat, PaStreamFlags flags );
-
-
-/** The generic buffer zeroer prototype. Buffer zeroers copy count zeros to
-    destinationBuffer. The actual type of the data pointed to varys for
-    different zeroer functions.
-    @param destinationBuffer A pointer to the first sample of the destination.
-    @param destinationStride An offset between successive destination samples
-    expressed in samples (not bytes.) It may be negative.
-    @param count The number of samples to zero.
-*/
-typedef void PaUtilZeroer(
-    void *destinationBuffer, signed int destinationStride, unsigned int count );
-
-    
-/** Find a buffer zeroer function for the given destination format.
-    @return
-    A pointer to a PaUtilZeroer which will perform the requested
-    zeroing.
-*/
-PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat );
-
-/*----------------------------------------------------------------------------*/
-/* low level functions and data structures which may be used for
-    substituting conversion functions */
-
-
-/** The type used to store all sample conversion functions.
-    @see paConverters;
-*/
-typedef struct{
-    PaUtilConverter *Float32_To_Int32;
-    PaUtilConverter *Float32_To_Int32_Dither;
-    PaUtilConverter *Float32_To_Int32_Clip;
-    PaUtilConverter *Float32_To_Int32_DitherClip;
-
-    PaUtilConverter *Float32_To_Int24;
-    PaUtilConverter *Float32_To_Int24_Dither;
-    PaUtilConverter *Float32_To_Int24_Clip;
-    PaUtilConverter *Float32_To_Int24_DitherClip;
-    
-    PaUtilConverter *Float32_To_Int16;
-    PaUtilConverter *Float32_To_Int16_Dither;
-    PaUtilConverter *Float32_To_Int16_Clip;
-    PaUtilConverter *Float32_To_Int16_DitherClip;
-
-    PaUtilConverter *Float32_To_Int8;
-    PaUtilConverter *Float32_To_Int8_Dither;
-    PaUtilConverter *Float32_To_Int8_Clip;
-    PaUtilConverter *Float32_To_Int8_DitherClip;
-
-    PaUtilConverter *Float32_To_UInt8;
-    PaUtilConverter *Float32_To_UInt8_Dither;
-    PaUtilConverter *Float32_To_UInt8_Clip;
-    PaUtilConverter *Float32_To_UInt8_DitherClip;
-
-    PaUtilConverter *Int32_To_Float32;
-    PaUtilConverter *Int32_To_Int24;
-    PaUtilConverter *Int32_To_Int24_Dither;
-    PaUtilConverter *Int32_To_Int16;
-    PaUtilConverter *Int32_To_Int16_Dither;
-    PaUtilConverter *Int32_To_Int8;
-    PaUtilConverter *Int32_To_Int8_Dither;
-    PaUtilConverter *Int32_To_UInt8;
-    PaUtilConverter *Int32_To_UInt8_Dither;
-
-    PaUtilConverter *Int24_To_Float32;
-    PaUtilConverter *Int24_To_Int32;
-    PaUtilConverter *Int24_To_Int16;
-    PaUtilConverter *Int24_To_Int16_Dither;
-    PaUtilConverter *Int24_To_Int8;
-    PaUtilConverter *Int24_To_Int8_Dither;
-    PaUtilConverter *Int24_To_UInt8;
-    PaUtilConverter *Int24_To_UInt8_Dither;
-
-    PaUtilConverter *Int16_To_Float32;
-    PaUtilConverter *Int16_To_Int32;
-    PaUtilConverter *Int16_To_Int24;
-    PaUtilConverter *Int16_To_Int8;
-    PaUtilConverter *Int16_To_Int8_Dither;
-    PaUtilConverter *Int16_To_UInt8;
-    PaUtilConverter *Int16_To_UInt8_Dither;
-
-    PaUtilConverter *Int8_To_Float32;
-    PaUtilConverter *Int8_To_Int32;
-    PaUtilConverter *Int8_To_Int24;
-    PaUtilConverter *Int8_To_Int16;
-    PaUtilConverter *Int8_To_UInt8;
-    
-    PaUtilConverter *UInt8_To_Float32;
-    PaUtilConverter *UInt8_To_Int32;
-    PaUtilConverter *UInt8_To_Int24;
-    PaUtilConverter *UInt8_To_Int16;
-    PaUtilConverter *UInt8_To_Int8;
-
-    PaUtilConverter *Copy_8_To_8;       /* copy without any conversion */
-    PaUtilConverter *Copy_16_To_16;     /* copy without any conversion */
-    PaUtilConverter *Copy_24_To_24;     /* copy without any conversion */
-    PaUtilConverter *Copy_32_To_32;     /* copy without any conversion */
-} PaUtilConverterTable;
-
-
-/** A table of pointers to all required converter functions.
-    PaUtil_SelectConverter() uses this table to lookup the appropriate
-    conversion functions. The fields of this structure are initialized
-    with default conversion functions. Fields may be NULL, indicating that
-    no conversion function is available. User code may substitue optimised
-    conversion functions by assigning different function pointers to
-    these fields.
-
-    @note
-    If the PA_NO_STANDARD_CONVERTERS preprocessor variable is defined,
-    PortAudio's standard converters will not be compiled, and all fields
-    of this structure will be initialized to NULL. In such cases, users
-    should supply their own conversion functions if the require PortAudio
-    to open a stream that requires sample conversion.
-
-    @see PaUtilConverterTable, PaUtilConverter, PaUtil_SelectConverter
-*/
-extern PaUtilConverterTable paConverters;
-
-
-/** The type used to store all buffer zeroing functions.
-    @see paZeroers;
-*/
-typedef struct{
-    PaUtilZeroer *ZeroU8; /* unsigned 8 bit, zero == 128 */
-    PaUtilZeroer *Zero8;
-    PaUtilZeroer *Zero16;
-    PaUtilZeroer *Zero24;
-    PaUtilZeroer *Zero32;
-} PaUtilZeroerTable;
-
-
-/** A table of pointers to all required zeroer functions.
-    PaUtil_SelectZeroer() uses this table to lookup the appropriate
-    conversion functions. The fields of this structure are initialized
-    with default conversion functions. User code may substitue optimised
-    conversion functions by assigning different function pointers to
-    these fields.
-
-    @note
-    If the PA_NO_STANDARD_ZEROERS preprocessor variable is defined,
-    PortAudio's standard zeroers will not be compiled, and all fields
-    of this structure will be initialized to NULL. In such cases, users
-    should supply their own zeroing functions for the sample sizes which
-    they intend to use.
-
-    @see PaUtilZeroerTable, PaUtilZeroer, PaUtil_SelectZeroer
-*/
-extern PaUtilZeroerTable paZeroers;
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PA_CONVERTERS_H */
diff --git a/portaudio/pa_common/pa_cpuload.c b/portaudio/pa_common/pa_cpuload.c
deleted file mode 100644
index e70fbf4ec..000000000
--- a/portaudio/pa_common/pa_cpuload.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * $Id: pa_cpuload.c,v 1.1.2.14 2004/01/08 22:01:12 rossbencina Exp $
- * Portable Audio I/O Library CPU Load measurement functions
- * Portable CPU load measurement facility.
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 2002 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.
- */
-
-/** @file
- @brief Functions to assist in measuring the CPU utilization of a callback
- stream. Used to implement the Pa_GetStreamCpuLoad() function.
-
- @todo Dynamically calculate the coefficients used to smooth the CPU Load
- Measurements over time to provide a uniform characterisation of CPU Load
- independent of rate at which PaUtil_BeginCpuLoadMeasurement /
- PaUtil_EndCpuLoadMeasurement are called.
-*/
-
-
-#include "pa_cpuload.h"
-
-#include <assert.h>
-
-#include "pa_util.h"   /* for PaUtil_GetTime() */
-
-
-void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate )
-{
-    assert( sampleRate > 0 );
-
-    measurer->samplingPeriod = 1. / sampleRate;
-    measurer->averageLoad = 0.;
-}
-
-void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer )
-{
-    measurer->averageLoad = 0.;
-}
-
-void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer )
-{
-    measurer->measurementStartTime = PaUtil_GetTime();
-}
-
-
-void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed )
-{
-    double measurementEndTime, secondsFor100Percent, measuredLoad;
-
-    if( framesProcessed > 0 ){
-        measurementEndTime = PaUtil_GetTime();
-
-        assert( framesProcessed > 0 );
-        secondsFor100Percent = framesProcessed * measurer->samplingPeriod;
-
-        measuredLoad = (measurementEndTime - measurer->measurementStartTime) / secondsFor100Percent;
-
-        /* Low pass filter the calculated CPU load to reduce jitter using a simple IIR low pass filter. */
-        /** FIXME @todo these coefficients shouldn't be hardwired */
-#define LOWPASS_COEFFICIENT_0   (0.9)
-#define LOWPASS_COEFFICIENT_1   (0.99999 - LOWPASS_COEFFICIENT_0)
-
-        measurer->averageLoad = (LOWPASS_COEFFICIENT_0 * measurer->averageLoad) +
-                               (LOWPASS_COEFFICIENT_1 * measuredLoad);
-    }
-}
-
-
-double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer )
-{
-    return measurer->averageLoad;
-}
diff --git a/portaudio/pa_common/pa_cpuload.h b/portaudio/pa_common/pa_cpuload.h
deleted file mode 100644
index f77d91995..000000000
--- a/portaudio/pa_common/pa_cpuload.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef PA_CPULOAD_H
-#define PA_CPULOAD_H
-/*
- * $Id: pa_cpuload.h,v 1.1.2.10 2004/01/08 22:01:12 rossbencina Exp $
- * Portable Audio I/O Library CPU Load measurement functions
- * Portable CPU load measurement facility.
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 2002 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.
- */
-
-/** @file
- @brief Functions to assist in measuring the CPU utilization of a callback
- stream. Used to implement the Pa_GetStreamCpuLoad() function.
-*/
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-typedef struct {
-    double samplingPeriod;
-    double measurementStartTime;
-    double averageLoad;
-} PaUtilCpuLoadMeasurer; /**< @todo need better name than measurer */
-
-void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate );
-void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer );
-void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed );
-void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer );
-double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer );
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */     
-#endif /* PA_CPULOAD_H */
diff --git a/portaudio/pa_common/pa_dither.c b/portaudio/pa_common/pa_dither.c
deleted file mode 100644
index 0600db625..000000000
--- a/portaudio/pa_common/pa_dither.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * $Id: pa_dither.c,v 1.1.2.6 2005/05/28 22:49:02 rossbencina Exp $
- * Portable Audio I/O Library triangular dither generator
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Phil Burk, 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.
- */
-
-/** @file
- @brief Functions for generating dither noise
-*/
-
-
-#include "pa_dither.h"
-#include "pa_types.h"
-
-#define PA_DITHER_BITS_   (15)
-
-
-void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *state )
-{
-    state->previous = 0;
-    state->randSeed1 = 22222;
-    state->randSeed2 = 5555555;
-}
-
-
-signed long PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *state )
-{
-    signed long current, highPass;
-
-    /* Generate two random numbers. */
-    state->randSeed1 = (state->randSeed1 * 196314165) + 907633515;
-    state->randSeed2 = (state->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_  ((SIZEOF_LONG*8 - PA_DITHER_BITS_) + 1)
-    current = (((signed long)state->randSeed1)>>DITHER_SHIFT_) +
-              (((signed long)state->randSeed2)>>DITHER_SHIFT_);
-
-    /* High pass filter to reduce audibility. */
-    highPass = current - state->previous;
-    state->previous = current;
-    return highPass;
-}
-
-
-/* Multiply by PA_FLOAT_DITHER_SCALE_ to get a float between -2.0 and +1.99999 */
-#define PA_FLOAT_DITHER_SCALE_  (1.0f / ((1<<PA_DITHER_BITS_)-1))
-static const float const_float_dither_scale_ = PA_FLOAT_DITHER_SCALE_;
-
-float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *state )
-{
-    signed long current, highPass;
-
-    /* Generate two random numbers. */
-    state->randSeed1 = (state->randSeed1 * 196314165) + 907633515;
-    state->randSeed2 = (state->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_  ((SIZEOF_LONG*8 - PA_DITHER_BITS_) + 1)
-    current = (((signed long)state->randSeed1)>>DITHER_SHIFT_) +
-              (((signed long)state->randSeed2)>>DITHER_SHIFT_);
-
-    /* High pass filter to reduce audibility. */
-    highPass = current - state->previous;
-    state->previous = current;
-    return ((float)highPass) * const_float_dither_scale_;
-}
-
-
-/*
-The following alternate dither algorithms (from musicdsp.org) could be
-considered
-*/
-
-/*Noise shaped dither  (March 2000)
--------------------
-
-This is a simple implementation of highpass triangular-PDF dither with
-2nd-order noise shaping, for use when truncating floating point audio
-data to fixed point.
-
-The noise shaping lowers the noise floor by 11dB below 5kHz (@ 44100Hz
-sample rate) compared to triangular-PDF dither. The code below assumes
-input data is in the range +1 to -1 and doesn't check for overloads!
-
-To save time when generating dither for multiple channels you can do
-things like this:  r3=(r1 & 0x7F)<<8; instead of calling rand() again.
-
-
-
-  int   r1, r2;                //rectangular-PDF random numbers
-  float s1, s2;                //error feedback buffers
-  float s = 0.5f;              //set to 0.0f for no noise shaping
-  float w = pow(2.0,bits-1);   //word length (usually bits=16)
-  float wi= 1.0f/w;            
-  float d = wi / RAND_MAX;     //dither amplitude (2 lsb)
-  float o = wi * 0.5f;         //remove dc offset
-  float in, tmp;
-  int   out;
-
-
-//for each sample...
-
-  r2=r1;                               //can make HP-TRI dither by
-  r1=rand();                           //subtracting previous rand()
-    
-  in += s * (s1 + s1 - s2);            //error feedback
-  tmp = in + o + d * (float)(r1 - r2); //dc offset and dither 
-  
-  out = (int)(w * tmp);                //truncate downwards
-  if(tmp<0.0f) out--;                  //this is faster than floor()
-
-  s2 = s1;                            
-  s1 = in - wi * (float)out;           //error
-
-
-
--- 
-paul.kellett@maxim.abel.co.uk
-http://www.maxim.abel.co.uk
-*/
-
-
-/*
-16-to-8-bit first-order dither
-
-Type : First order error feedforward dithering code
-References : Posted by Jon Watte
-
-Notes : 
-This is about as simple a dithering algorithm as you can implement, but it's
-likely to sound better than just truncating to N bits.
-
-Note that you might not want to carry forward the full difference for infinity.
-It's probably likely that the worst performance hit comes from the saturation
-conditionals, which can be avoided with appropriate instructions on many DSPs
-and integer SIMD type instructions, or CMOV.
-
-Last, if sound quality is paramount (such as when going from > 16 bits to 16
-bits) you probably want to use a higher-order dither function found elsewhere
-on this site. 
-
-
-Code : 
-// This code will down-convert and dither a 16-bit signed short 
-// mono signal into an 8-bit unsigned char signal, using a first 
-// order forward-feeding error term dither. 
-
-#define uchar unsigned char 
-
-void dither_one_channel_16_to_8( short * input, uchar * output, int count, int * memory ) 
-{ 
-  int m = *memory; 
-  while( count-- > 0 ) { 
-    int i = *input++; 
-    i += m; 
-    int j = i + 32768 - 128; 
-    uchar o; 
-    if( j < 0 ) { 
-      o = 0; 
-    } 
-    else if( j > 65535 ) { 
-      o = 255; 
-    } 
-    else { 
-      o = (uchar)((j>>8)&0xff); 
-    } 
-    m = ((j-32768+128)-i); 
-    *output++ = o; 
-  } 
-  *memory = m; 
-} 
-*/
diff --git a/portaudio/pa_common/pa_dither.h b/portaudio/pa_common/pa_dither.h
deleted file mode 100644
index 70369e187..000000000
--- a/portaudio/pa_common/pa_dither.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef PA_DITHER_H
-#define PA_DITHER_H
-/*
- * $Id: pa_dither.h,v 1.1.2.4 2003/09/20 21:06:19 rossbencina Exp $
- * Portable Audio I/O Library triangular dither generator
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Phil Burk, 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.
- */
-
-/** @file
- @brief Functions for generating dither noise
-*/
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-/** @brief State needed to generate a dither signal */
-typedef struct PaUtilTriangularDitherGenerator{
-    unsigned long previous;
-    unsigned long randSeed1;
-    unsigned long randSeed2;
-} PaUtilTriangularDitherGenerator;
-
-
-/** @brief Initialize dither state */
-void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *ditherState );
-
-
-/**
- @brief Calculate 2 LSB dither signal with a triangular distribution.
- Ranged for adding to a 1 bit right-shifted 32 bit integer
- prior to >>15. eg:
-<pre>
-    signed long in = *
-    signed long dither = PaUtil_Generate16BitTriangularDither( ditherState );
-    signed short out = (signed short)(((in>>1) + dither) >> 15);
-</pre>
- @return
- A signed long with a range of +32767 to -32768
-*/
-signed long PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *ditherState );
-
-
-/**
- @brief Calculate 2 LSB dither signal with a triangular distribution.
- Ranged for adding to a pre-scaled float.
-<pre>
-    float in = *
-    float dither = PaUtil_GenerateFloatTriangularDither( ditherState );
-    // use smaller scaler to prevent overflow when we add the dither
-    signed short out = (signed short)(in*(32766.0f) + dither );
-</pre>
- @return
- A float with a range of -2.0 to +1.99999.
-*/
-float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *ditherState );
-
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PA_DITHER_H */
diff --git a/portaudio/pa_common/pa_endianness.h b/portaudio/pa_common/pa_endianness.h
deleted file mode 100644
index cb6f8ad5e..000000000
--- a/portaudio/pa_common/pa_endianness.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef PA_ENDIANNESS_H
-#define PA_ENDIANNESS_H
-/*
- * $Id: pa_endianness.h,v 1.1.2.5 2006/02/16 16:26:07 bjornroche Exp $
- * Portable Audio I/O Library current platform endianness macros
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Phil Burk, 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.
- */
-
-/** @file
- @brief Configure endianness symbols for the target processor.
-
- Arrange for either the PA_LITTLE_ENDIAN or PA_BIG_ENDIAN preprocessor symbols
- to be defined. The one that is defined reflects the endianness of the target
- platform and may be used to implement conditional compilation of byte-order
- dependent code.
-
- If either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN is defined already, then no attempt
- is made to override that setting. This may be useful if you have a better way
- of determining the platform's endianness. The autoconf mechanism uses this for
- example.
-
- A PA_VALIDATE_ENDIANNESS macro is provided to compare the compile time
- and runtime endiannes and raise an assertion if they don't match.
-*/
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-#if defined(PA_LITTLE_ENDIAN) || defined(PA_BIG_ENDIAN)
-    /* endianness define has been set externally, such as by autoconf */
-
-    #if defined(PA_LITTLE_ENDIAN) && defined(PA_BIG_ENDIAN)
-    #error both PA_LITTLE_ENDIAN and PA_BIG_ENDIAN have been defined externally to pa_endianness.h - only one endianness at a time please
-    #endif
-
-#else
-    /* endianness define has not been set externally */
-
-    /* set PA_LITTLE_ENDIAN or PA_BIG_ENDIAN by testing well known platform specific defines */
-
-    #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(LITTLE_ENDIAN) || defined(__i386) || defined(_M_IX86)
-
-    #define PA_LITTLE_ENDIAN /* win32, assume intel byte order */
-
-    #else
-		
-		 #define PA_BIG_ENDIAN
-
-#endif
-
-    #if !defined(PA_LITTLE_ENDIAN) && !defined(PA_BIG_ENDIAN)
-    /*
-     If the following error is raised, you either need to modify the code above
-     to automatically determine the endianness from other symbols defined on your
-     platform, or define either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN externally.
-    */
-    #error pa_endianness.h was unable to automatically determine the endianness of the target platform
-    #endif
-    
-#endif
-
-/* PA_VALIDATE_ENDIANNESS compares the compile time and runtime endianness,
- and raises an assertion if they don't match. <assert.h> must be included in
- the context in which this macro is used.
-*/
-#if defined(PA_LITTLE_ENDIAN)
-    #define PA_VALIDATE_ENDIANNESS \
-    { \
-        const long nativeOne = 1; \
-        assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 1 ); \
-    }
-#elif defined(PA_BIG_ENDIAN)
-    #define PA_VALIDATE_ENDIANNESS \
-    { \
-        const long nativeOne = 1; \
-        assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 0 ); \
-    }
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PA_ENDIANNESS_H */
diff --git a/portaudio/pa_common/pa_front.c b/portaudio/pa_common/pa_front.c
deleted file mode 100644
index 696df8b2d..000000000
--- a/portaudio/pa_common/pa_front.c
+++ /dev/null
@@ -1,1981 +0,0 @@
-/*
- * $Id: pa_front.c,v 1.1.2.53 2006/03/20 18:11:09 aknudsen Exp $
- * Portable Audio I/O Library Multi-Host API front end
- * Validate function parameters and manage multiple host APIs.
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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.
- */
-
-/* doxygen index page */
-/** @mainpage
-
-PortAudio is an open-source cross-platform ‘C’ library for audio input
-and output. It is designed to simplify the porting of audio applications
-between various platforms, and also to simplify the development of audio
-software in general by hiding the complexities of device interfacing.
-
-See the PortAudio website for further information http://www.portaudio.com/
-
-This documentation pertains to PortAudio V19, API version 2.0 which is
-currently under development. API version 2.0 differs in a number of ways from
-previous versions, please consult the enhancement proposals for further details:
-http://www.portaudio.com/docs/proposals/index.html
-
-This documentation is under construction. Things you might be interested in
-include:
-
-- The PortAudio API 2.0, as documented in portaudio.h
-
-- The <a href="todo.html">TODO List</a>
-
-Feel free to pick an item off TODO list and fix/implement it. You may want to
-enquire about status on the PortAudio mailing list first.
-*/
-
-
-/** @file
- @brief Implements public PortAudio API, checks some errors, forwards to
- host API implementations.
- 
- Implements the functions defined in the PortAudio API, checks for
- some parameter and state inconsistencies and forwards API requests to
- specific Host API implementations (via the interface declared in
- pa_hostapi.h), and Streams (via the interface declared in pa_stream.h).
-
- This file handles initialization and termination of Host API
- implementations via initializers stored in the paHostApiInitializers
- global variable.
-
- Some utility functions declared in pa_util.h are implemented in this file.
-
- All PortAudio API functions can be conditionally compiled with logging code.
- To compile with logging, define the PA_LOG_API_CALLS precompiler symbol.
-
-    @todo Consider adding host API specific error text in Pa_GetErrorText() for
-    paUnanticipatedHostError
-
-    @todo Consider adding a new error code for when (inputParameters == NULL)
-    && (outputParameters == NULL)
-
-    @todo review whether Pa_CloseStream() should call the interface's
-    CloseStream function if aborting the stream returns an error code.
-
-    @todo Create new error codes if a NULL buffer pointer, or a
-    zero frame count is passed to Pa_ReadStream or Pa_WriteStream.
-*/
-
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <memory.h>
-#include <string.h>
-#include <assert.h> /* needed by PA_VALIDATE_ENDIANNESS */
-
-#include "portaudio.h"
-#include "pa_util.h"
-#include "pa_endianness.h"
-#include "pa_types.h"
-#include "pa_hostapi.h"
-#include "pa_stream.h"
-
-#include "pa_trace.h"
-
-
-#define PA_VERSION_  1899
-#define PA_VERSION_TEXT_ "PortAudio V19-devel"
-
-
-
-/* #define PA_LOG_API_CALLS */
-
-/*
-    The basic format for log messages is described below. If you need to
-    add any log messages, please follow this format.
- 
-    Function entry (void function):
- 
-        "FunctionName called.\n"
- 
-    Function entry (non void function):
- 
-        "FunctionName called:\n"
-        "\tParam1Type param1: param1Value\n"
-        "\tParam2Type param2: param2Value\n"      (etc...)
- 
- 
-    Function exit (no return value):
- 
-        "FunctionName returned.\n"
- 
-    Function exit (simple return value):
- 
-        "FunctionName returned:\n"
-        "\tReturnType: returnValue\n\n"
- 
-    If the return type is an error code, the error text is displayed in ()
- 
-    If the return type is not an error code, but has taken a special value
-    because an error occurred, then the reason for the error is shown in []
- 
-    If the return type is a struct ptr, the struct is dumped.
- 
-    See the code below for examples
-*/
-
-
-int Pa_GetVersion( void )
-{
-    return PA_VERSION_;
-}
-
-
-const char* Pa_GetVersionText( void )
-{
-    return PA_VERSION_TEXT_;
-}
-
-
-
-#define PA_LAST_HOST_ERROR_TEXT_LENGTH_  1024
-
-static char lastHostErrorText_[ PA_LAST_HOST_ERROR_TEXT_LENGTH_ + 1 ] = {0};
-
-static PaHostErrorInfo lastHostErrorInfo_ = { (PaHostApiTypeId)-1, 0, lastHostErrorText_ };
-
-
-void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode,
-        const char *errorText )
-{
-    lastHostErrorInfo_.hostApiType = hostApiType;
-    lastHostErrorInfo_.errorCode = errorCode;
-
-    strncpy( lastHostErrorText_, errorText, PA_LAST_HOST_ERROR_TEXT_LENGTH_ );
-}
-
-
-void PaUtil_DebugPrint( const char *format, ... )
-{
-    va_list ap;
-
-    va_start( ap, format );
-    vfprintf( stderr, format, ap );
-    va_end( ap );
-
-    fflush( stderr );
-}
-
-
-static PaUtilHostApiRepresentation **hostApis_ = 0;
-static int hostApisCount_ = 0;
-static int initializationCount_ = 0;
-static int deviceCount_ = 0;
-
-PaUtilStreamRepresentation *firstOpenStream_ = NULL;
-
-
-#define PA_IS_INITIALISED_ (initializationCount_ != 0)
-
-
-static int CountHostApiInitializers( void )
-{
-    int result = 0;
-
-    while( paHostApiInitializers[ result ] != 0 )
-        ++result;
-    return result;
-}
-
-
-static void TerminateHostApis( void )
-{
-    /* terminate in reverse order from initialization */
-
-    while( hostApisCount_ > 0 )
-    {
-        --hostApisCount_;
-        hostApis_[hostApisCount_]->Terminate( hostApis_[hostApisCount_] );
-    }
-    hostApisCount_ = 0;
-    deviceCount_ = 0;
-
-    if( hostApis_ != 0 )
-        PaUtil_FreeMemory( hostApis_ );
-    hostApis_ = 0;
-}
-
-
-static PaError InitializeHostApis( void )
-{
-    PaError result = paNoError;
-    int i, initializerCount, baseDeviceIndex;
-
-    initializerCount = CountHostApiInitializers();
-
-    hostApis_ = (PaUtilHostApiRepresentation**)PaUtil_AllocateMemory(
-            sizeof(PaUtilHostApiRepresentation*) * initializerCount );
-    if( !hostApis_ )
-    {
-        result = paInsufficientMemory;
-        goto error; 
-    }
-
-    hostApisCount_ = 0;
-    deviceCount_ = 0;
-    baseDeviceIndex = 0;
-
-    for( i=0; i< initializerCount; ++i )
-    {
-        hostApis_[hostApisCount_] = NULL;
-        result = paHostApiInitializers[i]( &hostApis_[hostApisCount_], hostApisCount_ );
-        if( result != paNoError )
-            goto error;
-
-        if( hostApis_[hostApisCount_] )
-        {
-            PaUtilHostApiRepresentation* hostApi = hostApis_[hostApisCount_];
-            assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount );
-            assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount );
-
-            hostApis_[hostApisCount_]->privatePaFrontInfo.baseDeviceIndex = baseDeviceIndex;
-
-            if( hostApis_[hostApisCount_]->info.defaultInputDevice != paNoDevice )
-                hostApis_[hostApisCount_]->info.defaultInputDevice += baseDeviceIndex;
-
-            if( hostApis_[hostApisCount_]->info.defaultOutputDevice != paNoDevice )
-                hostApis_[hostApisCount_]->info.defaultOutputDevice += baseDeviceIndex;
-
-            baseDeviceIndex += hostApis_[hostApisCount_]->info.deviceCount;
-            deviceCount_ += hostApis_[hostApisCount_]->info.deviceCount;
-
-            ++hostApisCount_;
-        }
-    }
-
-    return result;
-
-error:
-    TerminateHostApis();
-    return result;
-}
-
-
-/*
-    FindHostApi() finds the index of the host api to which
-    <device> belongs and returns it. if <hostSpecificDeviceIndex> is
-    non-null, the host specific device index is returned in it.
-    returns -1 if <device> is out of range.
- 
-*/
-static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex )
-{
-    int i=0;
-
-    if( !PA_IS_INITIALISED_ )
-        return -1;
-
-    if( device < 0 )
-        return -1;
-
-    while( i < hostApisCount_
-            && device >= hostApis_[i]->info.deviceCount )
-    {
-
-        device -= hostApis_[i]->info.deviceCount;
-        ++i;
-    }
-
-    if( i >= hostApisCount_ )
-        return -1;
-
-    if( hostSpecificDeviceIndex )
-        *hostSpecificDeviceIndex = device;
-
-    return i;
-}
-
-
-static void AddOpenStream( PaStream* stream )
-{
-    ((PaUtilStreamRepresentation*)stream)->nextOpenStream = firstOpenStream_;
-    firstOpenStream_ = (PaUtilStreamRepresentation*)stream;
-}
-
-
-static void RemoveOpenStream( PaStream* stream )
-{
-    PaUtilStreamRepresentation *previous = NULL;
-    PaUtilStreamRepresentation *current = firstOpenStream_;
-
-    while( current != NULL )
-    {
-        if( ((PaStream*)current) == stream )
-        {
-            if( previous == NULL )
-            {
-                firstOpenStream_ = current->nextOpenStream;
-            }
-            else
-            {
-                previous->nextOpenStream = current->nextOpenStream;
-            }
-            return;
-        }
-        else
-        {
-            previous = current;
-            current = current->nextOpenStream;
-        }
-    }
-}
-
-
-static void CloseOpenStreams( void )
-{
-    /* we call Pa_CloseStream() here to ensure that the same destruction
-        logic is used for automatically closed streams */
-
-    while( firstOpenStream_ != NULL )
-        Pa_CloseStream( firstOpenStream_ );
-}
-
-
-PaError Pa_Initialize( void )
-{
-    PaError result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint( "Pa_Initialize called.\n" );
-#endif
-
-    if( PA_IS_INITIALISED_ )
-    {
-        ++initializationCount_;
-        result = paNoError;
-    }
-    else
-    {
-        PA_VALIDATE_TYPE_SIZES;
-        PA_VALIDATE_ENDIANNESS;
-        
-        PaUtil_InitializeClock();
-        PaUtil_ResetTraceMessages();
-
-        result = InitializeHostApis();
-        if( result == paNoError )
-            ++initializationCount_;
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint( "Pa_Initialize returned:\n" );
-    PaUtil_DebugPrint( "\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-
-PaError Pa_Terminate( void )
-{
-    PaError result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_Terminate called.\n" );
-#endif
-
-    if( PA_IS_INITIALISED_ )
-    {
-        if( --initializationCount_ == 0 )
-        {
-            CloseOpenStreams();
-
-            TerminateHostApis();
-
-            PaUtil_DumpTraceMessages();
-        }
-        result = paNoError;
-    }
-    else
-    {
-        result=  paNotInitialized;
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_Terminate returned:\n" );
-    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-
-const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void )
-{
-    return &lastHostErrorInfo_;
-}
-
-
-const char *Pa_GetErrorText( PaError errorCode )
-{
-    const char *result;
-
-    switch( errorCode )
-    {
-    case paNoError:                  result = "Success"; break;
-    case paNotInitialized:           result = "PortAudio not initialized"; break;
-    /** @todo could catenate the last host error text to result in the case of paUnanticipatedHostError */
-    case paUnanticipatedHostError:   result = "Unanticipated host error"; break;
-    case paInvalidChannelCount:      result = "Invalid number of channels"; break;
-    case paInvalidSampleRate:        result = "Invalid sample rate"; break;
-    case paInvalidDevice:            result = "Invalid device"; break;
-    case paInvalidFlag:              result = "Invalid flag"; break;
-    case paSampleFormatNotSupported: result = "Sample format not supported"; break;
-    case paBadIODeviceCombination:   result = "Illegal combination of I/O devices"; break;
-    case paInsufficientMemory:       result = "Insufficient memory"; break;
-    case paBufferTooBig:             result = "Buffer too big"; break;
-    case paBufferTooSmall:           result = "Buffer too small"; break;
-    case paNullCallback:             result = "No callback routine specified"; break;
-    case paBadStreamPtr:             result = "Invalid stream pointer"; break;
-    case paTimedOut:                 result = "Wait timed out"; break;
-    case paInternalError:            result = "Internal PortAudio error"; break;
-    case paDeviceUnavailable:        result = "Device unavailable"; break;
-    case paIncompatibleHostApiSpecificStreamInfo:   result = "Incompatible host API specific stream info"; break;
-    case paStreamIsStopped:          result = "Stream is stopped"; break;
-    case paStreamIsNotStopped:       result = "Stream is not stopped"; break;
-    case paInputOverflowed:          result = "Input overflowed"; break;
-    case paOutputUnderflowed:        result = "Output underflowed"; break;
-    case paHostApiNotFound:          result = "Host API not found"; break;
-    case paInvalidHostApi:           result = "Invalid host API"; break;
-    case paCanNotReadFromACallbackStream:       result = "Can't read from a callback stream"; break;
-    case paCanNotWriteToACallbackStream:        result = "Can't write to a callback stream"; break;
-    case paCanNotReadFromAnOutputOnlyStream:    result = "Can't read from an output only stream"; break;
-    case paCanNotWriteToAnInputOnlyStream:      result = "Can't write to an input only stream"; break;
-    default:                         result = "Illegal error number"; break;
-    }
-    return result;
-}
-
-
-PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type )
-{
-    PaHostApiIndex result;
-    int i;
-    
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_HostApiTypeIdToHostApiIndex called:\n" );
-    PaUtil_DebugPrint("\tPaHostApiTypeId type: %d\n", type );
-#endif
-
-    if( !PA_IS_INITIALISED_ )
-    {
-        result = paNotInitialized;
-    }
-    else
-    {
-        result = paHostApiNotFound;
-        
-        for( i=0; i < hostApisCount_; ++i )
-        {
-            if( hostApis_[i]->info.type == type )
-            {
-                result = i;
-                break;
-            }         
-        }
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_HostApiTypeIdToHostApiIndex returned:\n" );
-    if( result < 0 )
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-    else
-        PaUtil_DebugPrint("\tPaHostApiIndex: %d\n\n", result );
-#endif
-
-    return result;
-}
-
-
-PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi,
-        PaHostApiTypeId type )
-{
-    PaError result;
-    int i;
-    
-    if( !PA_IS_INITIALISED_ )
-    {
-        result = paNotInitialized;
-    }
-    else
-    {
-        result = paHostApiNotFound;
-                
-        for( i=0; i < hostApisCount_; ++i )
-        {
-            if( hostApis_[i]->info.type == type )
-            {
-                *hostApi = hostApis_[i];
-                result = paNoError;
-                break;
-            }
-        }
-    }
-
-    return result;
-}
-
-
-PaError PaUtil_DeviceIndexToHostApiDeviceIndex(
-        PaDeviceIndex *hostApiDevice, PaDeviceIndex device, struct PaUtilHostApiRepresentation *hostApi )
-{
-    PaError result;
-    PaDeviceIndex x;
-    
-    x = device - hostApi->privatePaFrontInfo.baseDeviceIndex;
-
-    if( x < 0 || x >= hostApi->info.deviceCount )
-    {
-        result = paInvalidDevice;
-    }
-    else
-    {
-        *hostApiDevice = x;
-        result = paNoError;
-    }
-
-    return result;
-}
-
-
-PaHostApiIndex Pa_GetHostApiCount( void )
-{
-    int result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetHostApiCount called.\n" );
-#endif
-
-    if( !PA_IS_INITIALISED_ )
-    {
-        result = paNotInitialized;
-    }
-    else
-    {
-        result = hostApisCount_;
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetHostApiCount returned:\n" );
-    if( result < 0 )
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-    else
-        PaUtil_DebugPrint("\tPaHostApiIndex %d\n\n", result );
-#endif
-
-    return result;
-}
-
-
-PaHostApiIndex Pa_GetDefaultHostApi( void )
-{
-    int result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetDefaultHostApi called.\n" );
-#endif
-
-    if( !PA_IS_INITIALISED_ )
-    {
-        result = paNotInitialized;
-    }
-    else
-    {
-        result = paDefaultHostApiIndex;
-
-        /* internal consistency check: make sure that the default host api
-         index is within range */
-
-        if( result < 0 || result >= hostApisCount_ )
-        {
-            result = paInternalError;
-        }
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetDefaultHostApi returned:\n" );
-    if( result < 0 )
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-    else
-        PaUtil_DebugPrint("\tPaHostApiIndex %d\n\n", result );
-#endif
-
-    return result;
-}
-
-
-const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi )
-{
-    PaHostApiInfo *info;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetHostApiInfo called:\n" );
-    PaUtil_DebugPrint("\tPaHostApiIndex hostApi: %d\n", hostApi );
-#endif
-
-    if( !PA_IS_INITIALISED_ )
-    {
-        info = NULL;
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetHostApiInfo returned:\n" );
-        PaUtil_DebugPrint("\tPaHostApiInfo*: NULL [ PortAudio not initialized ]\n\n" );
-#endif
-
-    }
-    else if( hostApi < 0 || hostApi >= hostApisCount_ )
-    {
-        info = NULL;
-        
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetHostApiInfo returned:\n" );
-        PaUtil_DebugPrint("\tPaHostApiInfo*: NULL [ hostApi out of range ]\n\n" );
-#endif
-
-    }
-    else
-    {
-        info = &hostApis_[hostApi]->info;
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetHostApiInfo returned:\n" );
-        PaUtil_DebugPrint("\tPaHostApiInfo*: 0x%p\n", info );
-        PaUtil_DebugPrint("\t{" );
-        PaUtil_DebugPrint("\t\tint structVersion: %d\n", info->structVersion );
-        PaUtil_DebugPrint("\t\tPaHostApiTypeId type: %d\n", info->type );
-        PaUtil_DebugPrint("\t\tconst char *name: %s\n\n", info->name );
-        PaUtil_DebugPrint("\t}\n\n" );
-#endif
-
-    }
-
-     return info;
-}
-
-
-PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex )
-{
-    PaDeviceIndex result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_HostApiDeviceIndexToPaDeviceIndex called:\n" );
-    PaUtil_DebugPrint("\tPaHostApiIndex hostApi: %d\n", hostApi );
-    PaUtil_DebugPrint("\tint hostApiDeviceIndex: %d\n", hostApiDeviceIndex );
-#endif
-
-    if( !PA_IS_INITIALISED_ )
-    {
-        result = paNotInitialized;
-    }
-    else
-    {
-        if( hostApi < 0 || hostApi >= hostApisCount_ )
-        {
-            result = paInvalidHostApi;
-        }
-        else
-        {
-            if( hostApiDeviceIndex < 0 ||
-                    hostApiDeviceIndex >= hostApis_[hostApi]->info.deviceCount )
-            {
-                result = paInvalidDevice;
-            }
-            else
-            {
-                result = hostApis_[hostApi]->privatePaFrontInfo.baseDeviceIndex + hostApiDeviceIndex;
-            }
-        }
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_HostApiDeviceIndexToPaDeviceIndex returned:\n" );
-    if( result < 0 )
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-    else
-        PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result );
-#endif
-
-    return result;
-}
-
-
-PaDeviceIndex Pa_GetDeviceCount( void )
-{
-    PaDeviceIndex result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetDeviceCount called.\n" );
-#endif
-
-    if( !PA_IS_INITIALISED_ )
-    {
-        result = paNotInitialized;
-    }
-    else
-    {
-        result = deviceCount_;
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetDeviceCount returned:\n" );
-    if( result < 0 )
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-    else
-        PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result );
-#endif
-
-    return result;
-}
-
-
-PaDeviceIndex Pa_GetDefaultInputDevice( void )
-{
-    PaHostApiIndex hostApi;
-    PaDeviceIndex result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetDefaultInputDevice called.\n" );
-#endif
-
-    hostApi = Pa_GetDefaultHostApi();
-    if( hostApi < 0 )
-    {
-        result = paNoDevice;
-    }
-    else
-    {
-        result = hostApis_[hostApi]->info.defaultInputDevice;
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetDefaultInputDevice returned:\n" );
-    PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result );
-#endif
-
-    return result;
-}
-
-
-PaDeviceIndex Pa_GetDefaultOutputDevice( void )
-{
-    PaHostApiIndex hostApi;
-    PaDeviceIndex result;
-    
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetDefaultOutputDevice called.\n" );
-#endif
-
-    hostApi = Pa_GetDefaultHostApi();
-    if( hostApi < 0 )
-    {
-        result = paNoDevice;
-    }
-    else
-    {
-        result = hostApis_[hostApi]->info.defaultOutputDevice;
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetDefaultOutputDevice returned:\n" );
-    PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result );
-#endif
-
-    return result;
-}
-
-
-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device )
-{
-    int hostSpecificDeviceIndex;
-    int hostApiIndex = FindHostApi( device, &hostSpecificDeviceIndex );
-    PaDeviceInfo *result;
-
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetDeviceInfo called:\n" );
-    PaUtil_DebugPrint("\tPaDeviceIndex device: %d\n", device );
-#endif
-
-    if( hostApiIndex < 0 )
-    {
-        result = NULL;
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetDeviceInfo returned:\n" );
-        PaUtil_DebugPrint("\tPaDeviceInfo* NULL [ invalid device index ]\n\n" );
-#endif
-
-    }
-    else
-    {
-        result = hostApis_[hostApiIndex]->deviceInfos[ hostSpecificDeviceIndex ];
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetDeviceInfo returned:\n" );
-        PaUtil_DebugPrint("\tPaDeviceInfo*: 0x%p:\n", result );
-        PaUtil_DebugPrint("\t{\n" );
-
-        PaUtil_DebugPrint("\t\tint structVersion: %d\n", result->structVersion );
-        PaUtil_DebugPrint("\t\tconst char *name: %s\n", result->name );
-        PaUtil_DebugPrint("\t\tPaHostApiIndex hostApi: %d\n", result->hostApi );
-        PaUtil_DebugPrint("\t\tint maxInputChannels: %d\n", result->maxInputChannels );
-        PaUtil_DebugPrint("\t\tint maxOutputChannels: %d\n", result->maxOutputChannels );
-        PaUtil_DebugPrint("\t}\n\n" );
-#endif
-
-    }
-
-    return result;
-}
-
-
-/*
-    SampleFormatIsValid() returns 1 if sampleFormat is a sample format
-    defined in portaudio.h, or 0 otherwise.
-*/
-static int SampleFormatIsValid( PaSampleFormat format )
-{
-    switch( format & ~paNonInterleaved )
-    {
-    case paFloat32: return 1;
-    case paInt16: return 1;
-    case paInt32: return 1;
-    case paInt24: return 1;
-    case paInt8: return 1;
-    case paUInt8: return 1;
-    case paCustomFormat: return 1;
-    default: return 0;
-    }
-}
-
-/*
-    NOTE: make sure this validation list is kept syncronised with the one in
-            pa_hostapi.h
-
-    ValidateOpenStreamParameters() checks that parameters to Pa_OpenStream()
-    conform to the expected values as described below. This function is
-    also designed to be used with the proposed Pa_IsFormatSupported() function.
-    
-    There are basically two types of validation that could be performed:
-    Generic conformance validation, and device capability mismatch
-    validation. This function performs only generic conformance validation.
-    Validation that would require knowledge of device capabilities is
-    not performed because of potentially complex relationships between
-    combinations of parameters - for example, even if the sampleRate
-    seems ok, it might not be for a duplex stream - we have no way of
-    checking this in an API-neutral way, so we don't try.
- 
-    On success the function returns PaNoError and fills in hostApi,
-    hostApiInputDeviceID, and hostApiOutputDeviceID fields. On failure
-    the function returns an error code indicating the first encountered
-    parameter error.
- 
- 
-    If ValidateOpenStreamParameters() returns paNoError, the following
-    assertions are guaranteed to be true.
- 
-    - at least one of inputParameters & outputParmeters is valid (not NULL)
-
-    - if inputParameters & outputParameters are both valid, that
-        inputParameters->device & outputParameters->device  both use the same host api
- 
-    PaDeviceIndex inputParameters->device
-        - is within range (0 to Pa_GetDeviceCount-1) Or:
-        - is paUseHostApiSpecificDeviceSpecification and
-            inputParameters->hostApiSpecificStreamInfo is non-NULL and refers
-            to a valid host api
-
-    int inputParameters->channelCount
-        - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, channelCount is > 0
-        - upper bound is NOT validated against device capabilities
- 
-    PaSampleFormat inputParameters->sampleFormat
-        - is one of the sample formats defined in portaudio.h
-
-    void *inputParameters->hostApiSpecificStreamInfo
-        - if supplied its hostApi field matches the input device's host Api
- 
-    PaDeviceIndex outputParmeters->device
-        - is within range (0 to Pa_GetDeviceCount-1)
- 
-    int outputParmeters->channelCount
-        - if inputDevice is valid, channelCount is > 0
-        - upper bound is NOT validated against device capabilities
- 
-    PaSampleFormat outputParmeters->sampleFormat
-        - is one of the sample formats defined in portaudio.h
-        
-    void *outputParmeters->hostApiSpecificStreamInfo
-        - if supplied its hostApi field matches the output device's host Api
- 
-    double sampleRate
-        - is not an 'absurd' rate (less than 1000. or greater than 200000.)
-        - sampleRate is NOT validated against device capabilities
- 
-    PaStreamFlags streamFlags
-        - unused platform neutral flags are zero
-        - paNeverDropInput is only used for full-duplex callback streams with
-            variable buffer size (paFramesPerBufferUnspecified)
-*/
-static PaError ValidateOpenStreamParameters(
-    const PaStreamParameters *inputParameters,
-    const PaStreamParameters *outputParameters,
-    double sampleRate,
-    unsigned long framesPerBuffer,
-    PaStreamFlags streamFlags,
-    PaStreamCallback *streamCallback,
-    PaUtilHostApiRepresentation **hostApi,
-    PaDeviceIndex *hostApiInputDevice,
-    PaDeviceIndex *hostApiOutputDevice )
-{
-    int inputHostApiIndex  = -1, /* Surpress uninitialised var warnings: compiler does */
-        outputHostApiIndex = -1; /* not see that if inputParameters and outputParame-  */
-                                 /* ters are both nonzero, these indices are set.      */
-
-    if( (inputParameters == NULL) && (outputParameters == NULL) )
-    {
-        return paInvalidDevice; /** @todo should be a new error code "invalid device parameters" or something */
-    }
-    else
-    {
-        if( inputParameters == NULL )
-        {
-            *hostApiInputDevice = paNoDevice;
-        }
-        else if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-        {
-            if( inputParameters->hostApiSpecificStreamInfo )
-            {
-                inputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex(
-                        ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType );
-
-                if( inputHostApiIndex != -1 )
-                {
-                    *hostApiInputDevice = paUseHostApiSpecificDeviceSpecification;
-                    *hostApi = hostApis_[inputHostApiIndex];
-                }
-                else
-                {
-                    return paInvalidDevice;
-                }
-            }
-            else
-            {
-                return paInvalidDevice;
-            }
-        }
-        else
-        {
-            if( inputParameters->device < 0 || inputParameters->device >= deviceCount_ )
-                return paInvalidDevice;
-
-            inputHostApiIndex = FindHostApi( inputParameters->device, hostApiInputDevice );
-            if( inputHostApiIndex < 0 )
-                return paInternalError;
-
-            *hostApi = hostApis_[inputHostApiIndex];
-
-            if( inputParameters->channelCount <= 0 )
-                return paInvalidChannelCount;
-
-            if( !SampleFormatIsValid( inputParameters->sampleFormat ) )
-                return paSampleFormatNotSupported;
-
-            if( inputParameters->hostApiSpecificStreamInfo != NULL )
-            {
-                if( ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType
-                        != (*hostApi)->info.type )
-                    return paIncompatibleHostApiSpecificStreamInfo;
-            }
-        }
-
-        if( outputParameters == NULL )
-        {
-            *hostApiOutputDevice = paNoDevice;
-        }
-        else if( outputParameters->device == paUseHostApiSpecificDeviceSpecification  )
-        {
-            if( outputParameters->hostApiSpecificStreamInfo )
-            {
-                outputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex(
-                        ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType );
-
-                if( outputHostApiIndex != -1 )
-                {
-                    *hostApiOutputDevice = paUseHostApiSpecificDeviceSpecification;
-                    *hostApi = hostApis_[outputHostApiIndex];
-                }
-                else
-                {
-                    return paInvalidDevice;
-                }
-            }
-            else
-            {
-                return paInvalidDevice;
-            }
-        }
-        else
-        {
-            if( outputParameters->device < 0 || outputParameters->device >= deviceCount_ )
-                return paInvalidDevice;
-
-            outputHostApiIndex = FindHostApi( outputParameters->device, hostApiOutputDevice );
-            if( outputHostApiIndex < 0 )
-                return paInternalError;
-
-            *hostApi = hostApis_[outputHostApiIndex];
-
-            if( outputParameters->channelCount <= 0 )
-                return paInvalidChannelCount;
-
-            if( !SampleFormatIsValid( outputParameters->sampleFormat ) )
-                return paSampleFormatNotSupported;
-
-            if( outputParameters->hostApiSpecificStreamInfo != NULL )
-            {
-                if( ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType
-                        != (*hostApi)->info.type )
-                    return paIncompatibleHostApiSpecificStreamInfo;
-            }
-        }   
-
-        if( (inputParameters != NULL) && (outputParameters != NULL) )
-        {
-            /* ensure that both devices use the same API */
-            if( inputHostApiIndex != outputHostApiIndex )
-                return paBadIODeviceCombination;
-        }
-    }
-    
-    
-    /* Check for absurd sample rates. */
-    if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
-        return paInvalidSampleRate;
-
-    if( ((streamFlags & ~paPlatformSpecificFlags) & ~(paClipOff | paDitherOff | paNeverDropInput | paPrimeOutputBuffersUsingStreamCallback ) ) != 0 )
-        return paInvalidFlag;
-
-    if( streamFlags & paNeverDropInput )
-    {
-        /* must be a callback stream */
-        if( !streamCallback )
-             return paInvalidFlag;
-
-        /* must be a full duplex stream */
-        if( (inputParameters == NULL) || (outputParameters == NULL) )
-            return paInvalidFlag;
-
-        /* must use paFramesPerBufferUnspecified */
-        if( framesPerBuffer != paFramesPerBufferUnspecified )
-            return paInvalidFlag;
-    }
-    
-    return paNoError;
-}
-
-
-PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
-                              const PaStreamParameters *outputParameters,
-                              double sampleRate )
-{
-    PaError result;
-    PaUtilHostApiRepresentation *hostApi;
-    PaDeviceIndex hostApiInputDevice, hostApiOutputDevice;
-    PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
-    PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
-
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_IsFormatSupported called:\n" );
-
-    if( inputParameters == NULL ){
-        PaUtil_DebugPrint("\tPaStreamParameters *inputParameters: NULL\n" );
-    }else{
-        PaUtil_DebugPrint("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters );
-        PaUtil_DebugPrint("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device );
-        PaUtil_DebugPrint("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount );
-        PaUtil_DebugPrint("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat );
-        PaUtil_DebugPrint("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency );
-        PaUtil_DebugPrint("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo );
-    }
-
-    if( outputParameters == NULL ){
-        PaUtil_DebugPrint("\tPaStreamParameters *outputParameters: NULL\n" );
-    }else{
-        PaUtil_DebugPrint("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters );
-        PaUtil_DebugPrint("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device );
-        PaUtil_DebugPrint("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount );
-        PaUtil_DebugPrint("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat );
-        PaUtil_DebugPrint("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency );
-        PaUtil_DebugPrint("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo );
-    }
-    
-    PaUtil_DebugPrint("\tdouble sampleRate: %g\n", sampleRate );
-#endif
-
-    if( !PA_IS_INITIALISED_ )
-    {
-        result = paNotInitialized;
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_IsFormatSupported returned:\n" );
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-        return result;
-    }
-
-    result = ValidateOpenStreamParameters( inputParameters,
-                                           outputParameters,
-                                           sampleRate, 0, paNoFlag, 0,
-                                           &hostApi,
-                                           &hostApiInputDevice,
-                                           &hostApiOutputDevice );
-    if( result != paNoError )
-    {
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_IsFormatSupported returned:\n" );
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-        return result;
-    }
-    
-
-    if( inputParameters )
-    {
-        hostApiInputParameters.device = hostApiInputDevice;
-        hostApiInputParameters.channelCount = inputParameters->channelCount;
-        hostApiInputParameters.sampleFormat = inputParameters->sampleFormat;
-        hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency;
-        hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo;
-        hostApiInputParametersPtr = &hostApiInputParameters;
-    }
-    else
-    {
-        hostApiInputParametersPtr = NULL;
-    }
-
-    if( outputParameters )
-    {
-        hostApiOutputParameters.device = hostApiOutputDevice;
-        hostApiOutputParameters.channelCount = outputParameters->channelCount;
-        hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat;
-        hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency;
-        hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo;
-        hostApiOutputParametersPtr = &hostApiOutputParameters;
-    }
-    else
-    {
-        hostApiOutputParametersPtr = NULL;
-    }
-
-    result = hostApi->IsFormatSupported( hostApi,
-                                  hostApiInputParametersPtr, hostApiOutputParametersPtr,
-                                  sampleRate );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_OpenStream returned:\n" );
-    if( result == paFormatIsSupported )
-        PaUtil_DebugPrint("\tPaError: 0 [ paFormatIsSupported ]\n\n" );
-    else
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-
-PaError Pa_OpenStream( PaStream** stream,
-                       const PaStreamParameters *inputParameters,
-                       const PaStreamParameters *outputParameters,
-                       double sampleRate,
-                       unsigned long framesPerBuffer,
-                       PaStreamFlags streamFlags,
-                       PaStreamCallback *streamCallback,
-                       void *userData )
-{
-    PaError result;
-    PaUtilHostApiRepresentation *hostApi;
-    PaDeviceIndex hostApiInputDevice, hostApiOutputDevice;
-    PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
-    PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
-
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_OpenStream called:\n" );
-    PaUtil_DebugPrint("\tPaStream** stream: 0x%p\n", stream );
-
-    if( inputParameters == NULL ){
-        PaUtil_DebugPrint("\tPaStreamParameters *inputParameters: NULL\n" );
-    }else{
-        PaUtil_DebugPrint("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters );
-        PaUtil_DebugPrint("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device );
-        PaUtil_DebugPrint("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount );
-        PaUtil_DebugPrint("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat );
-        PaUtil_DebugPrint("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency );
-        PaUtil_DebugPrint("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo );
-    }
-
-    if( outputParameters == NULL ){
-        PaUtil_DebugPrint("\tPaStreamParameters *outputParameters: NULL\n" );
-    }else{
-        PaUtil_DebugPrint("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters );
-        PaUtil_DebugPrint("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device );
-        PaUtil_DebugPrint("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount );
-        PaUtil_DebugPrint("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat );
-        PaUtil_DebugPrint("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency );
-        PaUtil_DebugPrint("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo );
-    }
-    
-    PaUtil_DebugPrint("\tdouble sampleRate: %g\n", sampleRate );
-    PaUtil_DebugPrint("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer );
-    PaUtil_DebugPrint("\tPaStreamFlags streamFlags: 0x%x\n", streamFlags );
-    PaUtil_DebugPrint("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback );
-    PaUtil_DebugPrint("\tvoid *userData: 0x%p\n", userData );
-#endif
-
-    if( !PA_IS_INITIALISED_ )
-    {
-        result = paNotInitialized;
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_OpenStream returned:\n" );
-        PaUtil_DebugPrint("\t*(PaStream** stream): undefined\n" );
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-        return result;
-    }
-
-    /* Check for parameter errors.
-        NOTE: make sure this validation list is kept syncronised with the one
-        in pa_hostapi.h
-    */
-
-    if( stream == NULL )
-    {
-        result = paBadStreamPtr;
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_OpenStream returned:\n" );
-        PaUtil_DebugPrint("\t*(PaStream** stream): undefined\n" );
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-        return result;
-    }
-
-    result = ValidateOpenStreamParameters( inputParameters,
-                                           outputParameters,
-                                           sampleRate, framesPerBuffer,
-                                           streamFlags, streamCallback,
-                                           &hostApi,
-                                           &hostApiInputDevice,
-                                           &hostApiOutputDevice );
-    if( result != paNoError )
-    {
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_OpenStream returned:\n" );
-        PaUtil_DebugPrint("\t*(PaStream** stream): undefined\n" );
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-        return result;
-    }
-    
-
-    if( inputParameters )
-    {
-        hostApiInputParameters.device = hostApiInputDevice;
-        hostApiInputParameters.channelCount = inputParameters->channelCount;
-        hostApiInputParameters.sampleFormat = inputParameters->sampleFormat;
-        hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency;
-        hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo;
-        hostApiInputParametersPtr = &hostApiInputParameters;
-    }
-    else
-    {
-        hostApiInputParametersPtr = NULL;
-    }
-
-    if( outputParameters )
-    {
-        hostApiOutputParameters.device = hostApiOutputDevice;
-        hostApiOutputParameters.channelCount = outputParameters->channelCount;
-        hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat;
-        hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency;
-        hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo;
-        hostApiOutputParametersPtr = &hostApiOutputParameters;
-    }
-    else
-    {
-        hostApiOutputParametersPtr = NULL;
-    }
-
-    result = hostApi->OpenStream( hostApi, stream,
-                                  hostApiInputParametersPtr, hostApiOutputParametersPtr,
-                                  sampleRate, framesPerBuffer, streamFlags, streamCallback, userData );
-
-    if( result == paNoError )
-        AddOpenStream( *stream );
-
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_OpenStream returned:\n" );
-    PaUtil_DebugPrint("\t*(PaStream** stream): 0x%p\n", *stream );
-    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-
-PaError Pa_OpenDefaultStream( PaStream** stream,
-                              int inputChannelCount,
-                              int outputChannelCount,
-                              PaSampleFormat sampleFormat,
-                              double sampleRate,
-                              unsigned long framesPerBuffer,
-                              PaStreamCallback *streamCallback,
-                              void *userData )
-{
-    PaError result;
-    PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
-    PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_OpenDefaultStream called:\n" );
-    PaUtil_DebugPrint("\tPaStream** stream: 0x%p\n", stream );
-    PaUtil_DebugPrint("\tint inputChannelCount: %d\n", inputChannelCount );
-    PaUtil_DebugPrint("\tint outputChannelCount: %d\n", outputChannelCount );
-    PaUtil_DebugPrint("\tPaSampleFormat sampleFormat: %d\n", sampleFormat );
-    PaUtil_DebugPrint("\tdouble sampleRate: %g\n", sampleRate );
-    PaUtil_DebugPrint("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer );
-    PaUtil_DebugPrint("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback );
-    PaUtil_DebugPrint("\tvoid *userData: 0x%p\n", userData );
-#endif
-
-
-    if( inputChannelCount > 0 )
-    {
-        hostApiInputParameters.device = Pa_GetDefaultInputDevice();
-        hostApiInputParameters.channelCount = inputChannelCount;
-        hostApiInputParameters.sampleFormat = sampleFormat;
-        /* defaultHighInputLatency is used below instead of
-           defaultLowInputLatency because it is more important for the default
-           stream to work reliably than it is for it to work with the lowest
-           latency.
-         */
-        hostApiInputParameters.suggestedLatency = 
-             Pa_GetDeviceInfo( hostApiInputParameters.device )->defaultHighInputLatency;
-        hostApiInputParameters.hostApiSpecificStreamInfo = NULL;
-        hostApiInputParametersPtr = &hostApiInputParameters;
-    }
-    else
-    {
-        hostApiInputParametersPtr = NULL;
-    }
-
-    if( outputChannelCount > 0 )
-    {
-        hostApiOutputParameters.device = Pa_GetDefaultOutputDevice();
-        hostApiOutputParameters.channelCount = outputChannelCount;
-        hostApiOutputParameters.sampleFormat = sampleFormat;
-        /* defaultHighOutputLatency is used below instead of
-           defaultLowOutputLatency because it is more important for the default
-           stream to work reliably than it is for it to work with the lowest
-           latency.
-         */
-        hostApiOutputParameters.suggestedLatency =
-             Pa_GetDeviceInfo( hostApiOutputParameters.device )->defaultHighOutputLatency;
-        hostApiOutputParameters.hostApiSpecificStreamInfo = NULL;
-        hostApiOutputParametersPtr = &hostApiOutputParameters;
-    }
-    else
-    {
-        hostApiOutputParametersPtr = NULL;
-    }
-
-
-    result = Pa_OpenStream(
-                 stream, hostApiInputParametersPtr, hostApiOutputParametersPtr,
-                 sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_OpenDefaultStream returned:\n" );
-    PaUtil_DebugPrint("\t*(PaStream** stream): 0x%p", *stream );
-    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-
-PaError PaUtil_ValidateStreamPointer( PaStream* stream )
-{
-    if( !PA_IS_INITIALISED_ ) return paNotInitialized;
-
-    if( stream == NULL ) return paBadStreamPtr;
-
-    if( ((PaUtilStreamRepresentation*)stream)->magic != PA_STREAM_MAGIC )
-        return paBadStreamPtr;
-
-    return paNoError;
-}
-
-
-PaError Pa_CloseStream( PaStream* stream )
-{
-    PaUtilStreamInterface *interface;
-    PaError result = PaUtil_ValidateStreamPointer( stream );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_CloseStream called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    /* always remove the open stream from our list, even if this function
-        eventually returns an error. Otherwise CloseOpenStreams() will
-        get stuck in an infinite loop */
-    RemoveOpenStream( stream ); /* be sure to call this _before_ closing the stream */
-
-    if( result == paNoError )
-    {
-        interface = PA_STREAM_INTERFACE(stream);
-
-        /* abort the stream if it isn't stopped */
-        result = interface->IsStopped( stream );
-        if( result == 1 )
-            result = paNoError;
-        else if( result == 0 )
-            result = interface->Abort( stream );
-
-        if( result == paNoError )                 /** @todo REVIEW: shouldn't we close anyway? */
-            result = interface->Close( stream );
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_CloseStream returned:\n" );
-    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-
-PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback )
-{
-    PaError result = PaUtil_ValidateStreamPointer( stream );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_SetStreamFinishedCallback called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-    PaUtil_DebugPrint("\tPaStreamFinishedCallback* streamFinishedCallback: 0x%p\n", streamFinishedCallback );
-#endif
-
-    if( result == paNoError )
-    {
-        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
-        if( result == 0 )
-        {
-            result = paStreamIsNotStopped ;
-        }
-        if( result == 1 )
-        {
-            PA_STREAM_REP( stream )->streamFinishedCallback = streamFinishedCallback;
-            result = paNoError;
-        }
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_SetStreamFinishedCallback returned:\n" );
-    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-
-}
-
-
-PaError Pa_StartStream( PaStream *stream )
-{
-    PaError result = PaUtil_ValidateStreamPointer( stream );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_StartStream called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    if( result == paNoError )
-    {
-        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
-        if( result == 0 )
-        {
-            result = paStreamIsNotStopped ;
-        }
-        else if( result == 1 )
-        {
-            result = PA_STREAM_INTERFACE(stream)->Start( stream );
-        }
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_StartStream returned:\n" );
-    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-
-PaError Pa_StopStream( PaStream *stream )
-{
-    PaError result = PaUtil_ValidateStreamPointer( stream );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_StopStream called\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    if( result == paNoError )
-    {
-        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
-        if( result == 0 )
-        {
-            result = PA_STREAM_INTERFACE(stream)->Stop( stream );
-        }
-        else if( result == 1 )
-        {
-            result = paStreamIsStopped;
-        }
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_StopStream returned:\n" );
-    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-
-PaError Pa_AbortStream( PaStream *stream )
-{
-    PaError result = PaUtil_ValidateStreamPointer( stream );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_AbortStream called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    if( result == paNoError )
-    {
-        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
-        if( result == 0 )
-        {
-            result = PA_STREAM_INTERFACE(stream)->Abort( stream );
-        }
-        else if( result == 1 )
-        {
-            result = paStreamIsStopped;
-        }
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_AbortStream returned:\n" );
-    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-
-PaError Pa_IsStreamStopped( PaStream *stream )
-{
-    PaError result = PaUtil_ValidateStreamPointer( stream );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_IsStreamStopped called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    if( result == paNoError )
-        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_IsStreamStopped returned:\n" );
-    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-
-PaError Pa_IsStreamActive( PaStream *stream )
-{
-    PaError result = PaUtil_ValidateStreamPointer( stream );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_IsStreamActive called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    if( result == paNoError )
-        result = PA_STREAM_INTERFACE(stream)->IsActive( stream );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_IsStreamActive returned:\n" );
-    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-
-const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream )
-{
-    PaError error = PaUtil_ValidateStreamPointer( stream );
-    const PaStreamInfo *result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetStreamInfo called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    if( error != paNoError )
-    {
-        result = 0;
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetStreamInfo returned:\n" );
-        PaUtil_DebugPrint("\tconst PaStreamInfo*: 0 [PaError error:%d ( %s )]\n\n", result, error, Pa_GetErrorText( error ) );
-#endif
-
-    }
-    else
-    {
-        result = &PA_STREAM_REP( stream )->streamInfo;
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetStreamInfo returned:\n" );
-        PaUtil_DebugPrint("\tconst PaStreamInfo*: 0x%p:\n", result );
-        PaUtil_DebugPrint("\t{" );
-
-        PaUtil_DebugPrint("\t\tint structVersion: %d\n", result->structVersion );
-        PaUtil_DebugPrint("\t\tPaTime inputLatency: %f\n", result->inputLatency );
-        PaUtil_DebugPrint("\t\tPaTime outputLatency: %f\n", result->outputLatency );
-        PaUtil_DebugPrint("\t\tdouble sampleRate: %f\n", result->sampleRate );
-        PaUtil_DebugPrint("\t}\n\n" );
-#endif
-
-    }
-
-    return result;
-}
-
-
-PaTime Pa_GetStreamTime( PaStream *stream )
-{
-    PaError error = PaUtil_ValidateStreamPointer( stream );
-    PaTime result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetStreamTime called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    if( error != paNoError )
-    {
-        result = 0;
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetStreamTime returned:\n" );
-        PaUtil_DebugPrint("\tPaTime: 0 [PaError error:%d ( %s )]\n\n", result, error, Pa_GetErrorText( error ) );
-#endif
-
-    }
-    else
-    {
-        result = PA_STREAM_INTERFACE(stream)->GetTime( stream );
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetStreamTime returned:\n" );
-        PaUtil_DebugPrint("\tPaTime: %g\n\n", result );
-#endif
-
-    }
-
-    return result;
-}
-
-
-double Pa_GetStreamCpuLoad( PaStream* stream )
-{
-    PaError error = PaUtil_ValidateStreamPointer( stream );
-    double result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetStreamCpuLoad called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    if( error != paNoError )
-    {
-
-        result = 0.0;
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetStreamCpuLoad returned:\n" );
-        PaUtil_DebugPrint("\tdouble: 0.0 [PaError error: %d ( %s )]\n\n", error, Pa_GetErrorText( error ) );
-#endif
-
-    }
-    else
-    {
-        result = PA_STREAM_INTERFACE(stream)->GetCpuLoad( stream );
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetStreamCpuLoad returned:\n" );
-        PaUtil_DebugPrint("\tdouble: %g\n\n", result );
-#endif
-
-    }
-
-    return result;
-}
-
-
-PaError Pa_ReadStream( PaStream* stream,
-                       void *buffer,
-                       unsigned long frames )
-{
-    PaError result = PaUtil_ValidateStreamPointer( stream );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_ReadStream called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    if( result == paNoError )
-    {
-        if( frames == 0 )
-        {
-            /* XXX: Should we not allow the implementation to signal any overflow condition? */
-            result = paNoError;
-        }
-        else if( buffer == 0 )
-        {
-            result = paBadBufferPtr;
-        }
-        else
-        {
-            result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
-            if( result == 0 )
-            {
-                result = PA_STREAM_INTERFACE(stream)->Read( stream, buffer, frames );
-            }
-            else if( result == 1 )
-            {
-                result = paStreamIsStopped;
-            }
-        }
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_ReadStream returned:\n" );
-    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-
-PaError Pa_WriteStream( PaStream* stream,
-                        const void *buffer,
-                        unsigned long frames )
-{
-    PaError result = PaUtil_ValidateStreamPointer( stream );
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_WriteStream called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    if( result == paNoError )
-    {
-        if( frames == 0 )
-        {
-            /* XXX: Should we not allow the implementation to signal any underflow condition? */
-            result = paNoError;
-        }
-        else if( buffer == 0 )
-        {
-            result = paBadBufferPtr;
-        }
-        else
-        {
-            result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
-            if( result == 0 )
-            {
-                result = PA_STREAM_INTERFACE(stream)->Write( stream, buffer, frames );
-            }
-            else if( result == 1 )
-            {
-                result = paStreamIsStopped;
-            }  
-        }
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_WriteStream returned:\n" );
-    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return result;
-}
-
-signed long Pa_GetStreamReadAvailable( PaStream* stream )
-{
-    PaError error = PaUtil_ValidateStreamPointer( stream );
-    signed long result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetStreamReadAvailable called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    if( error != paNoError )
-    {
-        result = 0;
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetStreamReadAvailable returned:\n" );
-        PaUtil_DebugPrint("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n\n", error, Pa_GetErrorText( error ) );
-#endif
-
-    }
-    else
-    {
-        result = PA_STREAM_INTERFACE(stream)->GetReadAvailable( stream );
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetStreamReadAvailable returned:\n" );
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    }
-
-    return result;
-}
-
-
-signed long Pa_GetStreamWriteAvailable( PaStream* stream )
-{
-    PaError error = PaUtil_ValidateStreamPointer( stream );
-    signed long result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetStreamWriteAvailable called:\n" );
-    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
-#endif
-
-    if( error != paNoError )
-    {
-        result = 0;
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetStreamWriteAvailable returned:\n" );
-        PaUtil_DebugPrint("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n\n", error, Pa_GetErrorText( error ) );
-#endif
-
-    }
-    else
-    {
-        result = PA_STREAM_INTERFACE(stream)->GetWriteAvailable( stream );
-
-#ifdef PA_LOG_API_CALLS
-        PaUtil_DebugPrint("Pa_GetStreamWriteAvailable returned:\n" );
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    }
-
-    return result;
-}
-
-
-PaError Pa_GetSampleSize( PaSampleFormat format )
-{
-    int result;
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetSampleSize called:\n" );
-    PaUtil_DebugPrint("\tPaSampleFormat format: %d\n", format );
-#endif
-
-    switch( format & ~paNonInterleaved )
-    {
-
-    case paUInt8:
-    case paInt8:
-        result = 1;
-        break;
-
-    case paInt16:
-        result = 2;
-        break;
-
-    case paInt24:
-        result = 3;
-        break;
-
-    case paFloat32:
-    case paInt32:
-        result = 4;
-        break;
-
-    default:
-        result = paSampleFormatNotSupported;
-        break;
-    }
-
-#ifdef PA_LOG_API_CALLS
-    PaUtil_DebugPrint("Pa_GetSampleSize returned:\n" );
-    if( result > 0 )
-        PaUtil_DebugPrint("\tint: %d\n\n", result );
-    else
-        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
-#endif
-
-    return (PaError) result;
-}
-
diff --git a/portaudio/pa_common/pa_hostapi.h b/portaudio/pa_common/pa_hostapi.h
deleted file mode 100644
index d05507067..000000000
--- a/portaudio/pa_common/pa_hostapi.h
+++ /dev/null
@@ -1,244 +0,0 @@
-#ifndef PA_HOSTAPI_H
-#define PA_HOSTAPI_H
-/*
- * $Id: pa_hostapi.h,v 1.1.2.14 2004/01/08 22:01:12 rossbencina Exp $
- * Portable Audio I/O Library
- * host api representation
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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.
- */
-
-/** @file
- @brief Interface used by pa_front to virtualize functions which operate on
- host APIs.
-*/
-
-
-#include "portaudio.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-/** **FOR THE USE OF pa_front.c ONLY**
-    Do NOT use fields in this structure, they my change at any time.
-    Use functions defined in pa_util.h if you think you need functionality
-    which can be derived from here.
-*/
-typedef struct PaUtilPrivatePaFrontHostApiInfo {
-
-
-    unsigned long baseDeviceIndex;
-}PaUtilPrivatePaFrontHostApiInfo;
-
-
-/** The common header for all data structures whose pointers are passed through
- the hostApiSpecificStreamInfo field of the PaStreamParameters structure.
- Note that in order to keep the public PortAudio interface clean, this structure
- is not used explicitly when declaring hostApiSpecificStreamInfo data structures.
- However, some code in pa_front depends on the first 3 members being equivalent
- with this structure.
- @see PaStreamParameters
-*/
-typedef struct PaUtilHostApiSpecificStreamInfoHeader
-{
-    unsigned long size;             /**< size of whole structure including this header */
-    PaHostApiTypeId hostApiType;    /**< host API for which this data is intended */
-    unsigned long version;          /**< structure version */
-} PaUtilHostApiSpecificStreamInfoHeader;
-
-
-
-/** A structure representing the interface to a host API. Contains both
- concrete data and pointers to functions which implement the interface.
-*/
-typedef struct PaUtilHostApiRepresentation {
-    PaUtilPrivatePaFrontHostApiInfo privatePaFrontInfo;
-
-    /** The host api implementation should populate the info field. In the
-        case of info.defaultInputDevice and info.defaultOutputDevice the
-        values stored should be 0 based indices within the host api's own
-        device index range (0 to deviceCount). These values will be converted
-        to global device indices by pa_front after PaUtilHostApiInitializer()
-        returns.
-    */
-    PaHostApiInfo info;
-
-    PaDeviceInfo** deviceInfos;
-
-    /**
-        (*Terminate)() is guaranteed to be called with a valid <hostApi>
-        parameter, which was previously returned from the same implementation's
-        initializer.
-    */
-    void (*Terminate)( struct PaUtilHostApiRepresentation *hostApi );
-
-    /**
-        The inputParameters and outputParameters pointers should not be saved
-        as they will not remain valid after OpenStream is called.
-
-        
-        The following guarantees are made about parameters to (*OpenStream)():
-
-            [NOTE: the following list up to *END PA FRONT VALIDATIONS* should be
-                kept in sync with the one for ValidateOpenStreamParameters and
-                Pa_OpenStream in pa_front.c]
-                
-            PaHostApiRepresentation *hostApi
-                - is valid for this implementation
-
-            PaStream** stream
-                - is non-null
-
-            - at least one of inputParameters & outputParmeters is valid (not NULL)
-
-            - if inputParameters & outputParmeters are both valid, that
-                inputParameters->device & outputParmeters->device  both use the same host api
- 
-            PaDeviceIndex inputParameters->device
-                - is within range (0 to Pa_CountDevices-1) Or:
-                - is paUseHostApiSpecificDeviceSpecification and
-                    inputParameters->hostApiSpecificStreamInfo is non-NULL and refers
-                    to a valid host api
-
-            int inputParameters->numChannels
-                - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, numInputChannels is > 0
-                - upper bound is NOT validated against device capabilities
- 
-            PaSampleFormat inputParameters->sampleFormat
-                - is one of the sample formats defined in portaudio.h
-
-            void *inputParameters->hostApiSpecificStreamInfo
-                - if supplied its hostApi field matches the input device's host Api
- 
-            PaDeviceIndex outputParmeters->device
-                - is within range (0 to Pa_CountDevices-1)
- 
-            int outputParmeters->numChannels
-                - if inputDevice is valid, numInputChannels is > 0
-                - upper bound is NOT validated against device capabilities
- 
-            PaSampleFormat outputParmeters->sampleFormat
-                - is one of the sample formats defined in portaudio.h
-        
-            void *outputParmeters->hostApiSpecificStreamInfo
-                - if supplied its hostApi field matches the output device's host Api
- 
-            double sampleRate
-                - is not an 'absurd' rate (less than 1000. or greater than 200000.)
-                - sampleRate is NOT validated against device capabilities
- 
-            PaStreamFlags streamFlags
-                - unused platform neutral flags are zero
-                - paNeverDropInput is only used for full-duplex callback streams
-                    with variable buffer size (paFramesPerBufferUnspecified)
-
-            [*END PA FRONT VALIDATIONS*]
-
-
-        The following validations MUST be performed by (*OpenStream)():
-
-            - check that input device can support numInputChannels
-            
-            - check that input device can support inputSampleFormat, or that
-                we have the capability to convert from outputSampleFormat to
-                a native format
-
-            - if inputStreamInfo is supplied, validate its contents,
-                or return an error if no inputStreamInfo is expected
-
-            - check that output device can support numOutputChannels
-            
-            - check that output device can support outputSampleFormat, or that
-                we have the capability to convert from outputSampleFormat to
-                a native format
-
-            - if outputStreamInfo is supplied, validate its contents,
-                or return an error if no outputStreamInfo is expected
-
-            - if a full duplex stream is requested, check that the combination
-                of input and output parameters is supported
-
-            - check that the device supports sampleRate
-
-            - alter sampleRate to a close allowable rate if necessary
-
-            - validate inputLatency and outputLatency
-
-            - validate any platform specific flags, if flags are supplied they
-                must be valid.
-    */
-    PaError (*OpenStream)( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** stream,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerCallback,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData );
-
-
-    PaError (*IsFormatSupported)( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate );
-} PaUtilHostApiRepresentation;
-
-
-/** Prototype for the initialization function which must be implemented by every
- host API.
- 
- @see paHostApiInitializers
-*/
-typedef PaError PaUtilHostApiInitializer( PaUtilHostApiRepresentation**, PaHostApiIndex );
-
-
-/** paHostApiInitializers is a NULL-terminated array of host API initialization
- functions. These functions are called by pa_front to initialize the host APIs
- when the client calls Pa_Initialize().
-
- There is a platform specific file which defines paHostApiInitializers for that
- platform, pa_win/pa_win_hostapis.c contains the Win32 definitions for example.
-*/
-extern PaUtilHostApiInitializer *paHostApiInitializers[];
-
-
-/** The index of the default host API in the paHostApiInitializers array.
- 
- There is a platform specific file which defines paDefaultHostApiIndex for that
- platform, see pa_win/pa_win_hostapis.c for example.
-*/
-extern int paDefaultHostApiIndex;
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PA_HOSTAPI_H */
diff --git a/portaudio/pa_common/pa_process.c b/portaudio/pa_common/pa_process.c
deleted file mode 100644
index 4a52165b2..000000000
--- a/portaudio/pa_common/pa_process.c
+++ /dev/null
@@ -1,1763 +0,0 @@
-/*
- * $Id: pa_process.c,v 1.1.2.51 2005/10/27 23:28:48 aknudsen Exp $
- * Portable Audio I/O Library
- * streamCallback <-> host buffer processing adapter
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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.
- */
-
-/** @file
- @brief Buffer Processor implementation.
-    
- The code in this file is not optimised yet - although it's not clear that
- it needs to be. there may appear to be redundancies
- that could be factored into common functions, but the redundanceis are left
- intentionally as each appearance may have different optimisation possibilities.
-
- The optimisations which are planned involve only converting data in-place
- where possible, rather than copying to the temp buffer(s).
-
- Note that in the extreme case of being able to convert in-place, and there
- being no conversion necessary there should be some code which short-circuits
- the operation.
-
-    @todo Consider cache tilings for intereave<->deinterleave.
-
-    @todo implement timeInfo->currentTime int PaUtil_BeginBufferProcessing()
-
-    @todo specify and implement some kind of logical policy for handling the
-        underflow and overflow stream flags when the underflow/overflow overlaps
-        multiple user buffers/callbacks.
-
-	@todo provide support for priming the buffers with data from the callback.
-        The client interface is now implemented through PaUtil_SetNoInput()
-        which sets bp->hostInputChannels[0][0].data to zero. However this is
-        currently only implemented in NonAdaptingProcess(). It shouldn't be
-        needed for AdaptingInputOnlyProcess() (no priming should ever be
-        requested for AdaptingInputOnlyProcess()).
-        Not sure if additional work should be required to make it work with
-        AdaptingOutputOnlyProcess, but it definitely is required for
-        AdaptingProcess.
-
-    @todo implement PaUtil_SetNoOutput for AdaptingProcess
-
-    @todo don't allocate temp buffers for blocking streams unless they are
-        needed. At the moment they are needed, but perhaps for host APIs
-        where the implementation passes a buffer to the host they could be
-        used.
-*/
-
-
-#include <assert.h>
-#include <string.h> /* memset() */
-
-#include "pa_process.h"
-#include "pa_util.h"
-
-
-#define PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_    1024
-
-#define PA_MIN_( a, b ) ( ((a)<(b)) ? (a) : (b) )
-
-
-/* greatest common divisor - PGCD in French */
-static unsigned long GCD( unsigned long a, unsigned long b )
-{
-    return (b==0) ? a : GCD( b, a%b);
-}
-
-/* least common multiple - PPCM in French */
-static unsigned long LCM( unsigned long a, unsigned long b )
-{
-    return (a*b) / GCD(a,b);
-}
-
-#define PA_MAX_( a, b ) (((a) > (b)) ? (a) : (b))
-
-static unsigned long CalculateFrameShift( unsigned long M, unsigned long N )
-{
-    unsigned long result = 0;
-    unsigned long i;
-    unsigned long lcm;
-
-    assert( M > 0 );
-    assert( N > 0 );
-
-    lcm = LCM( M, N );
-    for( i = M; i < lcm; i += M )
-        result = PA_MAX_( result, i % N );
-
-    return result;
-}
-
-
-PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,
-        int inputChannelCount, PaSampleFormat userInputSampleFormat,
-        PaSampleFormat hostInputSampleFormat,
-        int outputChannelCount, PaSampleFormat userOutputSampleFormat,
-        PaSampleFormat hostOutputSampleFormat,
-        double sampleRate,
-        PaStreamFlags streamFlags,
-        unsigned long framesPerUserBuffer,
-        unsigned long framesPerHostBuffer,
-        PaUtilHostBufferSizeMode hostBufferSizeMode,
-        PaStreamCallback *streamCallback, void *userData )
-{
-    PaError result = paNoError;
-    PaError bytesPerSample;
-    unsigned long tempInputBufferSize, tempOutputBufferSize;
-
-    if( streamFlags & paNeverDropInput )
-    {
-        /* paNeverDropInput is only valid for full-duplex callback streams, with an unspecified number of frames per buffer. */
-        if( !streamCallback || !(inputChannelCount > 0 && outputChannelCount > 0) ||
-                framesPerUserBuffer != paFramesPerBufferUnspecified )
-            return paInvalidFlag;
-    }
-
-    /* initialize buffer ptrs to zero so they can be freed if necessary in error */
-    bp->tempInputBuffer = 0;
-    bp->tempInputBufferPtrs = 0;
-    bp->tempOutputBuffer = 0;
-    bp->tempOutputBufferPtrs = 0;
-
-    bp->framesPerUserBuffer = framesPerUserBuffer;
-    bp->framesPerHostBuffer = framesPerHostBuffer;
-
-    bp->inputChannelCount = inputChannelCount;
-    bp->outputChannelCount = outputChannelCount;
-
-    bp->hostBufferSizeMode = hostBufferSizeMode;
-
-    bp->hostInputChannels[0] = bp->hostInputChannels[1] = 0;
-    bp->hostOutputChannels[0] = bp->hostOutputChannels[1] = 0;
-
-    if( framesPerUserBuffer == 0 ) /* streamCallback will accept any buffer size */
-    {
-        bp->useNonAdaptingProcess = 1;
-        bp->initialFramesInTempInputBuffer = 0;
-        bp->initialFramesInTempOutputBuffer = 0;
-
-        if( hostBufferSizeMode == paUtilFixedHostBufferSize
-                || hostBufferSizeMode == paUtilBoundedHostBufferSize )
-        {
-            bp->framesPerTempBuffer = framesPerHostBuffer;
-        }
-        else /* unknown host buffer size */
-        {
-             bp->framesPerTempBuffer = PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_;
-        }
-    }
-    else
-    {
-        bp->framesPerTempBuffer = framesPerUserBuffer;
-
-        if( hostBufferSizeMode == paUtilFixedHostBufferSize
-                && framesPerHostBuffer % framesPerUserBuffer == 0 )
-        {
-            bp->useNonAdaptingProcess = 1;
-            bp->initialFramesInTempInputBuffer = 0;
-            bp->initialFramesInTempOutputBuffer = 0;
-        }
-        else
-        {
-            bp->useNonAdaptingProcess = 0;
-
-            if( inputChannelCount > 0 && outputChannelCount > 0 )
-            {
-                /* full duplex */
-                if( hostBufferSizeMode == paUtilFixedHostBufferSize )
-                {
-                    unsigned long frameShift =
-                        CalculateFrameShift( framesPerHostBuffer, framesPerUserBuffer );
-
-                    if( framesPerUserBuffer > framesPerHostBuffer )
-                    {
-                        bp->initialFramesInTempInputBuffer = frameShift;
-                        bp->initialFramesInTempOutputBuffer = 0;
-                    }
-                    else
-                    {
-                        bp->initialFramesInTempInputBuffer = 0;
-                        bp->initialFramesInTempOutputBuffer = frameShift;
-                    }
-                }
-                else /* variable host buffer size, add framesPerUserBuffer latency */
-                {
-                    bp->initialFramesInTempInputBuffer = 0;
-                    bp->initialFramesInTempOutputBuffer = framesPerUserBuffer;
-                }
-            }
-            else
-            {
-                /* half duplex */
-                bp->initialFramesInTempInputBuffer = 0;
-                bp->initialFramesInTempOutputBuffer = 0;
-            }
-        }
-    }
-
-
-    bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer;
-    bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer;
-
-    
-    if( inputChannelCount > 0 )
-    {
-        bytesPerSample = Pa_GetSampleSize( hostInputSampleFormat );
-        if( bytesPerSample > 0 )
-        {
-            bp->bytesPerHostInputSample = bytesPerSample;
-        }
-        else
-        {
-            result = bytesPerSample;
-            goto error;
-        }
-
-        bytesPerSample = Pa_GetSampleSize( userInputSampleFormat );
-        if( bytesPerSample > 0 )
-        {
-            bp->bytesPerUserInputSample = bytesPerSample;
-        }
-        else
-        {
-            result = bytesPerSample;
-            goto error;
-        }
-
-        bp->inputConverter =
-            PaUtil_SelectConverter( hostInputSampleFormat, userInputSampleFormat, streamFlags );
-
-        bp->inputZeroer = PaUtil_SelectZeroer( hostInputSampleFormat );
-            
-        bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1;
-
-
-        tempInputBufferSize =
-            bp->framesPerTempBuffer * bp->bytesPerUserInputSample * inputChannelCount;
-         
-        bp->tempInputBuffer = PaUtil_AllocateMemory( tempInputBufferSize );
-        if( bp->tempInputBuffer == 0 )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-        
-        if( bp->framesInTempInputBuffer > 0 )
-            memset( bp->tempInputBuffer, 0, tempInputBufferSize );
-
-        if( userInputSampleFormat & paNonInterleaved )
-        {
-            bp->tempInputBufferPtrs =
-                (void **)PaUtil_AllocateMemory( sizeof(void*)*inputChannelCount );
-            if( bp->tempInputBufferPtrs == 0 )
-            {
-                result = paInsufficientMemory;
-                goto error;
-            }
-        }
-
-        bp->hostInputChannels[0] = (PaUtilChannelDescriptor*)
-                PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor) * inputChannelCount * 2);
-        if( bp->hostInputChannels[0] == 0 )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        bp->hostInputChannels[1] = &bp->hostInputChannels[0][inputChannelCount];
-    }
-
-    if( outputChannelCount > 0 )
-    {
-        bytesPerSample = Pa_GetSampleSize( hostOutputSampleFormat );
-        if( bytesPerSample > 0 )
-        {
-            bp->bytesPerHostOutputSample = bytesPerSample;
-        }
-        else
-        {
-            result = bytesPerSample;
-            goto error;
-        }
-
-        bytesPerSample = Pa_GetSampleSize( userOutputSampleFormat );
-        if( bytesPerSample > 0 )
-        {
-            bp->bytesPerUserOutputSample = bytesPerSample;
-        }
-        else
-        {
-            result = bytesPerSample;
-            goto error;
-        }
-
-        bp->outputConverter =
-            PaUtil_SelectConverter( userOutputSampleFormat, hostOutputSampleFormat, streamFlags );
-
-        bp->outputZeroer = PaUtil_SelectZeroer( hostOutputSampleFormat );
-
-        bp->userOutputIsInterleaved = (userOutputSampleFormat & paNonInterleaved)?0:1;
-
-        tempOutputBufferSize =
-                bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * outputChannelCount;
-
-        bp->tempOutputBuffer = PaUtil_AllocateMemory( tempOutputBufferSize );
-        if( bp->tempOutputBuffer == 0 )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        if( bp->framesInTempOutputBuffer > 0 )
-            memset( bp->tempOutputBuffer, 0, tempOutputBufferSize );
-        
-        if( userOutputSampleFormat & paNonInterleaved )
-        {
-            bp->tempOutputBufferPtrs =
-                (void **)PaUtil_AllocateMemory( sizeof(void*)*outputChannelCount );
-            if( bp->tempOutputBufferPtrs == 0 )
-            {
-                result = paInsufficientMemory;
-                goto error;
-            }
-        }
-
-        bp->hostOutputChannels[0] = (PaUtilChannelDescriptor*)
-                PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor)*outputChannelCount * 2 );
-        if( bp->hostOutputChannels[0] == 0 )
-        {                                                                     
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        bp->hostOutputChannels[1] = &bp->hostOutputChannels[0][outputChannelCount];
-    }
-
-    PaUtil_InitializeTriangularDitherState( &bp->ditherGenerator );
-
-    bp->samplePeriod = 1. / sampleRate;
-
-    bp->streamCallback = streamCallback;
-    bp->userData = userData;
-
-    return result;
-
-error:
-    if( bp->tempInputBuffer )
-        PaUtil_FreeMemory( bp->tempInputBuffer );
-
-    if( bp->tempInputBufferPtrs )
-        PaUtil_FreeMemory( bp->tempInputBufferPtrs );
-
-    if( bp->hostInputChannels[0] )
-        PaUtil_FreeMemory( bp->hostInputChannels[0] );
-
-    if( bp->tempOutputBuffer )
-        PaUtil_FreeMemory( bp->tempOutputBuffer );
-
-    if( bp->tempOutputBufferPtrs )
-        PaUtil_FreeMemory( bp->tempOutputBufferPtrs );
-
-    if( bp->hostOutputChannels[0] )
-        PaUtil_FreeMemory( bp->hostOutputChannels[0] );
-
-    return result;
-}
-
-
-void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bp )
-{
-    if( bp->tempInputBuffer )
-        PaUtil_FreeMemory( bp->tempInputBuffer );
-
-    if( bp->tempInputBufferPtrs )
-        PaUtil_FreeMemory( bp->tempInputBufferPtrs );
-
-    if( bp->hostInputChannels[0] )
-        PaUtil_FreeMemory( bp->hostInputChannels[0] );
-        
-    if( bp->tempOutputBuffer )
-        PaUtil_FreeMemory( bp->tempOutputBuffer );
-
-    if( bp->tempOutputBufferPtrs )
-        PaUtil_FreeMemory( bp->tempOutputBufferPtrs );
-
-    if( bp->hostOutputChannels[0] )
-        PaUtil_FreeMemory( bp->hostOutputChannels[0] );
-}
-
-
-void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bp )
-{
-    unsigned long tempInputBufferSize, tempOutputBufferSize;
-
-    bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer;
-    bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer;
-
-    if( bp->framesInTempInputBuffer > 0 )
-    {
-        tempInputBufferSize =
-            bp->framesPerTempBuffer * bp->bytesPerUserInputSample * bp->inputChannelCount;
-        memset( bp->tempInputBuffer, 0, tempInputBufferSize );
-    }
-
-    if( bp->framesInTempOutputBuffer > 0 )
-    {      
-        tempOutputBufferSize =
-            bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * bp->outputChannelCount;
-        memset( bp->tempOutputBuffer, 0, tempOutputBufferSize );
-    }
-}
-
-
-unsigned long PaUtil_GetBufferProcessorInputLatency( PaUtilBufferProcessor* bp )
-{
-    return bp->initialFramesInTempInputBuffer;
-}
-
-
-unsigned long PaUtil_GetBufferProcessorOutputLatency( PaUtilBufferProcessor* bp )
-{
-    return bp->initialFramesInTempOutputBuffer;
-}
-
-
-void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bp,
-        unsigned long frameCount )
-{
-    if( frameCount == 0 )
-        bp->hostInputFrameCount[0] = bp->framesPerHostBuffer;
-    else
-        bp->hostInputFrameCount[0] = frameCount;
-}
-        
-
-void PaUtil_SetNoInput( PaUtilBufferProcessor* bp )
-{
-    assert( bp->inputChannelCount > 0 );
-
-    bp->hostInputChannels[0][0].data = 0;
-}
-
-
-void PaUtil_SetInputChannel( PaUtilBufferProcessor* bp,
-        unsigned int channel, void *data, unsigned int stride )
-{
-    assert( channel < bp->inputChannelCount );
-    
-    bp->hostInputChannels[0][channel].data = data;
-    bp->hostInputChannels[0][channel].stride = stride;
-}
-
-
-void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bp,
-        unsigned int firstChannel, void *data, unsigned int channelCount )
-{
-    unsigned int i;
-    unsigned int channel = firstChannel;
-    unsigned char *p = (unsigned char*)data;
-
-    if( channelCount == 0 )
-        channelCount = bp->inputChannelCount;
-
-    assert( firstChannel < bp->inputChannelCount );
-    assert( firstChannel + channelCount <= bp->inputChannelCount );
-
-    for( i=0; i< channelCount; ++i )
-    {
-        bp->hostInputChannels[0][channel+i].data = p;
-        p += bp->bytesPerHostInputSample;
-        bp->hostInputChannels[0][channel+i].stride = channelCount;
-    }
-}
-
-
-void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bp,
-        unsigned int channel, void *data )
-{
-    assert( channel < bp->inputChannelCount );
-    
-    bp->hostInputChannels[0][channel].data = data;
-    bp->hostInputChannels[0][channel].stride = 1;
-}
-
-
-void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bp,
-        unsigned long frameCount )
-{
-    bp->hostInputFrameCount[1] = frameCount;
-}
-
-
-void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bp,
-        unsigned int channel, void *data, unsigned int stride )
-{
-    assert( channel < bp->inputChannelCount );
-
-    bp->hostInputChannels[1][channel].data = data;
-    bp->hostInputChannels[1][channel].stride = stride;
-}
-
-
-void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bp,
-        unsigned int firstChannel, void *data, unsigned int channelCount )
-{
-    unsigned int i;
-    unsigned int channel = firstChannel;
-    unsigned char *p = (unsigned char*)data;
-
-    if( channelCount == 0 )
-        channelCount = bp->inputChannelCount;
-
-    assert( firstChannel < bp->inputChannelCount );
-    assert( firstChannel + channelCount <= bp->inputChannelCount );
-    
-    for( i=0; i< channelCount; ++i )
-    {
-        bp->hostInputChannels[1][channel+i].data = p;
-        p += bp->bytesPerHostInputSample;
-        bp->hostInputChannels[1][channel+i].stride = channelCount;
-    }
-}
-
-        
-void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bp,
-        unsigned int channel, void *data )
-{
-    assert( channel < bp->inputChannelCount );
-    
-    bp->hostInputChannels[1][channel].data = data;
-    bp->hostInputChannels[1][channel].stride = 1;
-}
-
-
-void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bp,
-        unsigned long frameCount )
-{
-    if( frameCount == 0 )
-        bp->hostOutputFrameCount[0] = bp->framesPerHostBuffer;
-    else
-        bp->hostOutputFrameCount[0] = frameCount;
-}
-
-
-void PaUtil_SetNoOutput( PaUtilBufferProcessor* bp )
-{
-    assert( bp->outputChannelCount > 0 );
-
-    bp->hostOutputChannels[0][0].data = 0;
-}
-
-
-void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bp,
-        unsigned int channel, void *data, unsigned int stride )
-{
-    assert( channel < bp->outputChannelCount );
-    assert( data != NULL );
-
-    bp->hostOutputChannels[0][channel].data = data;
-    bp->hostOutputChannels[0][channel].stride = stride;
-}
-
-
-void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bp,
-        unsigned int firstChannel, void *data, unsigned int channelCount )
-{
-    unsigned int i;
-    unsigned int channel = firstChannel;
-    unsigned char *p = (unsigned char*)data;
-
-    if( channelCount == 0 )
-        channelCount = bp->outputChannelCount;
-
-    assert( firstChannel < bp->outputChannelCount );
-    assert( firstChannel + channelCount <= bp->outputChannelCount );
-    
-    for( i=0; i< channelCount; ++i )
-    {
-        PaUtil_SetOutputChannel( bp, channel + i, p, channelCount );
-        p += bp->bytesPerHostOutputSample;
-    }
-}
-
-
-void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bp,
-        unsigned int channel, void *data )
-{
-    assert( channel < bp->outputChannelCount );
-
-    PaUtil_SetOutputChannel( bp, channel, data, 1 );
-}
-
-
-void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bp,
-        unsigned long frameCount )
-{
-    bp->hostOutputFrameCount[1] = frameCount;
-}
-
-
-void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bp,
-        unsigned int channel, void *data, unsigned int stride )
-{
-    assert( channel < bp->outputChannelCount );
-    assert( data != NULL );
-
-    bp->hostOutputChannels[1][channel].data = data;
-    bp->hostOutputChannels[1][channel].stride = stride;
-}
-
-
-void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bp,
-        unsigned int firstChannel, void *data, unsigned int channelCount )
-{
-    unsigned int i;
-    unsigned int channel = firstChannel;
-    unsigned char *p = (unsigned char*)data;
-
-    if( channelCount == 0 )
-        channelCount = bp->outputChannelCount;
-
-    assert( firstChannel < bp->outputChannelCount );
-    assert( firstChannel + channelCount <= bp->outputChannelCount );
-    
-    for( i=0; i< channelCount; ++i )
-    {
-        PaUtil_Set2ndOutputChannel( bp, channel + i, p, channelCount );
-        p += bp->bytesPerHostOutputSample;
-    }
-}
-
-        
-void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bp,
-        unsigned int channel, void *data )
-{
-    assert( channel < bp->outputChannelCount );
-    
-    PaUtil_Set2ndOutputChannel( bp, channel, data, 1 );
-}
-
-
-void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bp,
-        PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags )
-{
-    bp->timeInfo = timeInfo;
-
-    /* the first streamCallback will be called to process samples which are
-        currently in the input buffer before the ones starting at the timeInfo time */
-        
-    bp->timeInfo->inputBufferAdcTime -= bp->framesInTempInputBuffer * bp->samplePeriod;
-    
-    bp->timeInfo->currentTime = 0; /** FIXME: @todo time info currentTime not implemented */
-
-    /* the first streamCallback will be called to generate samples which will be
-        outputted after the frames currently in the output buffer have been
-        outputted. */
-    bp->timeInfo->outputBufferDacTime += bp->framesInTempOutputBuffer * bp->samplePeriod;
-
-    bp->callbackStatusFlags = callbackStatusFlags;
-
-    bp->hostInputFrameCount[1] = 0;
-    bp->hostOutputFrameCount[1] = 0;
-}
-
-
-/*
-    NonAdaptingProcess() is a simple buffer copying adaptor that can handle
-    both full and half duplex copies. It processes framesToProcess frames,
-    broken into blocks bp->framesPerTempBuffer long.
-    This routine can be used when the streamCallback doesn't care what length
-    the buffers are, or when framesToProcess is an integer multiple of
-    bp->framesPerTempBuffer, in which case streamCallback will always be called
-    with bp->framesPerTempBuffer samples.
-*/
-static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
-        int *streamCallbackResult,
-        PaUtilChannelDescriptor *hostInputChannels,
-        PaUtilChannelDescriptor *hostOutputChannels,
-        unsigned long framesToProcess )
-{
-    void *userInput, *userOutput;
-    unsigned char *srcBytePtr, *destBytePtr;
-    unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
-    unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */
-    unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
-    unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */
-    unsigned int i;
-    unsigned long frameCount;
-    unsigned long framesToGo = framesToProcess;
-    unsigned long framesProcessed = 0;
-
-
-    if( *streamCallbackResult == paContinue )
-    {
-        do
-        {
-            frameCount = PA_MIN_( bp->framesPerTempBuffer, framesToGo );
-
-            /* configure user input buffer and convert input data (host -> user) */
-            if( bp->inputChannelCount == 0 )
-            {
-                /* no input */
-                userInput = 0;
-            }
-            else /* there are input channels */
-            {
-                /*
-                    could use more elaborate logic here and sometimes process
-                    buffers in-place.
-                */
-            
-                destBytePtr = (unsigned char *)bp->tempInputBuffer;
-
-                if( bp->userInputIsInterleaved )
-                {
-                    destSampleStrideSamples = bp->inputChannelCount;
-                    destChannelStrideBytes = bp->bytesPerUserInputSample;
-                    userInput = bp->tempInputBuffer;
-                }
-                else /* user input is not interleaved */
-                {
-                    destSampleStrideSamples = 1;
-                    destChannelStrideBytes = frameCount * bp->bytesPerUserInputSample;
-
-                    /* setup non-interleaved ptrs */
-                    for( i=0; i<bp->inputChannelCount; ++i )
-                    {
-                        bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
-                            i * bp->bytesPerUserInputSample * frameCount;
-                    }
-                
-                    userInput = bp->tempInputBufferPtrs;
-                }
-
-                if( !bp->hostInputChannels[0][0].data )
-                {
-                    /* no input was supplied (see PaUtil_SetNoInput), so
-                        zero the input buffer */
-
-                    for( i=0; i<bp->inputChannelCount; ++i )
-                    {
-                        bp->inputZeroer( destBytePtr, destSampleStrideSamples, frameCount );
-                        destBytePtr += destChannelStrideBytes;  /* skip to next destination channel */
-                    }
-                }
-                else
-                {
-                    for( i=0; i<bp->inputChannelCount; ++i )
-                    {
-                        bp->inputConverter( destBytePtr, destSampleStrideSamples,
-                                                hostInputChannels[i].data,
-                                                hostInputChannels[i].stride,
-                                                frameCount, &bp->ditherGenerator );
-
-                        destBytePtr += destChannelStrideBytes;  /* skip to next destination channel */
-
-                        /* advance src ptr for next iteration */
-                        hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
-                                frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
-                    }
-                }
-            }
-
-            /* configure user output buffer */
-            if( bp->outputChannelCount == 0 )
-            {
-                /* no output */
-                userOutput = 0;
-            }
-            else /* there are output channels */
-            {
-                if( bp->userOutputIsInterleaved )
-                {
-                    userOutput = bp->tempOutputBuffer;
-                }
-                else /* user output is not interleaved */
-                {
-                    for( i = 0; i < bp->outputChannelCount; ++i )
-                    {
-                        bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
-                            i * bp->bytesPerUserOutputSample * frameCount;
-                    }
-
-                    userOutput = bp->tempOutputBufferPtrs;
-                }
-            }
-        
-            *streamCallbackResult = bp->streamCallback( userInput, userOutput,
-                    frameCount, bp->timeInfo, bp->callbackStatusFlags, bp->userData );
-
-            if( *streamCallbackResult == paAbort )
-            {
-                /* callback returned paAbort, don't advance framesProcessed
-                        and framesToGo, they will be handled below */
-            }
-            else
-            {
-                bp->timeInfo->inputBufferAdcTime += frameCount * bp->samplePeriod;
-                bp->timeInfo->outputBufferDacTime += frameCount * bp->samplePeriod;
-
-                /* convert output data (user -> host) */
-                
-                if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data )
-                {
-                    /*
-                        could use more elaborate logic here and sometimes process
-                        buffers in-place.
-                    */
-            
-                    srcBytePtr = (unsigned char *)bp->tempOutputBuffer;
-
-                    if( bp->userOutputIsInterleaved )
-                    {
-                        srcSampleStrideSamples = bp->outputChannelCount;
-                        srcChannelStrideBytes = bp->bytesPerUserOutputSample;
-                    }
-                    else /* user output is not interleaved */
-                    {
-                        srcSampleStrideSamples = 1;
-                        srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample;
-                    }
-
-                    for( i=0; i<bp->outputChannelCount; ++i )
-                    {
-                        bp->outputConverter(    hostOutputChannels[i].data,
-                                                hostOutputChannels[i].stride,
-                                                srcBytePtr, srcSampleStrideSamples,
-                                                frameCount, &bp->ditherGenerator );
-
-                        srcBytePtr += srcChannelStrideBytes;  /* skip to next source channel */
-
-                        /* advance dest ptr for next iteration */
-                        hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
-                                frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
-                    }
-                }
-             
-                framesProcessed += frameCount;
-
-                framesToGo -= frameCount;
-            }
-        }
-        while( framesToGo > 0  && *streamCallbackResult == paContinue );
-    }
-
-    if( framesToGo > 0 )
-    {
-        /* zero any remaining frames output. There will only be remaining frames
-            if the callback has returned paComplete or paAbort */
-
-        frameCount = framesToGo;
-
-        if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data )
-        {
-            for( i=0; i<bp->outputChannelCount; ++i )
-            {
-                bp->outputZeroer(   hostOutputChannels[i].data,
-                                    hostOutputChannels[i].stride,
-                                    frameCount );
-
-                /* advance dest ptr for next iteration */
-                hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
-                        frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
-            }
-        }
-
-        framesProcessed += frameCount;
-    }
-
-    return framesProcessed;
-}
-
-
-/*
-    AdaptingInputOnlyProcess() is a half duplex input buffer processor. It
-    converts data from the input buffers into the temporary input buffer,
-    when the temporary input buffer is full, it calls the streamCallback.
-*/
-static unsigned long AdaptingInputOnlyProcess( PaUtilBufferProcessor *bp,
-        int *streamCallbackResult,
-        PaUtilChannelDescriptor *hostInputChannels,
-        unsigned long framesToProcess )
-{
-    void *userInput, *userOutput;
-    unsigned char *destBytePtr;
-    unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
-    unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */
-    unsigned int i;
-    unsigned long frameCount;
-    unsigned long framesToGo = framesToProcess;
-    unsigned long framesProcessed = 0;
-    
-    userOutput = 0;
-
-    do
-    {
-        frameCount = ( bp->framesInTempInputBuffer + framesToGo > bp->framesPerUserBuffer )
-                ? ( bp->framesPerUserBuffer - bp->framesInTempInputBuffer )
-                : framesToGo;
-
-        /* convert frameCount samples into temp buffer */
-
-        if( bp->userInputIsInterleaved )
-        {
-            destBytePtr = ((unsigned char*)bp->tempInputBuffer) +
-                    bp->bytesPerUserInputSample * bp->inputChannelCount *
-                    bp->framesInTempInputBuffer;
-                      
-            destSampleStrideSamples = bp->inputChannelCount;
-            destChannelStrideBytes = bp->bytesPerUserInputSample;
-
-            userInput = bp->tempInputBuffer;
-        }
-        else /* user input is not interleaved */
-        {
-            destBytePtr = ((unsigned char*)bp->tempInputBuffer) +
-                    bp->bytesPerUserInputSample * bp->framesInTempInputBuffer;
-
-            destSampleStrideSamples = 1;
-            destChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserInputSample;
-
-            /* setup non-interleaved ptrs */
-            for( i=0; i<bp->inputChannelCount; ++i )
-            {
-                bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
-                    i * bp->bytesPerUserInputSample * bp->framesPerUserBuffer;
-            }
-                    
-            userInput = bp->tempInputBufferPtrs;
-        }
-
-        for( i=0; i<bp->inputChannelCount; ++i )
-        {
-            bp->inputConverter( destBytePtr, destSampleStrideSamples,
-                                    hostInputChannels[i].data,
-                                    hostInputChannels[i].stride,
-                                    frameCount, &bp->ditherGenerator );
-
-            destBytePtr += destChannelStrideBytes;  /* skip to next destination channel */
-
-            /* advance src ptr for next iteration */
-            hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
-                    frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
-        }
-
-        bp->framesInTempInputBuffer += frameCount;
-
-        if( bp->framesInTempInputBuffer == bp->framesPerUserBuffer )
-        {
-            /**
-            @todo (non-critical optimisation)
-            The conditional below implements the continue/complete/abort mechanism
-            simply by continuing on iterating through the input buffer, but not
-            passing the data to the callback. With care, the outer loop could be
-            terminated earlier, thus some unneeded conversion cycles would be
-            saved.
-            */
-            if( *streamCallbackResult == paContinue )
-            {
-                bp->timeInfo->outputBufferDacTime = 0;
-
-                *streamCallbackResult = bp->streamCallback( userInput, userOutput,
-                        bp->framesPerUserBuffer, bp->timeInfo,
-                        bp->callbackStatusFlags, bp->userData );
-
-                bp->timeInfo->inputBufferAdcTime += frameCount * bp->samplePeriod;
-            }
-            
-            bp->framesInTempInputBuffer = 0;
-        }
-
-        framesProcessed += frameCount;
-
-        framesToGo -= frameCount;
-    }while( framesToGo > 0 );
-
-    return framesProcessed;
-}
-
-
-/*
-    AdaptingOutputOnlyProcess() is a half duplex output buffer processor.
-    It converts data from the temporary output buffer, to the output buffers,
-    when the temporary output buffer is empty, it calls the streamCallback.
-*/
-static unsigned long AdaptingOutputOnlyProcess( PaUtilBufferProcessor *bp,
-        int *streamCallbackResult,
-        PaUtilChannelDescriptor *hostOutputChannels,
-        unsigned long framesToProcess )
-{
-    void *userInput, *userOutput;
-    unsigned char *srcBytePtr;
-    unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
-    unsigned int srcChannelStrideBytes;  /* stride from one channel to the next, in bytes */
-    unsigned int i;
-    unsigned long frameCount;
-    unsigned long framesToGo = framesToProcess;
-    unsigned long framesProcessed = 0;
-
-    do
-    {
-        if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult == paContinue )
-        {
-            userInput = 0;
-
-            /* setup userOutput */
-            if( bp->userOutputIsInterleaved )
-            {
-                userOutput = bp->tempOutputBuffer;
-            }
-            else /* user output is not interleaved */
-            {
-                for( i = 0; i < bp->outputChannelCount; ++i )
-                {
-                    bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
-                            i * bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;
-                }
-
-                userOutput = bp->tempOutputBufferPtrs;
-            }
-
-            bp->timeInfo->inputBufferAdcTime = 0;
-            
-            *streamCallbackResult = bp->streamCallback( userInput, userOutput,
-                    bp->framesPerUserBuffer, bp->timeInfo,
-                    bp->callbackStatusFlags, bp->userData );
-
-            if( *streamCallbackResult == paAbort )
-            {
-                /* if the callback returned paAbort, we disregard its output */
-            }
-            else
-            {
-                bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod;
-
-                bp->framesInTempOutputBuffer = bp->framesPerUserBuffer;
-            }
-        }
-
-        if( bp->framesInTempOutputBuffer > 0 )
-        {
-            /* convert frameCount frames from user buffer to host buffer */
-
-            frameCount = PA_MIN_( bp->framesInTempOutputBuffer, framesToGo );
-
-            if( bp->userOutputIsInterleaved )
-            {
-                srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
-                        bp->bytesPerUserOutputSample * bp->outputChannelCount *
-                        (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
-
-                srcSampleStrideSamples = bp->outputChannelCount;
-                srcChannelStrideBytes = bp->bytesPerUserOutputSample;
-            }
-            else /* user output is not interleaved */
-            {
-                srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
-                        bp->bytesPerUserOutputSample *
-                        (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
-                            
-                srcSampleStrideSamples = 1;
-                srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;
-            }
-
-            for( i=0; i<bp->outputChannelCount; ++i )
-            {
-                bp->outputConverter(    hostOutputChannels[i].data,
-                                        hostOutputChannels[i].stride,
-                                        srcBytePtr, srcSampleStrideSamples,
-                                        frameCount, &bp->ditherGenerator );
-
-                srcBytePtr += srcChannelStrideBytes;  /* skip to next source channel */
-
-                /* advance dest ptr for next iteration */
-                hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
-                        frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
-            }
-
-            bp->framesInTempOutputBuffer -= frameCount;
-        }
-        else
-        {
-            /* no more user data is available because the callback has returned
-                paComplete or paAbort. Fill the remainder of the host buffer
-                with zeros.
-            */
-
-            frameCount = framesToGo;
-
-            for( i=0; i<bp->outputChannelCount; ++i )
-            {
-                bp->outputZeroer(   hostOutputChannels[i].data,
-                                    hostOutputChannels[i].stride,
-                                    frameCount );
-
-                /* advance dest ptr for next iteration */
-                hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
-                        frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
-            }
-        }
-        
-        framesProcessed += frameCount;
-        
-        framesToGo -= frameCount;
-
-    }while( framesToGo > 0 );
-
-    return framesProcessed;
-}
-
-/* CopyTempOutputBuffersToHostOutputBuffers is called from AdaptingProcess to copy frames from
-	tempOutputBuffer to hostOutputChannels. This includes data conversion
-	and interleaving. 
-*/
-static void CopyTempOutputBuffersToHostOutputBuffers( PaUtilBufferProcessor *bp)
-{
-    unsigned long maxFramesToCopy;
-    PaUtilChannelDescriptor *hostOutputChannels;
-    unsigned int frameCount;
-    unsigned char *srcBytePtr;
-    unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
-    unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */
-    unsigned int i;
-
-     /* copy frames from user to host output buffers */
-     while( bp->framesInTempOutputBuffer > 0 &&
-             ((bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) > 0) )
-     {
-         maxFramesToCopy = bp->framesInTempOutputBuffer;
-
-         /* select the output buffer set (1st or 2nd) */
-         if( bp->hostOutputFrameCount[0] > 0 )
-         {
-             hostOutputChannels = bp->hostOutputChannels[0];
-             frameCount = PA_MIN_( bp->hostOutputFrameCount[0], maxFramesToCopy );
-         }
-         else
-         {
-             hostOutputChannels = bp->hostOutputChannels[1];
-             frameCount = PA_MIN_( bp->hostOutputFrameCount[1], maxFramesToCopy );
-         }
-
-         if( bp->userOutputIsInterleaved )
-         {
-             srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
-                     bp->bytesPerUserOutputSample * bp->outputChannelCount *
-                     (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
-                         
-             srcSampleStrideSamples = bp->outputChannelCount;
-             srcChannelStrideBytes = bp->bytesPerUserOutputSample;
-         }
-         else /* user output is not interleaved */
-         {
-             srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
-                     bp->bytesPerUserOutputSample *
-                     (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
-
-             srcSampleStrideSamples = 1;
-             srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;
-         }
-
-         for( i=0; i<bp->outputChannelCount; ++i )
-         {
-             assert( hostOutputChannels[i].data != NULL );
-             bp->outputConverter(    hostOutputChannels[i].data,
-                                     hostOutputChannels[i].stride,
-                                     srcBytePtr, srcSampleStrideSamples,
-                                     frameCount, &bp->ditherGenerator );
-
-             srcBytePtr += srcChannelStrideBytes;  /* skip to next source channel */
-
-             /* advance dest ptr for next iteration */
-             hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
-                     frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
-         }
-
-         if( bp->hostOutputFrameCount[0] > 0 )
-             bp->hostOutputFrameCount[0] -= frameCount;
-         else
-             bp->hostOutputFrameCount[1] -= frameCount;
-
-         bp->framesInTempOutputBuffer -= frameCount;
-     }
-}
-
-/*
-    AdaptingProcess is a full duplex adapting buffer processor. It converts
-    data from the temporary output buffer into the host output buffers, then
-    from the host input buffers into the temporary input buffers. Calling the
-    streamCallback when necessary.
-    When processPartialUserBuffers is 0, all available input data will be
-    consumed and all available output space will be filled. When
-    processPartialUserBuffers is non-zero, as many full user buffers
-    as possible will be processed, but partial buffers will not be consumed.
-*/
-static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp,
-        int *streamCallbackResult, int processPartialUserBuffers )
-{
-    void *userInput, *userOutput;
-    unsigned long framesProcessed = 0;
-    unsigned long framesAvailable;
-    unsigned long endProcessingMinFrameCount;
-    unsigned long maxFramesToCopy;
-    PaUtilChannelDescriptor *hostInputChannels, *hostOutputChannels;
-    unsigned int frameCount;
-    unsigned char *destBytePtr;
-    unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
-    unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */
-    unsigned int i, j;
- 
-
-    framesAvailable = bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1];/* this is assumed to be the same as the output buffer's frame count */
-
-    if( processPartialUserBuffers )
-        endProcessingMinFrameCount = 0;
-    else
-        endProcessingMinFrameCount = (bp->framesPerUserBuffer - 1);
-
-    /* Fill host output with remaining frames in user output (tempOutputBuffer) */
-    CopyTempOutputBuffersToHostOutputBuffers( bp );		  	
-
-    while( framesAvailable > endProcessingMinFrameCount ) 
-    {
-
-        if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult != paContinue )
-        {
-            /* the callback will not be called any more, so zero what remains
-                of the host output buffers */
-
-            for( i=0; i<2; ++i )
-            {
-                frameCount = bp->hostOutputFrameCount[i];
-                if( frameCount > 0 )
-                {
-                    hostOutputChannels = bp->hostOutputChannels[i];
-                    
-                    for( j=0; j<bp->outputChannelCount; ++j )
-                    {
-                        bp->outputZeroer(   hostOutputChannels[j].data,
-                                            hostOutputChannels[j].stride,
-                                            frameCount );
-
-                        /* advance dest ptr for next iteration  */
-                        hostOutputChannels[j].data = ((unsigned char*)hostOutputChannels[j].data) +
-                                frameCount * hostOutputChannels[j].stride * bp->bytesPerHostOutputSample;
-                    }
-                    bp->hostOutputFrameCount[i] = 0;
-                }
-            }
-        }          
-
-
-        /* copy frames from host to user input buffers */
-        while( bp->framesInTempInputBuffer < bp->framesPerUserBuffer &&
-                ((bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) > 0) )
-        {
-            maxFramesToCopy = bp->framesPerUserBuffer - bp->framesInTempInputBuffer;
-
-            /* select the input buffer set (1st or 2nd) */
-            if( bp->hostInputFrameCount[0] > 0 )
-            {
-                hostInputChannels = bp->hostInputChannels[0];
-                frameCount = PA_MIN_( bp->hostInputFrameCount[0], maxFramesToCopy );
-            }
-            else
-            {
-                hostInputChannels = bp->hostInputChannels[1];
-                frameCount = PA_MIN_( bp->hostInputFrameCount[1], maxFramesToCopy );
-            }
-
-            /* configure conversion destination pointers */
-            if( bp->userInputIsInterleaved )
-            {
-                destBytePtr = ((unsigned char*)bp->tempInputBuffer) +
-                        bp->bytesPerUserInputSample * bp->inputChannelCount *
-                        bp->framesInTempInputBuffer;
-
-                destSampleStrideSamples = bp->inputChannelCount;
-                destChannelStrideBytes = bp->bytesPerUserInputSample;
-            }
-            else /* user input is not interleaved */
-            {
-                destBytePtr = ((unsigned char*)bp->tempInputBuffer) +
-                        bp->bytesPerUserInputSample * bp->framesInTempInputBuffer;
-
-                destSampleStrideSamples = 1;
-                destChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserInputSample;
-            }
-
-            for( i=0; i<bp->inputChannelCount; ++i )
-            {
-                bp->inputConverter( destBytePtr, destSampleStrideSamples,
-                                        hostInputChannels[i].data,
-                                        hostInputChannels[i].stride,
-                                        frameCount, &bp->ditherGenerator );
-
-                destBytePtr += destChannelStrideBytes;  /* skip to next destination channel */
-
-                /* advance src ptr for next iteration */
-                hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
-                        frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
-            }
-
-            if( bp->hostInputFrameCount[0] > 0 )
-                bp->hostInputFrameCount[0] -= frameCount;
-            else
-                bp->hostInputFrameCount[1] -= frameCount;
-                
-            bp->framesInTempInputBuffer += frameCount;
-
-            /* update framesAvailable and framesProcessed based on input consumed
-                unless something is very wrong this will also correspond to the
-                amount of output generated */
-            framesAvailable -= frameCount;
-            framesProcessed += frameCount;
-        }
-
-        /* call streamCallback */
-        if( bp->framesInTempInputBuffer == bp->framesPerUserBuffer &&
-            bp->framesInTempOutputBuffer == 0 )
-        {
-            if( *streamCallbackResult == paContinue )
-            {
-                /* setup userInput */
-                if( bp->userInputIsInterleaved )
-                {
-                    userInput = bp->tempInputBuffer;
-                }
-                else /* user input is not interleaved */
-                {
-                    for( i = 0; i < bp->inputChannelCount; ++i )
-                    {
-                        bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
-                                i * bp->framesPerUserBuffer * bp->bytesPerUserInputSample;
-                    }
-
-                    userInput = bp->tempInputBufferPtrs;
-                }
-
-                /* setup userOutput */
-                if( bp->userOutputIsInterleaved )
-                {
-                    userOutput = bp->tempOutputBuffer;
-                }
-                else /* user output is not interleaved */
-                {
-                    for( i = 0; i < bp->outputChannelCount; ++i )
-                    {
-                        bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
-                                i * bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;
-                    }
-
-                    userOutput = bp->tempOutputBufferPtrs;
-                }
-
-                /* call streamCallback */
-
-                *streamCallbackResult = bp->streamCallback( userInput, userOutput,
-                        bp->framesPerUserBuffer, bp->timeInfo,
-                        bp->callbackStatusFlags, bp->userData );
-
-                bp->timeInfo->inputBufferAdcTime += bp->framesPerUserBuffer * bp->samplePeriod;
-                bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod;
-
-                bp->framesInTempInputBuffer = 0;
-
-                if( *streamCallbackResult == paAbort )
-                    bp->framesInTempOutputBuffer = 0;
-                else
-                    bp->framesInTempOutputBuffer = bp->framesPerUserBuffer;
-            }
-            else
-            {
-                /* paComplete or paAbort has already been called. */
-
-                bp->framesInTempInputBuffer = 0;
-            }
-        }
-
-        /* copy frames from user (tempOutputBuffer) to host output buffers (hostOutputChannels) 
-           Means to process the user output provided by the callback. Has to be called after
-            each callback. */
-        CopyTempOutputBuffersToHostOutputBuffers( bp );		  	
-
-    }
-    
-    return framesProcessed;
-}
-
-
-unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bp, int *streamCallbackResult )
-{
-    unsigned long framesToProcess, framesToGo;
-    unsigned long framesProcessed = 0;
-    
-    if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0
-            && bp->hostInputChannels[0][0].data /* input was supplied (see PaUtil_SetNoInput) */
-            && bp->hostOutputChannels[0][0].data /* output was supplied (see PaUtil_SetNoOutput) */ )
-    {
-        assert( (bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) ==
-                (bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) );
-    }
-
-    assert( *streamCallbackResult == paContinue
-            || *streamCallbackResult == paComplete
-            || *streamCallbackResult == paAbort ); /* don't forget to pass in a valid callback result value */
-
-    if( bp->useNonAdaptingProcess )
-    {
-        if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 )
-        {
-            /* full duplex non-adapting process, splice buffers if they are
-                different lengths */
-
-            framesToGo = bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]; /* relies on assert above for input/output equivalence */
-
-            do{
-                unsigned long noInputInputFrameCount;
-                unsigned long *hostInputFrameCount;
-                PaUtilChannelDescriptor *hostInputChannels;
-                unsigned long noOutputOutputFrameCount;
-                unsigned long *hostOutputFrameCount;
-                PaUtilChannelDescriptor *hostOutputChannels;
-                unsigned long framesProcessedThisIteration;
-
-                if( !bp->hostInputChannels[0][0].data )
-                {
-                    /* no input was supplied (see PaUtil_SetNoInput)
-                        NonAdaptingProcess knows how to deal with this
-                    */
-                    noInputInputFrameCount = framesToGo;
-                    hostInputFrameCount = &noInputInputFrameCount;
-                    hostInputChannels = 0;
-                }
-                else if( bp->hostInputFrameCount[0] != 0 )
-                {
-                    hostInputFrameCount = &bp->hostInputFrameCount[0];
-                    hostInputChannels = bp->hostInputChannels[0];
-                }
-                else
-                {
-                    hostInputFrameCount = &bp->hostInputFrameCount[1];
-                    hostInputChannels = bp->hostInputChannels[1];
-                }
-
-                if( !bp->hostOutputChannels[0][0].data )
-                {
-                    /* no output was supplied (see PaUtil_SetNoOutput)
-                        NonAdaptingProcess knows how to deal with this
-                    */
-                    noOutputOutputFrameCount = framesToGo;
-                    hostOutputFrameCount = &noOutputOutputFrameCount;
-                    hostOutputChannels = 0;
-                }
-                if( bp->hostOutputFrameCount[0] != 0 )
-                {
-                    hostOutputFrameCount = &bp->hostOutputFrameCount[0];
-                    hostOutputChannels = bp->hostOutputChannels[0];
-                }
-                else
-                {
-                    hostOutputFrameCount = &bp->hostOutputFrameCount[1];
-                    hostOutputChannels = bp->hostOutputChannels[1];
-                }
-
-                framesToProcess = PA_MIN_( *hostInputFrameCount,
-                                       *hostOutputFrameCount );
-
-                assert( framesToProcess != 0 );
-                
-                framesProcessedThisIteration = NonAdaptingProcess( bp, streamCallbackResult,
-                        hostInputChannels, hostOutputChannels,
-                        framesToProcess );                                       
-
-                *hostInputFrameCount -= framesProcessedThisIteration;
-                *hostOutputFrameCount -= framesProcessedThisIteration;
-
-                framesProcessed += framesProcessedThisIteration;
-                framesToGo -= framesProcessedThisIteration;
-                
-            }while( framesToGo > 0 );
-        }
-        else
-        {
-            /* half duplex non-adapting process, just process 1st and 2nd buffer */
-            /* process first buffer */
-
-            framesToProcess = (bp->inputChannelCount != 0)
-                            ? bp->hostInputFrameCount[0]
-                            : bp->hostOutputFrameCount[0];
-
-            framesProcessed = NonAdaptingProcess( bp, streamCallbackResult,
-                        bp->hostInputChannels[0], bp->hostOutputChannels[0],
-                        framesToProcess );
-
-            /* process second buffer if provided */
-    
-            framesToProcess = (bp->inputChannelCount != 0)
-                            ? bp->hostInputFrameCount[1]
-                            : bp->hostOutputFrameCount[1];
-            if( framesToProcess > 0 )
-            {
-                framesProcessed += NonAdaptingProcess( bp, streamCallbackResult,
-                    bp->hostInputChannels[1], bp->hostOutputChannels[1],
-                    framesToProcess );
-            }
-        }
-    }
-    else /* block adaption necessary*/
-    {
-
-        if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 )
-        {
-            /* full duplex */
-            
-            if( bp->hostBufferSizeMode == paUtilVariableHostBufferSizePartialUsageAllowed  )
-            {
-                framesProcessed = AdaptingProcess( bp, streamCallbackResult,
-                        0 /* dont process partial user buffers */ );
-            }
-            else
-            {
-                framesProcessed = AdaptingProcess( bp, streamCallbackResult,
-                        1 /* process partial user buffers */ );
-            }
-        }
-        else if( bp->inputChannelCount != 0 )
-        {
-            /* input only */
-            framesToProcess = bp->hostInputFrameCount[0];
-
-            framesProcessed = AdaptingInputOnlyProcess( bp, streamCallbackResult,
-                        bp->hostInputChannels[0], framesToProcess );
-
-            framesToProcess = bp->hostInputFrameCount[1];
-            if( framesToProcess > 0 )
-            {
-                framesProcessed += AdaptingInputOnlyProcess( bp, streamCallbackResult,
-                        bp->hostInputChannels[1], framesToProcess );
-            }
-        }
-        else
-        {
-            /* output only */
-            framesToProcess = bp->hostOutputFrameCount[0];
-
-            framesProcessed = AdaptingOutputOnlyProcess( bp, streamCallbackResult,
-                        bp->hostOutputChannels[0], framesToProcess );
-
-            framesToProcess = bp->hostOutputFrameCount[1];
-            if( framesToProcess > 0 )
-            {
-                framesProcessed += AdaptingOutputOnlyProcess( bp, streamCallbackResult,
-                        bp->hostOutputChannels[1], framesToProcess );
-            }
-        }
-    }
-
-    return framesProcessed;
-}
-
-
-int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bp )
-{
-    return (bp->framesInTempOutputBuffer) ? 0 : 1;
-} 
-
-
-unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
-        void **buffer, unsigned long frameCount )
-{
-    PaUtilChannelDescriptor *hostInputChannels;
-    unsigned int framesToCopy;
-    unsigned char *destBytePtr;
-    void **nonInterleavedDestPtrs;
-    unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
-    unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */
-    unsigned int i;
-
-    hostInputChannels = bp->hostInputChannels[0];
-    framesToCopy = PA_MIN_( bp->hostInputFrameCount[0], frameCount );
-
-    if( bp->userInputIsInterleaved )
-    {
-        destBytePtr = (unsigned char*)*buffer;
-        
-        destSampleStrideSamples = bp->inputChannelCount;
-        destChannelStrideBytes = bp->bytesPerUserInputSample;
-
-        for( i=0; i<bp->inputChannelCount; ++i )
-        {
-            bp->inputConverter( destBytePtr, destSampleStrideSamples,
-                                hostInputChannels[i].data,
-                                hostInputChannels[i].stride,
-                                framesToCopy, &bp->ditherGenerator );
-
-            destBytePtr += destChannelStrideBytes;  /* skip to next source channel */
-
-            /* advance dest ptr for next iteration */
-            hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
-                    framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
-        }
-
-        /* advance callers dest pointer (buffer) */
-        *buffer = ((unsigned char *)*buffer) +
-                framesToCopy * bp->inputChannelCount * bp->bytesPerUserInputSample;
-    }
-    else
-    {
-        /* user input is not interleaved */
-        
-        nonInterleavedDestPtrs = (void**)*buffer;
-
-        destSampleStrideSamples = 1;
-        
-        for( i=0; i<bp->inputChannelCount; ++i )
-        {
-            destBytePtr = (unsigned char*)nonInterleavedDestPtrs[i];
-
-            bp->inputConverter( destBytePtr, destSampleStrideSamples,
-                                hostInputChannels[i].data,
-                                hostInputChannels[i].stride,
-                                framesToCopy, &bp->ditherGenerator );
-
-            /* advance callers dest pointer (nonInterleavedDestPtrs[i]) */
-            destBytePtr += bp->bytesPerUserInputSample * framesToCopy;
-            nonInterleavedDestPtrs[i] = destBytePtr;
-            
-            /* advance dest ptr for next iteration */
-            hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
-                    framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
-        }
-    }
-
-    bp->hostInputFrameCount[0] -= framesToCopy;
-    
-    return framesToCopy;
-}
-
-unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bp,
-        const void ** buffer, unsigned long frameCount )
-{
-    PaUtilChannelDescriptor *hostOutputChannels;
-    unsigned int framesToCopy;
-    unsigned char *srcBytePtr;
-    void **nonInterleavedSrcPtrs;
-    unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
-    unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */
-    unsigned int i;
-
-    hostOutputChannels = bp->hostOutputChannels[0];
-    framesToCopy = PA_MIN_( bp->hostOutputFrameCount[0], frameCount );
-
-    if( bp->userOutputIsInterleaved )
-    {
-        srcBytePtr = (unsigned char*)*buffer;
-        
-        srcSampleStrideSamples = bp->outputChannelCount;
-        srcChannelStrideBytes = bp->bytesPerUserOutputSample;
-
-        for( i=0; i<bp->outputChannelCount; ++i )
-        {
-            bp->outputConverter(    hostOutputChannels[i].data,
-                                    hostOutputChannels[i].stride,
-                                    srcBytePtr, srcSampleStrideSamples,
-                                    framesToCopy, &bp->ditherGenerator );
-
-            srcBytePtr += srcChannelStrideBytes;  /* skip to next source channel */
-
-            /* advance dest ptr for next iteration */
-            hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
-                    framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
-        }
-
-        /* advance callers source pointer (buffer) */
-        *buffer = ((unsigned char *)*buffer) +
-                framesToCopy * bp->outputChannelCount * bp->bytesPerUserOutputSample;
-
-    }
-    else
-    {
-        /* user output is not interleaved */
-        
-        nonInterleavedSrcPtrs = (void**)*buffer;
-
-        srcSampleStrideSamples = 1;
-        
-        for( i=0; i<bp->outputChannelCount; ++i )
-        {
-            srcBytePtr = (unsigned char*)nonInterleavedSrcPtrs[i];
-            
-            bp->outputConverter(    hostOutputChannels[i].data,
-                                    hostOutputChannels[i].stride,
-                                    srcBytePtr, srcSampleStrideSamples,
-                                    framesToCopy, &bp->ditherGenerator );
-
-
-            /* advance callers source pointer (nonInterleavedSrcPtrs[i]) */
-            srcBytePtr += bp->bytesPerUserOutputSample * framesToCopy;
-            nonInterleavedSrcPtrs[i] = srcBytePtr;
-            
-            /* advance dest ptr for next iteration */
-            hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
-                    framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
-        }
-    }
-
-    bp->hostOutputFrameCount[0] += framesToCopy;
-    
-    return framesToCopy;
-}
-
-
-unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bp, unsigned long frameCount )
-{
-    PaUtilChannelDescriptor *hostOutputChannels;
-    unsigned int framesToZero;
-    unsigned int i;
-
-    hostOutputChannels = bp->hostOutputChannels[0];
-    framesToZero = PA_MIN_( bp->hostOutputFrameCount[0], frameCount );
-
-    for( i=0; i<bp->outputChannelCount; ++i )
-    {
-        bp->outputZeroer(   hostOutputChannels[i].data,
-                            hostOutputChannels[i].stride,
-                            framesToZero );
-
-
-        /* advance dest ptr for next iteration */
-        hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
-                framesToZero * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
-    }
-
-    bp->hostOutputFrameCount[0] += framesToZero;
-    
-    return framesToZero;
-}
diff --git a/portaudio/pa_common/pa_process.h b/portaudio/pa_common/pa_process.h
deleted file mode 100644
index c52e9ea0a..000000000
--- a/portaudio/pa_common/pa_process.h
+++ /dev/null
@@ -1,741 +0,0 @@
-#ifndef PA_PROCESS_H
-#define PA_PROCESS_H
-/*
- * $Id: pa_process.h,v 1.1.2.30 2004/12/13 09:48:44 rossbencina Exp $
- * Portable Audio I/O Library callback buffer processing adapters
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Phil Burk, 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.
- */
- 
-/** @file
- @brief Buffer Processor prototypes. A Buffer Processor performs buffer length
- adaption, coordinates sample format conversion, and interleaves/deinterleaves
- channels.
-
- <h3>Overview</h3>
-
- The "Buffer Processor" (PaUtilBufferProcessor) manages conversion of audio
- data from host buffers to user buffers and back again. Where required, the
- buffer processor takes care of converting between host and user sample formats,
- interleaving and deinterleaving multichannel buffers, and adapting between host
- and user buffers with different lengths. The buffer processor may be used with
- full and half duplex streams, for both callback streams and blocking read/write
- streams.
-
- One of the important capabilities provided by the buffer processor is
- the ability to adapt between user and host buffer sizes of different lengths
- with minimum latency. Although this task is relatively easy to perform when
- the host buffer size is an integer multiple of the user buffer size, the
- problem is more complicated when this is not the case - especially for
- full-duplex callback streams. Where necessary the adaption is implemented by
- internally buffering some input and/or output data. The buffer adation
- algorithm used by the buffer processor was originally implemented by
- Stephan Letz for the ASIO version of PortAudio, and is described in his
- Callback_adaption_.pdf which is included in the distribution.
-
- The buffer processor performs sample conversion using the functions provided
- by pa_converters.c.
-
- The following sections provide an overview of how to use the buffer processor.
- Interested readers are advised to consult the host API implementations for
- examples of buffer processor usage.
- 
-
- <h4>Initialization, resetting and termination</h4>
-
- When a stream is opened, the buffer processor should be initialized using
- PaUtil_InitializeBufferProcessor. This function initializes internal state
- and allocates temporary buffers as neccesary according to the supplied
- configuration parameters. Some of the parameters correspond to those requested
- by the user in their call to Pa_OpenStream(), others reflect the requirements
- of the host API implementation - they indicate host buffer sizes, formats,
- and the type of buffering which the Host API uses. The buffer processor should
- be initialized for callback streams and blocking read/write streams.
-
- Call PaUtil_ResetBufferProcessor to clear any sample data which is present
- in the buffer processor before starting to use it (for example when
- Pa_StartStream is called).
-
- When the buffer processor is no longer used call
- PaUtil_TerminateBufferProcessor.
-
- 
- <h4>Using the buffer processor for a callback stream</h4>
-
- The buffer processor's role in a callback stream is to take host input buffers
- process them with the stream callback, and fill host output buffers. For a
- full duplex stream, the buffer processor handles input and output simultaneously
- due to the requirements of the minimum-latency buffer adation algorithm.
-
- When a host buffer becomes available, the implementation should call
- the buffer processor to process the buffer. The buffer processor calls the
- stream callback to consume and/or produce audio data as necessary. The buffer
- processor will convert sample formats, interleave/deinterleave channels,
- and slice or chunk the data to the appropriate buffer lengths according to
- the requirements of the stream callback and the host API.
-
- To process a host buffer (or a pair of host buffers for a full-duplex stream)
- use the following calling sequence:
-
- -# Call PaUtil_BeginBufferProcessing
- -# For a stream which takes input:
-    - Call PaUtil_SetInputFrameCount with the number of frames in the host input
-        buffer.
-    - Call one of the following functions one or more times to tell the
-        buffer processor about the host input buffer(s): PaUtil_SetInputChannel,
-        PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel.
-        Which function you call will depend on whether the host buffer(s) are
-        interleaved or not.
-    - If the available host data is split accross two buffers (for example a
-        data range at the end of a circular buffer and another range at the
-        beginning of the circular buffer), also call
-        PaUtil_Set2ndInputFrameCount, PaUtil_Set2ndInputChannel,
-        PaUtil_Set2ndInterleavedInputChannels,
-        PaUtil_Set2ndNonInterleavedInputChannel as necessary to tell the buffer
-        processor about the second buffer.
- -# For a stream which generates output:
-    - Call PaUtil_SetOutputFrameCount with the number of frames in the host
-        output buffer.
-    - Call one of the following functions one or more times to tell the
-        buffer processor about the host output buffer(s): PaUtil_SetOutputChannel,
-        PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel.
-        Which function you call will depend on whether the host buffer(s) are
-        interleaved or not.
-    - If the available host output buffer space is split accross two buffers
-        (for example a data range at the end of a circular buffer and another
-        range at the beginning of the circular buffer), call
-        PaUtil_Set2ndOutputFrameCount, PaUtil_Set2ndOutputChannel,
-        PaUtil_Set2ndInterleavedOutputChannels,
-        PaUtil_Set2ndNonInterleavedOutputChannel as necessary to tell the buffer
-        processor about the second buffer.
- -# Call PaUtil_EndBufferProcessing, this function performs the actual data
-    conversion and processing.
-
-
- <h4>Using the buffer processor for a blocking read/write stream</h4>
-
- Blocking read/write streams use the buffer processor to convert and copy user
- output data to a host buffer, and to convert and copy host input data to
- the user's buffer. The buffer processor does not perform any buffer adaption.
- When using the buffer processor in a blocking read/write stream the input and
- output conversion are performed separately by the PaUtil_CopyInput and
- PaUtil_CopyOutput functions.
-
- To copy data from a host input buffer to the buffer(s) which the user supplies
- to Pa_ReadStream, use the following calling sequence.
-
- - Repeat the following three steps until the user buffer(s) have been filled
-    with samples from the host input buffers:
-     -# Call PaUtil_SetInputFrameCount with the number of frames in the host
-        input buffer.
-     -# Call one of the following functions one or more times to tell the
-        buffer processor about the host input buffer(s): PaUtil_SetInputChannel,
-        PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel.
-        Which function you call will depend on whether the host buffer(s) are
-        interleaved or not.
-     -# Call PaUtil_CopyInput with the user buffer pointer (or a copy of the
-        array of buffer pointers for a non-interleaved stream) passed to
-        Pa_ReadStream, along with the number of frames in the user buffer(s).
-        Be careful to pass a <i>copy</i> of the user buffer pointers to
-        PaUtil_CopyInput because PaUtil_CopyInput advances the pointers to
-        the start of the next region to copy.
- - PaUtil_CopyInput will not copy more data than is available in the
-    host buffer(s), so the above steps need to be repeated until the user
-    buffer(s) are full.
-
- 
- To copy data to the host output buffer from the user buffers(s) supplied
- to Pa_WriteStream use the following calling sequence.
-
- - Repeat the following three steps until all frames from the user buffer(s)
-    have been copied to the host API:
-     -# Call PaUtil_SetOutputFrameCount with the number of frames in the host
-        output buffer.
-     -# Call one of the following functions one or more times to tell the
-        buffer processor about the host output buffer(s): PaUtil_SetOutputChannel,
-        PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel.
-        Which function you call will depend on whether the host buffer(s) are
-        interleaved or not.
-     -# Call PaUtil_CopyOutput with the user buffer pointer (or a copy of the
-        array of buffer pointers for a non-interleaved stream) passed to
-        Pa_WriteStream, along with the number of frames in the user buffer(s).
-        Be careful to pass a <i>copy</i> of the user buffer pointers to 
-        PaUtil_CopyOutput because PaUtil_CopyOutput advances the pointers to
-        the start of the next region to copy.
- - PaUtil_CopyOutput will not copy more data than fits in the host buffer(s),
-    so the above steps need to be repeated until all user data is copied.
-*/
-
-
-#include "portaudio.h"
-#include "pa_converters.h"
-#include "pa_dither.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-/** @brief Mode flag passed to PaUtil_InitializeBufferProcessor indicating the type
- of buffering that the host API uses.
-
- The mode used depends on whether the host API or the implementation manages
- the buffers, and how these buffers are used (scatter gather, circular buffer).
-*/
-typedef enum {
-/** The host buffer size is a fixed known size. */
-    paUtilFixedHostBufferSize,
-
-/** The host buffer size may vary, but has a known maximum size. */
-    paUtilBoundedHostBufferSize,
-
-/** Nothing is known about the host buffer size. */
-    paUtilUnknownHostBufferSize,
-
-/** The host buffer size varies, and the client does not require the buffer
- processor to consume all of the input and fill all of the output buffer. This
- is useful when the implementation has access to the host API's circular buffer
- and only needs to consume/fill some of it, not necessarily all of it, with each
- call to the buffer processor. This is the only mode where
- PaUtil_EndBufferProcessing() may not consume the whole buffer.
-*/
-    paUtilVariableHostBufferSizePartialUsageAllowed
-}PaUtilHostBufferSizeMode;
-
-
-/** @brief An auxilliary data structure used internally by the buffer processor
- to represent host input and output buffers. */
-typedef struct PaUtilChannelDescriptor{
-    void *data;
-    unsigned int stride;  /**< stride in samples, not bytes */
-}PaUtilChannelDescriptor;
-
-
-/** @brief The main buffer processor data structure.
-
- Allocate one of these, initialize it with PaUtil_InitializeBufferProcessor
- and terminate it with PaUtil_TerminateBufferProcessor.
-*/
-typedef struct {
-    unsigned long framesPerUserBuffer;
-    unsigned long framesPerHostBuffer;
-
-    PaUtilHostBufferSizeMode hostBufferSizeMode;
-    int useNonAdaptingProcess;
-    unsigned long framesPerTempBuffer;
-
-    unsigned int inputChannelCount;
-    unsigned int bytesPerHostInputSample;
-    unsigned int bytesPerUserInputSample;
-    int userInputIsInterleaved;
-    PaUtilConverter *inputConverter;
-    PaUtilZeroer *inputZeroer;
-    
-    unsigned int outputChannelCount;
-    unsigned int bytesPerHostOutputSample;
-    unsigned int bytesPerUserOutputSample;
-    int userOutputIsInterleaved;
-    PaUtilConverter *outputConverter;
-    PaUtilZeroer *outputZeroer;
-
-    unsigned long initialFramesInTempInputBuffer;
-    unsigned long initialFramesInTempOutputBuffer;
-
-    void *tempInputBuffer;          /**< used for slips, block adaption, and conversion. */
-    void **tempInputBufferPtrs;     /**< storage for non-interleaved buffer pointers, NULL for interleaved user input */
-    unsigned long framesInTempInputBuffer; /**< frames remaining in input buffer from previous adaption iteration */
-
-    void *tempOutputBuffer;         /**< used for slips, block adaption, and conversion. */
-    void **tempOutputBufferPtrs;    /**< storage for non-interleaved buffer pointers, NULL for interleaved user output */
-    unsigned long framesInTempOutputBuffer; /**< frames remaining in input buffer from previous adaption iteration */
-
-    PaStreamCallbackTimeInfo *timeInfo;
-
-    PaStreamCallbackFlags callbackStatusFlags;
-
-    unsigned long hostInputFrameCount[2];
-    PaUtilChannelDescriptor *hostInputChannels[2]; /**< pointers to arrays of channel descriptors.
-                                                        pointers are NULL for half-duplex output processing.
-                                                        hostInputChannels[i].data is NULL when the caller
-                                                        calls PaUtil_SetNoInput()
-                                                        */
-    unsigned long hostOutputFrameCount[2];
-    PaUtilChannelDescriptor *hostOutputChannels[2]; /**< pointers to arrays of channel descriptors.
-                                                         pointers are NULL for half-duplex input processing.
-                                                         hostOutputChannels[i].data is NULL when the caller
-                                                         calls PaUtil_SetNoOutput()
-                                                         */
-
-    PaUtilTriangularDitherGenerator ditherGenerator;
-
-    double samplePeriod;
-
-    PaStreamCallback *streamCallback;
-    void *userData;
-} PaUtilBufferProcessor;
-
-
-/** @name Initialization, termination, resetting and info */
-/*@{*/
-
-/** Initialize a buffer processor's representation stored in a
- PaUtilBufferProcessor structure. Be sure to call
- PaUtil_TerminateBufferProcessor after finishing with a buffer processor.
-
- @param bufferProcessor The buffer processor structure to initialize.
-
- @param inputChannelCount The number of input channels as passed to
- Pa_OpenStream or 0 for an output-only stream.
-
- @param userInputSampleFormat Format of user input samples, as passed to
- Pa_OpenStream. This parameter is ignored for ouput-only streams.
- 
- @param hostInputSampleFormat Format of host input samples. This parameter is
- ignored for output-only streams. See note about host buffer interleave below.
-
- @param outputChannelCount The number of output channels as passed to
- Pa_OpenStream or 0 for an input-only stream.
-
- @param userOutputSampleFormat Format of user output samples, as passed to
- Pa_OpenStream. This parameter is ignored for input-only streams.
- 
- @param hostOutputSampleFormat Format of host output samples. This parameter is
- ignored for input-only streams. See note about host buffer interleave below.
-
- @param sampleRate Sample rate of the stream. The more accurate this is the
- better - it is used for updating time stamps when adapting buffers.
- 
- @param streamFlags Stream flags as passed to Pa_OpenStream, this parameter is
- used for selecting special sample conversion options such as clipping and
- dithering.
- 
- @param framesPerUserBuffer Number of frames per user buffer, as requested
- by the framesPerBuffer parameter to Pa_OpenStream. This parameter may be
- zero to indicate that the user will accept any (and varying) buffer sizes.
-
- @param framesPerHostBuffer Specifies the number of frames per host buffer
- for the fixed buffer size mode, and the maximum number of frames
- per host buffer for the bounded host buffer size mode. It is ignored for
- the other modes.
-
- @param hostBufferSizeMode A mode flag indicating the size variability of
- host buffers that will be passed to the buffer processor. See
- PaUtilHostBufferSizeMode for further details.
- 
- @param streamCallback The user stream callback passed to Pa_OpenStream.
-
- @param userData The user data field passed to Pa_OpenStream.
-    
- @note The interleave flag is ignored for host buffer formats. Host
- interleave is determined by the use of different SetInput and SetOutput
- functions.
-
- @return An error code indicating whether the initialization was successful.
- If the error code is not PaNoError, the buffer processor was not initialized
- and should not be used.
- 
- @see Pa_OpenStream, PaUtilHostBufferSizeMode, PaUtil_TerminateBufferProcessor
-*/
-PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bufferProcessor,
-            int inputChannelCount, PaSampleFormat userInputSampleFormat,
-            PaSampleFormat hostInputSampleFormat,
-            int outputChannelCount, PaSampleFormat userOutputSampleFormat,
-            PaSampleFormat hostOutputSampleFormat,
-            double sampleRate,
-            PaStreamFlags streamFlags,
-            unsigned long framesPerUserBuffer, /* 0 indicates don't care */
-            unsigned long framesPerHostBuffer,
-            PaUtilHostBufferSizeMode hostBufferSizeMode,
-            PaStreamCallback *streamCallback, void *userData );
-
-
-/** Terminate a buffer processor's representation. Deallocates any temporary
- buffers allocated by PaUtil_InitializeBufferProcessor.
- 
- @param bufferProcessor The buffer processor structure to terminate.
-
- @see PaUtil_InitializeBufferProcessor.
-*/
-void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bufferProcessor );
-
-
-/** Clear any internally buffered data. If you call
- PaUtil_InitializeBufferProcessor in your OpenStream routine, make sure you
- call PaUtil_ResetBufferProcessor in your StartStream call.
-
- @param bufferProcessor The buffer processor to reset.
-*/
-void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bufferProcessor );
-
-
-/** Retrieve the input latency of a buffer processor.
-
- @param bufferProcessor The buffer processor examine.
-
- @return The input latency introduced by the buffer processor, in frames.
-
- @see PaUtil_GetBufferProcessorOutputLatency
-*/
-unsigned long PaUtil_GetBufferProcessorInputLatency( PaUtilBufferProcessor* bufferProcessor );
-
-/** Retrieve the output latency of a buffer processor.
-
- @param bufferProcessor The buffer processor examine.
-
- @return The output latency introduced by the buffer processor, in frames.
-
- @see PaUtil_GetBufferProcessorInputLatency
-*/
-unsigned long PaUtil_GetBufferProcessorOutputLatency( PaUtilBufferProcessor* bufferProcessor );
-
-/*@}*/
-
-
-/** @name Host buffer pointer configuration
-
- Functions to set host input and output buffers, used by both callback streams
- and blocking read/write streams.
-*/
-/*@{*/ 
-
-
-/** Set the number of frames in the input host buffer(s) specified by the
- PaUtil_Set*InputChannel functions.
-
- @param bufferProcessor The buffer processor.
-
- @param frameCount The number of host input frames. A 0 frameCount indicates to
- use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor.
-
- @see PaUtil_SetNoInput, PaUtil_SetInputChannel,
- PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel
-*/
-void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bufferProcessor,
-        unsigned long frameCount );
-
-        
-/** Indicate that no input is avalable. This function should be used when
- priming the output of a full-duplex stream opened with the
- paPrimeOutputBuffersUsingStreamCallback flag. Note that it is not necessary
- to call this or any othe PaUtil_Set*Input* functions for ouput-only streams.
-
- @param bufferProcessor The buffer processor.
-*/
-void PaUtil_SetNoInput( PaUtilBufferProcessor* bufferProcessor );
-
-
-/** Provide the buffer processor with a pointer to a host input channel.
-
- @param bufferProcessor The buffer processor.
- @param channel The channel number.
- @param data The buffer.
- @param stride The stride from one sample to the next, in samples. For
- interleaved host buffers, the stride will usually be the same as the number of
- channels in the buffer.
-*/
-void PaUtil_SetInputChannel( PaUtilBufferProcessor* bufferProcessor,
-        unsigned int channel, void *data, unsigned int stride );
-
-
-/** Provide the buffer processor with a pointer to an number of interleaved
- host input channels.
-
- @param bufferProcessor The buffer processor.
- @param firstChannel The first channel number.
- @param data The buffer.
- @param channelCount The number of interleaved channels in the buffer. If
- channelCount is zero, the number of channels specified to
- PaUtil_InitializeBufferProcessor will be used.
-*/
-void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor,
-        unsigned int firstChannel, void *data, unsigned int channelCount );
-
-
-/** Provide the buffer processor with a pointer to one non-interleaved host
- output channel.
-
- @param bufferProcessor The buffer processor.
- @param channel The channel number.
- @param data The buffer.
-*/
-void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor,
-        unsigned int channel, void *data );
-
-
-/** Use for the second buffer half when the input buffer is split in two halves.
- @see PaUtil_SetInputFrameCount
-*/
-void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bufferProcessor,
-        unsigned long frameCount );
-
-/** Use for the second buffer half when the input buffer is split in two halves.
- @see PaUtil_SetInputChannel
-*/
-void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bufferProcessor,
-        unsigned int channel, void *data, unsigned int stride );
-
-/** Use for the second buffer half when the input buffer is split in two halves.
- @see PaUtil_SetInterleavedInputChannels
-*/
-void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor,
-        unsigned int firstChannel, void *data, unsigned int channelCount );
-
-/** Use for the second buffer half when the input buffer is split in two halves.
- @see PaUtil_SetNonInterleavedInputChannel
-*/
-void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor,
-        unsigned int channel, void *data );
-
-        
-/** Set the number of frames in the output host buffer(s) specified by the
- PaUtil_Set*OutputChannel functions.
-
- @param bufferProcessor The buffer processor.
-
- @param frameCount The number of host output frames. A 0 frameCount indicates to
- use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor.
-
- @see PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels,
- PaUtil_SetNonInterleavedOutputChannel
-*/
-void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bufferProcessor,
-        unsigned long frameCount );
-
-
-/** Indicate that the output will be discarded. This function should be used
- when implementing the paNeverDropInput mode for full duplex streams.
-
- @param bufferProcessor The buffer processor.
-*/
-void PaUtil_SetNoOutput( PaUtilBufferProcessor* bufferProcessor );
-
-
-/** Provide the buffer processor with a pointer to a host output channel.
-
- @param bufferProcessor The buffer processor.
- @param channel The channel number.
- @param data The buffer.
- @param stride The stride from one sample to the next, in samples. For
- interleaved host buffers, the stride will usually be the same as the number of
- channels in the buffer.
-*/
-void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bufferProcessor,
-        unsigned int channel, void *data, unsigned int stride );
-
-
-/** Provide the buffer processor with a pointer to a number of interleaved
- host output channels.
-
- @param bufferProcessor The buffer processor.
- @param firstChannel The first channel number.
- @param data The buffer.
- @param channelCount The number of interleaved channels in the buffer. If
- channelCount is zero, the number of channels specified to
- PaUtil_InitializeBufferProcessor will be used.
-*/
-void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor,
-        unsigned int firstChannel, void *data, unsigned int channelCount );
-
-        
-/** Provide the buffer processor with a pointer to one non-interleaved host
- output channel.
-
- @param bufferProcessor The buffer processor.
- @param channel The channel number.
- @param data The buffer.
-*/
-void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor,
-        unsigned int channel, void *data );
-
-
-/** Use for the second buffer half when the output buffer is split in two halves.
- @see PaUtil_SetOutputFrameCount
-*/
-void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bufferProcessor,
-        unsigned long frameCount );
-
-/** Use for the second buffer half when the output buffer is split in two halves.
- @see PaUtil_SetOutputChannel
-*/
-void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bufferProcessor,
-        unsigned int channel, void *data, unsigned int stride );
-
-/** Use for the second buffer half when the output buffer is split in two halves.
- @see PaUtil_SetInterleavedOutputChannels
-*/
-void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor,
-        unsigned int firstChannel, void *data, unsigned int channelCount );
-
-/** Use for the second buffer half when the output buffer is split in two halves.
- @see PaUtil_SetNonInterleavedOutputChannel
-*/
-void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor,
-        unsigned int channel, void *data );
-
-/*@}*/
-
-
-/** @name Buffer processing functions for callback streams
-*/
-/*@{*/
-
-/** Commence processing a host buffer (or a pair of host buffers in the
- full-duplex case) for a callback stream.
-
- @param bufferProcessor The buffer processor.
-
- @param timeInfo Timing information for the first sample of the host
- buffer(s). This information may be adjusted when buffer adaption is being
- performed.
-
- @param callbackStatusFlags Flags indicating whether underruns and overruns
- have occurred since the last time the buffer processor was called.
-*/
-void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bufferProcessor,
-        PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags );
-
-        
-/** Finish processing a host buffer (or a pair of host buffers in the
- full-duplex case) for a callback stream.
-
- @param bufferProcessor The buffer processor.
- 
- @param callbackResult On input, indicates a previous callback result, and on
- exit, the result of the user stream callback, if it is called.
- On entry callbackResult should contain one of { paContinue, paComplete, or
- paAbort}. If paComplete is passed, the stream callback will not be called
- but any audio that was generated by previous stream callbacks will be copied
- to the output buffer(s). You can check whether the buffer processor's internal
- buffer is empty by calling PaUtil_IsBufferProcessorOutputEmpty.
-
- If the stream callback is called its result is stored in *callbackResult. If
- the stream callback returns paComplete or paAbort, all output buffers will be
- full of valid data - some of which may be zeros to acount for data that
- wasn't generated by the terminating callback.
-
- @return The number of frames processed. This usually corresponds to the
- number of frames specified by the PaUtil_Set*FrameCount functions, exept in
- the paUtilVariableHostBufferSizePartialUsageAllowed buffer size mode when a
- smaller value may be returned.
-*/
-unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bufferProcessor,
-        int *callbackResult );
-
-
-/** Determine whether any callback generated output remains in the bufffer
- processor's internal buffers. This method may be used to determine when to
- continue calling PaUtil_EndBufferProcessing() after the callback has returned
- a callbackResult of paComplete.
-
- @param bufferProcessor The buffer processor.
- 
- @return Returns non-zero when callback generated output remains in the internal
- buffer and zero (0) when there internal buffer contains no callback generated
- data.
-*/
-int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bufferProcessor );
-
-/*@}*/
-
-
-/** @name Buffer processing functions for blocking read/write streams
-*/
-/*@{*/
-
-/** Copy samples from host input channels set up by the PaUtil_Set*InputChannels
- functions to a user supplied buffer. This function is intended for use with
- blocking read/write streams. Copies the minimum of the number of
- user frames (specified by the frameCount parameter) and the number of available
- host frames (specified in a previous call to SetInputFrameCount()).
-
- @param bufferProcessor The buffer processor.
-
- @param buffer A pointer to the user buffer pointer, or a pointer to a pointer
- to an array of user buffer pointers for a non-interleaved stream. It is
- important that this parameter points to a copy of the user buffer pointers,
- not to the actual user buffer pointers, because this function updates the
- pointers before returning.
-
- @param frameCount The number of frames of data in the buffer(s) pointed to by
- the buffer parameter.
-
- @return The number of frames copied. The buffer pointer(s) pointed to by the
- buffer parameter are advanced to point to the frame(s) following the last one
- filled.
-*/
-unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bufferProcessor,
-        void **buffer, unsigned long frameCount );
-
-
-/* Copy samples from a user supplied buffer to host output channels set up by
- the PaUtil_Set*OutputChannels functions. This function is intended for use with
- blocking read/write streams. Copies the minimum of the number of
- user frames (specified by the frameCount parameter) and the number of
- host frames (specified in a previous call to SetOutputFrameCount()).
-
- @param bufferProcessor The buffer processor.
-
- @param buffer A pointer to the user buffer pointer, or a pointer to a pointer
- to an array of user buffer pointers for a non-interleaved stream. It is
- important that this parameter points to a copy of the user buffer pointers,
- not to the actual user buffer pointers, because this function updates the
- pointers before returning.
-
- @param frameCount The number of frames of data in the buffer(s) pointed to by
- the buffer parameter.
-
- @return The number of frames copied. The buffer pointer(s) pointed to by the
- buffer parameter are advanced to point to the frame(s) following the last one
- copied.
-*/
-unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bufferProcessor,
-        const void ** buffer, unsigned long frameCount );
-
-
-/* Zero samples in host output channels set up by the PaUtil_Set*OutputChannels
- functions. This function is useful for flushing streams.
- Zeros the minimum of frameCount and the number of host frames specified in a
- previous call to SetOutputFrameCount().
-
- @param bufferProcessor The buffer processor.
-
- @param frameCount The maximum number of frames to zero.
- 
- @return The number of frames zeroed.
-*/
-unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bufferProcessor,
-        unsigned long frameCount );
-
-
-/*@}*/
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PA_PROCESS_H */
diff --git a/portaudio/pa_common/pa_skeleton.c b/portaudio/pa_common/pa_skeleton.c
deleted file mode 100644
index ebc1f5018..000000000
--- a/portaudio/pa_common/pa_skeleton.c
+++ /dev/null
@@ -1,807 +0,0 @@
-/*
- * $Id: pa_skeleton.c,v 1.1.2.39 2003/11/26 14:56:09 rossbencina Exp $
- * Portable Audio I/O Library skeleton implementation
- * demonstrates how to use the common functions to implement support
- * for a host API
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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.
- */
-
-/** @file
- @brief Skeleton implementation of support for a host API.
-
- @note This file is provided as a starting point for implementing support for
- a new host API. IMPLEMENT ME comments are used to indicate functionality
- which much be customised for each implementation.
-*/
-
-
-#include <string.h> /* strlen() */
-
-#include "pa_util.h"
-#include "pa_allocation.h"
-#include "pa_hostapi.h"
-#include "pa_stream.h"
-#include "pa_cpuload.h"
-#include "pa_process.h"
-
-
-/* prototypes for functions declared in this file */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate );
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData );
-static PaError CloseStream( PaStream* stream );
-static PaError StartStream( PaStream *stream );
-static PaError StopStream( PaStream *stream );
-static PaError AbortStream( PaStream *stream );
-static PaError IsStreamStopped( PaStream *s );
-static PaError IsStreamActive( PaStream *stream );
-static PaTime GetStreamTime( PaStream *stream );
-static double GetStreamCpuLoad( PaStream* stream );
-static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
-static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
-static signed long GetStreamReadAvailable( PaStream* stream );
-static signed long GetStreamWriteAvailable( PaStream* stream );
-
-
-/* IMPLEMENT ME: a macro like the following one should be used for reporting
- host errors */
-#define PA_SKELETON_SET_LAST_HOST_ERROR( errorCode, errorText ) \
-    PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText )
-
-/* PaSkeletonHostApiRepresentation - host api datastructure specific to this implementation */
-
-typedef struct
-{
-    PaUtilHostApiRepresentation inheritedHostApiRep;
-    PaUtilStreamInterface callbackStreamInterface;
-    PaUtilStreamInterface blockingStreamInterface;
-
-    PaUtilAllocationGroup *allocations;
-
-    /* implementation specific data goes here */
-}
-PaSkeletonHostApiRepresentation;  /* IMPLEMENT ME: rename this */
-
-
-PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
-{
-    PaError result = paNoError;
-    int i, deviceCount;
-    PaSkeletonHostApiRepresentation *skeletonHostApi;
-    PaDeviceInfo *deviceInfoArray;
-
-    skeletonHostApi = (PaSkeletonHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaSkeletonHostApiRepresentation) );
-    if( !skeletonHostApi )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    skeletonHostApi->allocations = PaUtil_CreateAllocationGroup();
-    if( !skeletonHostApi->allocations )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    *hostApi = &skeletonHostApi->inheritedHostApiRep;
-    (*hostApi)->info.structVersion = 1;
-    (*hostApi)->info.type = paInDevelopment;            /* IMPLEMENT ME: change to correct type id */
-    (*hostApi)->info.name = "skeleton implementation";  /* IMPLEMENT ME: change to correct name */
-
-    (*hostApi)->info.defaultInputDevice = paNoDevice;  /* IMPLEMENT ME */
-    (*hostApi)->info.defaultOutputDevice = paNoDevice; /* IMPLEMENT ME */
-
-    (*hostApi)->info.deviceCount = 0;  
-
-    deviceCount = 0; /* IMPLEMENT ME */
-    
-    if( deviceCount > 0 )
-    {
-        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
-                skeletonHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount );
-        if( !(*hostApi)->deviceInfos )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        /* allocate all device info structs in a contiguous block */
-        deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory(
-                skeletonHostApi->allocations, sizeof(PaDeviceInfo) * deviceCount );
-        if( !deviceInfoArray )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        for( i=0; i < deviceCount; ++i )
-        {
-            PaDeviceInfo *deviceInfo = &deviceInfoArray[i];
-            deviceInfo->structVersion = 2;
-            deviceInfo->hostApi = hostApiIndex;
-            deviceInfo->name = 0; /* IMPLEMENT ME: allocate block and copy name eg:
-                deviceName = (char*)PaUtil_GroupAllocateMemory( skeletonHostApi->allocations, strlen(srcName) + 1 );
-                if( !deviceName )
-                {
-                    result = paInsufficientMemory;
-                    goto error;
-                }
-                strcpy( deviceName, srcName );
-                deviceInfo->name = deviceName;
-            */
-
-            deviceInfo->maxInputChannels = 0;  /* IMPLEMENT ME */
-            deviceInfo->maxOutputChannels = 0;  /* IMPLEMENT ME */
-            
-            deviceInfo->defaultLowInputLatency = 0.;  /* IMPLEMENT ME */
-            deviceInfo->defaultLowOutputLatency = 0.;  /* IMPLEMENT ME */
-            deviceInfo->defaultHighInputLatency = 0.;  /* IMPLEMENT ME */
-            deviceInfo->defaultHighOutputLatency = 0.;  /* IMPLEMENT ME */  
-
-            deviceInfo->defaultSampleRate = 0.; /* IMPLEMENT ME */
-            
-            (*hostApi)->deviceInfos[i] = deviceInfo;
-            ++(*hostApi)->info.deviceCount;
-        }
-    }
-
-    (*hostApi)->Terminate = Terminate;
-    (*hostApi)->OpenStream = OpenStream;
-    (*hostApi)->IsFormatSupported = IsFormatSupported;
-
-    PaUtil_InitializeStreamInterface( &skeletonHostApi->callbackStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, GetStreamCpuLoad,
-                                      PaUtil_DummyRead, PaUtil_DummyWrite,
-                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
-
-    PaUtil_InitializeStreamInterface( &skeletonHostApi->blockingStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
-                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
-
-    return result;
-
-error:
-    if( skeletonHostApi )
-    {
-        if( skeletonHostApi->allocations )
-        {
-            PaUtil_FreeAllAllocations( skeletonHostApi->allocations );
-            PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations );
-        }
-                
-        PaUtil_FreeMemory( skeletonHostApi );
-    }
-    return result;
-}
-
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
-{
-    PaSkeletonHostApiRepresentation *skeletonHostApi = (PaSkeletonHostApiRepresentation*)hostApi;
-
-    /*
-        IMPLEMENT ME:
-            - clean up any resources not handled by the allocation group
-    */
-
-    if( skeletonHostApi->allocations )
-    {
-        PaUtil_FreeAllAllocations( skeletonHostApi->allocations );
-        PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations );
-    }
-
-    PaUtil_FreeMemory( skeletonHostApi );
-}
-
-
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate )
-{
-    int inputChannelCount, outputChannelCount;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-
-        /* all standard sample formats are supported by the buffer adapter,
-            this implementation doesn't support any custom sample formats */
-        if( inputSampleFormat & paCustomFormat )
-            return paSampleFormatNotSupported;
-            
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that input device can support inputChannelCount */
-        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
-            return paInvalidChannelCount;
-
-        /* validate inputStreamInfo */
-        if( inputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        inputChannelCount = 0;
-    }
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-
-        /* all standard sample formats are supported by the buffer adapter,
-            this implementation doesn't support any custom sample formats */
-        if( outputSampleFormat & paCustomFormat )
-            return paSampleFormatNotSupported;
-            
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that output device can support outputChannelCount */
-        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
-            return paInvalidChannelCount;
-
-        /* validate outputStreamInfo */
-        if( outputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        outputChannelCount = 0;
-    }
-    
-    /*
-        IMPLEMENT ME:
-
-            - if a full duplex stream is requested, check that the combination
-                of input and output parameters is supported if necessary
-
-            - check that the device supports sampleRate
-
-        Because the buffer adapter handles conversion between all standard
-        sample formats, the following checks are only required if paCustomFormat
-        is implemented, or under some other unusual conditions.
-
-            - check that input device can support inputSampleFormat, or that
-                we have the capability to convert from inputSampleFormat to
-                a native format
-
-            - check that output device can support outputSampleFormat, or that
-                we have the capability to convert from outputSampleFormat to
-                a native format
-    */
-
-
-    /* suppress unused variable warnings */
-    (void) sampleRate;
-
-    return paFormatIsSupported;
-}
-
-/* PaSkeletonStream - a stream data structure specifically for this implementation */
-
-typedef struct PaSkeletonStream
-{ /* IMPLEMENT ME: rename this */
-    PaUtilStreamRepresentation streamRepresentation;
-    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
-    PaUtilBufferProcessor bufferProcessor;
-
-    /* IMPLEMENT ME:
-            - implementation specific data goes here
-    */
-    unsigned long framesPerHostCallback; /* just an example */
-}
-PaSkeletonStream;
-
-/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */
-
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData )
-{
-    PaError result = paNoError;
-    PaSkeletonHostApiRepresentation *skeletonHostApi = (PaSkeletonHostApiRepresentation*)hostApi;
-    PaSkeletonStream *stream = 0;
-    unsigned long framesPerHostBuffer = framesPerBuffer; /* these may not be equivalent for all implementations */
-    int inputChannelCount, outputChannelCount;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
-
-
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that input device can support inputChannelCount */
-        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
-            return paInvalidChannelCount;
-
-        /* validate inputStreamInfo */
-        if( inputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-
-        /* IMPLEMENT ME - establish which  host formats are available */
-        hostInputSampleFormat =
-            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat );
-    }
-    else
-    {
-        inputChannelCount = 0;
-        inputSampleFormat = hostInputSampleFormat = paInt16; /* Surpress 'uninitialised var' warnings. */
-    }
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-        
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that output device can support inputChannelCount */
-        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
-            return paInvalidChannelCount;
-
-        /* validate outputStreamInfo */
-        if( outputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-
-        /* IMPLEMENT ME - establish which  host formats are available */
-        hostOutputSampleFormat =
-            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat );
-    }
-    else
-    {
-        outputChannelCount = 0;
-        outputSampleFormat = hostOutputSampleFormat = paInt16; /* Surpress 'uninitialized var' warnings. */
-    }
-
-    /*
-        IMPLEMENT ME:
-
-        ( the following two checks are taken care of by PaUtil_InitializeBufferProcessor() FIXME - checks needed? )
-
-            - check that input device can support inputSampleFormat, or that
-                we have the capability to convert from outputSampleFormat to
-                a native format
-
-            - check that output device can support outputSampleFormat, or that
-                we have the capability to convert from outputSampleFormat to
-                a native format
-
-            - if a full duplex stream is requested, check that the combination
-                of input and output parameters is supported
-
-            - check that the device supports sampleRate
-
-            - alter sampleRate to a close allowable rate if possible / necessary
-
-            - validate suggestedInputLatency and suggestedOutputLatency parameters,
-                use default values where necessary
-    */
-
-
-
-
-    /* validate platform specific flags */
-    if( (streamFlags & paPlatformSpecificFlags) != 0 )
-        return paInvalidFlag; /* unexpected platform specific flag */
-
-
-    stream = (PaSkeletonStream*)PaUtil_AllocateMemory( sizeof(PaSkeletonStream) );
-    if( !stream )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    if( streamCallback )
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &skeletonHostApi->callbackStreamInterface, streamCallback, userData );
-    }
-    else
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &skeletonHostApi->blockingStreamInterface, streamCallback, userData );
-    }
-
-    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
-
-
-    /* we assume a fixed host buffer size in this example, but the buffer processor
-        can also support bounded and unknown host buffer sizes by passing 
-        paUtilBoundedHostBufferSize or paUtilUnknownHostBufferSize instead of
-        paUtilFixedHostBufferSize below. */
-        
-    result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
-              inputChannelCount, inputSampleFormat, hostInputSampleFormat,
-              outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
-              sampleRate, streamFlags, framesPerBuffer,
-              framesPerHostBuffer, paUtilFixedHostBufferSize,
-              streamCallback, userData );
-    if( result != paNoError )
-        goto error;
-
-
-    /*
-        IMPLEMENT ME: initialise the following fields with estimated or actual
-        values.
-    */
-    stream->streamRepresentation.streamInfo.inputLatency =
-            PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor);
-    stream->streamRepresentation.streamInfo.outputLatency =
-            PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor);
-    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
-
-    
-    /*
-        IMPLEMENT ME:
-            - additional stream setup + opening
-    */
-
-    stream->framesPerHostCallback = framesPerHostBuffer;
-
-    *s = (PaStream*)stream;
-
-    return result;
-
-error:
-    if( stream )
-        PaUtil_FreeMemory( stream );
-
-    return result;
-}
-
-/*
-    ExampleHostProcessingLoop() illustrates the kind of processing which may
-    occur in a host implementation.
- 
-*/
-static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, void *userData )
-{
-    PaSkeletonStream *stream = (PaSkeletonStream*)userData;
-    PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* IMPLEMENT ME */
-    int callbackResult;
-    unsigned long framesProcessed;
-    
-    PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
-    
-    /*
-        IMPLEMENT ME:
-            - generate timing information
-            - handle buffer slips
-    */
-
-    /*
-        If you need to byte swap or shift inputBuffer to convert it into a
-        portaudio format, do it here.
-    */
-
-
-
-    PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, 0 /* IMPLEMENT ME: pass underflow/overflow flags when necessary */ );
-
-    /*
-        depending on whether the host buffers are interleaved, non-interleaved
-        or a mixture, you will want to call PaUtil_SetInterleaved*Channels(),
-        PaUtil_SetNonInterleaved*Channel() or PaUtil_Set*Channel() here.
-    */
-    
-    PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
-    PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor,
-            0, /* first channel of inputBuffer is channel 0 */
-            inputBuffer,
-            0 ); /* 0 - use inputChannelCount passed to init buffer processor */
-
-    PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
-    PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor,
-            0, /* first channel of outputBuffer is channel 0 */
-            outputBuffer,
-            0 ); /* 0 - use outputChannelCount passed to init buffer processor */
-
-    /* you must pass a valid value of callback result to PaUtil_EndBufferProcessing()
-        in general you would pass paContinue for normal operation, and
-        paComplete to drain the buffer processor's internal output buffer.
-        You can check whether the buffer processor's output buffer is empty
-        using PaUtil_IsBufferProcessorOuputEmpty( bufferProcessor )
-    */
-    callbackResult = paContinue;
-    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );
-
-    
-    /*
-        If you need to byte swap or shift outputBuffer to convert it to
-        host format, do it here.
-    */
-
-    PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
-
-
-    if( callbackResult == paContinue )
-    {
-        /* nothing special to do */
-    }
-    else if( callbackResult == paAbort )
-    {
-        /* IMPLEMENT ME - finish playback immediately  */
-
-        /* once finished, call the finished callback */
-        if( stream->streamRepresentation.streamFinishedCallback != 0 )
-            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
-    }
-    else
-    {
-        /* User callback has asked us to stop with paComplete or other non-zero value */
-
-        /* IMPLEMENT ME - finish playback once currently queued audio has completed  */
-
-        /* once finished, call the finished callback */
-        if( stream->streamRepresentation.streamFinishedCallback != 0 )
-            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
-    }
-}
-
-
-/*
-    When CloseStream() is called, the multi-api layer ensures that
-    the stream has already been stopped or aborted.
-*/
-static PaError CloseStream( PaStream* s )
-{
-    PaError result = paNoError;
-    PaSkeletonStream *stream = (PaSkeletonStream*)s;
-
-    /*
-        IMPLEMENT ME:
-            - additional stream closing + cleanup
-    */
-
-    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
-    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
-    PaUtil_FreeMemory( stream );
-
-    return result;
-}
-
-
-static PaError StartStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaSkeletonStream *stream = (PaSkeletonStream*)s;
-
-    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior */
-
-    /* suppress unused function warning. the code in ExampleHostProcessingLoop or
-       something similar should be implemented to feed samples to and from the
-       host after StartStream() is called.
-    */
-    (void) ExampleHostProcessingLoop;
-
-    return result;
-}
-
-
-static PaError StopStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaSkeletonStream *stream = (PaSkeletonStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) stream;
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior */
-
-    return result;
-}
-
-
-static PaError AbortStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaSkeletonStream *stream = (PaSkeletonStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior */
-
-    return result;
-}
-
-
-static PaError IsStreamStopped( PaStream *s )
-{
-    PaSkeletonStream *stream = (PaSkeletonStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior */
-
-    return 0;
-}
-
-
-static PaError IsStreamActive( PaStream *s )
-{
-    PaSkeletonStream *stream = (PaSkeletonStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior */
-
-    return 0;
-}
-
-
-static PaTime GetStreamTime( PaStream *s )
-{
-    PaSkeletonStream *stream = (PaSkeletonStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return 0;
-}
-
-
-static double GetStreamCpuLoad( PaStream* s )
-{
-    PaSkeletonStream *stream = (PaSkeletonStream*)s;
-
-    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
-}
-
-
-/*
-    As separate stream interfaces are used for blocking and callback
-    streams, the following functions can be guaranteed to only be called
-    for blocking streams.
-*/
-
-static PaError ReadStream( PaStream* s,
-                           void *buffer,
-                           unsigned long frames )
-{
-    PaSkeletonStream *stream = (PaSkeletonStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) buffer;
-    (void) frames;
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return paNoError;
-}
-
-
-static PaError WriteStream( PaStream* s,
-                            const void *buffer,
-                            unsigned long frames )
-{
-    PaSkeletonStream *stream = (PaSkeletonStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) buffer;
-    (void) frames;
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return paNoError;
-}
-
-
-static signed long GetStreamReadAvailable( PaStream* s )
-{
-    PaSkeletonStream *stream = (PaSkeletonStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return 0;
-}
-
-
-static signed long GetStreamWriteAvailable( PaStream* s )
-{
-    PaSkeletonStream *stream = (PaSkeletonStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return 0;
-}
-
-
-
-
diff --git a/portaudio/pa_common/pa_stream.c b/portaudio/pa_common/pa_stream.c
deleted file mode 100644
index 044dde29e..000000000
--- a/portaudio/pa_common/pa_stream.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * $Id: pa_stream.c,v 1.1.2.12 2003/09/20 21:31:00 rossbencina Exp $
- * Portable Audio I/O Library
- * 
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 2002 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.
- */
-
-/** @file
- @brief Interface used by pa_front to virtualize functions which operate on
- streams.
-*/
-
-
-#include "pa_stream.h"
-
-
-void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface,
-                                       PaError (*Close)( PaStream* ),
-                                       PaError (*Start)( PaStream* ),
-                                       PaError (*Stop)( PaStream* ),
-                                       PaError (*Abort)( PaStream* ),
-                                       PaError (*IsStopped)( PaStream* ),
-                                       PaError (*IsActive)( PaStream* ),
-                                       PaTime (*GetTime)( PaStream* ),
-                                       double (*GetCpuLoad)( PaStream* ),
-                                       PaError (*Read)( PaStream*, void *, unsigned long ),
-                                       PaError (*Write)( PaStream*, const void *, unsigned long ),
-                                       signed long (*GetReadAvailable)( PaStream* ),
-                                       signed long (*GetWriteAvailable)( PaStream* )  )
-{
-    streamInterface->Close = Close;
-    streamInterface->Start = Start;
-    streamInterface->Stop = Stop;
-    streamInterface->Abort = Abort;
-    streamInterface->IsStopped = IsStopped;
-    streamInterface->IsActive = IsActive;
-    streamInterface->GetTime = GetTime;
-    streamInterface->GetCpuLoad = GetCpuLoad;
-    streamInterface->Read = Read;
-    streamInterface->Write = Write;
-    streamInterface->GetReadAvailable = GetReadAvailable;
-    streamInterface->GetWriteAvailable = GetWriteAvailable;
-}
-
-
-void PaUtil_InitializeStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation,
-        PaUtilStreamInterface *streamInterface,
-        PaStreamCallback *streamCallback,
-        void *userData )
-{
-    streamRepresentation->magic = PA_STREAM_MAGIC;
-    streamRepresentation->nextOpenStream = 0;
-    streamRepresentation->streamInterface = streamInterface;
-    streamRepresentation->streamCallback = streamCallback;
-    streamRepresentation->streamFinishedCallback = 0;
-
-    streamRepresentation->userData = userData;
-
-    streamRepresentation->streamInfo.inputLatency = 0.;
-    streamRepresentation->streamInfo.outputLatency = 0.;
-    streamRepresentation->streamInfo.sampleRate = 0.;
-}
-
-
-void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation )
-{
-    streamRepresentation->magic = 0;
-}
-
-
-PaError PaUtil_DummyRead( PaStream* stream,
-                               void *buffer,
-                               unsigned long frames )
-{
-    (void)stream; /* unused parameter */
-    (void)buffer; /* unused parameter */
-    (void)frames; /* unused parameter */
-
-    return paCanNotReadFromACallbackStream;
-}
-
-
-PaError PaUtil_DummyWrite( PaStream* stream,
-                               const void *buffer,
-                               unsigned long frames )
-{
-    (void)stream; /* unused parameter */
-    (void)buffer; /* unused parameter */
-    (void)frames; /* unused parameter */
-
-    return paCanNotWriteToACallbackStream;
-}
-
-
-signed long PaUtil_DummyGetReadAvailable( PaStream* stream )
-{
-    (void)stream; /* unused parameter */
-
-    return paCanNotReadFromACallbackStream;
-}
-
-
-signed long PaUtil_DummyGetWriteAvailable( PaStream* stream )
-{
-    (void)stream; /* unused parameter */
-
-    return paCanNotWriteToACallbackStream;
-}
-
-
-double PaUtil_DummyGetCpuLoad( PaStream* stream )
-{
-    (void)stream; /* unused parameter */
-
-    return 0.0;
-}
diff --git a/portaudio/pa_common/pa_stream.h b/portaudio/pa_common/pa_stream.h
deleted file mode 100644
index 8b86943bf..000000000
--- a/portaudio/pa_common/pa_stream.h
+++ /dev/null
@@ -1,196 +0,0 @@
-#ifndef PA_STREAM_H
-#define PA_STREAM_H
-/*
- * $Id: pa_stream.h,v 1.1.2.13 2003/11/01 06:37:28 rossbencina Exp $
- * Portable Audio I/O Library
- * stream interface
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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.
- */
-
-/** @file
- @brief Interface used by pa_front to virtualize functions which operate on
- streams.
-*/
-
-
-#include "portaudio.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-#define PA_STREAM_MAGIC (0x18273645)
-
-
-/** A structure representing an (abstract) interface to a host API. Contains
- pointers to functions which implement the interface.
-
- All PaStreamInterface functions are guaranteed to be called with a non-null,
- valid stream parameter.
-*/
-typedef struct {
-    PaError (*Close)( PaStream* stream );
-    PaError (*Start)( PaStream *stream );
-    PaError (*Stop)( PaStream *stream );
-    PaError (*Abort)( PaStream *stream );
-    PaError (*IsStopped)( PaStream *stream );
-    PaError (*IsActive)( PaStream *stream );
-    PaTime (*GetTime)( PaStream *stream );
-    double (*GetCpuLoad)( PaStream* stream );
-    PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames );
-    PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames );
-    signed long (*GetReadAvailable)( PaStream* stream );
-    signed long (*GetWriteAvailable)( PaStream* stream );
-} PaUtilStreamInterface;
-
-
-/** Initialize the fields of a PaUtilStreamInterface structure.
-*/
-void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface,
-    PaError (*Close)( PaStream* ),
-    PaError (*Start)( PaStream* ),
-    PaError (*Stop)( PaStream* ),
-    PaError (*Abort)( PaStream* ),
-    PaError (*IsStopped)( PaStream* ),
-    PaError (*IsActive)( PaStream* ),
-    PaTime (*GetTime)( PaStream* ),
-    double (*GetCpuLoad)( PaStream* ),
-    PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames ),
-    PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames ),
-    signed long (*GetReadAvailable)( PaStream* stream ),
-    signed long (*GetWriteAvailable)( PaStream* stream ) );
-
-
-/** Dummy Read function for use in interfaces to a callback based streams.
- Pass to the Read parameter of PaUtil_InitializeStreamInterface.
- @return An error code indicating that the function has no effect
- because the stream is a callback stream.
-*/
-PaError PaUtil_DummyRead( PaStream* stream,
-                       void *buffer,
-                       unsigned long frames );
-
-
-/** Dummy Write function for use in an interfaces to callback based streams.
- Pass to the Write parameter of PaUtil_InitializeStreamInterface.
- @return An error code indicating that the function has no effect
- because the stream is a callback stream.
-*/
-PaError PaUtil_DummyWrite( PaStream* stream,
-                       const void *buffer,
-                       unsigned long frames );
-
-
-/** Dummy GetReadAvailable function for use in interfaces to callback based
- streams. Pass to the GetReadAvailable parameter of PaUtil_InitializeStreamInterface.
- @return An error code indicating that the function has no effect
- because the stream is a callback stream.
-*/
-signed long PaUtil_DummyGetReadAvailable( PaStream* stream );
-
-
-/** Dummy GetWriteAvailable function for use in interfaces to callback based
- streams. Pass to the GetWriteAvailable parameter of PaUtil_InitializeStreamInterface.
- @return An error code indicating that the function has no effect
- because the stream is a callback stream.
-*/
-signed long PaUtil_DummyGetWriteAvailable( PaStream* stream );
-
-
-
-/** Dummy GetCpuLoad function for use in an interface to a read/write stream.
- Pass to the GetCpuLoad parameter of PaUtil_InitializeStreamInterface.
- @return Returns 0.
-*/
-double PaUtil_DummyGetCpuLoad( PaStream* stream );
-
-
-/** Non host specific data for a stream. This data is used by pa_front to
- forward to the appropriate functions in the streamInterface structure.
-*/
-typedef struct PaUtilStreamRepresentation {
-    unsigned long magic;    /**< set to PA_STREAM_MAGIC */
-    struct PaUtilStreamRepresentation *nextOpenStream; /**< field used by multi-api code */
-    PaUtilStreamInterface *streamInterface;
-    PaStreamCallback *streamCallback;
-    PaStreamFinishedCallback *streamFinishedCallback;
-    void *userData;
-    PaStreamInfo streamInfo;
-} PaUtilStreamRepresentation;
-
-
-/** Initialize a PaUtilStreamRepresentation structure.
-
- @see PaUtil_InitializeStreamRepresentation
-*/
-void PaUtil_InitializeStreamRepresentation(
-        PaUtilStreamRepresentation *streamRepresentation,
-        PaUtilStreamInterface *streamInterface,
-        PaStreamCallback *streamCallback,
-        void *userData );
-        
-
-/** Clean up a PaUtilStreamRepresentation structure previously initialized
- by a call to PaUtil_InitializeStreamRepresentation.
-
- @see PaUtil_InitializeStreamRepresentation
-*/
-void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation );
-
-
-/** Check that the stream pointer is valid.
-
- @return Returns paNoError if the stream pointer appears to be OK, otherwise
- returns an error indicating the cause of failure.
-*/
-PaError PaUtil_ValidateStreamPointer( PaStream *stream );
-
-
-/** Cast an opaque stream pointer into a pointer to a PaUtilStreamRepresentation.
-
- @see PaUtilStreamRepresentation
-*/
-#define PA_STREAM_REP( stream )\
-    ((PaUtilStreamRepresentation*) (stream) )
-
-
-/** Cast an opaque stream pointer into a pointer to a PaUtilStreamInterface.
-
- @see PaUtilStreamRepresentation, PaUtilStreamInterface
-*/
-#define PA_STREAM_INTERFACE( stream )\
-    PA_STREAM_REP( (stream) )->streamInterface
-
-
-    
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PA_STREAM_H */
diff --git a/portaudio/pa_common/pa_trace.c b/portaudio/pa_common/pa_trace.c
deleted file mode 100644
index e36329fdf..000000000
--- a/portaudio/pa_common/pa_trace.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * $Id: pa_trace.c,v 1.1.1.1.2.4 2005/11/02 12:06:44 rossbencina Exp $
- * Portable Audio I/O Library Trace Facility
- * Store trace information in real-time for later printing.
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/** @file
- @brief Event trace mechanism for debugging.
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "pa_trace.h"
-
-#if PA_TRACE_REALTIME_EVENTS
-
-static char *traceTextArray[PA_MAX_TRACE_RECORDS];
-static int traceIntArray[PA_MAX_TRACE_RECORDS];
-static int traceIndex = 0;
-static int traceBlock = 0;
-
-/*********************************************************************/
-void PaUtil_ResetTraceMessages()
-{
-    traceIndex = 0;
-}
-
-/*********************************************************************/
-void PaUtil_DumpTraceMessages()
-{
-    int i;
-    int messageCount = (traceIndex < PA_MAX_TRACE_RECORDS) ? traceIndex : PA_MAX_TRACE_RECORDS;
-
-    printf("DumpTraceMessages: traceIndex = %d\n", traceIndex );
-    for( i=0; i<messageCount; i++ )
-    {
-        printf("%3d: %s = 0x%08X\n",
-               i, traceTextArray[i], traceIntArray[i] );
-    }
-    PaUtil_ResetTraceMessages();
-    fflush(stdout);
-}
-
-/*********************************************************************/
-void PaUtil_AddTraceMessage( const char *msg, int data )
-{
-    if( (traceIndex == PA_MAX_TRACE_RECORDS) && (traceBlock == 0) )
-    {
-        traceBlock = 1;
-        /*  PaUtil_DumpTraceMessages(); */
-    }
-    else if( traceIndex < PA_MAX_TRACE_RECORDS )
-    {
-        traceTextArray[traceIndex] = msg;
-        traceIntArray[traceIndex] = data;
-        traceIndex++;
-    }
-}
-
-#endif /* TRACE_REALTIME_EVENTS */
diff --git a/portaudio/pa_common/pa_trace.h b/portaudio/pa_common/pa_trace.h
deleted file mode 100644
index f72a78b34..000000000
--- a/portaudio/pa_common/pa_trace.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef PA_TRACE_H
-#define PA_TRACE_H
-/*
- * $Id: pa_trace.h,v 1.1.1.1.2.3 2003/09/20 21:09:15 rossbencina Exp $
- * Portable Audio I/O Library Trace Facility
- * Store trace information in real-time for later printing.
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/** @file
- @brief Event trace mechanism for debugging.
-
- Allows data to be written to the buffer at interrupt time and dumped later.
-*/
-
-
-#define PA_TRACE_REALTIME_EVENTS     (0)   /* Keep log of various real-time events. */
-#define PA_MAX_TRACE_RECORDS      (2048)
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-#if PA_TRACE_REALTIME_EVENTS
-
-void PaUtil_ResetTraceMessages();
-void PaUtil_AddTraceMessage( const char *msg, int data );
-void PaUtil_DumpTraceMessages();
-    
-#else
-
-#define PaUtil_ResetTraceMessages() /* noop */
-#define PaUtil_AddTraceMessage(msg,data) /* noop */
-#define PaUtil_DumpTraceMessages() /* noop */
-
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* PA_TRACE_H */
diff --git a/portaudio/pa_common/pa_types.h b/portaudio/pa_common/pa_types.h
deleted file mode 100644
index 343dc8cf8..000000000
--- a/portaudio/pa_common/pa_types.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef PA_TYPES_H
-#define PA_TYPES_H
-
-/*
-    SIZEOF_SHORT, SIZEOF_INT and SIZEOF_LONG are set by the configure script
-    when it is used. Otherwise we default to the common 32 bit values, if your
-    platform doesn't use configure, and doesn't use the default values below
-    you will need to explicitly define these symbols in your make file.
-
-    A PA_VALIDATE_SIZES macro is provided to assert that the values set in this
-    file are correct.
-*/
-
-#ifndef SIZEOF_SHORT
-#define SIZEOF_SHORT 2
-#endif
-
-#ifndef SIZEOF_INT
-#define SIZEOF_INT 4
-#endif
-
-#ifndef SIZEOF_LONG
-#define SIZEOF_LONG 4
-#endif
-
-
-#if SIZEOF_SHORT == 2
-typedef signed short PaInt16;
-typedef unsigned short PaUint16;
-#elif SIZEOF_INT == 2
-typedef signed int PaInt16;
-typedef unsigned int PaUint16;
-#else
-#error pa_types.h was unable to determine which type to use for 16bit integers on the target platform
-#endif
-
-#if SIZEOF_SHORT == 4
-typedef signed short PaInt32;
-typedef unsigned short PaUint32;
-#elif SIZEOF_INT == 4
-typedef signed int PaInt32;
-typedef unsigned int PaUint32;
-#elif SIZEOF_LONG == 4
-typedef signed long PaInt32;
-typedef unsigned long PaUint32;
-#else
-#error pa_types.h was unable to determine which type to use for 32bit integers on the target platform
-#endif
-
-
-/* PA_VALIDATE_TYPE_SIZES compares the size of the integer types at runtime to
- ensure that PortAudio was configured correctly, and raises an assertion if
- they don't match the expected values. <assert.h> must be included in the
- context in which this macro is used.
-*/
-#define PA_VALIDATE_TYPE_SIZES \
-    { \
-        assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaUint16 ) == 2 ); \
-        assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaInt16 ) == 2 ); \
-        assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaUint32 ) == 4 ); \
-        assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaInt32 ) == 4 ); \
-    }
-
-
-#endif /* PA_TYPES_H */
diff --git a/portaudio/pa_common/pa_util.h b/portaudio/pa_common/pa_util.h
deleted file mode 100644
index d20badd28..000000000
--- a/portaudio/pa_common/pa_util.h
+++ /dev/null
@@ -1,167 +0,0 @@
-#ifndef PA_UTIL_H
-#define PA_UTIL_H
-/*
- * $Id: pa_util.h,v 1.1.2.13 2005/11/09 06:31:42 aknudsen Exp $
- * Portable Audio I/O Library implementation utilities header
- * common implementation utilities and interfaces
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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.
- */
-
-/** @file
-    @brief Prototypes for utility functions used by PortAudio implementations.
-
-    @todo Document and adhere to the alignment guarantees provided by
-    PaUtil_AllocateMemory().
-*/
-
-
-#include "portaudio.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-struct PaUtilHostApiRepresentation;
-
-
-/** Retrieve a specific host API representation. This function can be used
- by implementations to retrieve a pointer to their representation in
- host api specific extension functions which aren't passed a rep pointer
- by pa_front.c.
-
- @param hostApi A pointer to a host API represenation pointer. Apon success
- this will receive the requested representation pointer.
-
- @param type A valid host API type identifier.
-
- @returns An error code. If the result is PaNoError then a pointer to the
- requested host API representation will be stored in *hostApi. If the host API
- specified by type is not found, this function returns paHostApiNotFound.
-*/
-PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi,
-        PaHostApiTypeId type );
-
-
-/** Convert a PortAudio device index into a host API specific device index.
- @param hostApiDevice Pointer to a device index, on success this will recieve the
- converted device index value.
- @param device The PortAudio device index to convert.
- @param hostApi The host api which the index should be converted for.
-
- @returns On success returns PaNoError and places the converted index in the
- hostApiDevice parameter.
-*/
-PaError PaUtil_DeviceIndexToHostApiDeviceIndex(
-        PaDeviceIndex *hostApiDevice, PaDeviceIndex device,
-        struct PaUtilHostApiRepresentation *hostApi );
-
-
-/** Set the host error information returned by Pa_GetLastHostErrorInfo. This
- function and the paUnanticipatedHostError error code should be used as a
- last resort.  Implementors should use existing PA error codes where possible,
- or nominate new ones. Note that at it is always better to use
- PaUtil_SetLastHostErrorInfo() and paUnanticipatedHostError than to return an
- ambiguous or inaccurate PaError code.
-
- @param hostApiType  The host API which encountered the error (ie of the caller)
-
- @param errorCode The error code returned by the native API function.
-
- @param errorText A string describing the error. PaUtil_SetLastHostErrorInfo
- makes a copy of the string, so it is not necessary for the pointer to remain
- valid after the call to PaUtil_SetLastHostErrorInfo() returns.
-
-*/
-void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode,
-        const char *errorText );
-
-
-        
-/** PA_DEBUG() provides a simple debug message printing facility. The macro
- passes it's argument to a printf-like function called PaUtil_DebugPrint()
- which prints to stderr and always flushes the stream after printing.
- Because preprocessor macros cannot directly accept variable length argument
- lists, calls to the macro must include an additional set of parenthesis, eg:
- PA_DEBUG(("errorno: %d", 1001 ));
-*/
-
-void PaUtil_DebugPrint( const char *format, ... );
-
-#ifdef PA_ENABLE_DEBUG_OUTPUT
-#define PA_DEBUG(x) PaUtil_DebugPrint x ;
-#else
-#define PA_DEBUG(x)
-#endif
-
-
-/* the following functions are implemented in a platform platform specific
- .c file
-*/
-
-/** Allocate size bytes, guaranteed to be aligned to a FIXME byte boundary */
-void *PaUtil_AllocateMemory( long size );
-
-
-/** Realease block if non-NULL. block may be NULL */
-void PaUtil_FreeMemory( void *block );
-
-
-/** Return the number of currently allocated blocks. This function can be
- used for detecting memory leaks.
-
- @note Allocations will only be tracked if PA_TRACK_MEMORY is #defined. If
- it isn't, this function will always return 0.
-*/
-int PaUtil_CountCurrentlyAllocatedBlocks( void );
-
-
-/** Initialize the clock used by PaUtil_GetTime(). Call this before calling
- PaUtil_GetTime.
-
- @see PaUtil_GetTime
-*/
-void PaUtil_InitializeClock( void );
-
-
-/** Return the system time in seconds. Used to implement CPU load functions
-
- @see PaUtil_InitializeClock
-*/
-double PaUtil_GetTime( void );
-
-
-/* void Pa_Sleep( long msec );  must also be implemented in per-platform .c file */
-
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PA_UTIL_H */
diff --git a/portaudio/pa_common/portaudio.h b/portaudio/pa_common/portaudio.h
deleted file mode 100644
index c5967b0bd..000000000
--- a/portaudio/pa_common/portaudio.h
+++ /dev/null
@@ -1,1124 +0,0 @@
-
-#ifndef PORTAUDIO_H
-#define PORTAUDIO_H
-/*
- * $Id: portaudio.h,v 1.5.2.53 2006/03/20 17:49:38 aknudsen Exp $
- * PortAudio Portable Real-Time Audio Library
- * PortAudio API Header File
- * Latest version available at: http://www.portaudio.com/
- *
- * Copyright (c) 1999-2002 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.
- */
-
-/** @file
- @brief The PortAudio API.
-*/
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
- 
-/** Retrieve the release number of the currently running PortAudio build,
- eg 1900.
-*/
-int Pa_GetVersion( void );
-
-
-/** Retrieve a textual description of the current PortAudio build,
- eg "PortAudio V19-devel 13 October 2002".
-*/
-const char* Pa_GetVersionText( void );
-
-
-/** Error codes returned by PortAudio functions.
- Note that with the exception of paNoError, all PaErrorCodes are negative.
-*/
-
-typedef int PaError;
-typedef enum PaErrorCode
-{
-    paNoError = 0,
-
-    paNotInitialized = -10000,
-    paUnanticipatedHostError,
-    paInvalidChannelCount,
-    paInvalidSampleRate,
-    paInvalidDevice,
-    paInvalidFlag,
-    paSampleFormatNotSupported,
-    paBadIODeviceCombination,
-    paInsufficientMemory,
-    paBufferTooBig,
-    paBufferTooSmall,
-    paNullCallback,
-    paBadStreamPtr,
-    paTimedOut,
-    paInternalError,
-    paDeviceUnavailable,
-    paIncompatibleHostApiSpecificStreamInfo,
-    paStreamIsStopped,
-    paStreamIsNotStopped,
-    paInputOverflowed,
-    paOutputUnderflowed,
-    paHostApiNotFound,
-    paInvalidHostApi,
-    paCanNotReadFromACallbackStream,      /**< @todo review error code name */
-    paCanNotWriteToACallbackStream,       /**< @todo review error code name */
-    paCanNotReadFromAnOutputOnlyStream,   /**< @todo review error code name */
-    paCanNotWriteToAnInputOnlyStream,     /**< @todo review error code name */
-    paIncompatibleStreamHostApi,
-    paBadBufferPtr
-} PaErrorCode;
-
-
-/** Translate the supplied PortAudio error code into a human readable
- message.
-*/
-const char *Pa_GetErrorText( PaError errorCode );
-
-
-/** Library initialization function - call this before using PortAudio.
- This function initialises internal data structures and prepares underlying
- host APIs for use. This function MUST be called before using any other
- PortAudio API functions.
-
- If Pa_Initialize() is called multiple times, each successful 
- call must be matched with a corresponding call to Pa_Terminate(). 
- Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not 
- required to be fully nested.
-
- Note that if Pa_Initialize() returns an error code, Pa_Terminate() should
- NOT be called.
-
- @return paNoError if successful, otherwise an error code indicating the cause
- of failure.
-
- @see Pa_Terminate
-*/
-PaError Pa_Initialize( void );
-
-
-/** Library termination function - call this when finished using PortAudio.
- This function deallocates all resources allocated by PortAudio since it was
- initializied by a call to Pa_Initialize(). In cases where Pa_Initialise() has
- been called multiple times, each call must be matched with a corresponding call
- to Pa_Terminate(). The final matching call to Pa_Terminate() will automatically
- close any PortAudio streams that are still open.
-
- Pa_Terminate() MUST be called before exiting a program which uses PortAudio.
- Failure to do so may result in serious resource leaks, such as audio devices
- not being available until the next reboot.
-
- @return paNoError if successful, otherwise an error code indicating the cause
- of failure.
- 
- @see Pa_Initialize
-*/
-PaError Pa_Terminate( void );
-
-
-
-/** The type used to refer to audio devices. Values of this type usually
- range from 0 to (Pa_DeviceCount-1), and may also take on the PaNoDevice
- and paUseHostApiSpecificDeviceSpecification values.
-
- @see Pa_DeviceCount, paNoDevice, paUseHostApiSpecificDeviceSpecification
-*/
-typedef int PaDeviceIndex;
-
-
-/** A special PaDeviceIndex value indicating that no device is available,
- or should be used.
-
- @see PaDeviceIndex
-*/
-#define paNoDevice ((PaDeviceIndex)-1)
-
-
-/** A special PaDeviceIndex value indicating that the device(s) to be used
- are specified in the host api specific stream info structure.
-
- @see PaDeviceIndex
-*/
-#define paUseHostApiSpecificDeviceSpecification ((PaDeviceIndex)-2)
-
-
-/* Host API enumeration mechanism */
-
-/** The type used to enumerate to host APIs at runtime. Values of this type
- range from 0 to (Pa_GetHostApiCount()-1).
-
- @see Pa_GetHostApiCount
-*/
-typedef int PaHostApiIndex;
-
-
-/** Retrieve the number of available host APIs. Even if a host API is
- available it may have no devices available.
-
- @return A non-negative value indicating the number of available host APIs
- or, a PaErrorCode (which are always negative) if PortAudio is not initialized
- or an error is encountered.
-
- @see PaHostApiIndex
-*/
-PaHostApiIndex Pa_GetHostApiCount( void );
-
-
-/** Retrieve the index of the default host API. The default host API will be
- the lowest common denominator host API on the current platform and is
- unlikely to provide the best performance.
-
- @return A non-negative value ranging from 0 to (Pa_GetHostApiCount()-1)
- indicating the default host API index or, a PaErrorCode (which are always
- negative) if PortAudio is not initialized or an error is encountered.
-*/
-PaHostApiIndex Pa_GetDefaultHostApi( void );
-
-
-/** Unchanging unique identifiers for each supported host API. This type
- is used in the PaHostApiInfo structure. The values are guaranteed to be
- unique and to never change, thus allowing code to be written that
- conditionally uses host API specific extensions.
-
- New type ids will be allocated when support for a host API reaches
- "public alpha" status, prior to that developers should use the
- paInDevelopment type id.
-
- @see PaHostApiInfo
-*/
-typedef enum PaHostApiTypeId
-{
-    paInDevelopment=0, /* use while developing support for a new host API */
-    paDirectSound=1,
-    paMME=2,
-    paASIO=3,
-    paSoundManager=4,
-    paCoreAudio=5,
-    paOSS=7,
-    paALSA=8,
-    paAL=9,
-    paBeOS=10,
-    paWDMKS=11,
-    paJACK=12
-} PaHostApiTypeId;
-
-
-/** A structure containing information about a particular host API. */
-
-typedef struct PaHostApiInfo
-{
-    /** this is struct version 1 */
-    int structVersion;
-    /** The well known unique identifier of this host API @see PaHostApiTypeId */
-    PaHostApiTypeId type;
-    /** A textual description of the host API for display on user interfaces. */
-    const char *name;
-
-    /**  The number of devices belonging to this host API. This field may be
-     used in conjunction with Pa_HostApiDeviceIndexToDeviceIndex() to enumerate
-     all devices for this host API.
-     @see Pa_HostApiDeviceIndexToDeviceIndex
-    */
-    int deviceCount;
-
-    /** The default input device for this host API. The value will be a
-     device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice
-     if no default input device is available.
-    */
-    PaDeviceIndex defaultInputDevice;
-
-    /** The default output device for this host API. The value will be a
-     device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice
-     if no default output device is available.
-    */
-    PaDeviceIndex defaultOutputDevice;
-    
-} PaHostApiInfo;
-
-
-/** Retrieve a pointer to a structure containing information about a specific
- host Api.
-
- @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1)
-
- @return A pointer to an immutable PaHostApiInfo structure describing
- a specific host API. If the hostApi parameter is out of range or an error
- is encountered, 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().
-*/
-const PaHostApiInfo * Pa_GetHostApiInfo( PaHostApiIndex hostApi );
-
-
-/** Convert a static host API unique identifier, into a runtime
- host API index.
-
- @param type A unique host API identifier belonging to the PaHostApiTypeId
- enumeration.
-
- @return A valid PaHostApiIndex ranging from 0 to (Pa_GetHostApiCount()-1) or,
- a PaErrorCode (which are always negative) if PortAudio is not initialized
- or an error is encountered.
- 
- The paHostApiNotFound error code indicates that the host API specified by the
- type parameter is not available.
-
- @see PaHostApiTypeId
-*/
-PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type );
-
-
-/** Convert a host-API-specific device index to standard PortAudio device index.
- This function may be used in conjunction with the deviceCount field of
- PaHostApiInfo to enumerate all devices for the specified host API.
-
- @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1)
-
- @param hostApiDeviceIndex A valid per-host device index in the range
- 0 to (Pa_GetHostApiInfo(hostApi)->deviceCount-1)
-
- @return A non-negative PaDeviceIndex ranging from 0 to (Pa_GetDeviceCount()-1)
- or, a PaErrorCode (which are always negative) if PortAudio is not initialized
- or an error is encountered.
-
- A paInvalidHostApi error code indicates that the host API index specified by
- the hostApi parameter is out of range.
-
- A paInvalidDevice error code indicates that the hostApiDeviceIndex parameter
- is out of range.
- 
- @see PaHostApiInfo
-*/
-PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi,
-        int hostApiDeviceIndex );
-
-
-
-/** Structure used to return information about a host error condition.
-*/
-typedef struct PaHostErrorInfo{
-    PaHostApiTypeId hostApiType;    /**< the host API which returned the error code */
-    long errorCode;                 /**< the error code returned */
-    const char *errorText;          /**< a textual description of the error if available, otherwise a zero-length string */
-}PaHostErrorInfo;
-
-
-/** Return information about the last host error encountered. The error
- information returned by Pa_GetLastHostErrorInfo() will never be modified
- asyncronously by errors occurring in other PortAudio owned threads
- (such as the thread that manages the stream callback.)
-
- This function is provided as a last resort, primarily to enhance debugging
- by providing clients with access to all available error information.
-
- @return A pointer to an immutable structure constaining information about
- the host error. The values in this structure will only be valid if a
- PortAudio function has previously returned the paUnanticipatedHostError
- error code.
-*/
-const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void );
-
-
-
-/* Device enumeration and capabilities */
-
-/** Retrieve the number of available devices. The number of available devices
- may be zero.
-
- @return A non-negative value indicating the number of available devices or,
- a PaErrorCode (which are always negative) if PortAudio is not initialized
- or an error is encountered.
-*/
-PaDeviceIndex Pa_GetDeviceCount( void );
-
-
-/** Retrieve the index of the default input device. The result can be
- used in the inputDevice parameter to Pa_OpenStream().
-
- @return The default input device index for the default host API, or paNoDevice
- if no default input device is available or an error was encountered.
-*/
-PaDeviceIndex Pa_GetDefaultInputDevice( void );
-
-
-/** Retrieve the index of the default output device. The result can be
- used in the outputDevice parameter to Pa_OpenStream().
-
- @return The default output device index for the defualt host API, or paNoDevice
- if no default output device is available or an error was encountered.
-
- @note
- On the PC, the user can specify a default device by
- setting an environment variable. For example, to use device #1.
-<pre>
- set PA_RECOMMENDED_OUTPUT_DEVICE=1
-</pre>
- The user should first determine the available device ids by using
- the supplied application "pa_devs".
-*/
-PaDeviceIndex Pa_GetDefaultOutputDevice( void );
-
-
-/** The type used to represent monotonic time in seconds that can be used
- for syncronisation. The type is used for the outTime argument to the
- PaStreamCallback and as the result of Pa_GetStreamTime().
-     
- @see PaStreamCallback, Pa_GetStreamTime
-*/
-typedef double PaTime;
-
-
-/** A type used to specify one or more sample formats. Each value indicates
- a possible format for sound data passed to and from the stream callback,
- Pa_ReadStream and Pa_WriteStream.
-
- The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8
- and aUInt8 are usually implemented by all implementations.
-
- The floating point representation (paFloat32) uses +1.0 and -1.0 as the
- maximum and minimum respectively.
-
- paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
-
- The paNonInterleaved flag indicates that a multichannel buffer is passed
- as a set of non-interleaved pointers.
-
- @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo
- @see paFloat32, paInt16, paInt32, paInt24, paInt8
- @see paUInt8, paCustomFormat, paNonInterleaved
-*/
-typedef unsigned long PaSampleFormat;
-
-
-#define paFloat32        ((PaSampleFormat) 0x00000001) /**< @see PaSampleFormat */
-#define paInt32          ((PaSampleFormat) 0x00000002) /**< @see PaSampleFormat */
-#define paInt24          ((PaSampleFormat) 0x00000004) /**< Packed 24 bit format. @see PaSampleFormat */
-#define paInt16          ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */
-#define paInt8           ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */
-#define paUInt8          ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */
-#define paCustomFormat   ((PaSampleFormat) 0x00010000)/**< @see PaSampleFormat */
-
-#define paNonInterleaved ((PaSampleFormat) 0x80000000)
-
-/** A structure providing information and capabilities of PortAudio devices.
- Devices may support input, output or both input and output.
-*/
-typedef struct PaDeviceInfo
-{
-    int structVersion;  /* this is struct version 2 */
-    const char *name;
-    PaHostApiIndex hostApi; /* note this is a host API index, not a type id*/
-    
-    int maxInputChannels;
-    int maxOutputChannels;
-
-    /* Default latency values for interactive performance. */
-    PaTime defaultLowInputLatency;
-    PaTime defaultLowOutputLatency;
-    /* Default latency values for robust non-interactive applications (eg. playing sound files). */
-    PaTime defaultHighInputLatency;
-    PaTime defaultHighOutputLatency;
-
-    double defaultSampleRate;
-} PaDeviceInfo;
-
-
-/** Retrieve a pointer to a PaDeviceInfo structure containing information
- about the specified device.
- @return A pointer to an immutable PaDeviceInfo structure. If the device
- parameter is out of range the function returns NULL.
-
- @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
-
- @note 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().
-
- @see PaDeviceInfo, PaDeviceIndex
-*/
-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device );
-
-
-/** Parameters for one direction (input or output) of a stream.
-*/
-typedef struct PaStreamParameters
-{
-    /** A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
-     specifying the device to be used or the special constant
-     paUseHostApiSpecificDeviceSpecification which indicates that the actual
-     device(s) to use are specified in hostApiSpecificStreamInfo.
-     This field must not be set to paNoDevice.
-    */
-    PaDeviceIndex device;
-    
-    /** The number of channels of sound to be delivered to the
-     stream callback or accessed by Pa_ReadStream() or Pa_WriteStream().
-     It can range from 1 to the value of maxInputChannels in the
-     PaDeviceInfo record for the device specified by the device parameter.
-    */
-    int channelCount;
-
-    /** The sample format of the buffer provided to the stream callback,
-     a_ReadStream() or Pa_WriteStream(). It may be any of the formats described
-     by the PaSampleFormat enumeration.
-    */
-    PaSampleFormat sampleFormat;
-
-    /** The desired latency in seconds. Where practical, implementations should
-     configure their latency based on these parameters, otherwise they may
-     choose the closest viable latency instead. Unless the suggested latency
-     is greater than the absolute upper limit for the device implementations
-     should round the suggestedLatency up to the next practial value - ie to
-     provide an equal or higher latency than suggestedLatency wherever possibe.
-     Actual latency values for an open stream may be retrieved using the
-     inputLatency and outputLatency fields of the PaStreamInfo structure
-     returned by Pa_GetStreamInfo().
-     @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo
-    */
-    PaTime suggestedLatency;
-
-    /** An optional pointer to a host api specific data structure
-     containing additional information for device setup and/or stream processing.
-     hostApiSpecificStreamInfo is never required for correct operation,
-     if not used it should be set to NULL.
-    */
-    void *hostApiSpecificStreamInfo;
-
-} PaStreamParameters;
-
-
-/** Return code for Pa_IsFormatSupported indicating success. */
-#define paFormatIsSupported (0)
-
-/** Determine whether it would be possible to open a stream with the specified
- parameters.
-
- @param inputParameters A structure that describes the input parameters used to
- open a stream. The suggestedLatency field is ignored. See PaStreamParameters
- for a description of these parameters. inputParameters must be NULL for
- output-only streams.
-
- @param outputParameters A structure that describes the output parameters used
- to open a stream. The suggestedLatency field is ignored. See PaStreamParameters
- for a description of these parameters. outputParameters must be NULL for
- input-only streams.
-
- @param sampleRate The required sampleRate. For full-duplex streams it is the
- sample rate for both input and output
-
- @return Returns 0 if the format is supported, and an error code indicating why
- the format is not supported otherwise. The constant paFormatIsSupported is
- provided to compare with the return value for success.
-
- @see paFormatIsSupported, PaStreamParameters
-*/
-PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
-                              const PaStreamParameters *outputParameters,
-                              double sampleRate );
-
-
-
-/* Streaming types and functions */
-
-
-/**
- A single PaStream can provide multiple channels of real-time
- streaming audio input and output to a client application. A stream
- provides access to audio hardware represented by one or more
- PaDevices. Depending on the underlying Host API, it may be possible 
- to open multiple streams using the same device, however this behavior 
- is implementation defined. Portable applications should assume that 
- a PaDevice may be simultaneously used by at most one PaStream.
-
- Pointers to PaStream objects are passed between PortAudio functions that
- operate on streams.
-
- @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream,
- Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive,
- Pa_GetStreamTime, Pa_GetStreamCpuLoad
-
-*/
-typedef void PaStream;
-
-
-/** Can be passed as the framesPerBuffer parameter to Pa_OpenStream()
- or Pa_OpenDefaultStream() to indicate that the stream callback will
- accept buffers of any size.
-*/
-#define paFramesPerBufferUnspecified  (0)
-
-
-/** Flags used to control the behavior of a stream. They are passed as
- parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be
- ORed together.
-
- @see Pa_OpenStream, Pa_OpenDefaultStream
- @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput,
-  paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags
-*/
-typedef unsigned long PaStreamFlags;
-
-/** @see PaStreamFlags */
-#define   paNoFlag          ((PaStreamFlags) 0)
-
-/** Disable default clipping of out of range samples.
- @see PaStreamFlags
-*/
-#define   paClipOff         ((PaStreamFlags) 0x00000001)
-
-/** Disable default dithering.
- @see PaStreamFlags
-*/
-#define   paDitherOff       ((PaStreamFlags) 0x00000002)
-
-/** Flag requests that where possible a full duplex stream will not discard
- overflowed input samples without calling the stream callback. This flag is
- only valid for full duplex callback streams and only when used in combination
- with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using
- this flag incorrectly results in a paInvalidFlag error being returned from
- Pa_OpenStream and Pa_OpenDefaultStream.
-
- @see PaStreamFlags, paFramesPerBufferUnspecified
-*/
-#define   paNeverDropInput  ((PaStreamFlags) 0x00000004)
-
-/** Call the stream callback to fill initial output buffers, rather than the
- default behavior of priming the buffers with zeros (silence). This flag has
- no effect for input-only and blocking read/write streams.
- 
- @see PaStreamFlags
-*/
-#define   paPrimeOutputBuffersUsingStreamCallback ((PaStreamFlags) 0x00000008)
-
-/** A mask specifying the platform specific bits.
- @see PaStreamFlags
-*/
-#define   paPlatformSpecificFlags ((PaStreamFlags)0xFFFF0000)
-
-/**
- Timing information for the buffers passed to the stream callback.
-*/
-typedef struct PaStreamCallbackTimeInfo{
-    PaTime inputBufferAdcTime;
-    PaTime currentTime;
-    PaTime outputBufferDacTime;
-} PaStreamCallbackTimeInfo;
-
-
-/**
- Flag bit constants for the statusFlags to PaStreamCallback.
-
- @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow,
- paPrimingOutput
-*/
-typedef unsigned long PaStreamCallbackFlags;
-
-/** In a stream opened with paFramesPerBufferUnspecified, indicates that
- input data is all silence (zeros) because no real data is available. In a
- stream opened without paFramesPerBufferUnspecified, it indicates that one or
- more zero samples have been inserted into the input buffer to compensate
- for an input underflow.
- @see PaStreamCallbackFlags
-*/
-#define paInputUnderflow   ((PaStreamCallbackFlags) 0x00000001)
-
-/** In a stream opened with paFramesPerBufferUnspecified, indicates that data
- prior to the first sample of the input buffer was discarded due to an
- overflow, possibly because the stream callback is using too much CPU time.
- Otherwise indicates that data prior to one or more samples in the
- input buffer was discarded.
- @see PaStreamCallbackFlags
-*/
-#define paInputOverflow    ((PaStreamCallbackFlags) 0x00000002)
-
-/** Indicates that output data (or a gap) was inserted, possibly because the
- stream callback is using too much CPU time.
- @see PaStreamCallbackFlags
-*/
-#define paOutputUnderflow  ((PaStreamCallbackFlags) 0x00000004)
-
-/** Indicates that output data will be discarded because no room is available.
- @see PaStreamCallbackFlags
-*/
-#define paOutputOverflow   ((PaStreamCallbackFlags) 0x00000008)
-
-/** Some of all of the output data will be used to prime the stream, input
- data may be zero.
- @see PaStreamCallbackFlags
-*/
-#define paPrimingOutput    ((PaStreamCallbackFlags) 0x00000010)
-
-/**
- Allowable return values for the PaStreamCallback.
- @see PaStreamCallback
-*/
-typedef enum PaStreamCallbackResult
-{
-    paContinue=0,
-    paComplete=1,
-    paAbort=2
-} PaStreamCallbackResult;
-
-
-/**
- Functions of type PaStreamCallback are implemented by PortAudio clients.
- They consume, process or generate audio in response to requests from an
- active PortAudio stream.
-     
- @param input and @param output are arrays of interleaved samples,
- the format, packing and number of channels used by the buffers are
- determined by parameters to Pa_OpenStream().
-     
- @param frameCount The number of sample frames to be processed by
- the stream callback.
-
- @param timeInfo The time in seconds when the first sample of the input
- buffer was received at the audio input, the time in seconds when the first
- sample of the output buffer will begin being played at the audio output, and
- the time in seconds when the stream callback was called.
- See also Pa_GetStreamTime()
-
- @param statusFlags Flags indicating whether input and/or output buffers
- have been inserted or will be dropped to overcome underflow or overflow
- conditions.
-
- @param userData The value of a user supplied pointer passed to
- Pa_OpenStream() intended for storing synthesis data etc.
-
- @return
- The stream callback should return one of the values in the
- PaStreamCallbackResult enumeration. To ensure that the callback continues
- to be called, it should return paContinue (0). Either paComplete or paAbort
- can be returned to finish stream processing, after either of these values is
- returned the callback will not be called again. If paAbort is returned the
- stream will finish as soon as possible. If paComplete is returned, the stream
- will continue until all buffers generated by the callback have been played.
- 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 Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also
- be used to stop the stream. The callback must always fill the entire output
- buffer irrespective of its return value.
-
- @see Pa_OpenStream, Pa_OpenDefaultStream
-
- @note With the exception of Pa_GetStreamCpuLoad() it is not permissable to call
- PortAudio API functions from within the stream callback.
-*/
-typedef int PaStreamCallback(
-    const void *input, void *output,
-    unsigned long frameCount,
-    const PaStreamCallbackTimeInfo* timeInfo,
-    PaStreamCallbackFlags statusFlags,
-    void *userData );
-
-
-/** Opens a stream for either input, output or both.
-     
- @param stream The address of a PaStream pointer which will receive
- a pointer to the newly opened stream.
-     
- @param inputParameters A structure that describes the input parameters used by
- the opened stream. See PaStreamParameters for a description of these parameters.
- inputParameters must be NULL for output-only streams.
-
- @param outputParameters A structure that describes the output parameters used by
- the opened stream. See PaStreamParameters for a description of these parameters.
- outputParameters must be NULL for input-only streams.
- 
- @param sampleRate The desired sampleRate. For full-duplex streams it is the
- sample rate for both input and output
-     
- @param framesPerBuffer The number of frames passed to the stream callback
- function, or the preferred block granularity for a blocking read/write stream.
- The special value paFramesPerBufferUnspecified (0) may be used to request that
- the stream callback will recieve an optimal (and possibly varying) number of
- frames based on host requirements and the requested latency settings.
- Note: With some host APIs, the use of non-zero framesPerBuffer for a callback
- stream may introduce an additional layer of buffering which could introduce
- additional latency. PortAudio guarantees that the additional latency
- will be kept to the theoretical minimum however, it is strongly recommended
- that a non-zero framesPerBuffer value only be used when your algorithm
- requires a fixed number of frames per stream callback.
- 
- @param streamFlags Flags which modify the behaviour of the streaming process.
- This parameter may contain a combination of flags ORed together. Some flags may
- only be relevant to certain buffer formats.
-     
- @param streamCallback A pointer to a client supplied function that is responsible
- for processing and filling input and output buffers. If this parameter is NULL
- the stream will be opened in 'blocking read/write' mode. In blocking mode,
- the client can receive sample data using Pa_ReadStream and write sample data
- using Pa_WriteStream, the number of samples that may be read or written
- without blocking is returned by Pa_GetStreamReadAvailable and
- Pa_GetStreamWriteAvailable respectively.
-
- @param userData A client supplied pointer which is passed to the stream callback
- function. It could for example, contain a pointer to instance data necessary
- for processing the audio buffers. This parameter is ignored if streamCallback
- is NULL.
-     
- @return
- Upon success Pa_OpenStream() returns paNoError and places a pointer to a
- valid PaStream 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 for possible error codes) and the value of stream is invalid.
-
- @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream,
- Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable
-*/
-PaError Pa_OpenStream( PaStream** stream,
-                       const PaStreamParameters *inputParameters,
-                       const PaStreamParameters *outputParameters,
-                       double sampleRate,
-                       unsigned long framesPerBuffer,
-                       PaStreamFlags streamFlags,
-                       PaStreamCallback *streamCallback,
-                       void *userData );
-
-
-/** A simplified version of Pa_OpenStream() that opens the default input
- and/or output devices.
-
- @param stream The address of a PaStream pointer which will receive
- a pointer to the newly opened stream.
- 
- @param numInputChannels  The number of channels of sound that will be supplied
- to the stream callback or returned by Pa_ReadStream. It can range from 1 to
- the value of maxInputChannels in the PaDeviceInfo record for the default input
- device. If 0 the stream is opened as an output-only stream.
-
- @param numOutputChannels The number of channels of sound to be delivered to the
- stream callback or passed to Pa_WriteStream. It can range from 1 to the value
- of maxOutputChannels in the PaDeviceInfo record for the default output dvice.
- If 0 the stream is opened as an output-only stream.
-
- @param sampleFormat The sample format of both the input and output buffers
- provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream.
- sampleFormat may be any of the formats described by the PaSampleFormat
- enumeration.
- 
- @param sampleRate Same as Pa_OpenStream parameter of the same name.
- @param framesPerBuffer Same as Pa_OpenStream parameter of the same name.
- @param streamCallback Same as Pa_OpenStream parameter of the same name.
- @param userData Same as Pa_OpenStream parameter of the same name.
-
- @return As for Pa_OpenStream
-
- @see Pa_OpenStream, PaStreamCallback
-*/
-PaError Pa_OpenDefaultStream( PaStream** stream,
-                              int numInputChannels,
-                              int numOutputChannels,
-                              PaSampleFormat sampleFormat,
-                              double sampleRate,
-                              unsigned long framesPerBuffer,
-                              PaStreamCallback *streamCallback,
-                              void *userData );
-
-
-/** Closes an audio stream. If the audio stream is active it
- discards any pending buffers as if Pa_AbortStream() had been called.
-*/
-PaError Pa_CloseStream( PaStream *stream );
-
-
-/** Functions of type PaStreamFinishedCallback are implemented by PortAudio 
- clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback
- function. Once registered they are called when the stream becomes inactive
- (ie once a call to Pa_StopStream() will not block).
- A stream will become inactive after the stream callback returns non-zero,
- or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio
- output, if the stream callback returns paComplete, or Pa_StopStream is called,
- the stream finished callback will not be called until all generated sample data
- has been played.
- 
- @param userData The userData parameter supplied to Pa_OpenStream()
-
- @see Pa_SetStreamFinishedCallback
-*/
-typedef void PaStreamFinishedCallback( void *userData );
-
-
-/** Register a stream finished callback function which will be called when the 
- stream becomes inactive. See the description of PaStreamFinishedCallback for 
- further details about when the callback will be called.
-
- @param stream a pointer to a PaStream that is in the stopped state - if the
- stream is not stopped, the stream's finished callback will remain unchanged 
- and an error code will be returned.
-
- @param streamFinishedCallback a pointer to a function with the same signature
- as PaStreamFinishedCallback, that will be called when the stream becomes
- inactive. Passing NULL for this parameter will un-register a previously
- registered stream finished callback function.
-
- @return on success returns paNoError, otherwise an error code indicating the cause
- of the error.
-
- @see PaStreamFinishedCallback
-*/
-PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ); 
-
-
-/** Commences audio processing.
-*/
-PaError Pa_StartStream( PaStream *stream );
-
-
-/** Terminates audio processing. It waits until all pending
- audio buffers have been played before it returns.
-*/
-PaError Pa_StopStream( PaStream *stream );
-
-
-/** Terminates audio processing immediately without waiting for pending
- buffers to complete.
-*/
-PaError Pa_AbortStream( PaStream *stream );
-
-
-/** Determine whether the stream is stopped.
- A stream is considered to be stopped prior to a successful call to
- Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream.
- If a stream callback returns a value other than paContinue the stream is NOT
- considered to be stopped.
-
- @return Returns one (1) when the stream is stopped, zero (0) when
- the stream is running or, a PaErrorCode (which are always negative) if
- PortAudio is not initialized or an error is encountered.
-
- @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive
-*/
-PaError Pa_IsStreamStopped( PaStream *stream );
-
-
-/** Determine whether the stream is active.
- A stream is active after a successful call to Pa_StartStream(), until it
- becomes inactive either as a result of a call to Pa_StopStream() or
- Pa_AbortStream(), or as a result of a return value other than paContinue from
- the stream callback. In the latter case, the stream is considered inactive
- after the last buffer has finished playing.
-
- @return Returns one (1) when the stream is active (ie playing or recording
- audio), zero (0) when not playing or, a PaErrorCode (which are always negative)
- if PortAudio is not initialized or an error is encountered.
-
- @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped
-*/
-PaError Pa_IsStreamActive( PaStream *stream );
-
-
-
-/** A structure containing unchanging information about an open stream.
- @see Pa_GetStreamInfo
-*/
-
-typedef struct PaStreamInfo
-{
-    /** this is struct version 1 */
-    int structVersion;
-
-    /** The input latency of the stream in seconds. This value provides the most
-     accurate estimate of input latency available to the implementation. It may
-     differ significantly from the suggestedLatency value passed to Pa_OpenStream().
-     The value of this field will be zero (0.) for output-only streams.
-     @see PaTime
-    */
-    PaTime inputLatency;
-
-    /** The output latency of the stream in seconds. This value provides the most
-     accurate estimate of output latency available to the implementation. It may
-     differ significantly from the suggestedLatency value passed to Pa_OpenStream().
-     The value of this field will be zero (0.) for input-only streams.
-     @see PaTime
-    */
-    PaTime outputLatency;
-
-    /** The sample rate of the stream in Hertz (samples per second). In cases
-     where the hardware sample rate is inaccurate and PortAudio is aware of it,
-     the value of this field may be different from the sampleRate parameter
-     passed to Pa_OpenStream(). If information about the actual hardware sample
-     rate is not available, this field will have the same value as the sampleRate
-     parameter passed to Pa_OpenStream().
-    */
-    double sampleRate;
-    
-} PaStreamInfo;
-
-
-/** Retrieve a pointer to a PaStreamInfo structure containing information
- about the specified stream.
- @return A pointer to an immutable PaStreamInfo structure. If the stream
- parameter invalid, or an error is encountered, the function returns NULL.
-
- @param stream A pointer to an open stream previously created with Pa_OpenStream.
-
- @note 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 until the specified stream is closed.
-
- @see PaStreamInfo
-*/
-const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream );
-
-
-/** Determine the current time for the stream according to the same clock used
- to generate buffer timestamps. This time may be used for syncronising other
- events to the audio stream, for example synchronizing audio to MIDI.
-                                        
- @return The stream's current time in seconds, or 0 if an error occurred.
-
- @see PaTime, PaStreamCallback
-*/
-PaTime Pa_GetStreamTime( PaStream *stream );
-
-
-/** Retrieve CPU usage information for the specified stream.
- The "CPU Load" is a fraction of total CPU time consumed by a callback stream's
- audio processing routines including, but not limited to the client supplied
- stream callback. This function does not work with blocking read/write streams.
-
- This function may be called from the stream callback function or the
- application.
-     
- @return
- A floating point value, typically between 0.0 and 1.0, where 1.0 indicates
- that the stream callback is consuming the maximum number of CPU cycles possible
- to maintain real-time operation. A value of 0.5 would imply that PortAudio and
- the stream callback was consuming roughly 50% of the available CPU time. The
- return value may exceed 1.0. A value of 0.0 will always be returned for a
- blocking read/write stream, or if an error occurrs.
-*/
-double Pa_GetStreamCpuLoad( PaStream* stream );
-
-
-/** Read samples from an input stream. The function doesn't return until
- the entire buffer has been filled - this may involve waiting for the operating
- system to supply the data.
-
- @param stream A pointer to an open stream previously created with Pa_OpenStream.
- 
- @param buffer A pointer to a buffer of sample frames. The buffer contains
- samples in the format specified by the inputParameters->sampleFormat field
- used to open the stream, and the number of channels specified by
- inputParameters->numChannels. If non-interleaved samples were requested,
- buffer is a pointer to the first element of an array of non-interleaved
- buffer pointers, one for each channel.
-
- @param frames The number of frames to be read into buffer. This parameter
- is not constrained to a specific range, however high performance applications
- will want to match this parameter to the framesPerBuffer parameter used
- when opening the stream.
-
- @return On success PaNoError will be returned, or PaInputOverflowed if input
- data was discarded by PortAudio after the previous call and before this call.
-*/
-PaError Pa_ReadStream( PaStream* stream,
-                       void *buffer,
-                       unsigned long frames );
-
-
-/** Write samples to an output stream. This function doesn't return until the
- entire buffer has been consumed - this may involve waiting for the operating
- system to consume the data.
-
- @param stream A pointer to an open stream previously created with Pa_OpenStream.
-
- @param buffer A pointer to a buffer of sample frames. The buffer contains
- samples in the format specified by the outputParameters->sampleFormat field
- used to open the stream, and the number of channels specified by
- outputParameters->numChannels. If non-interleaved samples were requested,
- buffer is a pointer to the first element of an array of non-interleaved
- buffer pointers, one for each channel.
-
- @param frames The number of frames to be written from buffer. This parameter
- is not constrained to a specific range, however high performance applications
- will want to match this parameter to the framesPerBuffer parameter used
- when opening the stream.
-
- @return On success PaNoError will be returned, or paOutputUnderflowed if
- additional output data was inserted after the previous call and before this
- call.
-*/
-PaError Pa_WriteStream( PaStream* stream,
-                        const void *buffer,
-                        unsigned long frames );
-
-
-/** Retrieve the number of frames that can be read from the stream without
- waiting.
-
- @return Returns a non-negative value representing the maximum number of frames
- that can be read from the stream without blocking or busy waiting or, a
- PaErrorCode (which are always negative) if PortAudio is not initialized or an
- error is encountered.
-*/
-signed long Pa_GetStreamReadAvailable( PaStream* stream );
-
-
-/** Retrieve the number of frames that can be written to the stream without
- waiting.
-
- @return Returns a non-negative value representing the maximum number of frames
- that can be written to the stream without blocking or busy waiting or, a
- PaErrorCode (which are always negative) if PortAudio is not initialized or an
- error is encountered.
-*/
-signed long Pa_GetStreamWriteAvailable( PaStream* stream );
-
-
-/* Miscellaneous utilities */
-
-
-/** Retrieve the size of a given sample format in bytes.
-
- @return The size in bytes of a single sample in the specified format,
- or paSampleFormatNotSupported if the format is not supported.
-*/
-PaError Pa_GetSampleSize( PaSampleFormat format );
-
-
-/** Put the caller to sleep for at least 'msec' milliseconds. This function is
- provided only as a convenience for authors of portable code (such as the tests
- and examples in the PortAudio distribution.)
-
- The function may sleep longer than requested so don't rely on this for accurate
- musical timing.
-*/
-void Pa_Sleep( long msec );
-
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PORTAUDIO_H */
diff --git a/portaudio/pa_dll_switch/CVS/Entries b/portaudio/pa_dll_switch/CVS/Entries
deleted file mode 100644
index e971ac482..000000000
--- a/portaudio/pa_dll_switch/CVS/Entries
+++ /dev/null
@@ -1,6 +0,0 @@
-/PaDllEntry.h/1.1.1.1/Tue Jan 22 00:52:13 2002//Tv19-devel
-/letter_from_tim_010817.txt/1.1.1.1/Tue Jan 22 00:52:12 2002//Tv19-devel
-/loadPA_DLL.cpp/1.1.1.1/Tue Jan 22 00:52:16 2002//Tv19-devel
-/pa_lib.c/1.1.1.1/Tue Jan 22 00:52:16 2002//Tv19-devel
-/portaudio.h/1.1.1.1/Tue Jan 22 00:52:14 2002//Tv19-devel
-D
diff --git a/portaudio/pa_dll_switch/CVS/Repository b/portaudio/pa_dll_switch/CVS/Repository
deleted file mode 100644
index c2647c860..000000000
--- a/portaudio/pa_dll_switch/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_dll_switch
diff --git a/portaudio/pa_dll_switch/CVS/Root b/portaudio/pa_dll_switch/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_dll_switch/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_dll_switch/CVS/Tag b/portaudio/pa_dll_switch/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_dll_switch/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_dll_switch/PaDllEntry.h b/portaudio/pa_dll_switch/PaDllEntry.h
deleted file mode 100644
index e070054b3..000000000
--- a/portaudio/pa_dll_switch/PaDllEntry.h
+++ /dev/null
@@ -1,184 +0,0 @@
-
-/*
- * PortAudio Portable Real-Time Audio Library
- * PortAudio DLL 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.
- *
- */
-
-// changed by zplane.developement in order to generate a DLL
-
-#ifndef __PADLLENTRY_HEADER_INCLUDED__
-
-#define __PADLLENTRY_HEADER_INCLUDED__
-
-typedef int PaError;
-typedef enum {
-    paNoError = 0,
-
-    paHostError = -10000,
-    paInvalidChannelCount,
-    paInvalidSampleRate,
-    paInvalidDeviceId,
-    paInvalidFlag,
-    paSampleFormatNotSupported,
-    paBadIODeviceCombination,
-    paInsufficientMemory,
-    paBufferTooBig,
-    paBufferTooSmall,
-    paNullCallback,
-    paBadStreamPtr,
-    paTimedOut,
-    paInternalError
-} PaErrorNum;
-
-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))
-
-
-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;
-
-
-typedef double PaTimestamp;
-
-
-typedef int (PortAudioCallback)(
-    void *inputBuffer, void *outputBuffer,
-    unsigned long framesPerBuffer,
-    PaTimestamp outTime, void *userData );
-
-
-#define   paNoFlag      (0)
-#define   paClipOff     (1<<0)   /* disable default clipping of out of range samples */
-#define   paDitherOff   (1<<1)   /* disable default dithering */
-#define   paPlatformSpecificFlags (0x00010000)
-typedef   unsigned long PaStreamFlags;
-
-typedef void PortAudioStream;
-#define PaStream PortAudioStream
-
-extern  PaError (__cdecl* Pa_Initialize)( void );
-
-
-
-extern  PaError (__cdecl* Pa_Terminate)( void );
-
-
-extern  long (__cdecl* Pa_GetHostError)( void );
-
-
-extern  const char* (__cdecl* Pa_GetErrorText)( PaError );
-
-
-
-extern  int (__cdecl* Pa_CountDevices)(void);
-
-extern  PaDeviceID (__cdecl* Pa_GetDefaultInputDeviceID)( void );
-
-extern  PaDeviceID (__cdecl* Pa_GetDefaultOutputDeviceID)( void );
-
-
-extern  const PaDeviceInfo* (__cdecl* Pa_GetDeviceInfo)( PaDeviceID);
-
-
-
-extern  PaError (__cdecl* Pa_OpenStream)(
-        PortAudioStream ** ,
-        PaDeviceID ,
-        int ,
-        PaSampleFormat ,
-        void *,
-        PaDeviceID ,
-        int ,
-        PaSampleFormat ,
-        void *,
-        double ,
-        unsigned long ,
-        unsigned long ,
-        unsigned long ,
-        PortAudioCallback *,
-        void * );
-
-
-
-extern  PaError (__cdecl* Pa_OpenDefaultStream)( PortAudioStream** stream,
-            int numInputChannels,
-            int numOutputChannels,
-            PaSampleFormat sampleFormat,
-            double sampleRate,
-            unsigned long framesPerBuffer,
-            unsigned long numberOfBuffers,
-            PortAudioCallback *callback,
-            void *userData );
-
-
-extern  PaError (__cdecl* Pa_CloseStream)( PortAudioStream* );
-
-
-extern  PaError (__cdecl* Pa_StartStream)( PortAudioStream *stream );
-
-extern  PaError (__cdecl* Pa_StopStream)( PortAudioStream *stream );
-
-extern  PaError (__cdecl* Pa_AbortStream)( PortAudioStream *stream );
-
-extern  PaError (__cdecl* Pa_StreamActive)( PortAudioStream *stream );
-
-extern  PaTimestamp (__cdecl* Pa_StreamTime)( PortAudioStream *stream );
-
-extern  double (__cdecl* Pa_GetCPULoad)( PortAudioStream* stream );
-
-extern  int (__cdecl* Pa_GetMinNumBuffers)( int framesPerBuffer, double sampleRate );
-
-extern  void (__cdecl* Pa_Sleep)( long msec );
-
-extern  PaError (__cdecl* Pa_GetSampleSize)( PaSampleFormat format );
-
-#endif // __PADLLENTRY_HEADER_INCLUDED__
-
diff --git a/portaudio/pa_dll_switch/letter_from_tim_010817.txt b/portaudio/pa_dll_switch/letter_from_tim_010817.txt
deleted file mode 100644
index a535cd1dae6afccc58d304b141166f7f7600dbd5..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1176
zcmZuxTT9$P6z=o<ii1#8>V{oit8R;E*@}X#()!Rhna!MR#+}TBxv1M;-|u9#rL+*p
zkaPPkXL1okH>0gP+tGy!ZREH`ADhkT>}T(^=gRP@x(mp<ZLOnEC9aUu<GjG}EQKbg
zwa;x;hwfB;FN+7R^Nhanj8a)HIb|C>ji@Uw+ukuPbiHD4lA7y`q>E^cUhmO)S(cP(
za<oVL<MD)!X47Lj|Dx2TC7HaZRLhacCVFahrYkbm%#@l`IM%K9OE#2Sre5DWyQpf?
z-cTQ6*2UORwPZboXgE?1)W`5>4U;D09O>SYBC-uVX`k6BwO>hkw??RUw$=lQD{8et
zNgaw12@N&H*F&fe7KJg9;l_F(*-6Z#__^lTXL3QC+w=SR^>tPE{Vs5V!IHB8wvisS
zD-2rf2L=KOG^I$e98{$7B_KCaV;!eWeMvl|--6@0a2&nDNdr(3<5tg|`|NXELjYxc
z?aI*eiugH4U4!h<<8OczN)~$HpF)W>;{}!5&_n;cok$fAAybCLdI2d?=(r6}u%aO!
zGBwPOng|J?wN9%_sk^~F4F|PDw?9yu5aA!!E9;kH!Q4h{&<{~SKWgh_fOxFCp|y$(
zH2|#0GBiMsL_Cx6_${1?QoKhC5V(?jTMrB&H@5KW9i?^3+@T^vjzpbJN#=@HuaHny
z(UJHsUkw!SrV>vE5gueq2fQ+UqXzN-=EKb{-E4|BUSTOkU5qh-li!Bjj5g~~2A)G>
zfzG%axC@39q!9Ub=9?HcB+(1s1y*m^kk{-DNedzRK42B3?aGHIOw@U|QkUY^a7$z|
zRF-|yehol=sT3%{L8Y?olp2lXO)ocJ{qqM<>i5s!kzMFJ_F1*TK}+jxLN7`=R&;PO
un(nK~{^b3H795@RxK>T@GkP~YsSd`~@!^!lCp0;%#uCxb|A`!`H@^T5#E2*W

diff --git a/portaudio/pa_dll_switch/loadPA_DLL.cpp b/portaudio/pa_dll_switch/loadPA_DLL.cpp
deleted file mode 100644
index 043eda878..000000000
--- a/portaudio/pa_dll_switch/loadPA_DLL.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-
-
-HINSTANCE   pPaDll;
-
-/*
- the function pointers to the PortAudio DLLs
-*/
-
-PaError (__cdecl* Pa_Initialize)( void );
-
-
-
-PaError (__cdecl* Pa_Terminate)( void );
-
-
-long (__cdecl* Pa_GetHostError)( void );
-
-
-const char* (__cdecl* Pa_GetErrorText)( PaError );
-
-
-int (__cdecl* Pa_CountDevices)(void);
-
-PaDeviceID (__cdecl* Pa_GetDefaultInputDeviceID)( void );
-
-PaDeviceID (__cdecl* Pa_GetDefaultOutputDeviceID)( void );
-
-
-const PaDeviceInfo* (__cdecl* Pa_GetDeviceInfo)( PaDeviceID);
-
-
-
-PaError (__cdecl* Pa_OpenStream)(
-    PortAudioStream ** ,
-    PaDeviceID ,
-    int ,
-    PaSampleFormat ,
-    void *,
-    PaDeviceID ,
-    int ,
-    PaSampleFormat ,
-    void *,
-    double ,
-    unsigned long ,
-    unsigned long ,
-    unsigned long ,
-    PortAudioCallback *,
-    void * );
-
-
-
-PaError (__cdecl* Pa_OpenDefaultStream)( PortAudioStream** stream,
-        int numInputChannels,
-        int numOutputChannels,
-        PaSampleFormat sampleFormat,
-        double sampleRate,
-        unsigned long framesPerBuffer,
-        unsigned long numberOfBuffers,
-        PortAudioCallback *callback,
-        void *userData );
-
-
-PaError (__cdecl* Pa_CloseStream)( PortAudioStream* );
-
-
-PaError (__cdecl* Pa_StartStream)( PortAudioStream *stream );
-
-PaError (__cdecl* Pa_StopStream)( PortAudioStream *stream );
-
-PaError (__cdecl* Pa_AbortStream)( PortAudioStream *stream );
-
-PaError (__cdecl* Pa_StreamActive)( PortAudioStream *stream );
-
-PaTimestamp (__cdecl* Pa_StreamTime)( PortAudioStream *stream );
-
-double (__cdecl* Pa_GetCPULoad)( PortAudioStream* stream );
-
-int (__cdecl* Pa_GetMinNumBuffers)( int framesPerBuffer, double sampleRate );
-
-void (__cdecl* Pa_Sleep)( long msec );
-
-PaError (__cdecl* Pa_GetSampleSize)( PaSampleFormat format );
-
-
-//////////////////////////////////////////////////////////////////////////
-
-...
-
-ZERROR AudioEngine::DirectXSupport(ZBOOL bSupDX)
-{
-    if (bSupDX)
-        if (CheckForDirectXSupport())
-            bSupportDirectX = _TRUE;
-        else
-            return _NO_SOUND;
-    else
-        bSupportDirectX  = _FALSE;
-    return _NO_ERROR;
-}
-
-
-
-ZBOOL AudioEngine::CheckForDirectXSupport()
-{
-    HMODULE pTestDXLib;
-    FARPROC pFunctionality;
-
-    pTestDXLib=LoadLibrary("DSOUND");
-    if (pTestDXLib!=NULL)  // check if there is a DirectSound
-    {
-        pFunctionality = GetProcAddress(pTestDXLib, (char*) 7);
-        if (pFunctionality!=NULL)
-        {
-            FreeLibrary(pTestDXLib);
-            return _TRUE;
-        }
-        else
-        {
-            FreeLibrary(pTestDXLib);
-            return _FALSE;
-        }
-    }
-    else
-        return _FALSE;
-}
-
-
-ZERROR AudioEngine::LoadPALib()
-{
-#ifdef _DEBUG
-    if (bSupportDirectX)
-        pPaDll  = LoadLibrary("PA_DXD");
-    else
-        pPaDll  = LoadLibrary("PA_MMED");
-#else
-    if (bSupportDirectX)
-        pPaDll  = LoadLibrary("PA_DX");
-    else
-        pPaDll  = LoadLibrary("PA_MME");
-#endif
-    if (pPaDll!=NULL)
-    {
-
-        Pa_Initialize    = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_Initialize");
-        Pa_Terminate    = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_Terminate");
-        Pa_GetHostError    = (long (__cdecl* )( void )) GetProcAddress(pPaDll,"Pa_GetHostError");
-        Pa_GetErrorText    = (const char* (__cdecl* )( PaError )) GetProcAddress(pPaDll,"Pa_GetErrorText");
-        Pa_CountDevices    = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_CountDevices");
-        Pa_GetDefaultInputDeviceID = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_GetDefaultInputDeviceID");
-        Pa_GetDefaultOutputDeviceID = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_GetDefaultOutputDeviceID");
-        Pa_GetDeviceInfo   = (const PaDeviceInfo* (__cdecl* )( PaDeviceID)) GetProcAddress(pPaDll,"Pa_GetDeviceInfo");
-        Pa_OpenStream    = ( PaError (__cdecl* )(
-                                 PortAudioStream ** ,
-                                 PaDeviceID ,
-                                 int ,
-                                 PaSampleFormat ,
-                                 void *,
-                                 PaDeviceID ,
-                                 int ,
-                                 PaSampleFormat ,
-                                 void *,
-                                 double ,
-                                 unsigned long ,
-                                 unsigned long ,
-                                 unsigned long ,
-                                 PortAudioCallback *,
-                                 void * )) GetProcAddress(pPaDll,"Pa_OpenStream");
-
-        Pa_OpenDefaultStream  = (PaError (__cdecl* )( PortAudioStream** ,
-                                 int ,
-                                 int ,
-                                 PaSampleFormat ,
-                                 double ,
-                                 unsigned long ,
-                                 unsigned long ,
-                                 PortAudioCallback *,
-                                 void * )) GetProcAddress(pPaDll,"Pa_OpenDefaultStream");
-        Pa_CloseStream    = (PaError (__cdecl* )( PortAudioStream* )) GetProcAddress(pPaDll,"Pa_CloseStream");
-        Pa_StartStream    = (PaError (__cdecl* )( PortAudioStream* )) GetProcAddress(pPaDll,"Pa_StartStream");
-        Pa_StopStream    = (PaError (__cdecl* )( PortAudioStream* ))GetProcAddress(pPaDll,"Pa_StopStream");
-        Pa_AbortStream    = (PaError (__cdecl* )( PortAudioStream* )) GetProcAddress(pPaDll,"Pa_AbortStream");
-        Pa_StreamActive    = (PaError (__cdecl* )( PortAudioStream* )) GetProcAddress(pPaDll,"Pa_StreamActive");
-        Pa_StreamTime    = (PaTimestamp (__cdecl* )( PortAudioStream *))GetProcAddress(pPaDll,"Pa_StreamTime");
-        Pa_GetCPULoad    = (double (__cdecl* )( PortAudioStream* ))GetProcAddress(pPaDll,"Pa_GetCPULoad");
-        Pa_GetMinNumBuffers   = (int (__cdecl* )( int , double )) GetProcAddress(pPaDll,"Pa_GetMinNumBuffers");
-        Pa_Sleep     = (void (__cdecl* )( long )) GetProcAddress(pPaDll,"Pa_Sleep");
-        Pa_GetSampleSize   = (PaError (__cdecl* )( PaSampleFormat )) GetProcAddress(pPaDll,"Pa_GetSampleSize");
-
-        return _NO_ERROR;
-    }
-    else
-        return _DLL_NOT_FOUND;
-}
-
-ZERROR AudioEngine::UnLoadPALib()
-{
-    if (pPaDll!=NULL)
-        FreeLibrary(pPaDll);
-    return _NO_ERROR;
-}
-
-...
diff --git a/portaudio/pa_dll_switch/pa_lib.c b/portaudio/pa_dll_switch/pa_lib.c
deleted file mode 100644
index 86601592c..000000000
--- a/portaudio/pa_dll_switch/pa_lib.c
+++ /dev/null
@@ -1,827 +0,0 @@
-/*
- * Portable Audio I/O Library
- * Host Independant Layer
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-/* Modification History:
- PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-/* PLB20010422 - "memory.h" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */
-#ifdef _WIN32
-#ifndef __MWERKS__
-#include <memory.h>
-#endif  /* __MWERKS__ */
-#else   /* !_WIN32 */
-#include <memory.h>
-#endif  /* _WIN32 */
-
-#include "portaudio.h"
-#include "pa_host.h"
-#include "pa_trace.h"
-
-/* The reason we might NOT want to validate the rate before opening the stream
- * is because many DirectSound drivers lie about the rates they actually support.
- */
-#define PA_VALIDATE_RATE    (0)   /* If true validate sample rate against driver info. */
-
-/*
-O- maybe not allocate past_InputBuffer and past_OutputBuffer if not needed for conversion
-*/
-
-#ifndef FALSE
- #define FALSE  (0)
- #define TRUE   (!FALSE)
-#endif
-
-#define PRINT(x) { printf x; fflush(stdout); }
-#define ERR_RPT(x) PRINT(x)
-#define DBUG(x)  /* PRINT(x) */
-#define DBUGX(x) /* PRINT(x) */
-
-static int gInitCount = 0; /* Count number of times Pa_Initialize() called to allow nesting and overlapping. */
-
-static PaError Pa_KillStream(  PortAudioStream *stream, int abort );
-
-/***********************************************************************/
-int PaHost_FindClosestTableEntry( double allowableError,  const double *rateTable, int numRates, double frameRate )
-{
-    double err, minErr = allowableError;
-    int i, bestFit = -1;
-
-    for( i=0; i<numRates; i++ )
-    {
-        err = fabs( frameRate - rateTable[i] );
-        if( err < minErr )
-        {
-            minErr = err;
-            bestFit = i;
-        }
-    }
-    return bestFit;
-}
-
-/**************************************************************************
-** Make sure sample rate is legal and also convert to enumeration for driver.
-*/
-PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate,
-                                   double *closestFrameRatePtr )
-{
-    long bestRateIndex;
-    const PaDeviceInfo *pdi;
-    pdi = Pa_GetDeviceInfo( id );
-    if( pdi == NULL ) return paInvalidDeviceId;
-
-    if( pdi->numSampleRates == -1 )
-    {
-        /* Is it out of range? */
-        if( (requestedFrameRate < pdi->sampleRates[0]) ||
-                (requestedFrameRate > pdi->sampleRates[1]) )
-        {
-            return paInvalidSampleRate;
-        }
-
-        *closestFrameRatePtr = requestedFrameRate;
-    }
-    else
-    {
-        bestRateIndex = PaHost_FindClosestTableEntry( 1.0, pdi->sampleRates, pdi->numSampleRates, requestedFrameRate );
-        if( bestRateIndex < 0 ) return paInvalidSampleRate;
-        *closestFrameRatePtr = pdi->sampleRates[bestRateIndex];
-    }
-    return paNoError;
-}
-
-/*************************************************************************/
-DLL_API PaError Pa_OpenStream(
-    PortAudioStream** streamPtrPtr,
-    PaDeviceID inputDeviceID,
-    int numInputChannels,
-    PaSampleFormat inputSampleFormat,
-    void *inputDriverInfo,
-    PaDeviceID outputDeviceID,
-    int numOutputChannels,
-    PaSampleFormat outputSampleFormat,
-    void *outputDriverInfo,
-    double sampleRate,
-    unsigned long framesPerBuffer,
-    unsigned long numberOfBuffers,
-    unsigned long streamFlags,
-    PortAudioCallback *callback,
-    void *userData )
-{
-    internalPortAudioStream   *past = NULL;
-    PaError                    result = paNoError;
-    int                        bitsPerInputSample;
-    int                        bitsPerOutputSample;
-    /* Print passed parameters. */
-    DBUG(("Pa_OpenStream( %p, %d, %d, %d, %p, /* input */ \n",
-          streamPtrPtr, inputDeviceID, numInputChannels,
-          inputSampleFormat, inputDriverInfo ));
-    DBUG(("               %d, %d, %d, %p, /* output */\n",
-          outputDeviceID, numOutputChannels,
-          outputSampleFormat, outputDriverInfo ));
-    DBUG(("               %g, %d, %d, 0x%x, , %p )\n",
-          sampleRate, framesPerBuffer, numberOfBuffers,
-          streamFlags, userData ));
-
-    /* Check for parameter errors. */
-    if( (streamFlags & ~(paClipOff | paDitherOff)) != 0 ) return paInvalidFlag;
-    if( streamPtrPtr == NULL ) return paBadStreamPtr;
-    if( inputDriverInfo != NULL ) return paHostError; /* REVIEW */
-    if( outputDriverInfo != NULL ) return paHostError; /* REVIEW */
-    if( (inputDeviceID < 0) && ( outputDeviceID < 0) ) return paInvalidDeviceId;
-    if( (outputDeviceID >= Pa_CountDevices()) || (inputDeviceID >= Pa_CountDevices()) ) return paInvalidDeviceId;
-    if( (numInputChannels <= 0) && ( numOutputChannels <= 0) ) return paInvalidChannelCount;
-
-#if SUPPORT_AUDIO_CAPTURE
-    if( inputDeviceID >= 0 )
-    {
-        PaError size = Pa_GetSampleSize( inputSampleFormat );
-        if( size < 0 ) return size;
-        bitsPerInputSample = 8 * size;
-        if( (numInputChannels <= 0) ) return paInvalidChannelCount;
-    }
-#else
-    if( inputDeviceID >= 0 )
-    {
-        return paInvalidChannelCount;
-    }
-#endif /* SUPPORT_AUDIO_CAPTURE */
-    else
-    {
-        if( numInputChannels > 0 ) return paInvalidChannelCount;
-        bitsPerInputSample = 0;
-    }
-
-    if( outputDeviceID >= 0 )
-    {
-        PaError size = Pa_GetSampleSize( outputSampleFormat );
-        if( size < 0 ) return size;
-        bitsPerOutputSample = 8 * size;
-        if( (numOutputChannels <= 0) ) return paInvalidChannelCount;
-    }
-    else
-    {
-        if( numOutputChannels > 0 ) return paInvalidChannelCount;
-        bitsPerOutputSample = 0;
-    }
-
-    if( callback == NULL ) return paNullCallback;
-
-    /* Allocate and clear stream structure. */
-    past = (internalPortAudioStream *) PaHost_AllocateFastMemory( sizeof(internalPortAudioStream) );
-    if( past == NULL ) return paInsufficientMemory;
-    memset( past, 0, sizeof(internalPortAudioStream) );
-    AddTraceMessage("Pa_OpenStream: past", (long) past );
-
-    past->past_Magic = PA_MAGIC;  /* Set ID to catch bugs. */
-    past->past_FramesPerUserBuffer = framesPerBuffer;
-    past->past_NumUserBuffers = numberOfBuffers; /* NOTE - PaHost_OpenStream() NMUST CHECK FOR ZERO! */
-    past->past_Callback = callback;
-    past->past_UserData = userData;
-    past->past_OutputSampleFormat = outputSampleFormat;
-    past->past_InputSampleFormat = inputSampleFormat;
-    past->past_OutputDeviceID = outputDeviceID;
-    past->past_InputDeviceID = inputDeviceID;
-    past->past_NumInputChannels = numInputChannels;
-    past->past_NumOutputChannels = numOutputChannels;
-    past->past_Flags = streamFlags;
-
-    /* Check for absurd sample rates. */
-    if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
-    {
-        result = paInvalidSampleRate;
-        goto cleanup;
-    }
-
-    /* Allocate buffers that may be used for format conversion from user to native buffers. */
-    if( numInputChannels > 0 )
-    {
-
-#if PA_VALIDATE_RATE
-        result = PaHost_ValidateSampleRate( inputDeviceID, sampleRate, &past->past_SampleRate );
-        if( result < 0 )
-        {
-            goto cleanup;
-        }
-#else
-        past->past_SampleRate = sampleRate;
-#endif
-        /* Allocate single Input buffer. */
-        past->past_InputBufferSize = framesPerBuffer * numInputChannels * ((bitsPerInputSample+7) / 8);
-        past->past_InputBuffer = PaHost_AllocateFastMemory(past->past_InputBufferSize);
-        if( past->past_InputBuffer == NULL )
-        {
-            result = paInsufficientMemory;
-            goto cleanup;
-        }
-    }
-    else
-    {
-        past->past_InputBuffer = NULL;
-    }
-
-    /* Allocate single Output buffer. */
-    if( numOutputChannels > 0 )
-    {
-#if PA_VALIDATE_RATE
-        result = PaHost_ValidateSampleRate( outputDeviceID, sampleRate, &past->past_SampleRate );
-        if( result < 0 )
-        {
-            goto cleanup;
-        }
-#else
-        past->past_SampleRate = sampleRate;
-#endif
-        past->past_OutputBufferSize = framesPerBuffer * numOutputChannels * ((bitsPerOutputSample+7) / 8);
-        past->past_OutputBuffer = PaHost_AllocateFastMemory(past->past_OutputBufferSize);
-        if( past->past_OutputBuffer == NULL )
-        {
-            result = paInsufficientMemory;
-            goto cleanup;
-        }
-    }
-    else
-    {
-        past->past_OutputBuffer = NULL;
-    }
-
-    result = PaHost_OpenStream( past );
-    if( result < 0 ) goto cleanup;
-
-    *streamPtrPtr = (void *) past;
-
-    return result;
-
-cleanup:
-    if( past != NULL ) Pa_CloseStream( past );
-    *streamPtrPtr = NULL;
-    return result;
-}
-
-
-/*************************************************************************/
-DLL_API PaError Pa_OpenDefaultStream( PortAudioStream** stream,
-                                      int numInputChannels,
-                                      int numOutputChannels,
-                                      PaSampleFormat sampleFormat,
-                                      double sampleRate,
-                                      unsigned long framesPerBuffer,
-                                      unsigned long numberOfBuffers,
-                                      PortAudioCallback *callback,
-                                      void *userData )
-{
-    return Pa_OpenStream(
-               stream,
-               ((numInputChannels > 0) ? Pa_GetDefaultInputDeviceID() : paNoDevice),
-               numInputChannels, sampleFormat, NULL,
-               ((numOutputChannels > 0) ? Pa_GetDefaultOutputDeviceID() : paNoDevice),
-               numOutputChannels, sampleFormat, NULL,
-               sampleRate, framesPerBuffer, numberOfBuffers, paNoFlag, callback, userData );
-}
-
-/*************************************************************************/
-DLL_API PaError Pa_CloseStream( PortAudioStream* stream)
-{
-    PaError   result;
-    internalPortAudioStream   *past;
-
-    DBUG(("Pa_CloseStream()\n"));
-    if( stream == NULL ) return paBadStreamPtr;
-    past = (internalPortAudioStream *) stream;
-
-    Pa_AbortStream( past );
-    result = PaHost_CloseStream( past );
-
-    if( past->past_InputBuffer ) PaHost_FreeFastMemory( past->past_InputBuffer, past->past_InputBufferSize );
-    if( past->past_OutputBuffer ) PaHost_FreeFastMemory( past->past_OutputBuffer, past->past_OutputBufferSize );
-    PaHost_FreeFastMemory( past, sizeof(internalPortAudioStream) );
-
-    return result;
-}
-
-/*************************************************************************/
-DLL_API PaError Pa_StartStream( PortAudioStream *stream )
-{
-    PaError result = paHostError;
-    internalPortAudioStream   *past;
-
-    if( stream == NULL ) return paBadStreamPtr;
-    past = (internalPortAudioStream *) stream;
-
-    past->past_FrameCount = 0.0;
-
-    if( past->past_NumInputChannels > 0 )
-    {
-        result = PaHost_StartInput( past );
-        DBUG(("Pa_StartStream: PaHost_StartInput returned = 0x%X.\n", result));
-        if( result < 0 ) goto error;
-    }
-
-    if( past->past_NumOutputChannels > 0 )
-    {
-        result = PaHost_StartOutput( past );
-        DBUG(("Pa_StartStream: PaHost_StartOutput returned = 0x%X.\n", result));
-        if( result < 0 ) goto error;
-    }
-
-    result = PaHost_StartEngine( past );
-    DBUG(("Pa_StartStream: PaHost_StartEngine returned = 0x%X.\n", result));
-    if( result < 0 ) goto error;
-
-    return paNoError;
-
-error:
-    return result;
-}
-
-/*************************************************************************/
-DLL_API PaError Pa_StopStream(  PortAudioStream *stream )
-{
-    return Pa_KillStream( stream, 0 );
-}
-
-/*************************************************************************/
-DLL_API PaError Pa_AbortStream(  PortAudioStream *stream )
-{
-    return Pa_KillStream( stream, 1 );
-}
-
-/*************************************************************************/
-static PaError Pa_KillStream(  PortAudioStream *stream, int abort )
-{
-    PaError result = paNoError;
-    internalPortAudioStream   *past;
-
-    DBUG(("Pa_StopStream().\n"));
-    if( stream == NULL ) return paBadStreamPtr;
-    past = (internalPortAudioStream *) stream;
-
-    if( (past->past_NumInputChannels > 0) || (past->past_NumOutputChannels > 0) )
-    {
-        result = PaHost_StopEngine( past, abort );
-        DBUG(("Pa_StopStream: PaHost_StopEngine returned = 0x%X.\n", result));
-        if( result < 0 ) goto error;
-    }
-
-    if( past->past_NumInputChannels > 0 )
-    {
-        result = PaHost_StopInput( past, abort );
-        DBUG(("Pa_StopStream: PaHost_StopInput returned = 0x%X.\n", result));
-        if( result != paNoError ) goto error;
-    }
-
-    if( past->past_NumOutputChannels > 0 )
-    {
-        result = PaHost_StopOutput( past, abort );
-        DBUG(("Pa_StopStream: PaHost_StopOutput returned = 0x%X.\n", result));
-        if( result != paNoError ) goto error;
-    }
-
-error:
-    past->past_Usage = 0;
-    past->past_IfLastExitValid = 0;
-
-    return result;
-}
-
-/*************************************************************************/
-DLL_API PaError Pa_StreamActive( PortAudioStream *stream )
-{
-    internalPortAudioStream   *past;
-    if( stream == NULL ) return paBadStreamPtr;
-    past = (internalPortAudioStream *) stream;
-    return PaHost_StreamActive( past );
-}
-
-/*************************************************************************/
-DLL_API const char *Pa_GetErrorText( PaError errnum )
-{
-    const char *msg;
-
-    switch(errnum)
-    {
-    case paNoError:                  msg = "Success"; break;
-    case paHostError:                msg = "Host error."; break;
-    case paInvalidChannelCount:      msg = "Invalid number of channels."; break;
-    case paInvalidSampleRate:        msg = "Invalid sample rate."; break;
-    case paInvalidDeviceId:          msg = "Invalid device ID."; break;
-    case paInvalidFlag:              msg = "Invalid flag."; break;
-    case paSampleFormatNotSupported: msg = "Sample format not supported"; break;
-    case paBadIODeviceCombination:   msg = "Illegal combination of I/O devices."; break;
-    case paInsufficientMemory:       msg = "Insufficient memory."; break;
-    case paBufferTooBig:             msg = "Buffer too big."; break;
-    case paBufferTooSmall:           msg = "Buffer too small."; break;
-    case paNullCallback:             msg = "No callback routine specified."; break;
-    case paBadStreamPtr:             msg = "Invalid stream pointer."; break;
-    case paTimedOut    :             msg = "Wait Timed Out."; break;
-    case paInternalError:            msg = "Internal PortAudio Error."; break;
-    default:                         msg = "Illegal error number."; break;
-    }
-    return msg;
-}
-
-/*
- Get CPU Load as a fraction of total CPU time.
- A value of 0.5 would imply that PortAudio and the sound generating
- callback was consuming roughly 50% of the available CPU time.
- The amount may vary depending on CPU load.
- This function may be called from the callback function.
-*/
-DLL_API double Pa_GetCPULoad(  PortAudioStream* stream)
-{
-    internalPortAudioStream   *past;
-    if( stream == NULL ) return (double) paBadStreamPtr;
-    past = (internalPortAudioStream *) stream;
-    return past->past_Usage;
-}
-
-/*************************************************************
-** Calculate 2 LSB dither signal with a triangular distribution.
-** Ranged properly for adding to a 32 bit integer prior to >>15.
-*/
-#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;
-    static unsigned long randSeed2 = 5555555;
-    long current, highPass;
-    /* Generate two random numbers. */
-    randSeed1 = (randSeed1 * 196314165) + 907633515;
-    randSeed2 = (randSeed2 * 196314165) + 907633515;
-    /* 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;
-    return highPass;
-}
-
-/*************************************************************************
-** Called by host code.
-** Convert input from Int16, call user code, then convert output
-** to Int16 format for native use.
-** Assumes host native format is paInt16.
-** Returns result from user callback.
-*/
-long Pa_CallConvertInt16( internalPortAudioStream   *past,
-                          short *nativeInputBuffer,
-                          short *nativeOutputBuffer )
-{
-    long              temp;
-    long              bytesEmpty = 0;
-    long              bytesFilled = 0;
-    int               userResult;
-    unsigned int      i;
-    void             *inputBuffer = NULL;
-    void             *outputBuffer = NULL;
-
-#if SUPPORT_AUDIO_CAPTURE
-    /* Get native data from DirectSound. */
-    if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )
-    {
-        /* Convert from native format to PA format. */
-        unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels;
-        switch(past->past_InputSampleFormat)
-        {
-
-        case paFloat32:
-            {
-                float *inBufPtr = (float *) past->past_InputBuffer;
-                inputBuffer = past->past_InputBuffer;
-                for( i=0; i<samplesPerBuffer; i++ )
-                {
-                    inBufPtr[i] = nativeInputBuffer[i] * (1.0f / 32767.0f);
-                }
-                break;
-            }
-
-        case paInt32:
-            {
-                /* Convert 16 bit data to 32 bit integers */
-                int *inBufPtr = (int *) past->past_InputBuffer;
-                inputBuffer = past->past_InputBuffer;
-                for( i=0; i<samplesPerBuffer; i++ )
-                {
-                    inBufPtr[i] = nativeInputBuffer[i] << 16;
-                }
-                break;
-            }
-
-        case paInt16:
-            {
-                /* Already in correct format so don't copy. */
-                inputBuffer = nativeInputBuffer;
-                break;
-            }
-
-        case paInt8:
-            {
-                /* Convert 16 bit data to 8 bit chars */
-                char *inBufPtr = (char *) past->past_InputBuffer;
-                inputBuffer = past->past_InputBuffer;
-                if( past->past_Flags & paDitherOff )
-                {
-                    for( i=0; i<samplesPerBuffer; i++ )
-                    {
-                        inBufPtr[i] = (char)(nativeInputBuffer[i] >> 8);
-                    }
-                }
-                else
-                {
-                    for( i=0; i<samplesPerBuffer; i++ )
-                    {
-                        temp = nativeInputBuffer[i];
-                        temp += Pa_TriangularDither() >> 7;
-                        temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
-                        inBufPtr[i] = (char)(temp >> 8);
-                    }
-                }
-                break;
-            }
-
-        case paUInt8:
-            {
-                /* Convert 16 bit data to 8 bit unsigned chars */
-                unsigned char *inBufPtr = (unsigned char *) past->past_InputBuffer;
-                inputBuffer = past->past_InputBuffer;
-                if( past->past_Flags & paDitherOff )
-                {
-                    for( i=0; i<samplesPerBuffer; i++ )
-                    {
-                        inBufPtr[i] = ((unsigned char)(nativeInputBuffer[i] >> 8)) + 0x80;
-                    }
-                }
-                else
-                {
-                    /* If you dither then you have to clip because dithering could push the signal out of range! */
-                    for( i=0; i<samplesPerBuffer; i++ )
-                    {
-                        temp = nativeInputBuffer[i];
-                        temp += Pa_TriangularDither() >> 7;
-                        temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
-                        inBufPtr[i] = (unsigned char)(temp + 0x80);
-                    }
-                }
-                break;
-            }
-
-        default:
-            break;
-        }
-    }
-#endif /* SUPPORT_AUDIO_CAPTURE */
-
-    /* Are we doing output time? */
-    if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )
-    {
-        /* May already be in native format so just write directly to native buffer. */
-        outputBuffer = (past->past_OutputSampleFormat == paInt16) ?
-                       nativeOutputBuffer : past->past_OutputBuffer;
-    }
-    /*
-     AddTraceMessage("Pa_CallConvertInt16: inputBuffer = ", (int) inputBuffer );
-     AddTraceMessage("Pa_CallConvertInt16: outputBuffer = ", (int) outputBuffer );
-    */
-    /* Call user callback routine. */
-    userResult = past->past_Callback(
-                     inputBuffer,
-                     outputBuffer,
-                     past->past_FramesPerUserBuffer,
-                     past->past_FrameCount,
-                     past->past_UserData );
-
-    past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;
-
-    /* Convert to native format if necessary. */
-    if( outputBuffer != NULL )
-    {
-        unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels;
-        switch(past->past_OutputSampleFormat)
-        {
-        case paFloat32:
-            {
-                float *outBufPtr = (float *) past->past_OutputBuffer;
-                if( past->past_Flags & paDitherOff )
-                {
-                    if( past->past_Flags & paClipOff ) /* NOTHING */
-                    {
-                        for( i=0; i<samplesPerBuffer; i++ )
-                        {
-                            *nativeOutputBuffer++ = (short) (outBufPtr[i] * (32767.0f));
-                        }
-                    }
-                    else /* CLIP */
-                    {
-                        for( i=0; i<samplesPerBuffer; i++ )
-                        {
-                            temp = (long)(outBufPtr[i] * 32767.0f);
-                            *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
-                        }
-                    }
-                }
-                else
-                {
-                    /* If you dither then you have to clip because dithering could push the signal out of range! */
-                    for( i=0; i<samplesPerBuffer; i++ )
-                    {
-                        float dither  = Pa_TriangularDither()*DITHER_SCALE;
-                        float dithered = (outBufPtr[i] * (32767.0f)) + dither;
-                        temp = (long) (dithered);
-                        *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
-                    }
-                }
-                break;
-            }
-
-        case paInt32:
-            {
-                int *outBufPtr = (int *) past->past_OutputBuffer;
-                if( past->past_Flags & paDitherOff )
-                {
-                    for( i=0; i<samplesPerBuffer; i++ )
-                    {
-                        *nativeOutputBuffer++ = (short) (outBufPtr[i] >> 16 );
-                    }
-                }
-                else
-                {
-                    for( i=0; i<samplesPerBuffer; i++ )
-                    {
-                        /* Shift one bit down before dithering so that we have room for overflow from add. */
-                        temp = (outBufPtr[i] >> 1) + Pa_TriangularDither();
-                        temp = temp >> 15;
-                        *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
-                    }
-                }
-                break;
-            }
-
-        case paInt8:
-            {
-                char *outBufPtr = (char *) past->past_OutputBuffer;
-                for( i=0; i<samplesPerBuffer; i++ )
-                {
-                    *nativeOutputBuffer++ = ((short)outBufPtr[i]) << 8;
-                }
-                break;
-            }
-
-        case paUInt8:
-            {
-                unsigned char *outBufPtr = (unsigned char *) past->past_OutputBuffer;
-                for( i=0; i<samplesPerBuffer; i++ )
-                {
-                    *nativeOutputBuffer++ = ((short)(outBufPtr[i] - 0x80)) << 8;
-                }
-                break;
-            }
-
-        default:
-            break;
-        }
-
-    }
-
-    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;
-}
-
-/*************************************************************************/
-DLL_API PaError Pa_Initialize( void )
-{
-    if( gInitCount++ > 0 ) return paNoError;
-    ResetTraceMessages();
-    return PaHost_Init();
-}
-
-DLL_API PaError Pa_Terminate( void )
-{
-    PaError result = paNoError;
-
-    if( gInitCount == 0 ) return paNoError;
-    else if( --gInitCount == 0 )
-    {
-        result = PaHost_Term();
-        DumpTraceMessages();
-    }
-    return result;
-}
-
-/*************************************************************************/
-DLL_API PaError Pa_GetSampleSize( PaSampleFormat format )
-{
-    int size;
-    switch(format )
-    {
-
-    case paUInt8:
-    case paInt8:
-        size = 1;
-        break;
-
-    case paInt16:
-        size = 2;
-        break;
-
-    case paPackedInt24:
-        size = 3;
-        break;
-
-    case paFloat32:
-    case paInt32:
-    case paInt24:
-        size = 4;
-        break;
-
-    default:
-        size = paSampleFormatNotSupported;
-        break;
-    }
-    return (PaError) size;
-}
-
-
diff --git a/portaudio/pa_dll_switch/portaudio.h b/portaudio/pa_dll_switch/portaudio.h
deleted file mode 100644
index 9632521eb..000000000
--- a/portaudio/pa_dll_switch/portaudio.h
+++ /dev/null
@@ -1,439 +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.
- *
- */
-
-// added by zplane.developement in order to generate a DLL
-
-#if defined(PA_MME_EXPORTS) || defined(PA_DX_EXPORTS)
-#define DLL_API __declspec( dllexport )
-#elif defined(_LIB) || defined(_STATIC_LINK) || defined(_STATIC_APP)
-#define DLL_API
-#else
-#define DLL_API __declspec(dllexport)
-#endif
-
-
-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.
-*/
-
-DLL_API PaError Pa_Initialize( void );
-
-/*
- Pa_Terminate() is the library termination function - call this after
- using the library.
-*/
-
-DLL_API PaError Pa_Terminate( void );
-
-/*
- Return host specific error.
- This can be called after receiving a paHostError.
-*/
-DLL_API long Pa_GetHostError( void );
-
-/*
- Translate the error number into a human readable message.
-*/
-DLL_API 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;
-
-
-DLL_API 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".
-*/
-DLL_API PaDeviceID Pa_GetDefaultInputDeviceID( void );
-DLL_API 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().
-*/
-
-DLL_API const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id );
-
-/*
- 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.
- 
-*/
-
-DLL_API 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.
-*/
-
-DLL_API 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.
-*/
-
-DLL_API PaError Pa_CloseStream( PortAudioStream* );
-
-/*
-  Pa_StartStream() and Pa_StopStream() begin and terminate audio processing.
- When Pa_StopStream() returns, all pending audio buffers have been played.
-    Pa_AbortStream() stops playing immediately without waiting for pending
-    buffers to complete.
-*/
-
-DLL_API PaError Pa_StartStream( PortAudioStream *stream );
-
-DLL_API PaError Pa_StopStream( PortAudioStream *stream );
-
-DLL_API 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.
-*/
-
-DLL_API 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).
-*/
-
-DLL_API 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.
-*/
-DLL_API 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.
-*/
-
-DLL_API 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.
-*/
-DLL_API void Pa_Sleep( long msec );
-
-/*
- Return size in bytes of a single sample in a given PaSampleFormat
- or paSampleFormatNotSupported. 
-*/
-DLL_API PaError Pa_GetSampleSize( PaSampleFormat format );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PORT_AUDIO_H */
diff --git a/portaudio/pa_jack/CVS/Entries b/portaudio/pa_jack/CVS/Entries
deleted file mode 100644
index 69d827fc4..000000000
--- a/portaudio/pa_jack/CVS/Entries
+++ /dev/null
@@ -1,2 +0,0 @@
-/pa_jack.c/1.1.2.20/Sun Oct  2 22:02:26 2005//Tv19-devel
-D
diff --git a/portaudio/pa_jack/CVS/Repository b/portaudio/pa_jack/CVS/Repository
deleted file mode 100644
index 51f4f90a7..000000000
--- a/portaudio/pa_jack/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_jack
diff --git a/portaudio/pa_jack/CVS/Root b/portaudio/pa_jack/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_jack/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_jack/CVS/Tag b/portaudio/pa_jack/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_jack/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_jack/pa_jack.c b/portaudio/pa_jack/pa_jack.c
deleted file mode 100644
index 2199365f4..000000000
--- a/portaudio/pa_jack/pa_jack.c
+++ /dev/null
@@ -1,1714 +0,0 @@
-/*
- * $Id: pa_jack.c,v 1.1.2.20 2005/10/02 22:02:26 aknudsen Exp $
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com
- * JACK Implementation by Joshua Haberman
- *
- * Copyright (c) 2004 Stefan Westerfeld <stefan@space.twc.de>
- * Copyright (c) 2004 Arve Knudsen <aknuds-1@broadpark.no>
- * Copyright (c) 2002 Joshua Haberman <joshua@haberman.com>
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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 <string.h>
-#include <regex.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>  /* EBUSY */
-#include <signal.h> /* sig_atomic_t */
-#include <math.h>
-#include <semaphore.h>
-
-#include <jack/types.h>
-#include <jack/jack.h>
-
-#include "pa_util.h"
-#include "pa_hostapi.h"
-#include "pa_stream.h"
-#include "pa_process.h"
-#include "pa_allocation.h"
-#include "pa_cpuload.h"
-#include "../pablio/ringbuffer.c"
-
-static int aErr_;
-static PaError paErr_;     /* For use with ENSURE_PA */
-static pthread_t mainThread_;
-static char *jackErr_ = NULL;
-
-#define STRINGIZE_HELPER(expr) #expr
-#define STRINGIZE(expr) STRINGIZE_HELPER(expr)
-
-/* Check PaError */
-#define ENSURE_PA(expr) \
-    do { \
-        if( (paErr_ = (expr)) < paNoError ) \
-        { \
-            if( (paErr_) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
-            { \
-                assert( jackErr_ ); \
-                PaUtil_SetLastHostErrorInfo( paJACK, -1, jackErr_ ); \
-            } \
-            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
-            result = paErr_; \
-            goto error; \
-        } \
-    } while( 0 )
-
-#define UNLESS(expr, code) \
-    do { \
-        if( (expr) == 0 ) \
-        { \
-            if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
-            { \
-                assert( jackErr_ ); \
-                PaUtil_SetLastHostErrorInfo( paJACK, -1, jackErr_ ); \
-            } \
-            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
-            result = (code); \
-            goto error; \
-        } \
-    } while( 0 )
-
-#define ASSERT_CALL(expr, success) \
-    aErr_ = (expr); \
-    assert( aErr_ == success );
-
-/*
- * Functions that directly map to the PortAudio stream interface
- */
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate );
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData );
-static PaError CloseStream( PaStream* stream );
-static PaError StartStream( PaStream *stream );
-static PaError StopStream( PaStream *stream );
-static PaError AbortStream( PaStream *stream );
-static PaError IsStreamStopped( PaStream *s );
-static PaError IsStreamActive( PaStream *stream );
-/*static PaTime GetStreamInputLatency( PaStream *stream );*/
-/*static PaTime GetStreamOutputLatency( PaStream *stream );*/
-static PaTime GetStreamTime( PaStream *stream );
-static double GetStreamCpuLoad( PaStream* stream );
-
-
-/*
- * Data specific to this API
- */
-
-struct PaJackStream;
-
-typedef struct
-{
-    PaUtilHostApiRepresentation commonHostApiRep;
-    PaUtilStreamInterface callbackStreamInterface;
-    PaUtilStreamInterface blockingStreamInterface;
-
-    PaUtilAllocationGroup *deviceInfoMemory;
-
-    jack_client_t *jack_client;
-    int jack_buffer_size;
-    PaHostApiIndex hostApiIndex;
-
-    pthread_mutex_t mtx;
-    pthread_cond_t cond;
-    unsigned long inputBase, outputBase;
-
-    /* For dealing with the process thread */
-    volatile int xrun;     /* Received xrun notification from JACK? */
-    struct PaJackStream * volatile toAdd, * volatile toRemove;
-    struct PaJackStream *processQueue;
-    volatile sig_atomic_t jackIsDown;
-}
-PaJackHostApiRepresentation;
-
-/* PaJackStream - a stream data structure specifically for this implementation */
-
-typedef struct PaJackStream
-{
-    PaUtilStreamRepresentation streamRepresentation;
-    PaUtilBufferProcessor bufferProcessor;
-    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
-    PaJackHostApiRepresentation *hostApi;
-
-    /* our input and output ports */
-    jack_port_t **local_input_ports;
-    jack_port_t **local_output_ports;
-
-    /* the input and output ports of the client we are connecting to */
-    jack_port_t **remote_input_ports;
-    jack_port_t **remote_output_ports;
-
-    int num_incoming_connections;
-    int num_outgoing_connections;
-
-    jack_client_t *jack_client;
-
-    /* The stream is running if it's still producing samples.
-     * The stream is active if samples it produced are still being heard.
-     */
-    volatile sig_atomic_t is_running;
-    volatile sig_atomic_t is_active;
-    /* Used to signal processing thread that stream should start or stop, respectively */
-    volatile sig_atomic_t doStart, doStop, doAbort;
-
-    jack_nframes_t t0;
-
-    PaUtilAllocationGroup *stream_memory;
-
-    /* These are useful in the process callback */
-
-    int callbackResult;
-    int isSilenced;
-    int xrun;
-
-    /* These are useful for the blocking API */
-
-    int                     isBlockingStream;
-    RingBuffer              inFIFO;
-    RingBuffer              outFIFO;
-    volatile sig_atomic_t   data_available;
-    sem_t                   data_semaphore;
-    int                     bytesPerFrame;
-    int                     samplesPerFrame;
-
-    struct PaJackStream *next;
-}
-PaJackStream;
-
-#define TRUE 1
-#define FALSE 0
-
-/*
- * Functions specific to this API
- */
-
-static int JackCallback( jack_nframes_t frames, void *userData );
-
-
-/*
- *
- * Implementation
- *
- */
-
-/* ---- blocking emulation layer ---- */
-
-/* Allocate buffer. */
-static PaError BlockingInitFIFO( RingBuffer *rbuf, long numFrames, long bytesPerFrame )
-{
-    long numBytes = numFrames * bytesPerFrame;
-    char *buffer = (char *) malloc( numBytes );
-    if( buffer == NULL ) return paInsufficientMemory;
-    memset( buffer, 0, numBytes );
-    return (PaError) RingBuffer_Init( rbuf, numBytes, buffer );
-}
-
-/* Free buffer. */
-static PaError BlockingTermFIFO( RingBuffer *rbuf )
-{
-    if( rbuf->buffer ) free( rbuf->buffer );
-    rbuf->buffer = NULL;
-    return paNoError;
-}
-
-static int
-BlockingCallback( const void                      *inputBuffer,
-                  void                            *outputBuffer,
-		  unsigned long                    framesPerBuffer,
-		  const PaStreamCallbackTimeInfo*  timeInfo,
-		  PaStreamCallbackFlags            statusFlags,
-		  void                             *userData )
-{
-    struct PaJackStream *stream = (PaJackStream *)userData;
-    long numBytes = stream->bytesPerFrame * framesPerBuffer;
-
-    /* This may get called with NULL inputBuffer during initial setup. */
-    if( inputBuffer != NULL )
-    {
-        RingBuffer_Write( &stream->inFIFO, inputBuffer, numBytes );
-    }
-    if( outputBuffer != NULL )
-    {
-        int numRead = RingBuffer_Read( &stream->outFIFO, outputBuffer, numBytes );
-        /* Zero out remainder of buffer if we run out of data. */
-        memset( (char *)outputBuffer + numRead, 0, numBytes - numRead );
-    }
-
-    if( !stream->data_available )
-    {
-        stream->data_available = 1;
-        sem_post( &stream->data_semaphore );
-    }
-    return paContinue;
-}
-
-static PaError
-BlockingBegin( PaJackStream *stream, int minimum_buffer_size )
-{
-    long    doRead = 0;
-    long    doWrite = 0;
-    PaError result = paNoError;
-    long    numFrames;
-
-    doRead = stream->local_input_ports != NULL;
-    doWrite = stream->local_output_ports != NULL;
-    /* <FIXME> */
-    stream->samplesPerFrame = 2;
-    stream->bytesPerFrame = sizeof(float) * stream->samplesPerFrame;
-    /* </FIXME> */
-    numFrames = 32;
-    while (numFrames < minimum_buffer_size)
-        numFrames *= 2;
-
-    if( doRead )
-    {
-        ENSURE_PA( BlockingInitFIFO( &stream->inFIFO, numFrames, stream->bytesPerFrame ) );
-    }
-    if( doWrite )
-    {
-        long numBytes;
-
-        ENSURE_PA( BlockingInitFIFO( &stream->outFIFO, numFrames, stream->bytesPerFrame ) );
-
-        /* Make Write FIFO appear full initially. */
-        numBytes = RingBuffer_GetWriteAvailable( &stream->outFIFO );
-        RingBuffer_AdvanceWriteIndex( &stream->outFIFO, numBytes );
-    }
-
-    stream->data_available = 0;
-    sem_init( &stream->data_semaphore, 0, 0 );
-
-error:
-    return result;
-}
-
-static void
-BlockingEnd( PaJackStream *stream )
-{
-    BlockingTermFIFO( &stream->inFIFO );
-    BlockingTermFIFO( &stream->outFIFO );
-
-    sem_destroy( &stream->data_semaphore );
-}
-
-static PaError BlockingReadStream( PaStream* s, void *data, unsigned long numFrames )
-{
-    PaError result = paNoError;
-    PaJackStream *stream = (PaJackStream *)s;
-
-    long bytesRead;
-    char *p = (char *) data;
-    long numBytes = stream->bytesPerFrame * numFrames;
-    while( numBytes > 0 )
-    {
-        bytesRead = RingBuffer_Read( &stream->inFIFO, p, numBytes );
-        numBytes -= bytesRead;
-        p += bytesRead;
-        if( numBytes > 0 )
-        {
-            /* see write for an explanation */
-            if( stream->data_available )
-                stream->data_available = 0;
-            else
-                sem_wait( &stream->data_semaphore );
-        }
-    }
-
-    return result;
-}
-
-static PaError BlockingWriteStream( PaStream* s, const void *data, unsigned long numFrames )
-{
-    PaError result = paNoError;
-    PaJackStream *stream = (PaJackStream *)s;
-    long bytesWritten;
-    char *p = (char *) data;
-    long numBytes = stream->bytesPerFrame * numFrames;
-    while( numBytes > 0 )
-    {
-        bytesWritten = RingBuffer_Write( &stream->outFIFO, p, numBytes );
-        numBytes -= bytesWritten;
-        p += bytesWritten;
-        if( numBytes > 0 ) 
-        {
-            /* we use the following algorithm: 
-             *   (1) write data
-             *   (2) if some data didn't fit into the ringbuffer, set data_available to 0
-             *       to indicate to the audio that if space becomes available, we want to know
-             *   (3) retry to write data (because it might be that between (1) and (2)
-             *       new space in the buffer became available)
-             *   (4) if this failed, we are sure that the buffer is really empty and
-             *       we will definitely receive a notification when it becomes available
-             *       thus we can safely sleep
-             *
-             * if the algorithm bailed out in step (3) before, it leaks a count of 1
-             * on the semaphore; however, it doesn't matter, because if we block in (4),
-             * we also do it in a loop
-             */
-            if( stream->data_available )
-                stream->data_available = 0;
-            else
-                sem_wait( &stream->data_semaphore );
-        }
-    }
-
-    return result;
-}
-
-static signed long
-BlockingGetStreamReadAvailable( PaStream* s )
-{
-    PaJackStream *stream = (PaJackStream *)s;
-
-    int bytesFull = RingBuffer_GetReadAvailable( &stream->inFIFO );
-    return bytesFull / stream->bytesPerFrame;
-}
-
-static signed long
-BlockingGetStreamWriteAvailable( PaStream* s )
-{
-    PaJackStream *stream = (PaJackStream *)s;
-
-    int bytesEmpty = RingBuffer_GetWriteAvailable( &stream->outFIFO );
-    return bytesEmpty / stream->bytesPerFrame;
-}
-
-static PaError
-BlockingWaitEmpty( PaStream *s )
-{
-    PaJackStream *stream = (PaJackStream *)s;
-
-    while( RingBuffer_GetReadAvailable( &stream->outFIFO ) > 0 )
-    {
-        stream->data_available = 0;
-        sem_wait( &stream->data_semaphore );
-    }
-    return 0;
-}
-
-/* ---- jack driver ---- */
-
-/* BuildDeviceList():
- *
- * The process of determining a list of PortAudio "devices" from
- * JACK's client/port system is fairly involved, so it is separated
- * into its own routine.
- */
-
-static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
-{
-    /* Utility macros for the repetitive process of allocating memory */
-
-    /* ... MALLOC: allocate memory as part of the device list
-     * allocation group */
-#define MALLOC(size) \
-     (PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, (size) ))
-
-    /* JACK has no concept of a device.  To JACK, there are clients
-     * which have an arbitrary number of ports.  To make this
-     * intelligible to PortAudio clients, we will group each JACK client
-     * into a device, and make each port of that client a channel */
-
-    PaError result = paNoError;
-    PaUtilHostApiRepresentation *commonApi = &jackApi->commonHostApiRep;
-
-    const char **jack_ports = NULL;
-    char **client_names = NULL;
-    char *regex_pattern = alloca( jack_client_name_size() + 3 );
-    int port_index, client_index, i;
-    double globalSampleRate;
-    regex_t port_regex;
-    unsigned long numClients = 0, numPorts = 0;
-    char *tmp_client_name = alloca( jack_client_name_size() );
-
-    commonApi->info.defaultInputDevice = paNoDevice;
-    commonApi->info.defaultOutputDevice = paNoDevice;
-    commonApi->info.deviceCount = 0;
-
-    /* Parse the list of ports, using a regex to grab the client names */
-    ASSERT_CALL( regcomp( &port_regex, "^[^:]*", REG_EXTENDED ), 0 );
-
-    /* since we are rebuilding the list of devices, free all memory
-     * associated with the previous list */
-    PaUtil_FreeAllAllocations( jackApi->deviceInfoMemory );
-
-    /* We can only retrieve the list of clients indirectly, by first
-     * asking for a list of all ports, then parsing the port names
-     * according to the client_name:port_name convention (which is
-     * enforced by jackd)
-     * A: If jack_get_ports returns NULL, there's nothing for us to do */
-    UNLESS( (jack_ports = jack_get_ports( jackApi->jack_client, "", "", 0 )) && jack_ports[0], paNoError );
-    /* Find number of ports */
-    while( jack_ports[numPorts] )
-        ++numPorts;
-    /* At least there will be one port per client :) */
-    UNLESS( client_names = alloca( numPorts * sizeof (char *) ), paInsufficientMemory );
-
-    /* Build a list of clients from the list of ports */
-    for( numClients = 0, port_index = 0; jack_ports[port_index] != NULL; port_index++ )
-    {
-        int client_seen = FALSE;
-        regmatch_t match_info;
-        const char *port = jack_ports[port_index];
-
-        /* extract the client name from the port name, using a regex
-         * that parses the clientname:portname syntax */
-        UNLESS( !regexec( &port_regex, port, 1, &match_info, 0 ), paInternalError );
-        assert(match_info.rm_eo - match_info.rm_so < jack_client_name_size());
-        memcpy( tmp_client_name, port + match_info.rm_so,
-                match_info.rm_eo - match_info.rm_so );
-        tmp_client_name[match_info.rm_eo - match_info.rm_so] = '\0';
-
-        /* do we know about this port's client yet? */
-        for( i = 0; i < numClients; i++ )
-        {
-            if( strcmp( tmp_client_name, client_names[i] ) == 0 )
-                client_seen = TRUE;
-        }
-
-        if (client_seen)
-            continue;   /* A: Nothing to see here, move along */
-
-        UNLESS( client_names[numClients] = (char*)MALLOC(strlen(tmp_client_name) + 1), paInsufficientMemory );
-
-        /* The alsa_pcm client should go in spot 0.  If this
-         * is the alsa_pcm client AND we are NOT about to put
-         * it in spot 0 put it in spot 0 and move whatever
-         * was already in spot 0 to the end. */
-        if( strcmp( "alsa_pcm", tmp_client_name ) == 0 && numClients > 0 )
-        {
-            /* alsa_pcm goes in spot 0 */
-            strcpy( client_names[ numClients ], client_names[0] );
-            strcpy( client_names[0], tmp_client_name );
-        }
-        else
-        {
-            /* put the new client at the end of the client list */
-            strcpy( client_names[ numClients ], tmp_client_name );
-        }
-        ++numClients;
-    }
-
-    /* Now we have a list of clients, which will become the list of
-     * PortAudio devices. */
-
-    /* there is one global sample rate all clients must conform to */
-
-    globalSampleRate = jack_get_sample_rate( jackApi->jack_client );
-    UNLESS( commonApi->deviceInfos = (PaDeviceInfo**)MALLOC( sizeof(PaDeviceInfo*) *
-                                                     numClients ), paInsufficientMemory );
-
-    assert( commonApi->info.deviceCount == 0 );
-
-    /* Create a PaDeviceInfo structure for every client */
-    for( client_index = 0; client_index < numClients; client_index++ )
-    {
-        PaDeviceInfo *curDevInfo;
-        const char **clientPorts = NULL;
-
-        UNLESS( curDevInfo = (PaDeviceInfo*)MALLOC( sizeof(PaDeviceInfo) ), paInsufficientMemory );
-        UNLESS( curDevInfo->name = (char*)MALLOC( strlen(client_names[client_index]) + 1 ), paInsufficientMemory );
-        strcpy( (char *)curDevInfo->name, client_names[client_index] );
-
-        curDevInfo->structVersion = 2;
-        curDevInfo->hostApi = jackApi->hostApiIndex;
-
-        /* JACK is very inflexible: there is one sample rate the whole
-         * system must run at, and all clients must speak IEEE float. */
-        curDevInfo->defaultSampleRate = globalSampleRate;
-
-        /* To determine how many input and output channels are available,
-         * we re-query jackd with more specific parameters. */
-
-        sprintf( regex_pattern, "%s:.*", client_names[client_index] );
-
-        /* ... what are your output ports (that we could input from)? */
-        clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern,
-                                     NULL, JackPortIsOutput);
-        curDevInfo->maxInputChannels = 0;
-        curDevInfo->defaultLowInputLatency = 0.;
-        curDevInfo->defaultHighInputLatency = 0.;
-        if( clientPorts )
-        {
-            jack_port_t *p = jack_port_by_name( jackApi->jack_client, clientPorts[0] );
-            curDevInfo->defaultLowInputLatency = curDevInfo->defaultHighInputLatency =
-                jack_port_get_latency( p ) / globalSampleRate;
-
-            for( i = 0; clientPorts[i] != NULL; i++)
-            {
-                /* The number of ports returned is the number of output channels.
-                 * We don't care what they are, we just care how many */
-                curDevInfo->maxInputChannels++;
-            }
-            free(clientPorts);
-        }
-
-        /* ... what are your input ports (that we could output to)? */
-        clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern,
-                                     NULL, JackPortIsInput);
-        curDevInfo->maxOutputChannels = 0;
-        curDevInfo->defaultLowOutputLatency = 0.;
-        curDevInfo->defaultHighOutputLatency = 0.;
-        if( clientPorts )
-        {
-            jack_port_t *p = jack_port_by_name( jackApi->jack_client, clientPorts[0] );
-            curDevInfo->defaultLowOutputLatency = curDevInfo->defaultHighOutputLatency =
-                jack_port_get_latency( p ) / globalSampleRate;
-
-            for( i = 0; clientPorts[i] != NULL; i++)
-            {
-                /* The number of ports returned is the number of input channels.
-                 * We don't care what they are, we just care how many */
-                curDevInfo->maxOutputChannels++;
-            }
-            free(clientPorts);
-        }
-
-        /* Add this client to the list of devices */
-        commonApi->deviceInfos[client_index] = curDevInfo;
-        ++commonApi->info.deviceCount;
-        if( commonApi->info.defaultInputDevice == paNoDevice && curDevInfo->maxInputChannels > 0 )
-            commonApi->info.defaultInputDevice = client_index;
-        if( commonApi->info.defaultOutputDevice == paNoDevice && curDevInfo->maxOutputChannels > 0 )
-            commonApi->info.defaultOutputDevice = client_index;
-    }
-
-error:
-    regfree( &port_regex );
-    free( jack_ports );
-    return result;
-}
-#undef MALLOC
-
-static void UpdateSampleRate( PaJackStream *stream, double sampleRate )
-{
-    /* XXX: Maybe not the cleanest way of going about this? */
-    stream->cpuLoadMeasurer.samplingPeriod = stream->bufferProcessor.samplePeriod = 1. / sampleRate;
-    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
-}
-
-static void JackErrorCallback( const char *msg )
-{
-    if( pthread_self() == mainThread_ )
-    {
-        assert( msg );
-        free( jackErr_ );
-        jackErr_ = malloc( strlen( msg ) );
-        sprintf( jackErr_, msg );
-    }
-}
-
-static void JackOnShutdown( void *arg )
-{
-    PaJackHostApiRepresentation *jackApi = (PaJackHostApiRepresentation *)arg;
-    PaJackStream *stream = jackApi->processQueue;
-
-    PA_DEBUG(( "%s: JACK server is shutting down\n", __FUNCTION__ ));
-    for( ; stream; stream = stream->next )
-    {
-        stream->is_active = 0;
-    }
-
-    /* Make sure that the main thread doesn't get stuck waiting on the condition */
-    ASSERT_CALL( pthread_mutex_lock( &jackApi->mtx ), 0 );
-    jackApi->jackIsDown = 1;
-    ASSERT_CALL( pthread_cond_signal( &jackApi->cond ), 0 );
-    ASSERT_CALL( pthread_mutex_unlock( &jackApi->mtx ), 0 );
-
-}
-
-static int JackSrCb( jack_nframes_t nframes, void *arg )
-{
-    PaJackHostApiRepresentation *jackApi = (PaJackHostApiRepresentation *)arg;
-    double sampleRate = (double)nframes;
-    PaJackStream *stream = jackApi->processQueue;
-
-    /* Update all streams in process queue */
-    PA_DEBUG(( "%s: Acting on change in JACK samplerate: %f\n", __FUNCTION__, sampleRate ));
-    for( ; stream; stream = stream->next )
-    {
-        if( stream->streamRepresentation.streamInfo.sampleRate != sampleRate )
-        {
-            PA_DEBUG(( "%s: Updating samplerate\n", __FUNCTION__ ));
-            UpdateSampleRate( stream, sampleRate );
-        }
-    }
-
-    return 0;
-}
-
-static int JackXRunCb(void *arg) {
-    PaJackHostApiRepresentation *hostApi = (PaJackHostApiRepresentation *)arg;
-    assert( hostApi );
-    hostApi->xrun = TRUE;
-    PA_DEBUG(( "%s: JACK signalled xrun\n", __FUNCTION__ ));
-    return 0;
-}
-
-PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi,
-                           PaHostApiIndex hostApiIndex )
-{
-    PaError result = paNoError;
-    PaJackHostApiRepresentation *jackHostApi;
-    int activated = 0;
-    char *clientName;
-    int written;
-    *hostApi = NULL;    /* Initialize to NULL */
-
-    UNLESS( jackHostApi = (PaJackHostApiRepresentation*)
-        PaUtil_AllocateMemory( sizeof(PaJackHostApiRepresentation) ), paInsufficientMemory );
-    jackHostApi->deviceInfoMemory = NULL;
-
-    mainThread_ = pthread_self();
-    ASSERT_CALL( pthread_mutex_init( &jackHostApi->mtx, NULL ), 0 );
-    ASSERT_CALL( pthread_cond_init( &jackHostApi->cond, NULL ), 0 );
-
-    /* Try to become a client of the JACK server.  If we cannot do
-     * this, then this API cannot be used. */
-
-    clientName = alloca( jack_client_name_size() );
-    written = snprintf( clientName, jack_client_name_size(), "PortAudio-%d", getpid() );
-    assert( written < jack_client_name_size() );
-    jackHostApi->jack_client = jack_client_new( clientName );
-    if( jackHostApi->jack_client == NULL )
-    {
-       /* the V19 development docs say that if an implementation
-        * detects that it cannot be used, it should return a NULL
-        * interface and paNoError */
-       result = paNoError;
-       goto error;
-    }
-
-    UNLESS( jackHostApi->deviceInfoMemory = PaUtil_CreateAllocationGroup(), paInsufficientMemory );
-    jackHostApi->hostApiIndex = hostApiIndex;
-
-    *hostApi = &jackHostApi->commonHostApiRep;
-    (*hostApi)->info.structVersion = 1;
-    (*hostApi)->info.type = paJACK;
-    (*hostApi)->info.name = "JACK Audio Connection Kit";
-
-    /* Build a device list by querying the JACK server */
-
-    ENSURE_PA( BuildDeviceList( jackHostApi ) );
-
-    /* Register functions */
-
-    (*hostApi)->Terminate = Terminate;
-    (*hostApi)->OpenStream = OpenStream;
-    (*hostApi)->IsFormatSupported = IsFormatSupported;
-
-    PaUtil_InitializeStreamInterface( &jackHostApi->callbackStreamInterface,
-                                      CloseStream, StartStream,
-                                      StopStream, AbortStream,
-                                      IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, GetStreamCpuLoad,
-                                      PaUtil_DummyRead, PaUtil_DummyWrite,
-                                      PaUtil_DummyGetReadAvailable,
-                                      PaUtil_DummyGetWriteAvailable );
-
-    PaUtil_InitializeStreamInterface( &jackHostApi->blockingStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
-                                      BlockingReadStream, BlockingWriteStream,
-                                      BlockingGetStreamReadAvailable, BlockingGetStreamWriteAvailable );
-
-    jackHostApi->inputBase = jackHostApi->outputBase = 0;
-    jackHostApi->xrun = 0;
-    jackHostApi->toAdd = jackHostApi->toRemove = NULL;
-    jackHostApi->processQueue = NULL;
-    jackHostApi->jackIsDown = 0;
-
-    jack_on_shutdown( jackHostApi->jack_client, JackOnShutdown, jackHostApi );
-    jack_set_error_function( JackErrorCallback );
-    jackHostApi->jack_buffer_size = jack_get_buffer_size ( jackHostApi->jack_client );
-    UNLESS( !jack_set_sample_rate_callback( jackHostApi->jack_client, JackSrCb, jackHostApi ), paUnanticipatedHostError );
-    UNLESS( !jack_set_xrun_callback( jackHostApi->jack_client, JackXRunCb, jackHostApi ), paUnanticipatedHostError );
-    UNLESS( !jack_set_process_callback( jackHostApi->jack_client, JackCallback, jackHostApi ), paUnanticipatedHostError );
-    UNLESS( !jack_activate( jackHostApi->jack_client ), paUnanticipatedHostError );
-    activated = 1;
-
-    return result;
-
-error:
-    if( activated )
-        ASSERT_CALL( jack_deactivate( jackHostApi->jack_client ), 0 );
-
-    if( jackHostApi )
-    {
-        if( jackHostApi->jack_client )
-            ASSERT_CALL( jack_client_close( jackHostApi->jack_client ), 0 );
-
-        if( jackHostApi->deviceInfoMemory )
-        {
-            PaUtil_FreeAllAllocations( jackHostApi->deviceInfoMemory );
-            PaUtil_DestroyAllocationGroup( jackHostApi->deviceInfoMemory );
-        }
-
-        PaUtil_FreeMemory( jackHostApi );
-    }
-    return result;
-}
-
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
-{
-    PaJackHostApiRepresentation *jackHostApi = (PaJackHostApiRepresentation*)hostApi;
-
-    /* note: this automatically disconnects all ports, since a deactivated
-     * client is not allowed to have any ports connected */
-    ASSERT_CALL( jack_deactivate( jackHostApi->jack_client ), 0 );
-
-    ASSERT_CALL( pthread_mutex_destroy( &jackHostApi->mtx ), 0 );
-    ASSERT_CALL( pthread_cond_destroy( &jackHostApi->cond ), 0 );
-
-    ASSERT_CALL( jack_client_close( jackHostApi->jack_client ), 0 );
-
-    if( jackHostApi->deviceInfoMemory )
-    {
-        PaUtil_FreeAllAllocations( jackHostApi->deviceInfoMemory );
-        PaUtil_DestroyAllocationGroup( jackHostApi->deviceInfoMemory );
-    }
-
-    PaUtil_FreeMemory( jackHostApi );
-
-    free( jackErr_ );
-}
-
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate )
-{
-    int inputChannelCount = 0, outputChannelCount = 0;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that input device can support inputChannelCount */
-        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
-            return paInvalidChannelCount;
-
-        /* validate inputStreamInfo */
-        if( inputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        inputChannelCount = 0;
-    }
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that output device can support inputChannelCount */
-        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
-            return paInvalidChannelCount;
-
-        /* validate outputStreamInfo */
-        if( outputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        outputChannelCount = 0;
-    }
-
-    /*
-        The following check is not necessary for JACK.
-        
-            - if a full duplex stream is requested, check that the combination
-                of input and output parameters is supported
-
-
-        Because the buffer adapter handles conversion between all standard
-        sample formats, the following checks are only required if paCustomFormat
-        is implemented, or under some other unusual conditions.
-        
-            - check that input device can support inputSampleFormat, or that
-                we have the capability to convert from outputSampleFormat to
-                a native format
-
-            - check that output device can support outputSampleFormat, or that
-                we have the capability to convert from outputSampleFormat to
-                a native format
-    */
-
-    /* check that the device supports sampleRate */
-    
-#define ABS(x) ( (x) > 0 ? (x) : -(x) )
-    if( ABS(sampleRate - jack_get_sample_rate(((PaJackHostApiRepresentation *) hostApi)->jack_client )) > 1 )
-       return paInvalidSampleRate;
-#undef ABS
-
-    return paFormatIsSupported;
-}
-
-/* Basic stream initialization */
-static PaError InitializeStream( PaJackStream *stream, PaJackHostApiRepresentation *hostApi, int numInputChannels,
-        int numOutputChannels )
-{
-    PaError result = paNoError;
-    assert( stream );
-
-    memset( stream, 0, sizeof (PaJackStream) );
-    UNLESS( stream->stream_memory = PaUtil_CreateAllocationGroup(), paInsufficientMemory );
-    stream->jack_client = hostApi->jack_client;
-    stream->hostApi = hostApi;
-
-    if( numInputChannels > 0 )
-    {
-        UNLESS( stream->local_input_ports =
-                (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numInputChannels ),
-                paInsufficientMemory );
-        memset( stream->local_input_ports, 0, sizeof(jack_port_t*) * numInputChannels );
-        UNLESS( stream->remote_output_ports =
-                (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numInputChannels ),
-                paInsufficientMemory );
-        memset( stream->remote_output_ports, 0, sizeof(jack_port_t*) * numInputChannels );
-    }
-    if( numOutputChannels > 0 )
-    {
-        UNLESS( stream->local_output_ports =
-                (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numOutputChannels ),
-                paInsufficientMemory );
-        memset( stream->local_output_ports, 0, sizeof(jack_port_t*) * numOutputChannels );
-        UNLESS( stream->remote_input_ports =
-                (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numOutputChannels ),
-                paInsufficientMemory );
-        memset( stream->remote_input_ports, 0, sizeof(jack_port_t*) * numOutputChannels );
-    }
-
-    stream->num_incoming_connections = numInputChannels;
-    stream->num_outgoing_connections = numOutputChannels;
-
-error:
-    return result;
-}
-
-/*!
- * Free resources associated with stream, and eventually stream itself.
- *
- * Frees allocated memory, and closes opened pcms.
- */
-static void CleanUpStream( PaJackStream *stream, int terminateStreamRepresentation, int terminateBufferProcessor )
-{
-    int i;
-    assert( stream );
-
-    if( stream->isBlockingStream )
-        BlockingEnd( stream );
-
-    for( i = 0; i < stream->num_incoming_connections; ++i )
-    {
-        if( stream->local_input_ports[i] )
-            ASSERT_CALL( jack_port_unregister( stream->jack_client, stream->local_input_ports[i] ), 0 );
-    }
-    for( i = 0; i < stream->num_outgoing_connections; ++i )
-    {
-        if( stream->local_output_ports[i] )
-            ASSERT_CALL( jack_port_unregister( stream->jack_client, stream->local_output_ports[i] ), 0 );
-    }
-
-    if( terminateStreamRepresentation )
-        PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
-    if( terminateBufferProcessor )
-        PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
-
-    if( stream->stream_memory )
-    {
-        PaUtil_FreeAllAllocations( stream->stream_memory );
-        PaUtil_DestroyAllocationGroup( stream->stream_memory );
-    }
-    PaUtil_FreeMemory( stream );
-}
-
-static PaError WaitCondition( PaJackHostApiRepresentation *hostApi )
-{
-    PaError result = paNoError;
-    int err = 0;
-    PaTime pt = PaUtil_GetTime();
-    struct timespec ts;
-
-    ts.tv_sec = (time_t) floor( pt + 1 );
-    ts.tv_nsec = (long) ((pt - floor( pt )) * 1000000000);
-    /* XXX: Best enclose in loop, in case of spurious wakeups? */
-    err = pthread_cond_timedwait( &hostApi->cond, &hostApi->mtx, &ts );
-
-    /* Make sure we didn't time out */
-    UNLESS( err != ETIMEDOUT, paTimedOut );
-    UNLESS( !err, paInternalError );
-
-error:
-    return result;
-}
-
-static PaError AddStream( PaJackStream *stream )
-{
-    PaError result = paNoError;
-    PaJackHostApiRepresentation *hostApi = stream->hostApi;
-    /* Add to queue of streams that should be processed */
-    ASSERT_CALL( pthread_mutex_lock( &hostApi->mtx ), 0 );
-    if( !hostApi->jackIsDown )
-    {
-        hostApi->toAdd = stream;
-        /* Unlock mutex and await signal from processing thread */
-        result = WaitCondition( stream->hostApi );
-    }
-    ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 );
-    ENSURE_PA( result );
-
-    UNLESS( !hostApi->jackIsDown, paDeviceUnavailable );
-
-error:
-    return result;
-}
-
-/* Remove stream from processing queue */
-static PaError RemoveStream( PaJackStream *stream )
-{
-    PaError result = paNoError;
-    PaJackHostApiRepresentation *hostApi = stream->hostApi;
-
-    /* Add to queue over streams that should be processed */
-    ASSERT_CALL( pthread_mutex_lock( &hostApi->mtx ), 0 );
-    if( !hostApi->jackIsDown )
-    {
-        hostApi->toRemove = stream;
-        /* Unlock mutex and await signal from processing thread */
-        result = WaitCondition( stream->hostApi );
-    }
-    ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 );
-    ENSURE_PA( result );
-
-error:
-    return result;
-}
-
-/* Add stream to processing queue */
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData )
-{
-    PaError result = paNoError;
-    PaJackHostApiRepresentation *jackHostApi = (PaJackHostApiRepresentation*)hostApi;
-    PaJackStream *stream = NULL;
-    char *port_string = alloca( jack_port_name_size() );
-    unsigned long regexSz = jack_client_name_size() + 3;
-    char *regex_pattern = alloca( regexSz );
-    const char **jack_ports = NULL;
-    /* int jack_max_buffer_size = jack_get_buffer_size( jackHostApi->jack_client ); */
-    int i;
-    int inputChannelCount, outputChannelCount;
-    const double jackSr = jack_get_sample_rate( jackHostApi->jack_client );
-    PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0;
-    int bpInitialized = 0, srInitialized = 0;   /* Initialized buffer processor and stream representation? */
-    unsigned long ofs;
-
-    /* validate platform specific flags */
-    if( (streamFlags & paPlatformSpecificFlags) != 0 )
-        return paInvalidFlag; /* unexpected platform specific flag */
-    if( (streamFlags & paPrimeOutputBuffersUsingStreamCallback) != 0 )
-    {
-        streamFlags &= ~paPrimeOutputBuffersUsingStreamCallback;
-        /*return paInvalidFlag;*/   /* This implementation does not support buffer priming */
-    }
-
-    if( framesPerBuffer != paFramesPerBufferUnspecified )
-    {
-        /* Jack operates with power of two buffers, and we don't support non-integer buffer adaption (yet) */
-        /*UNLESS( !(framesPerBuffer & (framesPerBuffer - 1)), paBufferTooBig );*/  /* TODO: Add descriptive error code? */
-    }
-
-    /* Preliminary checks */
-
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that input device can support inputChannelCount */
-        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
-            return paInvalidChannelCount;
-
-        /* validate inputStreamInfo */
-        if( inputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        inputChannelCount = 0;
-    }
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that output device can support inputChannelCount */
-        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
-            return paInvalidChannelCount;
-
-        /* validate outputStreamInfo */
-        if( outputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        outputChannelCount = 0;
-    }
-
-    /* ... check that the sample rate exactly matches the ONE acceptable rate
-     * A: This rate isn't necessarily constant though? */
-
-#define ABS(x) ( (x) > 0 ? (x) : -(x) )
-    if( ABS(sampleRate - jackSr) > 1 )
-       return paInvalidSampleRate;
-#undef ABS
-
-    UNLESS( stream = (PaJackStream*)PaUtil_AllocateMemory( sizeof(PaJackStream) ), paInsufficientMemory );
-    ENSURE_PA( InitializeStream( stream, jackHostApi, inputChannelCount, outputChannelCount ) );
-
-    /* the blocking emulation, if necessary */
-    stream->isBlockingStream = !streamCallback;
-    if( stream->isBlockingStream )
-    {
-        float latency = 0.001; /* 1ms is the absolute minimum we support */
-        int   minimum_buffer_frames = 0;
-
-        if( inputParameters && inputParameters->suggestedLatency > latency )
-            latency = inputParameters->suggestedLatency;
-        else if( outputParameters && outputParameters->suggestedLatency > latency )
-            latency = outputParameters->suggestedLatency;
-
-        /* the latency the user asked for indicates the minimum buffer size in frames */
-        minimum_buffer_frames = (int) (latency * jack_get_sample_rate( jackHostApi->jack_client ));
-
-        /* we also need to be able to store at least three full jack buffers to avoid dropouts */
-        if( jackHostApi->jack_buffer_size * 3 > minimum_buffer_frames )
-            minimum_buffer_frames = jackHostApi->jack_buffer_size * 3;
-
-        /* setup blocking API data structures (FIXME: can fail) */
-	BlockingBegin( stream, minimum_buffer_frames );
-
-        /* install our own callback for the blocking API */
-        streamCallback = BlockingCallback;
-        userData = stream;
-
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &jackHostApi->blockingStreamInterface, streamCallback, userData );
-    }
-    else
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &jackHostApi->callbackStreamInterface, streamCallback, userData );
-    }
-    srInitialized = 1;
-    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, jackSr );
-
-    /* create the JACK ports.  We cannot connect them until audio
-     * processing begins */
-
-    /* Register a unique set of ports for this stream
-     * TODO: Robust allocation of new port names */
-
-    ofs = jackHostApi->inputBase;
-    for( i = 0; i < inputChannelCount; i++ )
-    {
-        snprintf( port_string, jack_port_name_size(), "in_%lu", ofs + i );
-        UNLESS( stream->local_input_ports[i] = jack_port_register(
-              jackHostApi->jack_client, port_string,
-              JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ), paInsufficientMemory );
-    }
-    jackHostApi->inputBase += inputChannelCount;
-
-    ofs = jackHostApi->outputBase;
-    for( i = 0; i < outputChannelCount; i++ )
-    {
-        snprintf( port_string, jack_port_name_size(), "out_%lu", ofs + i );
-        UNLESS( stream->local_output_ports[i] = jack_port_register(
-             jackHostApi->jack_client, port_string,
-             JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ), paInsufficientMemory );
-    }
-    jackHostApi->outputBase += outputChannelCount;
-
-    /* look up the jack_port_t's for the remote ports.  We could do
-     * this at stream start time, but doing it here ensures the
-     * name lookup only happens once. */
-
-    if( inputChannelCount > 0 )
-    {
-        int err = 0;
-        
-        /* ... remote output ports (that we input from) */
-        snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ inputParameters->device ]->name );
-        UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern,
-                                     NULL, JackPortIsOutput ), paUnanticipatedHostError );
-        for( i = 0; i < inputChannelCount && jack_ports[i]; i++ )
-        {
-            if( (stream->remote_output_ports[i] = jack_port_by_name(
-                 jackHostApi->jack_client, jack_ports[i] )) == NULL ) 
-            {
-                err = 1;
-                break;
-            }
-        }
-        free( jack_ports );
-        UNLESS( !err, paInsufficientMemory );
-
-        /* Fewer ports than expected? */
-        UNLESS( i == inputChannelCount, paInternalError );
-    }
-
-    if( outputChannelCount > 0 )
-    {
-        int err = 0;
-
-        /* ... remote input ports (that we output to) */
-        snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ outputParameters->device ]->name );
-        UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern,
-                                     NULL, JackPortIsInput ), paUnanticipatedHostError );
-        for( i = 0; i < outputChannelCount && jack_ports[i]; i++ )
-        {
-            if( (stream->remote_input_ports[i] = jack_port_by_name(
-                 jackHostApi->jack_client, jack_ports[i] )) == 0 )
-            {
-                err = 1;
-                break;
-            }
-        }
-        free( jack_ports );
-        UNLESS( !err , paInsufficientMemory );
-
-        /* Fewer ports than expected? */
-        UNLESS( i == outputChannelCount, paInternalError );
-    }
-
-    ENSURE_PA( PaUtil_InitializeBufferProcessor(
-                  &stream->bufferProcessor,
-                  inputChannelCount,
-                  inputSampleFormat,
-                  paFloat32,            /* hostInputSampleFormat */
-                  outputChannelCount,
-                  outputSampleFormat,
-                  paFloat32,            /* hostOutputSampleFormat */
-                  jackSr,
-                  streamFlags,
-                  framesPerBuffer,
-                  0,                            /* Ignored */
-                  paUtilUnknownHostBufferSize,  /* Buffer size may vary on JACK's discretion */
-                  streamCallback,
-                  userData ) );
-    bpInitialized = 1;
-
-    if( stream->num_incoming_connections > 0 )
-        stream->streamRepresentation.streamInfo.inputLatency = (jack_port_get_latency( stream->remote_output_ports[0] )
-                - jack_get_buffer_size( jackHostApi->jack_client )  /* One buffer is not counted as latency */
-            + PaUtil_GetBufferProcessorInputLatency( &stream->bufferProcessor )) / sampleRate;
-    if( stream->num_outgoing_connections > 0 )
-        stream->streamRepresentation.streamInfo.outputLatency = (jack_port_get_latency( stream->remote_input_ports[0] )
-                - jack_get_buffer_size( jackHostApi->jack_client )  /* One buffer is not counted as latency */
-            + PaUtil_GetBufferProcessorOutputLatency( &stream->bufferProcessor )) / sampleRate;
-
-    stream->streamRepresentation.streamInfo.sampleRate = jackSr;
-    stream->t0 = jack_frame_time( jackHostApi->jack_client );   /* A: Time should run from Pa_OpenStream */
-
-    ENSURE_PA( AddStream( stream ) );  /* Add to queue over opened streams */
-    
-    *s = (PaStream*)stream;
-
-    return result;
-
-error:
-    if( stream )
-        CleanUpStream( stream, srInitialized, bpInitialized );
-
-    return result;
-}
-
-/*
-    When CloseStream() is called, the multi-api layer ensures that
-    the stream has already been stopped or aborted.
-*/
-static PaError CloseStream( PaStream* s )
-{
-    PaError result = paNoError;
-    PaJackStream *stream = (PaJackStream*)s;
-
-    /* Remove this stream from the processing queue */
-    ENSURE_PA( RemoveStream( stream ) );
-
-error:
-    CleanUpStream( stream, 1, 1 );
-    return result;
-}
-
-static PaError RealProcess( PaJackStream *stream, jack_nframes_t frames )
-{
-    PaError result = paNoError;
-    PaStreamCallbackTimeInfo timeInfo = {0,0,0};
-    int chn;
-    int framesProcessed;
-    const double sr = jack_get_sample_rate( stream->jack_client );    /* Shouldn't change during the process callback */
-    PaStreamCallbackFlags cbFlags = 0;
-
-    /* If the user has returned !paContinue from the callback we'll want to flush the internal buffers,
-     * when these are empty we can finally mark the stream as inactive */
-    if( stream->callbackResult != paContinue &&
-            PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) )
-    {
-        stream->is_active = 0;
-        if( stream->streamRepresentation.streamFinishedCallback )
-            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
-        PA_DEBUG(( "%s: Callback finished\n", __FUNCTION__ ));
-
-        goto end;
-    }
-
-    timeInfo.currentTime = (jack_frame_time( stream->jack_client ) - stream->t0) / sr;
-    if( stream->num_incoming_connections > 0 )
-        timeInfo.inputBufferAdcTime = timeInfo.currentTime - jack_port_get_latency( stream->remote_output_ports[0] )
-            / sr;
-    if( stream->num_outgoing_connections > 0 )
-        timeInfo.outputBufferDacTime = timeInfo.currentTime + jack_port_get_latency( stream->remote_input_ports[0] )
-            / sr;
-
-    PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
-
-    if( stream->xrun )
-    {
-        /* XXX: Any way to tell which of these occurred? */
-        cbFlags = paOutputUnderflow | paInputOverflow;
-        stream->xrun = FALSE;
-    }
-    PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo,
-            cbFlags );
-
-    if( stream->num_incoming_connections > 0 )
-        PaUtil_SetInputFrameCount( &stream->bufferProcessor, frames );
-    if( stream->num_outgoing_connections > 0 )
-        PaUtil_SetOutputFrameCount( &stream->bufferProcessor, frames );
-
-    for( chn = 0; chn < stream->num_incoming_connections; chn++ )
-    {
-        jack_default_audio_sample_t *channel_buf = (jack_default_audio_sample_t*)
-            jack_port_get_buffer( stream->local_input_ports[chn],
-                    frames );
-
-        PaUtil_SetNonInterleavedInputChannel( &stream->bufferProcessor,
-                chn,
-                channel_buf );
-    }
-
-    for( chn = 0; chn < stream->num_outgoing_connections; chn++ )
-    {
-        jack_default_audio_sample_t *channel_buf = (jack_default_audio_sample_t*)
-            jack_port_get_buffer( stream->local_output_ports[chn],
-                    frames );
-
-        PaUtil_SetNonInterleavedOutputChannel( &stream->bufferProcessor,
-                chn,
-                channel_buf );
-    }
-
-    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor,
-            &stream->callbackResult );
-    /* We've specified a host buffer size mode where every frame should be consumed by the buffer processor */
-    assert( framesProcessed == frames );
-
-    PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
-
-end:
-    return result;
-}
-
-/* Alter the processing queue if necessary */
-static PaError UpdateQueue( PaJackHostApiRepresentation *hostApi )
-{
-    PaError result = paNoError;
-    int queueModified = 0;
-    const double jackSr = jack_get_sample_rate( hostApi->jack_client );
-    int err;
-
-    if( (err = pthread_mutex_trylock( &hostApi->mtx )) != 0 )
-    {
-        assert( err == EBUSY );
-        return paNoError;
-    }
-
-    if( hostApi->toAdd )
-    {
-        if( hostApi->processQueue )
-        {
-            PaJackStream *node = hostApi->processQueue;
-            /* Advance to end of queue */
-            while( node->next )
-                node = node->next;
-
-            node->next = hostApi->toAdd;
-        }
-        else
-            hostApi->processQueue = (PaJackStream *)hostApi->toAdd;
-
-        /* If necessary, update stream state */
-        if( hostApi->toAdd->streamRepresentation.streamInfo.sampleRate != jackSr )
-            UpdateSampleRate( hostApi->toAdd, jackSr );
-
-        hostApi->toAdd = NULL;
-        queueModified = 1;
-    }
-    if( hostApi->toRemove )
-    {
-        int removed = 0;
-        PaJackStream *node = hostApi->processQueue, *prev = NULL;
-        assert( hostApi->processQueue );
-
-        while( node )
-        {
-            if( node == hostApi->toRemove )
-            {
-                if( prev )
-                    prev->next = node->next;
-                else
-                    hostApi->processQueue = (PaJackStream *)node->next;
-
-                removed = 1;
-                break;
-            }
-
-            prev = node;
-            node = node->next;
-        }
-        UNLESS( removed, paInternalError );
-        hostApi->toRemove = NULL;
-        PA_DEBUG(( "%s: Removed stream from processing queue\n", __FUNCTION__ ));
-        queueModified = 1;
-    }
-
-    if( queueModified )
-    {
-        /* Signal that we've done what was asked of us */
-        ASSERT_CALL( pthread_cond_signal( &hostApi->cond ), 0 );
-    }
-
-error:
-    ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 );
-
-    return result;
-}
-
-static int JackCallback( jack_nframes_t frames, void *userData )
-{
-    PaError result = paNoError;
-    PaJackHostApiRepresentation *hostApi = (PaJackHostApiRepresentation *)userData;
-    PaJackStream *stream = NULL;
-    int xrun = hostApi->xrun;
-    hostApi->xrun = 0;
-
-    assert( hostApi );
-
-    ENSURE_PA( UpdateQueue( hostApi ) );
-
-    /* Process each stream */
-    stream = hostApi->processQueue;
-    for( ; stream; stream = stream->next )
-    {
-        if( xrun )  /* Don't override if already set */
-            stream->xrun = 1;
-
-        /* See if this stream is to be started */
-        if( stream->doStart )
-        {
-            /* If we can't obtain a lock, we'll try next time */
-            int err = pthread_mutex_trylock( &stream->hostApi->mtx );
-            if( !err )
-            {
-                if( stream->doStart )   /* Could potentially change before obtaining the lock */
-                {
-                    stream->is_active = 1;
-                    stream->doStart = 0;
-                    PA_DEBUG(( "%s: Starting stream\n", __FUNCTION__ ));
-                    ASSERT_CALL( pthread_cond_signal( &stream->hostApi->cond ), 0 );
-                    stream->callbackResult = paContinue;
-                    stream->isSilenced = 0;
-                }
-
-                ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 );
-            }
-            else
-                assert( err == EBUSY );
-        }
-        else if( stream->doStop || stream->doAbort )    /* Should we stop/abort stream? */
-        {
-            if( stream->callbackResult == paContinue )     /* Ok, make it stop */
-            {
-                PA_DEBUG(( "%s: Stopping stream\n", __FUNCTION__ ));
-                stream->callbackResult = stream->doStop ? paComplete : paAbort;
-            }
-        }
-
-        if( stream->is_active )
-            ENSURE_PA( RealProcess( stream, frames ) );
-        /* If we have just entered inactive state, silence output */
-        if( !stream->is_active && !stream->isSilenced )
-        {
-            int i;
-
-            /* Silence buffer after entering inactive state */
-            PA_DEBUG(( "Silencing the output\n" ));
-            for( i = 0; i < stream->num_outgoing_connections; ++i )
-            {
-                jack_default_audio_sample_t *buffer = jack_port_get_buffer( stream->local_output_ports[i], frames );
-                memset( buffer, 0, sizeof (jack_default_audio_sample_t) * frames );
-            }
-
-            stream->isSilenced = 1;
-        }
-
-        if( stream->doStop || stream->doAbort )
-        {
-            /* See if RealProcess has acted on the request */
-            if( !stream->is_active )   /* Ok, signal to the main thread that we've carried out the operation */
-            {
-                /* If we can't obtain a lock, we'll try next time */
-                int err = pthread_mutex_trylock( &stream->hostApi->mtx );
-                if( !err )
-                {
-                    stream->doStop = stream->doAbort = 0;
-                    ASSERT_CALL( pthread_cond_signal( &stream->hostApi->cond ), 0 );
-                    ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 );
-                }
-                else
-                    assert( err == EBUSY );
-            }
-        }
-    }
-
-    return 0;
-error:
-    return -1;
-}
-
-static PaError StartStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaJackStream *stream = (PaJackStream*)s;
-    int i;
-
-    /* Ready the processor */
-    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
-
-    /* connect the ports */
-
-    /* NOTE: I would rather use jack_port_connect which uses jack_port_t's
-     * instead of port names, but it is not implemented yet. */
-    if( stream->num_incoming_connections > 0 )
-    {
-        for( i = 0; i < stream->num_incoming_connections; i++ )
-            UNLESS( jack_connect( stream->jack_client,
-                    jack_port_name( stream->remote_output_ports[i] ),
-                    jack_port_name( stream->local_input_ports[i] ) ) == 0, paUnanticipatedHostError );
-    }
-
-    if( stream->num_outgoing_connections > 0 )
-    {
-        for( i = 0; i < stream->num_outgoing_connections; i++ )
-            UNLESS( jack_connect( stream->jack_client,
-                    jack_port_name( stream->local_output_ports[i] ),
-                    jack_port_name( stream->remote_input_ports[i] ) ) == 0, paUnanticipatedHostError );
-    }
-
-    stream->xrun = FALSE;
-
-    /* Enable processing */
-
-    ASSERT_CALL( pthread_mutex_lock( &stream->hostApi->mtx ), 0 );
-    stream->doStart = 1;
-
-    /* Wait for stream to be started */
-    result = WaitCondition( stream->hostApi );
-    /*
-    do
-    {
-        err = pthread_cond_timedwait( &stream->hostApi->cond, &stream->hostApi->mtx, &ts );
-    } while( !stream->is_active && !err );
-    */
-    if( result != paNoError )   /* Something went wrong, call off the stream start */
-    {
-        stream->doStart = 0;
-        stream->is_active = 0;  /* Cancel any processing */
-    }
-    ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 );
-
-    ENSURE_PA( result );
-
-    stream->is_running = TRUE;
-    PA_DEBUG(( "%s: Stream started\n", __FUNCTION__ ));
-
-error:
-    return result;
-}
-
-static PaError RealStop( PaJackStream *stream, int abort )
-{
-    PaError result = paNoError;
-    int i;
-
-    if( stream->isBlockingStream )
-        BlockingWaitEmpty ( stream );
-
-    ASSERT_CALL( pthread_mutex_lock( &stream->hostApi->mtx ), 0 );
-    if( abort )
-        stream->doAbort = 1;
-    else
-        stream->doStop = 1;
-
-    /* Wait for stream to be stopped */
-    result = WaitCondition( stream->hostApi );
-    ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 );
-    ENSURE_PA( result );
-
-    UNLESS( !stream->is_active, paInternalError );
-    
-    PA_DEBUG(( "%s: Stream stopped\n", __FUNCTION__ ));
-
-error:
-    stream->is_running = FALSE;
-
-    /* Disconnect ports belonging to this stream */
-
-    if( !stream->hostApi->jackIsDown )  /* XXX: Well? */
-    {
-        if( stream->num_incoming_connections > 0 )
-        {
-            for( i = 0; i < stream->num_incoming_connections; i++ )
-                UNLESS( !jack_disconnect( stream->jack_client,
-                            jack_port_name( stream->remote_output_ports[i] ),
-                            jack_port_name( stream->local_input_ports[i] ) ), paUnanticipatedHostError );
-        }
-        if( stream->num_outgoing_connections > 0 )
-        {
-            for( i = 0; i < stream->num_outgoing_connections; i++ )
-                UNLESS( !jack_disconnect( stream->jack_client,
-                            jack_port_name( stream->local_output_ports[i] ),
-                            jack_port_name( stream->remote_input_ports[i] ) ), paUnanticipatedHostError );
-        }
-    }
-
-    return result;
-}
-
-static PaError StopStream( PaStream *s )
-{
-    assert(s);
-    return RealStop( (PaJackStream *)s, 0 );
-}
-
-static PaError AbortStream( PaStream *s )
-{
-    assert(s);
-    return RealStop( (PaJackStream *)s, 1 );
-}
-
-static PaError IsStreamStopped( PaStream *s )
-{
-    PaJackStream *stream = (PaJackStream*)s;
-    return !stream->is_running;
-}
-
-
-static PaError IsStreamActive( PaStream *s )
-{
-    PaJackStream *stream = (PaJackStream*)s;
-    return stream->is_active;
-}
-
-
-static PaTime GetStreamTime( PaStream *s )
-{
-    PaJackStream *stream = (PaJackStream*)s;
-
-    /* A: Is this relevant?? --> TODO: what if we're recording-only? */
-    return (jack_frame_time( stream->jack_client ) - stream->t0) / (PaTime)jack_get_sample_rate( stream->jack_client );
-}
-
-
-static double GetStreamCpuLoad( PaStream* s )
-{
-    PaJackStream *stream = (PaJackStream*)s;
-    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
-}
diff --git a/portaudio/pa_linux_alsa/CVS/Entries b/portaudio/pa_linux_alsa/CVS/Entries
deleted file mode 100644
index 6bfbe173d..000000000
--- a/portaudio/pa_linux_alsa/CVS/Entries
+++ /dev/null
@@ -1,3 +0,0 @@
-/pa_linux_alsa.c/1.1.2.92/Wed Mar 22 19:36:04 2006//Tv19-devel
-/pa_linux_alsa.h/1.1.2.12/Sat Sep 25 14:15:25 2004//Tv19-devel
-D
diff --git a/portaudio/pa_linux_alsa/CVS/Repository b/portaudio/pa_linux_alsa/CVS/Repository
deleted file mode 100644
index 26c4919b4..000000000
--- a/portaudio/pa_linux_alsa/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_linux_alsa
diff --git a/portaudio/pa_linux_alsa/CVS/Root b/portaudio/pa_linux_alsa/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_linux_alsa/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_linux_alsa/CVS/Tag b/portaudio/pa_linux_alsa/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_linux_alsa/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_linux_alsa/pa_linux_alsa.c b/portaudio/pa_linux_alsa/pa_linux_alsa.c
deleted file mode 100644
index 2f88fc2fa..000000000
--- a/portaudio/pa_linux_alsa/pa_linux_alsa.c
+++ /dev/null
@@ -1,3682 +0,0 @@
-/*
- * $Id: pa_linux_alsa.c,v 1.1.2.92 2006/03/22 19:36:04 aknudsen Exp $
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com
- * ALSA implementation by Joshua Haberman and Arve Knudsen
- *
- * Copyright (c) 2002 Joshua Haberman <joshua@haberman.com>
- * Copyright (c) 2005-2006 Arve Knudsen <aknuds-1@broadpark.no>
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#define ALSA_PCM_NEW_HW_PARAMS_API
-#define ALSA_PCM_NEW_SW_PARAMS_API
-#include <alsa/asoundlib.h>
-#undef ALSA_PCM_NEW_HW_PARAMS_API
-#undef ALSA_PCM_NEW_SW_PARAMS_API
-
-#include <sys/poll.h>
-#include <string.h> /* strlen() */
-#include <limits.h>
-#include <math.h>
-#include <pthread.h>
-#include <signal.h>
-#include <time.h>
-#include <sys/mman.h>
-#include <signal.h> /* For sig_atomic_t */
-
-#include "portaudio.h"
-#include "pa_util.h"
-#include "../pa_unix/pa_unix_util.h"
-#include "pa_allocation.h"
-#include "pa_hostapi.h"
-#include "pa_stream.h"
-#include "pa_cpuload.h"
-#include "pa_process.h"
-
-#include "pa_linux_alsa.h"
-
-/* Check return value of ALSA function, and map it to PaError */
-#define ENSURE_(expr, code) \
-    do { \
-        if( UNLIKELY( (aErr_ = (expr)) < 0 ) ) \
-        { \
-            /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \
-            if( (code) == paUnanticipatedHostError && pthread_self() != callbackThread_ ) \
-            { \
-                PaUtil_SetLastHostErrorInfo( paALSA, aErr_, snd_strerror( aErr_ ) ); \
-            } \
-            PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \
-            if( (code) == paUnanticipatedHostError ) \
-                PA_DEBUG(( "Host error description: %s\n", snd_strerror( aErr_ ) )); \
-            result = (code); \
-            goto error; \
-        } \
-    } while( 0 );
-
-#define ENSURE_SYSTEM_(expr, success) \
-    do { \
-        if( UNLIKELY( (aErr_ = (expr)) != success ) ) \
-        { \
-            /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \
-            if( pthread_self() != callbackThread_ ) \
-            { \
-                PaUtil_SetLastHostErrorInfo( paALSA, aErr_, strerror( aErr_ ) ); \
-            } \
-            PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \
-            result = paUnanticipatedHostError; \
-            goto error; \
-        } \
-    } while( 0 );
-
-#define ASSERT_CALL_(expr, success) \
-    aErr_ = (expr); \
-    assert( success == aErr_ );
-
-static int aErr_;               /* Used with ENSURE_ */
-static pthread_t callbackThread_;
-
-typedef enum
-{
-    StreamDirection_In,
-    StreamDirection_Out
-} StreamDirection;
-
-/* Threading utility struct */
-typedef struct PaAlsaThreading
-{
-    pthread_t watchdogThread;
-    pthread_t callbackThread;
-    int watchdogRunning;
-    int rtSched;
-    int rtPrio;
-    int useWatchdog;
-    unsigned long throttledSleepTime;
-    volatile PaTime callbackTime;
-    volatile PaTime callbackCpuTime;
-    PaUtilCpuLoadMeasurer *cpuLoadMeasurer;
-} PaAlsaThreading;
-
-typedef struct
-{
-    PaSampleFormat hostSampleFormat;
-    unsigned long framesPerBuffer;
-    int numUserChannels, numHostChannels;
-    int userInterleaved, hostInterleaved;
-
-    snd_pcm_t *pcm;
-    snd_pcm_uframes_t bufferSize;
-    snd_pcm_format_t nativeFormat;
-    unsigned int nfds;
-    int ready;  /* Marked ready from poll */
-    void **userBuffers;
-    snd_pcm_uframes_t offset;
-    StreamDirection streamDir;
-
-    snd_pcm_channel_area_t *channelAreas;  /* Needed for channel adaption */
-} PaAlsaStreamComponent;
-
-/* Implementation specific stream structure */
-typedef struct PaAlsaStream
-{
-    PaUtilStreamRepresentation streamRepresentation;
-    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
-    PaUtilBufferProcessor bufferProcessor;
-    PaAlsaThreading threading;
-
-    unsigned long framesPerUserBuffer, maxFramesPerHostBuffer;
-
-    int primeBuffers;
-    int callbackMode;              /* bool: are we running in callback mode? */
-    int pcmsSynced;	            /* Have we successfully synced pcms */
-
-    /* the callback thread uses these to poll the sound device(s), waiting
-     * for data to be ready/available */
-    struct pollfd* pfds;
-    int pollTimeout;
-
-    /* Used in communication between threads */
-    volatile sig_atomic_t callback_finished; /* bool: are we in the "callback finished" state? */
-    volatile sig_atomic_t callbackAbort;    /* Drop frames? */
-    volatile sig_atomic_t callbackStop;     /* Signal a stop */
-    volatile sig_atomic_t isActive;         /* Is stream in active state? (Between StartStream and StopStream || !paContinue) */
-    pthread_mutex_t stateMtx;               /* Used to synchronize access to stream state */
-    pthread_mutex_t startMtx;               /* Used to synchronize stream start in callback mode */
-    pthread_cond_t startCond;               /* Wait untill audio is started in callback thread */
-
-    int neverDropInput;
-
-    PaTime underrun;
-    PaTime overrun;
-
-    PaAlsaStreamComponent capture, playback;
-}
-PaAlsaStream;
-
-/* PaAlsaHostApiRepresentation - host api datastructure specific to this implementation */
-
-typedef struct PaAlsaHostApiRepresentation
-{
-    PaUtilHostApiRepresentation baseHostApiRep;
-    PaUtilStreamInterface callbackStreamInterface;
-    PaUtilStreamInterface blockingStreamInterface;
-
-    PaUtilAllocationGroup *allocations;
-
-    PaHostApiIndex hostApiIndex;
-}
-PaAlsaHostApiRepresentation;
-
-typedef struct PaAlsaDeviceInfo
-{
-    PaDeviceInfo baseDeviceInfo;
-    char *alsaName;
-    int isPlug;
-    int minInputChannels;
-    int minOutputChannels;
-}
-PaAlsaDeviceInfo;
-
-/* Threading utilities */
-
-static void InitializeThreading( PaAlsaThreading *th, PaUtilCpuLoadMeasurer *clm )
-{
-    th->watchdogRunning = 0;
-    th->rtSched = 0;
-    th->callbackTime = 0;
-    th->callbackCpuTime = 0;
-    th->useWatchdog = 1;
-    th->throttledSleepTime = 0;
-    th->cpuLoadMeasurer = clm;
-
-    th->rtPrio = (sched_get_priority_max( SCHED_FIFO ) - sched_get_priority_min( SCHED_FIFO )) / 2
-            + sched_get_priority_min( SCHED_FIFO );
-}
-
-static PaError KillCallbackThread( PaAlsaThreading *th, int wait, PaError *exitResult, PaError *watchdogExitResult )
-{
-    PaError result = paNoError;
-    void *pret;
-
-    if( exitResult )
-        *exitResult = paNoError;
-    if( watchdogExitResult )
-        *watchdogExitResult = paNoError;
-
-    if( th->watchdogRunning )
-    {
-        pthread_cancel( th->watchdogThread );
-        ENSURE_SYSTEM_( pthread_join( th->watchdogThread, &pret ), 0 );
-
-        if( pret && pret != PTHREAD_CANCELED )
-        {
-            if( watchdogExitResult )
-                *watchdogExitResult = *(PaError *) pret;
-            free( pret );
-        }
-    }
-
-    /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */
-    /* TODO: Make join time out */
-    if( !wait )
-    {
-        PA_DEBUG(( "%s: Canceling thread %d\n", __FUNCTION__, th->callbackThread ));
-        pthread_cancel( th->callbackThread );   /* XXX: Safe to call this if the thread has exited on its own? */
-    }
-    PA_DEBUG(( "%s: Joining thread %d\n", __FUNCTION__, th->callbackThread ));
-    ENSURE_SYSTEM_( pthread_join( th->callbackThread, &pret ), 0 );
-
-    if( pret && pret != PTHREAD_CANCELED )
-    {
-        if( exitResult )
-            *exitResult = *(PaError *) pret;
-        free( pret );
-    }
-
-error:
-    return result;
-}
-
-/** Lock a pthread_mutex_t.
- *
- * @concern ThreadCancellation We're disabling thread cancellation while the thread is holding a lock, so mutexes are 
- * properly unlocked at termination time.
- */
-static PaError LockMutex( pthread_mutex_t *mtx )
-{
-    PaError result = paNoError;
-    int oldState;
-    
-    ENSURE_SYSTEM_( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldState ), 0 );
-    ENSURE_SYSTEM_( pthread_mutex_lock( mtx ), 0 );
-
-error:
-    return result;
-}
-
-/** Unlock a pthread_mutex_t.
- *
- * @concern ThreadCancellation Thread cancellation is enabled again after the mutex is properly unlocked.
- */
-static PaError UnlockMutex( pthread_mutex_t *mtx )
-{
-    PaError result = paNoError;
-    int oldState;
-
-    ENSURE_SYSTEM_( pthread_mutex_unlock( mtx ), 0 );
-    ENSURE_SYSTEM_( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldState ), 0 );
-
-error:
-    return result;
-}
-
-static void OnWatchdogExit( void *userData )
-{
-    PaAlsaThreading *th = (PaAlsaThreading *) userData;
-    struct sched_param spm = { 0 };
-    assert( th );
-
-    ASSERT_CALL_( pthread_setschedparam( th->callbackThread, SCHED_OTHER, &spm ), 0 );    /* Lower before exiting */
-    PA_DEBUG(( "Watchdog exiting\n" ));
-}
-
-static PaError BoostPriority( PaAlsaThreading *th )
-{
-    PaError result = paNoError;
-    struct sched_param spm = { 0 };
-    spm.sched_priority = th->rtPrio;
-
-    assert( th );
-
-    if( pthread_setschedparam( th->callbackThread, SCHED_FIFO, &spm ) != 0 )
-    {
-        PA_UNLESS( errno == EPERM, paInternalError );  /* Lack permission to raise priority */
-        PA_DEBUG(( "Failed bumping priority\n" ));
-        result = 0;
-    }
-    else
-        result = 1; /* Success */
-error:
-    return result;
-}
-
-static void *WatchdogFunc( void *userData )
-{
-    PaError result = paNoError, *pres = NULL;
-    int err;
-    PaAlsaThreading *th = (PaAlsaThreading *) userData;
-    unsigned intervalMsec = 500;
-    const PaTime maxSeconds = 3.;   /* Max seconds between callbacks */
-    PaTime timeThen = PaUtil_GetTime(), timeNow, timeElapsed, cpuTimeThen, cpuTimeNow, cpuTimeElapsed;
-    double cpuLoad, avgCpuLoad = 0.;
-    int throttled = 0;
-
-    assert( th );
-
-    /* Execute OnWatchdogExit when exiting */
-    pthread_cleanup_push( &OnWatchdogExit, th );
-
-    /* Boost priority of callback thread */
-    PA_ENSURE( result = BoostPriority( th ) );
-    if( !result )
-    {
-        /* Boost failed, might as well exit */
-        pthread_exit( NULL );
-    }
-
-    cpuTimeThen = th->callbackCpuTime;
-    {
-        int policy;
-        struct sched_param spm = { 0 };
-        pthread_getschedparam( pthread_self(), &policy, &spm );
-        PA_DEBUG(( "%s: Watchdog priority is %d\n", __FUNCTION__, spm.sched_priority ));
-    }
-
-    while( 1 )
-    {
-        double lowpassCoeff = 0.9, lowpassCoeff1 = 0.99999 - lowpassCoeff;
-        
-        /* Test before and after in case whatever underlying sleep call isn't interrupted by pthread_cancel */
-        pthread_testcancel();
-        Pa_Sleep( intervalMsec );
-        pthread_testcancel();
-
-        if( PaUtil_GetTime() - th->callbackTime > maxSeconds )
-        {
-            PA_DEBUG(( "Watchdog: Terminating callback thread\n" ));
-            /* Tell thread to terminate */
-            err = pthread_kill( th->callbackThread, SIGKILL );
-            pthread_exit( NULL );
-        }
-
-        PA_DEBUG(( "%s: PortAudio reports CPU load: %g\n", __FUNCTION__, PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) ));
-
-        /* Check if we should throttle, or unthrottle :P */
-        cpuTimeNow = th->callbackCpuTime;
-        cpuTimeElapsed = cpuTimeNow - cpuTimeThen;
-        cpuTimeThen = cpuTimeNow;
-
-        timeNow = PaUtil_GetTime();
-        timeElapsed = timeNow - timeThen;
-        timeThen = timeNow;
-        cpuLoad = cpuTimeElapsed / timeElapsed;
-        avgCpuLoad = avgCpuLoad * lowpassCoeff + cpuLoad * lowpassCoeff1;
-        /*
-        if( throttled )
-            PA_DEBUG(( "Watchdog: CPU load: %g, %g\n", avgCpuLoad, cpuTimeElapsed ));
-            */
-        if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) > .925 )
-        {
-            static int policy;
-            static struct sched_param spm = { 0 };
-            static const struct sched_param defaultSpm = { 0 };
-            PA_DEBUG(( "%s: Throttling audio thread, priority %d\n", __FUNCTION__, spm.sched_priority ));
-
-            pthread_getschedparam( th->callbackThread, &policy, &spm );
-            if( !pthread_setschedparam( th->callbackThread, SCHED_OTHER, &defaultSpm ) )
-            {
-                throttled = 1;
-            }
-            else
-                PA_DEBUG(( "Watchdog: Couldn't lower priority of audio thread: %s\n", strerror( errno ) ));
-
-            /* Give other processes a go, before raising priority again */
-            PA_DEBUG(( "%s: Watchdog sleeping for %lu msecs before unthrottling\n", __FUNCTION__, th->throttledSleepTime ));
-            Pa_Sleep( th->throttledSleepTime );
-
-            /* Reset callback priority */
-            if( pthread_setschedparam( th->callbackThread, SCHED_FIFO, &spm ) != 0 )
-            {
-                PA_DEBUG(( "%s: Couldn't raise priority of audio thread: %s\n", __FUNCTION__, strerror( errno ) ));
-            }
-
-            if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) >= .99 )
-                intervalMsec = 50;
-            else
-                intervalMsec = 100;
-
-            /*
-            lowpassCoeff = .97;
-            lowpassCoeff1 = .99999 - lowpassCoeff;
-            */
-        }
-        else if( throttled && avgCpuLoad < .8 )
-        {
-            intervalMsec = 500;
-            throttled = 0;
-
-            /*
-            lowpassCoeff = .9;
-            lowpassCoeff1 = .99999 - lowpassCoeff;
-            */
-        }
-    }
-
-    pthread_cleanup_pop( 1 );   /* Execute cleanup on exit */
-
-error:
-    /* Shouldn't get here in the normal case */
-
-    /* Pass on error code */
-    pres = malloc( sizeof (PaError) );
-    *pres = result;
-    
-    pthread_exit( pres );
-}
-
-static PaError CreateCallbackThread( PaAlsaThreading *th, void *(*callbackThreadFunc)( void * ), PaStream *s )
-{
-    PaError result = paNoError;
-    pthread_attr_t attr;
-    int started = 0;
-
-#if defined _POSIX_MEMLOCK && (_POSIX_MEMLOCK != -1)
-    if( th->rtSched )
-    {
-        if( mlockall( MCL_CURRENT | MCL_FUTURE ) < 0 )
-        {
-            int savedErrno = errno;             /* In case errno gets overwritten */
-            assert( savedErrno != EINVAL );     /* Most likely a programmer error */
-            PA_UNLESS( (savedErrno == EPERM), paInternalError );
-            PA_DEBUG(( "%s: Failed locking memory\n", __FUNCTION__ ));
-        }
-        else
-            PA_DEBUG(( "%s: Successfully locked memory\n", __FUNCTION__ ));
-    }
-#endif
-
-    PA_UNLESS( !pthread_attr_init( &attr ), paInternalError );
-    /* Priority relative to other processes */
-    PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError );   
-
-    PA_UNLESS( !pthread_create( &th->callbackThread, &attr, callbackThreadFunc, s ), paInternalError );
-    started = 1;
-
-    if( th->rtSched )
-    {
-        if( th->useWatchdog )
-        {
-            int err;
-            struct sched_param wdSpm = { 0 };
-            /* Launch watchdog, watchdog sets callback thread priority */
-            int prio = PA_MIN( th->rtPrio + 4, sched_get_priority_max( SCHED_FIFO ) );
-            wdSpm.sched_priority = prio;
-
-            PA_UNLESS( !pthread_attr_init( &attr ), paInternalError );
-            PA_UNLESS( !pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ), paInternalError );
-            PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError );
-            PA_UNLESS( !pthread_attr_setschedpolicy( &attr, SCHED_FIFO ), paInternalError );
-            PA_UNLESS( !pthread_attr_setschedparam( &attr, &wdSpm ), paInternalError );
-            if( (err = pthread_create( &th->watchdogThread, &attr, &WatchdogFunc, th )) )
-            {
-                PA_UNLESS( err == EPERM, paInternalError );
-                /* Permission error, go on without realtime privileges */
-                PA_DEBUG(( "Failed bumping priority\n" ));
-            }
-            else
-            {
-                int policy;
-                th->watchdogRunning = 1;
-                ENSURE_SYSTEM_( pthread_getschedparam( th->watchdogThread, &policy, &wdSpm ), 0 );
-                /* Check if priority is right, policy could potentially differ from SCHED_FIFO (but that's alright) */
-                if( wdSpm.sched_priority != prio )
-                {
-                    PA_DEBUG(( "Watchdog priority not set correctly (%d)\n", wdSpm.sched_priority ));
-                    PA_ENSURE( paInternalError );
-                }
-            }
-        }
-        else
-            PA_ENSURE( BoostPriority( th ) );
-    }
-
-end:
-    return result;
-error:
-    if( started )
-        KillCallbackThread( th, 0, NULL, NULL );
-
-    goto end;
-}
-
-static void CallbackUpdate( PaAlsaThreading *th )
-{
-    th->callbackTime = PaUtil_GetTime();
-    th->callbackCpuTime = PaUtil_GetCpuLoad( th->cpuLoadMeasurer );
-}
-
-/* prototypes for functions declared in this file */
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate );
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *callback,
-                           void *userData );
-static PaError CloseStream( PaStream* stream );
-static PaError StartStream( PaStream *stream );
-static PaError StopStream( PaStream *stream );
-static PaError AbortStream( PaStream *stream );
-static PaError IsStreamStopped( PaStream *s );
-static PaError IsStreamActive( PaStream *stream );
-static PaTime GetStreamTime( PaStream *stream );
-static double GetStreamCpuLoad( PaStream* stream );
-static PaError BuildDeviceList( PaAlsaHostApiRepresentation *hostApi );
-static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate );
-static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate );
-
-/* Callback prototypes */
-static void *CallbackThreadFunc( void *userData );
-
-/* Blocking prototypes */
-static signed long GetStreamReadAvailable( PaStream* s );
-static signed long GetStreamWriteAvailable( PaStream* s );
-static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
-static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
-
-
-static const PaAlsaDeviceInfo *GetDeviceInfo( const PaUtilHostApiRepresentation *hostApi, int device )
-{
-    return (const PaAlsaDeviceInfo *)hostApi->deviceInfos[device];
-}
-
-static void AlsaErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...)
-{
-}
-
-PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
-{
-    PaError result = paNoError;
-    PaAlsaHostApiRepresentation *alsaHostApi = NULL;
-
-    PA_UNLESS( alsaHostApi = (PaAlsaHostApiRepresentation*) PaUtil_AllocateMemory(
-                sizeof(PaAlsaHostApiRepresentation) ), paInsufficientMemory );
-    PA_UNLESS( alsaHostApi->allocations = PaUtil_CreateAllocationGroup(), paInsufficientMemory );
-    alsaHostApi->hostApiIndex = hostApiIndex;
-
-    *hostApi = (PaUtilHostApiRepresentation*)alsaHostApi;
-    (*hostApi)->info.structVersion = 1;
-    (*hostApi)->info.type = paALSA;
-    (*hostApi)->info.name = "ALSA";
-
-    (*hostApi)->Terminate = Terminate;
-    (*hostApi)->OpenStream = OpenStream;
-    (*hostApi)->IsFormatSupported = IsFormatSupported;
-
-    ENSURE_( snd_lib_error_set_handler(AlsaErrorHandler), paUnanticipatedHostError );
-
-    PA_ENSURE( BuildDeviceList( alsaHostApi ) );
-
-    PaUtil_InitializeStreamInterface( &alsaHostApi->callbackStreamInterface,
-                                      CloseStream, StartStream,
-                                      StopStream, AbortStream,
-                                      IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, GetStreamCpuLoad,
-                                      PaUtil_DummyRead, PaUtil_DummyWrite,
-                                      PaUtil_DummyGetReadAvailable,
-                                      PaUtil_DummyGetWriteAvailable );
-
-    PaUtil_InitializeStreamInterface( &alsaHostApi->blockingStreamInterface,
-                                      CloseStream, StartStream,
-                                      StopStream, AbortStream,
-                                      IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
-                                      ReadStream, WriteStream,
-                                      GetStreamReadAvailable,
-                                      GetStreamWriteAvailable );
-
-    return result;
-
-error:
-    if( alsaHostApi )
-    {
-        if( alsaHostApi->allocations )
-        {
-            PaUtil_FreeAllAllocations( alsaHostApi->allocations );
-            PaUtil_DestroyAllocationGroup( alsaHostApi->allocations );
-        }
-
-        PaUtil_FreeMemory( alsaHostApi );
-    }
-
-    return result;
-}
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
-{
-    PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi;
-
-    assert( hostApi );
-
-    if( alsaHostApi->allocations )
-    {
-        PaUtil_FreeAllAllocations( alsaHostApi->allocations );
-        PaUtil_DestroyAllocationGroup( alsaHostApi->allocations );
-    }
-
-    PaUtil_FreeMemory( alsaHostApi );
-    snd_config_update_free_global();
-}
-
-/** Determine max channels and default latencies.
- *
- * This function provides functionality to grope an opened (might be opened for capture or playback) pcm device for 
- * traits like max channels, suitable default latencies and default sample rate. Upon error, max channels is set to zero,
- * and a suitable result returned. The device is closed before returning.
- */
-static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, int openBlocking,
-        PaAlsaDeviceInfo* devInfo, int* canMmap )
-{
-    PaError result = paNoError;
-    snd_pcm_hw_params_t *hwParams;
-    snd_pcm_uframes_t lowLatency = 512, highLatency = 2048;
-    unsigned int minChans, maxChans;
-    int* minChannels, * maxChannels;
-    double * defaultLowLatency, * defaultHighLatency, * defaultSampleRate =
-        &devInfo->baseDeviceInfo.defaultSampleRate;
-    double defaultSr = *defaultSampleRate;
-
-    assert( pcm );
-
-    if( StreamDirection_In == mode )
-    {
-        minChannels = &devInfo->minInputChannels;
-        maxChannels = &devInfo->baseDeviceInfo.maxInputChannels;
-        defaultLowLatency = &devInfo->baseDeviceInfo.defaultLowInputLatency;
-        defaultHighLatency = &devInfo->baseDeviceInfo.defaultHighInputLatency;
-    }
-    else
-    {
-        minChannels = &devInfo->minOutputChannels;
-        maxChannels = &devInfo->baseDeviceInfo.maxOutputChannels;
-        defaultLowLatency = &devInfo->baseDeviceInfo.defaultLowOutputLatency;
-        defaultHighLatency = &devInfo->baseDeviceInfo.defaultHighOutputLatency;
-    }
-
-    ENSURE_( snd_pcm_nonblock( pcm, 0 ), paUnanticipatedHostError );
-
-    snd_pcm_hw_params_alloca( &hwParams );
-    snd_pcm_hw_params_any( pcm, hwParams );
-
-    *canMmap = snd_pcm_hw_params_test_access( pcm, hwParams, SND_PCM_ACCESS_MMAP_INTERLEAVED ) >= 0 ||
-            snd_pcm_hw_params_test_access( pcm, hwParams, SND_PCM_ACCESS_MMAP_NONINTERLEAVED ) >= 0;
-
-    if( defaultSr >= 0 )
-    {
-        /* Could be that the device opened in one mode supports samplerates that the other mode wont have,
-         * so try again .. */
-        if( SetApproximateSampleRate( pcm, hwParams, defaultSr ) < 0 )
-        {
-            defaultSr = -1.;
-            PA_DEBUG(( "%s: Original default samplerate failed, trying again ..\n", __FUNCTION__ ));
-        }
-    }
-
-    if( defaultSr < 0. )           /* Default sample rate not set */
-    {
-        unsigned int sampleRate = 44100;        /* Will contain approximate rate returned by alsa-lib */
-        if( snd_pcm_hw_params_set_rate_near( pcm, hwParams, &sampleRate, NULL ) < 0)
-        {
-            result = paUnanticipatedHostError;
-            goto error;
-        }
-        ENSURE_( GetExactSampleRate( hwParams, &defaultSr ), paUnanticipatedHostError );
-    }
-    
-    ENSURE_( snd_pcm_hw_params_get_channels_min( hwParams, &minChans ), paUnanticipatedHostError );
-    ENSURE_( snd_pcm_hw_params_get_channels_max( hwParams, &maxChans ), paUnanticipatedHostError );
-    assert( maxChans <= INT_MAX );
-    assert( maxChans > 0 );    /* Weird linking issue could cause wrong version of ALSA symbols to be called,
-                                   resulting in zeroed values */
-
-    /* XXX: Limit to sensible number (ALSA plugins accept a crazy amount of channels)? */
-    if( isPlug && maxChans > 128 )
-    {
-        maxChans = 128;
-        PA_DEBUG(( "%s: Limiting number of plugin channels to %u\n", __FUNCTION__, maxChans ));
-    }
-
-    /* TWEAKME:
-     *
-     * Giving values for default min and max latency is not
-     * straightforward.  Here are our objectives:
-     *
-     *         * for low latency, we want to give the lowest value
-     *         that will work reliably.  This varies based on the
-     *         sound card, kernel, CPU, etc.  I think it is better
-     *         to give sub-optimal latency than to give a number
-     *         too low and cause dropouts.  My conservative
-     *         estimate at this point is to base it on 4096-sample
-     *         latency at 44.1 kHz, which gives a latency of 23ms.
-     *         * for high latency we want to give a large enough
-     *         value that dropouts are basically impossible.  This
-     *         doesn't really require as much tweaking, since
-     *         providing too large a number will just cause us to
-     *         select the nearest setting that will work at stream
-     *         config time.
-     */
-    ENSURE_( snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &lowLatency ), paUnanticipatedHostError );
-
-    /* Have to reset hwParams, to set new buffer size */
-    ENSURE_( snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError ); 
-    ENSURE_( snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &highLatency ), paUnanticipatedHostError );
-
-    *minChannels = (int)minChans;
-    *maxChannels = (int)maxChans;
-    *defaultSampleRate = defaultSr;
-    *defaultLowLatency = (double) lowLatency / *defaultSampleRate;
-    *defaultHighLatency = (double) highLatency / *defaultSampleRate;
-
-end:
-    snd_pcm_close( pcm );
-    return result;
-
-error:
-    goto end;
-}
-
-/* Initialize device info with invalid values (maxInputChannels and maxOutputChannels are set to zero since these indicate
- * wether input/output is available) */
-static void InitializeDeviceInfo( PaDeviceInfo *deviceInfo )
-{
-    deviceInfo->structVersion = -1;
-    deviceInfo->name = NULL;
-    deviceInfo->hostApi = -1;
-    deviceInfo->maxInputChannels = 0;
-    deviceInfo->maxOutputChannels = 0;
-    deviceInfo->defaultLowInputLatency = -1.;
-    deviceInfo->defaultLowOutputLatency = -1.;
-    deviceInfo->defaultHighInputLatency = -1.;
-    deviceInfo->defaultHighOutputLatency = -1.;
-    deviceInfo->defaultSampleRate = -1.;
-}
-
-/* Helper struct */
-typedef struct
-{
-    char *alsaName;
-    char *name;
-    int isPlug;
-    int hasPlayback;
-    int hasCapture;
-} DeviceNames;
-
-static PaError PaAlsa_StrDup( PaAlsaHostApiRepresentation *alsaApi,
-        char **dst,
-        const char *src)
-{
-    PaError result = paNoError;
-    int len = strlen( src ) + 1;
-
-    /* PA_DEBUG(("PaStrDup %s %d\n", src, len)); */
-
-    PA_UNLESS( *dst = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ),
-            paInsufficientMemory );
-    strncpy( *dst, src, len );
-
-error:
-    return result;
-}
-
-/* Disregard some standard plugins
- */
-static int IgnorePlugin( const char *pluginId )
-{
-    /* XXX: dmix and default ignored because after opening and closing, they seem to keep hogging resources.
-     */
-    static const char *ignoredPlugins[] = {"hw", "plughw", "plug", "dsnoop", "tee",
-        "file", "null", "shm", "cards", "dmix", "default", NULL};
-    int i = 0;
-    while( ignoredPlugins[i] )
-    {
-        if( !strcmp( pluginId, ignoredPlugins[i] ) )
-        {
-            return 1;
-        }
-        ++i;
-    }
-
-    return 0;
-}
-
-/* Build PaDeviceInfo list, ignore devices for which we cannot determine capabilities (possibly busy, sigh) */
-static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
-{
-    PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep;
-    PaAlsaDeviceInfo *deviceInfoArray;
-    int cardIdx = -1, devIdx = 0;
-    snd_ctl_card_info_t *cardInfo;
-    PaError result = paNoError;
-    size_t numDeviceNames = 0, maxDeviceNames = 1, i;
-    DeviceNames *deviceNames = NULL;
-    snd_config_t *topNode = NULL;
-    snd_pcm_info_t *pcmInfo;
-    int res;
-    int blocking = SND_PCM_NONBLOCK;
-    char alsaCardName[50];
-    if( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) && atoi( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) ) )
-        blocking = 0;
-
-    /* These two will be set to the first working input and output device, respectively */
-    baseApi->info.defaultInputDevice = paNoDevice;
-    baseApi->info.defaultOutputDevice = paNoDevice;
-
-    /* count the devices by enumerating all the card numbers */
-
-    /* snd_card_next() modifies the integer passed to it to be:
-     *      the index of the first card if the parameter is -1
-     *      the index of the next card if the parameter is the index of a card
-     *      -1 if there are no more cards
-     *
-     * The function itself returns 0 if it succeeded. */
-    cardIdx = -1;
-    snd_ctl_card_info_alloca( &cardInfo );
-    snd_pcm_info_alloca( &pcmInfo );
-    while( snd_card_next( &cardIdx ) == 0 && cardIdx >= 0 )
-    {
-        char *cardName;
-        int devIdx = -1;
-        snd_ctl_t *ctl;
-        char buf[50];
-
-        snprintf( alsaCardName, sizeof (alsaCardName), "hw:%d", cardIdx );
-
-        /* Acquire name of card */
-        if( snd_ctl_open( &ctl, alsaCardName, 0 ) < 0 )
-        {
-            /* Unable to open card :( */
-            continue;
-        }
-        snd_ctl_card_info( ctl, cardInfo );
-
-        PA_ENSURE( PaAlsa_StrDup( alsaApi, &cardName, snd_ctl_card_info_get_name( cardInfo )) );
-
-        while( snd_ctl_pcm_next_device( ctl, &devIdx ) == 0 && devIdx >= 0 )
-        {
-            char *alsaDeviceName, *deviceName;
-            size_t len;
-            int hasPlayback = 0, hasCapture = 0;
-            snprintf( buf, sizeof (buf), "%s:%d,%d", "hw", cardIdx, devIdx );
-
-            /* Obtain info about this particular device */
-            snd_pcm_info_set_device( pcmInfo, devIdx );
-            snd_pcm_info_set_subdevice( pcmInfo, 0 );
-            snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_CAPTURE );
-            if( snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 )
-            {
-                hasCapture = 1;
-            }
-            
-            snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_PLAYBACK );
-            if( snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 )
-            {
-                hasPlayback = 1;
-            }
-
-            if( !hasPlayback && !hasCapture )
-            {
-                continue;   /* Error */
-            }
-
-            /* The length of the string written by snprintf plus terminating 0 */
-            len = snprintf( NULL, 0, "%s: %s (%s)", cardName, snd_pcm_info_get_name( pcmInfo ), buf ) + 1;
-            PA_UNLESS( deviceName = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ),
-                    paInsufficientMemory );
-            snprintf( deviceName, len, "%s: %s (%s)", cardName,
-                    snd_pcm_info_get_name( pcmInfo ), buf );
-
-            ++numDeviceNames;
-            if( !deviceNames || numDeviceNames > maxDeviceNames )
-            {
-                maxDeviceNames *= 2;
-                PA_UNLESS( deviceNames = (DeviceNames *) realloc( deviceNames, maxDeviceNames * sizeof (DeviceNames) ),
-                        paInsufficientMemory );
-            }
-
-            PA_ENSURE( PaAlsa_StrDup( alsaApi, &alsaDeviceName, buf ) );
-
-            deviceNames[ numDeviceNames - 1 ].alsaName = alsaDeviceName;
-            deviceNames[ numDeviceNames - 1 ].name = deviceName;
-            deviceNames[ numDeviceNames - 1 ].isPlug = 0;
-            deviceNames[ numDeviceNames - 1 ].hasPlayback = hasPlayback;
-            deviceNames[ numDeviceNames - 1 ].hasCapture = hasCapture;
-        }
-        snd_ctl_close( ctl );
-    }
-
-    /* Iterate over plugin devices */
-    if( NULL == snd_config )
-    {
-        /* snd_config_update is called implicitly by some functions, if this hasn't happened snd_config will be NULL (bleh) */
-        ENSURE_( snd_config_update(), paUnanticipatedHostError );
-        PA_DEBUG(( "Updating snd_config\n" ));
-    }
-    assert( snd_config );
-    if( (res = snd_config_search( snd_config, "pcm", &topNode )) >= 0 )
-    {
-        snd_config_iterator_t i, next;
-
-        snd_config_for_each( i, next, topNode )
-        {
-            const char *tpStr = "unknown", *idStr = NULL;
-            int err = 0;
-
-            char *alsaDeviceName, *deviceName;
-            snd_config_t *n = snd_config_iterator_entry( i ), * tp = NULL;;
-
-            if( (err = snd_config_search( n, "type", &tp )) < 0 )
-            {
-                if( -ENOENT != err )
-                {
-                    ENSURE_(err, paUnanticipatedHostError);
-                }
-            }
-            else 
-            {
-                ENSURE_( snd_config_get_string( tp, &tpStr ), paUnanticipatedHostError );
-            }
-            ENSURE_( snd_config_get_id( n, &idStr ), paUnanticipatedHostError );
-            if( IgnorePlugin( idStr ) )
-            {
-                PA_DEBUG(( "%s: Ignoring ALSA plugin device %s of type %s\n", __FUNCTION__, idStr, tpStr ));
-                continue;
-            }
-            PA_DEBUG(( "%s: Found plugin %s of type %s\n", __FUNCTION__, idStr, tpStr ));
-
-            PA_UNLESS( alsaDeviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations,
-                                                            strlen(idStr) + 6 ), paInsufficientMemory );
-            strcpy( alsaDeviceName, idStr );
-            PA_UNLESS( deviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations,
-                                                            strlen(idStr) + 1 ), paInsufficientMemory );
-            strcpy( deviceName, idStr );
-
-            ++numDeviceNames;
-            if( !deviceNames || numDeviceNames > maxDeviceNames )
-            {
-                maxDeviceNames *= 2;
-                PA_UNLESS( deviceNames = (DeviceNames *) realloc( deviceNames, maxDeviceNames * sizeof (DeviceNames) ),
-                        paInsufficientMemory );
-            }
-
-            deviceNames[numDeviceNames - 1].alsaName = alsaDeviceName;
-            deviceNames[numDeviceNames - 1].name = deviceName;
-            deviceNames[numDeviceNames - 1].isPlug = 1;
-            deviceNames[numDeviceNames - 1].hasPlayback = 1;
-            deviceNames[numDeviceNames - 1].hasCapture = 1;
-        }
-    }
-    else
-        PA_DEBUG(( "%s: Iterating over ALSA plugins failed: %s\n", __FUNCTION__, snd_strerror( res ) ));
-
-    /* allocate deviceInfo memory based on the number of devices */
-    PA_UNLESS( baseApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
-            alsaApi->allocations, sizeof(PaDeviceInfo*) * (numDeviceNames) ), paInsufficientMemory );
-
-    /* allocate all device info structs in a contiguous block */
-    PA_UNLESS( deviceInfoArray = (PaAlsaDeviceInfo*)PaUtil_GroupAllocateMemory(
-            alsaApi->allocations, sizeof(PaAlsaDeviceInfo) * numDeviceNames ), paInsufficientMemory );
-
-    /* Loop over list of cards, filling in info, if a device is deemed unavailable (can't get name),
-     * it's ignored.
-     */
-    /* while( snd_card_next( &cardIdx ) == 0 && cardIdx >= 0 ) */
-    for( i = 0, devIdx = 0; i < numDeviceNames; ++i )
-    {
-        snd_pcm_t *pcm;
-        PaAlsaDeviceInfo *deviceInfo = &deviceInfoArray[devIdx];
-        PaDeviceInfo *baseDeviceInfo = &deviceInfo->baseDeviceInfo;
-        int canMmap = -1;
-
-        /* Zero fields */
-        InitializeDeviceInfo( baseDeviceInfo );
-
-        /* to determine device capabilities, we must open the device and query the
-         * hardware parameter configuration space */
-
-        /* Query capture */
-        if( deviceNames[i].hasCapture &&
-                snd_pcm_open( &pcm, deviceNames[i].alsaName, SND_PCM_STREAM_CAPTURE, blocking ) >= 0 )
-        {
-            if( GropeDevice( pcm, deviceNames[i].isPlug, StreamDirection_In, blocking, deviceInfo,
-                        &canMmap ) != paNoError )
-            {
-                /* Error */
-                PA_DEBUG(("%s: Failed groping %s for capture\n", __FUNCTION__, deviceNames[i].alsaName));
-                continue;
-            }
-        }
-
-        /* Query playback */
-        if( deviceNames[i].hasPlayback &&
-                snd_pcm_open( &pcm, deviceNames[i].alsaName, SND_PCM_STREAM_PLAYBACK, blocking ) >= 0 )
-        {
-            if( GropeDevice( pcm, deviceNames[i].isPlug, StreamDirection_Out, blocking, deviceInfo,
-                        &canMmap ) != paNoError )
-            {
-                /* Error */
-                PA_DEBUG(("%s: Failed groping %s for playback\n", __FUNCTION__, deviceNames[i].alsaName));
-                continue;
-            }
-        }
-
-        if( 0 == canMmap )
-        {
-            PA_DEBUG(("%s: Device %s doesn't support mmap\n", __FUNCTION__, deviceNames[i].alsaName));
-            continue;
-        }
-
-        baseDeviceInfo->structVersion = 2;
-        baseDeviceInfo->hostApi = alsaApi->hostApiIndex;
-        baseDeviceInfo->name = deviceNames[i].name;
-        deviceInfo->alsaName = deviceNames[i].alsaName;
-        deviceInfo->isPlug = deviceNames[i].isPlug;
-
-        /* A: Storing pointer to PaAlsaDeviceInfo object as pointer to PaDeviceInfo object.
-         * Should now be safe to add device info, unless the device supports neither capture nor playback
-         */
-        if( baseDeviceInfo->maxInputChannels > 0 || baseDeviceInfo->maxOutputChannels > 0 )
-        {
-            if( baseApi->info.defaultInputDevice == paNoDevice && baseDeviceInfo->maxInputChannels > 0 )
-                baseApi->info.defaultInputDevice = devIdx;
-            if(  baseApi->info.defaultOutputDevice == paNoDevice && baseDeviceInfo->maxOutputChannels > 0 )
-                baseApi->info.defaultOutputDevice = devIdx;
-            PA_DEBUG(("%s: Adding device %s\n", __FUNCTION__, deviceNames[i].name));
-            baseApi->deviceInfos[devIdx++] = (PaDeviceInfo *) deviceInfo;
-        }
-    }
-    free( deviceNames );
-
-    baseApi->info.deviceCount = devIdx;   /* Number of successfully queried devices */
-
-end:
-    return result;
-
-error:
-    /* No particular action */
-    goto end;
-}
-
-/* Check against known device capabilities */
-static PaError ValidateParameters( const PaStreamParameters *parameters, PaUtilHostApiRepresentation *hostApi, StreamDirection mode )
-{
-    PaError result = paNoError;
-    int maxChans;
-    const PaAlsaDeviceInfo *deviceInfo = NULL;
-    assert( parameters );
-
-    if( parameters->device != paUseHostApiSpecificDeviceSpecification )
-    {
-        assert( parameters->device < hostApi->info.deviceCount );
-        PA_UNLESS( parameters->hostApiSpecificStreamInfo == NULL, paBadIODeviceCombination );
-        deviceInfo = GetDeviceInfo( hostApi, parameters->device );
-    }
-    else
-    {
-        const PaAlsaStreamInfo *streamInfo = parameters->hostApiSpecificStreamInfo;
-
-        PA_UNLESS( parameters->device == paUseHostApiSpecificDeviceSpecification, paInvalidDevice );
-        PA_UNLESS( streamInfo->size == sizeof (PaAlsaStreamInfo) && streamInfo->version == 1,
-                paIncompatibleHostApiSpecificStreamInfo );
-        PA_UNLESS( streamInfo->deviceString != NULL, paInvalidDevice );
-
-        /* Skip further checking */
-        return paNoError;
-    }
-
-    assert( deviceInfo );
-    assert( parameters->hostApiSpecificStreamInfo == NULL );
-    maxChans = (StreamDirection_In == mode ? deviceInfo->baseDeviceInfo.maxInputChannels :
-        deviceInfo->baseDeviceInfo.maxOutputChannels);
-    PA_UNLESS( parameters->channelCount <= maxChans, paInvalidChannelCount );
-
-error:
-    return result;
-}
-
-/* Given an open stream, what sample formats are available? */
-static PaSampleFormat GetAvailableFormats( snd_pcm_t *pcm )
-{
-    PaSampleFormat available = 0;
-    snd_pcm_hw_params_t *hwParams;
-    snd_pcm_hw_params_alloca( &hwParams );
-
-    snd_pcm_hw_params_any( pcm, hwParams );
-
-    if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT ) >= 0)
-        available |= paFloat32;
-
-    if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S32 ) >= 0)
-        available |= paInt32;
-
-    if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24 ) >= 0)
-        available |= paInt24;
-
-    if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16 ) >= 0)
-        available |= paInt16;
-
-    if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U8 ) >= 0)
-        available |= paUInt8;
-
-    if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S8 ) >= 0)
-        available |= paInt8;
-
-    return available;
-}
-
-static snd_pcm_format_t Pa2AlsaFormat( PaSampleFormat paFormat )
-{
-    switch( paFormat )
-    {
-        case paFloat32:
-            return SND_PCM_FORMAT_FLOAT;
-
-        case paInt16:
-            return SND_PCM_FORMAT_S16;
-
-        case paInt24:
-            return SND_PCM_FORMAT_S24;
-
-        case paInt32:
-            return SND_PCM_FORMAT_S32;
-
-        case paInt8:
-            return SND_PCM_FORMAT_S8;
-
-        case paUInt8:
-            return SND_PCM_FORMAT_U8;
-
-        default:
-            return SND_PCM_FORMAT_UNKNOWN;
-    }
-}
-
-/** Open an ALSA pcm handle.
- * 
- * The device to be open can be specified in a custom PaAlsaStreamInfo struct, or it will be a device number. In case of a
- * device number, it maybe specified through an env variable (PA_ALSA_PLUGHW) that we should open the corresponding plugin
- * device.
- */
-static PaError AlsaOpen( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *params, StreamDirection
-        streamDir, snd_pcm_t **pcm )
-{
-    PaError result = paNoError;
-    int ret;
-    const char *deviceName = alloca( 50 );
-    const PaAlsaDeviceInfo *deviceInfo = NULL;
-    PaAlsaStreamInfo *streamInfo = (PaAlsaStreamInfo *)params->hostApiSpecificStreamInfo;
-
-    if( !streamInfo )
-    {
-        int usePlug = 0;
-        deviceInfo = GetDeviceInfo( hostApi, params->device );
-        
-        /* If device name starts with hw: and PA_ALSA_PLUGHW is 1, we open the plughw device instead */
-        if( !strncmp( "hw:", deviceInfo->alsaName, 3 ) && getenv( "PA_ALSA_PLUGHW" ) )
-            usePlug = atoi( getenv( "PA_ALSA_PLUGHW" ) );
-        if( usePlug )
-            snprintf( (char *) deviceName, 50, "plug%s", deviceInfo->alsaName );
-        else
-            deviceName = deviceInfo->alsaName;
-    }
-    else
-        deviceName = streamInfo->deviceString;
-
-    PA_DEBUG(( "%s: Opening device %s\n", __FUNCTION__, deviceName ));
-    if( (ret = snd_pcm_open( pcm, deviceName, streamDir == StreamDirection_In ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
-                    SND_PCM_NONBLOCK )) < 0 )
-    {
-        /* Not to be closed */
-        *pcm = NULL;
-        ENSURE_( ret, ret == -EBUSY ? paDeviceUnavailable : paBadIODeviceCombination );
-    }
-    ENSURE_( snd_pcm_nonblock( *pcm, 0 ), paUnanticipatedHostError );
-
-end:
-    return result;
-
-error:
-    goto end;
-}
-
-static PaError TestParameters( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *parameters,
-        double sampleRate, StreamDirection streamDir )
-{
-    PaError result = paNoError;
-    snd_pcm_t *pcm = NULL;
-    PaSampleFormat availableFormats;
-    /* We are able to adapt to a number of channels less than what the device supports */
-    unsigned int numHostChannels;
-    PaSampleFormat hostFormat;
-    snd_pcm_hw_params_t *hwParams;
-    snd_pcm_hw_params_alloca( &hwParams );
-    
-    if( !parameters->hostApiSpecificStreamInfo )
-    {
-        const PaAlsaDeviceInfo *devInfo = GetDeviceInfo( hostApi, parameters->device );
-        numHostChannels = PA_MAX( parameters->channelCount, StreamDirection_In == streamDir ?
-                devInfo->minInputChannels : devInfo->minOutputChannels );
-    }
-    else
-        numHostChannels = parameters->channelCount;
-
-    PA_ENSURE( AlsaOpen( hostApi, parameters, streamDir, &pcm ) );
-
-    snd_pcm_hw_params_any( pcm, hwParams );
-
-    if( SetApproximateSampleRate( pcm, hwParams, sampleRate ) < 0 )
-    {
-        result = paInvalidSampleRate;
-        goto error;
-    }
-
-    if( snd_pcm_hw_params_set_channels( pcm, hwParams, numHostChannels ) < 0 )
-    {
-        result = paInvalidChannelCount;
-        goto error;
-    }
-
-    /* See if we can find a best possible match */
-    availableFormats = GetAvailableFormats( pcm );
-    PA_ENSURE( hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, parameters->sampleFormat ) );
-    ENSURE_( snd_pcm_hw_params_set_format( pcm, hwParams, Pa2AlsaFormat( hostFormat ) ), paUnanticipatedHostError );
-
-    {
-        /* It happens that this call fails because the device is busy */
-        int ret = 0;
-        if( (ret = snd_pcm_hw_params( pcm, hwParams )) < 0)
-        {
-            ENSURE_( ret, ret == -EBUSY ? paDeviceUnavailable : paUnanticipatedHostError );
-        }
-    }
-
-end:
-    if( pcm )
-    {
-        snd_pcm_close( pcm );
-    }
-    return result;
-
-error:
-    goto end;
-}
-
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate )
-{
-    int inputChannelCount = 0, outputChannelCount = 0;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    PaError result = paFormatIsSupported;
-
-    if( inputParameters )
-    {
-        PA_ENSURE( ValidateParameters( inputParameters, hostApi, StreamDirection_In ) );
-
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-    }
-
-    if( outputParameters )
-    {
-        PA_ENSURE( ValidateParameters( outputParameters, hostApi, StreamDirection_Out ) );
-
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-    }
-
-    if( inputChannelCount )
-    {
-        if( (result = TestParameters( hostApi, inputParameters, sampleRate, StreamDirection_In ))
-                != paNoError )
-            goto error;
-    }
-    if ( outputChannelCount )
-    {
-        if( (result = TestParameters( hostApi, outputParameters, sampleRate, StreamDirection_Out ))
-                != paNoError )
-            goto error;
-    }
-
-    return paFormatIsSupported;
-
-error:
-    return result;
-}
-
-static PaError PaAlsaStreamComponent_Initialize( PaAlsaStreamComponent *self, PaAlsaHostApiRepresentation *alsaApi,
-        const PaStreamParameters *params, StreamDirection streamDir, int callbackMode )
-{
-    PaError result = paNoError;
-    PaSampleFormat userSampleFormat = params->sampleFormat, hostSampleFormat;
-    assert( params->channelCount > 0 );
-
-    /* Make sure things have an initial value */
-    memset( self, 0, sizeof (PaAlsaStreamComponent) );
-
-    if( NULL == params->hostApiSpecificStreamInfo )
-    {
-        const PaAlsaDeviceInfo *devInfo = GetDeviceInfo( &alsaApi->baseHostApiRep, params->device );
-        self->numHostChannels = PA_MAX( params->channelCount, StreamDirection_In == streamDir ? devInfo->minInputChannels
-                : devInfo->minOutputChannels );
-    }
-    else
-    {
-        /* We're blissfully unaware of the minimum channelCount */
-        self->numHostChannels = params->channelCount;
-    }
-
-    PA_ENSURE( AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm ) );
-    self->nfds = snd_pcm_poll_descriptors_count( self->pcm );
-    hostSampleFormat = PaUtil_SelectClosestAvailableFormat( GetAvailableFormats( self->pcm ), userSampleFormat );
-
-    self->hostSampleFormat = hostSampleFormat;
-    self->nativeFormat = Pa2AlsaFormat( hostSampleFormat );
-    self->hostInterleaved = self->userInterleaved = !(userSampleFormat & paNonInterleaved);
-    self->numUserChannels = params->channelCount;
-    self->streamDir = streamDir;
-
-    if( !callbackMode && !self->userInterleaved )
-    {
-        /* Pre-allocate non-interleaved user provided buffers */
-        PA_UNLESS( self->userBuffers = PaUtil_AllocateMemory( sizeof (void *) * self->numUserChannels ),
-                paInsufficientMemory );
-    }
-
-error:
-    return result;
-}
-
-static void PaAlsaStreamComponent_Terminate( PaAlsaStreamComponent *self )
-{
-    snd_pcm_close( self->pcm );
-    if( self->userBuffers )
-        PaUtil_FreeMemory( self->userBuffers );
-}
-
-int nearbyint_(float value) {
-    if(  value - (int)value > .5 )
-        return (int)ceil( value );
-    return (int)floor( value );
-}
-
-/** Initiate configuration, preparing for determining a period size suitable for both capture and playback components.
- *
- */
-static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *self, const PaStreamParameters *params,
-        int primeBuffers, snd_pcm_hw_params_t *hwParams, double *sampleRate )
-{
-    /* Configuration consists of setting all of ALSA's parameters.
-     * These parameters come in two flavors: hardware parameters
-     * and software paramters.  Hardware parameters will affect
-     * the way the device is initialized, software parameters
-     * affect the way ALSA interacts with me, the user-level client.
-     */
-
-    PaError result = paNoError;
-    snd_pcm_access_t accessMode, alternateAccessMode;
-    int dir = 0;
-    snd_pcm_t *pcm = self->pcm;
-    double sr = *sampleRate;
-    unsigned int minPeriods = 2;
-
-    /* self->framesPerBuffer = framesPerHostBuffer; */
-
-    /* ... fill up the configuration space with all possibile
-     * combinations of parameters this device will accept */
-    ENSURE_( snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError );
-
-    ENSURE_( snd_pcm_hw_params_set_periods_integer( pcm, hwParams ), paUnanticipatedHostError );
-    /* I think there should be at least 2 periods (even though ALSA doesn't appear to enforce this) */
-    dir = 0;
-    ENSURE_( snd_pcm_hw_params_set_periods_min( pcm, hwParams, &minPeriods, &dir ), paUnanticipatedHostError );
-
-    if( self->userInterleaved )
-    {
-        accessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED;
-        alternateAccessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;
-    }
-    else
-    {
-        accessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;
-        alternateAccessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED;
-    }
-    /* If requested access mode fails, try alternate mode */
-    if( snd_pcm_hw_params_set_access( pcm, hwParams, accessMode ) < 0 )
-    {
-        int err = 0;
-        if( (err = snd_pcm_hw_params_set_access( pcm, hwParams, alternateAccessMode )) < 0)
-        {
-            result = paUnanticipatedHostError;
-            if( -EINVAL == err )
-            {
-                PaUtil_SetLastHostErrorInfo( paALSA, err, "PA ALSA requires that a device supports mmap access" );
-            }
-            else
-            {
-                PaUtil_SetLastHostErrorInfo( paALSA, err, snd_strerror( err ) );
-            }
-            goto error;
-        }
-        /* Flip mode */
-        self->hostInterleaved = !self->userInterleaved;
-    }
-
-    ENSURE_( snd_pcm_hw_params_set_format( pcm, hwParams, self->nativeFormat ), paUnanticipatedHostError );
-
-    ENSURE_( SetApproximateSampleRate( pcm, hwParams, sr ), paInvalidSampleRate );
-    ENSURE_( GetExactSampleRate( hwParams, &sr ), paUnanticipatedHostError );
-    /* reject if there's no sample rate within 1% of the one requested */
-    if( (fabs( *sampleRate - sr ) / *sampleRate) > 0.01 )
-    {
-        PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr ));                 
-        PA_ENSURE( paInvalidSampleRate );
-    }
-
-    ENSURE_( snd_pcm_hw_params_set_channels( pcm, hwParams, self->numHostChannels ), paInvalidChannelCount );
-
-    *sampleRate = sr;
-
-end:
-    return result;
-
-error:
-    /* No particular action */
-    goto end;
-}
-
-/** Finish the configuration of the component's ALSA device.
- *
- * As part of this method, the component's bufferSize attribute will be set.
- * @param latency: The latency for this component.
- */
-static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *self, snd_pcm_hw_params_t* hwParams,
-        const PaStreamParameters *params, int primeBuffers, double sampleRate, PaTime* latency )
-{
-    PaError result = paNoError;
-    snd_pcm_sw_params_t* swParams;
-    snd_pcm_uframes_t bufSz = 0;
-    *latency = -1.;
-
-    snd_pcm_sw_params_alloca( &swParams );
-
-    bufSz = (params->suggestedLatency * sampleRate) + self->framesPerBuffer;    /* One period does not count as latency */
-    ENSURE_( snd_pcm_hw_params_set_buffer_size_near( self->pcm, hwParams, &bufSz ), paUnanticipatedHostError );
-
-    /* Set the parameters! */
-    ENSURE_( snd_pcm_hw_params( self->pcm, hwParams ), paUnanticipatedHostError );
-    ENSURE_( snd_pcm_hw_params_get_buffer_size( hwParams, &self->bufferSize ), paUnanticipatedHostError );
-    /* Latency in seconds, one period is not counted as latency */
-    *latency = (self->bufferSize - self->framesPerBuffer) / sampleRate;
-
-    /* Now software parameters... */
-    ENSURE_( snd_pcm_sw_params_current( self->pcm, swParams ), paUnanticipatedHostError );
-
-    ENSURE_( snd_pcm_sw_params_set_start_threshold( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError );
-    ENSURE_( snd_pcm_sw_params_set_stop_threshold( self->pcm, swParams, self->bufferSize ), paUnanticipatedHostError );
-
-    /* Silence buffer in the case of underrun */
-    if( !primeBuffers ) /* XXX: Make sense? */
-    {
-        snd_pcm_uframes_t boundary;
-        ENSURE_( snd_pcm_sw_params_get_boundary( swParams, &boundary ), paUnanticipatedHostError );
-        ENSURE_( snd_pcm_sw_params_set_silence_threshold( self->pcm, swParams, 0 ), paUnanticipatedHostError );
-        ENSURE_( snd_pcm_sw_params_set_silence_size( self->pcm, swParams, boundary ), paUnanticipatedHostError );
-    }
-        
-    ENSURE_( snd_pcm_sw_params_set_avail_min( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError );
-    ENSURE_( snd_pcm_sw_params_set_xfer_align( self->pcm, swParams, 1 ), paUnanticipatedHostError );
-    ENSURE_( snd_pcm_sw_params_set_tstamp_mode( self->pcm, swParams, SND_PCM_TSTAMP_MMAP ), paUnanticipatedHostError );
-
-    /* Set the parameters! */
-    ENSURE_( snd_pcm_sw_params( self->pcm, swParams ), paUnanticipatedHostError );
-
-error:
-    return result;
-}
-
-static PaError PaAlsaStream_Initialize( PaAlsaStream *self, PaAlsaHostApiRepresentation *alsaApi, const PaStreamParameters *inParams,
-        const PaStreamParameters *outParams, double sampleRate, unsigned long framesPerUserBuffer, PaStreamCallback callback,
-        PaStreamFlags streamFlags, void *userData )
-{
-    PaError result = paNoError;
-    assert( self );
-
-    memset( self, 0, sizeof (PaAlsaStream) );
-
-    if( NULL != callback )
-    {
-        PaUtil_InitializeStreamRepresentation( &self->streamRepresentation,
-                                               &alsaApi->callbackStreamInterface,
-                                               callback, userData );
-        self->callbackMode = 1;
-    }
-    else
-    {
-        PaUtil_InitializeStreamRepresentation( &self->streamRepresentation,
-                                               &alsaApi->blockingStreamInterface,
-                                               NULL, userData );
-    }
-
-    self->framesPerUserBuffer = framesPerUserBuffer;
-    self->neverDropInput = streamFlags & paNeverDropInput;
-    /* XXX: Ignore paPrimeOutputBuffersUsingStreamCallback untill buffer priming is fully supported in pa_process.c */
-    /*
-    if( outParams & streamFlags & paPrimeOutputBuffersUsingStreamCallback )
-        self->primeBuffers = 1;
-        */
-    memset( &self->capture, 0, sizeof (PaAlsaStreamComponent) );
-    memset( &self->playback, 0, sizeof (PaAlsaStreamComponent) );
-    if( inParams )
-        PA_ENSURE( PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback ) );
-    if( outParams )
-        PA_ENSURE( PaAlsaStreamComponent_Initialize( &self->playback, alsaApi, outParams, StreamDirection_Out, NULL != callback ) );
-
-    assert( self->capture.nfds || self->playback.nfds );
-
-    PA_UNLESS( self->pfds = (struct pollfd*)PaUtil_AllocateMemory( (self->capture.nfds +
-                    self->playback.nfds) * sizeof (struct pollfd) ), paInsufficientMemory );
-
-    PaUtil_InitializeCpuLoadMeasurer( &self->cpuLoadMeasurer, sampleRate );
-    InitializeThreading( &self->threading, &self->cpuLoadMeasurer );
-    ASSERT_CALL_( pthread_mutex_init( &self->stateMtx, NULL ), 0 );
-    ASSERT_CALL_( pthread_mutex_init( &self->startMtx, NULL ), 0 );
-    ASSERT_CALL_( pthread_cond_init( &self->startCond, NULL ), 0 );
-
-error:
-    return result;
-}
-
-/** Free resources associated with stream, and eventually stream itself.
- *
- * Frees allocated memory, and terminates individual StreamComponents.
- */
-static void PaAlsaStream_Terminate( PaAlsaStream *self )
-{
-    assert( self );
-
-    if( self->capture.pcm )
-    {
-        PaAlsaStreamComponent_Terminate( &self->capture );
-    }
-    if( self->playback.pcm )
-    {
-        PaAlsaStreamComponent_Terminate( &self->playback );
-    }
-
-    PaUtil_FreeMemory( self->pfds );
-    ASSERT_CALL_( pthread_mutex_destroy( &self->stateMtx ), 0 );
-    ASSERT_CALL_( pthread_mutex_destroy( &self->startMtx ), 0 );
-    ASSERT_CALL_( pthread_cond_destroy( &self->startCond ), 0 );
-
-    PaUtil_FreeMemory( self );
-}
-
-/** Calculate polling timeout
- *
- * @param frames Time to wait
- * @return Polling timeout in milliseconds
- */
-static int CalculatePollTimeout( const PaAlsaStream *stream, unsigned long frames )
-{
-    assert( stream->streamRepresentation.streamInfo.sampleRate > 0.0 );
-    /* Period in msecs, rounded up */
-    return (int)ceil( 1000 * frames / stream->streamRepresentation.streamInfo.sampleRate );
-}
-
-/** Determine size per host buffer.
- *
- * During this method call, the component's framesPerBuffer attribute gets computed, and the corresponding period size
- * gets configured for the device.
- * @param accurate: If the configured period size is non-integer, this will be set to 0.
- */
-static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamComponent* self, const PaStreamParameters* params,
-        unsigned long framesPerUserBuffer, double sampleRate, snd_pcm_hw_params_t* hwParams, int* accurate )
-{
-    PaError result = paNoError;
-    unsigned long bufferSize = params->suggestedLatency * sampleRate, framesPerHostBuffer;
-    int dir = 0;
-    
-    {
-        snd_pcm_uframes_t tmp;
-        snd_pcm_hw_params_get_buffer_size_min( hwParams, &tmp );
-        bufferSize = PA_MAX( bufferSize, tmp );
-        snd_pcm_hw_params_get_buffer_size_max( hwParams, &tmp );
-        bufferSize = PA_MIN( bufferSize, tmp );
-    }
-
-    assert( bufferSize > 0 );
-
-    if( framesPerUserBuffer != paFramesPerBufferUnspecified )
-    {
-        /* Preferably the host buffer size should be a multiple of the user buffer size */
-
-        if( bufferSize > framesPerUserBuffer )
-        {
-            snd_pcm_uframes_t remainder = bufferSize % framesPerUserBuffer;
-            if( remainder > framesPerUserBuffer / 2. )
-                bufferSize += framesPerUserBuffer - remainder;
-            else
-                bufferSize -= remainder;
-
-            assert( bufferSize % framesPerUserBuffer == 0 );
-        }
-        else if( framesPerUserBuffer % bufferSize != 0 )
-        {
-            /*  Find a good compromise between user specified latency and buffer size */
-            if( bufferSize > framesPerUserBuffer * .75 )
-            {
-                bufferSize = framesPerUserBuffer;
-            }
-            else
-            {
-                snd_pcm_uframes_t newSz = framesPerUserBuffer;
-                while( newSz / 2 >= bufferSize )
-                {
-                    if( framesPerUserBuffer % (newSz / 2) != 0 )
-                    {
-                        /* No use dividing any further */
-                        break;
-                    }
-                    newSz /= 2;
-                }
-                bufferSize = newSz;
-            }
-
-            assert( framesPerUserBuffer % bufferSize == 0 );
-        }
-    }
-
-    /* Using 5 as a base number of periods, we try to approximate the suggested latency (+1 period),
-       finding a combination of period/buffer size which best fits these constraints */
-    {
-        unsigned numPeriods = 4, maxPeriods = 0;
-        /* It may be that the device only supports 2 periods for instance */
-        dir = 0;
-        ENSURE_( snd_pcm_hw_params_get_periods_max( hwParams, &maxPeriods, &dir ), paUnanticipatedHostError );
-        assert( maxPeriods > 1 );
-        /* One period is not counted as latency */
-        maxPeriods -= 1;
-        numPeriods = PA_MIN( maxPeriods, numPeriods );
-
-        if( framesPerUserBuffer != paFramesPerBufferUnspecified )
-        {
-            framesPerHostBuffer = framesPerUserBuffer;
-            if( framesPerHostBuffer < bufferSize )
-            {
-                while( bufferSize / framesPerHostBuffer > numPeriods )
-                {
-                    framesPerHostBuffer *= 2;
-                }
-            }
-            else
-            {
-                while( bufferSize / framesPerHostBuffer < numPeriods )
-                {
-                    if( framesPerUserBuffer % (framesPerHostBuffer / 2) != 0 )
-                    {
-                        /* Can't be divided any further */
-                        break;
-                    }
-                    framesPerHostBuffer /= 2;
-                }
-            }
-
-            if( framesPerHostBuffer < framesPerUserBuffer )
-            {
-                assert( framesPerUserBuffer % framesPerHostBuffer == 0 );
-                if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 )
-                {
-                    if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer * 2, 0 ) == 0 )
-                        framesPerHostBuffer *= 2;
-                    else if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 )
-                        framesPerHostBuffer /= 2;
-                }
-            }
-            else
-            {
-                assert( framesPerHostBuffer % framesPerUserBuffer == 0 );
-                if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 )
-                {
-                    if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer + framesPerUserBuffer, 0 ) == 0 )
-                        framesPerHostBuffer += framesPerUserBuffer;
-                    else if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer - framesPerUserBuffer, 0 ) == 0 )
-                        framesPerHostBuffer -= framesPerUserBuffer;
-                }
-            }
-        }
-        else
-        {
-            framesPerHostBuffer = bufferSize / numPeriods;
-        }
-    }
-
-    assert( framesPerHostBuffer > 0 );
-    {
-        snd_pcm_uframes_t min = 0, max = 0;
-        ENSURE_( snd_pcm_hw_params_get_period_size_min( hwParams, &min, NULL ), paUnanticipatedHostError );
-        ENSURE_( snd_pcm_hw_params_get_period_size_max( hwParams, &max, NULL ), paUnanticipatedHostError );
-
-        if( framesPerHostBuffer < min )
-        {
-            framesPerHostBuffer = min;
-            PA_DEBUG(( "%s: The determined period size (%lu) is less than minimum (%lu)\n", __FUNCTION__,
-                        framesPerHostBuffer, min ));
-        }
-        else if( framesPerHostBuffer > max )
-        {
-            framesPerHostBuffer = max;
-            PA_DEBUG(( "%s: The determined period size (%lu) is greater than maximum (%lu)\n", __FUNCTION__,
-                        framesPerHostBuffer, max ));
-        }
-
-        assert( framesPerHostBuffer >= min && framesPerHostBuffer <= max );
-        dir = 0;
-        ENSURE_( snd_pcm_hw_params_set_period_size_near( self->pcm, hwParams, &framesPerHostBuffer, &dir ),
-                paUnanticipatedHostError );
-        if( dir != 0 )
-        {
-            PA_DEBUG(( "%s: The configured period size is non-integer.\n", __FUNCTION__, dir ));
-            *accurate = 0;
-        }
-    }
-    self->framesPerBuffer = framesPerHostBuffer;
-
-error:
-    return result;
-}
-
-/* We need to determine how many frames per host buffer (period) to use.  Our
- * goals are to provide the best possible performance, but also to
- * honor the requested latency settings as closely as we can. Therefore this
- * decision is based on:
- *
- *   - the period sizes that playback and/or capture support.  The
- *     host buffer size has to be one of these.
- *   - the number of periods that playback and/or capture support.
- *
- * We want to make period_size*(num_periods-1) to be as close as possible
- * to latency*rate for both playback and capture.
- *
- * This method will determine suitable period sizes for capture and playback handles, and report the maximum number of
- * frames per host buffer. The latter is relevant, in case we should be so unfortunate that the period size differs
- * between capture and playback. If this should happen, the stream's hostBufferSizeMode attribute will be set to
- * paUtilBoundedHostBufferSize, because the best we can do is limit the size of individual host buffers to the upper
- * bound. The size of host buffers scheduled for processing should only matter if the user has specified a buffer size,
- * but when he/she does we must strive for an optimal configuration. By default we'll opt for a fixed host buffer size,
- * which should be fine if the period size is the same for capture and playback. In general, if there is a specified user
- * buffer size, this method tries it best to determine a period size which is a multiple of the user buffer size.
- *
- * The framesPerBuffer attributes of the individual capture and playback components of the stream are set to corresponding
- * values determined here. Since these should be reported as 
- *
- * This is one of those blocks of code that will just take a lot of
- * refinement to be any good.
- *
- * In the full-duplex case it is possible that the routine was unable
- * to find a number of frames per buffer acceptable to both devices
- * TODO: Implement an algorithm to find the value closest to acceptance
- * by both devices, to minimize difference between period sizes?
- *
- * @param determinedFramesPerHostBuffer: The determined host buffer size.
- */
-static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double sampleRate, const PaStreamParameters* inputParameters,
-        const PaStreamParameters* outputParameters, unsigned long framesPerUserBuffer, snd_pcm_hw_params_t* hwParamsCapture,
-        snd_pcm_hw_params_t* hwParamsPlayback, PaUtilHostBufferSizeMode* hostBufferSizeMode )
-{
-    PaError result = paNoError;
-    unsigned long framesPerHostBuffer = 0;
-    int dir = 0;
-    int accurate = 1;
-
-    if( self->capture.pcm && self->playback.pcm )
-    {
-        if( framesPerUserBuffer == paFramesPerBufferUnspecified )
-        {
-            snd_pcm_uframes_t desiredLatency, e, minPeriodSize, maxPeriodSize, optimalPeriodSize, periodSize,
-                              minCapture, minPlayback, maxCapture, maxPlayback;
-
-            /* Come up with a common desired latency */
-
-            dir = 0;
-            ENSURE_( snd_pcm_hw_params_get_period_size_min( hwParamsCapture, &minCapture, &dir ), paUnanticipatedHostError );
-            dir = 0;
-            ENSURE_( snd_pcm_hw_params_get_period_size_min( hwParamsPlayback, &minPlayback, &dir ), paUnanticipatedHostError );
-            dir = 0;
-            ENSURE_( snd_pcm_hw_params_get_period_size_max( hwParamsCapture, &maxCapture, &dir ), paUnanticipatedHostError );
-            dir = 0;
-            ENSURE_( snd_pcm_hw_params_get_period_size_max( hwParamsPlayback, &maxPlayback, &dir ), paUnanticipatedHostError );
-            minPeriodSize = PA_MAX( minPlayback, minCapture );
-            maxPeriodSize = PA_MIN( maxPlayback, maxCapture );
-            PA_UNLESS( minPeriodSize <= maxPeriodSize, paBadIODeviceCombination );
-
-            desiredLatency = (snd_pcm_uframes_t)(PA_MIN( outputParameters->suggestedLatency, inputParameters->suggestedLatency )
-                    * sampleRate);
-            /* Clamp desiredLatency */
-            {
-                snd_pcm_uframes_t maxBufferSize;
-                snd_pcm_uframes_t maxBufferSizeCapture, maxBufferSizePlayback;
-                ENSURE_( snd_pcm_hw_params_get_buffer_size_max( hwParamsCapture, &maxBufferSizeCapture ), paUnanticipatedHostError );
-                ENSURE_( snd_pcm_hw_params_get_buffer_size_max( hwParamsPlayback, &maxBufferSizePlayback ), paUnanticipatedHostError );
-                maxBufferSize = PA_MIN( maxBufferSizeCapture, maxBufferSizePlayback );
-
-                desiredLatency = PA_MIN( desiredLatency, maxBufferSize );
-            }
-
-            /* Find the closest power of 2 */
-            e = ilogb( minPeriodSize );
-            if( minPeriodSize & (minPeriodSize - 1) )
-                e += 1;
-            periodSize = (snd_pcm_uframes_t)pow( 2, e );
-
-            while( periodSize <= maxPeriodSize )
-            {
-                if( snd_pcm_hw_params_test_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ) >= 0 &&
-                        snd_pcm_hw_params_test_period_size( self->capture.pcm, hwParamsCapture, periodSize, 0 ) >= 0 )
-                    break;  /* Ok! */
-
-                periodSize *= 2;
-            }
-
-            /* 4 periods considered optimal */
-            optimalPeriodSize = PA_MAX( desiredLatency / 4, minPeriodSize );
-            optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize );
-
-            /* Find the closest power of 2 */
-            e = ilogb( optimalPeriodSize );
-            if( optimalPeriodSize & (optimalPeriodSize - 1) )
-                e += 1;
-            optimalPeriodSize = (snd_pcm_uframes_t)pow( 2, e );
-
-            while( optimalPeriodSize >= periodSize )
-            {
-                if( snd_pcm_hw_params_test_period_size( self->capture.pcm, hwParamsCapture, optimalPeriodSize, 0 ) < 0 )
-                    continue;
-                if( snd_pcm_hw_params_test_period_size( self->playback.pcm, hwParamsPlayback, optimalPeriodSize, 0 ) >= 0 )
-                    break;
-                optimalPeriodSize /= 2;
-            }
-            if( optimalPeriodSize > periodSize )
-                periodSize = optimalPeriodSize;
-
-            if( periodSize <= maxPeriodSize )
-            {
-                /* Looks good, the periodSize _should_ be acceptable by both devices */
-                ENSURE_( snd_pcm_hw_params_set_period_size( self->capture.pcm, hwParamsCapture, periodSize, 0 ),
-                        paUnanticipatedHostError );
-                ENSURE_( snd_pcm_hw_params_set_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ),
-                        paUnanticipatedHostError );
-                self->capture.framesPerBuffer = self->playback.framesPerBuffer = periodSize;
-                framesPerHostBuffer = periodSize;
-            }
-            else
-            {
-                /* Unable to find a common period size, oh well */
-                optimalPeriodSize = PA_MAX( desiredLatency / 4, minPeriodSize );
-                optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize );
-
-                self->capture.framesPerBuffer = optimalPeriodSize;
-                dir = 0;
-                ENSURE_( snd_pcm_hw_params_set_period_size_near( self->capture.pcm, hwParamsCapture, &self->capture.framesPerBuffer, &dir ),
-                        paUnanticipatedHostError );
-                self->playback.framesPerBuffer = optimalPeriodSize;
-                dir = 0;
-                ENSURE_( snd_pcm_hw_params_set_period_size_near( self->playback.pcm, hwParamsPlayback, &self->playback.framesPerBuffer, &dir ),
-                        paUnanticipatedHostError );
-                framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer );
-                *hostBufferSizeMode = paUtilBoundedHostBufferSize;
-            }
-        }
-        else
-        {
-            /* We choose the simple route and determine a suitable number of frames per buffer for one component of
-             * the stream, then we hope that this will work for the other component too (it should!).
-             */
-
-            unsigned maxPeriods = 0;
-            PaAlsaStreamComponent* first = &self->capture, * second = &self->playback;
-            const PaStreamParameters* firstStreamParams = inputParameters;
-            snd_pcm_hw_params_t* firstHwParams = hwParamsCapture, * secondHwParams = hwParamsPlayback;
-
-            dir = 0;
-            ENSURE_( snd_pcm_hw_params_get_periods_max( hwParamsPlayback, &maxPeriods, &dir ), paUnanticipatedHostError );
-            if( maxPeriods < 4 )
-            {
-                /* The playback component is trickier to get right, try that first */
-                first = &self->playback;
-                second = &self->capture;
-                firstStreamParams = outputParameters;
-                firstHwParams = hwParamsPlayback;
-                secondHwParams = hwParamsCapture;
-            }
-
-            PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( first, firstStreamParams, framesPerUserBuffer,
-                        sampleRate, firstHwParams, &accurate ) );
-
-            second->framesPerBuffer = first->framesPerBuffer;
-            dir = 0;
-            ENSURE_( snd_pcm_hw_params_set_period_size_near( second->pcm, secondHwParams, &second->framesPerBuffer, &dir ),
-                    paUnanticipatedHostError );
-            if( self->capture.framesPerBuffer == self->playback.framesPerBuffer )
-            {
-                framesPerHostBuffer = self->capture.framesPerBuffer;
-            }
-            else
-            {
-                framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer );
-                *hostBufferSizeMode = paUtilBoundedHostBufferSize;
-            }
-        }
-    }
-    else    /* half-duplex is a slightly simpler case */
-    {
-        if( self->capture.pcm )
-        {
-            PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->capture, inputParameters, framesPerUserBuffer,
-                        sampleRate, hwParamsCapture, &accurate) );
-            framesPerHostBuffer = self->capture.framesPerBuffer;
-        }
-        else
-        {
-            assert( self->playback.pcm );
-            PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->playback, outputParameters, framesPerUserBuffer,
-                        sampleRate, hwParamsPlayback, &accurate ) );
-            framesPerHostBuffer = self->playback.framesPerBuffer;
-        }
-    }
-
-    PA_UNLESS( framesPerHostBuffer != 0, paInternalError );
-    self->maxFramesPerHostBuffer = framesPerHostBuffer;
-
-    if( !accurate )
-    {
-        /* Don't know the exact size per host buffer */
-        *hostBufferSizeMode = paUtilBoundedHostBufferSize;
-        /* Raise upper bound */
-        ++self->maxFramesPerHostBuffer;
-    }
-
-error:
-    return result;
-}
-
-/** Set up ALSA stream parameters.
- *
- */
-static PaError PaAlsaStream_Configure( PaAlsaStream *self, const PaStreamParameters *inParams, const PaStreamParameters*
-        outParams, double sampleRate, unsigned long framesPerUserBuffer, double* inputLatency, double* outputLatency,
-        PaUtilHostBufferSizeMode* hostBufferSizeMode )
-{
-    PaError result = paNoError;
-    double realSr = sampleRate;
-    snd_pcm_hw_params_t* hwParamsCapture, * hwParamsPlayback;
-
-    snd_pcm_hw_params_alloca( &hwParamsCapture );
-    snd_pcm_hw_params_alloca( &hwParamsPlayback );
-
-    if( self->capture.pcm )
-        PA_ENSURE( PaAlsaStreamComponent_InitialConfigure( &self->capture, inParams, self->primeBuffers, hwParamsCapture,
-                    &realSr ) );
-    if( self->playback.pcm )
-        PA_ENSURE( PaAlsaStreamComponent_InitialConfigure( &self->playback, outParams, self->primeBuffers, hwParamsPlayback,
-                    &realSr ) );
-
-    PA_ENSURE( PaAlsaStream_DetermineFramesPerBuffer( self, realSr, inParams, outParams, framesPerUserBuffer,
-                hwParamsCapture, hwParamsPlayback, hostBufferSizeMode ) );
-
-    if( self->capture.pcm )
-    {
-        assert( self->capture.framesPerBuffer != 0 );
-        PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->capture, hwParamsCapture, inParams, self->primeBuffers, realSr,
-                    inputLatency ) );
-        PA_DEBUG(( "%s: Capture period size: %lu, latency: %f\n", __FUNCTION__, self->capture.framesPerBuffer, *inputLatency ));
-    }
-    if( self->playback.pcm )
-    {
-        assert( self->playback.framesPerBuffer != 0 );
-        PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->playback, hwParamsPlayback, outParams, self->primeBuffers, realSr,
-                    outputLatency ) );
-        PA_DEBUG(( "%s: Playback period size: %lu, latency: %f\n", __FUNCTION__, self->playback.framesPerBuffer, *outputLatency ));
-    }
-
-    /* Should be exact now */
-    self->streamRepresentation.streamInfo.sampleRate = realSr;
-
-    /* this will cause the two streams to automatically start/stop/prepare in sync.
-     * We only need to execute these operations on one of the pair.
-     * A: We don't want to do this on a blocking stream.
-     */
-    if( self->callbackMode && self->capture.pcm && self->playback.pcm )
-    {
-        int err = snd_pcm_link( self->capture.pcm, self->playback.pcm );
-        if( err == 0 )
-            self->pcmsSynced = 1;
-        else
-            PA_DEBUG(( "%s: Unable to sync pcms: %s\n", __FUNCTION__, snd_strerror( err ) ));
-    }
-
-    {
-        unsigned long minFramesPerHostBuffer = PA_MIN( self->capture.pcm ? self->capture.framesPerBuffer : ULONG_MAX,
-            self->playback.pcm ? self->playback.framesPerBuffer : ULONG_MAX );
-        self->pollTimeout = CalculatePollTimeout( self, minFramesPerHostBuffer );    /* Period in msecs, rounded up */
-
-        /* Time before watchdog unthrottles realtime thread == 1/4 of period time in msecs */
-        self->threading.throttledSleepTime = (unsigned long) (minFramesPerHostBuffer / sampleRate / 4 * 1000);
-    }
-
-    if( self->callbackMode )
-    {
-        /* If the user expects a certain number of frames per callback we will either have to rely on block adaption
-         * (framesPerHostBuffer is not an integer multiple of framesPerBuffer) or we can simply align the number
-         * of host buffer frames with what the user specified */
-        if( self->framesPerUserBuffer != paFramesPerBufferUnspecified )
-        {
-            /* self->alignFrames = 1; */
-
-            /* Unless the ratio between number of host and user buffer frames is an integer we will have to rely
-             * on block adaption */
-        /*
-            if( framesPerHostBuffer % framesPerBuffer != 0 || (self->capture.pcm && self->playback.pcm &&
-                        self->capture.framesPerBuffer != self->playback.framesPerBuffer) )
-                self->useBlockAdaption = 1;
-            else
-                self->alignFrames = 1;
-        */
-        }
-    }
-
-error:
-    return result;
-}
-
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback* callback,
-                           void *userData )
-{
-    PaError result = paNoError;
-    PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi;
-    PaAlsaStream *stream = NULL;
-    PaSampleFormat hostInputSampleFormat = 0, hostOutputSampleFormat = 0;
-    PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0;
-    int numInputChannels = 0, numOutputChannels = 0;
-    PaTime inputLatency, outputLatency;
-    /* Operate with fixed host buffer size by default, since other modes will invariably lead to block adaption */
-    /* XXX: Use Bounded by default? Output tends to get stuttery with Fixed ... */
-    PaUtilHostBufferSizeMode hostBufferSizeMode = paUtilFixedHostBufferSize;
-
-    if( (streamFlags & paPlatformSpecificFlags) != 0 )
-        return paInvalidFlag;
-
-    if( inputParameters )
-    {
-        PA_ENSURE( ValidateParameters( inputParameters, hostApi, StreamDirection_In ) );
-
-        numInputChannels = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-    }
-    if( outputParameters )
-    {
-        PA_ENSURE( ValidateParameters( outputParameters, hostApi, StreamDirection_Out ) );
-
-        numOutputChannels = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-    }
-
-    /* XXX: Why do we support this anyway? */
-    if( framesPerBuffer == paFramesPerBufferUnspecified && getenv( "PA_ALSA_PERIODSIZE" ) != NULL )
-    {
-        PA_DEBUG(( "%s: Getting framesPerBuffer from environment\n", __FUNCTION__ ));
-        framesPerBuffer = atoi( getenv("PA_ALSA_PERIODSIZE") );
-    }
-
-    PA_UNLESS( stream = (PaAlsaStream*)PaUtil_AllocateMemory( sizeof(PaAlsaStream) ), paInsufficientMemory );
-    PA_ENSURE( PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate,
-                framesPerBuffer, callback, streamFlags, userData ) );
-
-    PA_ENSURE( PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer,
-                &inputLatency, &outputLatency, &hostBufferSizeMode ) );
-    hostInputSampleFormat = stream->capture.hostSampleFormat;
-    hostOutputSampleFormat = stream->playback.hostSampleFormat;
-
-    PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
-                    numInputChannels, inputSampleFormat, hostInputSampleFormat,
-                    numOutputChannels, outputSampleFormat, hostOutputSampleFormat,
-                    sampleRate, streamFlags, framesPerBuffer, stream->maxFramesPerHostBuffer,
-                    hostBufferSizeMode, callback, userData ) );
-
-    /* Ok, buffer processor is initialized, now we can deduce it's latency */
-    if( numInputChannels > 0 )
-        stream->streamRepresentation.streamInfo.inputLatency = inputLatency + PaUtil_GetBufferProcessorInputLatency(
-                &stream->bufferProcessor );
-    if( numOutputChannels > 0 )
-        stream->streamRepresentation.streamInfo.outputLatency = outputLatency + PaUtil_GetBufferProcessorOutputLatency(
-                &stream->bufferProcessor );
-
-    *s = (PaStream*)stream;
-
-    return result;
-
-error:
-    if( stream )
-    {
-        PA_DEBUG(( "%s: Stream in error, terminating\n", __FUNCTION__ ));
-        PaAlsaStream_Terminate( stream );
-    }
-
-    return result;
-}
-
-static PaError CloseStream( PaStream* s )
-{
-    PaError result = paNoError;
-    PaAlsaStream *stream = (PaAlsaStream*)s;
-
-    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
-    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
-
-    PaAlsaStream_Terminate( stream );
-
-    return result;
-}
-
-static void SilenceBuffer( PaAlsaStream *stream )
-{
-    const snd_pcm_channel_area_t *areas;
-    snd_pcm_uframes_t frames = (snd_pcm_uframes_t)snd_pcm_avail_update( stream->playback.pcm ), offset;
-
-    snd_pcm_mmap_begin( stream->playback.pcm, &areas, &offset, &frames );
-    snd_pcm_areas_silence( areas, offset, stream->playback.numHostChannels, frames, stream->playback.nativeFormat );
-    snd_pcm_mmap_commit( stream->playback.pcm, offset, frames );
-}
-
-/** Start/prepare pcm(s) for streaming.
- *
- * Depending on wether the stream is in callback or blocking mode, we will respectively start or simply
- * prepare the playback pcm. If the buffer has _not_ been primed, we will in callback mode prepare and
- * silence the buffer before starting playback. In blocking mode we simply prepare, as the playback will
- * be started automatically as the user writes to output. 
- *
- * The capture pcm, however, will simply be prepared and started.
- *
- * PaAlsaStream::startMtx makes sure access is synchronized (useful in callback mode)
- */
-static PaError AlsaStart( PaAlsaStream *stream, int priming )
-{
-    PaError result = paNoError;
-
-    if( stream->playback.pcm )
-    {
-        if( stream->callbackMode )
-        {
-            if( !priming )
-            {
-                /* Buffer isn't primed, so prepare and silence */
-                ENSURE_( snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError );
-                SilenceBuffer( stream );
-            }
-            ENSURE_( snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError );
-        }
-        else
-            ENSURE_( snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError );
-    }
-    if( stream->capture.pcm && !stream->pcmsSynced )
-    {
-        ENSURE_( snd_pcm_prepare( stream->capture.pcm ), paUnanticipatedHostError );
-        /* For a blocking stream we want to start capture as well, since nothing will happen otherwise */
-        ENSURE_( snd_pcm_start( stream->capture.pcm ), paUnanticipatedHostError );
-    }
-
-end:
-    return result;
-error:
-    goto end;
-}
-
-/** Utility function for determining if pcms are in running state.
- *
- */
-static int IsRunning( PaAlsaStream *stream )
-{
-    int result = 0;
-
-    LockMutex( &stream->stateMtx );
-    if( stream->capture.pcm )
-    {
-        snd_pcm_state_t capture_state = snd_pcm_state( stream->capture.pcm );
-
-        if( capture_state == SND_PCM_STATE_RUNNING || capture_state == SND_PCM_STATE_XRUN
-                || capture_state == SND_PCM_STATE_DRAINING )
-        {
-            result = 1;
-            goto end;
-        }
-    }
-
-    if( stream->playback.pcm )
-    {
-        snd_pcm_state_t playback_state = snd_pcm_state( stream->playback.pcm );
-
-        if( playback_state == SND_PCM_STATE_RUNNING || playback_state == SND_PCM_STATE_XRUN
-                || playback_state == SND_PCM_STATE_DRAINING )
-        {
-            result = 1;
-            goto end;
-        }
-    }
-
-end:
-    ASSERT_CALL_( UnlockMutex( &stream->stateMtx ), paNoError );
-
-    return result;
-}
-
-static PaError StartStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaAlsaStream *stream = (PaAlsaStream*)s;
-    int streamStarted = 0;  /* So we can know wether we need to take the stream down */
-
-    /* Ready the processor */
-    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
-
-    /* Set now, so we can test for activity further down */
-    stream->isActive = 1;
-
-    if( stream->callbackMode )
-    {
-        int res = 0;
-        PaTime pt = PaUtil_GetTime();
-        struct timespec ts;
-
-        PA_ENSURE( CreateCallbackThread( &stream->threading, &CallbackThreadFunc, stream ) );
-        streamStarted = 1;
-
-        /* Wait for stream to be started */
-        ts.tv_sec = (time_t) floor( pt + 1 );
-        ts.tv_nsec = (long) ((pt - floor( pt )) * 1000000000);
-
-        /* Since we'll be holding a lock on the startMtx (when not waiting on the condition), IsRunning won't be checking
-         * stream state at the same time as the callback thread affects it. We also check IsStreamActive, in the unlikely
-         * case the callback thread exits in the meantime (the stream will be considered inactive after the thread exits) */
-        PA_ENSURE( LockMutex( &stream->startMtx ) );
-
-        /* Due to possible spurious wakeups, we enclose in a loop */
-        while( !IsRunning( stream ) && IsStreamActive( s ) && !res )
-        {
-            res = pthread_cond_timedwait( &stream->startCond, &stream->startMtx, &ts );
-        }
-        PA_ENSURE( UnlockMutex( &stream->startMtx ) );
-
-        PA_UNLESS( !res || res == ETIMEDOUT, paInternalError );
-        PA_DEBUG(( "%s: Waited for %g seconds for stream to start\n", __FUNCTION__, PaUtil_GetTime() - pt ));
-
-        if( res == ETIMEDOUT )
-        {
-            PA_ENSURE( paTimedOut );
-        }
-    }
-    else
-    {
-        PA_ENSURE( AlsaStart( stream, 0 ) );
-        streamStarted = 1;
-    }
-
-end:
-    return result;
-error:
-    if( streamStarted )
-        AbortStream( stream );
-    stream->isActive = 0;
-    
-    goto end;
-}
-
-static PaError AlsaStop( PaAlsaStream *stream, int abort )
-{
-    PaError result = paNoError;
-
-    if( abort )
-    {
-        if( stream->playback.pcm )
-        {
-            ENSURE_( snd_pcm_drop( stream->playback.pcm ), paUnanticipatedHostError );
-        }
-        if( stream->capture.pcm && !stream->pcmsSynced )
-        {
-            ENSURE_( snd_pcm_drop( stream->capture.pcm ), paUnanticipatedHostError );
-        }
-
-        PA_DEBUG(( "%s: Dropped frames\n", __FUNCTION__ ));
-    }
-    else
-    {
-        if( stream->playback.pcm )
-        {
-            ENSURE_( snd_pcm_nonblock( stream->playback.pcm, 0 ), paUnanticipatedHostError );
-            if( snd_pcm_drain( stream->playback.pcm ) < 0 )
-            {
-                PA_DEBUG(( "%s: Draining playback handle failed!\n", __FUNCTION__ ));
-            }
-        }
-        if( stream->capture.pcm && !stream->pcmsSynced )
-        {
-            /* We don't need to retrieve any remaining frames */
-            if( snd_pcm_drop( stream->capture.pcm ) < 0 )
-            {
-                PA_DEBUG(( "%s: Draining capture handle failed!\n", __FUNCTION__ ));
-            }
-        }
-    }
-
-end:
-    return result;
-error:
-    goto end;
-}
-
-/** Stop or abort stream.
- *
- * If a stream is in callback mode we will have to inspect wether the background thread has
- * finished, or we will have to take it out. In either case we join the thread before
- * returning. In blocking mode, we simply tell ALSA to stop abruptly (abort) or finish
- * buffers (drain)
- *
- * Stream will be considered inactive (!PaAlsaStream::isActive) after a call to this function
- */
-static PaError RealStop( PaAlsaStream *stream, int abort )
-{
-    PaError result = paNoError;
-
-    /* First deal with the callback thread, cancelling and/or joining
-     * it if necessary
-     */
-    if( stream->callbackMode )
-    {
-        PaError threadRes, watchdogRes;
-        stream->callbackAbort = abort;
-
-        if( !abort )
-        {
-            PA_DEBUG(( "Stopping callback\n" ));
-            stream->callbackStop = 1;
-        }
-        PA_ENSURE( KillCallbackThread( &stream->threading, !abort, &threadRes, &watchdogRes ) );
-        if( threadRes != paNoError )
-            PA_DEBUG(( "Callback thread returned: %d\n", threadRes ));
-        if( watchdogRes != paNoError )
-            PA_DEBUG(( "Watchdog thread returned: %d\n", watchdogRes ));
-
-        stream->callbackStop = 0;   /* The deed is done */
-        stream->callback_finished = 0;
-    }
-    else
-    {
-        PA_ENSURE( AlsaStop( stream, abort ) );
-    }
-
-    stream->isActive = 0;
-
-end:
-    return result;
-
-error:
-    goto end;
-}
-
-static PaError StopStream( PaStream *s )
-{
-    return RealStop( (PaAlsaStream *) s, 0 );
-}
-
-static PaError AbortStream( PaStream *s )
-{
-    return RealStop( (PaAlsaStream * ) s, 1 );
-}
-
-/** The stream is considered stopped before StartStream, or AFTER a call to Abort/StopStream (callback
- * returning !paContinue is not considered)
- *
- */
-static PaError IsStreamStopped( PaStream *s )
-{
-    PaAlsaStream *stream = (PaAlsaStream *)s;
-
-    /* callback_finished indicates we need to join callback thread (ie. in Abort/StopStream) */
-    return !IsStreamActive( s ) && !stream->callback_finished;
-}
-
-static PaError IsStreamActive( PaStream *s )
-{
-    PaAlsaStream *stream = (PaAlsaStream*)s;
-    return stream->isActive;
-}
-
-static PaTime GetStreamTime( PaStream *s )
-{
-    PaAlsaStream *stream = (PaAlsaStream*)s;
-
-    snd_timestamp_t timestamp;
-    snd_pcm_status_t* status;
-    snd_pcm_status_alloca( &status );
-
-    /* TODO: what if we have both?  does it really matter? */
-
-    /* TODO: if running in callback mode, this will mean
-     * libasound routines are being called from multiple threads.
-     * need to verify that libasound is thread-safe. */
-
-    if( stream->capture.pcm )
-    {
-        snd_pcm_status( stream->capture.pcm, status );
-    }
-    else if( stream->playback.pcm )
-    {
-        snd_pcm_status( stream->playback.pcm, status );
-    }
-
-    snd_pcm_status_get_tstamp( status, &timestamp );
-    return timestamp.tv_sec + (PaTime)timestamp.tv_usec / 1e6;
-}
-
-static double GetStreamCpuLoad( PaStream* s )
-{
-    PaAlsaStream *stream = (PaAlsaStream*)s;
-
-    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
-}
-
-static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate )
-{
-    unsigned long approx = (unsigned long) sampleRate;
-    int dir = 0;
-    double fraction = sampleRate - approx;
-
-    assert( pcm && hwParams );
-
-    if( fraction > 0.0 )
-    {
-        if( fraction > 0.5 )
-        {
-            ++approx;
-            dir = -1;
-        }
-        else
-            dir = 1;
-    }
-
-    return snd_pcm_hw_params_set_rate( pcm, hwParams, approx, dir );
-}
-
-/* Return exact sample rate in param sampleRate */
-static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate )
-{
-    unsigned int num, den;
-    int err; 
-
-    assert( hwParams );
-
-    err = snd_pcm_hw_params_get_rate_numden( hwParams, &num, &den );
-    *sampleRate = (double) num / den;
-
-    return err;
-}
-
-/* Utility functions for blocking/callback interfaces */
-
-/* Atomic restart of stream (we don't want the intermediate state visible) */
-static PaError AlsaRestart( PaAlsaStream *stream )
-{
-    PaError result = paNoError;
-
-    PA_ENSURE( LockMutex( &stream->stateMtx ) );
-    PA_ENSURE( AlsaStop( stream, 0 ) );
-    PA_ENSURE( AlsaStart( stream, 0 ) );
-
-    PA_DEBUG(( "%s: Restarted audio\n", __FUNCTION__ ));
-
-error:
-    PA_ENSURE( UnlockMutex( &stream->stateMtx ) );
-
-    return result;
-}
-
-/** Recover from xrun state.
- *
- */
-static PaError PaAlsaStream_HandleXrun( PaAlsaStream *self )
-{
-    PaError result = paNoError;
-    snd_pcm_status_t *st;
-    PaTime now = PaUtil_GetTime();
-    snd_timestamp_t t;
-
-    snd_pcm_status_alloca( &st );
-
-    if( self->playback.pcm )
-    {
-        snd_pcm_status( self->playback.pcm, st );
-        if( snd_pcm_status_get_state( st ) == SND_PCM_STATE_XRUN )
-        {
-            snd_pcm_status_get_trigger_tstamp( st, &t );
-            self->underrun = now * 1000 - ((PaTime) t.tv_sec * 1000 + (PaTime) t.tv_usec / 1000);
-        }
-    }
-    if( self->capture.pcm )
-    {
-        snd_pcm_status( self->capture.pcm, st );
-        if( snd_pcm_status_get_state( st ) == SND_PCM_STATE_XRUN )
-        {
-            snd_pcm_status_get_trigger_tstamp( st, &t );
-            self->overrun = now * 1000 - ((PaTime) t.tv_sec * 1000 + (PaTime) t.tv_usec / 1000);
-        }
-    }
-
-    PA_ENSURE( AlsaRestart( self ) );
-
-end:
-    return result;
-error:
-    goto end;
-}
-
-/** Decide if we should continue polling for specified direction, eventually adjust the poll timeout.
- * 
- */
-static PaError ContinuePoll( const PaAlsaStream *stream, StreamDirection streamDir, int *pollTimeout, int *continuePoll )
-{
-    PaError result = paNoError;
-    snd_pcm_sframes_t delay, margin;
-    int err;
-    const PaAlsaStreamComponent *component = NULL, *otherComponent = NULL;
-
-    *continuePoll = 1;
-
-    if( StreamDirection_In == streamDir )
-    {
-        component = &stream->capture;
-        otherComponent = &stream->playback;
-    }
-    else
-    {
-        component = &stream->playback;
-        otherComponent = &stream->capture;
-    }
-
-    /* ALSA docs say that negative delay should indicate xrun, but in my experience snd_pcm_delay returns -EPIPE */
-    if( (err = snd_pcm_delay( otherComponent->pcm, &delay )) < 0 )
-    {
-        if( err == -EPIPE )
-        {
-            /* Xrun */
-            *continuePoll = 0;
-            goto error;
-        }
-
-        ENSURE_( err, paUnanticipatedHostError );
-    }
-
-    if( StreamDirection_Out == streamDir )
-    {
-        /* Number of eligible frames before capture overrun */
-        delay = otherComponent->bufferSize - delay;
-    }
-    margin = delay - otherComponent->framesPerBuffer / 2;
-
-    if( margin < 0 )
-    {
-        PA_DEBUG(( "%s: Stopping poll for %s\n", __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback" ));
-        *continuePoll = 0;
-    }
-    else if( margin < otherComponent->framesPerBuffer )
-    {
-        *pollTimeout = CalculatePollTimeout( stream, margin );
-        PA_DEBUG(( "%s: Trying to poll again for %s frames, pollTimeout: %d\n",
-                    __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback", *pollTimeout ));
-    }
-
-error:
-    return result;
-}
-
-/* Callback interface */
-
-static void OnExit( void *data )
-{
-    PaAlsaStream *stream = (PaAlsaStream *) data;
-
-    assert( data );
-
-    PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer );
-
-    stream->callback_finished = 1;  /* Let the outside world know stream was stopped in callback */
-    PA_DEBUG(( "%s: Stopping ALSA handles\n", __FUNCTION__ ));
-    AlsaStop( stream, stream->callbackAbort );
-    stream->callbackAbort = 0;      /* Clear state */
-    
-    PA_DEBUG(( "%s: Stoppage\n", __FUNCTION__ ));
-
-    /* Eventually notify user all buffers have played */
-    if( stream->streamRepresentation.streamFinishedCallback )
-        stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
-    stream->isActive = 0;
-}
-
-static void CalculateTimeInfo( PaAlsaStream *stream, PaStreamCallbackTimeInfo *timeInfo )
-{
-    snd_pcm_status_t *capture_status, *playback_status;
-    snd_timestamp_t capture_timestamp, playback_timestamp;
-    PaTime capture_time = 0., playback_time = 0.;
-
-    snd_pcm_status_alloca( &capture_status );
-    snd_pcm_status_alloca( &playback_status );
-
-    if( stream->capture.pcm )
-    {
-        snd_pcm_sframes_t capture_delay;
-
-        snd_pcm_status( stream->capture.pcm, capture_status );
-        snd_pcm_status_get_tstamp( capture_status, &capture_timestamp );
-
-        capture_time = capture_timestamp.tv_sec +
-            ((PaTime)capture_timestamp.tv_usec / 1000000.0);
-        timeInfo->currentTime = capture_time;
-
-        capture_delay = snd_pcm_status_get_delay( capture_status );
-        timeInfo->inputBufferAdcTime = timeInfo->currentTime -
-            (PaTime)capture_delay / stream->streamRepresentation.streamInfo.sampleRate;
-    }
-    if( stream->playback.pcm )
-    {
-        snd_pcm_sframes_t playback_delay;
-
-        snd_pcm_status( stream->playback.pcm, playback_status );
-        snd_pcm_status_get_tstamp( playback_status, &playback_timestamp );
-
-        playback_time = playback_timestamp.tv_sec +
-            ((PaTime)playback_timestamp.tv_usec / 1000000.0);
-
-        if( stream->capture.pcm ) /* Full duplex */
-        {
-            /* Hmm, we have both a playback and a capture timestamp.
-             * Hopefully they are the same... */
-            if( fabs( capture_time - playback_time ) > 0.01 )
-                PA_DEBUG(("Capture time and playback time differ by %f\n", fabs(capture_time-playback_time)));
-        }
-        else
-            timeInfo->currentTime = playback_time;
-
-        playback_delay = snd_pcm_status_get_delay( playback_status );
-        timeInfo->outputBufferDacTime = timeInfo->currentTime +
-            (PaTime)playback_delay / stream->streamRepresentation.streamInfo.sampleRate;
-    }
-}
-
-/** Called after buffer processing is finished.
- *
- * A number of mmapped frames is committed, it is possible that an xrun has occurred in the meantime.
- *
- * @param numFrames The number of frames that has been processed
- * @param xrun Return whether an xrun has occurred
- */
-static PaError PaAlsaStreamComponent_EndProcessing( PaAlsaStreamComponent *self, unsigned long numFrames, int *xrun )
-{
-    PaError result = paNoError;
-    int res;
-
-    /* @concern FullDuplex It is possible that only one direction is marked ready after polling, and processed
-     * afterwards
-     */
-    if( !self->ready )
-        goto end;
-
-    res = snd_pcm_mmap_commit( self->pcm, self->offset, numFrames );
-    if( res == -EPIPE || res == -ESTRPIPE )
-    {
-        *xrun = 1;
-    }
-    else
-    {
-        ENSURE_( res, paUnanticipatedHostError );
-    }
-
-end:
-error:
-    return result;
-}
-
-/* Extract buffer from channel area */
-static unsigned char *ExtractAddress( const snd_pcm_channel_area_t *area, snd_pcm_uframes_t offset )
-{
-    return (unsigned char *) area->addr + (area->first + offset * area->step) / 8;
-}
-
-/** Do necessary adaption between user and host channels.
- *
-    @concern ChannelAdaption Adapting between user and host channels can involve silencing unused channels and
-    duplicating mono information if host outputs come in pairs.
- */
-static PaError PaAlsaStreamComponent_DoChannelAdaption( PaAlsaStreamComponent *self, PaUtilBufferProcessor *bp, int numFrames )
-{
-    PaError result = paNoError;
-    unsigned char *p;
-    int i;
-    int unusedChans = self->numHostChannels - self->numUserChannels;
-    unsigned char *src, *dst;
-    int convertMono = (self->numHostChannels % 2) == 0 && (self->numUserChannels % 2) != 0;
-
-    assert( StreamDirection_Out == self->streamDir );
-
-    if( self->hostInterleaved )
-    {
-        int swidth = snd_pcm_format_size( self->nativeFormat, 1 );
-        unsigned char *buffer = ExtractAddress( self->channelAreas, self->offset );
-
-        /* Start after the last user channel */
-        p = buffer + self->numUserChannels * swidth;
-
-        if( convertMono )
-        {
-            /* Convert the last user channel into stereo pair */
-            src = buffer + (self->numUserChannels - 1) * swidth;
-            for( i = 0; i < numFrames; ++i )
-            {
-                dst = src + swidth;
-                memcpy( dst, src, swidth );
-                src += self->numHostChannels * swidth;
-            }
-
-            /* Don't touch the channel we just wrote to */
-            p += swidth;
-            --unusedChans;
-        }
-
-        if( unusedChans > 0 )
-        {
-            /* Silence unused output channels */
-            for( i = 0; i < numFrames; ++i )
-            {
-                memset( p, 0, swidth * unusedChans );
-                p += self->numHostChannels * swidth;
-            }
-        }
-    }
-    else
-    {
-        /* We extract the last user channel */
-        if( convertMono )
-        {
-            ENSURE_( snd_pcm_area_copy( self->channelAreas + self->numUserChannels, self->offset, self->channelAreas +
-                    (self->numUserChannels - 1), self->offset, numFrames, self->nativeFormat ), paUnanticipatedHostError );
-            --unusedChans;
-        }
-        if( unusedChans > 0 )
-        {
-            snd_pcm_areas_silence( self->channelAreas + (self->numHostChannels - unusedChans), self->offset, unusedChans, numFrames,
-                    self->nativeFormat );
-        }
-    }
-
-error:
-    return result;
-}
-
-static PaError PaAlsaStream_EndProcessing( PaAlsaStream *self, unsigned long numFrames, int *xrunOccurred )
-{
-    PaError result = paNoError;
-    int xrun = 0;
-
-    if( self->capture.pcm )
-    {
-        PA_ENSURE( PaAlsaStreamComponent_EndProcessing( &self->capture, numFrames, &xrun ) );
-    }
-    if( self->playback.pcm )
-    {
-        if( self->playback.numHostChannels > self->playback.numUserChannels )
-            PA_ENSURE( PaAlsaStreamComponent_DoChannelAdaption( &self->playback, &self->bufferProcessor, numFrames ) );
-        PA_ENSURE( PaAlsaStreamComponent_EndProcessing( &self->playback, numFrames, &xrun ) );
-    }
-
-error:
-    *xrunOccurred = xrun;
-    return result;
-}
-
-/** Update the number of available frames.
- *
- */
-static PaError PaAlsaStreamComponent_GetAvailableFrames( PaAlsaStreamComponent *self, unsigned long *numFrames, int *xrunOccurred )
-{
-    PaError result = paNoError;
-    snd_pcm_sframes_t framesAvail = snd_pcm_avail_update( self->pcm );
-    *xrunOccurred = 0;
-
-    if( -EPIPE == framesAvail )
-    {
-        *xrunOccurred = 1;
-        framesAvail = 0;
-    }
-    else
-        ENSURE_( framesAvail, paUnanticipatedHostError );
-
-    *numFrames = framesAvail;
-
-error:
-    return result;
-}
-
-/** Fill in pollfd objects.
- */
-static PaError PaAlsaStreamComponent_BeginPolling( PaAlsaStreamComponent* self, struct pollfd* pfds )
-{
-    PaError result = paNoError;
-    int ret = snd_pcm_poll_descriptors( self->pcm, pfds, self->nfds );
-    (void)ret;  /* Prevent unused variable warning if asserts are turned off */
-    assert( ret == self->nfds );
-
-    self->ready = 0;
-
-    return result;
-}
-
-/** Examine results from poll().
- *
- * @param pfds pollfds to inspect
- * @param shouldPoll Should we continue to poll
- * @param xrun Has an xrun occurred
- */
-static PaError PaAlsaStreamComponent_EndPolling( PaAlsaStreamComponent* self, struct pollfd* pfds, int* shouldPoll, int* xrun )
-{
-    PaError result = paNoError;
-    unsigned short revents;
-
-    ENSURE_( snd_pcm_poll_descriptors_revents( self->pcm, pfds, self->nfds, &revents ), paUnanticipatedHostError );
-    if( revents != 0 )
-    {
-        if( revents & POLLERR )
-        {
-            *xrun = 1;
-        }
-        else
-            self->ready = 1;
-
-        *shouldPoll = 0;
-    }
-
-error:
-    return result;
-}
-
-/** Return the number of available frames for this stream.
- *
- * @concern FullDuplex The minimum available for the two directions is calculated, it might be desirable to ignore
- * one direction however (not marked ready from poll), so this is controlled by queryCapture and queryPlayback.
- *
- * @param queryCapture Check available for capture
- * @param queryPlayback Check available for playback
- * @param available The returned number of frames
- * @param xrunOccurred Return whether an xrun has occurred
- */
-static PaError PaAlsaStream_GetAvailableFrames( PaAlsaStream *self, int queryCapture, int queryPlayback, unsigned long
-        *available, int *xrunOccurred )
-{
-    PaError result = paNoError;
-    unsigned long captureFrames, playbackFrames;
-    *xrunOccurred = 0;
-
-    assert( queryCapture || queryPlayback );
-
-    if( queryCapture )
-    {
-        assert( self->capture.pcm );
-        PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &self->capture, &captureFrames, xrunOccurred ) );
-        if( *xrunOccurred )
-            goto end;
-    }
-    if( queryPlayback )
-    {
-        assert( self->playback.pcm );
-        PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &self->playback, &playbackFrames, xrunOccurred ) );
-        if( *xrunOccurred )
-            goto end;
-    }
-
-    if( queryCapture && queryPlayback )
-    {
-        *available = PA_MIN( captureFrames, playbackFrames );
-        /*PA_DEBUG(("capture: %lu, playback: %lu, combined: %lu\n", captureFrames, playbackFrames, *available));*/
-    }
-    else if( queryCapture )
-    {
-        *available = captureFrames;
-    }
-    else
-    {
-        *available = playbackFrames;
-    }
-
-end:
-error:
-    return result;
-}
-
-/** Wait for and report available buffer space from ALSA.
- *
- * Unless ALSA reports a minimum of frames available for I/O, we poll the ALSA filedescriptors for more.
- * Both of these operations can uncover xrun conditions.
- *
- * @concern Xruns Both polling and querying available frames can report an xrun condition.
- *
- * @param framesAvail Return the number of available frames
- * @param xrunOccurred Return whether an xrun has occurred
- */ 
-static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *framesAvail, int *xrunOccurred )
-{
-    PaError result = paNoError;
-    int pollPlayback = self->playback.pcm != NULL, pollCapture = self->capture.pcm != NULL;
-    int pollTimeout = self->pollTimeout;
-    int xrun = 0;
-
-    assert( self );
-    assert( framesAvail );
-
-    if( !self->callbackMode )
-    {
-        /* In blocking mode we will only wait if necessary */
-        PA_ENSURE( PaAlsaStream_GetAvailableFrames( self, self->capture.pcm != NULL, self->playback.pcm != NULL,
-                    framesAvail, &xrun ) );
-        if( xrun )
-        {
-            goto end;
-        }
-
-        if( *framesAvail > 0 )
-        {
-            /* Mark pcms ready from poll */
-            if( self->capture.pcm )
-                self->capture.ready = 1;
-            if( self->playback.pcm )
-                self->playback.ready = 1;
-
-            goto end;
-        }
-    }
-
-    while( pollPlayback || pollCapture )
-    {
-        int totalFds = 0;
-        struct pollfd *capturePfds = NULL, *playbackPfds = NULL;
-
-        pthread_testcancel();
-
-        if( pollCapture )
-        {
-            capturePfds = self->pfds;
-            PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->capture, capturePfds ) );
-            totalFds += self->capture.nfds;
-        }
-        if( pollPlayback )
-        {
-            playbackPfds = self->pfds + (self->capture.pcm ? self->capture.nfds : 0);
-            PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->playback, playbackPfds ) );
-            totalFds += self->playback.nfds;
-        }
-        
-        if( poll( self->pfds, totalFds, pollTimeout ) < 0 )
-        {
-            /*  XXX: Depend on preprocessor condition? */
-            if( errno == EINTR )
-            {
-                /* gdb */
-                continue;
-            }
-
-            /* TODO: Add macro for checking system calls */
-            PA_ENSURE( paInternalError );
-        }
-
-        /* check the return status of our pfds */
-        if( pollCapture )
-        {
-            PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->capture, capturePfds, &pollCapture, &xrun ) );
-        }
-        if( pollPlayback )
-        {
-            PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->playback, playbackPfds, &pollPlayback, &xrun ) );
-        }
-        if( xrun )
-        {
-            break;
-        }
-
-        /* @concern FullDuplex If only one of two pcms is ready we may want to compromise between the two.
-         * If there is less than half a period's worth of samples left of frames in the other pcm's buffer we will
-         * stop polling.
-         */
-        if( self->capture.pcm && self->playback.pcm )
-        {
-            if( pollCapture && !pollPlayback )
-            {
-                PA_ENSURE( ContinuePoll( self, StreamDirection_In, &pollTimeout, &pollCapture ) );
-            }
-            else if( pollPlayback && !pollCapture )
-            {
-                PA_ENSURE( ContinuePoll( self, StreamDirection_Out, &pollTimeout, &pollPlayback ) );
-            }
-        }
-    }
-
-    if( !xrun )
-    {
-        /* Get the number of available frames for the pcms that are marked ready.
-         * @concern FullDuplex If only one direction is marked ready (from poll), the number of frames available for
-         * the other direction is returned. Output is normally preferred over capture however, so capture frames may be
-         * discarded to avoid overrun unless paNeverDropInput is specified.
-         */
-        int captureReady = self->capture.pcm ? self->capture.ready : 0,
-            playbackReady = self->playback.pcm ? self->playback.ready : 0;
-        PA_ENSURE( PaAlsaStream_GetAvailableFrames( self, captureReady, playbackReady, framesAvail, &xrun ) );
-
-        if( self->capture.pcm && self->playback.pcm )
-        {
-            if( !self->playback.ready && !self->neverDropInput )
-            {
-                /* Drop input, a period's worth */
-                assert( self->capture.ready );
-                PaAlsaStreamComponent_EndProcessing( &self->capture, PA_MIN( self->capture.framesPerBuffer,
-                            *framesAvail ), &xrun );
-                *framesAvail = 0;
-                self->capture.ready = 0;
-            }
-        }
-        else if( self->capture.pcm )
-            assert( self->capture.ready );
-        else
-            assert( self->playback.ready );
-    }
-
-end:
-error:
-    if( xrun )
-    {
-        /* Recover from the xrun state */
-        PA_ENSURE( PaAlsaStream_HandleXrun( self ) );
-        *framesAvail = 0;
-    }
-    else
-    {
-        if( 0 != *framesAvail )
-        {
-            /* If we're reporting frames eligible for processing, one of the handles better be ready */
-            PA_UNLESS( self->capture.ready || self->playback.ready, paInternalError );
-        }
-    }
-    *xrunOccurred = xrun;
-
-    return result;
-}
-
-/** Register per-channel ALSA buffer information with buffer processor.
- *
- * Mmapped buffer space is acquired from ALSA, and registered with the buffer processor. Differences between the
- * number of host and user channels is taken into account.
- * 
- * @param numFrames On entrance the number of requested frames, on exit the number of contiguously accessible frames.
- */
-static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* self, PaUtilBufferProcessor* bp,
-        unsigned long* numFrames, int* xrun )
-{
-    PaError result = paNoError;
-    const snd_pcm_channel_area_t *areas, *area;
-    void (*setChannel)(PaUtilBufferProcessor *, unsigned int, void *, unsigned int) =
-        StreamDirection_In == self->streamDir ? PaUtil_SetInputChannel : PaUtil_SetOutputChannel;
-    unsigned char *buffer, *p;
-    int i;
-    unsigned long framesAvail;
-
-    /* This _must_ be called before mmap_begin */
-    PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( self, &framesAvail, xrun ) );
-    if( *xrun )
-    {
-        *numFrames = 0;
-        goto end;
-    }
-
-    ENSURE_( snd_pcm_mmap_begin( self->pcm, &areas, &self->offset, numFrames ), paUnanticipatedHostError );
-
-    if( self->hostInterleaved )
-    {
-        int swidth = snd_pcm_format_size( self->nativeFormat, 1 );
-
-        p = buffer = ExtractAddress( areas, self->offset );
-        for( i = 0; i < self->numUserChannels; ++i )
-        {
-            /* We're setting the channels up to userChannels, but the stride will be hostChannels samples */
-            setChannel( bp, i, p, self->numHostChannels );
-            p += swidth;
-        }
-    }
-    else
-    {
-        for( i = 0; i < self->numUserChannels; ++i )
-        {
-            area = areas + i;
-            buffer = ExtractAddress( area, self->offset );
-            setChannel( bp, i, buffer, 1 );
-        }
-    }
-
-    /* @concern ChannelAdaption Buffer address is recorded so we can do some channel adaption later */
-    self->channelAreas = (snd_pcm_channel_area_t *)areas;
-
-end:
-error:
-    return result;
-}
-
-/** Initiate buffer processing.
- *
- * ALSA buffers are registered with the PA buffer processor and the buffer size (in frames) set.
- *
- * @concern FullDuplex If both directions are being processed, the minimum amount of frames for the two directions is
- * calculated.
- *
- * @param numFrames On entrance the number of available frames, on exit the number of received frames
- * @param xrunOccurred Return whether an xrun has occurred
- */
-static PaError PaAlsaStream_SetUpBuffers( PaAlsaStream* self, unsigned long* numFrames, int* xrunOccurred )
-{
-    PaError result = paNoError;
-    unsigned long captureFrames = ULONG_MAX, playbackFrames = ULONG_MAX, commonFrames = 0;
-    int xrun = 0;
-
-    if( *xrunOccurred )
-    {
-        *numFrames = 0;
-        return result;
-    }
-    /* If we got here at least one of the pcm's should be marked ready */
-    PA_UNLESS( self->capture.ready || self->playback.ready, paInternalError );
-
-    /* Extract per-channel ALSA buffer pointers and register them with the buffer processor.
-     * It is possible that a direction is not marked ready however, because it is out of sync with the other.
-     */
-    if( self->capture.pcm && self->capture.ready )
-    {
-        captureFrames = *numFrames;
-        PA_ENSURE( PaAlsaStreamComponent_RegisterChannels( &self->capture, &self->bufferProcessor, &captureFrames, 
-                    &xrun ) );
-    }
-    if( self->playback.pcm && self->playback.ready )
-    {
-        playbackFrames = *numFrames;
-        PA_ENSURE( PaAlsaStreamComponent_RegisterChannels( &self->playback, &self->bufferProcessor, &playbackFrames, 
-                    &xrun ) );
-    }
-    if( xrun )
-    {
-        /* Nothing more to do */
-        assert( 0 == commonFrames );
-        goto end;
-    }
-
-    commonFrames = PA_MIN( captureFrames, playbackFrames );
-    /* assert( commonFrames <= *numFrames ); */
-    if( commonFrames > *numFrames )
-    {
-        /* Hmmm ... how come there are more frames available than we requested!? Blah. */
-        PA_DEBUG(( "%s: Common available frames are reported to be more than number requested: %lu, %lu, callbackMode: %d\n", __FUNCTION__,
-                    commonFrames, *numFrames, self->callbackMode ));
-        if( self->capture.pcm )
-        {
-            PA_DEBUG(( "%s: captureFrames: %lu, capture.ready: %d\n", __FUNCTION__, captureFrames, self->capture.ready ));
-        }
-        if( self->playback.pcm )
-        {
-            PA_DEBUG(( "%s: playbackFrames: %lu, playback.ready: %d\n", __FUNCTION__, playbackFrames, self->playback.ready ));
-        }
-        
-        commonFrames = 0;
-        goto end;
-    }
-
-    /* Inform PortAudio of the number of frames we got.
-     * @concern FullDuplex We might be experiencing underflow in either end; if its an input underflow, we go on
-     * with output. If its output underflow however, depending on the paNeverDropInput flag, we may want to simply
-     * discard the excess input or call the callback with paOutputOverflow flagged.
-     */
-    if( self->capture.pcm )
-    {
-        if( self->capture.ready )
-        {
-            PaUtil_SetInputFrameCount( &self->bufferProcessor, commonFrames );
-        }
-        else
-        {
-            /* We have input underflow */
-            PaUtil_SetNoInput( &self->bufferProcessor );
-        }
-    }
-    if( self->playback.pcm )
-    {
-        if( self->playback.ready )
-        {
-            PaUtil_SetOutputFrameCount( &self->bufferProcessor, commonFrames );
-        }
-        else
-        {
-            /* We have output underflow, but keeping input data (paNeverDropInput) */
-            assert( self->neverDropInput );
-            assert( self->capture.pcm != NULL );
-            PA_DEBUG(( "%s: Setting output buffers to NULL\n", __FUNCTION__ ));
-            PaUtil_SetNoOutput( &self->bufferProcessor );
-        }
-    }
-    
-end:
-    *numFrames = commonFrames;
-error:
-    if( xrun )
-    {
-        PA_ENSURE( PaAlsaStream_HandleXrun( self ) );
-        *numFrames = 0;
-    }
-    *xrunOccurred = xrun;
-
-    return result;
-}
-
-/** Callback thread's function.
- *
- * Roughly, the workflow can be described in the following way: The number of available frames that can be processed
- * directly is obtained from ALSA, we then request as much directly accessible memory as possible within this amount
- * from ALSA. The buffer memory is registered with the PA buffer processor and processing is carried out with
- * PaUtil_EndBufferProcessing. Finally, the number of processed frames is reported to ALSA. The processing can
- * happen in several iterations untill we have consumed the known number of available frames (or an xrun is detected).
- */
-static void *CallbackThreadFunc( void *userData )
-{
-    PaError result = paNoError, *pres = NULL;
-    PaAlsaStream *stream = (PaAlsaStream*) userData;
-    PaStreamCallbackTimeInfo timeInfo = {0, 0, 0};
-    snd_pcm_sframes_t startThreshold = 0;
-    int callbackResult = paContinue;
-    PaStreamCallbackFlags cbFlags = 0;  /* We might want to keep state across iterations */
-    int streamStarted = 0;
-
-    assert( stream );
-
-    callbackThread_ = pthread_self();
-    /* Execute OnExit when exiting */
-    pthread_cleanup_push( &OnExit, stream );
-
-    /* Not implemented */
-    assert( !stream->primeBuffers );
-
-    /* @concern StreamStart If the output is being primed the output pcm needs to be prepared, otherwise the
-     * stream is started immediately. The latter involves signaling the waiting main thread.
-     */
-    if( stream->primeBuffers )
-    {
-        snd_pcm_sframes_t avail;
-        
-        if( stream->playback.pcm )
-            ENSURE_( snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError );
-        if( stream->capture.pcm && !stream->pcmsSynced )
-            ENSURE_( snd_pcm_prepare( stream->capture.pcm ), paUnanticipatedHostError );
-
-        /* We can't be certain that the whole ring buffer is available for priming, but there should be
-         * at least one period */
-        avail = snd_pcm_avail_update( stream->playback.pcm );
-        startThreshold = avail - (avail % stream->playback.framesPerBuffer);
-        assert( startThreshold >= stream->playback.framesPerBuffer );
-    }
-    else
-    {
-        PA_ENSURE( LockMutex( &stream->startMtx ) );
-        /* Buffer will be zeroed */
-        PA_ENSURE( AlsaStart( stream, 0 ) );
-        ENSURE_SYSTEM_( pthread_cond_signal( &stream->startCond ), 0 );
-        PA_ENSURE( UnlockMutex( &stream->startMtx ) );
-
-        streamStarted = 1;
-    }
-
-    while( 1 )
-    {
-        unsigned long framesAvail, framesGot;
-        int xrun = 0;
-
-        pthread_testcancel();
-
-        /* @concern StreamStop if the main thread has requested a stop and the stream has not been effectively
-         * stopped we signal this condition by modifying callbackResult (we'll want to flush buffered output).
-         */
-        if( stream->callbackStop && paContinue == callbackResult )
-        {
-            PA_DEBUG(( "Setting callbackResult to paComplete\n" ));
-            callbackResult = paComplete;
-        }
-
-        if( paContinue != callbackResult )
-        {
-            stream->callbackAbort = (paAbort == callbackResult);
-            if( stream->callbackAbort ||
-                    /** @concern BlockAdaption: Go on if adaption buffers are empty */
-                    PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) 
-                goto end;
-
-            PA_DEBUG(( "%s: Flushing buffer processor\n", __FUNCTION__ ));
-            /* There is still buffered output that needs to be processed */
-        }
-
-        /* Wait for data to become available, this comes down to polling the ALSA file descriptors untill we have
-         * a number of available frames.
-         */
-        PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) );
-        if( xrun )
-        {
-            assert( 0 == framesAvail );
-            continue;
-
-            /* XXX: Report xruns to the user? A situation is conceivable where the callback is never invoked due
-             * to constant xruns, it might be desirable to notify the user of this.
-             */
-        }
-
-        /* Consume buffer space. Once we have a number of frames available for consumption we must retrieve the
-         * mmapped buffers from ALSA, this is contiguously accessible memory however, so we may receive smaller
-         * portions at a time than is available as a whole. Therefore we should be prepared to process several
-         * chunks successively. The buffers are passed to the PA buffer processor.
-         */
-        while( framesAvail > 0 )
-        {
-            xrun = 0;
-
-            pthread_testcancel();
-
-            /** @concern Xruns Under/overflows are to be reported to the callback */
-            if( stream->underrun > 0.0 )
-            {
-                cbFlags |= paOutputUnderflow;
-                stream->underrun = 0.0;
-            }
-            if( stream->overrun > 0.0 )
-            {
-                cbFlags |= paInputOverflow;
-                stream->overrun = 0.0;
-            }
-            if( stream->capture.pcm && stream->playback.pcm )
-            {
-                /** @concern FullDuplex It's possible that only one direction is being processed to avoid an
-                 * under- or overflow, this should be reported correspondingly */
-                if( !stream->capture.ready )
-                {
-                    cbFlags |= paInputUnderflow;
-                    PA_DEBUG(( "%s: Input underflow\n", __FUNCTION__ ));
-                }
-                else if( !stream->playback.ready )
-                {
-                    cbFlags |= paOutputOverflow;
-                    PA_DEBUG(( "%s: Output overflow\n", __FUNCTION__ ));
-                }
-            }
-
-            CallbackUpdate( &stream->threading );
-            CalculateTimeInfo( stream, &timeInfo );
-            PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, cbFlags );
-            cbFlags = 0;
-
-            /* CPU load measurement should include processing activivity external to the stream callback */
-            PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
-
-            framesGot = framesAvail;
-            if( paUtilFixedHostBufferSize == stream->bufferProcessor.hostBufferSizeMode )
-            {
-                /* We've committed to a fixed host buffer size, stick to that */
-                framesGot = framesGot >= stream->maxFramesPerHostBuffer ? stream->maxFramesPerHostBuffer : 0;
-            }
-            else
-            {
-                /* We've committed to an upper bound on the size of host buffers */
-                assert( paUtilBoundedHostBufferSize == stream->bufferProcessor.hostBufferSizeMode );
-                framesGot = PA_MIN( framesGot, stream->maxFramesPerHostBuffer );
-            }
-            PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) );
-            /* Check the host buffer size against the buffer processor configuration */
-            framesAvail -= framesGot;
-
-            if( framesGot > 0 )
-            {
-                assert( !xrun );
-                PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );
-                PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) );
-            }
-            PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesGot );
-
-            if( 0 == framesGot )
-            {
-                /* Go back to polling for more frames */
-                break;
-
-            }
-
-            if( paContinue != callbackResult )
-                break;
-        }
-    }
-
-    /* Match pthread_cleanup_push */
-    pthread_cleanup_pop( 1 );
-
-end:
-    PA_DEBUG(( "%s: Thread %d exiting\n ", __FUNCTION__, pthread_self() ));
-    pthread_exit( pres );
-
-error:
-    /* Pass on error code */
-    pres = malloc( sizeof (PaError) );
-    *pres = result;
-    
-    goto end;
-}
-
-/* Blocking interface */
-
-static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames )
-{
-    PaError result = paNoError;
-    PaAlsaStream *stream = (PaAlsaStream*)s;
-    unsigned long framesGot, framesAvail;
-    void *userBuffer;
-    snd_pcm_t *save = stream->playback.pcm;
-
-    assert( stream );
-
-    PA_UNLESS( stream->capture.pcm, paCanNotReadFromAnOutputOnlyStream );
-
-    /* Disregard playback */
-    stream->playback.pcm = NULL;
-
-    if( stream->overrun > 0. )
-    {
-        result = paInputOverflowed;
-        stream->overrun = 0.0;
-    }
-
-    if( stream->capture.userInterleaved )
-    {
-        userBuffer = buffer;
-    }
-    else
-    {
-        /* Copy channels into local array */
-        userBuffer = stream->capture.userBuffers;
-        memcpy( userBuffer, buffer, sizeof (void *) * stream->capture.numUserChannels );
-    }
-
-    /* Start stream if in prepared state */
-    if( snd_pcm_state( stream->capture.pcm ) == SND_PCM_STATE_PREPARED )
-    {
-        ENSURE_( snd_pcm_start( stream->capture.pcm ), paUnanticipatedHostError );
-    }
-
-    while( frames > 0 )
-    {
-        int xrun = 0;
-        PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) );
-        framesGot = PA_MIN( framesAvail, frames );
-
-        PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) );
-        if( framesGot > 0 )
-        {
-            framesGot = PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, framesGot );
-            PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) );
-            frames -= framesGot;
-        }
-    }
-
-end:
-    stream->playback.pcm = save;
-    return result;
-error:
-    goto end;
-}
-
-static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames )
-{
-    PaError result = paNoError;
-    signed long err;
-    PaAlsaStream *stream = (PaAlsaStream*)s;
-    snd_pcm_uframes_t framesGot, framesAvail;
-    const void *userBuffer;
-    snd_pcm_t *save = stream->capture.pcm;
-    
-    assert( stream );
-
-    PA_UNLESS( stream->playback.pcm, paCanNotWriteToAnInputOnlyStream );
-
-    /* Disregard capture */
-    stream->capture.pcm = NULL;
-
-    if( stream->underrun > 0. )
-    {
-        result = paOutputUnderflowed;
-        stream->underrun = 0.0;
-    }
-
-    if( stream->playback.userInterleaved )
-        userBuffer = buffer;
-    else /* Copy channels into local array */
-    {
-        userBuffer = stream->playback.userBuffers;
-        memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->playback.numUserChannels );
-    }
-
-    while( frames > 0 )
-    {
-        int xrun = 0;
-        snd_pcm_uframes_t hwAvail;
-
-        PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) );
-        framesGot = PA_MIN( framesAvail, frames );
-
-        PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) );
-        if( framesGot > 0 )
-        {
-            framesGot = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, framesGot );
-            PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) );
-            frames -= framesGot;
-        }
-
-        /* Start stream after one period of samples worth */
-
-        /* Frames residing in buffer */
-        PA_ENSURE( err = GetStreamWriteAvailable( stream ) );
-        framesAvail = err;
-        hwAvail = stream->playback.bufferSize - framesAvail;
-
-        if( snd_pcm_state( stream->playback.pcm ) == SND_PCM_STATE_PREPARED &&
-                hwAvail >= stream->playback.framesPerBuffer )
-        {
-            ENSURE_( snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError );
-        }
-    }
-
-end:
-    stream->capture.pcm = save;
-    return result;
-error:
-    goto end;
-}
-
-/* Return frames available for reading. In the event of an overflow, the capture pcm will be restarted */
-static signed long GetStreamReadAvailable( PaStream* s )
-{
-    PaError result = paNoError;
-    PaAlsaStream *stream = (PaAlsaStream*)s;
-    unsigned long avail;
-    int xrun;
-
-    PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->capture, &avail, &xrun ) );
-    if( xrun )
-    {
-        PA_ENSURE( PaAlsaStream_HandleXrun( stream ) );
-        PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->capture, &avail, &xrun ) );
-        if( xrun )
-            PA_ENSURE( paInputOverflowed );
-    }
-
-    return (signed long)avail;
-
-error:
-    return result;
-}
-
-static signed long GetStreamWriteAvailable( PaStream* s )
-{
-    PaError result = paNoError;
-    PaAlsaStream *stream = (PaAlsaStream*)s;
-    unsigned long avail;
-    int xrun;
-
-    PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->playback, &avail, &xrun ) );
-    if( xrun )
-    {
-        snd_pcm_sframes_t savail;
-
-        PA_ENSURE( PaAlsaStream_HandleXrun( stream ) );
-        savail = snd_pcm_avail_update( stream->playback.pcm );
-
-        /* savail should not contain -EPIPE now, since PaAlsaStream_HandleXrun will only prepare the pcm */
-        ENSURE_( savail, paUnanticipatedHostError );
-
-        avail = (unsigned long) savail;
-    }
-
-    return (signed long)avail;
-
-error:
-    return result;
-}
-
-/* Extensions */
-
-/* Initialize host api specific structure */
-void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info )
-{
-    info->size = sizeof (PaAlsaStreamInfo);
-    info->hostApiType = paALSA;
-    info->version = 1;
-    info->deviceString = NULL;
-}
-
-void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable )
-{
-    PaAlsaStream *stream = (PaAlsaStream *) s;
-    stream->threading.rtSched = enable;
-}
-
-void PaAlsa_EnableWatchdog( PaStream *s, int enable )
-{
-    PaAlsaStream *stream = (PaAlsaStream *) s;
-    stream->threading.useWatchdog = enable;
-}
diff --git a/portaudio/pa_linux_alsa/pa_linux_alsa.h b/portaudio/pa_linux_alsa/pa_linux_alsa.h
deleted file mode 100644
index e6f44b16e..000000000
--- a/portaudio/pa_linux_alsa/pa_linux_alsa.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef PA_LINUX_ALSA_H
-#define PA_LINUX_ALSA_H
-
-/*
- * $Id: pa_linux_alsa.h,v 1.1.2.12 2004/09/25 14:15:25 aknudsen Exp $
- * PortAudio Portable Real-Time Audio Library
- * ALSA-specific extensions
- *
- * 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.
- *
- */
-
-/** @file
- * ALSA-specific PortAudio API extension header file.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct PaAlsaStreamInfo
-{
-    unsigned long size;
-    PaHostApiTypeId hostApiType;
-    unsigned long version;
-
-    const char *deviceString;
-}
-PaAlsaStreamInfo;
-
-void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info );
-
-void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable );
-
-void PaAlsa_EnableWatchdog( PaStream *s, int enable );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/portaudio/pa_mac/CVS/Entries b/portaudio/pa_mac/CVS/Entries
deleted file mode 100644
index 24943262a..000000000
--- a/portaudio/pa_mac/CVS/Entries
+++ /dev/null
@@ -1,2 +0,0 @@
-/pa_mac_hostapis.c/1.1.2.1/Thu May 27 22:39:58 2004//Tv19-devel
-D
diff --git a/portaudio/pa_mac/CVS/Repository b/portaudio/pa_mac/CVS/Repository
deleted file mode 100644
index a8e170174..000000000
--- a/portaudio/pa_mac/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_mac
diff --git a/portaudio/pa_mac/CVS/Root b/portaudio/pa_mac/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_mac/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_mac/CVS/Tag b/portaudio/pa_mac/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_mac/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_mac/pa_mac_hostapis.c b/portaudio/pa_mac/pa_mac_hostapis.c
deleted file mode 100644
index 2e71577e7..000000000
--- a/portaudio/pa_mac/pa_mac_hostapis.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * $Id: pa_mac_hostapis.c,v 1.1.2.1 2004/05/27 22:39:58 gregpfeil Exp $
- * Portable Audio I/O Library Windows initialization table
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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.
- */
-
-/** @file
-Mac OS host API initialization function table.
-*/
-
-
-#include "pa_hostapi.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-    
-    PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-    PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-    PaError PaMacSm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-    PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-    PaError PaMacAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-    
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-PaUtilHostApiInitializer *paHostApiInitializers[] =
-{
-#ifdef PA_USE_COREAUDIO
-    PaMacCore_Initialize,
-#endif
-    
-#ifdef PA_USE_SM
-    PaMacSm_Initialize,
-#endif
-    
-#ifdef PA_USE_JACK
-    PaJack_Initialize,
-#endif
-
-#ifdef PA_USE_ASIO
-    PaMacAsio_Initialize,
-#endif
-    
-    PaSkeleton_Initialize, /* just for testing */
-    
-    0   /* NULL terminated array */
-};
-
-
-int paDefaultHostApiIndex = 0;
diff --git a/portaudio/pa_mac_core/CVS/Entries b/portaudio/pa_mac_core/CVS/Entries
deleted file mode 100644
index 442a32691..000000000
--- a/portaudio/pa_mac_core/CVS/Entries
+++ /dev/null
@@ -1,6 +0,0 @@
-/notes.txt/1.3.2.9/Thu Feb 23 18:07:11 2006//Tv19-devel
-/pa_mac_core.c/1.8.2.13/Thu Apr  6 13:19:23 2006//Tv19-devel
-/pa_mac_core.h/1.1.2.3/Thu Feb 16 18:25:39 2006//Tv19-devel
-/pa_mac_core_old.c/1.1.2.1/Sat Dec 24 01:22:52 2005//Tv19-devel
-/pa_mac_core_utilities.c/1.1.2.2/Fri Dec  9 19:43:14 2005//Tv19-devel
-D
diff --git a/portaudio/pa_mac_core/CVS/Repository b/portaudio/pa_mac_core/CVS/Repository
deleted file mode 100644
index 9203f53ab..000000000
--- a/portaudio/pa_mac_core/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_mac_core
diff --git a/portaudio/pa_mac_core/CVS/Root b/portaudio/pa_mac_core/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_mac_core/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_mac_core/CVS/Tag b/portaudio/pa_mac_core/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_mac_core/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_mac_core/notes.txt b/portaudio/pa_mac_core/notes.txt
deleted file mode 100644
index ad66f358d..000000000
--- a/portaudio/pa_mac_core/notes.txt
+++ /dev/null
@@ -1,145 +0,0 @@
-Notes on status of CoreAudio Implementation of PortAudio
-
-Document Last Updated December 9, 2005
-
-There are currently two implementations of PortAudio for Mac Core Audio.
-
-The original is in pa_mac_core_old.c, and the newer, default implementation
-is in pa_mac_core.c.
-Only pa_mac_core.c is currently developed and supported as it uses apple's
-current core audio technology. To select use the old implementation, replace
-pa_mac_core.c with pa_mac_core_old.c (eg. "cp pa_mac_core_auhal.c
-pa_mac_core.c"), then run configure and make as usual.
-
-----------------------------------------
-
-Notes on Original implementation:
-
-by Phil Burk and Darren Gibbs
-
-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 
-Built-In 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.
-
--------------------------------------------
-
-Notes on Newer/Default AUHAL implementation:
-
-by Bjorn Roche
-
-Last Updated December 9, 2005
-
-Principle of Operation:
-
-This implementation uses AUHAL for audio I/O. To some extent, it also
-operates at the "HAL" Layer, though this behavior can be limited by
-platform specific flags (see pa_mac_core.h for details). The default
-settings should be reasonable: they don't change the SR of the device and
-don't cause interruptions if other devices are using the device.
-
-Major Software Elements Used: Apple's HAL AUs provide output SR
-conversion transparently, however, only on output, so this
-implementation uses AudioConverters to convert the sample rate on input.
-A PortAudio ring buffer is used to buffer input when sample rate
-conversion is required or when separate audio units are used for duplex
-IO. Finally, a PortAudio buffer processor is used to convert formats and
-provide additional buffers if needed. Internally, interleaved floating
-point data streams are used exclusively - the audio unit converts from
-the audio hardware's native format to interleaved float PCM and
-PortAudio's Buffer processor is used for conversion to user formats.
-
-Simplex Input: Simplex input uses a single callback. If sample rate
-conversion is required, a ring buffer and AudioConverter are used as
-well.
-
-Simplex output: Simplex output uses a single callback. No ring buffer or
-audio converter is used because AUHAL does its own output SR conversion.
-
-Duplex, one device (no SR conversion): When one device is used, a single
-callback is used. This achieves very low latency.
-
-Duplex, separate devices or SR conversion: When SR conversion is
-required, data must be buffered before it is converted and data is not
-always available at the same times on input and output, so SR conversion
-requires the same treatment as separate devices. The input callback
-reads data and puts it in the ring buffer. The output callback reads the
-data off the ring buffer, into an audio converter and finally to the
-buffer processor.
-
-Platform Specific Options:
-
-By using the flags in pa_mac_core.h, the user may specify several options.
-For example, the user can specify the sample-rate conversion quality, and
-the extent to which PA will attempt to "play nice" and to what extent it
-will interrupt other apps to improve performance. For example, if 44100 Hz
-sample rate is requested but the device is set at 48000 Hz, PA can either
-change the device for optimal playback ("Pro" mode), which may interrupt
-other programs playing back audio, or simple use a sample-rate coversion,
-which allows for friendlier sharing of the device ("Play Nice" mode).
-
-
-Known issues:
-
-- Latency: Latency settings are ignored in most cases. Exceptions are when
-doing I/O between different devices and as a hint for selecting a realtively
-low or relatively high latency in conjunction with
-paHostFramesPerBufferUnspecified. Latency settings are always automatically
-bound to "safe" values, however, so setting extreme values here should not be
-an issue.
-
-- Buffer Size: paHostFramesPerBufferUnspecified and specific host buffer sizes
-are supported. paHostFramesPerBufferUnspecified works best in "pro" mode,
-where the buffer size and sample rate of the audio device is most likely
-to match the expected values.
-
-- Timing info. It reports on stream time, but I'm probably doing something
-wrong since patest_sine_time often reports negative latency numbers.
-
-- xrun detection: The only xrun detection performed is when reading
-and writing the ring buffer. There is probably more that can be done.
-
-- abort/stop issues: stopping a stream is always a complete operation,
-but latency should be low enough to make the lack of a separate abort
-unnecessary. Apple clarifies its AudioOutputUnitStop() call here:
-http://lists.apple.com/archives/coreaudio-api/2005/Dec/msg00055.html
-
-- blocking interface: Not implemented.
-
-- multichannel: It has been tested successfully on multichannel hardware
-from MOTU: traveler and 896HD.
-
-- sample rate conversion quality: By default, SR conversion is the maximum
-available. This can be tweaked using flags pa_mac_core.h. Note that the AU
-render quyality property is used to set the sample rat conversion quality
-as "documented" here:
-http://lists.apple.com/archives/coreaudio-api/2004/Jan/msg00141.html
-
-- x86: I haven't tested it on an x86 Mac myself, but users have reported 
-being able to comiple and run it.
diff --git a/portaudio/pa_mac_core/pa_mac_core.c b/portaudio/pa_mac_core/pa_mac_core.c
deleted file mode 100644
index 16eb08249..000000000
--- a/portaudio/pa_mac_core/pa_mac_core.c
+++ /dev/null
@@ -1,2105 +0,0 @@
-/*
- * This is the AUHAL implementation of portaudio. Hopefully this will
- * one day replace pa_mac_core.
- *
- * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code.
- * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation)
- *
- * Dominic's code was based on code by Phil Burk, Darren Gibbs,
- * Gord Peters, Stephane Letz, and Greg Pfiel.
- *
- * Bjorn Roche and XO Audio LLC reserve no rights to this code.
- * The maintainers of PortAudio may redistribute and modify the code and
- * licenses as they deam appropriate.
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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.
- */
-
-/**
- @file pa_mac_core
- @author Bjorn Roche
- @brief AUHAL implementation of PortAudio
-*/
-
-#include <string.h> /* strlen(), memcmp() etc. */
-
-#include <AudioUnit/AudioUnit.h>
-#include <AudioToolbox/AudioToolbox.h>
-
-
-#include "pa_util.h"
-#include "pa_allocation.h"
-#include "pa_hostapi.h"
-#include "pa_stream.h"
-#include "pa_cpuload.h"
-#include "pa_process.h"
-#include "../pablio/ringbuffer.h"
-#include "pa_mac_core.h"
-
-#ifndef MIN
-#define MIN(a, b)  (((a)<(b))?(a):(b))
-#endif
-
-#ifndef MAX
-#define MAX(a, b)  (((a)<(b))?(b):(a))
-#endif
-
-/* prototypes for functions declared in this file */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#define ERR(mac_error) PaMacCore_SetError(mac_error, __LINE__, 1 )
-#define WARNING(mac_error) PaMacCore_SetError(mac_error, __LINE__, 0 )
-
-/* Help keep track of AUHAL element numbers */
-#define INPUT_ELEMENT  (1)
-#define OUTPUT_ELEMENT (0)
-
-/* Normal level of debugging: fine for most apps that don't mind the occational warning being printf'ed */
-/*
- */
-#define MAC_CORE_DEBUG
-#ifdef MAC_CORE_DEBUG
-# define DBUG(MSG) do { printf("||PaMacCore (AUHAL)|| "); printf MSG ; fflush(stdout); } while(0)
-#else
-# define DBUG(MSG)
-#endif
-
-/* Verbose Debugging: useful for developement */
-/*
-#define MAC_CORE_VERBOSE_DEBUG
- */
-#ifdef MAC_CORE_VERBOSE_DEBUG
-# define VDBUG(MSG) do { printf("||PaMacCore (v )|| "); printf MSG ; fflush(stdout); } while(0)
-#else
-# define VDBUG(MSG)
-#endif
-
-/* Very Verbose Debugging: Traces every call. */
-/*
-#define MAC_CORE_VERY_VERBOSE_DEBUG
- */
-#ifdef MAC_CORE_VERY_VERBOSE_DEBUG
-# define VVDBUG(MSG) do { printf("||PaMacCore (vv)|| "); printf MSG ; fflush(stdout); } while(0)
-#else
-# define VVDBUG(MSG)
-#endif
-
-#define RING_BUFFER_ADVANCE_DENOMINATOR (4)
-
-/* Some utilities that sort of belong here, but were getting too unweildy */
-#include "pa_mac_core_utilities.c"
-/* Special purpose ring buffer just for pa_mac_core input processing. */
-/* #include "pa_mac_core_input_ring_buffer.c" */
-#include "../pablio/ringbuffer.c"
-
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate );
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData );
-static PaError CloseStream( PaStream* stream );
-static PaError StartStream( PaStream *stream );
-static PaError StopStream( PaStream *stream );
-static PaError AbortStream( PaStream *stream );
-static PaError IsStreamStopped( PaStream *s );
-static PaError IsStreamActive( PaStream *stream );
-static PaTime GetStreamTime( PaStream *stream );
-static void setStreamStartTime( PaStream *stream );
-static OSStatus AudioIOProc( void *inRefCon,
-                               AudioUnitRenderActionFlags *ioActionFlags,
-                               const AudioTimeStamp *inTimeStamp,
-                               UInt32 inBusNumber,
-                               UInt32 inNumberFrames,
-                               AudioBufferList *ioData );
-static double GetStreamCpuLoad( PaStream* stream );
-static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
-static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
-static signed long GetStreamReadAvailable( PaStream* stream );
-static signed long GetStreamWriteAvailable( PaStream* stream );
-/* PaMacAUHAL - host api datastructure specific to this implementation */
-typedef struct
-{
-    PaUtilHostApiRepresentation inheritedHostApiRep;
-    PaUtilStreamInterface callbackStreamInterface;
-    PaUtilStreamInterface blockingStreamInterface;
-
-    PaUtilAllocationGroup *allocations;
-
-    /* implementation specific data goes here */
-    long devCount;
-    AudioDeviceID *devIds; /*array of all audio devices*/
-    AudioDeviceID defaultIn;
-    AudioDeviceID defaultOut;
-}
-PaMacAUHAL;
-
-/* stream data structure specifically for this implementation */
-typedef struct PaMacCoreStream
-{
-    PaUtilStreamRepresentation streamRepresentation;
-    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
-    PaUtilBufferProcessor bufferProcessor;
-
-    /* implementation specific data goes here */
-    bool bufferProcessorIsInitialized;
-    AudioUnit inputUnit;
-    AudioUnit outputUnit;
-    AudioDeviceID inputDevice;
-    AudioDeviceID outputDevice;
-    size_t userInChan;
-    size_t userOutChan;
-    size_t inputFramesPerBuffer;
-    size_t outputFramesPerBuffer;
-    /* We use this ring buffer when input and out devs are different. */
-    RingBuffer inputRingBuffer;
-    /* We may need to do SR conversion on input. */
-    AudioConverterRef inputSRConverter;
-    /* We need to preallocate an inputBuffer for reading data. */
-    AudioBufferList inputAudioBufferList;
-    AudioTimeStamp startTime;
-    //volatile bool isTimeSet;
-    volatile PaStreamCallbackFlags xrunFlags;
-    volatile enum {
-       STOPPED          = 0, /* playback is completely stopped,
-                                and the user has called StopStream(). */
-       CALLBACK_STOPPED = 1, /* callback has requested stop,
-                                but user has not yet called StopStream(). */
-       STOPPING         = 2, /* The stream is in the process of closing.
-                                This state is just used internally;
-                                externally it is indistinguishable from
-                                ACTIVE.*/
-       ACTIVE           = 3  /* The stream is active and running. */
-    } state;
-    double sampleRate;
-}
-PaMacCoreStream;
-
-static PaError OpenAndSetupOneAudioUnit(
-                                   const PaStreamParameters *inStreamParams,
-                                   const PaStreamParameters *outStreamParams,
-                                   const unsigned long requestedFramesPerBuffer,
-                                   unsigned long *actualInputFramesPerBuffer,
-                                   unsigned long *actualOutputFramesPerBuffer,
-                                   const PaMacAUHAL *auhalHostApi,
-                                   AudioUnit *audioUnit,
-                                   AudioConverterRef *srConverter,
-                                   AudioDeviceID *audioDevice,
-                                   const double sampleRate,
-                                   void *refCon );
-
-/* for setting errors. */
-#define PA_AUHAL_SET_LAST_HOST_ERROR( errorCode, errorText ) \
-    PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText )
-
-
-
-
-/*currently, this is only used in initialization, but it might be modified
-  to be used when the list of devices changes.*/
-static PaError gatherDeviceInfo(PaMacAUHAL *auhalHostApi)
-{
-    UInt32 size;
-    UInt32 propsize;
-    VVDBUG(("gatherDeviceInfo()\n"));
-    /* -- free any previous allocations -- */
-    if( auhalHostApi->devIds )
-        PaUtil_GroupFreeMemory(auhalHostApi->allocations, auhalHostApi->devIds);
-    auhalHostApi->devIds = NULL;
-
-    /* -- figure out how many devices there are -- */
-    AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices,
-                                  &propsize,
-                                  NULL );
-    auhalHostApi->devCount = propsize / sizeof( AudioDeviceID );
-
-    VDBUG( ( "Found %ld device(s).\n", auhalHostApi->devCount ) );
-
-    /* -- copy the device IDs -- */
-    auhalHostApi->devIds = (AudioDeviceID *)PaUtil_GroupAllocateMemory(
-                             auhalHostApi->allocations,
-                             propsize );
-    if( !auhalHostApi->devIds )
-        return paInsufficientMemory;
-    AudioHardwareGetProperty( kAudioHardwarePropertyDevices,
-                                  &propsize,
-                                  auhalHostApi->devIds );
-#ifdef MAC_CORE_VERBOSE_DEBUG
-    {
-       int i;
-       for( i=0; i<auhalHostApi->devCount; ++i )
-          printf( "Device %d\t: %ld\n", i, auhalHostApi->devIds[i] );
-    }
-#endif
-
-    size = sizeof(AudioDeviceID);
-    auhalHostApi->defaultIn  = kAudioDeviceUnknown;
-    auhalHostApi->defaultOut = kAudioDeviceUnknown;
-    /* FEEDBACK: these calls could fail, in which case default in and out will
-                 be unknown devices or could be undefined. Do I need to be more
-                 rigorous here? */
-    AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
-                     &size,
-                     &auhalHostApi->defaultIn);
-    AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
-                     &size,
-                     &auhalHostApi->defaultOut);
-    VDBUG( ( "Default in : %ld\n", auhalHostApi->defaultIn  ) );
-    VDBUG( ( "Default out: %ld\n", auhalHostApi->defaultOut ) );
-
-    return paNoError;
-}
-
-static PaError GetChannelInfo( PaMacAUHAL *auhalHostApi,
-                               PaDeviceInfo *deviceInfo,
-                               AudioDeviceID macCoreDeviceId,
-                               int isInput)
-{
-    UInt32 propSize;
-    PaError err = paNoError;
-    UInt32 i;
-    int numChannels = 0;
-    AudioBufferList *buflist;
-    UInt32 frameLatency;
-
-    VVDBUG(("GetChannelInfo()\n"));
-
-    /* Get the number of channels from the stream configuration.
-       Fail if we can't get this. */
-
-    err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, NULL));
-    if (err)
-        return err;
-
-    buflist = PaUtil_AllocateMemory(propSize);
-    err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, buflist));
-    if (err)
-        return err;
-
-    for (i = 0; i < buflist->mNumberBuffers; ++i)
-        numChannels += buflist->mBuffers[i].mNumberChannels;
-
-    if (isInput)
-        deviceInfo->maxInputChannels = numChannels;
-    else
-        deviceInfo->maxOutputChannels = numChannels;
-      
-    if (numChannels > 0) // do not try to retrieve the latency if there is no channels.
-    {
-       /* Get the latency.  Don't fail if we can't get this. */
-       /* default to something reasonable */
-       deviceInfo->defaultLowInputLatency = .01;
-       deviceInfo->defaultHighInputLatency = .01;
-       deviceInfo->defaultLowOutputLatency = .01;
-       deviceInfo->defaultHighOutputLatency = .01;
-       propSize = sizeof(UInt32);
-       err = WARNING(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyLatency, &propSize, &frameLatency));
-       if (!err)
-       {
-          double secondLatency = frameLatency / deviceInfo->defaultSampleRate;
-          if (isInput)
-          {
-             deviceInfo->defaultLowInputLatency = secondLatency;
-             deviceInfo->defaultHighInputLatency = secondLatency;
-          }
-          else
-          {
-             deviceInfo->defaultLowOutputLatency = secondLatency;
-             deviceInfo->defaultHighOutputLatency = secondLatency;
-          }
-       }
-    }
-    return paNoError;
-}
-
-static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi,
-                                     PaDeviceInfo *deviceInfo,
-                                     AudioDeviceID macCoreDeviceId,
-                                     PaHostApiIndex hostApiIndex )
-{
-    Float64 sampleRate;
-    char *name;
-    PaError err = paNoError;
-    UInt32 propSize;
-
-    VVDBUG(("InitializeDeviceInfo(): macCoreDeviceId=%ld\n", macCoreDeviceId));
-
-    memset(deviceInfo, 0, sizeof(deviceInfo));
-
-    deviceInfo->structVersion = 2;
-    deviceInfo->hostApi = hostApiIndex;
-
-    /* Get the device name.  Fail if we can't get it. */
-    err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL));
-    if (err)
-        return err;
-
-    name = PaUtil_GroupAllocateMemory(auhalHostApi->allocations,propSize);
-    if ( !name )
-        return paInsufficientMemory;
-    err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name));
-    if (err)
-        return err;
-    deviceInfo->name = name;
-
-    /* Try to get the default sample rate.  Don't fail if we can't get this. */
-    propSize = sizeof(Float64);
-    err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &sampleRate));
-    if (err)
-        deviceInfo->defaultSampleRate = 0.0;
-    else
-        deviceInfo->defaultSampleRate = sampleRate;
-
-    /* Get the maximum number of input and output channels.  Fail if we can't get this. */
-
-    err = GetChannelInfo(auhalHostApi, deviceInfo, macCoreDeviceId, 1);
-    if (err)
-        return err;
-
-    err = GetChannelInfo(auhalHostApi, deviceInfo, macCoreDeviceId, 0);
-    if (err)
-        return err;
-
-    return paNoError;
-}
-
-PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
-{
-    PaError result = paNoError;
-    int i;
-    PaMacAUHAL *auhalHostApi;
-    PaDeviceInfo *deviceInfoArray;
-
-    VVDBUG(("PaMacCore_Initialize(): hostApiIndex=%d\n", hostApiIndex));
-
-    auhalHostApi = (PaMacAUHAL*)PaUtil_AllocateMemory( sizeof(PaMacAUHAL) );
-    if( !auhalHostApi )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    auhalHostApi->allocations = PaUtil_CreateAllocationGroup();
-    if( !auhalHostApi->allocations )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    auhalHostApi->devIds = NULL;
-    auhalHostApi->devCount = 0;
-
-    /* get the info we need about the devices */
-    result = gatherDeviceInfo( auhalHostApi );
-    if( result != paNoError )
-       goto error;
-
-    *hostApi = &auhalHostApi->inheritedHostApiRep;
-    (*hostApi)->info.structVersion = 1;
-    (*hostApi)->info.type = paCoreAudio;
-    (*hostApi)->info.name = "Core Audio";
-
-    (*hostApi)->info.defaultInputDevice = paNoDevice;
-    (*hostApi)->info.defaultOutputDevice = paNoDevice;
-
-    (*hostApi)->info.deviceCount = 0;  
-
-    if( auhalHostApi->devCount > 0 )
-    {
-        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
-                auhalHostApi->allocations, sizeof(PaDeviceInfo*) * auhalHostApi->devCount);
-        if( !(*hostApi)->deviceInfos )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        /* allocate all device info structs in a contiguous block */
-        deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory(
-                auhalHostApi->allocations, sizeof(PaDeviceInfo) * auhalHostApi->devCount );
-        if( !deviceInfoArray )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        for( i=0; i < auhalHostApi->devCount; ++i )
-        {
-            int err;
-            err = InitializeDeviceInfo( auhalHostApi, &deviceInfoArray[i],
-                                      auhalHostApi->devIds[i],
-                                      hostApiIndex );
-            if (err == paNoError)
-            { /* copy some info and set the defaults */
-                (*hostApi)->deviceInfos[(*hostApi)->info.deviceCount] = &deviceInfoArray[i];
-                if (auhalHostApi->devIds[i] == auhalHostApi->defaultIn)
-                    (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount;
-                if (auhalHostApi->devIds[i] == auhalHostApi->defaultOut)
-                    (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount;
-                (*hostApi)->info.deviceCount++;
-            }
-            else
-            { /* there was an error. we need to shift the devices down, so we ignore this one */
-                int j;
-                auhalHostApi->devCount--;
-                for( j=i; j<auhalHostApi->devCount; ++j )
-                   auhalHostApi->devIds[j] = auhalHostApi->devIds[j+1];
-                i--;
-            }
-        }
-    }
-
-    (*hostApi)->Terminate = Terminate;
-    (*hostApi)->OpenStream = OpenStream;
-    (*hostApi)->IsFormatSupported = IsFormatSupported;
-
-    PaUtil_InitializeStreamInterface( &auhalHostApi->callbackStreamInterface,
-                                      CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped,
-                                      IsStreamActive,
-                                      GetStreamTime, GetStreamCpuLoad,
-                                      PaUtil_DummyRead, PaUtil_DummyWrite,
-                                      PaUtil_DummyGetReadAvailable,
-                                      PaUtil_DummyGetWriteAvailable );
-
-    PaUtil_InitializeStreamInterface( &auhalHostApi->blockingStreamInterface,
-                                      CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped,
-                                      IsStreamActive,
-                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
-                                      ReadStream, WriteStream,
-                                      GetStreamReadAvailable,
-                                      GetStreamWriteAvailable );
-
-    return result;
-
-error:
-    if( auhalHostApi )
-    {
-        if( auhalHostApi->allocations )
-        {
-            PaUtil_FreeAllAllocations( auhalHostApi->allocations );
-            PaUtil_DestroyAllocationGroup( auhalHostApi->allocations );
-        }
-                
-        PaUtil_FreeMemory( auhalHostApi );
-    }
-    return result;
-}
-
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
-{
-    PaMacAUHAL *auhalHostApi = (PaMacAUHAL*)hostApi;
-
-    VVDBUG(("Terminate()\n"));
-
-    /*
-        IMPLEMENT ME:
-            - clean up any resources not handled by the allocation group
-        TODO: Double check that everything is handled by alloc group
-    */
-
-    if( auhalHostApi->allocations )
-    {
-        PaUtil_FreeAllAllocations( auhalHostApi->allocations );
-        PaUtil_DestroyAllocationGroup( auhalHostApi->allocations );
-    }
-
-    PaUtil_FreeMemory( auhalHostApi );
-}
-
-
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate )
-{
-    int inputChannelCount, outputChannelCount;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-
-    VVDBUG(("IsFormatSupported(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld sampleRate=%g\n",
-                inputParameters  ? inputParameters->channelCount  : -1,
-                inputParameters  ? inputParameters->sampleFormat  : -1,
-                outputParameters ? outputParameters->channelCount : -1,
-                outputParameters ? outputParameters->sampleFormat : -1,
-                (float) sampleRate ));
- 
-    /** These first checks are standard PA checks. We do some fancier checks
-        later. */
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-
-        /* all standard sample formats are supported by the buffer adapter,
-            this implementation doesn't support any custom sample formats */
-        if( inputSampleFormat & paCustomFormat )
-            return paSampleFormatNotSupported;
-            
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that input device can support inputChannelCount */
-        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
-            return paInvalidChannelCount;
-    }
-    else
-    {
-        inputChannelCount = 0;
-    }
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-
-        /* all standard sample formats are supported by the buffer adapter,
-            this implementation doesn't support any custom sample formats */
-        if( outputSampleFormat & paCustomFormat )
-            return paSampleFormatNotSupported;
-            
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that output device can support outputChannelCount */
-        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
-            return paInvalidChannelCount;
-
-    }
-    else
-    {
-        outputChannelCount = 0;
-    }
- 
-    /* FEEDBACK */
-    /*        I think the only way to check a given format SR combo is     */
-    /*        to try opening it. This could be disruptive, is that Okay?   */
-    /*        The alternative is to just read off available sample rates,  */
-    /*        but this will not work %100 of the time (eg, a device that   */
-    /*        supports N output at one rate but only N/2 at a higher rate.)*/
-
-    /* The following code opens the device with the requested parameters to
-       see if it works. */
-    {
-       PaError err;
-       PaStream *s;
-       err = OpenStream( hostApi, &s, inputParameters, outputParameters,
-                           sampleRate, 1024, 0, (PaStreamCallback *)1, NULL );
-       if( err != paNoError && err != paInvalidSampleRate )
-          DBUG( ( "OpenStream @ %g returned: %d: %s\n",
-                  (float) sampleRate, err, Pa_GetErrorText( err ) ) );
-       if( err ) 
-          return err;
-       err = CloseStream( s );
-       if( err ) {
-          /* FEEDBACK: is this more serious? should we assert? */
-          DBUG( ( "WARNING: could not close Stream. %d: %s\n",
-                  err, Pa_GetErrorText( err ) ) );
-       }
-    }
-
-    return paFormatIsSupported;
-}
-
-static PaError OpenAndSetupOneAudioUnit(
-                                   const PaStreamParameters *inStreamParams,
-                                   const PaStreamParameters *outStreamParams,
-                                   const unsigned long requestedFramesPerBuffer,
-                                   unsigned long *actualInputFramesPerBuffer,
-                                   unsigned long *actualOutputFramesPerBuffer,
-                                   const PaMacAUHAL *auhalHostApi,
-                                   AudioUnit *audioUnit,
-                                   AudioConverterRef *srConverter,
-                                   AudioDeviceID *audioDevice,
-                                   const double sampleRate,
-                                   void *refCon )
-{
-    ComponentDescription desc;
-    Component comp;
-    /*An Apple TN suggests using CAStreamBasicDescription, but that is C++*/
-    AudioStreamBasicDescription desiredFormat;
-    OSErr result = noErr;
-    PaError paResult = paNoError;
-    int line;
-    UInt32 callbackKey;
-    AURenderCallbackStruct rcbs;
-    unsigned long macInputStreamFlags  = paMacCorePlayNice;
-    unsigned long macOutputStreamFlags = paMacCorePlayNice;
-
-    VVDBUG(("OpenAndSetupOneAudioUnit(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld, requestedFramesPerBuffer=%ld\n",
-                inStreamParams  ? inStreamParams->channelCount  : -1,
-                inStreamParams  ? inStreamParams->sampleFormat  : -1,
-                outStreamParams ? outStreamParams->channelCount : -1,
-                outStreamParams ? outStreamParams->sampleFormat : -1,
-                requestedFramesPerBuffer ));
-
-    /* -- handle the degenerate case  -- */
-    if( !inStreamParams && !outStreamParams ) {
-       *audioUnit = NULL;
-       *audioDevice = kAudioDeviceUnknown;
-       return paNoError;
-    }
-
-    /* -- get the user's api specific info, if they set any -- */
-    if( inStreamParams && inStreamParams->hostApiSpecificStreamInfo )
-       macInputStreamFlags=
-            ((paMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo)
-                  ->flags;
-    if( outStreamParams && outStreamParams->hostApiSpecificStreamInfo )
-       macOutputStreamFlags=
-            ((paMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo)
-                  ->flags;
-    /* Override user's flags here, if desired for testing. */
-
-    /*
-     * The HAL AU is a Mac OS style "component".
-     * the first few steps deal with that.
-     * Later steps work on a combination of Mac OS
-     * components and the slightly lower level
-     * HAL.
-     */
-
-    /* -- describe the output type AudioUnit -- */
-    /*  Note: for the default AudioUnit, we could use the
-     *  componentSubType value kAudioUnitSubType_DefaultOutput;
-     *  but I don't think that's relevant here.
-     */
-    desc.componentType         = kAudioUnitType_Output;
-    desc.componentSubType      = kAudioUnitSubType_HALOutput;
-    desc.componentManufacturer = kAudioUnitManufacturer_Apple;
-    desc.componentFlags        = 0;
-    desc.componentFlagsMask    = 0;
-    /* -- find the component -- */
-    comp = FindNextComponent( NULL, &desc );
-    if( !comp )
-    {
-       DBUG( ( "AUHAL component not found." ) );
-       *audioUnit = NULL;
-       *audioDevice = kAudioDeviceUnknown;
-       return paUnanticipatedHostError;
-    }
-    /* -- open it -- */
-    result = OpenAComponent( comp, audioUnit );
-    if( result )
-    {
-       DBUG( ( "Failed to open AUHAL component." ) );
-       *audioUnit = NULL;
-       *audioDevice = kAudioDeviceUnknown;
-       return ERR( result );
-    }
-    /* -- prepare a little error handling logic / hackery -- */
-#define ERR_WRAP(mac_err) do { result = mac_err ; line = __LINE__ ; if ( result != noErr ) goto error ; } while(0)
-
-    /* -- if there is input, we have to explicitly enable input -- */
-    if( inStreamParams )
-    {
-       UInt32 enableIO;
-       enableIO = 1;
-       ERR_WRAP( AudioUnitSetProperty( *audioUnit,
-                 kAudioOutputUnitProperty_EnableIO,
-                 kAudioUnitScope_Input,
-                 INPUT_ELEMENT,
-                 &enableIO,
-                 sizeof(enableIO) ) );
-    }
-    /* -- if there is no output, we must explicitly disable output -- */
-    if( !outStreamParams )
-    {
-       UInt32 enableIO;
-       enableIO = 0;
-       ERR_WRAP( AudioUnitSetProperty( *audioUnit,
-                 kAudioOutputUnitProperty_EnableIO,
-                 kAudioUnitScope_Output,
-                 OUTPUT_ELEMENT,
-                 &enableIO,
-                 sizeof(enableIO) ) );
-    }
-    /* -- set the devices -- */
-    /* make sure input and output are the same device if we are doing input and
-       output. */
-    if( inStreamParams && outStreamParams )
-       assert( outStreamParams->device == inStreamParams->device );
-    if( inStreamParams )
-    {
-       *audioDevice = auhalHostApi->devIds[inStreamParams->device] ;
-       ERR_WRAP( AudioUnitSetProperty( *audioUnit,
-                    kAudioOutputUnitProperty_CurrentDevice,
-                    kAudioUnitScope_Global,
-                    INPUT_ELEMENT,
-                    audioDevice,
-                    sizeof(AudioDeviceID) ) );
-    }
-    if( outStreamParams )
-    {
-       *audioDevice = auhalHostApi->devIds[outStreamParams->device] ;
-       ERR_WRAP( AudioUnitSetProperty( *audioUnit,
-                    kAudioOutputUnitProperty_CurrentDevice,
-                    kAudioUnitScope_Global,
-                    OUTPUT_ELEMENT,
-                    audioDevice,
-                    sizeof(AudioDeviceID) ) );
-    }
-
-    /* -- set format -- */
-    bzero( &desiredFormat, sizeof(desiredFormat) );
-    desiredFormat.mFormatID         = kAudioFormatLinearPCM ;
-    desiredFormat.mFormatFlags      = kAudioFormatFlagsNativeFloatPacked;
-    desiredFormat.mFramesPerPacket  = 1;
-    desiredFormat.mBitsPerChannel   = sizeof( float ) * 8;
-
-    result = 0;
-    /*  set device format first, but only touch the device if the user asked */
-    if( inStreamParams ) {
-       /*The callback never calls back if we don't set the FPB */
-       /*This seems wierd, because I would think setting anything on the device
-         would be disruptive.*/
-       paResult = setBestFramesPerBuffer( *audioDevice, FALSE,
-                                          requestedFramesPerBuffer,
-                                          actualInputFramesPerBuffer );
-       if( paResult ) goto error;
-       if( macInputStreamFlags & paMacCore_ChangeDeviceParameters ) {
-          bool requireExact;
-          requireExact=macInputStreamFlags&paMacCore_FailIfConversionRequired;
-          paResult = setBestSampleRateForDevice( *audioDevice, FALSE,
-                                                 requireExact, sampleRate );
-          if( paResult ) goto error;
-       }
-       if( actualInputFramesPerBuffer && actualOutputFramesPerBuffer )
-          *actualOutputFramesPerBuffer = *actualInputFramesPerBuffer ;
-    }
-    if( outStreamParams && !inStreamParams ) {
-       /*The callback never calls back if we don't set the FPB */
-       /*This seems wierd, because I would think setting anything on the device
-         would be disruptive.*/
-       paResult = setBestFramesPerBuffer( *audioDevice, TRUE,
-                                          requestedFramesPerBuffer,
-                                          actualOutputFramesPerBuffer );
-       if( paResult ) goto error;
-       if( macOutputStreamFlags & paMacCore_ChangeDeviceParameters ) {
-          bool requireExact;
-          requireExact=macOutputStreamFlags&paMacCore_FailIfConversionRequired;
-          paResult = setBestSampleRateForDevice( *audioDevice, TRUE,
-                                                 requireExact, sampleRate );
-          if( paResult ) goto error;
-       }
-    }
-
-    /* -- set the quality of the output converter -- */
-    if( outStreamParams ) {
-       UInt32 value = kAudioConverterQuality_Max;
-       switch( macOutputStreamFlags & 0x0700 ) {
-       case 0x0100: /*paMacCore_ConversionQualityMin:*/
-          value=kRenderQuality_Min;
-          break;
-       case 0x0200: /*paMacCore_ConversionQualityLow:*/
-          value=kRenderQuality_Low;
-          break;
-       case 0x0300: /*paMacCore_ConversionQualityMedium:*/
-          value=kRenderQuality_Medium;
-          break;
-       case 0x0400: /*paMacCore_ConversionQualityHigh:*/
-          value=kRenderQuality_High;
-          break;
-       }
-       ERR_WRAP( AudioUnitSetProperty( *audioUnit,
-                    kAudioUnitProperty_RenderQuality,
-                    kAudioUnitScope_Global,
-                    OUTPUT_ELEMENT,
-                    &value,
-                    sizeof(value) ) );
-    }
-    /* now set the format on the Audio Units. */
-    if( outStreamParams )
-    {
-       desiredFormat.mSampleRate    =sampleRate;
-       desiredFormat.mBytesPerPacket=sizeof(float)*outStreamParams->channelCount;
-       desiredFormat.mBytesPerFrame =sizeof(float)*outStreamParams->channelCount;
-       desiredFormat.mChannelsPerFrame = outStreamParams->channelCount;
-       ERR_WRAP( AudioUnitSetProperty( *audioUnit,
-                            kAudioUnitProperty_StreamFormat,
-                            kAudioUnitScope_Input,
-                            OUTPUT_ELEMENT,
-                            &desiredFormat,
-                            sizeof(AudioStreamBasicDescription) ) );
-    }
-    if( inStreamParams )
-    {
-       AudioStreamBasicDescription sourceFormat;
-       UInt32 size = sizeof( AudioStreamBasicDescription );
-
-       /* keep the sample rate of the device, or we confuse AUHAL */
-       ERR_WRAP( AudioUnitGetProperty( *audioUnit,
-                            kAudioUnitProperty_StreamFormat,
-                            kAudioUnitScope_Input,
-                            INPUT_ELEMENT,
-                            &sourceFormat,
-                            &size ) );
-       desiredFormat.mSampleRate = sourceFormat.mSampleRate;
-       desiredFormat.mBytesPerPacket=sizeof(float)*inStreamParams->channelCount;
-       desiredFormat.mBytesPerFrame =sizeof(float)*inStreamParams->channelCount;
-       desiredFormat.mChannelsPerFrame = inStreamParams->channelCount;
-       ERR_WRAP( AudioUnitSetProperty( *audioUnit,
-                            kAudioUnitProperty_StreamFormat,
-                            kAudioUnitScope_Output,
-                            INPUT_ELEMENT,
-                            &desiredFormat,
-                            sizeof(AudioStreamBasicDescription) ) );
-    }
-    /* set the maximumFramesPerSlice */
-    /* not doing this causes real problems
-       (eg. the callback might not be called). The idea of setting both this
-       and the frames per buffer on the device is that we'll be most likely
-       to actually get the frame size we requested in the callback with the
-       minimum latency. */
-    if( outStreamParams ) {
-       UInt32 size = sizeof( *actualOutputFramesPerBuffer );
-       ERR_WRAP( AudioUnitSetProperty( *audioUnit,
-                            kAudioUnitProperty_MaximumFramesPerSlice,
-                            kAudioUnitScope_Input,
-                            OUTPUT_ELEMENT,
-                            actualOutputFramesPerBuffer,
-                            sizeof(unsigned long) ) );
-       ERR_WRAP( AudioUnitGetProperty( *audioUnit,
-                            kAudioUnitProperty_MaximumFramesPerSlice,
-                            kAudioUnitScope_Global,
-                            OUTPUT_ELEMENT,
-                            actualOutputFramesPerBuffer,
-                            &size ) );
-    }
-    if( inStreamParams ) {
-       /*UInt32 size = sizeof( *actualInputFramesPerBuffer );*/
-       ERR_WRAP( AudioUnitSetProperty( *audioUnit,
-                            kAudioUnitProperty_MaximumFramesPerSlice,
-                            kAudioUnitScope_Output,
-                            INPUT_ELEMENT,
-                            actualInputFramesPerBuffer,
-                            sizeof(unsigned long) ) );
-/* Don't know why this causes problems
-       ERR_WRAP( AudioUnitGetProperty( *audioUnit,
-                            kAudioUnitProperty_MaximumFramesPerSlice,
-                            kAudioUnitScope_Global, //Output,
-                            INPUT_ELEMENT,
-                            actualInputFramesPerBuffer,
-                            &size ) );
-*/
-    }
-
-    /* -- if we have input, we may need to setup an SR converter -- */
-    /* even if we got the sample rate we asked for, we need to do
-       the conversion in case another program changes the underlying SR. */
-    /* FIXME: I think we need to monitor stream and change the converter if the incoming format changes. */
-    if( inStreamParams ) {
-       AudioStreamBasicDescription desiredFormat;
-       AudioStreamBasicDescription sourceFormat;
-       UInt32 sourceSize = sizeof( sourceFormat );
-       bzero( &desiredFormat, sizeof(desiredFormat) );
-       desiredFormat.mSampleRate       = sampleRate;
-       desiredFormat.mFormatID         = kAudioFormatLinearPCM ;
-       desiredFormat.mFormatFlags      = kAudioFormatFlagsNativeFloatPacked;
-       desiredFormat.mFramesPerPacket  = 1;
-       desiredFormat.mBitsPerChannel   = sizeof( float ) * 8;
-       desiredFormat.mBytesPerPacket=sizeof(float)*inStreamParams->channelCount;
-       desiredFormat.mBytesPerFrame =sizeof(float)*inStreamParams->channelCount;
-       desiredFormat.mChannelsPerFrame = inStreamParams->channelCount;
-
-       /* get the source format */
-       ERR_WRAP( AudioUnitGetProperty(
-                         *audioUnit,
-                         kAudioUnitProperty_StreamFormat,
-                         kAudioUnitScope_Output,
-                         INPUT_ELEMENT,
-                         &sourceFormat,
-                         &sourceSize ) );
-
-       if( desiredFormat.mSampleRate != sourceFormat.mSampleRate )
-       {
-          UInt32 value = kAudioConverterQuality_Max;
-          switch( macInputStreamFlags & 0x0700 ) {
-          case 0x0100: /*paMacCore_ConversionQualityMin:*/
-             value=kAudioConverterQuality_Min;
-             break;
-          case 0x0200: /*paMacCore_ConversionQualityLow:*/
-             value=kAudioConverterQuality_Low;
-             break;
-          case 0x0300: /*paMacCore_ConversionQualityMedium:*/
-             value=kAudioConverterQuality_Medium;
-             break;
-          case 0x0400: /*paMacCore_ConversionQualityHigh:*/
-             value=kAudioConverterQuality_High;
-             break;
-          }
-          VDBUG(( "Creating sample rate converter for input"
-                  " to convert from %g to %g\n",
-                  (float)sourceFormat.mSampleRate,
-                  (float)desiredFormat.mSampleRate ) );
-          /* create our converter */
-          ERR_WRAP( AudioConverterNew( 
-                             &sourceFormat,
-                             &desiredFormat,
-                             srConverter ) );
-          /* Set quality */
-          ERR_WRAP( AudioConverterSetProperty(
-                             *srConverter,
-                             kAudioConverterSampleRateConverterQuality,
-                             sizeof( value ),
-                             &value ) );
-       }
-    }
-    /* -- set IOProc (callback) -- */
-    callbackKey = outStreamParams ? kAudioUnitProperty_SetRenderCallback
-                                  : kAudioOutputUnitProperty_SetInputCallback ;
-    rcbs.inputProc = AudioIOProc;
-    rcbs.inputProcRefCon = refCon;
-    ERR_WRAP( AudioUnitSetProperty(
-                               *audioUnit,
-                               callbackKey,
-                               kAudioUnitScope_Output,
-                               outStreamParams ? OUTPUT_ELEMENT : INPUT_ELEMENT,
-                               &rcbs,
-                               sizeof(rcbs)) );
-
-    if( inStreamParams && outStreamParams && *srConverter )
-           ERR_WRAP( AudioUnitSetProperty(
-                               *audioUnit,
-                               kAudioOutputUnitProperty_SetInputCallback,
-                               kAudioUnitScope_Output,
-                               INPUT_ELEMENT,
-                               &rcbs,
-                               sizeof(rcbs)) );
-
-    /*IMPLEMENTME: may need to worry about channel mapping.*/
-
-    /* initialize the audio unit */
-    ERR_WRAP( AudioUnitInitialize(*audioUnit) );
-
-    if( inStreamParams && outStreamParams )
-       VDBUG( ("Opened device %ld for input and output.\n", *audioDevice ) );
-    else if( inStreamParams )
-       VDBUG( ("Opened device %ld for input.\n", *audioDevice ) );
-    else if( outStreamParams )
-       VDBUG( ("Opened device %ld for output.\n", *audioDevice ) );
-    return paNoError;
-#undef ERR_WRAP
-
-    error:
-       CloseComponent( *audioUnit );
-       *audioUnit = NULL;
-       if( result )
-          return PaMacCore_SetError( result, line, 1 );
-       return paResult;
-}
-
-/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData )
-{
-    PaError result = paNoError;
-    PaMacAUHAL *auhalHostApi = (PaMacAUHAL*)hostApi;
-    PaMacCoreStream *stream = 0;
-    int inputChannelCount, outputChannelCount;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
-    VVDBUG(("OpenStream(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld SR=%g, FPB=%ld\n",
-                inputParameters  ? inputParameters->channelCount  : -1,
-                inputParameters  ? inputParameters->sampleFormat  : -1,
-                outputParameters ? outputParameters->channelCount : -1,
-                outputParameters ? outputParameters->sampleFormat : -1,
-                (float) sampleRate,
-                framesPerBuffer ));
-    VDBUG( ("Opening Stream.\n") );
-
-    /*These first few bits of code are from paSkeleton with few modifications.*/
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that input device can support inputChannelCount */
-        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
-            return paInvalidChannelCount;
-
-        /* Host supports interleaved float32 */
-        hostInputSampleFormat = paFloat32;
-    }
-    else
-    {
-        inputChannelCount = 0;
-        inputSampleFormat = hostInputSampleFormat = paInt16; /* Surpress 'uninitialised var' warnings. */
-    }
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-        
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that output device can support inputChannelCount */
-        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
-            return paInvalidChannelCount;
-
-        /* Host supports interleaved float32 */
-        hostOutputSampleFormat = paFloat32;
-    }
-    else
-    {
-        outputChannelCount = 0;
-        outputSampleFormat = hostOutputSampleFormat = paFloat32; /* Surpress 'uninitialized var' warnings. */
-    }
-
-    /* validate platform specific flags */
-    if( (streamFlags & paPlatformSpecificFlags) != 0 )
-        return paInvalidFlag; /* unexpected platform specific flag */
-
-    stream = (PaMacCoreStream*)PaUtil_AllocateMemory( sizeof(PaMacCoreStream) );
-    if( !stream )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    /* If we fail after this point, we my be left in a bad state, with
-       some data structures setup and others not. So, first thing we
-       do is initialize everything so that if we fail, we know what hasn't
-       been touched.
-     */
-
-    stream->inputAudioBufferList.mBuffers[0].mData = NULL;
-    stream->inputRingBuffer.buffer = NULL;
-    stream->inputSRConverter = NULL;
-    stream->inputUnit = NULL;
-    stream->outputUnit = NULL;
-    stream->inputFramesPerBuffer = 0;
-    stream->outputFramesPerBuffer = 0;
-    stream->bufferProcessorIsInitialized = FALSE;
-
-    assert( streamCallback ) ; /* only callback mode is implemented */
-    if( streamCallback )
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &auhalHostApi->callbackStreamInterface, streamCallback, userData );
-    }
-    else
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &auhalHostApi->blockingStreamInterface, streamCallback, userData );
-    }
-
-    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
-
-    /* -- handle paFramesPerBufferUnspecified -- */
-    if( framesPerBuffer == paFramesPerBufferUnspecified ) {
-       long requested = 64;
-       if( inputParameters )
-          requested = MAX( requested, inputParameters->suggestedLatency * sampleRate / 2 );
-       if( outputParameters )
-          requested = MAX( requested, outputParameters->suggestedLatency *sampleRate / 2 );
-       VDBUG( ("Block Size unspecified. Based on Latency, the user wants a Block Size near: %ld.\n",
-              requested ) );
-       if( requested <= 64 ) {
-          /*requested a realtively low latency. make sure this is in range of devices */
-          /*try to get the device's min natural buffer size and use that (but no smaller than 64).*/
-          AudioValueRange audioRange;
-          size_t size = sizeof( audioRange );
-          if( inputParameters ) {
-             WARNING( result = AudioDeviceGetProperty( auhalHostApi->devIds[inputParameters->device],
-                                          0,
-                                          false,
-                                          kAudioDevicePropertyBufferFrameSizeRange,
-                                          &size, &audioRange ) );
-             if( result )
-                requested = MAX( requested, audioRange.mMinimum );
-          }
-          if( outputParameters ) {
-             WARNING( result = AudioDeviceGetProperty( auhalHostApi->devIds[outputParameters->device],
-                                          0,
-                                          false,
-                                          kAudioDevicePropertyBufferFrameSizeRange,
-                                          &size, &audioRange ) );
-             if( result )
-                requested = MAX( requested, audioRange.mMinimum );
-          }
-       } else {
-          /* requested a realtively high latency. make sure this is in range of devices */
-          /*try to get the device's max natural buffer size and use that (but no larger than 1024).*/
-          AudioValueRange audioRange;
-          size_t size = sizeof( audioRange );
-          requested = MIN( requested, 1024 );
-          if( inputParameters ) {
-             WARNING( result = AudioDeviceGetProperty( auhalHostApi->devIds[inputParameters->device],
-                                          0,
-                                          false,
-                                          kAudioDevicePropertyBufferFrameSizeRange,
-                                          &size, &audioRange ) );
-             if( result )
-                requested = MIN( requested, audioRange.mMaximum );
-          }
-          if( outputParameters ) {
-             WARNING( result = AudioDeviceGetProperty( auhalHostApi->devIds[outputParameters->device],
-                                          0,
-                                          false,
-                                          kAudioDevicePropertyBufferFrameSizeRange,
-                                          &size, &audioRange ) );
-             if( result )
-                requested = MIN( requested, audioRange.mMaximum );
-          }
-       }
-       /* -- double check ranges -- */
-       if( requested > 1024 ) requested = 1024;
-       if( requested < 64 ) requested = 64;
-       VDBUG(("After querying hardware, setting block size to %ld.\n", requested));
-       framesPerBuffer = requested;
-    }
-
-    /* -- Now we actually open and setup streams. -- */
-    if( inputParameters && outputParameters && outputParameters->device == inputParameters->device )
-    { /* full duplex. One device. */
-       result = OpenAndSetupOneAudioUnit( inputParameters,
-                                          outputParameters,
-                                          framesPerBuffer,
-                                          &(stream->inputFramesPerBuffer),
-                                          &(stream->outputFramesPerBuffer),
-                                          auhalHostApi,
-                                          &(stream->inputUnit),
-                                          &(stream->inputSRConverter),
-                                          &(stream->inputDevice),
-                                          sampleRate,
-                                          stream );
-       stream->outputUnit = stream->inputUnit;
-       stream->outputDevice = stream->inputDevice;
-       if( result != paNoError )
-           goto error;
-    }
-    else
-    { /* full duplex, different devices OR simplex */
-       result = OpenAndSetupOneAudioUnit( NULL,
-                                          outputParameters,
-                                          framesPerBuffer,
-                                          NULL,
-                                          &(stream->outputFramesPerBuffer),
-                                          auhalHostApi,
-                                          &(stream->outputUnit),
-                                          NULL,
-                                          &(stream->outputDevice),
-                                          sampleRate,
-                                          stream );
-       if( result != paNoError )
-           goto error;
-       result = OpenAndSetupOneAudioUnit( inputParameters,
-                                          NULL,
-                                          framesPerBuffer,
-                                          &(stream->inputFramesPerBuffer),
-                                          NULL,
-                                          auhalHostApi,
-                                          &(stream->inputUnit),
-                                          &(stream->inputSRConverter),
-                                          &(stream->inputDevice),
-                                          sampleRate,
-                                          stream );
-       if( result != paNoError )
-           goto error;
-    }
-
-    if( stream->inputUnit ) {
-       const size_t szfl = sizeof(float);
-       /* setup the AudioBufferList used for input */
-       bzero( &stream->inputAudioBufferList, sizeof( AudioBufferList ) );
-       stream->inputAudioBufferList.mNumberBuffers = 1;
-       stream->inputAudioBufferList.mBuffers[0].mNumberChannels
-                 = inputChannelCount;
-       stream->inputAudioBufferList.mBuffers[0].mDataByteSize
-                 = stream->inputFramesPerBuffer*inputChannelCount*szfl;
-       stream->inputAudioBufferList.mBuffers[0].mData
-                 = (float *) calloc(
-                               stream->inputFramesPerBuffer*inputChannelCount,
-                               szfl );
-       if( !stream->inputAudioBufferList.mBuffers[0].mData )
-       {
-          result = paInsufficientMemory;
-          goto error;
-       }
-        
-       /*
-        * If input and output devs are different or we are doing SR conversion,
-        * we also need a
-        * ring buffer to store inpt data while waiting for output
-        * data.
-        */
-       if( (stream->outputUnit && stream->inputUnit != stream->outputUnit)
-           || stream->inputSRConverter )
-       {
-          /* May want the ringSize ot initial position in
-             ring buffer to depend somewhat on sample rate change */
-          /* Calculate an appropriate ring buffer size. It must be at least
-             3x framesPerBuffer and 2x suggested latency and it must be a
-             power of 2. FEEDBACK: too liberal/conservative/another way?*/
-          double latency;
-          int index, i;
-          void *data;
-          long ringSize;
-          if( !outputParameters )
-             latency = inputParameters->suggestedLatency;
-          else
-             latency = MAX( inputParameters->suggestedLatency,
-                            outputParameters->suggestedLatency );
-          ringSize = latency * sampleRate * 2 * inputChannelCount;
-          VDBUG( ( "suggested latency: %d\n", (int) (latency*sampleRate) ) );
-          if( ringSize < stream->inputFramesPerBuffer * 3 )
-             ringSize = stream->inputFramesPerBuffer * 3 * inputChannelCount;
-          if( outputParameters && ringSize < stream->outputFramesPerBuffer * 3 )
-             ringSize = stream->outputFramesPerBuffer * 3 * inputChannelCount;
-          VDBUG(("inFramesPerBuffer:%d\n",(int)stream->inputFramesPerBuffer));
-          if( outputParameters )
-             VDBUG(("outFramesPerBuffer:%d\n",
-                      (int)stream->outputFramesPerBuffer));
-          VDBUG(("Ringbuffer size (1): %d\n", (int)ringSize ));
-
-          /* round up to the next power of 2 */
-          index = -1;
-          for( i=0; i<sizeof(long)*8; ++i )
-             if( ringSize >> i & 0x01 )
-                index = i;
-          assert( index > 0 );
-          if( ringSize <= ( 0x01 << index ) )
-             ringSize = 0x01 << index ;
-          else
-             ringSize = 0x01 << ( index + 1 );
-
-          /*ringSize <<= 4; *//*16x bigger, for testing */
-
-          VDBUG(( "Final Ringbuffer size (2): %d\n", (int)ringSize ));
-
-          /*now, we need to allocate memory for the ring buffer*/
-          data = calloc( ringSize, szfl );
-          if( !data )
-          {
-             result = paInsufficientMemory;
-             goto error;
-          }
-
-          /* now we can initialize the ring buffer */
-          assert( 0 ==
-            RingBuffer_Init( &stream->inputRingBuffer,
-                             ringSize*szfl, data ) );
-          /* advance the read point a little, so we are reading from the
-             middle of the buffer */
-          if( stream->outputUnit )
-             RingBuffer_AdvanceWriteIndex( &stream->inputRingBuffer, ringSize*szfl / RING_BUFFER_ADVANCE_DENOMINATOR );
-       }
-    }
-
-    /* -- initialize Buffer Processor -- */
-    {
-       unsigned long maxHostFrames = stream->inputFramesPerBuffer;
-       if( stream->outputFramesPerBuffer > maxHostFrames )
-          maxHostFrames = stream->outputFramesPerBuffer;
-       result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
-                 inputChannelCount, inputSampleFormat,
-                 hostInputSampleFormat,
-                 outputChannelCount, outputSampleFormat,
-                 hostOutputSampleFormat,
-                 sampleRate,
-                 streamFlags,
-                 framesPerBuffer,
-                 /* If sample rate conversion takes place, the buffer size
-                    will not be known. */
-                 maxHostFrames,
-                 stream->inputSRConverter
-                              ? paUtilUnknownHostBufferSize
-                              : paUtilBoundedHostBufferSize,
-                 streamCallback, userData );
-       if( result != paNoError )
-           goto error;
-    }
-    stream->bufferProcessorIsInitialized = TRUE;
-
-    /*
-        IMPLEMENT ME: initialise the following fields with estimated or actual
-        values.
-        I think this is okay the way it is br 12/1/05
-        maybe need to change input latency estimate if IO devs differ
-    */
-    stream->streamRepresentation.streamInfo.inputLatency =
-            PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor);
-    stream->streamRepresentation.streamInfo.outputLatency =
-            PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor);
-    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
-
-    stream->sampleRate  = sampleRate;
-    stream->userInChan  = inputChannelCount;
-    stream->userOutChan = outputChannelCount;
-
-    //stream->isTimeSet   = FALSE;
-    stream->state = STOPPED;
-    stream->xrunFlags = 0;
-
-    *s = (PaStream*)stream;
-
-    setStreamStartTime( stream );
-
-    return result;
-
-error:
-    CloseStream( stream );
-    return result;
-}
-
-PaTime GetStreamTime( PaStream *s )
-{
-   /* FIXME: I am not at all sure this timing info stuff is right.
-             patest_sine_time reports negative latencies, which is wierd.*/
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    AudioTimeStamp timeStamp;
-
-    VVDBUG(("GetStreamTime()\n"));
-
-    //if ( !stream->isTimeSet )
-    //    return (PaTime)0;
-
-    if ( stream->outputDevice )
-        AudioDeviceGetCurrentTime( stream->outputDevice, &timeStamp);
-    else if ( stream->inputDevice )
-        AudioDeviceGetCurrentTime( stream->inputDevice, &timeStamp);
-    else
-        return (PaTime)0;
-
-    return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->sampleRate;
-}
-
-static void setStreamStartTime( PaStream *stream )
-{
-   /* FIXME: I am not at all sure this timing info stuff is right.
-             patest_sine_time reports negative latencies, which is wierd.*/
-   VVDBUG(("setStreamStartTime()\n"));
-   PaMacCoreStream *s = (PaMacCoreStream *) stream;
-   if( s->inputDevice )
-      AudioDeviceGetCurrentTime( s->inputDevice, &s->startTime);
-   else
-      AudioDeviceGetCurrentTime( s->outputDevice, &s->startTime);
-}
-
-
-static PaTime TimeStampToSecs(PaMacCoreStream *stream, const AudioTimeStamp* timeStamp)
-{
-    VVDBUG(("TimeStampToSecs()\n"));
-    if (timeStamp->mFlags & kAudioTimeStampSampleTimeValid)
-        return (timeStamp->mSampleTime / stream->sampleRate);
-    else
-        return 0;
-}
-
-#define RING_BUFFER_EMPTY (1000)
-
-static OSStatus ringBufferIOProc( AudioConverterRef inAudioConverter, 
-                             UInt32*ioDataSize, 
-                             void** outData, 
-                             void*inUserData )
-{
-   void *dummyData;
-   long dummySize;
-   RingBuffer *rb = (RingBuffer *) inUserData;
-
-   VVDBUG(("ringBufferIOProc()\n"));
-
-   assert( sizeof( UInt32 ) == sizeof( long ) );
-   if( RingBuffer_GetReadAvailable( rb ) == 0 ) {
-      *outData = NULL;
-      *ioDataSize = 0;
-      return RING_BUFFER_EMPTY;
-   }
-   RingBuffer_GetReadRegions( rb, *ioDataSize,
-                              outData, (long *)ioDataSize, 
-                              &dummyData, &dummySize );
-      
-   assert( *ioDataSize );
-   RingBuffer_AdvanceReadIndex( rb, *ioDataSize );
-
-   return noErr;
-}
-
-/*
- * Called by the AudioUnit API to process audio from the sound card.
- * This is where the magic happens.
- */
-/* FEEDBACK: there is a lot of redundant code here because of how all the cases differ. This makes it hard to maintain, so if there are suggestinos for cleaning it up, I'm all ears. */
-static OSStatus AudioIOProc( void *inRefCon,
-                               AudioUnitRenderActionFlags *ioActionFlags,
-                               const AudioTimeStamp *inTimeStamp,
-                               UInt32 inBusNumber,
-                               UInt32 inNumberFrames,
-                               AudioBufferList *ioData )
-{
-   unsigned long framesProcessed     = 0;
-   PaStreamCallbackTimeInfo timeInfo = {0,0,0};
-   PaMacCoreStream *stream           = (PaMacCoreStream*)inRefCon;
-   const bool isRender               = inBusNumber == OUTPUT_ELEMENT;
-   int callbackResult                = paContinue ;
-
-   VVDBUG(("AudioIOProc()\n"));
-
-   PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
-
-   //if( !stream->isTimeSet )
-   //   setStreamStartTime( stream );
-   //stream->isTimeSet = TRUE;
-
-
-   /* -----------------------------------------------------------------*\
-      This output may be useful for debugging,
-      But printing durring the callback is a bad enough idea that
-      this is not enabled by enableing the usual debugging calls.
-   \* -----------------------------------------------------------------*/
-   /*
-   static int renderCount = 0;
-   static int inputCount = 0;
-   printf( "-------------------  starting reder/input\n" );
-   if( isRender )
-      printf("Render callback (%d):\t", ++renderCount);
-   else
-      printf("Input callback  (%d):\t", ++inputCount);
-   printf( "Call totals: %d (input), %d (render)\n", inputCount, renderCount );
-
-   printf( "--- inBusNumber: %lu\n", inBusNumber );
-   printf( "--- inNumberFrames: %lu\n", inNumberFrames );
-   printf( "--- %x ioData\n", (unsigned) ioData );
-   if( ioData )
-   {
-      int i=0;
-      printf( "--- ioData.mNumBuffers %lu: \n", ioData->mNumberBuffers );
-      for( i=0; i<ioData->mNumberBuffers; ++i )
-         printf( "--- ioData buffer %d size: %lu.\n", i, ioData->mBuffers[i].mDataByteSize );
-   }
-      ----------------------------------------------------------------- */
-
-   if( isRender ) {
-      AudioTimeStamp currentTime;
-      timeInfo.outputBufferDacTime = TimeStampToSecs(stream, inTimeStamp);
-      AudioDeviceGetCurrentTime(stream->outputDevice, &currentTime);
-      timeInfo.currentTime = TimeStampToSecs(stream, &currentTime);
-   }
-   if( isRender && stream->inputUnit == stream->outputUnit )
-      timeInfo.inputBufferAdcTime = TimeStampToSecs(stream, inTimeStamp);
-   if( !isRender ) {
-      AudioTimeStamp currentTime;
-      timeInfo.inputBufferAdcTime = TimeStampToSecs(stream, inTimeStamp);
-      AudioDeviceGetCurrentTime(stream->inputDevice, &currentTime);
-      timeInfo.currentTime = TimeStampToSecs(stream, &currentTime);
-   }
-
-
-   if( isRender && stream->inputUnit == stream->outputUnit
-                && !stream->inputSRConverter )
-   {
-      /* --------- Full Duplex, One Device, no SR Conversion -------
-       *
-       * This is the lowest latency case, and also the simplest.
-       * Input data and output data are available at the same time.
-       * we do not use the input SR converter or the input ring buffer.
-       *
-       */
-      OSErr err = 0;
-      unsigned long frames;
-
-      /* -- start processing -- */
-      PaUtil_BeginBufferProcessing( &(stream->bufferProcessor),
-                                    &timeInfo,
-                                    stream->xrunFlags );
-      stream->xrunFlags = 0;
-
-      /* -- compute frames. do some checks -- */
-      assert( ioData->mNumberBuffers == 1 );
-      assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan );
-      frames = ioData->mBuffers[0].mDataByteSize;
-      frames /= sizeof( float ) * ioData->mBuffers[0].mNumberChannels;
-      /* -- copy and process input data -- */
-      err= AudioUnitRender(stream->inputUnit,
-                    ioActionFlags,
-                    inTimeStamp,
-                    INPUT_ELEMENT,
-                    inNumberFrames,
-                    &stream->inputAudioBufferList );
-      /* FEEDBACK: I'm not sure what to do when this call fails */
-      assert( !err );
-
-      PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames );
-      PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
-                          0,
-                          stream->inputAudioBufferList.mBuffers[0].mData,
-                          stream->inputAudioBufferList.mBuffers[0].mNumberChannels);
-      /* -- Copy and process output data -- */
-      PaUtil_SetOutputFrameCount( &(stream->bufferProcessor), frames );
-      PaUtil_SetInterleavedOutputChannels( &(stream->bufferProcessor),
-                                        0,
-                                        ioData->mBuffers[0].mData,
-                                        ioData->mBuffers[0].mNumberChannels);
-      /* -- complete processing -- */
-      framesProcessed =
-                 PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
-                                             &callbackResult );
-   }
-   else if( isRender )
-   {
-      /* -------- Output Side of Full Duplex (Separate Devices or SR Conversion)
-       *       -- OR Simplex Output
-       *
-       * This case handles output data as in the full duplex case,
-       * and, if there is input data, reads it off the ring buffer 
-       * and into the PA buffer processor. If sample rate conversion
-       * is required on input, that is done here as well.
-       */
-      unsigned long frames;
-
-      /* Sometimes, when stopping a duplex stream we get erroneous
-         xrun flags, so if this is our last run, clear the flags. */
-      int xrunFlags = stream->xrunFlags;
-      if( xrunFlags & paInputUnderflow )
-         printf( "input underflow.\n" );
-      if( xrunFlags & paInputOverflow )
-         printf( "input overflow.\n" );
-      if( stream->state == STOPPING || stream->state == CALLBACK_STOPPED )
-         xrunFlags = 0;
-
-      /* -- start processing -- */
-      PaUtil_BeginBufferProcessing( &(stream->bufferProcessor),
-                                    &timeInfo,
-                                    xrunFlags );
-      stream->xrunFlags = 0; /* FEEDBACK: we only send flags to Buf Proc once */
-
-      /* -- Copy and process output data -- */
-      assert( ioData->mNumberBuffers == 1 );
-      frames = ioData->mBuffers[0].mDataByteSize;
-      frames /= sizeof( float ) * ioData->mBuffers[0].mNumberChannels;
-      assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan );
-      PaUtil_SetOutputFrameCount( &(stream->bufferProcessor), frames );
-      PaUtil_SetInterleavedOutputChannels( &(stream->bufferProcessor),
-                                     0,
-                                     ioData->mBuffers[0].mData,
-                                     ioData->mBuffers[0].mNumberChannels);
-
-      /* -- copy and process input data, and complete processing -- */
-      if( stream->inputUnit ) {
-         const int flsz = sizeof( float );
-         /* Here, we read the data out of the ring buffer, through the
-            audio converter. */
-         int inChan = stream->inputAudioBufferList.mBuffers[0].mNumberChannels;
-         if( stream->inputSRConverter )
-         {
-               OSStatus err;
-               UInt32 size;
-               float data[ inChan * frames ];
-               size = sizeof( data );
-               err = AudioConverterFillBuffer( 
-                             stream->inputSRConverter,
-                             ringBufferIOProc,
-                             &stream->inputRingBuffer,
-                             &size,
-                             (void *)&data );
-               if( err == RING_BUFFER_EMPTY )
-               { /*the ring buffer callback underflowed */
-                  err = 0;
-                  bzero( ((char *)data) + size, sizeof(data)-size );
-                  stream->xrunFlags |= paInputUnderflow;
-               }
-               ERR( err );
-               assert( !err );
-               
-               PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames );
-               PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
-                                   0,
-                                   data,
-                                   inChan );
-               framesProcessed =
-                    PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
-                                                &callbackResult );
-         }
-         else
-         {
-            /* Without the AudioConverter is actually a bit more complex
-               because we have to do a little buffer processing that the
-               AudioConverter would otherwise handle for us. */
-            void *data1, *data2;
-            long size1, size2;
-            RingBuffer_GetReadRegions( &stream->inputRingBuffer,
-                                       inChan*frames*flsz,
-                                       &data1, &size1,
-                                       &data2, &size2 );
-            if( size1 / ( flsz * inChan ) == frames ) {
-               /* simplest case: all in first buffer */
-               PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames );
-               PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
-                                   0,
-                                   data1,
-                                   inChan );
-               framesProcessed =
-                    PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
-                                                &callbackResult );
-               RingBuffer_AdvanceReadIndex(&stream->inputRingBuffer, size1 );
-            } else if( ( size1 + size2 ) / ( flsz * inChan ) < frames ) {
-               /*we underflowed. take what data we can, zero the rest.*/
-               float data[frames*inChan];
-               if( size1 )
-                  memcpy( data, data1, size1 );
-               if( size2 )
-                  memcpy( data+size1, data2, size2 );
-               bzero( data+size1+size2, frames*flsz*inChan - size1 - size2 );
-
-               PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames );
-               PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
-                                   0,
-                                   data,
-                                   inChan );
-               framesProcessed =
-                    PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
-                                                &callbackResult );
-               RingBuffer_AdvanceReadIndex( &stream->inputRingBuffer,
-                                            size1+size2 );
-               /* flag underflow */
-               stream->xrunFlags |= paInputUnderflow;
-            } else {
-               /*we got all the data, but split between buffers*/
-               PaUtil_SetInputFrameCount( &(stream->bufferProcessor),
-                                          size1 / ( flsz * inChan ) );
-               PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
-                                   0,
-                                   data1,
-                                   inChan );
-               PaUtil_Set2ndInputFrameCount( &(stream->bufferProcessor),
-                                             size2 / ( flsz * inChan ) );
-               PaUtil_Set2ndInterleavedInputChannels( &(stream->bufferProcessor),
-                                   0,
-                                   data2,
-                                   inChan );
-               framesProcessed =
-                    PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
-                                                &callbackResult );
-               RingBuffer_AdvanceReadIndex(&stream->inputRingBuffer, size1+size2 );
-            }
-         }
-      } else {
-         framesProcessed =
-                 PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
-                                             &callbackResult );
-      }
-
-   }
-   else
-   {
-      /* ------------------ Input
-       *
-       * First, we read off the audio data and put it in the ring buffer.
-       * if this is an input-only stream, we need to process it more,
-       * otherwise, we let the output case deal with it.
-       */
-      OSErr err = 0;
-      int chan = stream->inputAudioBufferList.mBuffers[0].mNumberChannels ;
-      /* FIXME: looping here may not actually be necessary, but it was something I tried in testing. */
-      do {
-         err= AudioUnitRender(stream->inputUnit,
-                 ioActionFlags,
-                 inTimeStamp,
-                 INPUT_ELEMENT,
-                 inNumberFrames,
-                 &stream->inputAudioBufferList );
-         if( err == -10874 )
-            inNumberFrames /= 2;
-      } while( err == -10874 && inNumberFrames > 1 );
-      /* FEEDBACK: I'm not sure what to do when this call fails */
-      ERR( err );
-      assert( !err );
-      if( stream->inputSRConverter || stream->outputUnit )
-      {
-         /* If this is duplex or we use a converter, put the data
-            into the ring buffer. */
-         long bytesIn, bytesOut;
-         bytesIn = sizeof( float ) * inNumberFrames * chan;
-         bytesOut = RingBuffer_Write( &stream->inputRingBuffer,
-                                stream->inputAudioBufferList.mBuffers[0].mData,
-                                bytesIn );
-         if( bytesIn != bytesOut )
-            stream->xrunFlags |= paInputOverflow ;
-      }
-      else
-      {
-         /* for simplex input w/o SR conversion,
-            just pop the data into the buffer processor.*/
-         PaUtil_BeginBufferProcessing( &(stream->bufferProcessor),
-                              &timeInfo,
-                              stream->xrunFlags );
-         stream->xrunFlags = 0;
-
-         PaUtil_SetInputFrameCount( &(stream->bufferProcessor), inNumberFrames);
-         PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
-                             0,
-                             stream->inputAudioBufferList.mBuffers[0].mData,
-                             chan );
-         framesProcessed =
-              PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
-                                          &callbackResult );
-      }
-      if( !stream->outputUnit && stream->inputSRConverter )
-      {
-         /* ------------------ Simplex Input w/ SR Conversion
-          *
-          * if this is a simplex input stream, we need to read off the buffer,
-          * do our sample rate conversion and pass the results to the buffer
-          * processor.
-          * The logic here is complicated somewhat by the fact that we don't
-          * know how much data is available, so we loop on reasonably sized
-          * chunks, and let the BufferProcessor deal with the rest.
-          *
-          */
-         /*This might be too big or small depending on SR conversion*/
-         float data[ chan * inNumberFrames ];
-         OSStatus err;
-         do
-         { /*Run the buffer processor until we are out of data*/
-            UInt32 size;
-            long f;
-
-            size = sizeof( data );
-            err = AudioConverterFillBuffer( 
-                          stream->inputSRConverter,
-                          ringBufferIOProc,
-                          &stream->inputRingBuffer,
-                          &size,
-                          (void *)data );
-            if( err != RING_BUFFER_EMPTY )
-               ERR( err );
-            assert( err == 0 || err == RING_BUFFER_EMPTY );
-
-            f = size / ( chan * sizeof(float) );
-            PaUtil_SetInputFrameCount( &(stream->bufferProcessor), f );
-            if( f )
-            {
-               PaUtil_BeginBufferProcessing( &(stream->bufferProcessor),
-                                             &timeInfo,
-                                             stream->xrunFlags );
-               stream->xrunFlags = 0;
-
-               PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
-                                0,
-                                data,
-                                chan );
-               framesProcessed =
-                    PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
-                                                &callbackResult );
-            }
-         } while( callbackResult == paContinue && !err );
-      }
-   }
-
-   switch( callbackResult )
-   {
-   case paContinue: break;
-   case paComplete:
-   case paAbort:
-      stream->state = CALLBACK_STOPPED ;
-      if( stream->outputUnit )
-         AudioOutputUnitStop(stream->outputUnit);
-      if( stream->inputUnit )
-         AudioOutputUnitStop(stream->inputUnit);
-      break;
-   }
-
-   PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
-   return noErr;
-}
-
-
-/*
-    When CloseStream() is called, the multi-api layer ensures that
-    the stream has already been stopped or aborted.
-*/
-static PaError CloseStream( PaStream* s )
-{
-    /* This may be called from a failed OpenStream.
-       Therefore, each piece of info is treated seperately. */
-    PaError result = paNoError;
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-
-    VVDBUG(("CloseStream()\n"));
-    VDBUG( ( "Closing stream.\n" ) );
-
-    if( stream ) {
-       if( stream->outputUnit && stream->outputUnit != stream->inputUnit ) {
-          AudioUnitUninitialize( stream->outputUnit );
-          CloseComponent( stream->outputUnit );
-       }
-       stream->outputUnit = NULL;
-       if( stream->inputUnit )
-       {
-          AudioUnitUninitialize( stream->inputUnit );
-          CloseComponent( stream->inputUnit );
-          stream->inputUnit = NULL;
-       }
-       if( stream->inputRingBuffer.buffer )
-          free( stream->inputRingBuffer.buffer );
-       stream->inputRingBuffer.buffer = NULL;
-       /*TODO: is there more that needs to be done on error
-               from AudioConverterDispose?*/
-       if( stream->inputSRConverter )
-          ERR( AudioConverterDispose( stream->inputSRConverter ) );
-       stream->inputSRConverter = NULL;
-       if( stream->inputAudioBufferList.mBuffers[0].mData )
-          free( stream->inputAudioBufferList.mBuffers[0].mData );
-       stream->inputAudioBufferList.mBuffers[0].mData = NULL;
-
-       if( stream->bufferProcessorIsInitialized )
-          PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
-       PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
-       PaUtil_FreeMemory( stream );
-    }
-
-    return result;
-}
-
-
-static PaError StartStream( PaStream *s )
-{
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    OSErr result = noErr;
-    VVDBUG(("StartStream()\n"));
-    VDBUG( ( "Starting stream.\n" ) );
-
-#define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0)
-
-    /*FIXME: maybe want to do this on close/abort for faster start? */
-    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
-    if(  stream->inputSRConverter )
-       ERR_WRAP( AudioConverterReset( stream->inputSRConverter ) );
-
-    /* -- start -- */
-    stream->state = ACTIVE;
-    if( stream->inputUnit ) {
-       ERR_WRAP( AudioOutputUnitStart(stream->inputUnit) );
-    }
-    if( stream->outputUnit && stream->outputUnit != stream->inputUnit ) {
-       ERR_WRAP( AudioOutputUnitStart(stream->outputUnit) );
-    }
-
-    return paNoError;
-#undef ERR_WRAP
-}
-
-
-static PaError StopStream( PaStream *s )
-{
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    OSErr result = noErr;
-    VVDBUG(("StopStream()\n"));
-    VDBUG( ( "Stopping stream.\n" ) );
-
-    stream->state = STOPPING;
-
-#define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0)
-    /* -- stop and reset -- */
-    if( stream->inputUnit == stream->outputUnit && stream->inputUnit )
-    {
-       ERR_WRAP( AudioOutputUnitStop(stream->inputUnit) );
-       ERR_WRAP( AudioUnitReset(stream->inputUnit, kAudioUnitScope_Global, 1) );
-       ERR_WRAP( AudioUnitReset(stream->inputUnit, kAudioUnitScope_Global, 0) );
-    }
-    else
-    {
-       if( stream->inputUnit )
-       {
-          ERR_WRAP(AudioOutputUnitStop(stream->inputUnit) );
-          ERR_WRAP(AudioUnitReset(stream->inputUnit,kAudioUnitScope_Global,1));
-       }
-       if( stream->outputUnit )
-       {
-          ERR_WRAP(AudioOutputUnitStop(stream->outputUnit));
-          ERR_WRAP(AudioUnitReset(stream->outputUnit,kAudioUnitScope_Global,0));
-       }
-    }
-    if( stream->inputRingBuffer.buffer ) {
-       RingBuffer_Flush( &stream->inputRingBuffer );
-       bzero(stream->inputRingBuffer.buffer,stream->inputRingBuffer.bufferSize);
-       /* advance the write point a little, so we are reading from the
-          middle of the buffer. We'll need extra at the end because
-          testing has shown that this helps. */
-       if( stream->outputUnit )
-          RingBuffer_AdvanceWriteIndex( &stream->inputRingBuffer,
-                                    stream->inputRingBuffer.bufferSize
-                                           / RING_BUFFER_ADVANCE_DENOMINATOR );
-    }
-
-    //stream->isTimeSet = FALSE;
-    stream->xrunFlags = 0;
-    stream->state = STOPPED;
-
-    VDBUG( ( "Stream Stopped.\n" ) );
-    return paNoError;
-#undef ERR_WRAP
-}
-
-static PaError AbortStream( PaStream *s )
-{
-    VVDBUG(("AbortStream()->StopStream()\n"));
-    VDBUG( ( "Aborting stream.\n" ) );
-    /* We have nothing faster than StopStream. */
-    return StopStream(s);
-}
-
-
-static PaError IsStreamStopped( PaStream *s )
-{
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    VVDBUG(("IsStreamStopped()\n"));
-
-    return stream->state == STOPPED ? 1 : 0;
-}
-
-
-static PaError IsStreamActive( PaStream *s )
-{
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    VVDBUG(("IsStreamActive()\n"));
-    return ( stream->state == ACTIVE || stream->state == STOPPING );
-}
-
-
-static double GetStreamCpuLoad( PaStream* s )
-{
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    VVDBUG(("GetStreamCpuLoad()\n"));
-
-    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
-}
-
-
-/*
-    As separate stream interfaces are used for blocking and callback
-    streams, the following functions can be guaranteed to only be called
-    for blocking streams. IMPLEMENTME: no blocking interface yet!
-*/
-
-static PaError ReadStream( PaStream* s,
-                           void *buffer,
-                           unsigned long frames )
-{
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    VVDBUG(("ReadStream()\n"));
-
-    /* suppress unused variable warnings */
-    (void) buffer;
-    (void) frames;
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return paNoError;
-}
-
-
-static PaError WriteStream( PaStream* s,
-                            const void *buffer,
-                            unsigned long frames )
-{
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    VVDBUG(("WriteStream()\n"));
-
-    /* suppress unused variable warnings */
-    (void) buffer;
-    (void) frames;
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return paNoError;
-}
-
-
-static signed long GetStreamReadAvailable( PaStream* s )
-{
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    VVDBUG(("GetStreamReadAvailable()\n"));
-
-    /* suppress unused variable warnings */
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return 0;
-}
-
-
-static signed long GetStreamWriteAvailable( PaStream* s )
-{
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    VVDBUG(("GetStreamWriteAvailable()\n"));
-
-    /* suppress unused variable warnings */
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return 0;
-}
diff --git a/portaudio/pa_mac_core/pa_mac_core.h b/portaudio/pa_mac_core/pa_mac_core.h
deleted file mode 100644
index 5994294ad..000000000
--- a/portaudio/pa_mac_core/pa_mac_core.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Mac spcific flags for PA.
- * portaudio.h should be included before this file.
- */
-
-/*
- * A pointer to a paMacCoreStreamInfo may be passed as
- * the hostApiSpecificStreamInfo in the PaStreamParameters struct
- * when opening a stream. Use NULL, for the defaults. Note that for
- * duplex streams, both infos should be the same or behaviour
- * is undefined.
- */
-typedef struct paMacCoreStreamInfo
-{
-    unsigned long size;         /**size of whole structure including this header */
-    PaHostApiTypeId hostApiType;/**host API for which this data is intended */
-    unsigned long version;      /**structure version */
-    unsigned long flags;        /* flags to modify behaviour */
-} paMacCoreStreamInfo;
-
-/* Use this function to initialize a paMacCoreStreamInfo struct
-   using the requested flags. */
-void paSetupMacCoreStreamInfo( paMacCoreStreamInfo *data, unsigned long flags )
-{
-   bzero( data, sizeof( paMacCoreStreamInfo ) );
-   data->size = sizeof( paMacCoreStreamInfo );
-   data->hostApiType = paCoreAudio;
-   data->version = 0x01;
-   data->flags = flags;
-}
-
-/*
- * The following flags alter the behaviour of PA on the mac platform.
- * they can be ORed together. These should work both for opening and
- * checking a device.
- */
-/* Allows PortAudio to change things like the device's frame size,
- * which allows for much lower latency, but might disrupt the device
- * if other programs are using it. */
-const unsigned long paMacCore_ChangeDeviceParameters      = 0x01;
-
-/* In combination with the above flag,
- * causes the stream opening to fail, unless the exact sample rates
- * are supported by the device. */
-const unsigned long paMacCore_FailIfConversionRequired    = 0x02;
-
-/* These flags set the SR conversion quality, if required. The wierd ordering
- * allows Maximum Quality to be the default.*/
-const unsigned long paMacCore_ConversionQualityMin    = 0x0100;
-const unsigned long paMacCore_ConversionQualityMedium = 0x0200;
-const unsigned long paMacCore_ConversionQualityLow    = 0x0300;
-const unsigned long paMacCore_ConversionQualityHigh   = 0x0400;
-const unsigned long paMacCore_ConversionQualityMax    = 0x0000;
-
-/*
- * Here are some "preset" combinations of flags (above) to get to some
- * common configurations. THIS IS OVERKILL, but if more flags are added
- * it won't be.
- */
-/*This is the default setting: do as much sample rate conversion as possible
- * and as little mucking with the device as possible. */
-const unsigned long paMacCorePlayNice = 0x00;
-/*This setting is tuned for pro audio apps. It allows SR conversion on input
-  and output, but it tries to set the appropriate SR on the device.*/
-const unsigned long paMacCorePro      = 0x01;
-/*This is a setting to minimize CPU usage and still play nice.*/
-const unsigned long paMacCoreMinimizeCPUButPlayNice = 0x0100;
-/*This is a setting to minimize CPU usage, even if that means interrupting the device. */
-const unsigned long paMacCoreMinimizeCPU = 0x0101;
diff --git a/portaudio/pa_mac_core/pa_mac_core_old.c b/portaudio/pa_mac_core/pa_mac_core_old.c
deleted file mode 100644
index b1a1f0e15..000000000
--- a/portaudio/pa_mac_core/pa_mac_core_old.c
+++ /dev/null
@@ -1,907 +0,0 @@
-/*
- * $Id: pa_mac_core_old.c,v 1.1.2.1 2005/12/24 01:22:52 bjornroche Exp $
- * pa_mac_core.c
- * Implementation of PortAudio for Mac OS X CoreAudio       
- *                                                                                         
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com
- *
- * Authors: Ross Bencina and Phil Burk
- * 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 <CoreAudio/CoreAudio.h>
-#include <AudioToolbox/AudioToolbox.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <assert.h>
-
-#include "portaudio.h"
-#include "pa_trace.h"
-#include "pa_util.h"
-#include "pa_allocation.h"
-#include "pa_hostapi.h"
-#include "pa_stream.h"
-#include "pa_cpuload.h"
-#include "pa_process.h"
-
-// =====  constants  =====
-
-// =====  structs  =====
-#pragma mark structs
-
-// PaMacCoreHostApiRepresentation - host api datastructure specific to this implementation
-typedef struct PaMacCore_HAR
-{
-    PaUtilHostApiRepresentation inheritedHostApiRep;
-    PaUtilStreamInterface callbackStreamInterface;
-    PaUtilStreamInterface blockingStreamInterface;
-    
-    PaUtilAllocationGroup *allocations;
-    AudioDeviceID *macCoreDeviceIds;
-}
-PaMacCoreHostApiRepresentation;
-
-typedef struct PaMacCore_DI
-{
-    PaDeviceInfo inheritedDeviceInfo;
-}
-PaMacCoreDeviceInfo;
-
-// PaMacCoreStream - a stream data structure specifically for this implementation
-typedef struct PaMacCore_S
-{
-    PaUtilStreamRepresentation streamRepresentation;
-    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
-    PaUtilBufferProcessor bufferProcessor;
-    
-    int primeStreamUsingCallback;
-    
-    AudioDeviceID inputDevice;
-    AudioDeviceID outputDevice;
-    
-    // Processing thread management --------------
-//    HANDLE abortEvent;
-//    HANDLE processingThread;
-//    DWORD processingThreadId;
-    
-    char throttleProcessingThreadOnOverload; // 0 -> don't throtte, non-0 -> throttle
-    int processingThreadPriority;
-    int highThreadPriority;
-    int throttledThreadPriority;
-    unsigned long throttledSleepMsecs;
-    
-    int isStopped;
-    volatile int isActive;
-    volatile int stopProcessing; // stop thread once existing buffers have been returned
-    volatile int abortProcessing; // stop thread immediately
-    
-//    DWORD allBuffersDurationMs; // used to calculate timeouts
-}
-PaMacCoreStream;
-
-// Data needed by the CoreAudio callback functions
-typedef struct PaMacCore_CD
-{
-    PaMacCoreStream *stream;
-    PaStreamCallback *callback;
-    void *userData;
-    PaUtilConverter *inputConverter;
-    PaUtilConverter *outputConverter;
-    void *inputBuffer;
-    void *outputBuffer;
-    int inputChannelCount;
-    int outputChannelCount;
-    PaSampleFormat inputSampleFormat;
-    PaSampleFormat outputSampleFormat;
-    PaUtilTriangularDitherGenerator *ditherGenerator;
-}
-PaMacClientData;
-
-// =====  CoreAudio-PortAudio bridge functions =====
-#pragma mark CoreAudio-PortAudio bridge functions
-
-// Maps CoreAudio OSStatus codes to PortAudio PaError codes
-static PaError conv_err(OSStatus error)
-{
-    PaError result;
-    
-    switch (error) {
-        case kAudioHardwareNoError:
-            result = paNoError; break;
-        case kAudioHardwareNotRunningError:
-            result = paInternalError; break;
-        case kAudioHardwareUnspecifiedError:
-            result = paInternalError; break;
-        case kAudioHardwareUnknownPropertyError:
-            result = paInternalError; break;
-        case kAudioHardwareBadPropertySizeError:
-            result = paInternalError; break;
-        case kAudioHardwareIllegalOperationError:
-            result = paInternalError; break;
-        case kAudioHardwareBadDeviceError:
-            result = paInvalidDevice; break;
-        case kAudioHardwareBadStreamError:
-            result = paBadStreamPtr; break;
-        case kAudioHardwareUnsupportedOperationError:
-            result = paInternalError; break;
-        case kAudioDeviceUnsupportedFormatError:
-            result = paSampleFormatNotSupported; break;
-        case kAudioDevicePermissionsError:
-            result = paDeviceUnavailable; break;
-        default:
-            result = paInternalError;
-    }
-    
-    return result;
-}
-
-/* This function is unused
-static AudioStreamBasicDescription *InitializeStreamDescription(const PaStreamParameters *parameters, double sampleRate)
-{
-    struct AudioStreamBasicDescription *streamDescription = PaUtil_AllocateMemory(sizeof(AudioStreamBasicDescription));
-    streamDescription->mSampleRate = sampleRate;
-    streamDescription->mFormatID = kAudioFormatLinearPCM;
-    streamDescription->mFormatFlags = 0;
-    streamDescription->mFramesPerPacket = 1;
-    
-    if (parameters->sampleFormat & paNonInterleaved) {
-        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsNonInterleaved;
-        streamDescription->mChannelsPerFrame = 1;
-        streamDescription->mBytesPerFrame = Pa_GetSampleSize(parameters->sampleFormat);
-        streamDescription->mBytesPerPacket = Pa_GetSampleSize(parameters->sampleFormat);
-    }
-    else {
-        streamDescription->mChannelsPerFrame = parameters->channelCount;
-    }
-    
-    streamDescription->mBytesPerFrame = Pa_GetSampleSize(parameters->sampleFormat) * streamDescription->mChannelsPerFrame;
-    streamDescription->mBytesPerPacket = streamDescription->mBytesPerFrame * streamDescription->mFramesPerPacket;
-    
-    if (parameters->sampleFormat & paFloat32) {
-        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
-        streamDescription->mBitsPerChannel = 32;
-    }
-    else if (parameters->sampleFormat & paInt32) {
-        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
-        streamDescription->mBitsPerChannel = 32;
-    }
-    else if (parameters->sampleFormat & paInt24) {
-        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
-        streamDescription->mBitsPerChannel = 24;
-    }
-    else if (parameters->sampleFormat & paInt16) {
-        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
-        streamDescription->mBitsPerChannel = 16;
-    }
-    else if (parameters->sampleFormat & paInt8) {
-        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
-        streamDescription->mBitsPerChannel = 8;
-    }    
-    else if (parameters->sampleFormat & paInt32) {
-        streamDescription->mBitsPerChannel = 8;
-    }
-    
-    return streamDescription;
-}
-*/
-
-static PaStreamCallbackTimeInfo *InitializeTimeInfo(const AudioTimeStamp* now, const AudioTimeStamp* inputTime, const AudioTimeStamp* outputTime)
-{
-    PaStreamCallbackTimeInfo *timeInfo = PaUtil_AllocateMemory(sizeof(PaStreamCallbackTimeInfo));
-    
-    timeInfo->inputBufferAdcTime = inputTime->mSampleTime;
-    timeInfo->currentTime = now->mSampleTime;
-    timeInfo->outputBufferDacTime = outputTime->mSampleTime;
-    
-    return timeInfo;
-}
-
-// =====  support functions  =====
-#pragma mark support functions
-
-static void CleanUp(PaMacCoreHostApiRepresentation *macCoreHostApi)
-{
-    if( macCoreHostApi->allocations )
-    {
-        PaUtil_FreeAllAllocations( macCoreHostApi->allocations );
-        PaUtil_DestroyAllocationGroup( macCoreHostApi->allocations );
-    }
-    
-    PaUtil_FreeMemory( macCoreHostApi );    
-}
-
-static PaError GetChannelInfo(PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, int isInput)
-{
-    UInt32 propSize;
-    PaError err = paNoError;
-    UInt32 i;
-    int numChannels = 0;
-    AudioBufferList *buflist;
-
-    err = conv_err(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, NULL));
-    buflist = PaUtil_AllocateMemory(propSize);
-    err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, buflist));
-    if (!err) {
-        for (i = 0; i < buflist->mNumberBuffers; ++i) {
-            numChannels += buflist->mBuffers[i].mNumberChannels;
-        }
-		
-		if (isInput)
-			deviceInfo->maxInputChannels = numChannels;
-		else
-			deviceInfo->maxOutputChannels = numChannels;
-		
-        int frameLatency;
-        propSize = sizeof(UInt32);
-        err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyLatency, &propSize, &frameLatency));
-        if (!err) {
-            double secondLatency = frameLatency / deviceInfo->defaultSampleRate;
-            if (isInput) {
-                deviceInfo->defaultLowInputLatency = secondLatency;
-                deviceInfo->defaultHighInputLatency = secondLatency;
-            }
-            else {
-                deviceInfo->defaultLowOutputLatency = secondLatency;
-                deviceInfo->defaultHighOutputLatency = secondLatency;
-            }
-        }
-    }
-    PaUtil_FreeMemory(buflist);
-    
-    return err;
-}
-
-static PaError InitializeDeviceInfo(PaMacCoreDeviceInfo *macCoreDeviceInfo,  AudioDeviceID macCoreDeviceId, PaHostApiIndex hostApiIndex )
-{
-    PaDeviceInfo *deviceInfo = &macCoreDeviceInfo->inheritedDeviceInfo;
-    deviceInfo->structVersion = 2;
-    deviceInfo->hostApi = hostApiIndex;
-    
-    PaError err = paNoError;
-    UInt32 propSize;
-
-    err = conv_err(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL));
-    // FIXME: this allocation should be part of the allocations group
-    char *name = PaUtil_AllocateMemory(propSize);
-    err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name));
-    if (!err) {
-        deviceInfo->name = name;
-    }
-    
-    Float64 sampleRate;
-    propSize = sizeof(Float64);
-    err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &sampleRate));
-    if (!err) {
-        deviceInfo->defaultSampleRate = sampleRate;
-    }
-
-
-    // Get channel info
-    err = GetChannelInfo(deviceInfo, macCoreDeviceId, 1);
-    err = GetChannelInfo(deviceInfo, macCoreDeviceId, 0);
-
-    return err;
-}
-
-static PaError InitializeDeviceInfos( PaMacCoreHostApiRepresentation *macCoreHostApi, PaHostApiIndex hostApiIndex )
-{
-    PaError result = paNoError;
-    PaUtilHostApiRepresentation *hostApi;
-    PaMacCoreDeviceInfo *deviceInfoArray;
-
-    // initialise device counts and default devices under the assumption that there are no devices. These values are incremented below if and when devices are successfully initialized.
-    hostApi = &macCoreHostApi->inheritedHostApiRep;
-    hostApi->info.deviceCount = 0;
-    hostApi->info.defaultInputDevice = paNoDevice;
-    hostApi->info.defaultOutputDevice = paNoDevice;
-    
-    UInt32 propsize;
-    AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propsize, NULL);
-    int numDevices = propsize / sizeof(AudioDeviceID);
-    hostApi->info.deviceCount = numDevices;
-    if (numDevices > 0) {
-        hostApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
-                                            macCoreHostApi->allocations, sizeof(PaDeviceInfo*) * numDevices );
-        if( !hostApi->deviceInfos )
-        {
-            return paInsufficientMemory;
-        }
-
-        // allocate all device info structs in a contiguous block
-        deviceInfoArray = (PaMacCoreDeviceInfo*)PaUtil_GroupAllocateMemory(
-                                macCoreHostApi->allocations, sizeof(PaMacCoreDeviceInfo) * numDevices );
-        if( !deviceInfoArray )
-        {
-            return paInsufficientMemory;
-        }
-        
-        macCoreHostApi->macCoreDeviceIds = PaUtil_GroupAllocateMemory(macCoreHostApi->allocations, propsize);
-        AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propsize, macCoreHostApi->macCoreDeviceIds);
-
-        AudioDeviceID defaultInputDevice, defaultOutputDevice;
-        propsize = sizeof(AudioDeviceID);
-        AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &propsize, &defaultInputDevice);
-        AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &propsize, &defaultOutputDevice);
-        
-        UInt32 i;
-        for (i = 0; i < numDevices; ++i) {
-            if (macCoreHostApi->macCoreDeviceIds[i] == defaultInputDevice) {
-                hostApi->info.defaultInputDevice = i;
-            }
-            if (macCoreHostApi->macCoreDeviceIds[i] == defaultOutputDevice) {
-                hostApi->info.defaultOutputDevice = i;
-            }
-            InitializeDeviceInfo(&deviceInfoArray[i], macCoreHostApi->macCoreDeviceIds[i], hostApiIndex);
-            hostApi->deviceInfos[i] = &(deviceInfoArray[i].inheritedDeviceInfo);      
-        }
-    }
-
-    return result;
-}
-
-static OSStatus CheckFormat(AudioDeviceID macCoreDeviceId, const PaStreamParameters *parameters, double sampleRate, int isInput)
-{
-    UInt32 propSize = sizeof(AudioStreamBasicDescription);
-    AudioStreamBasicDescription *streamDescription = PaUtil_AllocateMemory(propSize);
-
-    streamDescription->mSampleRate = sampleRate;
-    streamDescription->mFormatID = 0;
-    streamDescription->mFormatFlags = 0;
-    streamDescription->mBytesPerPacket = 0;
-    streamDescription->mFramesPerPacket = 0;
-    streamDescription->mBytesPerFrame = 0;
-    streamDescription->mChannelsPerFrame = 0;
-    streamDescription->mBitsPerChannel = 0;
-    streamDescription->mReserved = 0;
-
-    OSStatus result = AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamFormatSupported, &propSize, streamDescription);
-    PaUtil_FreeMemory(streamDescription);
-    return result;
-}
-
-static OSStatus CopyInputData(PaMacClientData* destination, const AudioBufferList *source, unsigned long frameCount)
-{
-    int frameSpacing, channelSpacing;
-    if (destination->inputSampleFormat & paNonInterleaved) {
-        frameSpacing = 1;
-        channelSpacing = destination->inputChannelCount;
-    }
-    else {
-        frameSpacing = destination->inputChannelCount;
-        channelSpacing = 1;
-    }
-    
-    AudioBuffer const *inputBuffer = &source->mBuffers[0];
-    void *coreAudioBuffer = inputBuffer->mData;
-    void *portAudioBuffer = destination->inputBuffer;
-    UInt32 i, streamNumber, streamChannel;
-    for (i = streamNumber = streamChannel = 0; i < destination->inputChannelCount; ++i, ++streamChannel) {
-        if (streamChannel >= inputBuffer->mNumberChannels) {
-            ++streamNumber;
-            inputBuffer = &source->mBuffers[streamNumber];
-            coreAudioBuffer = inputBuffer->mData;
-            streamChannel = 0;
-        }
-        destination->inputConverter(portAudioBuffer, frameSpacing, coreAudioBuffer, inputBuffer->mNumberChannels, frameCount, destination->ditherGenerator);
-        coreAudioBuffer += sizeof(Float32);
-        portAudioBuffer += Pa_GetSampleSize(destination->inputSampleFormat) * channelSpacing;
-    }
-    return noErr;
-}
-
-static OSStatus CopyOutputData(AudioBufferList* destination, PaMacClientData *source, unsigned long frameCount)
-{
-    int frameSpacing, channelSpacing;
-    if (source->outputSampleFormat & paNonInterleaved) {
-        frameSpacing = 1;
-        channelSpacing = source->outputChannelCount;
-    }
-    else {
-        frameSpacing = source->outputChannelCount;
-        channelSpacing = 1;
-    }
-    
-    AudioBuffer *outputBuffer = &destination->mBuffers[0];
-    void *coreAudioBuffer = outputBuffer->mData;
-    void *portAudioBuffer = source->outputBuffer;
-    UInt32 i, streamNumber, streamChannel;
-    for (i = streamNumber = streamChannel = 0; i < source->outputChannelCount; ++i, ++streamChannel) {
-        if (streamChannel >= outputBuffer->mNumberChannels) {
-            ++streamNumber;
-            outputBuffer = &destination->mBuffers[streamNumber];
-            coreAudioBuffer = outputBuffer->mData;
-            streamChannel = 0;
-        }
-        source->outputConverter(coreAudioBuffer, outputBuffer->mNumberChannels, portAudioBuffer, frameSpacing, frameCount, NULL);
-        coreAudioBuffer += sizeof(Float32);
-        portAudioBuffer += Pa_GetSampleSize(source->outputSampleFormat) * channelSpacing;
-    }
-    return noErr;
-}
-
-static OSStatus AudioIOProc( AudioDeviceID inDevice,
-                      const AudioTimeStamp* inNow,
-                      const AudioBufferList* inInputData,
-                      const AudioTimeStamp* inInputTime,
-                      AudioBufferList* outOutputData, 
-                      const AudioTimeStamp* inOutputTime,
-                      void* inClientData)
-{
-    PaMacClientData *clientData = (PaMacClientData *)inClientData;
-    PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);
-    
-    PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );
-    
-    AudioBuffer *outputBuffer = &outOutputData->mBuffers[0];
-    unsigned long frameCount = outputBuffer->mDataByteSize / (outputBuffer->mNumberChannels * sizeof(Float32));
-
-    if (clientData->inputBuffer) {
-        CopyInputData(clientData, inInputData, frameCount);
-    }
-    PaStreamCallbackResult result = clientData->callback(clientData->inputBuffer, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);
-    if (clientData->outputBuffer) {
-        CopyOutputData(outOutputData, clientData, frameCount);
-    }
-
-    PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
-    
-    if (result == paComplete || result == paAbort) {
-        Pa_StopStream(clientData->stream);
-    }
-
-    PaUtil_FreeMemory( timeInfo );
-    return noErr;
-}
-
-// This is not for input-only streams, this is for streams where the input device is different from the output device
-static OSStatus AudioInputProc( AudioDeviceID inDevice,
-                         const AudioTimeStamp* inNow,
-                         const AudioBufferList* inInputData,
-                         const AudioTimeStamp* inInputTime,
-                         AudioBufferList* outOutputData, 
-                         const AudioTimeStamp* inOutputTime,
-                         void* inClientData)
-{
-    PaMacClientData *clientData = (PaMacClientData *)inClientData;
-    PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);
-
-    PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );
-
-    AudioBuffer const *inputBuffer = &inInputData->mBuffers[0];
-    unsigned long frameCount = inputBuffer->mDataByteSize / (inputBuffer->mNumberChannels * sizeof(Float32));
-
-    CopyInputData(clientData, inInputData, frameCount);
-    PaStreamCallbackResult result = clientData->callback(clientData->inputBuffer, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);
-    
-    PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
-    if( result == paComplete || result == paAbort )
-       Pa_StopStream(clientData->stream);
-    PaUtil_FreeMemory( timeInfo );
-    return noErr;
-}
-
-// This is not for output-only streams, this is for streams where the input device is different from the output device
-static OSStatus AudioOutputProc( AudioDeviceID inDevice,
-                          const AudioTimeStamp* inNow,
-                          const AudioBufferList* inInputData,
-                          const AudioTimeStamp* inInputTime,
-                          AudioBufferList* outOutputData, 
-                          const AudioTimeStamp* inOutputTime,
-                          void* inClientData)
-{
-    PaMacClientData *clientData = (PaMacClientData *)inClientData;
-    //PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);
-
-    PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );
-
-    AudioBuffer *outputBuffer = &outOutputData->mBuffers[0];
-    unsigned long frameCount = outputBuffer->mDataByteSize / (outputBuffer->mNumberChannels * sizeof(Float32));
-
-    //clientData->callback(NULL, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);
-
-    CopyOutputData(outOutputData, clientData, frameCount);
-
-    PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
-    return noErr;
-}
-
-static PaError SetSampleRate(AudioDeviceID device, double sampleRate, int isInput)
-{
-    PaError result = paNoError;
-    
-    double actualSampleRate;
-    UInt32 propSize = sizeof(double);
-    result = conv_err(AudioDeviceSetProperty(device, NULL, 0, isInput, kAudioDevicePropertyNominalSampleRate, propSize, &sampleRate));
-    
-    result = conv_err(AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyNominalSampleRate, &propSize, &actualSampleRate));
-    
-    if (result == paNoError && actualSampleRate != sampleRate) {
-        result = paInvalidSampleRate;
-    }
-    
-    return result;    
-}
-
-static PaError SetFramesPerBuffer(AudioDeviceID device, unsigned long framesPerBuffer, int isInput)
-{
-    PaError result = paNoError;
-    UInt32 preferredFramesPerBuffer = framesPerBuffer;
-    //    while (preferredFramesPerBuffer > UINT32_MAX) {
-    //        preferredFramesPerBuffer /= 2;
-    //    }
-    
-    UInt32 actualFramesPerBuffer;
-    UInt32 propSize = sizeof(UInt32);
-    result = conv_err(AudioDeviceSetProperty(device, NULL, 0, isInput, kAudioDevicePropertyBufferFrameSize, propSize, &preferredFramesPerBuffer));
-    
-    result = conv_err(AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propSize, &actualFramesPerBuffer));
-    
-    if (result != paNoError) {
-        // do nothing
-    }
-    else if (actualFramesPerBuffer > framesPerBuffer) {
-        result = paBufferTooSmall;
-    }
-    else if (actualFramesPerBuffer < framesPerBuffer) {
-        result = paBufferTooBig;
-    }
-    
-    return result;    
-}
-    
-static PaError SetUpUnidirectionalStream(AudioDeviceID device, double sampleRate, unsigned long framesPerBuffer, int isInput)
-{
-    PaError err = paNoError;
-    err = SetSampleRate(device, sampleRate, isInput);
-    if( err == paNoError )
-        err = SetFramesPerBuffer(device, framesPerBuffer, isInput);
-    return err;
-}
-
-// =====  PortAudio functions  =====
-#pragma mark PortAudio functions
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif // __cplusplus
-    
-    PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-    
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
-{
-    PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation*)hostApi;
-    
-    CleanUp(macCoreHostApi);
-}
-
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate )
-{
-    PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation*)hostApi;
-    PaDeviceInfo *deviceInfo;
-    
-    PaError result = paNoError;
-    if (inputParameters) {
-        deviceInfo = macCoreHostApi->inheritedHostApiRep.deviceInfos[inputParameters->device];
-        if (inputParameters->channelCount > deviceInfo->maxInputChannels)
-            result = paInvalidChannelCount;
-        else if (CheckFormat(macCoreHostApi->macCoreDeviceIds[inputParameters->device], inputParameters, sampleRate, 1) != kAudioHardwareNoError) {
-            result = paInvalidSampleRate;
-        }
-    }
-    if (outputParameters && result == paNoError) {
-        deviceInfo = macCoreHostApi->inheritedHostApiRep.deviceInfos[outputParameters->device];
-        if (outputParameters->channelCount > deviceInfo->maxOutputChannels)
-            result = paInvalidChannelCount;
-        else if (CheckFormat(macCoreHostApi->macCoreDeviceIds[outputParameters->device], outputParameters, sampleRate, 0) != kAudioHardwareNoError) {
-            result = paInvalidSampleRate;
-        }
-    }
-
-    return result;
-}
-
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData )
-{
-    PaError err = paNoError;
-    PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation *)hostApi;
-    PaMacCoreStream *stream = PaUtil_AllocateMemory(sizeof(PaMacCoreStream));
-    stream->isActive = 0;
-    stream->isStopped = 1;
-    stream->inputDevice = kAudioDeviceUnknown;
-    stream->outputDevice = kAudioDeviceUnknown;
-    
-    PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                           ( (streamCallback)
-                                             ? &macCoreHostApi->callbackStreamInterface
-                                             : &macCoreHostApi->blockingStreamInterface ),
-                                           streamCallback, userData );
-    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
-    
-    *s = (PaStream*)stream;
-    PaMacClientData *clientData = PaUtil_AllocateMemory(sizeof(PaMacClientData));
-    clientData->stream = stream;
-    clientData->callback = streamCallback;
-    clientData->userData = userData;
-    clientData->inputBuffer = 0;
-    clientData->outputBuffer = 0;
-    clientData->ditherGenerator = PaUtil_AllocateMemory(sizeof(PaUtilTriangularDitherGenerator));
-    PaUtil_InitializeTriangularDitherState(clientData->ditherGenerator);
-    
-    if (inputParameters != NULL) {
-        stream->inputDevice = macCoreHostApi->macCoreDeviceIds[inputParameters->device];
-        clientData->inputConverter = PaUtil_SelectConverter(paFloat32, inputParameters->sampleFormat, streamFlags);
-        clientData->inputBuffer = PaUtil_AllocateMemory(Pa_GetSampleSize(inputParameters->sampleFormat) * framesPerBuffer * inputParameters->channelCount);
-        clientData->inputChannelCount = inputParameters->channelCount;
-        clientData->inputSampleFormat = inputParameters->sampleFormat;
-        err = SetUpUnidirectionalStream(stream->inputDevice, sampleRate, framesPerBuffer, 1);
-    }
-    
-    if (err == paNoError && outputParameters != NULL) {
-        stream->outputDevice = macCoreHostApi->macCoreDeviceIds[outputParameters->device];
-        clientData->outputConverter = PaUtil_SelectConverter(outputParameters->sampleFormat, paFloat32, streamFlags);
-        clientData->outputBuffer = PaUtil_AllocateMemory(Pa_GetSampleSize(outputParameters->sampleFormat) * framesPerBuffer * outputParameters->channelCount);
-        clientData->outputChannelCount = outputParameters->channelCount;
-        clientData->outputSampleFormat = outputParameters->sampleFormat;
-        err = SetUpUnidirectionalStream(stream->outputDevice, sampleRate, framesPerBuffer, 0);
-    }
-
-    if (inputParameters == NULL || outputParameters == NULL || stream->inputDevice == stream->outputDevice) {
-        AudioDeviceID device = (inputParameters == NULL) ? stream->outputDevice : stream->inputDevice;
-
-        AudioDeviceAddIOProc(device, AudioIOProc, clientData);
-    }
-    else {
-        // using different devices for input and output
-        AudioDeviceAddIOProc(stream->inputDevice, AudioInputProc, clientData);
-        AudioDeviceAddIOProc(stream->outputDevice, AudioOutputProc, clientData);
-    }
-    
-    return err;
-}
-
-// Note: When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted.
-static PaError CloseStream( PaStream* s )
-{
-    PaError err = paNoError;
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-
-    PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer );
-
-    if (stream->inputDevice != kAudioDeviceUnknown) {
-        if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
-            err = conv_err(AudioDeviceRemoveIOProc(stream->inputDevice, AudioIOProc));
-        }
-        else {
-            err = conv_err(AudioDeviceRemoveIOProc(stream->inputDevice, AudioInputProc));
-            err = conv_err(AudioDeviceRemoveIOProc(stream->outputDevice, AudioOutputProc));
-        }
-    }
-    else {
-        err = conv_err(AudioDeviceRemoveIOProc(stream->outputDevice, AudioIOProc));
-    }
-    
-    return err;
-}
-
-
-static PaError StartStream( PaStream *s )
-{
-    PaError err = paNoError;
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-
-    if (stream->inputDevice != kAudioDeviceUnknown) {
-        if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
-            err = conv_err(AudioDeviceStart(stream->inputDevice, AudioIOProc));
-        }
-        else {
-            err = conv_err(AudioDeviceStart(stream->inputDevice, AudioInputProc));
-            err = conv_err(AudioDeviceStart(stream->outputDevice, AudioOutputProc));
-        }
-    }
-    else {
-        err = conv_err(AudioDeviceStart(stream->outputDevice, AudioIOProc));
-    }
-    
-    stream->isActive = 1;
-    stream->isStopped = 0;
-    return err;
-}
-
-static PaError AbortStream( PaStream *s )
-{
-    PaError err = paNoError;
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    
-    if (stream->inputDevice != kAudioDeviceUnknown) {
-        if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
-            err = conv_err(AudioDeviceStop(stream->inputDevice, AudioIOProc));
-        }
-        else {
-            err = conv_err(AudioDeviceStop(stream->inputDevice, AudioInputProc));
-            err = conv_err(AudioDeviceStop(stream->outputDevice, AudioOutputProc));
-        }
-    }
-    else {
-        err = conv_err(AudioDeviceStop(stream->outputDevice, AudioIOProc));
-    }
-    
-    stream->isActive = 0;
-    stream->isStopped = 1;
-    return err;
-}    
-
-static PaError StopStream( PaStream *s )
-{
-    // TODO: this should be nicer than abort
-    return AbortStream(s);
-}
-
-static PaError IsStreamStopped( PaStream *s )
-{
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    
-    return stream->isStopped;
-}
-
-
-static PaError IsStreamActive( PaStream *s )
-{
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-
-    return stream->isActive;
-}
-
-
-static PaTime GetStreamTime( PaStream *s )
-{
-    OSStatus err;
-    PaTime result;
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-
-    AudioTimeStamp *timeStamp = PaUtil_AllocateMemory(sizeof(AudioTimeStamp));
-    if (stream->inputDevice != kAudioDeviceUnknown) {
-        err = AudioDeviceGetCurrentTime(stream->inputDevice, timeStamp);
-    }
-    else {
-        err = AudioDeviceGetCurrentTime(stream->outputDevice, timeStamp);
-    }
-    
-    result = err ? 0 : timeStamp->mSampleTime;
-    PaUtil_FreeMemory(timeStamp);
-
-    return result;
-}
-
-
-static double GetStreamCpuLoad( PaStream* s )
-{
-    PaMacCoreStream *stream = (PaMacCoreStream*)s;
-    
-    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
-}
-
-
-// As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams.
-
-static PaError ReadStream( PaStream* s,
-                           void *buffer,
-                           unsigned long frames )
-{
-    return paInternalError;
-}
-
-
-static PaError WriteStream( PaStream* s,
-                            const void *buffer,
-                            unsigned long frames )
-{
-    return paInternalError;
-}
-
-
-static signed long GetStreamReadAvailable( PaStream* s )
-{
-    return paInternalError;
-}
-
-
-static signed long GetStreamWriteAvailable( PaStream* s )
-{
-    return paInternalError;
-}
-
-// HostAPI-specific initialization function
-PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
-{
-    PaError result = paNoError;
-    PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation *)PaUtil_AllocateMemory( sizeof(PaMacCoreHostApiRepresentation) );
-    if( !macCoreHostApi )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-    
-    macCoreHostApi->allocations = PaUtil_CreateAllocationGroup();
-    if( !macCoreHostApi->allocations )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-    
-    *hostApi = &macCoreHostApi->inheritedHostApiRep;
-    (*hostApi)->info.structVersion = 1;
-    (*hostApi)->info.type = paCoreAudio;
-    (*hostApi)->info.name = "CoreAudio";
-
-    result = InitializeDeviceInfos(macCoreHostApi, hostApiIndex);
-    if (result != paNoError) {
-        goto error;
-    }
-    
-    // Set up the proper callbacks to this HostApi's functions
-    (*hostApi)->Terminate = Terminate;
-    (*hostApi)->OpenStream = OpenStream;
-    (*hostApi)->IsFormatSupported = IsFormatSupported;
-    
-    PaUtil_InitializeStreamInterface( &macCoreHostApi->callbackStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, GetStreamCpuLoad,
-                                      PaUtil_DummyRead, PaUtil_DummyWrite,
-                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
-    
-    PaUtil_InitializeStreamInterface( &macCoreHostApi->blockingStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
-                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
-    
-    return result;
-    
-error:
-        if( macCoreHostApi ) {
-            CleanUp(macCoreHostApi);
-        }
-    
-    return result;
-}
diff --git a/portaudio/pa_mac_core/pa_mac_core_utilities.c b/portaudio/pa_mac_core/pa_mac_core_utilities.c
deleted file mode 100644
index f2cbd29cb..000000000
--- a/portaudio/pa_mac_core/pa_mac_core_utilities.c
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- *
- * pa_mac_core_utilities.c
- *
- * utilitiy functions for pa_mac_core.c
- *
- * This functions are more like helper functions than part of the core,
- *  so I moved them to a separate file so the core code would be cleaner.
- *
- * by Bjorn Roche.
- */
-
-/*
- * Translates MacOS generated errors into PaErrors
- */
-static PaError PaMacCore_SetError(OSStatus error, int line, int isError)
-{
-    /*FIXME: still need to handle possible ComponentResult values.*/
-    /*       unfortunately, they don't seem to be documented anywhere.*/
-    PaError result;
-    const char *errorType; 
-    const char *errorText;
-    
-    switch (error) {
-    case kAudioHardwareNoError:
-        return paNoError;
-    case kAudioHardwareNotRunningError:
-        errorText = "Audio Hardware Not Running";
-        result = paInternalError; break;
-    case kAudioHardwareUnspecifiedError: 
-        errorText = "Unspecified Audio Hardware Error";
-        result = paInternalError; break;
-    case kAudioHardwareUnknownPropertyError:
-        errorText = "Audio Hardware: Unknown Property";
-        result = paInternalError; break;
-    case kAudioHardwareBadPropertySizeError:
-        errorText = "Audio Hardware: Bad Property Size";
-        result = paInternalError; break;
-    case kAudioHardwareIllegalOperationError: 
-        errorText = "Audio Hardware: Illegal Operation";
-        result = paInternalError; break;
-    case kAudioHardwareBadDeviceError:
-        errorText = "Audio Hardware: Bad Device";
-        result = paInvalidDevice; break;
-    case kAudioHardwareBadStreamError:
-        errorText = "Audio Hardware: BadStream";
-        result = paBadStreamPtr; break;
-    case kAudioHardwareUnsupportedOperationError:
-        errorText = "Audio Hardware: Unsupported Operation";
-        result = paInternalError; break;
-    case kAudioDeviceUnsupportedFormatError:
-        errorText = "Audio Device: Unsupported Format";
-        result = paSampleFormatNotSupported; break;
-    case kAudioDevicePermissionsError:
-        errorText = "Audio Device: Permissions Error";
-        result = paDeviceUnavailable; break;
-    /* Audio Unit Errors: http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudio/audio_units/chapter_5_section_3.html */
-    case kAudioUnitErr_InvalidProperty:
-        errorText = "Audio Unit: Invalid Property";
-        result = paInternalError; break;
-    case kAudioUnitErr_InvalidParameter:
-        errorText = "Audio Unit: Invalid Parameter";
-        result = paInternalError; break;
-    case kAudioUnitErr_NoConnection:
-        errorText = "Audio Unit: No Connection";
-        result = paInternalError; break;
-    case kAudioUnitErr_FailedInitialization:
-        errorText = "Audio Unit: Initialization Failed";
-        result = paInternalError; break;
-    case kAudioUnitErr_TooManyFramesToProcess:
-        errorText = "Audio Unit: Too Many Frames";
-        result = paInternalError; break;
-    case kAudioUnitErr_IllegalInstrument:
-        errorText = "Audio Unit: Illegal Instrument";
-        result = paInternalError; break;
-    case kAudioUnitErr_InstrumentTypeNotFound:
-        errorText = "Audio Unit: Instrument Type Not Found";
-        result = paInternalError; break;
-    case kAudioUnitErr_InvalidFile:
-        errorText = "Audio Unit: Invalid File";
-        result = paInternalError; break;
-    case kAudioUnitErr_UnknownFileType:
-        errorText = "Audio Unit: Unknown File Type";
-        result = paInternalError; break;
-    case kAudioUnitErr_FileNotSpecified:
-        errorText = "Audio Unit: File Not Specified";
-        result = paInternalError; break;
-    case kAudioUnitErr_FormatNotSupported:
-        errorText = "Audio Unit: Format Not Supported";
-        result = paInternalError; break;
-    case kAudioUnitErr_Uninitialized:
-        errorText = "Audio Unit: Unitialized";
-        result = paInternalError; break;
-    case kAudioUnitErr_InvalidScope:
-        errorText = "Audio Unit: Invalid Scope";
-        result = paInternalError; break;
-    case kAudioUnitErr_PropertyNotWritable:
-        errorText = "Audio Unit: PropertyNotWritable";
-        result = paInternalError; break;
-    case kAudioUnitErr_InvalidPropertyValue:
-        errorText = "Audio Unit: Invalid Property Value";
-        result = paInternalError; break;
-    case kAudioUnitErr_PropertyNotInUse:
-        errorText = "Audio Unit: Property Not In Use";
-        result = paInternalError; break;
-    case kAudioUnitErr_Initialized:
-        errorText = "Audio Unit: Initialized";
-        result = paInternalError; break;
-    case kAudioUnitErr_InvalidOfflineRender:
-        errorText = "Audio Unit: Invalid Offline Render";
-        result = paInternalError; break;
-    case kAudioUnitErr_Unauthorized:
-        errorText = "Audio Unit: Unauthorized";
-        result = paInternalError; break;
-    case kAudioUnitErr_CannotDoInCurrentContext:
-        errorText = "Audio Unit: cannot do in current context";
-        result = paInternalError; break;
-    default:
-        errorText = "Unknown Error";
-        result = paInternalError;
-    }
-
-    if (isError)
-        errorType = "Error";
-    else
-        errorType = "Warning";
-
-    if ((int)error < -99999 || (int)error > 99999)
-        DBUG(("%s on line %d: err='%4s', msg='%s'\n", errorType, line, (const char *)&error, errorText));
-    else
-        DBUG(("%s on line %d: err=%d, 0x%x, msg='%s'\n", errorType, line, (int)error, (unsigned)error, errorText));
-
-    PaUtil_SetLastHostErrorInfo( paCoreAudio, error, errorText );
-
-    return result;
-}
-
-
-
-
-/*
- * Durring testing of core audio, I found that serious crashes could occur
- * if properties such as sample rate were changed multiple times in rapid
- * succession. The function below has some fancy logic to make sure that changes
- * are acknowledged before another is requested. That seems to help a lot.
- */
-
-#include <pthread.h>
-typedef struct {
-   bool once; /* I didn't end up using this. bdr */
-   pthread_mutex_t mutex;
-} MutexAndBool ;
-
-static OSStatus propertyProc(
-    AudioDeviceID inDevice, 
-    UInt32 inChannel, 
-    Boolean isInput, 
-    AudioDevicePropertyID inPropertyID, 
-    void* inClientData )
-{
-   MutexAndBool *mab = (MutexAndBool *) inClientData;
-   mab->once = TRUE;
-   pthread_mutex_unlock( &(mab->mutex) );
-   return noErr;
-}
-
-/* sets the value of the given property and waits for the change to 
-   be acknowledged, and returns the final value, which is not guaranteed
-   by this function to be the same as the desired value. Obviously, this
-   function can only be used for data whose input and output are the
-   same size and format, and their size and format are known in advance.*/
-PaError AudioDeviceSetPropertyNowAndWaitForChange(
-    AudioDeviceID inDevice,
-    UInt32 inChannel, 
-    Boolean isInput, 
-    AudioDevicePropertyID inPropertyID,
-    UInt32 inPropertyDataSize, 
-    const void *inPropertyData,
-    void *outPropertyData )
-{
-   OSStatus macErr;
-   int unixErr;
-   MutexAndBool mab;
-   UInt32 outPropertyDataSize = inPropertyDataSize;
-
-   /* First, see if it already has that value. If so, return. */
-   macErr = AudioDeviceGetProperty( inDevice, inChannel,
-                                 isInput, inPropertyID, 
-                                 &outPropertyDataSize, outPropertyData );
-   if( macErr )
-      goto failMac2;
-   if( inPropertyDataSize!=outPropertyDataSize )
-      return paInternalError;
-   if( 0==memcmp( outPropertyData, inPropertyData, outPropertyDataSize ) )
-      return paNoError;
-
-   /* setup and lock mutex */
-   mab.once = FALSE;
-   unixErr = pthread_mutex_init( &mab.mutex, NULL );
-   if( unixErr )
-      goto failUnix2;
-   unixErr = pthread_mutex_lock( &mab.mutex );
-   if( unixErr )
-      goto failUnix;
-
-   /* add property listener */
-   macErr = AudioDeviceAddPropertyListener( inDevice, inChannel, isInput,
-                                   inPropertyID, propertyProc,
-                                   &mab ); 
-   if( macErr )
-      goto failMac;
-   /* set property */
-   macErr  = AudioDeviceSetProperty( inDevice, NULL, inChannel,
-                                 isInput, inPropertyID,
-                                 inPropertyDataSize, inPropertyData );
-   if( macErr ) {
-      /* we couldn't set the property, so we'll just unlock the mutex
-         and move on. */
-      pthread_mutex_unlock( &mab.mutex );
-   }
-
-   /* wait for property to change */                      
-   unixErr = pthread_mutex_lock( &mab.mutex );
-   if( unixErr )
-      goto failUnix;
-
-   /* now read the property back out */
-   macErr = AudioDeviceGetProperty( inDevice, inChannel,
-                                 isInput, inPropertyID, 
-                                 &outPropertyDataSize, outPropertyData );
-   if( macErr )
-      goto failMac;
-   /* cleanup */
-   AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput,
-                                      inPropertyID, propertyProc );
-   unixErr = pthread_mutex_unlock( &mab.mutex );
-   if( unixErr )
-      goto failUnix2;
-   unixErr = pthread_mutex_destroy( &mab.mutex );
-   if( unixErr )
-      goto failUnix2;
-
-   return paNoError;
-
- failUnix:
-   pthread_mutex_destroy( &mab.mutex );
-   AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput,
-                                      inPropertyID, propertyProc );
-
- failUnix2:
-   DBUG( ("Error #%d while setting a device property: %s\n", unixErr, strerror( unixErr ) ) );
-   return paUnanticipatedHostError;
-
- failMac:
-   pthread_mutex_destroy( &mab.mutex );
-   AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput,
-                                      inPropertyID, propertyProc );
- failMac2:
-   return ERR( macErr );
-}
-
-/*
- * Sets the sample rate the HAL device.
- * if requireExact: set the sample rate or fail.
- *
- * otherwise      : set the exact sample rate.
- *             If that fails, check for available sample rates, and choose one
- *             higher than the requested rate. If there isn't a higher one,
- *             just use the highest available.
- */
-static PaError setBestSampleRateForDevice( const AudioDeviceID device,
-                                    const bool isOutput,
-                                    const bool requireExact,
-                                    const Float64 desiredSrate )
-{
-   /*FIXME: changing the sample rate is disruptive to other programs using the
-            device, so it might be good to offer a custom flag to not change the
-            sample rate and just do conversion. (in my casual tests, there is
-            no disruption unless the sample rate really does need to change) */
-   const bool isInput = isOutput ? 0 : 1;
-   Float64 srate;
-   UInt32 propsize = sizeof( Float64 );
-   OSErr err;
-   AudioValueRange *ranges;
-   int i=0;
-   Float64 max  = -1; /*the maximum rate available*/
-   Float64 best = -1; /*the lowest sample rate still greater than desired rate*/
-   VDBUG(("Setting sample rate for device %ld to %g.\n",device,(float)desiredSrate));
-
-   /* -- try setting the sample rate -- */
-   err = AudioDeviceSetPropertyNowAndWaitForChange(
-                                 device, 0, isInput,
-                                 kAudioDevicePropertyNominalSampleRate,
-                                 propsize, &desiredSrate, &srate );
-   if( err )
-      return err;
-
-   /* -- if the rate agrees, and we got no errors, we are done -- */
-   if( !err && srate == desiredSrate )
-      return paNoError;
-   /* -- we've failed if the rates disagree and we are setting input -- */
-   if( requireExact )
-      return paInvalidSampleRate;
-
-   /* -- generate a list of available sample rates -- */
-   err = AudioDeviceGetPropertyInfo( device, 0, isInput,
-                                kAudioDevicePropertyAvailableNominalSampleRates,
-                                &propsize, NULL );
-   if( err )
-      return ERR( err );
-   ranges = (AudioValueRange *)calloc( 1, propsize );
-   if( !ranges )
-      return paInsufficientMemory;
-   err = AudioDeviceGetProperty( device, 0, isInput,
-                                kAudioDevicePropertyAvailableNominalSampleRates,
-                                &propsize, ranges );
-   if( err )
-   {
-      free( ranges );
-      return ERR( err );
-   }
-   VDBUG(("Requested sample rate of %g was not available.\n", (float)desiredSrate));
-   VDBUG(("%lu Available Sample Rates are:\n",propsize/sizeof(AudioValueRange)));
-#ifdef MAC_CORE_VERBOSE_DEBUG
-   for( i=0; i<propsize/sizeof(AudioValueRange); ++i )
-      VDBUG( ("\t%g-%g\n",
-              (float) ranges[i].mMinimum,
-              (float) ranges[i].mMaximum ) );
-#endif
-   VDBUG(("-----\n"));
-   
-   /* -- now pick the best available sample rate -- */
-   for( i=0; i<propsize/sizeof(AudioValueRange); ++i )
-   {
-      if( ranges[i].mMaximum > max ) max = ranges[i].mMaximum;
-      if( ranges[i].mMinimum > desiredSrate ) {
-         if( best < 0 )
-            best = ranges[i].mMinimum;
-         else if( ranges[i].mMinimum < best )
-            best = ranges[i].mMinimum;
-      }
-   }
-   if( best < 0 )
-      best = max;
-   VDBUG( ("Maximum Rate %g. best is %g.\n", max, best ) );
-   free( ranges );
-
-   /* -- set the sample rate -- */
-   propsize = sizeof( best );
-   err = AudioDeviceSetPropertyNowAndWaitForChange(
-                                 device, 0, isInput,
-                                 kAudioDevicePropertyNominalSampleRate,
-                                 propsize, &best, &srate );
-   if( err )
-      return err;
-
-   if( err )
-      return ERR( err );
-   /* -- if the set rate matches, we are done -- */
-   if( srate == best )
-      return paNoError;
-
-   /* -- otherwise, something wierd happened: we didn't set the rate, and we got no errors. Just bail. */
-   return paInternalError;
-}
-
-
-/*
-   Attempts to set the requestedFramesPerBuffer. If it can't set the exact
-   value, it settles for something smaller if available. If nothing smaller
-   is available, it uses the smallest available size.
-   actualFramesPerBuffer will be set to the actual value on successful return.
-   OK to pass NULL to actualFramesPerBuffer.
-   The logic is very simmilar too setBestSampleRate only failure here is
-   not usually catastrophic.
-*/
-static PaError setBestFramesPerBuffer( const AudioDeviceID device,
-                                       const bool isOutput,
-                                       unsigned long requestedFramesPerBuffer, 
-                                       unsigned long *actualFramesPerBuffer )
-{
-   UInt32 afpb;
-   const bool isInput = !isOutput;
-   UInt32 propsize = sizeof(UInt32);
-   OSErr err;
-   Float64 min  = -1; /*the min blocksize*/
-   Float64 best = -1; /*the best blocksize*/
-   int i=0;
-   AudioValueRange *ranges;
-
-   if( actualFramesPerBuffer == NULL )
-      actualFramesPerBuffer = &afpb;
-
-
-   /* -- try and set exact FPB -- */
-   err = AudioDeviceSetProperty( device, NULL, 0, isInput,
-                                 kAudioDevicePropertyBufferFrameSize,
-                                 propsize, &requestedFramesPerBuffer);
-   err = AudioDeviceGetProperty( device, 0, isInput,
-                           kAudioDevicePropertyBufferFrameSize,
-                           &propsize, actualFramesPerBuffer);
-   if( err )
-      return ERR( err );
-   if( *actualFramesPerBuffer == requestedFramesPerBuffer )
-      return paNoError; /* we are done */
-
-   /* -- fetch available block sizes -- */
-   err = AudioDeviceGetPropertyInfo( device, 0, isInput,
-                           kAudioDevicePropertyBufferSizeRange,
-                           &propsize, NULL );
-   if( err )
-      return ERR( err );
-   ranges = (AudioValueRange *)calloc( 1, propsize );
-   if( !ranges )
-      return paInsufficientMemory;
-   err = AudioDeviceGetProperty( device, 0, isInput,
-                                kAudioDevicePropertyBufferSizeRange,
-                                &propsize, ranges );
-   if( err )
-   {
-      free( ranges );
-      return ERR( err );
-   }
-   VDBUG(("Requested block size of %lu was not available.\n",
-          requestedFramesPerBuffer ));
-   VDBUG(("%lu Available block sizes are:\n",propsize/sizeof(AudioValueRange)));
-#ifdef MAC_CORE_VERBOSE_DEBUG
-   for( i=0; i<propsize/sizeof(AudioValueRange); ++i )
-      VDBUG( ("\t%g-%g\n",
-              (float) ranges[i].mMinimum,
-              (float) ranges[i].mMaximum ) );
-#endif
-   VDBUG(("-----\n"));
-   
-   /* --- now pick the best available framesPerBuffer -- */
-   for( i=0; i<propsize/sizeof(AudioValueRange); ++i )
-   {
-      if( min == -1 || ranges[i].mMinimum < min ) min = ranges[i].mMinimum;
-      if( ranges[i].mMaximum < requestedFramesPerBuffer ) {
-         if( best < 0 )
-            best = ranges[i].mMaximum;
-         else if( ranges[i].mMaximum > best )
-            best = ranges[i].mMaximum;
-      }
-   }
-   if( best == -1 )
-      best = min;
-   VDBUG( ("Minimum FPB  %g. best is %g.\n", min, best ) );
-   free( ranges );
-
-   /* --- set the buffer size (ignore errors) -- */
-   requestedFramesPerBuffer = (UInt32) best ;
-   propsize = sizeof( UInt32 );
-   err = AudioDeviceSetProperty( device, NULL, 0, isInput,
-                                 kAudioDevicePropertyBufferSize,
-                                 propsize, &requestedFramesPerBuffer );
-   /* --- read the property to check that it was set -- */
-   err = AudioDeviceGetProperty( device, 0, isInput,
-                                 kAudioDevicePropertyBufferSize,
-                                 &propsize, actualFramesPerBuffer );
-
-   if( err )
-      return ERR( err );
-
-   return paNoError;
-}
diff --git a/portaudio/pa_unix/CVS/Entries b/portaudio/pa_unix/CVS/Entries
deleted file mode 100644
index 7f24f7229..000000000
--- a/portaudio/pa_unix/CVS/Entries
+++ /dev/null
@@ -1,4 +0,0 @@
-/pa_unix_hostapis.c/1.1.2.5/Thu Oct  2 12:35:46 2003//Tv19-devel
-/pa_unix_util.c/1.1.2.8/Sun Nov 20 13:46:13 2005//Tv19-devel
-/pa_unix_util.h/1.1.2.3/Fri Feb 25 02:19:40 2005//Tv19-devel
-D
diff --git a/portaudio/pa_unix/CVS/Repository b/portaudio/pa_unix/CVS/Repository
deleted file mode 100644
index 610e5b880..000000000
--- a/portaudio/pa_unix/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_unix
diff --git a/portaudio/pa_unix/CVS/Root b/portaudio/pa_unix/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_unix/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_unix/CVS/Tag b/portaudio/pa_unix/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_unix/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_unix/pa_unix_hostapis.c b/portaudio/pa_unix/pa_unix_hostapis.c
deleted file mode 100644
index 9bddc2e0d..000000000
--- a/portaudio/pa_unix/pa_unix_hostapis.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * $Id: pa_unix_hostapis.c,v 1.1.2.5 2003/10/02 12:35:46 pieter Exp $
- * Portable Audio I/O Library UNIX initialization table
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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 "pa_hostapi.h"
-
-PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-/* Added for IRIX, Pieter, oct 2, 2003: */
-PaError PaSGI_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-
-
-PaUtilHostApiInitializer *paHostApiInitializers[] =
-    {
-#ifdef PA_USE_OSS
-        PaOSS_Initialize,
-#endif
-
-#ifdef PA_USE_ALSA
-        PaAlsa_Initialize,
-#endif
-
-#ifdef PA_USE_JACK
-        PaJack_Initialize,
-#endif
-                    /* Added for IRIX, Pieter, oct 2, 2003: */
-#ifdef PA_USE_SGI 
-        PaSGI_Initialize,
-#endif
-        0   /* NULL terminated array */
-    };
-
-int paDefaultHostApiIndex = 0;
-
-
diff --git a/portaudio/pa_unix/pa_unix_util.c b/portaudio/pa_unix/pa_unix_util.c
deleted file mode 100644
index 88ca60922..000000000
--- a/portaudio/pa_unix/pa_unix_util.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * $Id: pa_unix_util.c,v 1.1.2.8 2005/11/20 13:46:13 aknudsen Exp $
- * Portable Audio I/O Library
- * UNIX platform-specific support functions
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2000 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.
- */
-
- 
-#include <pthread.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <time.h>
-#include <sys/time.h>
-#include <assert.h>
-#include <string.h> /* For memset */
-
-#include "pa_util.h"
-#include "pa_unix_util.h"
-
-/*
-   Track memory allocations to avoid leaks.
- */
-
-#if PA_TRACK_MEMORY
-static int numAllocations_ = 0;
-#endif
-
-
-void *PaUtil_AllocateMemory( long size )
-{
-    void *result = malloc( size );
-
-#if PA_TRACK_MEMORY
-    if( result != NULL ) numAllocations_ += 1;
-#endif
-    return result;
-}
-
-
-void PaUtil_FreeMemory( void *block )
-{
-    if( block != NULL )
-    {
-        free( block );
-#if PA_TRACK_MEMORY
-        numAllocations_ -= 1;
-#endif
-
-    }
-}
-
-
-int PaUtil_CountCurrentlyAllocatedBlocks( void )
-{
-#if PA_TRACK_MEMORY
-    return numAllocations_;
-#else
-    return 0;
-#endif
-}
-
-
-void Pa_Sleep( long msec )
-{
-#ifdef HAVE_NANOSLEEP
-    struct timespec req = {0}, rem = {0};
-    PaTime time = msec / 1.e3;
-    req.tv_sec = (time_t)time;
-    assert(time - req.tv_sec < 1.0);
-    req.tv_nsec = (long)((time - req.tv_sec) * 1.e9);
-    nanosleep(&req, &rem);
-    /* XXX: Try sleeping the remaining time (contained in rem) if interrupted by a signal? */
-#else
-    while( msec > 999 )     /* For OpenBSD and IRIX, argument */
-        {                   /* to usleep must be < 1000000.   */
-        usleep( 999000 );
-        msec -= 999;
-        }
-    usleep( msec * 1000 );
-#endif
-}
-
-/*            *** NOT USED YET: ***
-static int usePerformanceCounter_;
-static double microsecondsPerTick_;
-*/
-
-void PaUtil_InitializeClock( void )
-{
-    /* TODO */
-}
-
-
-PaTime PaUtil_GetTime( void )
-{
-#ifdef HAVE_CLOCK_GETTIME
-    struct timespec tp;
-    clock_gettime(CLOCK_REALTIME, &tp);
-    return (PaTime)(tp.tv_sec + tp.tv_nsec / 1.e9);
-#else
-    struct timeval tv;
-    gettimeofday( &tv, NULL );
-    return (PaTime) tv.tv_usec / 1000000. + tv.tv_sec;
-#endif
-}
-
-PaError PaUtil_InitializeThreading( PaUtilThreading *threading )
-{
-    (void) paUtilErr_;
-    return paNoError;
-}
-
-void PaUtil_TerminateThreading( PaUtilThreading *threading )
-{
-}
-
-PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data )
-{
-    pthread_create( &threading->callbackThread, NULL, threadRoutine, data );
-    return paNoError;
-}
-
-PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult )
-{
-    PaError result = paNoError;
-    void *pret;
-
-    if( exitResult )
-        *exitResult = paNoError;
-
-    /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */
-    if( !wait )
-        pthread_cancel( threading->callbackThread );   /* XXX: Safe to call this if the thread has exited on its own? */
-    pthread_join( threading->callbackThread, &pret );
-
-#ifdef PTHREAD_CANCELED
-    if( pret && PTHREAD_CANCELED != pret )
-#else
-    /* !wait means the thread may have been canceled */
-    if( pret && wait )
-#endif
-    {
-        if( exitResult )
-            *exitResult = *(PaError *) pret;
-        free( pret );
-    }
-
-    return result;
-}
-
-/*
-static void *CanaryFunc( void *userData )
-{
-    const unsigned intervalMsec = 1000;
-    PaUtilThreading *th = (PaUtilThreading *) userData;
-
-    while( 1 )
-    {
-        th->canaryTime = PaUtil_GetTime();
-
-        pthread_testcancel();
-        Pa_Sleep( intervalMsec );
-    }
-
-    pthread_exit( NULL );
-}
-*/
diff --git a/portaudio/pa_unix/pa_unix_util.h b/portaudio/pa_unix/pa_unix_util.h
deleted file mode 100644
index 01dda01e5..000000000
--- a/portaudio/pa_unix/pa_unix_util.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef PA_UNIX_UTIL_H
-#define PA_UNIX_UTIL_H
-
-#include "pa_cpuload.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-#define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) )
-#define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) )
-
-/* Utilize GCC branch prediction for error tests */
-#if defined __GNUC__ && __GNUC__ >= 3
-#define UNLIKELY(expr) __builtin_expect( (expr), 0 )
-#else
-#define UNLIKELY(expr) (expr)
-#endif
-
-#define STRINGIZE_HELPER(expr) #expr
-#define STRINGIZE(expr) STRINGIZE_HELPER(expr)
-
-#define PA_UNLESS(expr, code) \
-    do { \
-        if( UNLIKELY( (expr) == 0 ) ) \
-        { \
-            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
-            result = (code); \
-            goto error; \
-        } \
-    } while (0);
-
-static PaError paUtilErr_;          /* Used with PA_ENSURE */
-
-/* Check PaError */
-#define PA_ENSURE(expr) \
-    do { \
-        if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \
-        { \
-            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
-            result = paUtilErr_; \
-            goto error; \
-        } \
-    } while (0);
-
-typedef struct {
-    pthread_t callbackThread;
-} PaUtilThreading;
-
-PaError PaUtil_InitializeThreading( PaUtilThreading *threading );
-void PaUtil_TerminateThreading( PaUtilThreading *threading );
-PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data );
-PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult );
-
-/* State accessed by utility functions */
-
-/*
-void PaUnix_SetRealtimeScheduling( int rt );
-
-void PaUtil_InitializeThreading( PaUtilThreading *th, PaUtilCpuLoadMeasurer *clm );
-
-PaError PaUtil_CreateCallbackThread( PaUtilThreading *th, void *(*CallbackThreadFunc)( void * ), PaStream *s );
-
-PaError PaUtil_KillCallbackThread( PaUtilThreading *th, PaError *exitResult );
-
-void PaUtil_CallbackUpdate( PaUtilThreading *th );
-*/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif
diff --git a/portaudio/pa_unix_oss/CVS/Entries b/portaudio/pa_unix_oss/CVS/Entries
deleted file mode 100644
index d949129d7..000000000
--- a/portaudio/pa_unix_oss/CVS/Entries
+++ /dev/null
@@ -1,4 +0,0 @@
-/low_latency_tip.txt/1.1.1.1/Tue Jan 22 00:52:44 2002//Tv19-devel
-/pa_unix_oss.c/1.6.2.28/Mon Mar 20 18:22:06 2006//Tv19-devel
-/recplay.c/1.1.1.1/Tue Jan 22 00:52:44 2002//Tv19-devel
-D
diff --git a/portaudio/pa_unix_oss/CVS/Repository b/portaudio/pa_unix_oss/CVS/Repository
deleted file mode 100644
index 274189e5c..000000000
--- a/portaudio/pa_unix_oss/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_unix_oss
diff --git a/portaudio/pa_unix_oss/CVS/Root b/portaudio/pa_unix_oss/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_unix_oss/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_unix_oss/CVS/Tag b/portaudio/pa_unix_oss/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_unix_oss/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_unix_oss/low_latency_tip.txt b/portaudio/pa_unix_oss/low_latency_tip.txt
deleted file mode 100644
index 2d982b79baa6d943c1fae0c7122d190ebf46c6f4..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3111
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

diff --git a/portaudio/pa_unix_oss/pa_unix_oss.c b/portaudio/pa_unix_oss/pa_unix_oss.c
deleted file mode 100644
index 125fb8ce6..000000000
--- a/portaudio/pa_unix_oss/pa_unix_oss.c
+++ /dev/null
@@ -1,1924 +0,0 @@
-/*
- * $Id: pa_unix_oss.c,v 1.6.2.28 2006/03/20 18:22:06 aknudsen Exp $
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com
- * OSS implementation by:
- *   Douglas Repetto
- *   Phil Burk
- *   Dominic Mazzoni
- *   Arve Knudsen
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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 <string.h>
-#include <math.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <alloca.h>
-#include <malloc.h>
-#include <assert.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/poll.h>
-#include <limits.h>
-#include <semaphore.h>
-
-#ifdef __FreeBSD__
-# include <sys/soundcard.h>
-# define DEVICE_NAME_BASE            "/dev/dsp"
-#elif defined __linux__
-# include <linux/soundcard.h>
-# define DEVICE_NAME_BASE            "/dev/dsp"
-#else
-# include <machine/soundcard.h> /* JH20010905 */
-# define DEVICE_NAME_BASE            "/dev/audio"
-#endif
-
-#include "portaudio.h"
-#include "pa_util.h"
-#include "pa_allocation.h"
-#include "pa_hostapi.h"
-#include "pa_stream.h"
-#include "pa_cpuload.h"
-#include "pa_process.h"
-#include "../pa_unix/pa_unix_util.h"
-
-static int sysErr_;
-static pthread_t mainThread_;
-
-/* Check return value of system call, and map it to PaError */
-#define ENSURE_(expr, code) \
-    do { \
-        if( UNLIKELY( (sysErr_ = (expr)) < 0 ) ) \
-        { \
-            /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \
-            if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
-            { \
-                PaUtil_SetLastHostErrorInfo( paALSA, sysErr_, strerror( errno ) ); \
-            } \
-            \
-            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
-            result = (code); \
-            goto error; \
-        } \
-    } while( 0 );
-
-#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
-
-/* PaOSSHostApiRepresentation - host api datastructure specific to this implementation */
-
-typedef struct
-{
-    PaUtilHostApiRepresentation inheritedHostApiRep;
-    PaUtilStreamInterface callbackStreamInterface;
-    PaUtilStreamInterface blockingStreamInterface;
-
-    PaUtilAllocationGroup *allocations;
-
-    PaHostApiIndex hostApiIndex;
-}
-PaOSSHostApiRepresentation;
-
-/** Per-direction structure for PaOssStream.
- *
- * Aspect StreamChannels: In case the user requests to open the same device for both capture and playback,
- * but with different number of channels we will have to adapt between the number of user and host
- * channels for at least one direction, since the configuration space is the same for both directions
- * of an OSS device.
- */
-typedef struct
-{
-    int fd;
-    const char *devName;
-    int userChannelCount, hostChannelCount;
-    int userInterleaved;
-    void *buffer;
-    PaSampleFormat userFormat, hostFormat;
-    double latency;
-    unsigned long hostFrames, numBufs;
-    void **userBuffers; /* For non-interleaved blocking */
-} PaOssStreamComponent;
-
-/** Implementation specific representation of a PaStream.
- *
- */
-typedef struct PaOssStream
-{
-    PaUtilStreamRepresentation streamRepresentation;
-    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
-    PaUtilBufferProcessor bufferProcessor;
-
-    PaUtilThreading threading;
-
-    int sharedDevice;
-    unsigned long framesPerHostBuffer;
-    int triggered;  /* Have the devices been triggered yet (first start) */
-
-    int isActive;
-    int isStopped;
-
-    int lastPosPtr;
-    double lastStreamBytes;
-
-    int framesProcessed;
-
-    double sampleRate;
-
-    int callbackMode;
-    int callbackStop, callbackAbort;
-
-    PaOssStreamComponent *capture, *playback;
-    unsigned long pollTimeout;
-    sem_t semaphore;
-}
-PaOssStream;
-
-typedef enum {
-    StreamMode_In,
-    StreamMode_Out
-} StreamMode;
-
-/* prototypes for functions declared in this file */
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate );
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData );
-static PaError CloseStream( PaStream* stream );
-static PaError StartStream( PaStream *stream );
-static PaError StopStream( PaStream *stream );
-static PaError AbortStream( PaStream *stream );
-static PaError IsStreamStopped( PaStream *s );
-static PaError IsStreamActive( PaStream *stream );
-static PaTime GetStreamTime( PaStream *stream );
-static double GetStreamCpuLoad( PaStream* stream );
-static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
-static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
-static signed long GetStreamReadAvailable( PaStream* stream );
-static signed long GetStreamWriteAvailable( PaStream* stream );
-static PaError BuildDeviceList( PaOSSHostApiRepresentation *hostApi );
-
-
-/** Initialize the OSS API implementation.
- *
- * This function will initialize host API datastructures and query host devices for information.
- *
- * Aspect DeviceCapabilities: Enumeration of host API devices is initiated from here
- *
- * Aspect FreeResources: If an error is encountered under way we have to free each resource allocated in this function,
- * this happens with the usual "error" label.
- */
-PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
-{
-    PaError result = paNoError;
-    PaOSSHostApiRepresentation *ossHostApi = NULL;
-
-    PA_UNLESS( ossHostApi = (PaOSSHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaOSSHostApiRepresentation) ),
-            paInsufficientMemory );
-    PA_UNLESS( ossHostApi->allocations = PaUtil_CreateAllocationGroup(), paInsufficientMemory );
-    ossHostApi->hostApiIndex = hostApiIndex;
-
-    /* Initialize host API structure */
-    *hostApi = &ossHostApi->inheritedHostApiRep;
-    (*hostApi)->info.structVersion = 1;
-    (*hostApi)->info.type = paOSS;
-    (*hostApi)->info.name = "OSS";
-    (*hostApi)->Terminate = Terminate;
-    (*hostApi)->OpenStream = OpenStream;
-    (*hostApi)->IsFormatSupported = IsFormatSupported;
-
-    PA_ENSURE( BuildDeviceList( ossHostApi ) );
-
-    PaUtil_InitializeStreamInterface( &ossHostApi->callbackStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, GetStreamCpuLoad,
-                                      PaUtil_DummyRead, PaUtil_DummyWrite,
-                                      PaUtil_DummyGetReadAvailable,
-                                      PaUtil_DummyGetWriteAvailable );
-
-    PaUtil_InitializeStreamInterface( &ossHostApi->blockingStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
-                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
-
-    mainThread_ = pthread_self();
-
-    return result;
-
-error:
-    if( ossHostApi )
-    {
-        if( ossHostApi->allocations )
-        {
-            PaUtil_FreeAllAllocations( ossHostApi->allocations );
-            PaUtil_DestroyAllocationGroup( ossHostApi->allocations );
-        }
-                
-        PaUtil_FreeMemory( ossHostApi );
-    }
-    return result;
-}
-
-PaError PaUtil_InitializeDeviceInfo( PaDeviceInfo *deviceInfo, const char *name, PaHostApiIndex hostApiIndex, int maxInputChannels,
-        int maxOutputChannels, PaTime defaultLowInputLatency, PaTime defaultLowOutputLatency, PaTime defaultHighInputLatency,
-        PaTime defaultHighOutputLatency, double defaultSampleRate, PaUtilAllocationGroup *allocations  )
-{
-    PaError result = paNoError;
-    
-    deviceInfo->structVersion = 2;
-    if( allocations )
-    {
-        size_t len = strlen( name ) + 1;
-        PA_UNLESS( deviceInfo->name = PaUtil_GroupAllocateMemory( allocations, len ), paInsufficientMemory );
-        strncpy( (char *)deviceInfo->name, name, len );
-    }
-    else
-        deviceInfo->name = name;
-
-    deviceInfo->hostApi = hostApiIndex;
-    deviceInfo->maxInputChannels = maxInputChannels;
-    deviceInfo->maxOutputChannels = maxOutputChannels;
-    deviceInfo->defaultLowInputLatency = defaultLowInputLatency;
-    deviceInfo->defaultLowOutputLatency = defaultLowOutputLatency;
-    deviceInfo->defaultHighInputLatency = defaultHighInputLatency;
-    deviceInfo->defaultHighOutputLatency = defaultHighOutputLatency;
-    deviceInfo->defaultSampleRate = defaultSampleRate;
-
-error:
-    return result;
-}
-
-static PaError QueryDirection( const char *deviceName, StreamMode mode, double *defaultSampleRate, int *maxChannelCount,
-        double *defaultLowLatency, double *defaultHighLatency )
-{
-    PaError result = paNoError;
-    int numChannels, maxNumChannels;
-    int busy = 0;
-    int devHandle = -1;
-    int sr;
-    *maxChannelCount = 0;  /* Default value in case this fails */
-
-    if ( (devHandle = open( deviceName, (mode == StreamMode_In ? O_RDONLY : O_WRONLY) | O_NONBLOCK ))  < 0 )
-    {
-        if( errno == EBUSY || errno == EAGAIN )
-        {
-            PA_DEBUG(( "%s: Device %s busy\n", __FUNCTION__, deviceName ));
-        }
-        else
-        {
-            PA_DEBUG(( "%s: Can't access device: %s\n", __FUNCTION__, strerror( errno ) ));
-        }
-
-        return paDeviceUnavailable;
-    }
-
-    /* Negotiate for the maximum number of channels for this device. PLB20010927
-     * Consider up to 16 as the upper number of channels.
-     * Variable maxNumChannels should contain the actual upper limit after the call.
-     * Thanks to John Lazzaro and Heiko Purnhagen for suggestions.
-     */
-    maxNumChannels = 0;
-    for( numChannels = 1; numChannels <= 16; numChannels++ )
-    {
-        int temp = numChannels;
-        if( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ) < 0 )
-        {
-            busy = EAGAIN == errno || EBUSY == errno;
-            /* ioctl() failed so bail out if we already have stereo */
-            if( maxNumChannels >= 2 )
-                break;
-        }
-        else
-        {
-            /* ioctl() worked but bail out if it does not support numChannels.
-             * We don't want to leave gaps in the numChannels supported.
-             */
-            if( (numChannels > 2) && (temp != numChannels) )
-                break;
-            if( temp > maxNumChannels )
-                maxNumChannels = temp; /* Save maximum. */
-        }
-    }
-    /* A: We're able to open a device for capture if it's busy playing back and vice versa,
-     * but we can't configure anything */
-    if( 0 == maxNumChannels && busy )
-    {
-        result = paDeviceUnavailable;
-        goto error;
-    }
-
-    /* The above negotiation may fail for an old driver so try this older technique. */
-    if( maxNumChannels < 1 )
-    {
-        int stereo = 1;
-        if( ioctl( devHandle, SNDCTL_DSP_STEREO, &stereo ) < 0 )
-        {
-            maxNumChannels = 1;
-        }
-        else
-        {
-            maxNumChannels = (stereo) ? 2 : 1;
-        }
-        PA_DEBUG(( "%s: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", __FUNCTION__, maxNumChannels ))
-    }
-
-    /* During channel negotiation, the last ioctl() may have failed. This can
-     * also cause sample rate negotiation to fail. Hence the following, to return
-     * to a supported number of channels. SG20011005 */
-    {
-        /* use most reasonable default value */
-        int temp = PA_MIN( maxNumChannels, 2 );
-        ENSURE_( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ), paUnanticipatedHostError );
-    }
-
-    /* Get supported sample rate closest to 44100 Hz */
-    if( *defaultSampleRate < 0 )
-    {
-        sr = 44100;
-        if( ioctl( devHandle, SNDCTL_DSP_SPEED, &sr ) < 0 )
-        {
-            result = paUnanticipatedHostError;
-            goto error;
-        }
-
-        *defaultSampleRate = sr;
-    }
-
-    *maxChannelCount = maxNumChannels;
-    /* TODO */
-    *defaultLowLatency = 512. / *defaultSampleRate;
-    *defaultHighLatency = 2048. / *defaultSampleRate;
-
-error:
-    if( devHandle >= 0 )
-        close( devHandle );
-
-    return result;
-}
-
-/** Query OSS device.
- *
- * This is where PaDeviceInfo objects are constructed and filled in with relevant information.
- *
- * Aspect DeviceCapabilities: The inferred device capabilities are recorded in a PaDeviceInfo object that is constructed
- * in place.
- */
-static PaError QueryDevice( char *deviceName, PaOSSHostApiRepresentation *ossApi, PaDeviceInfo **deviceInfo )
-{
-    PaError result = paNoError;
-    double sampleRate = -1.;
-    int maxInputChannels, maxOutputChannels;
-    PaTime defaultLowInputLatency, defaultLowOutputLatency, defaultHighInputLatency, defaultHighOutputLatency;
-    PaError tmpRes = paNoError;
-    int busy = 0;
-    *deviceInfo = NULL;
-
-    /* douglas:
-       we have to do this querying in a slightly different order. apparently
-       some sound cards will give you different info based on their settins. 
-       e.g. a card might give you stereo at 22kHz but only mono at 44kHz.
-       the correct order for OSS is: format, channels, sample rate
-    */
-
-    /* Aspect StreamChannels: The number of channels supported for a device may depend on the mode it is
-     * opened in, it may have more channels available for capture than playback and vice versa. Therefore
-     * we will open the device in both read- and write-only mode to determine the supported number.
-     */
-    if( (tmpRes = QueryDirection( deviceName, StreamMode_In, &sampleRate, &maxInputChannels, &defaultLowInputLatency,
-                &defaultHighInputLatency )) != paNoError )
-    {
-        if( tmpRes != paDeviceUnavailable )
-        {
-            PA_DEBUG(( "%s: Querying device %s for capture failed!\n", __FUNCTION__, deviceName ));
-            /* PA_ENSURE( tmpRes ); */
-        }
-        ++busy;
-    }
-    if( (tmpRes = QueryDirection( deviceName, StreamMode_Out, &sampleRate, &maxOutputChannels, &defaultLowOutputLatency,
-                &defaultHighOutputLatency )) != paNoError )
-    {
-        if( tmpRes != paDeviceUnavailable )
-        {
-            PA_DEBUG(( "%s: Querying device %s for playback failed!\n", __FUNCTION__, deviceName ));
-            /* PA_ENSURE( tmpRes ); */
-        }
-        ++busy;
-    }
-    assert( 0 <= busy && busy <= 2 );
-    if( 2 == busy )     /* Both directions are unavailable to us */
-    {
-        result = paDeviceUnavailable;
-        goto error;
-    }
-
-    PA_UNLESS( *deviceInfo = PaUtil_GroupAllocateMemory( ossApi->allocations, sizeof (PaDeviceInfo) ), paInsufficientMemory );
-    PA_ENSURE( PaUtil_InitializeDeviceInfo( *deviceInfo, deviceName, ossApi->hostApiIndex, maxInputChannels, maxOutputChannels,
-                defaultLowInputLatency, defaultLowOutputLatency, defaultHighInputLatency, defaultHighOutputLatency, sampleRate,
-                ossApi->allocations ) );
-
-error:
-    return result;
-}
-
-/** Query host devices.
- *
- * Loop over host devices and query their capabilitiesu
- *
- * Aspect DeviceCapabilities: This function calls QueryDevice on each device entry and receives a filled in PaDeviceInfo object
- * per device, these are placed in the host api representation's deviceInfos array.
- */
-static PaError BuildDeviceList( PaOSSHostApiRepresentation *ossApi )
-{
-    PaError result = paNoError;
-    PaUtilHostApiRepresentation *commonApi = &ossApi->inheritedHostApiRep;
-    int i;
-    int numDevices = 0, maxDeviceInfos = 1;
-    PaDeviceInfo **deviceInfos = NULL;
-
-    /* These two will be set to the first working input and output device, respectively */
-    commonApi->info.defaultInputDevice = paNoDevice;
-    commonApi->info.defaultOutputDevice = paNoDevice;
-
-    /* Find devices by calling QueryDevice on each
-     * potential device names.  When we find a valid one,
-     * add it to a linked list.
-     * A: Can there only be 10 devices? */
-
-    for( i = 0; i < 10; i++ )
-    {
-       char deviceName[32];
-       PaDeviceInfo *deviceInfo;
-       int testResult;
-       struct stat stbuf;
-
-       if( i == 0 )
-          snprintf(deviceName, sizeof (deviceName), "%s", DEVICE_NAME_BASE);
-       else
-          snprintf(deviceName, sizeof (deviceName), "%s%d", DEVICE_NAME_BASE, i);
-
-       /* PA_DEBUG(("PaOSS BuildDeviceList: trying device %s\n", deviceName )); */
-       if( stat( deviceName, &stbuf ) < 0 )
-       {
-           if( ENOENT != errno )
-               PA_DEBUG(( "%s: Error stat'ing %s: %s\n", __FUNCTION__, deviceName, strerror( errno ) ));
-           continue;
-       }
-       if( (testResult = QueryDevice( deviceName, ossApi, &deviceInfo )) != paNoError )
-       {
-           if( testResult != paDeviceUnavailable )
-               PA_ENSURE( testResult );
-
-           continue;
-       }
-
-       ++numDevices;
-       if( !deviceInfos || numDevices > maxDeviceInfos )
-       {
-           maxDeviceInfos *= 2;
-           PA_UNLESS( deviceInfos = (PaDeviceInfo **) realloc( deviceInfos, maxDeviceInfos * sizeof (PaDeviceInfo *) ),
-                   paInsufficientMemory );
-       }
-       {
-           int devIdx = numDevices - 1;
-           deviceInfos[devIdx] = deviceInfo;
-
-           if( commonApi->info.defaultInputDevice == paNoDevice && deviceInfo->maxInputChannels > 0 )
-               commonApi->info.defaultInputDevice = devIdx;
-           if( commonApi->info.defaultOutputDevice == paNoDevice && deviceInfo->maxOutputChannels > 0 )
-               commonApi->info.defaultOutputDevice = devIdx;
-       }
-    }
-
-    /* Make an array of PaDeviceInfo pointers out of the linked list */
-
-    PA_DEBUG(("PaOSS %s: Total number of devices found: %d\n", __FUNCTION__, numDevices));
-
-    commonApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
-        ossApi->allocations, sizeof(PaDeviceInfo*) * numDevices );
-    memcpy( commonApi->deviceInfos, deviceInfos, numDevices * sizeof (PaDeviceInfo *) );
-
-    commonApi->info.deviceCount = numDevices;
-
-error:
-    free( deviceInfos );
-
-    return result;
-}
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
-{
-    PaOSSHostApiRepresentation *ossHostApi = (PaOSSHostApiRepresentation*)hostApi;
-
-    if( ossHostApi->allocations )
-    {
-        PaUtil_FreeAllAllocations( ossHostApi->allocations );
-        PaUtil_DestroyAllocationGroup( ossHostApi->allocations );
-    }
-
-    PaUtil_FreeMemory( ossHostApi );
-}
-
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate )
-{
-    PaError result = paNoError;
-    PaDeviceIndex device;
-    PaDeviceInfo *deviceInfo;
-    char *deviceName;
-    int inputChannelCount, outputChannelCount;
-    int tempDevHandle = -1;
-    int flags;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that input device can support inputChannelCount */
-        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
-            return paInvalidChannelCount;
-
-        /* validate inputStreamInfo */
-        if( inputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        inputChannelCount = 0;
-    }
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-        
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that output device can support inputChannelCount */
-        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
-            return paInvalidChannelCount;
-
-        /* validate outputStreamInfo */
-        if( outputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        outputChannelCount = 0;
-    }
-
-    if (inputChannelCount == 0 && outputChannelCount == 0)
-        return paInvalidChannelCount;
-
-    /* if full duplex, make sure that they're the same device */
-
-    if (inputChannelCount > 0 && outputChannelCount > 0 &&
-        inputParameters->device != outputParameters->device)
-        return paInvalidDevice;
-
-    /* if full duplex, also make sure that they're the same number of channels */
-
-    if (inputChannelCount > 0 && outputChannelCount > 0 &&
-        inputChannelCount != outputChannelCount)
-       return paInvalidChannelCount;
-
-    /* open the device so we can do more tests */
-    
-    if( inputChannelCount > 0 )
-    {
-        result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, inputParameters->device, hostApi);
-        if (result != paNoError)
-            return result;
-    }
-    else
-    {
-        result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, outputParameters->device, hostApi);
-        if (result != paNoError)
-            return result;
-    }
-
-    deviceInfo = hostApi->deviceInfos[device];
-    deviceName = (char *)deviceInfo->name;
-    
-    flags = O_NONBLOCK;
-    if (inputChannelCount > 0 && outputChannelCount > 0)
-       flags |= O_RDWR;
-    else if (inputChannelCount > 0)
-       flags |= O_RDONLY;
-    else
-       flags |= O_WRONLY;
-
-    ENSURE_( tempDevHandle = open( deviceInfo->name, flags ), paDeviceUnavailable );
-
-    /* PaOssStream_Configure will do the rest of the checking for us */
-    /* PA_ENSURE( PaOssStream_Configure( tempDevHandle, deviceName, outputChannelCount, &sampleRate ) ); */
-
-    /* everything succeeded! */
-
- error:
-    if( tempDevHandle >= 0 )
-        close( tempDevHandle );         
-
-    return result;
-}
-
-/** Validate stream parameters.
- *
- * Aspect StreamChannels: We verify that the number of channels is within the allowed range for the device
- */
-static PaError ValidateParameters( const PaStreamParameters *parameters, const PaDeviceInfo *deviceInfo, StreamMode mode )
-{
-    int maxChans;
-
-    assert( parameters );
-
-    if( parameters->device == paUseHostApiSpecificDeviceSpecification )
-    {
-        return paInvalidDevice;
-    }
-
-    maxChans = (mode == StreamMode_In ? deviceInfo->maxInputChannels :
-        deviceInfo->maxOutputChannels);
-    if( parameters->channelCount > maxChans )
-    {
-        return paInvalidChannelCount;
-    }
-
-    return paNoError;
-}
-
-static PaError PaOssStreamComponent_Initialize( PaOssStreamComponent *component, const PaStreamParameters *parameters,
-        int callbackMode, int fd, const char *deviceName )
-{
-    PaError result = paNoError;
-    assert( component );
-
-    memset( component, 0, sizeof (PaOssStreamComponent) );
-
-    component->fd = fd;
-    component->devName = deviceName;
-    component->userChannelCount = parameters->channelCount;
-    component->userFormat = parameters->sampleFormat;
-    component->latency = parameters->suggestedLatency;
-    component->userInterleaved = !(parameters->sampleFormat & paNonInterleaved);
-
-    if( !callbackMode && !component->userInterleaved )
-    {
-        /* Pre-allocate non-interleaved user provided buffers */
-        PA_UNLESS( component->userBuffers = PaUtil_AllocateMemory( sizeof (void *) * component->userChannelCount ),
-                paInsufficientMemory );
-    }
-
-error:
-    return result;
-}
-
-static void PaOssStreamComponent_Terminate( PaOssStreamComponent *component )
-{
-    assert( component );
-
-    if( component->fd >= 0 )
-        close( component->fd );
-    if( component->buffer )
-        PaUtil_FreeMemory( component->buffer );
-
-    if( component->userBuffers )
-        PaUtil_FreeMemory( component->userBuffers );
-
-    PaUtil_FreeMemory( component );
-}
-
-static PaError ModifyBlocking( int fd, int blocking )
-{
-    PaError result = paNoError;
-    int fflags;
-
-    ENSURE_( fflags = fcntl( fd, F_GETFL ), paUnanticipatedHostError );
-
-    if( blocking )
-        fflags &= ~O_NONBLOCK;
-    else
-        fflags |= O_NONBLOCK;
-
-    ENSURE_( fcntl( fd, F_SETFL, fflags ), paUnanticipatedHostError );
-
-error:
-    return result;
-}
-
-static PaError OpenDevices( const char *idevName, const char *odevName, int *idev, int *odev )
-{
-    PaError result = paNoError;
-    int flags = O_NONBLOCK, duplex = 0;
-    int enableBits = 0;
-    *idev = *odev = -1;
-
-    if( idevName && odevName )
-    {
-        duplex = 1;
-        flags |= O_RDWR;
-    }
-    else if( idevName )
-        flags |= O_RDONLY;
-    else
-        flags |= O_WRONLY;
-
-    /* open first in nonblocking mode, in case it's busy...
-     * A: then unset the non-blocking attribute */
-    assert( flags & O_NONBLOCK );
-    if( idevName )
-    {
-        ENSURE_( *idev = open( idevName, flags ), paDeviceUnavailable );
-        PA_ENSURE( ModifyBlocking( *idev, 1 ) ); /* Blocking */
-
-        /* Initially disable */
-        enableBits = ~PCM_ENABLE_INPUT;
-        ENSURE_( ioctl( *idev, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError );
-    }
-    if( odevName )
-    {
-        if( !idevName )
-        {
-            ENSURE_( *odev = open( odevName, flags ), paDeviceUnavailable );
-            PA_ENSURE( ModifyBlocking( *odev, 1 ) ); /* Blocking */
-
-            /* Initially disable */
-            enableBits = ~PCM_ENABLE_OUTPUT;
-            ENSURE_( ioctl( *odev, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError );
-        }
-        else
-        {
-            ENSURE_( *odev = dup( *idev ), paUnanticipatedHostError );
-        }
-    }
-
-error:
-    return result;
-}
-
-static PaError PaOssStream_Initialize( PaOssStream *stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters,
-        PaStreamCallback callback, void *userData, PaStreamFlags streamFlags,
-        PaOSSHostApiRepresentation *ossApi )
-{
-    PaError result = paNoError;
-    int idev, odev;
-    PaUtilHostApiRepresentation *hostApi = &ossApi->inheritedHostApiRep;
-    const char *idevName = NULL, *odevName = NULL;
-
-    assert( stream );
-
-    memset( stream, 0, sizeof (PaOssStream) );
-    stream->isStopped = 1;
-
-    PA_ENSURE( PaUtil_InitializeThreading( &stream->threading ) );
-
-    if( inputParameters && outputParameters )
-    {
-        if( inputParameters->device == outputParameters->device )
-            stream->sharedDevice = 1;
-    }
-
-    if( inputParameters )
-        idevName = hostApi->deviceInfos[inputParameters->device]->name;
-    if( outputParameters )
-        odevName = hostApi->deviceInfos[outputParameters->device]->name;
-    PA_ENSURE( OpenDevices( idevName, odevName, &idev, &odev ) );
-    if( inputParameters )
-    {
-        PA_UNLESS( stream->capture = PaUtil_AllocateMemory( sizeof (PaOssStreamComponent) ), paInsufficientMemory );
-        PA_ENSURE( PaOssStreamComponent_Initialize( stream->capture, inputParameters, callback != NULL, idev, idevName ) );
-    }
-    if( outputParameters )
-    {
-        PA_UNLESS( stream->playback = PaUtil_AllocateMemory( sizeof (PaOssStreamComponent) ), paInsufficientMemory );
-        PA_ENSURE( PaOssStreamComponent_Initialize( stream->playback, outputParameters, callback != NULL, odev, odevName ) );
-    }
-
-    if( callback != NULL )
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &ossApi->callbackStreamInterface, callback, userData );
-        stream->callbackMode = 1;
-    }
-    else
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &ossApi->blockingStreamInterface, callback, userData );
-    }    
-
-    ENSURE_( sem_init( &stream->semaphore, 0, 0 ), paInternalError );
-
-error:
-    return result;
-}
-
-static void PaOssStream_Terminate( PaOssStream *stream )
-{
-    assert( stream );
-
-    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
-    PaUtil_TerminateThreading( &stream->threading );
-
-    if( stream->capture )
-        PaOssStreamComponent_Terminate( stream->capture );
-    if( stream->playback )
-        PaOssStreamComponent_Terminate( stream->playback );
-
-    sem_destroy( &stream->semaphore );
-
-    PaUtil_FreeMemory( stream );
-}
-
-/** Translate from PA format to OSS native.
- *
- */
-static PaError Pa2OssFormat( PaSampleFormat paFormat, int *ossFormat )
-{
-    switch( paFormat )
-    {
-        case paUInt8:
-            *ossFormat = AFMT_U8;
-            break;
-        case paInt8:
-            *ossFormat = AFMT_S8;
-            break;
-        case paInt16:
-            *ossFormat = AFMT_S16_NE;
-            break;
-        default:
-            return paInternalError;     /* This shouldn't happen */
-    }
-
-    return paNoError;
-}
-
-/** Return the PA-compatible formats that this device can support.
- *
- */
-static PaError GetAvailableFormats( PaOssStreamComponent *component, PaSampleFormat *availableFormats )
-{
-    PaError result = paNoError;
-    int mask = 0;
-    PaSampleFormat frmts = 0;
-
-    ENSURE_( ioctl( component->fd, SNDCTL_DSP_GETFMTS, &mask ), paUnanticipatedHostError );
-    if( mask & AFMT_U8 )
-        frmts |= paUInt8;
-    if( mask & AFMT_S8 )
-        frmts |= paInt8;
-    if( mask & AFMT_S16_NE )
-        frmts |= paInt16;
-    else
-        result = paSampleFormatNotSupported;
-    
-    *availableFormats = frmts;
-
-error:
-    return result;
-}
-
-static unsigned int PaOssStreamComponent_FrameSize( PaOssStreamComponent *component )
-{
-    return Pa_GetSampleSize( component->hostFormat ) * component->hostChannelCount;
-}
-
-/** Buffer size in bytes.
- *
- */
-static unsigned long PaOssStreamComponent_BufferSize( PaOssStreamComponent *component )
-{
-    return PaOssStreamComponent_FrameSize( component ) * component->hostFrames * component->numBufs;
-}
-
-static int CalcHigherLogTwo( int n )
-{
-    int log2 = 0;
-    while( (1<<log2) < n ) log2++;
-    return log2;
-}
-
-static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component, double sampleRate, unsigned long framesPerBuffer,
-        StreamMode streamMode, PaOssStreamComponent *master )
-{
-    PaError result = paNoError;
-    int temp, nativeFormat;
-    int sr = (int)sampleRate;
-    PaSampleFormat availableFormats, hostFormat;
-    int chans = component->userChannelCount;
-    int frgmt;
-    int numBufs;
-    int bytesPerBuf;
-    double bufSz;
-    unsigned long fragSz;
-    audio_buf_info bufInfo;
-
-    /* We may have a situation where only one component (the master) is configured, if both point to the same device.
-     * In that case, the second component will copy settings from the other */
-    if( !master )
-    {
-        /* Aspect BufferSettings: If framesPerBuffer is unspecified we have to infer a suitable fragment size.
-         * The hardware need not respect the requested fragment size, so we may have to adapt.
-         */
-        if( framesPerBuffer == paFramesPerBufferUnspecified )
-        { 
-            bufSz = component->latency * sampleRate;
-            fragSz = bufSz / 4;
-        }
-        else
-        {
-            fragSz = framesPerBuffer;
-            bufSz = component->latency * sampleRate + fragSz; /* Latency + 1 buffer */
-        }
-
-        PA_ENSURE( GetAvailableFormats( component, &availableFormats ) );
-        hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, component->userFormat );
-
-        /* OSS demands at least 2 buffers, and 16 bytes per buffer */
-        numBufs = PA_MAX( bufSz / fragSz, 2 );
-        bytesPerBuf = PA_MAX( fragSz * Pa_GetSampleSize( hostFormat ) * chans, 16 );
-
-        /* The fragment parameters are encoded like this:
-         * Most significant byte: number of fragments
-         * Least significant byte: exponent of fragment size (i.e., for 256, 8)
-         */
-        frgmt = (numBufs << 16) + (CalcHigherLogTwo( bytesPerBuf ) & 0xffff);
-        ENSURE_( ioctl( component->fd, SNDCTL_DSP_SETFRAGMENT, &frgmt ), paUnanticipatedHostError );
-
-        /* A: according to the OSS programmer's guide parameters should be set in this order:
-         * format, channels, rate */
-
-        /* This format should be deemed good before we get this far */
-        PA_ENSURE( Pa2OssFormat( hostFormat, &temp ) );
-        nativeFormat = temp;
-        ENSURE_( ioctl( component->fd, SNDCTL_DSP_SETFMT, &temp ), paUnanticipatedHostError );
-        PA_UNLESS( temp == nativeFormat, paInternalError );
-
-        /* try to set the number of channels */
-        ENSURE_( ioctl( component->fd, SNDCTL_DSP_CHANNELS, &chans ), paSampleFormatNotSupported );   /* XXX: Should be paInvalidChannelCount? */
-        /* It's possible that the minimum number of host channels is greater than what the user requested */
-        PA_UNLESS( chans >= component->userChannelCount, paInvalidChannelCount );
-
-        /* try to set the sample rate */
-        ENSURE_( ioctl( component->fd, SNDCTL_DSP_SPEED, &sr ), paInvalidSampleRate );
-
-        /* reject if there's no sample rate within 1% of the one requested */
-        if( (fabs( sampleRate - sr ) / sampleRate) > 0.01 )
-        {
-            PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr ));                 
-            PA_ENSURE( paInvalidSampleRate );
-        }
-
-        ENSURE_( ioctl( component->fd, streamMode == StreamMode_In ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &bufInfo ),
-                paUnanticipatedHostError );
-        component->numBufs = bufInfo.fragstotal;
-
-        /* This needs to be the last ioctl call before the first read/write, according to the OSS programmer's guide */
-        ENSURE_( ioctl( component->fd, SNDCTL_DSP_GETBLKSIZE, &bytesPerBuf ), paUnanticipatedHostError );
-
-        component->hostFrames = bytesPerBuf / Pa_GetSampleSize( hostFormat ) / chans;
-        component->hostChannelCount = chans;
-        component->hostFormat = hostFormat;
-    }
-    else
-    {
-        component->hostFormat = master->hostFormat;
-        component->hostFrames = master->hostFrames;
-        component->hostChannelCount = master->hostChannelCount;
-        component->numBufs = master->numBufs;
-    }
-
-    PA_UNLESS( component->buffer = PaUtil_AllocateMemory( PaOssStreamComponent_BufferSize( component ) ),
-            paInsufficientMemory );
-
-error:
-    return result;
-}
-
-static PaError PaOssStreamComponent_Read( PaOssStreamComponent *component, unsigned long *frames )
-{
-    PaError result = paNoError;
-    size_t len = *frames * PaOssStreamComponent_FrameSize( component );
-    ssize_t bytesRead;
-
-    ENSURE_( bytesRead = read( component->fd, component->buffer, len ), paUnanticipatedHostError );
-    *frames = bytesRead / PaOssStreamComponent_FrameSize( component );
-    /* TODO: Handle condition where number of frames read doesn't equal number of frames requested */
-
-error:
-    return result;
-}
-
-static PaError PaOssStreamComponent_Write( PaOssStreamComponent *component, unsigned long *frames )
-{
-    PaError result = paNoError;
-    size_t len = *frames * PaOssStreamComponent_FrameSize( component );
-    ssize_t bytesWritten;
-
-    ENSURE_( bytesWritten = write( component->fd, component->buffer, len ), paUnanticipatedHostError );
-    *frames = bytesWritten / PaOssStreamComponent_FrameSize( component );
-    /* TODO: Handle condition where number of frames written doesn't equal number of frames requested */
-
-error:
-    return result;
-}
-
-/** Configure the stream according to input/output parameters.
- *
- * Aspect StreamChannels: The minimum number of channels supported by the device may exceed that requested by
- * the user, if so we'll record the actual number of host channels and adapt later.
- */
-static PaError PaOssStream_Configure( PaOssStream *stream, double sampleRate, unsigned long framesPerBuffer,
-        double *inputLatency, double *outputLatency )
-{
-    PaError result = paNoError;
-    int duplex = stream->capture && stream->playback;
-    unsigned long framesPerHostBuffer = 0;
-
-    /* We should request full duplex first thing after opening the device */
-    if( duplex && stream->sharedDevice )
-        ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETDUPLEX, 0 ), paUnanticipatedHostError );
-
-    if( stream->capture )
-    {
-        PaOssStreamComponent *component = stream->capture;
-        PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_In, NULL );
-
-        assert( component->hostChannelCount > 0 );
-        assert( component->hostFrames > 0 );
-
-        *inputLatency = component->hostFrames * (component->numBufs - 1) / sampleRate;
-    }
-    if( stream->playback )
-    {
-        PaOssStreamComponent *component = stream->playback, *master = stream->sharedDevice ? stream->capture : NULL;
-        PA_ENSURE( PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_Out,
-                    master ) );
-
-        assert( component->hostChannelCount > 0 );
-        assert( component->hostFrames > 0 );
-
-        *outputLatency = component->hostFrames * (component->numBufs - 1) / sampleRate;
-    }
-
-    if( duplex )
-        framesPerHostBuffer = PA_MIN( stream->capture->hostFrames, stream->playback->hostFrames );
-    else if( stream->capture )
-        framesPerHostBuffer = stream->capture->hostFrames;
-    else if( stream->playback )
-        framesPerHostBuffer = stream->playback->hostFrames;
-
-    stream->framesPerHostBuffer = framesPerHostBuffer;
-    stream->pollTimeout = (int) ceil( 1e6 * framesPerHostBuffer / sampleRate );    /* Period in usecs, rounded up */
-
-    stream->sampleRate = stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
-
-error:
-    return result;
-}
-
-/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */
-
-/** Open a PA OSS stream.
- *
- * Aspect StreamChannels: The number of channels is specified per direction (in/out), and can differ between the
- * two. However, OSS doesn't support separate configuration spaces for capture and playback so if both
- * directions are the same device we will demand the same number of channels. The number of channels can range
- * from 1 to the maximum supported by the device.
- *
- * Aspect BufferSettings: If framesPerBuffer != paFramesPerBufferUnspecified the number of frames per callback
- * must reflect this, in addition the host latency per device should approximate the corresponding
- * suggestedLatency. Based on these constraints we need to determine a number of frames per host buffer that
- * both capture and playback can agree on (they can be different devices), the buffer processor can adapt
- * between host and user buffer size, but the ratio should preferably be integral.
- */
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData )
-{
-    PaError result = paNoError;
-    PaOSSHostApiRepresentation *ossHostApi = (PaOSSHostApiRepresentation*)hostApi;
-    PaOssStream *stream = NULL;
-    int inputChannelCount = 0, outputChannelCount = 0;
-    PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0, inputHostFormat = 0, outputHostFormat = 0;
-    const PaDeviceInfo *inputDeviceInfo = 0, *outputDeviceInfo = 0;
-    int bpInitialized = 0;
-    double inLatency, outLatency;
-
-    /* validate platform specific flags */
-    if( (streamFlags & paPlatformSpecificFlags) != 0 )
-        return paInvalidFlag; /* unexpected platform specific flag */
-
-    if( inputParameters )
-    {
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-        inputDeviceInfo = hostApi->deviceInfos[inputParameters->device];
-        PA_ENSURE( ValidateParameters( inputParameters, inputDeviceInfo, StreamMode_In ) );
-
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-    }
-    if( outputParameters )
-    {
-        outputDeviceInfo = hostApi->deviceInfos[outputParameters->device];
-        PA_ENSURE( ValidateParameters( outputParameters, outputDeviceInfo, StreamMode_Out ) );
-
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-    }
-
-    /* Aspect StreamChannels: We currently demand that number of input and output channels are the same, if the same
-     * device is opened for both directions
-     */
-    if( inputChannelCount > 0 && outputChannelCount > 0 )
-    {
-        if( inputParameters->device == outputParameters->device )
-        {
-            if( inputParameters->channelCount != outputParameters->channelCount )
-                return paInvalidChannelCount;
-        }
-    }
-    
-    /* allocate and do basic initialization of the stream structure */
-    PA_UNLESS( stream = (PaOssStream*)PaUtil_AllocateMemory( sizeof(PaOssStream) ), paInsufficientMemory );
-    PA_ENSURE( PaOssStream_Initialize( stream, inputParameters, outputParameters, streamCallback, userData, streamFlags, ossHostApi ) );
-
-    PA_ENSURE( PaOssStream_Configure( stream, sampleRate, framesPerBuffer, &inLatency, &outLatency ) );
-
-    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
-        
-    if( inputParameters )
-    {
-        inputHostFormat = stream->capture->hostFormat;
-        stream->streamRepresentation.streamInfo.inputLatency = inLatency +
-            PaUtil_GetBufferProcessorInputLatency( &stream->bufferProcessor ) / sampleRate;
-    }
-    if( outputParameters )
-    {
-        outputHostFormat = stream->playback->hostFormat;
-        stream->streamRepresentation.streamInfo.outputLatency = outLatency +
-            PaUtil_GetBufferProcessorOutputLatency( &stream->bufferProcessor ) / sampleRate;
-    }
-
-    /* Initialize buffer processor with fixed host buffer size.
-     * Aspect StreamSampleFormat: Here we commit the user and host sample formats, PA infrastructure will
-     * convert between the two.
-     */
-    PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
-              inputChannelCount, inputSampleFormat, inputHostFormat, outputChannelCount, outputSampleFormat,
-              outputHostFormat, sampleRate, streamFlags, framesPerBuffer, stream->framesPerHostBuffer,
-              paUtilFixedHostBufferSize, streamCallback, userData ) );
-    bpInitialized = 1;
-
-    *s = (PaStream*)stream;
-
-    return result;
-
-error:
-    if( bpInitialized )
-        PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
-    if( stream )
-        PaOssStream_Terminate( stream );
-
-    return result;
-}
-
-/*! Poll on I/O filedescriptors.
-
-  Poll till we've determined there's data for read or write. In the full-duplex case,
-  we don't want to hang around forever waiting for either input or output frames, so
-  whenever we have a timed out filedescriptor we check if we're nearing under/overrun
-  for the other direction (critical limit set at one buffer). If so, we exit the waiting
-  state, and go on with what we got. We align the number of frames on a host buffer
-  boundary because it is possible that the buffer size differs for the two directions and
-  the host buffer size is a compromise between the two.
-  */
-static PaError PaOssStream_WaitForFrames( PaOssStream *stream, unsigned long *frames )
-{
-    PaError result = paNoError;
-    int pollPlayback = 0, pollCapture = 0;
-    int captureAvail = INT_MAX, playbackAvail = INT_MAX, commonAvail;
-    audio_buf_info bufInfo;
-    /* int ofs = 0, nfds = stream->nfds; */
-    fd_set readFds, writeFds;
-    int nfds = 0;
-    struct timeval selectTimeval = {0, 0};
-    unsigned long timeout = stream->pollTimeout;    /* In usecs */
-    int captureFd = -1, playbackFd = -1;
-
-    assert( stream );
-    assert( frames );
-
-    if( stream->capture )
-    {
-        pollCapture = 1;
-        captureFd = stream->capture->fd;
-        /* stream->capture->pfd->events = POLLIN; */
-    }
-    if( stream->playback )
-    {
-        pollPlayback = 1;
-        playbackFd = stream->playback->fd;
-        /* stream->playback->pfd->events = POLLOUT; */
-    }
-
-    FD_ZERO( &readFds );
-    FD_ZERO( &writeFds );
-
-    while( pollPlayback || pollCapture )
-    {
-        pthread_testcancel();
-
-        /* select may modify the timeout parameter */
-        selectTimeval.tv_usec = timeout;
-        nfds = 0;
-
-        if( pollCapture )
-        {
-            FD_SET( captureFd, &readFds );
-            nfds = captureFd + 1;
-        }
-        if( pollPlayback )
-        {
-            FD_SET( playbackFd, &writeFds );
-            nfds = PA_MAX( nfds, playbackFd + 1 );
-        }
-        ENSURE_( select( nfds, &readFds, &writeFds, NULL, &selectTimeval ), paUnanticipatedHostError );
-        /*
-        if( poll( stream->pfds + ofs, nfds, stream->pollTimeout ) < 0 )
-        {
-
-            ENSURE_( -1, paUnanticipatedHostError );
-        }
-        */
-        pthread_testcancel();
-
-        if( pollCapture )
-        {
-            if( FD_ISSET( captureFd, &readFds ) )
-            {
-                FD_CLR( captureFd, &readFds );
-                pollCapture = 0;
-            }
-            /*
-            if( stream->capture->pfd->revents & POLLIN )
-            {
-                --nfds;
-                ++ofs;
-                pollCapture = 0;
-            }
-            */
-            else if( stream->playback ) /* Timed out, go on with playback? */ 
-            {
-                /*PA_DEBUG(( "%s: Trying to poll again for capture frames, pollTimeout: %d\n",
-                            __FUNCTION__, stream->pollTimeout ));*/
-            }
-        }
-        if( pollPlayback )
-        {
-            if( FD_ISSET( playbackFd, &writeFds ) )
-            {
-                FD_CLR( playbackFd, &writeFds );
-                pollPlayback = 0;
-            }
-            /*
-            if( stream->playback->pfd->revents & POLLOUT )
-            {
-                --nfds;
-                pollPlayback = 0;
-            }
-            */
-            else if( stream->capture )  /* Timed out, go on with capture? */
-            {
-                /*PA_DEBUG(( "%s: Trying to poll again for playback frames, pollTimeout: %d\n\n",
-                            __FUNCTION__, stream->pollTimeout ));*/
-            }
-        }
-    }
-
-    if( stream->capture )
-    {
-        ENSURE_( ioctl( captureFd, SNDCTL_DSP_GETISPACE, &bufInfo ), paUnanticipatedHostError );
-        captureAvail = bufInfo.fragments * stream->capture->hostFrames;
-        if( !captureAvail )
-            PA_DEBUG(( "%s: captureAvail: 0\n", __FUNCTION__ ));
-
-        captureAvail = captureAvail == 0 ? INT_MAX : captureAvail;      /* Disregard if zero */
-    }
-    if( stream->playback )
-    {
-        ENSURE_( ioctl( playbackFd, SNDCTL_DSP_GETOSPACE, &bufInfo ), paUnanticipatedHostError );
-        playbackAvail = bufInfo.fragments * stream->playback->hostFrames;
-        if( !playbackAvail )
-        {
-            PA_DEBUG(( "%s: playbackAvail: 0\n", __FUNCTION__ ));
-        }
-
-        playbackAvail = playbackAvail == 0 ? INT_MAX : playbackAvail;      /* Disregard if zero */
-    }
-
-    commonAvail = PA_MIN( captureAvail, playbackAvail );
-    if( commonAvail == INT_MAX )
-        commonAvail = 0;
-    commonAvail -= commonAvail % stream->framesPerHostBuffer;
-
-    assert( commonAvail != INT_MAX );
-    assert( commonAvail >= 0 );
-    *frames = commonAvail;
-
-error:
-    return result;
-}
-
-/** Prepare stream for capture/playback.
- *
- * In order to synchronize capture and playback properly we use the SETTRIGGER command.
- */
-static PaError PaOssStream_Prepare( PaOssStream *stream )
-{
-    PaError result = paNoError;
-    int enableBits = 0;
-
-    if( stream->triggered )
-        return result;
-
-    if( stream->playback )
-    {
-        size_t bufSz = PaOssStreamComponent_BufferSize( stream->playback );
-        memset( stream->playback->buffer, 0, bufSz );
-
-        /* Looks like we have to turn off blocking before we try this, but if we don't fill the buffer
-         * OSS will complain. */
-        PA_ENSURE( ModifyBlocking( stream->playback->fd, 0 ) );
-        while (1)
-        {
-            if( write( stream->playback->fd, stream->playback->buffer, bufSz ) < 0 )
-                break;
-        }
-        PA_ENSURE( ModifyBlocking( stream->playback->fd, 1 ) );
-    }
-
-    if( stream->sharedDevice )
-    {
-        enableBits = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
-        ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError );
-    }
-    else
-    {
-        if( stream->capture )
-        {
-            enableBits = PCM_ENABLE_INPUT;
-            ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError );
-        }
-        if( stream->playback )
-        {
-            enableBits = PCM_ENABLE_OUTPUT;
-            ENSURE_( ioctl( stream->playback->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError );
-        }
-    }
-
-    /* Ok, we have triggered the stream */
-    stream->triggered = 1;
-    
-error:
-    return result;
-}
-
-/** Stop audio processing
- *
- */
-static PaError PaOssStream_Stop( PaOssStream *stream, int abort )
-{
-    PaError result = paNoError;
-
-    /* Looks like the only safe way to stop audio without reopening the device is SNDCTL_DSP_POST.
-     * Also disable capture/playback till the stream is started again */
-    if( stream->capture )
-    {
-        ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_POST, 0 ), paUnanticipatedHostError );
-    }
-    if( stream->playback && !stream->sharedDevice )
-    {
-        ENSURE_( ioctl( stream->playback->fd, SNDCTL_DSP_POST, 0 ), paUnanticipatedHostError );
-    }
-
-error:
-    return result;
-}
-
-/** Clean up after thread exit.
- *
- * Aspect StreamState: If the user has registered a streamFinishedCallback it will be called here
- */
-static void OnExit( void *data )
-{
-    PaOssStream *stream = (PaOssStream *) data;
-    assert( data );
-
-    PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer );
-
-    PaOssStream_Stop( stream, stream->callbackAbort );
-    
-    PA_DEBUG(( "OnExit: Stoppage\n" ));
-
-    /* Eventually notify user all buffers have played */
-    if( stream->streamRepresentation.streamFinishedCallback )
-        stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
-
-    stream->callbackAbort = 0;      /* Clear state */
-    stream->isActive = 0;
-}
-
-static PaError SetUpBuffers( PaOssStream *stream, unsigned long framesAvail )
-{
-    PaError result = paNoError;
-
-    if( stream->capture )
-    {
-        PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, stream->capture->buffer,
-                stream->capture->hostChannelCount );
-        PaUtil_SetInputFrameCount( &stream->bufferProcessor, framesAvail );
-    }
-    if( stream->playback )
-    {
-        PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, stream->playback->buffer,
-                stream->playback->hostChannelCount );
-        PaUtil_SetOutputFrameCount( &stream->bufferProcessor, framesAvail );
-    }
-
-    return result;
-}
-
-/** Thread procedure for callback processing.
- *
- * Aspect StreamState: StartStream will wait on this to initiate audio processing, useful in case the
- * callback should be used for buffer priming. When the stream is cancelled a separate function will
- * take care of the transition to the Callback Finished state (the stream isn't considered Stopped
- * before StopStream() or AbortStream() are called).
- */
-static void *PaOSS_AudioThreadProc( void *userData )
-{
-    PaError result = paNoError;
-    PaOssStream *stream = (PaOssStream*)userData;
-    unsigned long framesAvail, framesProcessed;
-    int callbackResult = paContinue;
-    int triggered = stream->triggered;  /* See if SNDCTL_DSP_TRIGGER has been issued already */
-    int initiateProcessing = triggered;    /* Already triggered? */
-    PaStreamCallbackFlags cbFlags = 0;  /* We might want to keep state across iterations */
-    PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* TODO: IMPLEMENT ME */
-    
-    /*
-#if ( SOUND_VERSION > 0x030904 )
-        audio_errinfo errinfo;
-#endif
-*/
-    
-    assert( stream );
-
-    pthread_cleanup_push( &OnExit, stream );	/* Execute OnExit when exiting */
-
-    /* The first time the stream is started we use SNDCTL_DSP_TRIGGER to accurately start capture and
-     * playback in sync, when the stream is restarted after being stopped we simply start by reading/
-     * writing.
-     */
-    PA_ENSURE( PaOssStream_Prepare( stream ) );
-
-    /* If we are to initiate processing implicitly by reading/writing data, we start off in blocking mode */
-    if( initiateProcessing )
-    {
-        /* Make sure devices are in blocking mode */
-        if( stream->capture )
-            ModifyBlocking( stream->capture->fd, 1 );
-        if( stream->playback )
-            ModifyBlocking( stream->playback->fd, 1 );
-    }
-
-    while( 1 )
-    {
-        pthread_testcancel();
-
-        if( stream->callbackStop && callbackResult == paContinue )
-        {
-            PA_DEBUG(( "Setting callbackResult to paComplete\n" ));
-            callbackResult = paComplete;
-        }
-
-        /* Aspect StreamState: Because of the messy OSS scheme we can't explicitly trigger device start unless
-         * the stream has been recently started, we will have to go right ahead and read/write in blocking
-         * fashion to trigger operation. Therefore we begin with processing one host buffer before we switch
-         * to non-blocking mode.
-         */
-        if( !initiateProcessing )
-        {
-            PA_ENSURE( PaOssStream_WaitForFrames( stream, &framesAvail ) );  /* Wait on available frames */
-            assert( framesAvail % stream->framesPerHostBuffer == 0 );
-        }
-        else
-        {
-            framesAvail = stream->framesPerHostBuffer;
-        }
-
-        while( framesAvail > 0 )
-        {
-            unsigned long frames = framesAvail;
-
-            pthread_testcancel();
-
-            PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
-
-            /* Read data */
-            if ( stream->capture )
-            {
-                PA_ENSURE( PaOssStreamComponent_Read( stream->capture, &frames ) );
-                assert( frames == framesAvail );
-            }
-
-#if ( SOUND_VERSION >= 0x030904 )
-            /*
-               Check with OSS to see if there have been any under/overruns
-               since last time we checked.
-               */
-            /*
-            if( ioctl( stream->deviceHandle, SNDCTL_DSP_GETERROR, &errinfo ) >= 0 )
-            {
-                if( errinfo.play_underruns )
-                    cbFlags |= paOutputUnderflow ;
-                if( errinfo.record_underruns )
-                    cbFlags |= paInputUnderflow ;
-            }
-            else
-                PA_DEBUG(( "SNDCTL_DSP_GETERROR command failed: %s\n", strerror( errno ) ));
-                */
-#endif
-
-            PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo,
-                    cbFlags );
-            cbFlags = 0;
-            PA_ENSURE( SetUpBuffers( stream, framesAvail ) );
-
-            framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor,
-                    &callbackResult );
-            assert( framesProcessed == framesAvail );
-            PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
-
-            if ( stream->playback )
-            {
-                frames = framesAvail;
-
-                PA_ENSURE( PaOssStreamComponent_Write( stream->playback, &frames ) );
-                assert( frames == framesAvail );
-
-                /* TODO: handle bytesWritten != bytesRequested (slippage?) */
-            }
-
-            framesAvail -= framesProcessed;
-            stream->framesProcessed += framesProcessed;
-
-            if( callbackResult != paContinue )
-                break;
-        }
-
-        if( initiateProcessing || !triggered )
-        {
-            /* Non-blocking */
-            if( stream->capture )
-                PA_ENSURE( ModifyBlocking( stream->capture->fd, 0 ) );
-            if( stream->playback && !stream->sharedDevice )
-                PA_ENSURE( ModifyBlocking( stream->playback->fd, 0 ) );
-
-            initiateProcessing = 0;
-            sem_post( &stream->semaphore );
-        }
-
-        if( callbackResult != paContinue )
-        {
-            stream->callbackAbort = callbackResult == paAbort;
-            if( stream->callbackAbort || PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) )
-                break;
-        }
-    }
-
-    pthread_cleanup_pop( 1 );
-
-error:
-    pthread_exit( NULL );
-}
-
-/** Close the stream.
- *
- */
-static PaError CloseStream( PaStream* s )
-{
-    PaError result = paNoError;
-    PaOssStream *stream = (PaOssStream*)s;
-
-    assert( stream );
-
-    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
-    PaOssStream_Terminate( stream );
-
-    return result;
-}
-
-/** Start the stream.
- *
- * Aspect StreamState: After returning, the stream shall be in the Active state, implying that an eventual
- * callback will be repeatedly called in a separate thread. If a separate thread is started this function
- * will block untill it has started processing audio, otherwise audio processing is started directly.
- */
-static PaError StartStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaOssStream *stream = (PaOssStream*)s;
-
-    stream->isActive = 1;
-    stream->isStopped = 0;
-    stream->lastPosPtr = 0;
-    stream->lastStreamBytes = 0;
-    stream->framesProcessed = 0;
-
-    /* only use the thread for callback streams */
-    if( stream->bufferProcessor.streamCallback )
-    {
-        PA_ENSURE( PaUtil_StartThreading( &stream->threading, &PaOSS_AudioThreadProc, stream ) );
-        sem_wait( &stream->semaphore );
-    }
-    else
-        PA_ENSURE( PaOssStream_Prepare( stream ) );
-
-error:
-    return result;
-}
-
-static PaError RealStop( PaOssStream *stream, int abort )
-{
-    PaError result = paNoError;
-
-    if( stream->callbackMode )
-    {
-        if( abort )
-            stream->callbackAbort = 1;
-        else
-            stream->callbackStop = 1;
-
-        PA_ENSURE( PaUtil_CancelThreading( &stream->threading, !abort, NULL ) );
-
-        stream->callbackStop = stream->callbackAbort = 0;
-    }
-    else
-        PA_ENSURE( PaOssStream_Stop( stream, abort ) );
-
-    stream->isStopped = 1;
-
-error:
-    return result;
-}
-
-/** Stop the stream.
- *
- * Aspect StreamState: This will cause the stream to transition to the Stopped state, playing all enqueued
- * buffers.
- */
-static PaError StopStream( PaStream *s )
-{
-    return RealStop( (PaOssStream *)s, 0 );
-}
-
-/** Abort the stream.
- *
- * Aspect StreamState: This will cause the stream to transition to the Stopped state, discarding all enqueued
- * buffers. Note that the buffers are not currently correctly discarded, this is difficult without closing
- * the OSS device.
- */
-static PaError AbortStream( PaStream *s )
-{
-    return RealStop( (PaOssStream *)s, 1 );
-}
-
-/** Is the stream in the Stopped state.
- *
- */
-static PaError IsStreamStopped( PaStream *s )
-{
-    PaOssStream *stream = (PaOssStream*)s;
-
-    return (stream->isStopped);
-}
-
-/** Is the stream in the Active state.
- *
- */
-static PaError IsStreamActive( PaStream *s )
-{
-    PaOssStream *stream = (PaOssStream*)s;
-
-    return (stream->isActive);
-}
-
-static PaTime GetStreamTime( PaStream *s )
-{
-    PaOssStream *stream = (PaOssStream*)s;
-    count_info info;
-    int delta;
-
-    if( stream->playback ) {
-        if( ioctl( stream->playback->fd, SNDCTL_DSP_GETOPTR, &info) == 0 ) {
-            delta = ( info.bytes - stream->lastPosPtr ) /* & 0x000FFFFF*/;
-            return (float)(stream->lastStreamBytes + delta) / PaOssStreamComponent_FrameSize( stream->playback ) / stream->sampleRate;
-        }
-    }
-    else {
-        if (ioctl( stream->capture->fd, SNDCTL_DSP_GETIPTR, &info) == 0) {
-            delta = (info.bytes - stream->lastPosPtr) /*& 0x000FFFFF*/;
-            return (float)(stream->lastStreamBytes + delta) / PaOssStreamComponent_FrameSize( stream->capture ) / stream->sampleRate;
-        }
-    }
-
-    /* the ioctl failed, but we can still give a coarse estimate */
-
-    return stream->framesProcessed / stream->sampleRate;
-}
-
-
-static double GetStreamCpuLoad( PaStream* s )
-{
-    PaOssStream *stream = (PaOssStream*)s;
-
-    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
-}
-
-
-/*
-    As separate stream interfaces are used for blocking and callback
-    streams, the following functions can be guaranteed to only be called
-    for blocking streams.
-*/
-
-
-static PaError ReadStream( PaStream* s,
-                           void *buffer,
-                           unsigned long frames )
-{
-    PaOssStream *stream = (PaOssStream*)s;
-    int bytesRequested, bytesRead;
-    unsigned long framesRequested;
-    void *userBuffer;
-
-    /* If user input is non-interleaved, PaUtil_CopyInput will manipulate the channel pointers,
-     * so we copy the user provided pointers */
-    if( stream->bufferProcessor.userInputIsInterleaved )
-        userBuffer = buffer;
-    else /* Copy channels into local array */
-    {
-        userBuffer = stream->capture->userBuffers;
-        memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->capture->userChannelCount );
-    }
-
-    while( frames )
-    {
-        framesRequested = PA_MIN( frames, stream->capture->hostFrames );
-
-	bytesRequested = framesRequested * PaOssStreamComponent_FrameSize( stream->capture );
-	bytesRead = read( stream->capture->fd, stream->capture->buffer, bytesRequested );
-	if ( bytesRequested != bytesRead )
-	    return paUnanticipatedHostError;
-
-	PaUtil_SetInputFrameCount( &stream->bufferProcessor, stream->capture->hostFrames );
-	PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, stream->capture->buffer, stream->capture->hostChannelCount );
-        PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, framesRequested );
-	frames -= framesRequested;
-    }
-    return paNoError;
-}
-
-
-static PaError WriteStream( PaStream *s, const void *buffer, unsigned long frames )
-{
-    PaOssStream *stream = (PaOssStream*)s;
-    int bytesRequested, bytesWritten;
-    unsigned long framesConverted;
-    const void *userBuffer;
-
-    /* If user output is non-interleaved, PaUtil_CopyOutput will manipulate the channel pointers,
-     * so we copy the user provided pointers */
-    if( stream->bufferProcessor.userOutputIsInterleaved )
-        userBuffer = buffer;
-    else
-    {
-        /* Copy channels into local array */
-        userBuffer = stream->playback->userBuffers;
-        memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->playback->userChannelCount );
-    }
-
-    while( frames )
-    {
-	PaUtil_SetOutputFrameCount( &stream->bufferProcessor, stream->playback->hostFrames );
-	PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, stream->playback->buffer, stream->playback->hostChannelCount );
-
-	framesConverted = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, frames );
-	frames -= framesConverted;
-
-	bytesRequested = framesConverted * PaOssStreamComponent_FrameSize( stream->playback );
-	bytesWritten = write( stream->playback->fd, stream->playback->buffer, bytesRequested );
-
-	if ( bytesRequested != bytesWritten )
-	    return paUnanticipatedHostError;
-    }
-    return paNoError;
-}
-
-
-static signed long GetStreamReadAvailable( PaStream* s )
-{
-    PaOssStream *stream = (PaOssStream*)s;
-    audio_buf_info info;
-
-    if( ioctl( stream->capture->fd, SNDCTL_DSP_GETISPACE, &info ) < 0 )
-        return paUnanticipatedHostError;
-    return info.fragments * stream->capture->hostFrames;
-}
-
-
-/* TODO: Compute number of allocated bytes somewhere else, can we use ODELAY with capture */
-static signed long GetStreamWriteAvailable( PaStream* s )
-{
-    PaOssStream *stream = (PaOssStream*)s;
-    int delay = 0;
-
-    if( ioctl( stream->playback->fd, SNDCTL_DSP_GETODELAY, &delay ) < 0 )
-        return paUnanticipatedHostError;
-    
-    return (PaOssStreamComponent_BufferSize( stream->playback ) - delay) / PaOssStreamComponent_FrameSize( stream->playback );
-}
-
diff --git a/portaudio/pa_unix_oss/recplay.c b/portaudio/pa_unix_oss/recplay.c
deleted file mode 100644
index 9d4c78cfa..000000000
--- a/portaudio/pa_unix_oss/recplay.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * recplay.c
- * Phil Burk
- * Minimal record and playback test.
- * 
- */
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#ifndef __STDC__
-/* #include <getopt.h> */
-#endif /* __STDC__ */
-#include <fcntl.h>
-#ifdef __STDC__
-#include <string.h>
-#else /* __STDC__ */
-#include <strings.h>
-#endif /* __STDC__ */
-#include <sys/soundcard.h>
-
-#define NUM_BYTES   (64*1024)
-#define BLOCK_SIZE   (4*1024)
-
-#define AUDIO "/dev/dsp"
-
-char buffer[NUM_BYTES];
-
-int audioDev = 0;
-
-main (int argc, char *argv[])
-{
-    int   numLeft;
-    char *ptr;
-    int   num;
-    int   samplesize;
-
-    /********** RECORD ********************/
-    /* Open audio device. */
-    audioDev = open (AUDIO, O_RDONLY, 0);
-    if (audioDev == -1)
-    {
-        perror (AUDIO);
-        exit (-1);
-    }
-
-    /* Set to 16 bit samples. */
-    samplesize = 16;
-    ioctl(audioDev, SNDCTL_DSP_SAMPLESIZE, &samplesize);
-    if (samplesize != 16)
-    {
-        perror("Unable to set the sample size.");
-        exit(-1);
-    }
-
-    /* Record in blocks */
-    printf("Begin recording.\n");
-    numLeft = NUM_BYTES;
-    ptr = buffer;
-    while( numLeft >= BLOCK_SIZE )
-    {
-        if ( (num = read (audioDev, ptr, BLOCK_SIZE)) < 0 )
-        {
-            perror (AUDIO);
-            exit (-1);
-        }
-        else
-        {
-            printf("Read %d bytes\n", num);
-            ptr += num;
-            numLeft -= num;
-        }
-    }
-
-    close( audioDev );
-
-    /********** PLAYBACK ********************/
-    /* Open audio device for writing. */
-    audioDev = open (AUDIO, O_WRONLY, 0);
-    if (audioDev == -1)
-    {
-        perror (AUDIO);
-        exit (-1);
-    }
-
-    /* Set to 16 bit samples. */
-    samplesize = 16;
-    ioctl(audioDev, SNDCTL_DSP_SAMPLESIZE, &samplesize);
-    if (samplesize != 16)
-    {
-        perror("Unable to set the sample size.");
-        exit(-1);
-    }
-
-    /* Play in blocks */
-    printf("Begin playing.\n");
-    numLeft = NUM_BYTES;
-    ptr = buffer;
-    while( numLeft >= BLOCK_SIZE )
-    {
-        if ( (num = write (audioDev, ptr, BLOCK_SIZE)) < 0 )
-        {
-            perror (AUDIO);
-            exit (-1);
-        }
-        else
-        {
-            printf("Wrote %d bytes\n", num);
-            ptr += num;
-            numLeft -= num;
-        }
-    }
-
-    close( audioDev );
-}
diff --git a/portaudio/pa_win/CVS/Entries b/portaudio/pa_win/CVS/Entries
deleted file mode 100644
index 857a6055a..000000000
--- a/portaudio/pa_win/CVS/Entries
+++ /dev/null
@@ -1,5 +0,0 @@
-/pa_win_hostapis.c/1.1.2.10/Wed Sep  8 17:31:37 2004//Tv19-devel
-/pa_win_util.c/1.1.2.7/Mon Sep 15 18:30:26 2003//Tv19-devel
-/pa_x86_plain_converters.c/1.1.2.2/Fri Feb 28 01:49:59 2003//Tv19-devel
-/pa_x86_plain_converters.h/1.1.2.2/Sat Sep 20 21:09:55 2003//Tv19-devel
-D
diff --git a/portaudio/pa_win/CVS/Entries.Log b/portaudio/pa_win/CVS/Entries.Log
deleted file mode 100644
index 0d56e1d46..000000000
--- a/portaudio/pa_win/CVS/Entries.Log
+++ /dev/null
@@ -1,2 +0,0 @@
-A D/dev-cpp////
-A D/msvc////
diff --git a/portaudio/pa_win/CVS/Repository b/portaudio/pa_win/CVS/Repository
deleted file mode 100644
index 064cf91c2..000000000
--- a/portaudio/pa_win/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_win
diff --git a/portaudio/pa_win/CVS/Root b/portaudio/pa_win/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_win/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_win/CVS/Tag b/portaudio/pa_win/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_win/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_win/dev-cpp/CVS/Entries b/portaudio/pa_win/dev-cpp/CVS/Entries
deleted file mode 100644
index 87893783b..000000000
--- a/portaudio/pa_win/dev-cpp/CVS/Entries
+++ /dev/null
@@ -1,6 +0,0 @@
-/Makefile-dll/1.1.2.1/Wed Sep 17 19:52:09 2003//Tv19-devel
-/Makefile-static/1.1.2.1/Wed Sep 17 19:52:09 2003//Tv19-devel
-/portaudio-dll.dev/1.1.2.1/Wed Sep 17 19:52:09 2003//Tv19-devel
-/portaudio-static.dev/1.1.2.1/Wed Sep 17 19:52:09 2003//Tv19-devel
-/readme.txt/1.1.2.1/Wed Sep 17 19:52:09 2003//Tv19-devel
-D
diff --git a/portaudio/pa_win/dev-cpp/CVS/Repository b/portaudio/pa_win/dev-cpp/CVS/Repository
deleted file mode 100644
index ebf18943a..000000000
--- a/portaudio/pa_win/dev-cpp/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_win/dev-cpp
diff --git a/portaudio/pa_win/dev-cpp/CVS/Root b/portaudio/pa_win/dev-cpp/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_win/dev-cpp/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_win/dev-cpp/CVS/Tag b/portaudio/pa_win/dev-cpp/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_win/dev-cpp/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_win/dev-cpp/Makefile-dll b/portaudio/pa_win/dev-cpp/Makefile-dll
deleted file mode 100644
index 856af638e..000000000
--- a/portaudio/pa_win/dev-cpp/Makefile-dll
+++ /dev/null
@@ -1,78 +0,0 @@
-# Project: portaudio-dll
-# Makefile created by Dev-C++ 4.9.8.2
-
-CPP  = g++.exe
-CC   = gcc.exe
-WINDRES = windres.exe
-RES  = 
-OBJ  = ./pa_skeleton.o ./pa_stream.o ./pa_trace.o ./pa_allocation.o ./pa_converters.o ./pa_cpuload.o ./pa_dither.o ./pa_front.o ./pa_process.o ./pa_asio.o ./pa_win_util.o ./pa_win_hostapis.o ./pa_win_ds.o ./dsound_wrapper.o ./pa_win_wmme.o ./iasiothiscallresolver.o $(RES)
-LINKOBJ  = ./pa_skeleton.o ./pa_stream.o ./pa_trace.o ./pa_allocation.o ./pa_converters.o ./pa_cpuload.o ./pa_dither.o ./pa_front.o ./pa_process.o ./pa_asio.o ./pa_win_util.o ./pa_win_hostapis.o ./pa_win_ds.o ./dsound_wrapper.o ./pa_win_wmme.o ./iasiothiscallresolver.o $(RES)
-LIBS =  -L"C:/Dev-CPP/lib" -fmessage-length=0 --no-export-all-symbols --add-stdcall-alias ../../../asiosdk2/asiosdk2.a -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lwinmm -O3 -s 
-INCS =  -I"C:/Dev-CPP/include"  -I"../../../asiosdk2"  -I"../../../asiosdk2/common"  -I"../../../asiosdk2/host"  -I"../../../asiosdk2/host/pc"  -I"../../pa_common" 
-CXXINCS =  -I"C:/Dev-CPP/include/c++"  -I"C:/Dev-CPP/include/c++/mingw32"  -I"C:/Dev-CPP/include/c++/backward"  -I"C:/Dev-CPP/include"  -I"../../../asiosdk2"  -I"../../../asiosdk2/common"  -I"../../../asiosdk2/host"  -I"../../../asiosdk2/host/pc"  -I"../../pa_common" 
-BIN  = portaudio-dll.dll
-CXXFLAGS = $(CXXINCS)-O3   -fmessage-length=0 -Wall
-CFLAGS = $(INCS)-DBUILDING_DLL=1 -O3   -fmessage-length=0 -Wall
-
-.PHONY: all all-before all-after clean clean-custom
-
-all: all-before portaudio-dll.dll all-after
-
-
-clean: clean-custom
-	rm -f $(OBJ) $(BIN)
-
-DLLWRAP=dllwrap.exe
-DEFFILE=libportaudio-dll.def
-STATICLIB=libportaudio-dll.a
-
-$(BIN): $(LINKOBJ)
-	$(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
-
-./pa_skeleton.o: ../../pa_common/pa_skeleton.c
-	$(CPP) -c ../../pa_common/pa_skeleton.c -o ./pa_skeleton.o $(CXXFLAGS)
-
-./pa_stream.o: ../../pa_common/pa_stream.c
-	$(CPP) -c ../../pa_common/pa_stream.c -o ./pa_stream.o $(CXXFLAGS)
-
-./pa_trace.o: ../../pa_common/pa_trace.c
-	$(CPP) -c ../../pa_common/pa_trace.c -o ./pa_trace.o $(CXXFLAGS)
-
-./pa_allocation.o: ../../pa_common/pa_allocation.c
-	$(CPP) -c ../../pa_common/pa_allocation.c -o ./pa_allocation.o $(CXXFLAGS)
-
-./pa_converters.o: ../../pa_common/pa_converters.c
-	$(CPP) -c ../../pa_common/pa_converters.c -o ./pa_converters.o $(CXXFLAGS)
-
-./pa_cpuload.o: ../../pa_common/pa_cpuload.c
-	$(CPP) -c ../../pa_common/pa_cpuload.c -o ./pa_cpuload.o $(CXXFLAGS)
-
-./pa_dither.o: ../../pa_common/pa_dither.c
-	$(CPP) -c ../../pa_common/pa_dither.c -o ./pa_dither.o $(CXXFLAGS)
-
-./pa_front.o: ../../pa_common/pa_front.c
-	$(CPP) -c ../../pa_common/pa_front.c -o ./pa_front.o $(CXXFLAGS)
-
-./pa_process.o: ../../pa_common/pa_process.c
-	$(CPP) -c ../../pa_common/pa_process.c -o ./pa_process.o $(CXXFLAGS)
-
-./pa_asio.o: ../../pa_asio/pa_asio.cpp
-	$(CPP) -c ../../pa_asio/pa_asio.cpp -o ./pa_asio.o $(CXXFLAGS)
-
-./pa_win_util.o: ../pa_win_util.c
-	$(CPP) -c ../pa_win_util.c -o ./pa_win_util.o $(CXXFLAGS)
-
-./pa_win_hostapis.o: ../pa_win_hostapis.c
-	$(CPP) -c ../pa_win_hostapis.c -o ./pa_win_hostapis.o $(CXXFLAGS)
-
-./pa_win_ds.o: ../../pa_win_ds/pa_win_ds.c
-	$(CPP) -c ../../pa_win_ds/pa_win_ds.c -o ./pa_win_ds.o $(CXXFLAGS)
-
-./dsound_wrapper.o: ../../pa_win_ds/dsound_wrapper.c
-	$(CPP) -c ../../pa_win_ds/dsound_wrapper.c -o ./dsound_wrapper.o $(CXXFLAGS)
-
-./pa_win_wmme.o: ../../pa_win_wmme/pa_win_wmme.c
-	$(CPP) -c ../../pa_win_wmme/pa_win_wmme.c -o ./pa_win_wmme.o $(CXXFLAGS)
-
-./iasiothiscallresolver.o: ../../pa_asio/iasiothiscallresolver.cpp
-	$(CPP) -c ../../pa_asio/iasiothiscallresolver.cpp -o ./iasiothiscallresolver.o $(CXXFLAGS)
diff --git a/portaudio/pa_win/dev-cpp/Makefile-static b/portaudio/pa_win/dev-cpp/Makefile-static
deleted file mode 100644
index 2a1647ddc..000000000
--- a/portaudio/pa_win/dev-cpp/Makefile-static
+++ /dev/null
@@ -1,75 +0,0 @@
-# Project: portaudio-static
-# Makefile created by Dev-C++ 4.9.8.2
-
-CPP  = g++.exe
-CC   = gcc.exe
-WINDRES = windres.exe
-RES  = 
-OBJ  = ./pa_skeleton.o ./pa_stream.o ./pa_trace.o ./pa_allocation.o ./pa_converters.o ./pa_cpuload.o ./pa_dither.o ./pa_front.o ./pa_process.o ./pa_asio.o ./pa_win_util.o ./pa_win_hostapis.o ./pa_win_ds.o ./dsound_wrapper.o ./pa_win_wmme.o ./iasiothiscallresolver.o $(RES)
-LINKOBJ  = ./pa_skeleton.o ./pa_stream.o ./pa_trace.o ./pa_allocation.o ./pa_converters.o ./pa_cpuload.o ./pa_dither.o ./pa_front.o ./pa_process.o ./pa_asio.o ./pa_win_util.o ./pa_win_hostapis.o ./pa_win_ds.o ./dsound_wrapper.o ./pa_win_wmme.o ./iasiothiscallresolver.o $(RES)
-LIBS =  -L"C:/Dev-CPP/lib" -fmessage-length=0 -O3 -s 
-INCS =  -I"C:/Dev-CPP/include"  -I"../../../asiosdk2"  -I"../../../asiosdk2/common"  -I"../../../asiosdk2/host"  -I"../../../asiosdk2/host/pc"  -I"../../pa_common" 
-CXXINCS =  -I"C:/Dev-CPP/include/c++"  -I"C:/Dev-CPP/include/c++/mingw32"  -I"C:/Dev-CPP/include/c++/backward"  -I"C:/Dev-CPP/include"  -I"../../../asiosdk2"  -I"../../../asiosdk2/common"  -I"../../../asiosdk2/host"  -I"../../../asiosdk2/host/pc"  -I"../../pa_common" 
-BIN  = portaudio-static.a
-CXXFLAGS = $(CXXINCS)-O3   -fmessage-length=0 -Wall
-CFLAGS = $(INCS)-O3   -fmessage-length=0 -Wall
-
-.PHONY: all all-before all-after clean clean-custom
-
-all: all-before portaudio-static.a all-after
-
-
-clean: clean-custom
-	rm -f $(OBJ) $(BIN)
-
-$(BIN): $(LINKOBJ)
-	ar r $(BIN) $(LINKOBJ)
-	ranlib $(BIN)
-
-./pa_skeleton.o: ../../pa_common/pa_skeleton.c
-	$(CPP) -c ../../pa_common/pa_skeleton.c -o ./pa_skeleton.o $(CXXFLAGS)
-
-./pa_stream.o: ../../pa_common/pa_stream.c
-	$(CPP) -c ../../pa_common/pa_stream.c -o ./pa_stream.o $(CXXFLAGS)
-
-./pa_trace.o: ../../pa_common/pa_trace.c
-	$(CPP) -c ../../pa_common/pa_trace.c -o ./pa_trace.o $(CXXFLAGS)
-
-./pa_allocation.o: ../../pa_common/pa_allocation.c
-	$(CPP) -c ../../pa_common/pa_allocation.c -o ./pa_allocation.o $(CXXFLAGS)
-
-./pa_converters.o: ../../pa_common/pa_converters.c
-	$(CPP) -c ../../pa_common/pa_converters.c -o ./pa_converters.o $(CXXFLAGS)
-
-./pa_cpuload.o: ../../pa_common/pa_cpuload.c
-	$(CPP) -c ../../pa_common/pa_cpuload.c -o ./pa_cpuload.o $(CXXFLAGS)
-
-./pa_dither.o: ../../pa_common/pa_dither.c
-	$(CPP) -c ../../pa_common/pa_dither.c -o ./pa_dither.o $(CXXFLAGS)
-
-./pa_front.o: ../../pa_common/pa_front.c
-	$(CPP) -c ../../pa_common/pa_front.c -o ./pa_front.o $(CXXFLAGS)
-
-./pa_process.o: ../../pa_common/pa_process.c
-	$(CPP) -c ../../pa_common/pa_process.c -o ./pa_process.o $(CXXFLAGS)
-
-./pa_asio.o: ../../pa_asio/pa_asio.cpp
-	$(CPP) -c ../../pa_asio/pa_asio.cpp -o ./pa_asio.o $(CXXFLAGS)
-
-./pa_win_util.o: ../pa_win_util.c
-	$(CPP) -c ../pa_win_util.c -o ./pa_win_util.o $(CXXFLAGS)
-
-./pa_win_hostapis.o: ../pa_win_hostapis.c
-	$(CPP) -c ../pa_win_hostapis.c -o ./pa_win_hostapis.o $(CXXFLAGS)
-
-./pa_win_ds.o: ../../pa_win_ds/pa_win_ds.c
-	$(CPP) -c ../../pa_win_ds/pa_win_ds.c -o ./pa_win_ds.o $(CXXFLAGS)
-
-./dsound_wrapper.o: ../../pa_win_ds/dsound_wrapper.c
-	$(CPP) -c ../../pa_win_ds/dsound_wrapper.c -o ./dsound_wrapper.o $(CXXFLAGS)
-
-./pa_win_wmme.o: ../../pa_win_wmme/pa_win_wmme.c
-	$(CPP) -c ../../pa_win_wmme/pa_win_wmme.c -o ./pa_win_wmme.o $(CXXFLAGS)
-
-./iasiothiscallresolver.o: ../../pa_asio/iasiothiscallresolver.cpp
-	$(CPP) -c ../../pa_asio/iasiothiscallresolver.cpp -o ./iasiothiscallresolver.o $(CXXFLAGS)
diff --git a/portaudio/pa_win/dev-cpp/portaudio-dll.dev b/portaudio/pa_win/dev-cpp/portaudio-dll.dev
deleted file mode 100644
index 086e109ee..000000000
--- a/portaudio/pa_win/dev-cpp/portaudio-dll.dev
+++ /dev/null
@@ -1,209 +0,0 @@
-[Project]
-FileName=portaudio-dll.dev
-Name=portaudio-dll
-UnitCount=16
-Type=3
-Ver=1
-ObjFiles=
-Includes=..\..\..\asiosdk2;..\..\..\asiosdk2\common;..\..\..\asiosdk2\host;..\..\..\asiosdk2\host\pc;..\..\pa_common
-Libs=
-PrivateResource=
-ResourceIncludes=
-MakeIncludes=
-Compiler=-DBUILDING_DLL=1_@@_-O3_@@_
-CppCompiler=-O3_@@_
-Linker=--no-export-all-symbols --add-stdcall-alias_@@_../../../asiosdk2/asiosdk2.a_@@_-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lwinmm_@@_-O3 -s_@@_
-IsCpp=1
-Icon=
-ExeOutput=.
-ObjectOutput=.
-OverrideOutput=0
-OverrideOutputName=portaudio.a
-HostApplication=
-Folders=
-CommandLine=
-IncludeVersionInfo=0
-SupportXPThemes=0
-CompilerSet=0
-CompilerSettings=0000000000000000000
-UseCustomMakefile=0
-CustomMakefile=
-
-[Unit1]
-FileName=..\..\pa_common\pa_skeleton.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_skeleton.c -o ./pa_skeleton.o $(CFLAGS)
-
-[Unit2]
-FileName=..\..\pa_common\pa_stream.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_stream.c -o ./pa_stream.o $(CFLAGS)
-
-[Unit3]
-FileName=..\..\pa_common\pa_trace.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_trace.c -o ./pa_trace.o $(CFLAGS)
-
-[Unit4]
-FileName=..\..\pa_common\pa_allocation.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_allocation.c -o ./pa_allocation.o $(CFLAGS)
-
-[Unit5]
-FileName=..\..\pa_common\pa_converters.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_converters.c -o ./pa_converters.o $(CFLAGS)
-
-[Unit6]
-FileName=..\..\pa_common\pa_cpuload.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_cpuload.c -o ./pa_cpuload.o $(CFLAGS)
-
-[Unit7]
-FileName=..\..\pa_common\pa_dither.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_dither.c -o ./pa_dither.o $(CFLAGS)
-
-[Unit8]
-FileName=..\..\pa_common\pa_front.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_front.c -o ./pa_front.o $(CFLAGS)
-
-[Unit9]
-FileName=..\..\pa_common\pa_process.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_process.c -o ./pa_process.o $(CFLAGS)
-
-[VersionInfo]
-Major=0
-Minor=1
-Release=1
-Build=1
-LanguageID=1033
-CharsetID=1252
-CompanyName=
-FileVersion=
-FileDescription=Developed using the Dev-C++ IDE
-InternalName=
-LegalCopyright=
-LegalTrademarks=
-OriginalFilename=
-ProductName=
-ProductVersion=
-AutoIncBuildNr=0
-
-[Unit10]
-FileName=..\..\pa_asio\pa_asio.cpp
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CPP) -c pa_asio.cpp -o ./pa_asio.o $(CXXFLAGS)
-
-[Unit11]
-FileName=..\pa_win_util.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_win_util.c -o ./pa_win_util.o $(CFLAGS)
-
-[Unit12]
-FileName=..\pa_win_hostapis.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_win_hostapis.c -o ./pa_win_hostapis.o $(CFLAGS)
-
-[Unit13]
-FileName=..\..\pa_win_ds\pa_win_ds.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_win_ds.c -o ./pa_win_ds.o $(CFLAGS)
-
-[Unit14]
-FileName=..\..\pa_win_ds\dsound_wrapper.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c dsound_wrapper.c -o ./dsound_wrapper.o $(CFLAGS)
-
-[Unit15]
-FileName=..\..\pa_win_wmme\pa_win_wmme.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_win_wmme.c -o ./pa_win_wmme.o $(CFLAGS)
-
-[Unit16]
-FileName=..\..\pa_asio\iasiothiscallresolver.cpp
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=
-
diff --git a/portaudio/pa_win/dev-cpp/portaudio-static.dev b/portaudio/pa_win/dev-cpp/portaudio-static.dev
deleted file mode 100644
index 2aae584df..000000000
--- a/portaudio/pa_win/dev-cpp/portaudio-static.dev
+++ /dev/null
@@ -1,209 +0,0 @@
-[Project]
-FileName=portaudio-static.dev
-Name=portaudio-static
-UnitCount=16
-Type=2
-Ver=1
-ObjFiles=
-Includes=..\..\..\asiosdk2;..\..\..\asiosdk2\common;..\..\..\asiosdk2\host;..\..\..\asiosdk2\host\pc;..\..\pa_common
-Libs=
-PrivateResource=
-ResourceIncludes=
-MakeIncludes=
-Compiler=-O3_@@_
-CppCompiler=-O3_@@_
-Linker=-O3 -s_@@_
-IsCpp=1
-Icon=
-ExeOutput=.
-ObjectOutput=.
-OverrideOutput=0
-OverrideOutputName=portaudio.a
-HostApplication=
-Folders=
-CommandLine=
-IncludeVersionInfo=0
-SupportXPThemes=0
-CompilerSet=0
-CompilerSettings=0000000000000000000
-UseCustomMakefile=0
-CustomMakefile=
-
-[Unit1]
-FileName=..\..\pa_common\pa_skeleton.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_skeleton.c -o ./pa_skeleton.o $(CFLAGS)
-
-[Unit2]
-FileName=..\..\pa_common\pa_stream.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_stream.c -o ./pa_stream.o $(CFLAGS)
-
-[Unit3]
-FileName=..\..\pa_common\pa_trace.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_trace.c -o ./pa_trace.o $(CFLAGS)
-
-[Unit4]
-FileName=..\..\pa_common\pa_allocation.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_allocation.c -o ./pa_allocation.o $(CFLAGS)
-
-[Unit5]
-FileName=..\..\pa_common\pa_converters.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_converters.c -o ./pa_converters.o $(CFLAGS)
-
-[Unit6]
-FileName=..\..\pa_common\pa_cpuload.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_cpuload.c -o ./pa_cpuload.o $(CFLAGS)
-
-[Unit7]
-FileName=..\..\pa_common\pa_dither.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_dither.c -o ./pa_dither.o $(CFLAGS)
-
-[Unit8]
-FileName=..\..\pa_common\pa_front.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_front.c -o ./pa_front.o $(CFLAGS)
-
-[Unit9]
-FileName=..\..\pa_common\pa_process.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_process.c -o ./pa_process.o $(CFLAGS)
-
-[VersionInfo]
-Major=0
-Minor=1
-Release=1
-Build=1
-LanguageID=1033
-CharsetID=1252
-CompanyName=
-FileVersion=
-FileDescription=Developed using the Dev-C++ IDE
-InternalName=
-LegalCopyright=
-LegalTrademarks=
-OriginalFilename=
-ProductName=
-ProductVersion=
-AutoIncBuildNr=0
-
-[Unit10]
-FileName=..\..\pa_asio\pa_asio.cpp
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CPP) -c pa_asio.cpp -o ./pa_asio.o $(CXXFLAGS)
-
-[Unit11]
-FileName=..\..\pa_win\pa_win_util.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_win_util.c -o ./pa_win_util.o $(CFLAGS)
-
-[Unit12]
-FileName=..\..\pa_win\pa_win_hostapis.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_win_hostapis.c -o ./pa_win_hostapis.o $(CFLAGS)
-
-[Unit13]
-FileName=..\..\pa_win_ds\pa_win_ds.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_win_ds.c -o ./pa_win_ds.o $(CFLAGS)
-
-[Unit14]
-FileName=..\..\pa_win_ds\dsound_wrapper.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c dsound_wrapper.c -o ./dsound_wrapper.o $(CFLAGS)
-
-[Unit15]
-FileName=..\..\pa_win_wmme\pa_win_wmme.c
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c pa_win_wmme.c -o ./pa_win_wmme.o $(CFLAGS)
-
-[Unit16]
-FileName=..\..\pa_asio\iasiothiscallresolver.cpp
-CompileCpp=1
-Folder=portaudio
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=
-
diff --git a/portaudio/pa_win/dev-cpp/readme.txt b/portaudio/pa_win/dev-cpp/readme.txt
deleted file mode 100644
index 07108a7dd..000000000
--- a/portaudio/pa_win/dev-cpp/readme.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-From: "Peter L Jones" 
-Sent: Wednesday, September 17, 2003 5:18 AM
-Subject: Dev-C++ project files
-
-I attach two project files intended for portaudio/pa_win/dev-cpp (i.e. in
-parallel with the msvc directory), if you want them.  One is for a static
-library build and one for a DLL.  I've used the static library (in building
-a single monolithic DLL) but I can't guarantee the DLL version will build a
-working library (I think it's mostly there, though!).
-
-I also attach the resulting makefiles, which may be of use to other MinGW
-users.
-
-They're rooted in the directory given above and drop their object and
-library files in the same place.  They assume the asiosdk2 files are in the
-same directory as portaudio/ in a sub-directory called asiosdk2/.  Oh!  The
-DLL is built against a static asiosdk2.a library... maybe not the best way
-to do it...  I ought to figure out how to link against a "home made" dll in
-Dev-C++, I guess ;-)
-
-Cheers,
-
--- Peter
diff --git a/portaudio/pa_win/msvc/CVS/Entries b/portaudio/pa_win/msvc/CVS/Entries
deleted file mode 100644
index a6ddafc01..000000000
--- a/portaudio/pa_win/msvc/CVS/Entries
+++ /dev/null
@@ -1,7 +0,0 @@
-/Makefile.msvc/1.1.2.3/Wed Apr 16 16:16:47 2003//Tv19-devel
-/clean.bat/1.1.2.1/Wed Mar 26 21:49:35 2003//Tv19-devel
-/make.bat/1.1.2.1/Tue Apr  8 19:32:22 2003//Tv19-devel
-/portaudio.def/1.1.2.3/Sun May 15 11:39:26 2005//Tv19-devel
-/readme.txt/1.1.2.3/Wed Apr 16 16:16:47 2003//Tv19-devel
-/setenv.bat/1.1.2.1/Wed Mar 26 21:49:35 2003//Tv19-devel
-D
diff --git a/portaudio/pa_win/msvc/CVS/Repository b/portaudio/pa_win/msvc/CVS/Repository
deleted file mode 100644
index 07681ffee..000000000
--- a/portaudio/pa_win/msvc/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_win/msvc
diff --git a/portaudio/pa_win/msvc/CVS/Root b/portaudio/pa_win/msvc/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_win/msvc/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_win/msvc/CVS/Tag b/portaudio/pa_win/msvc/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_win/msvc/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_win/msvc/Makefile.msvc b/portaudio/pa_win/msvc/Makefile.msvc
deleted file mode 100644
index 2f1a104e7..000000000
--- a/portaudio/pa_win/msvc/Makefile.msvc
+++ /dev/null
@@ -1,159 +0,0 @@
-#  Portaudio v1.9-devel VC6 DLL makefile 1.0
-#  
-#  David Viens, davidv@plogue.com
-#  (im far from a VC6 makefile expert, so please bear with me :)
-#  
-#  For more info, look at readme.txt
-#
-#if you keep the ASIODIR as ".", it will use the SDK files that direclty in "pa_win/msvc" dir
-ASIODIR=.
-ASIOINC=/I ".\host" /I ".\host\pc" /I ".\common" 
-#
-
-LIBZ=kernel32.lib user32.lib gdi32.lib wininet.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib winmm.lib dsound.lib dxguid.lib 
-
-CPP=cl.exe
-LINK32=link.exe 
-
-#release
-CFLAGS=/nologo /MD  /W3 /GX /O2 /Ob2 /I "src" /I "Win32" /I "$(MSVCDir)\Include" /D "WIN32" /D "NDEBUG"  /D "_USRDLL"   /YX /FD
-DLL_LINK_FLAGS= /nologo /dll /incremental:no /libpath:"$(MSVCDir)\Lib" $(LIBZ) /pdb:"portaudio.pdb" /implib:".\portaudio.lib"    /machine:I386 /out:"portaudio.dll" 
-
-
-COMMONINC=/I "..\..\pa_common" /I "."
-
-#====================================================================
-# Targets
-
-ALL : portaudio.dll
-
-CLEAN :
-    -@erase "*.obj"
-
-#====================================================================
-
-
-LINK32_OBJS= \
-	".\pa_allocation.obj" \
-	".\pa_converters.obj" \
-	".\pa_x86_plain_converters.obj" \
-#   ".\pa_cppHelp.obj" \
-	".\pa_cpuload.obj" \
-	".\pa_dither.obj" \
-	".\pa_front.obj" \
-	".\pa_process.obj" \
-	".\pa_skeleton.obj" \
-	".\pa_stream.obj" \
-	".\pa_trace.obj" \
-#
-	".\pa_win_hostapis.obj" \
-	".\pa_win_util.obj" \
-#
-	".\pa_win_wmme.obj" \
-#
-	".\pa_win_ds.obj" \
-	".\dsound_wrapper.obj" \
-#
-	".\pa_asio.obj" \
-#
-	".\asio.obj" \
-	".\ASIOConvertSamples.obj" \
-	".\asiodrivers.obj" \
-	".\asiolist.obj" \
-	".\combase.obj" \
-	".\debugmessage.obj" \
-#	".\dllentry.obj" \
-	".\register.obj" 
-
-
-portaudio.dll : $(LINK32_OBJS) ".\portaudio.def"
-    $(LINK32) $(DLL_LINK_FLAGS) /def:".\portaudio.def" $(LINK32_OBJS)
-
-#====================================================================
-# asio files (need to agree to steinberg agreement)
-# this makefile assumes all files have being copied in the pa_win/msvc dir (for now)
-# see readme.txt for details
-
-".\asio.obj" : ".\common\asio.cpp" 
-    $(CPP) $(CFLAGS) $(ASIOINC) /Fo".\asio.obj" /c ".\common\asio.cpp"
-    
-".\ASIOConvertSamples.obj" : ".\host\ASIOConvertSamples.cpp" 
-    $(CPP) $(CFLAGS) $(ASIOINC) /Fo".\ASIOConvertSamples.obj" /c ".\host\ASIOConvertSamples.cpp"
-    
-".\asiodrivers.obj" : ".\host\asiodrivers.cpp" 
-    $(CPP) $(CFLAGS) $(ASIOINC) /Fo".\asiodrivers.obj" /c ".\host\asiodrivers.cpp"
-    
-".\asiolist.obj" : ".\host\pc\asiolist.cpp" 
-    $(CPP) $(CFLAGS) $(ASIOINC) /Fo".\asiolist.obj" /c ".\host\pc\asiolist.cpp"
-    
-".\combase.obj" : ".\common\combase.cpp" 
-    $(CPP) $(CFLAGS) $(ASIOINC) /Fo".\combase.obj" /c ".\common\combase.cpp"
-    
-".\debugmessage.obj" : ".\common\debugmessage.cpp" 
-    $(CPP) $(CFLAGS) $(ASIOINC) /Fo".\debugmessage.obj" /c ".\common\debugmessage.cpp"
-    
-".\register.obj" : ".\common\register.cpp" 
-    $(CPP) $(CFLAGS) $(ASIOINC) /Fo".\register.obj" /c ".\common\register.cpp"
-
-#====================================================================
-#  Portaudio Common
-# 
-".\pa_allocation.obj" : "..\..\pa_common\pa_allocation.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_allocation.obj" /c "..\..\pa_common\pa_allocation.c"
-
-".\pa_converters.obj" : "..\..\pa_common\pa_converters.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_converters.obj" /c "..\..\pa_common\pa_converters.c"
-
-".\pa_cppHelp.obj" : "..\..\pa_common\pa_cppHelp.cpp" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_cppHelp.obj" /c "..\..\pa_common\pa_cppHelp.cpp"
-
-".\pa_cpuload.obj" : "..\..\pa_common\pa_cpuload.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_cpuload.obj" /c "..\..\pa_common\pa_cpuload.c"
-
-".\pa_dither.obj" : "..\..\pa_common\pa_dither.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_dither.obj" /c "..\..\pa_common\pa_dither.c"
-
-".\pa_front.obj" : "..\..\pa_common\pa_front.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_front.obj" /c "..\..\pa_common\pa_front.c"
-
-".\pa_process.obj" : "..\..\pa_common\pa_process.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_process.obj" /c "..\..\pa_common\pa_process.c"
-
-".\pa_skeleton.obj" : "..\..\pa_common\pa_skeleton.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_skeleton.obj" /c "..\..\pa_common\pa_skeleton.c"
-
-".\pa_stream.obj" : "..\..\pa_common\pa_stream.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_stream.obj" /c "..\..\pa_common\pa_stream.c"
-    
-".\pa_trace.obj" : "..\..\pa_common\pa_trace.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_trace.obj" /c "..\..\pa_common\pa_trace.c"
-
-#====================================================================
-#  Portaudio implementations
-# 
-
-".\pa_win_hostapis.obj" : "..\..\pa_win\pa_win_hostapis.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_win_hostapis.obj" /c "..\..\pa_win\pa_win_hostapis.c"
-    
-".\pa_win_util.obj" : "..\..\pa_win\pa_win_util.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_win_util.obj" /c "..\..\pa_win\pa_win_util.c"
-
-".\pa_x86_plain_converters.obj" : "..\..\pa_win\pa_x86_plain_converters.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_x86_plain_converters.obj" /c "..\..\pa_win\pa_x86_plain_converters.c"
-
-".\pa_asio.obj" : "..\..\pa_asio\pa_asio.cpp" 
-    $(CPP) $(CFLAGS) $(ASIOINC) $(COMMONINC) /Fo".\pa_asio.obj" /c "..\..\pa_asio\pa_asio.cpp"
-
-".\pa_win_wmme.obj" : "..\..\pa_win_wmme\pa_win_wmme.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_win_wmme.obj" /c "..\..\pa_win_wmme\pa_win_wmme.c"
-
-".\pa_win_ds.obj" : "..\..\pa_win_ds\pa_win_ds.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\pa_win_ds.obj" /c "..\..\pa_win_ds\pa_win_ds.c"
-
-".\dsound_wrapper.obj" : "..\..\pa_win_ds\dsound_wrapper.c" 
-    $(CPP) $(CFLAGS) $(COMMONINC) /Fo".\dsound_wrapper.obj" /c "..\..\pa_win_ds\dsound_wrapper.c"
-
-
-# End of Makefile
-#====================================================================
-#
\ No newline at end of file
diff --git a/portaudio/pa_win/msvc/clean.bat b/portaudio/pa_win/msvc/clean.bat
deleted file mode 100755
index 601c0d314..000000000
--- a/portaudio/pa_win/msvc/clean.bat
+++ /dev/null
@@ -1,7 +0,0 @@
-del *.obj
-del *.dll
-del *.lib
-del *.exp
-del *.pch
-del *.idb
-
diff --git a/portaudio/pa_win/msvc/make.bat b/portaudio/pa_win/msvc/make.bat
deleted file mode 100755
index 34d6aed48..000000000
--- a/portaudio/pa_win/msvc/make.bat
+++ /dev/null
@@ -1,8 +0,0 @@
-CALL C:\progra~1\micros~2\VC98\bin\vcvars32
-del *.dll
-del *.lib
-nmake Makefile.msvc
-del *.obj
-del *.exp
-del *.pch
-del *.idb
diff --git a/portaudio/pa_win/msvc/portaudio.def b/portaudio/pa_win/msvc/portaudio.def
deleted file mode 100644
index 97a1c3502..000000000
--- a/portaudio/pa_win/msvc/portaudio.def
+++ /dev/null
@@ -1,43 +0,0 @@
-LIBRARY  portaudio.dll
-EXPORTS
-
-;
-Pa_GetVersion                       @1
-Pa_GetVersionText                   @2
-Pa_GetErrorText                     @3                 
-Pa_Initialize                       @4
-Pa_Terminate                        @5
-Pa_GetHostApiCount                  @6
-Pa_GetDefaultHostApi                @7
-Pa_GetHostApiInfo                   @8
-Pa_HostApiTypeIdToHostApiIndex      @9
-Pa_HostApiDeviceIndexToDeviceIndex  @10
-Pa_GetLastHostErrorInfo             @11
-Pa_GetDeviceCount                   @12
-Pa_GetDefaultInputDevice            @13
-Pa_GetDefaultOutputDevice           @14
-Pa_GetDeviceInfo                    @15
-Pa_IsFormatSupported                @16
-Pa_OpenStream                       @17
-Pa_OpenDefaultStream                @18
-Pa_CloseStream                      @19
-Pa_SetStreamFinishedCallback        @20
-Pa_StartStream                      @21
-Pa_StopStream                       @22
-Pa_AbortStream                      @23
-Pa_IsStreamStopped                  @24
-Pa_IsStreamActive                   @25
-Pa_GetStreamInfo                    @26
-Pa_GetStreamTime                    @27
-Pa_GetStreamCpuLoad                 @28
-Pa_ReadStream                       @29
-Pa_WriteStream                      @30
-Pa_GetStreamReadAvailable           @31
-Pa_GetStreamWriteAvailable          @32
-Pa_GetSampleSize                    @33
-Pa_Sleep                            @34
-PaAsio_GetAvailableLatencyValues    @50
-PaAsio_ShowControlPanel             @51
-PaUtil_InitializeX86PlainConverters @52
-PaAsio_GetInputChannelName          @53
-PaAsio_GetOutputChannelName         @54
\ No newline at end of file
diff --git a/portaudio/pa_win/msvc/readme.txt b/portaudio/pa_win/msvc/readme.txt
deleted file mode 100644
index 19ced4c4c..000000000
--- a/portaudio/pa_win/msvc/readme.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-Hello
-
-  This is a small list of steps in order to build portaudio
-(Currently v19-devel) into a VC6 DLL and lib file.
-This DLL contains all 3 current win32 PA APIS (MM/DS/ASIO)
-
-1)Copy the source dirs that comes with the ASIO SDK inside pa_win\msvc
-  so you should now have:
-  
-  pa_win\msvc\common
-  pa_win\msvc\host
-  pa_win\msvc\host\sample
-  pa_win\msvc\host\pc
-  pa_win\msvc\host\mac (not needed)
-  
-  You dont need "driver"
-  
-
-2)execure "make.bat", this assumes VC6 is installed in 
-     C:\Program Files\Microsoft Visual Studio\
- 
- if its not, 
-  
-  Open a command Prompt and execute "vcvars32.bat" which sets the environment
-  so that you can use Microsoft's "nmake"  
-  EX: C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat
-  or (C:\progra~1\micros~2\VC98\bin\vcvars32) dumb de dumb
-  
-  You should now have seen a line that said:
-  "Setting environment for using Microsoft Visual C++ tools."
-  While in pa_win\msvc , type "nmake makefile.msvc"  
-  this _should_ create portaudio.dll and portaudio.lib 
- 
-3)Now in any VC6 project, in which you require portaudio,
-  you can just link with portaudio.lib, and of course include the 
-  relevant headers
-  (portaudio.h, and/or pa_asio.h , pa_x86_plain_converters.h) See (*)
-  
-4) Your new exe should now use portaudio.dll.
-
-
-Have fun!
-
-(*): you may want to add/remove some DLL entry points.
-Right now those 3 entries are _not_ from portaudio.h
-
-(from portaudio.def)
-(...)
-PaAsio_GetAvailableLatencyValues    @50
-PaAsio_ShowControlPanel             @51
-PaUtil_InitializeX86PlainConverters @52
-
-
------
-last update April 16th 2003
-David Viens, davidv@plogue.com
\ No newline at end of file
diff --git a/portaudio/pa_win/msvc/setenv.bat b/portaudio/pa_win/msvc/setenv.bat
deleted file mode 100755
index f4c815a78..000000000
--- a/portaudio/pa_win/msvc/setenv.bat
+++ /dev/null
@@ -1 +0,0 @@
-C:\progra~1\micros~2\VC98\bin\vcvars32
diff --git a/portaudio/pa_win/pa_win_hostapis.c b/portaudio/pa_win/pa_win_hostapis.c
deleted file mode 100644
index 3db1e18ae..000000000
--- a/portaudio/pa_win/pa_win_hostapis.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * $Id: pa_win_hostapis.c,v 1.1.2.10 2004/09/08 17:31:37 rossbencina Exp $
- * Portable Audio I/O Library Windows initialization table
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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.
- */
-
-/** @file
-    Win32 host API initialization function table.
-
-    @todo Consider using PA_USE_WMME etc instead of PA_NO_WMME. This is what
-    the Unix version does, we should consider being consistent.
-*/
-
-
-#include "pa_hostapi.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-PaUtilHostApiInitializer *paHostApiInitializers[] =
-    {
-
-#ifndef PA_NO_WMME
-        PaWinMme_Initialize,
-#endif
-
-#ifndef PA_NO_DS
-        PaWinDs_Initialize,
-#endif
-
-#ifndef PA_NO_ASIO
-        PaAsio_Initialize,
-#endif
-
-/*
-#ifndef PA_NO_WDMKS
-        PaWinWdm_Initialize,
-#endif
-*/
-
-        PaSkeleton_Initialize, /* just for testing */
-
-        0   /* NULL terminated array */
-    };
-
-
-int paDefaultHostApiIndex = 0;
-
diff --git a/portaudio/pa_win/pa_win_util.c b/portaudio/pa_win/pa_win_util.c
deleted file mode 100644
index 0395e5c84..000000000
--- a/portaudio/pa_win/pa_win_util.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * $Id: pa_win_util.c,v 1.1.2.7 2003/09/15 18:30:26 rossbencina Exp $
- * Portable Audio I/O Library
- * Win32 platform-specific support functions
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2000 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.
- */
-
-/** @file
- Win32 platform-specific support functions.
-
-    @todo Implement workaround for QueryPerformanceCounter() skipping forward
-    bug. (see msdn kb Q274323).
-*/
- 
-#include <windows.h>
-#include <mmsystem.h> /* for timeGetTime() */
-
-#include "pa_util.h"
-
-
-/*
-   Track memory allocations to avoid leaks.
- */
-
-#if PA_TRACK_MEMORY
-static int numAllocations_ = 0;
-#endif
-
-
-void *PaUtil_AllocateMemory( long size )
-{
-    void *result = GlobalAlloc( GPTR, size );
-
-#if PA_TRACK_MEMORY
-    if( result != NULL ) numAllocations_ += 1;
-#endif
-    return result;
-}
-
-
-void PaUtil_FreeMemory( void *block )
-{
-    if( block != NULL )
-    {
-        GlobalFree( block );
-#if PA_TRACK_MEMORY
-        numAllocations_ -= 1;
-#endif
-
-    }
-}
-
-
-int PaUtil_CountCurrentlyAllocatedBlocks( void )
-{
-#if PA_TRACK_MEMORY
-    return numAllocations_;
-#else
-    return 0;
-#endif
-}
-
-
-void Pa_Sleep( long msec )
-{
-    Sleep( msec );
-}
-
-static int usePerformanceCounter_;
-static double secondsPerTick_;
-
-void PaUtil_InitializeClock( void )
-{
-    LARGE_INTEGER ticksPerSecond;
-
-    if( QueryPerformanceFrequency( &ticksPerSecond ) != 0 )
-    {
-        usePerformanceCounter_ = 1;
-        secondsPerTick_ = 1.0 / (double)ticksPerSecond.QuadPart;
-    }
-    else
-    {
-        usePerformanceCounter_ = 0;
-    }
-}
-
-
-double PaUtil_GetTime( void )
-{
-    LARGE_INTEGER time;
-
-    if( usePerformanceCounter_ )
-    {
-        /* FIXME:
-            according to this knowledge-base article, QueryPerformanceCounter
-            can skip forward by seconds!
-            http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323&
-
-            it may be better to use the rtdsc instruction using inline asm,
-            however then a method is needed to calculate a ticks/seconds ratio.
-        */
-        QueryPerformanceCounter( &time );
-        return time.QuadPart * secondsPerTick_;
-    }
-    else
-    {
-        return timeGetTime() * .001;
-    }
-}
diff --git a/portaudio/pa_win/pa_x86_plain_converters.c b/portaudio/pa_win/pa_x86_plain_converters.c
deleted file mode 100644
index 98442a8c6..000000000
--- a/portaudio/pa_win/pa_x86_plain_converters.c
+++ /dev/null
@@ -1,1167 +0,0 @@
-#include "pa_x86_plain_converters.h"
-
-#include "pa_converters.h"
-#include "pa_dither.h"
-
-/*
-    plain intel assemby versions of standard pa converter functions.
-
-    the main reason these versions are faster than the equivalent C versions
-    is that float -> int casting is expensive in C on x86 because the rounding
-    mode needs to be changed for every cast. these versions only set
-    the rounding mode once outside the loop.
-
-    small additional speed gains are made by the way that clamping is
-    implemented.
-
-TODO:
-    o- inline dither code
-    o- implement Dither only (no-clip) versions
-    o- implement int8 and uint8 versions
-    o- test thouroughly
-
-    o- the packed 24 bit functions could benefit from unrolling and avoiding
-        byte and word sized register access.
-*/
-
-/* -------------------------------------------------------------------------- */
-
-/*
-#define PA_CLIP_( val, min, max )\
-    { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); }
-*/
-
-/*
-    the following notes were used to determine whether a floating point
-    value should be saturated (ie >1 or <-1) by loading it into an integer
-    register. these should be rewritten so that they make sense.
-
-    an ieee floating point value
-
-    1.xxxxxxxxxxxxxxxxxxxx?
-
-
-    is less than  or equal to 1 and greater than or equal to -1 either:
-
-        if the mantissa is 0 and the unbiased exponent is 0
-
-        OR
-
-        if the unbiased exponent < 0
-
-    this translates to:
-
-        if the mantissa is 0 and the biased exponent is 7F
-
-        or
-
-        if the biased exponent is less than 7F
-
-
-    therefore the value is greater than 1 or less than -1 if
-
-        the mantissa is not 0 and the biased exponent is 7F
-
-        or
-
-        if the biased exponent is greater than 7F
-
-
-    in other words, if we mask out the sign bit, the value is
-    greater than 1 or less than -1 if its integer representation is greater than:
-
-    0 01111111 0000 0000 0000 0000 0000 000
-
-    0011 1111 1000 0000 0000 0000 0000 0000 => 0x3F800000
-*/
-
-/* -------------------------------------------------------------------------- */
-
-static const short fpuControlWord_ = 0x033F; /*round to nearest, 64 bit precision, all exceptions masked*/
-static const double int32Scaler_ = 0x7FFFFFFF;
-static const double ditheredInt32Scaler_ = 0x7FFFFFFE;
-static const double int24Scaler_ = 0x7FFFFF;
-static const double ditheredInt24Scaler_ = 0x7FFFFE;
-static const double int16Scaler_ = 0x7FFF;
-static const double ditheredInt16Scaler_ = 0x7FFE;
-
-#define PA_DITHER_BITS_   (15)
-/* Multiply by PA_FLOAT_DITHER_SCALE_ to get a float between -2.0 and +1.99999 */
-#define PA_FLOAT_DITHER_SCALE_  (1.0 / ((1<<PA_DITHER_BITS_)-1))
-static const float const_float_dither_scale_ = PA_FLOAT_DITHER_SCALE_;
-#define PA_DITHER_SHIFT_  ((32 - PA_DITHER_BITS_) + 1)
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int32(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-/*
-    float *src = (float*)sourceBuffer;
-    signed long *dest =  (signed long*)destinationBuffer;
-    (void)ditherGenerator; // unused parameter
-
-    while( count-- )
-    {
-        // REVIEW
-        double scaled = *src * 0x7FFFFFFF;
-        *dest = (signed long) scaled;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-*/
-
-    short savedFpuControlWord;
-
-    (void) ditherGenerator; /* unused parameter */
-
-
-    __asm{
-        // esi -> source ptr
-        // eax -> source byte stride
-        // edi -> destination ptr
-        // ebx -> destination byte stride
-        // ecx -> source end ptr
-        // edx -> temp
-
-        mov     esi, sourceBuffer
-
-        mov     edx, 4                  // sizeof float32 and int32
-        mov     eax, sourceStride
-        imul    eax, edx
-
-        mov     ecx, count
-        imul    ecx, eax
-        add     ecx, esi
-    
-        mov     edi, destinationBuffer
-        
-        mov     ebx, destinationStride
-        imul    ebx, edx
-
-        fwait
-        fstcw   savedFpuControlWord
-        fldcw   fpuControlWord_
-
-        fld     int32Scaler_             // stack:  (int)0x7FFFFFFF
-
-    Float32_To_Int32_loop:
-
-        // load unscaled value into st(0)
-        fld     dword ptr [esi]         // stack:  value, (int)0x7FFFFFFF
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*0x7FFFFFFF, (int)0x7FFFFFFF
-        /*
-            note: we could store to a temporary qword here which would cause
-            wraparound distortion instead of int indefinite 0x10. that would
-            be more work, and given that not enabling clipping is only advisable
-            when you know that your signal isn't going to clip it isn't worth it.
-        */
-        fistp   dword ptr [edi]         // pop st(0) into dest, stack:  (int)0x7FFFFFFF
-
-        add     edi, ebx                // increment destination ptr
-        //lea     edi, [edi+ebx]
-
-        cmp     esi, ecx                // has src ptr reached end?
-        jne     Float32_To_Int32_loop
-
-        ffree   st(0)
-        fincstp
-
-        fwait
-        fnclex
-        fldcw   savedFpuControlWord
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int32_Clip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-/*
-    float *src = (float*)sourceBuffer;
-    signed long *dest =  (signed long*)destinationBuffer;
-    (void) ditherGenerator; // unused parameter
-
-    while( count-- )
-    {
-        // REVIEW
-        double scaled = *src * 0x7FFFFFFF;
-        PA_CLIP_( scaled, -2147483648., 2147483647.  );
-        *dest = (signed long) scaled;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-*/
-
-    short savedFpuControlWord;
-
-    (void) ditherGenerator; /* unused parameter */
-
-    __asm{
-        // esi -> source ptr
-        // eax -> source byte stride
-        // edi -> destination ptr
-        // ebx -> destination byte stride
-        // ecx -> source end ptr
-        // edx -> temp
-
-        mov     esi, sourceBuffer
-
-        mov     edx, 4                  // sizeof float32 and int32
-        mov     eax, sourceStride
-        imul    eax, edx
-
-        mov     ecx, count
-        imul    ecx, eax
-        add     ecx, esi
-    
-        mov     edi, destinationBuffer
-        
-        mov     ebx, destinationStride
-        imul    ebx, edx
-
-        fwait
-        fstcw   savedFpuControlWord
-        fldcw   fpuControlWord_
-
-        fld     int32Scaler_             // stack:  (int)0x7FFFFFFF
-
-    Float32_To_Int32_Clip_loop:
-
-        mov     edx, dword ptr [esi]    // load floating point value into integer register
-
-        and     edx, 0x7FFFFFFF         // mask off sign
-        cmp     edx, 0x3F800000         // greater than 1.0 or less than -1.0
-
-        jg      Float32_To_Int32_Clip_clamp
-
-        // load unscaled value into st(0)
-        fld     dword ptr [esi]         // stack:  value, (int)0x7FFFFFFF
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*0x7FFFFFFF, (int)0x7FFFFFFF
-        fistp   dword ptr [edi]         // pop st(0) into dest, stack:  (int)0x7FFFFFFF
-        jmp     Float32_To_Int32_Clip_stored
-    
-    Float32_To_Int32_Clip_clamp:
-        mov     edx, dword ptr [esi]    // load floating point value into integer register
-        shr     edx, 31                 // move sign bit into bit 0
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        add     edx, 0x7FFFFFFF         // convert to maximum range integers
-        mov     dword ptr [edi], edx
-
-    Float32_To_Int32_Clip_stored:
-
-        //add     edi, ebx                // increment destination ptr
-        lea     edi, [edi+ebx]
-
-        cmp     esi, ecx                // has src ptr reached end?
-        jne     Float32_To_Int32_Clip_loop
-
-        ffree   st(0)
-        fincstp
-
-        fwait
-        fnclex
-        fldcw   savedFpuControlWord
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int32_DitherClip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-    /*
-    float *src = (float*)sourceBuffer;
-    signed long *dest =  (signed long*)destinationBuffer;
-
-    while( count-- )
-    {
-        // REVIEW
-        double dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        // use smaller scaler to prevent overflow when we add the dither
-        double dithered = ((double)*src * (2147483646.0)) + dither;
-        PA_CLIP_( dithered, -2147483648., 2147483647.  );
-        *dest = (signed long) dithered;
-
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-    */
-
-    short savedFpuControlWord;
-
-    // spill storage:
-    signed long sourceByteStride;
-    signed long highpassedDither;
-
-    // dither state:
-    unsigned long ditherPrevious = ditherGenerator->previous;
-    unsigned long ditherRandSeed1 = ditherGenerator->randSeed1;
-    unsigned long ditherRandSeed2 = ditherGenerator->randSeed2;
-                    
-    __asm{
-        // esi -> source ptr
-        // eax -> source byte stride
-        // edi -> destination ptr
-        // ebx -> destination byte stride
-        // ecx -> source end ptr
-        // edx -> temp
-
-        mov     esi, sourceBuffer
-
-        mov     edx, 4                  // sizeof float32 and int32
-        mov     eax, sourceStride
-        imul    eax, edx
-
-        mov     ecx, count
-        imul    ecx, eax
-        add     ecx, esi
-    
-        mov     edi, destinationBuffer
-        
-        mov     ebx, destinationStride
-        imul    ebx, edx
-
-        fwait
-        fstcw   savedFpuControlWord
-        fldcw   fpuControlWord_
-
-        fld     ditheredInt32Scaler_    // stack:  int scaler
-
-    Float32_To_Int32_DitherClip_loop:
-
-        mov     edx, dword ptr [esi]    // load floating point value into integer register
-
-        and     edx, 0x7FFFFFFF         // mask off sign
-        cmp     edx, 0x3F800000         // greater than 1.0 or less than -1.0
-
-        jg      Float32_To_Int32_DitherClip_clamp
-
-        // load unscaled value into st(0)
-        fld     dword ptr [esi]         // stack:  value, int scaler
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*(int scaler), int scaler
-
-        /*
-        // call PaUtil_GenerateFloatTriangularDither with C calling convention
-        mov     sourceByteStride, eax   // save eax
-        mov     sourceEnd, ecx          // save ecx
-        push    ditherGenerator         // pass ditherGenerator parameter on stack
-	    call    PaUtil_GenerateFloatTriangularDither  // stack:  dither, value*(int scaler), int scaler
-	    pop     edx                     // clear parameter off stack
-        mov     ecx, sourceEnd          // restore ecx
-        mov     eax, sourceByteStride   // restore eax
-        */
-
-    // generate dither
-        mov     sourceByteStride, eax   // save eax
-        mov     edx, 196314165
-        mov     eax, ditherRandSeed1
-        mul     edx                     // eax:edx = eax * 196314165
-        //add     eax, 907633515
-        lea     eax, [eax+907633515]
-        mov     ditherRandSeed1, eax
-        mov     edx, 196314165
-        mov     eax, ditherRandSeed2
-        mul     edx                     // eax:edx = eax * 196314165
-        //add     eax, 907633515
-        lea     eax, [eax+907633515]
-        mov     edx, ditherRandSeed1
-        shr     edx, PA_DITHER_SHIFT_
-        mov     ditherRandSeed2, eax
-        shr     eax, PA_DITHER_SHIFT_
-        //add     eax, edx                // eax -> current
-        lea     eax, [eax+edx]
-        mov     edx, ditherPrevious
-        neg     edx
-        lea     edx, [eax+edx]          // highpass = current - previous
-        mov     highpassedDither, edx
-        mov     ditherPrevious, eax     // previous = current
-        mov     eax, sourceByteStride   // restore eax
-        fild    highpassedDither
-        fmul    const_float_dither_scale_
-    // end generate dither, dither signal in st(0)
-    
-        faddp   st(1), st(0)            // stack: dither + value*(int scaler), int scaler
-        fistp   dword ptr [edi]         // pop st(0) into dest, stack:  int scaler
-        jmp     Float32_To_Int32_DitherClip_stored
-    
-    Float32_To_Int32_DitherClip_clamp:
-        mov     edx, dword ptr [esi]    // load floating point value into integer register
-        shr     edx, 31                 // move sign bit into bit 0
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        add     edx, 0x7FFFFFFF         // convert to maximum range integers
-        mov     dword ptr [edi], edx
-
-    Float32_To_Int32_DitherClip_stored:
-
-        //add     edi, ebx              // increment destination ptr
-        lea     edi, [edi+ebx]
-
-        cmp     esi, ecx                // has src ptr reached end?
-        jne     Float32_To_Int32_DitherClip_loop
-
-        ffree   st(0)
-        fincstp
-
-        fwait
-        fnclex
-        fldcw   savedFpuControlWord
-    }
-
-    ditherGenerator->previous = ditherPrevious;
-    ditherGenerator->randSeed1 = ditherRandSeed1;
-    ditherGenerator->randSeed2 = ditherRandSeed2;
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int24(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-/*
-    float *src = (float*)sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-    signed long temp;
-
-    (void) ditherGenerator; // unused parameter
-    
-    while( count-- )
-    {
-        // convert to 32 bit and drop the low 8 bits
-        double scaled = *src * 0x7FFFFFFF;
-        temp = (signed long) scaled;
-
-        dest[0] = (unsigned char)(temp >> 8);
-        dest[1] = (unsigned char)(temp >> 16);
-        dest[2] = (unsigned char)(temp >> 24);
-
-        src += sourceStride;
-        dest += destinationStride * 3;
-    }
-*/
-
-    short savedFpuControlWord;
-    
-    signed long tempInt32;
-
-    (void) ditherGenerator; /* unused parameter */
-                 
-    __asm{
-        // esi -> source ptr
-        // eax -> source byte stride
-        // edi -> destination ptr
-        // ebx -> destination byte stride
-        // ecx -> source end ptr
-        // edx -> temp
-
-        mov     esi, sourceBuffer
-
-        mov     edx, 4                  // sizeof float32
-        mov     eax, sourceStride
-        imul    eax, edx
-
-        mov     ecx, count
-        imul    ecx, eax
-        add     ecx, esi
-
-        mov     edi, destinationBuffer
-
-        mov     edx, 3                  // sizeof int24
-        mov     ebx, destinationStride
-        imul    ebx, edx
-
-        fwait
-        fstcw   savedFpuControlWord
-        fldcw   fpuControlWord_
-
-        fld     int24Scaler_             // stack:  (int)0x7FFFFF
-
-    Float32_To_Int24_loop:
-
-        // load unscaled value into st(0)
-        fld     dword ptr [esi]         // stack:  value, (int)0x7FFFFF
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*0x7FFFFF, (int)0x7FFFFF
-        fistp   tempInt32               // pop st(0) into tempInt32, stack:  (int)0x7FFFFF
-        mov     edx, tempInt32
-
-        mov     byte ptr [edi], DL
-        shr     edx, 8
-        //mov     byte ptr [edi+1], DL
-        //mov     byte ptr [edi+2], DH
-        mov     word ptr [edi+1], DX
-
-        //add     edi, ebx                // increment destination ptr
-        lea     edi, [edi+ebx]
-
-        cmp     esi, ecx                // has src ptr reached end?
-        jne     Float32_To_Int24_loop
-
-        ffree   st(0)
-        fincstp
-
-        fwait
-        fnclex
-        fldcw   savedFpuControlWord
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int24_Clip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-/*
-    float *src = (float*)sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-    signed long temp;
-
-    (void) ditherGenerator; // unused parameter
-    
-    while( count-- )
-    {
-        // convert to 32 bit and drop the low 8 bits
-        double scaled = *src * 0x7FFFFFFF;
-        PA_CLIP_( scaled, -2147483648., 2147483647.  );
-        temp = (signed long) scaled;
-
-        dest[0] = (unsigned char)(temp >> 8);
-        dest[1] = (unsigned char)(temp >> 16);
-        dest[2] = (unsigned char)(temp >> 24);
-
-        src += sourceStride;
-        dest += destinationStride * 3;
-    }
-*/
-
-    short savedFpuControlWord;
-    
-    signed long tempInt32;
-
-    (void) ditherGenerator; /* unused parameter */
-                 
-    __asm{
-        // esi -> source ptr
-        // eax -> source byte stride
-        // edi -> destination ptr
-        // ebx -> destination byte stride
-        // ecx -> source end ptr
-        // edx -> temp
-
-        mov     esi, sourceBuffer
-
-        mov     edx, 4                  // sizeof float32
-        mov     eax, sourceStride
-        imul    eax, edx
-
-        mov     ecx, count
-        imul    ecx, eax
-        add     ecx, esi
-
-        mov     edi, destinationBuffer
-
-        mov     edx, 3                  // sizeof int24
-        mov     ebx, destinationStride
-        imul    ebx, edx
-
-        fwait
-        fstcw   savedFpuControlWord
-        fldcw   fpuControlWord_
-
-        fld     int24Scaler_             // stack:  (int)0x7FFFFF
-
-    Float32_To_Int24_Clip_loop:
-
-        mov     edx, dword ptr [esi]    // load floating point value into integer register
-
-        and     edx, 0x7FFFFFFF         // mask off sign
-        cmp     edx, 0x3F800000         // greater than 1.0 or less than -1.0
-
-        jg      Float32_To_Int24_Clip_clamp
-
-        // load unscaled value into st(0)
-        fld     dword ptr [esi]         // stack:  value, (int)0x7FFFFF
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*0x7FFFFF, (int)0x7FFFFF
-        fistp   tempInt32               // pop st(0) into tempInt32, stack:  (int)0x7FFFFF
-        mov     edx, tempInt32
-        jmp     Float32_To_Int24_Clip_store
-    
-    Float32_To_Int24_Clip_clamp:
-        mov     edx, dword ptr [esi]    // load floating point value into integer register
-        shr     edx, 31                 // move sign bit into bit 0
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        add     edx, 0x7FFFFF           // convert to maximum range integers
-
-    Float32_To_Int24_Clip_store:
-
-        mov     byte ptr [edi], DL
-        shr     edx, 8
-        //mov     byte ptr [edi+1], DL
-        //mov     byte ptr [edi+2], DH
-        mov     word ptr [edi+1], DX
-
-        //add     edi, ebx                // increment destination ptr
-        lea     edi, [edi+ebx]
-
-        cmp     esi, ecx                // has src ptr reached end?
-        jne     Float32_To_Int24_Clip_loop
-
-        ffree   st(0)
-        fincstp
-
-        fwait
-        fnclex
-        fldcw   savedFpuControlWord
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int24_DitherClip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-/*
-    float *src = (float*)sourceBuffer;
-    unsigned char *dest = (unsigned char*)destinationBuffer;
-    signed long temp;
-    
-    while( count-- )
-    {
-        // convert to 32 bit and drop the low 8 bits
-
-        // FIXME: the dither amplitude here appears to be too small by 8 bits
-        double dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        // use smaller scaler to prevent overflow when we add the dither
-        double dithered = ((double)*src * (2147483646.0)) + dither;
-        PA_CLIP_( dithered, -2147483648., 2147483647.  );
-        
-        temp = (signed long) dithered;
-
-        dest[0] = (unsigned char)(temp >> 8);
-        dest[1] = (unsigned char)(temp >> 16);
-        dest[2] = (unsigned char)(temp >> 24);
-
-        src += sourceStride;
-        dest += destinationStride * 3;
-    }
-*/
-
-    short savedFpuControlWord;
-
-    // spill storage:
-    signed long sourceByteStride;
-    signed long highpassedDither;
-
-    // dither state:
-    unsigned long ditherPrevious = ditherGenerator->previous;
-    unsigned long ditherRandSeed1 = ditherGenerator->randSeed1;
-    unsigned long ditherRandSeed2 = ditherGenerator->randSeed2;
-    
-    signed long tempInt32;
-                 
-    __asm{
-        // esi -> source ptr
-        // eax -> source byte stride
-        // edi -> destination ptr
-        // ebx -> destination byte stride
-        // ecx -> source end ptr
-        // edx -> temp
-
-        mov     esi, sourceBuffer
-
-        mov     edx, 4                  // sizeof float32
-        mov     eax, sourceStride
-        imul    eax, edx
-
-        mov     ecx, count
-        imul    ecx, eax
-        add     ecx, esi
-
-        mov     edi, destinationBuffer
-
-        mov     edx, 3                  // sizeof int24
-        mov     ebx, destinationStride
-        imul    ebx, edx
-
-        fwait
-        fstcw   savedFpuControlWord
-        fldcw   fpuControlWord_
-
-        fld     ditheredInt24Scaler_    // stack:  int scaler
-
-    Float32_To_Int24_DitherClip_loop:
-
-        mov     edx, dword ptr [esi]    // load floating point value into integer register
-
-        and     edx, 0x7FFFFFFF         // mask off sign
-        cmp     edx, 0x3F800000         // greater than 1.0 or less than -1.0
-
-        jg      Float32_To_Int24_DitherClip_clamp
-
-        // load unscaled value into st(0)
-        fld     dword ptr [esi]         // stack:  value, int scaler
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*(int scaler), int scaler
-
-    /*
-        // call PaUtil_GenerateFloatTriangularDither with C calling convention
-        mov     sourceByteStride, eax   // save eax
-        mov     sourceEnd, ecx          // save ecx
-        push    ditherGenerator         // pass ditherGenerator parameter on stack
-	    call    PaUtil_GenerateFloatTriangularDither  // stack:  dither, value*(int scaler), int scaler
-	    pop     edx                     // clear parameter off stack
-        mov     ecx, sourceEnd          // restore ecx
-        mov     eax, sourceByteStride   // restore eax
-    */
-    
-    // generate dither
-        mov     sourceByteStride, eax   // save eax
-        mov     edx, 196314165
-        mov     eax, ditherRandSeed1
-        mul     edx                     // eax:edx = eax * 196314165
-        //add     eax, 907633515
-        lea     eax, [eax+907633515]
-        mov     ditherRandSeed1, eax
-        mov     edx, 196314165
-        mov     eax, ditherRandSeed2
-        mul     edx                     // eax:edx = eax * 196314165
-        //add     eax, 907633515
-        lea     eax, [eax+907633515]
-        mov     edx, ditherRandSeed1
-        shr     edx, PA_DITHER_SHIFT_
-        mov     ditherRandSeed2, eax
-        shr     eax, PA_DITHER_SHIFT_
-        //add     eax, edx                // eax -> current
-        lea     eax, [eax+edx]
-        mov     edx, ditherPrevious
-        neg     edx
-        lea     edx, [eax+edx]          // highpass = current - previous
-        mov     highpassedDither, edx
-        mov     ditherPrevious, eax     // previous = current
-        mov     eax, sourceByteStride   // restore eax
-        fild    highpassedDither
-        fmul    const_float_dither_scale_
-    // end generate dither, dither signal in st(0)
-
-        faddp   st(1), st(0)            // stack: dither * value*(int scaler), int scaler
-        fistp   tempInt32               // pop st(0) into tempInt32, stack:  int scaler
-        mov     edx, tempInt32
-        jmp     Float32_To_Int24_DitherClip_store
-    
-    Float32_To_Int24_DitherClip_clamp:
-        mov     edx, dword ptr [esi]    // load floating point value into integer register
-        shr     edx, 31                 // move sign bit into bit 0
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        add     edx, 0x7FFFFF           // convert to maximum range integers
-
-    Float32_To_Int24_DitherClip_store:
-
-        mov     byte ptr [edi], DL
-        shr     edx, 8
-        //mov     byte ptr [edi+1], DL
-        //mov     byte ptr [edi+2], DH
-        mov     word ptr [edi+1], DX
-
-        //add     edi, ebx                // increment destination ptr
-        lea     edi, [edi+ebx]
-
-        cmp     esi, ecx                // has src ptr reached end?
-        jne     Float32_To_Int24_DitherClip_loop
-
-        ffree   st(0)
-        fincstp
-
-        fwait
-        fnclex
-        fldcw   savedFpuControlWord
-    }
-
-    ditherGenerator->previous = ditherPrevious;
-    ditherGenerator->randSeed1 = ditherRandSeed1;
-    ditherGenerator->randSeed2 = ditherRandSeed2;
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int16(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-/*
-    float *src = (float*)sourceBuffer;
-    signed short *dest =  (signed short*)destinationBuffer;
-    (void)ditherGenerator; // unused parameter
-
-    while( count-- )
-    {
-
-        short samp = (short) (*src * (32767.0f));
-        *dest = samp;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-*/
-
-    short savedFpuControlWord;
-   
-    (void) ditherGenerator; /* unused parameter */
-
-    __asm{
-        // esi -> source ptr
-        // eax -> source byte stride
-        // edi -> destination ptr
-        // ebx -> destination byte stride
-        // ecx -> source end ptr
-        // edx -> temp
-
-        mov     esi, sourceBuffer
-
-        mov     edx, 4                  // sizeof float32
-        mov     eax, sourceStride
-        imul    eax, edx                // source byte stride
-
-        mov     ecx, count
-        imul    ecx, eax
-        add     ecx, esi                // source end ptr = count * source byte stride + source ptr
-
-        mov     edi, destinationBuffer
-
-        mov     edx, 2                  // sizeof int16
-        mov     ebx, destinationStride
-        imul    ebx, edx                // destination byte stride
-
-        fwait
-        fstcw   savedFpuControlWord
-        fldcw   fpuControlWord_
-
-        fld     int16Scaler_            // stack:  (int)0x7FFF
-
-    Float32_To_Int16_loop:
-
-        // load unscaled value into st(0)
-        fld     dword ptr [esi]         // stack:  value, (int)0x7FFF
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*0x7FFF, (int)0x7FFF
-        fistp   word ptr [edi]          // store scaled int into dest, stack:  (int)0x7FFF
-
-        add     edi, ebx                // increment destination ptr
-        //lea     edi, [edi+ebx]
-        
-        cmp     esi, ecx                // has src ptr reached end?
-        jne     Float32_To_Int16_loop
-
-        ffree   st(0)
-        fincstp
-
-        fwait
-        fnclex
-        fldcw   savedFpuControlWord
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int16_Clip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-/*
-    float *src = (float*)sourceBuffer;
-    signed short *dest =  (signed short*)destinationBuffer;
-    (void)ditherGenerator; // unused parameter
-
-    while( count-- )
-    {
-        long samp = (signed long) (*src * (32767.0f));
-        PA_CLIP_( samp, -0x8000, 0x7FFF );
-        *dest = (signed short) samp;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-*/
-
-    short savedFpuControlWord;
-   
-    (void) ditherGenerator; /* unused parameter */
-
-    __asm{
-        // esi -> source ptr
-        // eax -> source byte stride
-        // edi -> destination ptr
-        // ebx -> destination byte stride
-        // ecx -> source end ptr
-        // edx -> temp
-
-        mov     esi, sourceBuffer
-
-        mov     edx, 4                  // sizeof float32
-        mov     eax, sourceStride
-        imul    eax, edx                // source byte stride
-
-        mov     ecx, count
-        imul    ecx, eax
-        add     ecx, esi                // source end ptr = count * source byte stride + source ptr
-
-        mov     edi, destinationBuffer
-
-        mov     edx, 2                  // sizeof int16
-        mov     ebx, destinationStride
-        imul    ebx, edx                // destination byte stride
-
-        fwait
-        fstcw   savedFpuControlWord
-        fldcw   fpuControlWord_
-
-        fld     int16Scaler_            // stack:  (int)0x7FFF
-
-    Float32_To_Int16_Clip_loop:
-
-        mov     edx, dword ptr [esi]    // load floating point value into integer register
-
-        and     edx, 0x7FFFFFFF         // mask off sign
-        cmp     edx, 0x3F800000         // greater than 1.0 or less than -1.0
-
-        jg      Float32_To_Int16_Clip_clamp
-
-        // load unscaled value into st(0)
-        fld     dword ptr [esi]         // stack:  value, (int)0x7FFF
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*0x7FFF, (int)0x7FFF
-        fistp   word ptr [edi]          // store scaled int into dest, stack:  (int)0x7FFF
-        jmp     Float32_To_Int16_Clip_stored
-    
-    Float32_To_Int16_Clip_clamp:
-        mov     edx, dword ptr [esi]    // load floating point value into integer register
-        shr     edx, 31                 // move sign bit into bit 0
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        add     dx, 0x7FFF              // convert to maximum range integers
-        mov     word ptr [edi], dx      // store clamped into into dest
-
-    Float32_To_Int16_Clip_stored:
-
-        add     edi, ebx                // increment destination ptr
-        //lea     edi, [edi+ebx]
-        
-        cmp     esi, ecx                // has src ptr reached end?
-        jne     Float32_To_Int16_Clip_loop
-
-        ffree   st(0)
-        fincstp
-
-        fwait
-        fnclex
-        fldcw   savedFpuControlWord
-    }
-}
-
-/* -------------------------------------------------------------------------- */
-
-static void Float32_To_Int16_DitherClip(
-    void *destinationBuffer, signed int destinationStride,
-    void *sourceBuffer, signed int sourceStride,
-    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
-{
-/*
-    float *src = (float*)sourceBuffer;
-    signed short *dest =  (signed short*)destinationBuffer;
-    (void)ditherGenerator; // unused parameter
-
-    while( count-- )
-    {
-
-        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
-        // use smaller scaler to prevent overflow when we add the dither 
-        float dithered = (*src * (32766.0f)) + dither;
-        signed long samp = (signed long) dithered;
-        PA_CLIP_( samp, -0x8000, 0x7FFF );
-        *dest = (signed short) samp;
-
-        src += sourceStride;
-        dest += destinationStride;
-    }
-*/
-
-    short savedFpuControlWord;
-
-    // spill storage:
-    signed long sourceByteStride;
-    signed long highpassedDither;
-
-    // dither state:
-    unsigned long ditherPrevious = ditherGenerator->previous;
-    unsigned long ditherRandSeed1 = ditherGenerator->randSeed1;
-    unsigned long ditherRandSeed2 = ditherGenerator->randSeed2;
-
-    __asm{
-        // esi -> source ptr
-        // eax -> source byte stride
-        // edi -> destination ptr
-        // ebx -> destination byte stride
-        // ecx -> source end ptr
-        // edx -> temp
-
-        mov     esi, sourceBuffer
-
-        mov     edx, 4                  // sizeof float32
-        mov     eax, sourceStride
-        imul    eax, edx                // source byte stride
-
-        mov     ecx, count
-        imul    ecx, eax
-        add     ecx, esi                // source end ptr = count * source byte stride + source ptr
-
-        mov     edi, destinationBuffer
-
-        mov     edx, 2                  // sizeof int16
-        mov     ebx, destinationStride
-        imul    ebx, edx                // destination byte stride
-
-        fwait
-        fstcw   savedFpuControlWord
-        fldcw   fpuControlWord_
-
-        fld     ditheredInt16Scaler_    // stack:  int scaler
-
-    Float32_To_Int16_DitherClip_loop:
-
-        mov     edx, dword ptr [esi]    // load floating point value into integer register
-
-        and     edx, 0x7FFFFFFF         // mask off sign
-        cmp     edx, 0x3F800000         // greater than 1.0 or less than -1.0
-
-        jg      Float32_To_Int16_DitherClip_clamp
-
-        // load unscaled value into st(0)
-        fld     dword ptr [esi]         // stack:  value, int scaler
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*(int scaler), int scaler
-
-        /*
-        // call PaUtil_GenerateFloatTriangularDither with C calling convention
-        mov     sourceByteStride, eax   // save eax
-        mov     sourceEnd, ecx          // save ecx
-        push    ditherGenerator         // pass ditherGenerator parameter on stack
-	    call    PaUtil_GenerateFloatTriangularDither  // stack:  dither, value*(int scaler), int scaler
-	    pop     edx                     // clear parameter off stack
-        mov     ecx, sourceEnd          // restore ecx
-        mov     eax, sourceByteStride   // restore eax
-        */
-
-    // generate dither
-        mov     sourceByteStride, eax   // save eax
-        mov     edx, 196314165
-        mov     eax, ditherRandSeed1
-        mul     edx                     // eax:edx = eax * 196314165
-        //add     eax, 907633515
-        lea     eax, [eax+907633515]
-        mov     ditherRandSeed1, eax
-        mov     edx, 196314165
-        mov     eax, ditherRandSeed2
-        mul     edx                     // eax:edx = eax * 196314165
-        //add     eax, 907633515
-        lea     eax, [eax+907633515]
-        mov     edx, ditherRandSeed1
-        shr     edx, PA_DITHER_SHIFT_
-        mov     ditherRandSeed2, eax
-        shr     eax, PA_DITHER_SHIFT_
-        //add     eax, edx                // eax -> current
-        lea     eax, [eax+edx]            // current = randSeed1>>x + randSeed2>>x
-        mov     edx, ditherPrevious
-        neg     edx
-        lea     edx, [eax+edx]          // highpass = current - previous
-        mov     highpassedDither, edx
-        mov     ditherPrevious, eax     // previous = current
-        mov     eax, sourceByteStride   // restore eax
-        fild    highpassedDither
-        fmul    const_float_dither_scale_
-    // end generate dither, dither signal in st(0)
-        
-        faddp   st(1), st(0)            // stack: dither * value*(int scaler), int scaler
-        fistp   word ptr [edi]          // store scaled int into dest, stack:  int scaler
-        jmp     Float32_To_Int16_DitherClip_stored
-    
-    Float32_To_Int16_DitherClip_clamp:
-        mov     edx, dword ptr [esi]    // load floating point value into integer register
-        shr     edx, 31                 // move sign bit into bit 0
-        add     esi, eax                // increment source ptr
-        //lea     esi, [esi+eax]
-        add     dx, 0x7FFF              // convert to maximum range integers
-        mov     word ptr [edi], dx      // store clamped into into dest
-
-    Float32_To_Int16_DitherClip_stored:
-
-        add     edi, ebx                // increment destination ptr
-        //lea     edi, [edi+ebx]
-        
-        cmp     esi, ecx                // has src ptr reached end?
-        jne     Float32_To_Int16_DitherClip_loop
-
-        ffree   st(0)
-        fincstp
-
-        fwait
-        fnclex
-        fldcw   savedFpuControlWord
-    }
-
-    ditherGenerator->previous = ditherPrevious;
-    ditherGenerator->randSeed1 = ditherRandSeed1;
-    ditherGenerator->randSeed2 = ditherRandSeed2;
-}
-
-/* -------------------------------------------------------------------------- */
-
-void PaUtil_InitializeX86PlainConverters( void )
-{
-    paConverters.Float32_To_Int32 = Float32_To_Int32;
-    paConverters.Float32_To_Int32_Clip = Float32_To_Int32_Clip;
-    paConverters.Float32_To_Int32_DitherClip = Float32_To_Int32_DitherClip;
-
-    paConverters.Float32_To_Int24 = Float32_To_Int24;
-    paConverters.Float32_To_Int24_Clip = Float32_To_Int24_Clip;
-    paConverters.Float32_To_Int24_DitherClip = Float32_To_Int24_DitherClip;
-    
-    paConverters.Float32_To_Int16 = Float32_To_Int16;
-    paConverters.Float32_To_Int16_Clip = Float32_To_Int16_Clip;
-    paConverters.Float32_To_Int16_DitherClip = Float32_To_Int16_DitherClip;
-}
-
-/* -------------------------------------------------------------------------- */
diff --git a/portaudio/pa_win/pa_x86_plain_converters.h b/portaudio/pa_win/pa_x86_plain_converters.h
deleted file mode 100644
index f56c710fd..000000000
--- a/portaudio/pa_win/pa_x86_plain_converters.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef PA_X86_PLAIN_CONVERTERS_H
-#define PA_X86_PLAIN_CONVERTERS_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-/**
- @brief Install optimised converter functions suitable for all IA32 processors
-*/
-void PaUtil_InitializeX86PlainConverters( void );
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PA_X86_PLAIN_CONVERTERS_H */
diff --git a/portaudio/pa_win_ds/CVS/Entries b/portaudio/pa_win_ds/CVS/Entries
deleted file mode 100644
index 57e06c1aa..000000000
--- a/portaudio/pa_win_ds/CVS/Entries
+++ /dev/null
@@ -1,4 +0,0 @@
-/dsound_wrapper.c/1.1.1.1.2.11/Sun Sep  7 13:04:53 2003//Tv19-devel
-/dsound_wrapper.h/1.1.1.1.2.8/Sun Jan 16 20:48:37 2005//Tv19-devel
-/pa_win_ds.c/1.1.2.51/Thu Jan 26 01:13:18 2006//Tv19-devel
-D
diff --git a/portaudio/pa_win_ds/CVS/Repository b/portaudio/pa_win_ds/CVS/Repository
deleted file mode 100644
index cf1b05e7f..000000000
--- a/portaudio/pa_win_ds/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_win_ds
diff --git a/portaudio/pa_win_ds/CVS/Root b/portaudio/pa_win_ds/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_win_ds/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_win_ds/CVS/Tag b/portaudio/pa_win_ds/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_win_ds/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_win_ds/dsound_wrapper.c b/portaudio/pa_win_ds/dsound_wrapper.c
deleted file mode 100644
index 207d28734..000000000
--- a/portaudio/pa_win_ds/dsound_wrapper.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
- * $Id: dsound_wrapper.c,v 1.1.1.1.2.11 2003/09/07 13:04:53 rossbencina Exp $
- * Simplified DirectSound interface.
- *
- * Author: Phil Burk & Robert Marsanyi
- *
- * PortAudio Portable Real-Time Audio Library
- * For more information see: http://www.softsynth.com/portaudio/
- * DirectSound Implementation
- * Copyright (c) 1999-2000 Phil Burk & Robert Marsanyi
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include "dsound_wrapper.h"
-#include "pa_trace.h"
-
-/*
-    Rather than linking with dxguid.a or using "#define INITGUID" to force a
-    header file to instantiate the required GUID(s), we define them directly
-    below.
-*/
-#include <initguid.h> // needed for the DEFINE_GUID macro
-DEFINE_GUID(IID_IDirectSoundNotify, 0xb0210783, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16);
-
-
-/************************************************************************************/
-DSoundEntryPoints dswDSoundEntryPoints = { 0, 0, 0, 0, 0, 0, 0 };
-/************************************************************************************/
-static HRESULT WINAPI DummyDirectSoundCreate(LPGUID lpcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter)
-{
-    (void)lpcGuidDevice; /* unused parameter */
-    (void)ppDS; /* unused parameter */
-    (void)pUnkOuter; /* unused parameter */
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI DummyDirectSoundEnumerateW(LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext)
-{
-    (void)lpDSEnumCallback; /* unused parameter */
-    (void)lpContext; /* unused parameter */
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI DummyDirectSoundEnumerateA(LPDSENUMCALLBACKA lpDSEnumCallback, LPVOID lpContext)
-{
-    (void)lpDSEnumCallback; /* unused parameter */
-    (void)lpContext; /* unused parameter */
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI DummyDirectSoundCaptureCreate(LPGUID lpcGUID, LPDIRECTSOUNDCAPTURE *lplpDSC, LPUNKNOWN pUnkOuter)
-{
-    (void)lpcGUID; /* unused parameter */
-    (void)lplpDSC; /* unused parameter */
-    (void)pUnkOuter; /* unused parameter */
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI DummyDirectSoundCaptureEnumerateW(LPDSENUMCALLBACKW lpDSCEnumCallback, LPVOID lpContext)
-{
-    (void)lpDSCEnumCallback; /* unused parameter */
-    (void)lpContext; /* unused parameter */
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI DummyDirectSoundCaptureEnumerateA(LPDSENUMCALLBACKA lpDSCEnumCallback, LPVOID lpContext)
-{
-    (void)lpDSCEnumCallback; /* unused parameter */
-    (void)lpContext; /* unused parameter */
-    return E_NOTIMPL;
-}
-/************************************************************************************/
-void DSW_InitializeDSoundEntryPoints(void)
-{
-    dswDSoundEntryPoints.hInstance_ = LoadLibrary("dsound.dll");
-    if( dswDSoundEntryPoints.hInstance_ != NULL )
-    {
-        dswDSoundEntryPoints.DirectSoundCreate =
-                (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN))
-                GetProcAddress( dswDSoundEntryPoints.hInstance_, "DirectSoundCreate" );
-        if( dswDSoundEntryPoints.DirectSoundCreate == NULL )
-            dswDSoundEntryPoints.DirectSoundCreate = DummyDirectSoundCreate;
-
-        dswDSoundEntryPoints.DirectSoundEnumerateW =
-                (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID))
-                GetProcAddress( dswDSoundEntryPoints.hInstance_, "DirectSoundEnumerateW" );
-        if( dswDSoundEntryPoints.DirectSoundEnumerateW == NULL )
-            dswDSoundEntryPoints.DirectSoundEnumerateW = DummyDirectSoundEnumerateW;
-
-        dswDSoundEntryPoints.DirectSoundEnumerateA =
-                (HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID))
-                GetProcAddress( dswDSoundEntryPoints.hInstance_, "DirectSoundEnumerateA" );
-        if( dswDSoundEntryPoints.DirectSoundEnumerateA == NULL )
-            dswDSoundEntryPoints.DirectSoundEnumerateA = DummyDirectSoundEnumerateA;
-
-        dswDSoundEntryPoints.DirectSoundCaptureCreate =
-                (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN))
-                GetProcAddress( dswDSoundEntryPoints.hInstance_, "DirectSoundCaptureCreate" );
-        if( dswDSoundEntryPoints.DirectSoundCaptureCreate == NULL )
-            dswDSoundEntryPoints.DirectSoundCaptureCreate = DummyDirectSoundCaptureCreate;
-
-        dswDSoundEntryPoints.DirectSoundCaptureEnumerateW =
-                (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID))
-                GetProcAddress( dswDSoundEntryPoints.hInstance_, "DirectSoundCaptureEnumerateW" );
-        if( dswDSoundEntryPoints.DirectSoundCaptureEnumerateW == NULL )
-            dswDSoundEntryPoints.DirectSoundCaptureEnumerateW = DummyDirectSoundCaptureEnumerateW;
-
-        dswDSoundEntryPoints.DirectSoundCaptureEnumerateA =
-                (HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID))
-                GetProcAddress( dswDSoundEntryPoints.hInstance_, "DirectSoundCaptureEnumerateA" );
-        if( dswDSoundEntryPoints.DirectSoundCaptureEnumerateA == NULL )
-            dswDSoundEntryPoints.DirectSoundCaptureEnumerateA = DummyDirectSoundCaptureEnumerateA;
-    }
-    else
-    {
-        /* initialize with dummy entry points to make live easy when ds isn't present */
-        dswDSoundEntryPoints.DirectSoundCreate = DummyDirectSoundCreate;
-        dswDSoundEntryPoints.DirectSoundEnumerateW = DummyDirectSoundEnumerateW;
-        dswDSoundEntryPoints.DirectSoundEnumerateA = DummyDirectSoundEnumerateA;
-        dswDSoundEntryPoints.DirectSoundCaptureCreate = DummyDirectSoundCaptureCreate;
-        dswDSoundEntryPoints.DirectSoundCaptureEnumerateW = DummyDirectSoundCaptureEnumerateW;
-        dswDSoundEntryPoints.DirectSoundCaptureEnumerateA = DummyDirectSoundCaptureEnumerateA;
-    }
-}
-/************************************************************************************/
-void DSW_TerminateDSoundEntryPoints(void)
-{
-    if( dswDSoundEntryPoints.hInstance_ != NULL )
-    {
-        FreeLibrary( dswDSoundEntryPoints.hInstance_ );
-        dswDSoundEntryPoints.hInstance_ = NULL;
-        /* ensure that we crash reliably if the entry points arent initialised */
-        dswDSoundEntryPoints.DirectSoundCreate = 0;
-        dswDSoundEntryPoints.DirectSoundEnumerateW = 0;
-        dswDSoundEntryPoints.DirectSoundEnumerateA = 0;
-        dswDSoundEntryPoints.DirectSoundCaptureCreate = 0;
-        dswDSoundEntryPoints.DirectSoundCaptureEnumerateW = 0;
-        dswDSoundEntryPoints.DirectSoundCaptureEnumerateA = 0;
-    }
-}
-/************************************************************************************/
-void DSW_Term( DSoundWrapper *dsw )
-{
-    // Cleanup the sound buffers
-    if (dsw->dsw_OutputBuffer)
-    {
-        IDirectSoundBuffer_Stop( dsw->dsw_OutputBuffer );
-        IDirectSoundBuffer_Release( dsw->dsw_OutputBuffer );
-        dsw->dsw_OutputBuffer = NULL;
-    }
-
-    if (dsw->dsw_InputBuffer)
-    {
-        IDirectSoundCaptureBuffer_Stop( dsw->dsw_InputBuffer );
-        IDirectSoundCaptureBuffer_Release( dsw->dsw_InputBuffer );
-        dsw->dsw_InputBuffer = NULL;
-    }
-
-    if (dsw->dsw_pDirectSoundCapture)
-    {
-        IDirectSoundCapture_Release( dsw->dsw_pDirectSoundCapture );
-        dsw->dsw_pDirectSoundCapture = NULL;
-    }
-
-    if (dsw->dsw_pDirectSound)
-    {
-        IDirectSound_Release( dsw->dsw_pDirectSound );
-        dsw->dsw_pDirectSound = NULL;
-    }
-}
-/************************************************************************************/
-HRESULT DSW_Init( DSoundWrapper *dsw )
-{
-    memset( dsw, 0, sizeof(DSoundWrapper) );
-    return 0;
-}
-/************************************************************************************/
-HRESULT DSW_InitOutputDevice( DSoundWrapper *dsw, LPGUID lpGUID )
-{
-    // Create the DS object
-    HRESULT hr = dswDSoundEntryPoints.DirectSoundCreate( lpGUID, &dsw->dsw_pDirectSound, NULL );
-    if( hr != DS_OK ) return hr;
-    return hr;
-}
-
-/************************************************************************************/
-HRESULT DSW_InitOutputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate, WORD nChannels, int bytesPerBuffer )
-{
-    DWORD          dwDataLen;
-    DWORD          playCursor;
-    HRESULT        result;
-    LPDIRECTSOUNDBUFFER pPrimaryBuffer;
-    HWND           hWnd;
-    HRESULT        hr;
-    WAVEFORMATEX   wfFormat;
-    DSBUFFERDESC   primaryDesc;
-    DSBUFFERDESC   secondaryDesc;
-    unsigned char* pDSBuffData;
-    LARGE_INTEGER  counterFrequency;
-
-    dsw->dsw_OutputSize = bytesPerBuffer;
-    dsw->dsw_OutputRunning = FALSE;
-    dsw->dsw_OutputUnderflows = 0;
-    dsw->dsw_FramesWritten = 0;
-    dsw->dsw_BytesPerOutputFrame = nChannels * sizeof(short);
-
-    // We were using getForegroundWindow() but sometimes the ForegroundWindow may not be the
-    // applications's window. Also if that window is closed before the Buffer is closed
-    // then DirectSound can crash. (Thanks for Scott Patterson for reporting this.)
-    // So we will use GetDesktopWindow() which was suggested by Miller Puckette.
-    // hWnd = GetForegroundWindow();
-    //
-    //  FIXME: The example code I have on the net creates a hidden window that
-    //      is managed by our code - I think we should do that - one hidden
-    //      window for the whole of Pa_DS
-    //
-    hWnd = GetDesktopWindow();
-
-    // Set cooperative level to DSSCL_EXCLUSIVE so that we can get 16 bit output, 44.1 KHz.
-    // Exclusize also prevents unexpected sounds from other apps during a performance.
-    if ((hr = IDirectSound_SetCooperativeLevel( dsw->dsw_pDirectSound,
-              hWnd, DSSCL_EXCLUSIVE)) != DS_OK)
-    {
-        return hr;
-    }
-
-    // -----------------------------------------------------------------------
-    // Create primary buffer and set format just so we can specify our custom format.
-    // Otherwise we would be stuck with the default which might be 8 bit or 22050 Hz.
-    // Setup the primary buffer description
-    ZeroMemory(&primaryDesc, sizeof(DSBUFFERDESC));
-    primaryDesc.dwSize        = sizeof(DSBUFFERDESC);
-    primaryDesc.dwFlags       = DSBCAPS_PRIMARYBUFFER; // all panning, mixing, etc done by synth
-    primaryDesc.dwBufferBytes = 0;
-    primaryDesc.lpwfxFormat   = NULL;
-    // Create the buffer
-    if ((result = IDirectSound_CreateSoundBuffer( dsw->dsw_pDirectSound,
-                  &primaryDesc, &pPrimaryBuffer, NULL)) != DS_OK) return result;
-    // Define the buffer format
-    wfFormat.wFormatTag = WAVE_FORMAT_PCM;
-    wfFormat.nChannels = nChannels;
-    wfFormat.nSamplesPerSec = nFrameRate;
-    wfFormat.wBitsPerSample = 8 * sizeof(short);
-    wfFormat.nBlockAlign = (WORD)(wfFormat.nChannels * (wfFormat.wBitsPerSample / 8));
-    wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
-    wfFormat.cbSize = 0;  /* No extended format info. */
-    // Set the primary buffer's format
-    if((result = IDirectSoundBuffer_SetFormat( pPrimaryBuffer, &wfFormat)) != DS_OK) return result;
-
-    // ----------------------------------------------------------------------
-    // Setup the secondary buffer description
-    ZeroMemory(&secondaryDesc, sizeof(DSBUFFERDESC));
-    secondaryDesc.dwSize = sizeof(DSBUFFERDESC);
-    secondaryDesc.dwFlags =  DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;
-    secondaryDesc.dwBufferBytes = bytesPerBuffer;
-    secondaryDesc.lpwfxFormat = &wfFormat;
-    // Create the secondary buffer
-    if ((result = IDirectSound_CreateSoundBuffer( dsw->dsw_pDirectSound,
-                  &secondaryDesc, &dsw->dsw_OutputBuffer, NULL)) != DS_OK) return result;
-    // Lock the DS buffer
-    if ((result = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, 0, dsw->dsw_OutputSize, (LPVOID*)&pDSBuffData,
-                                           &dwDataLen, NULL, 0, 0)) != DS_OK) return result;
-    // Zero the DS buffer
-    ZeroMemory(pDSBuffData, dwDataLen);
-    // Unlock the DS buffer
-    if ((result = IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) return result;
-    if( QueryPerformanceFrequency( &counterFrequency ) )
-    {
-        int framesInBuffer = bytesPerBuffer / (nChannels * sizeof(short));
-        dsw->dsw_CounterTicksPerBuffer.QuadPart = (counterFrequency.QuadPart * framesInBuffer) / nFrameRate;
-    }
-    else
-    {
-        dsw->dsw_CounterTicksPerBuffer.QuadPart = 0;
-    }
-    // Let DSound set the starting write position because if we set it to zero, it looks like the
-    // buffer is full to begin with. This causes a long pause before sound starts when using large buffers.
-    hr = IDirectSoundBuffer_GetCurrentPosition( dsw->dsw_OutputBuffer, &playCursor, &dsw->dsw_WriteOffset );
-    if( hr != DS_OK )
-    {
-        return hr;
-    }
-    dsw->dsw_FramesWritten = dsw->dsw_WriteOffset / dsw->dsw_BytesPerOutputFrame;
-    /* printf("DSW_InitOutputBuffer: playCursor = %d, writeCursor = %d\n", playCursor, dsw->dsw_WriteOffset ); */
-    return DS_OK;
-}
-
-/************************************************************************************/
-HRESULT DSW_StartOutput( DSoundWrapper *dsw )
-{
-    HRESULT        hr;
-    QueryPerformanceCounter( &dsw->dsw_LastPlayTime );
-    dsw->dsw_LastPlayCursor = 0;
-    dsw->dsw_FramesPlayed = 0;
-    hr = IDirectSoundBuffer_SetCurrentPosition( dsw->dsw_OutputBuffer, 0 );
-    if( hr != DS_OK )
-    {
-        return hr;
-    }
-    // Start the buffer playback in a loop.
-    if( dsw->dsw_OutputBuffer != NULL )
-    {
-        hr = IDirectSoundBuffer_Play( dsw->dsw_OutputBuffer, 0, 0, DSBPLAY_LOOPING );
-        if( hr != DS_OK )
-        {
-            return hr;
-        }
-        dsw->dsw_OutputRunning = TRUE;
-    }
-
-    return 0;
-}
-/************************************************************************************/
-HRESULT DSW_StopOutput( DSoundWrapper *dsw )
-{
-    // Stop the buffer playback
-    if( dsw->dsw_OutputBuffer != NULL )
-    {
-        dsw->dsw_OutputRunning = FALSE;
-        return IDirectSoundBuffer_Stop( dsw->dsw_OutputBuffer );
-    }
-    else return 0;
-}
-
-/************************************************************************************/
-HRESULT DSW_QueryOutputFilled( DSoundWrapper *dsw, long *bytesFilledPtr )
-{
-    HRESULT hr;
-    DWORD   playCursor;
-    DWORD   writeCursor;
-    long    bytesFilled;
-    // Query to see where play position is.
-    // We don't need the writeCursor but sometimes DirectSound doesn't handle NULLS correctly
-    // so let's pass a pointer just to be safe.
-    hr = IDirectSoundBuffer_GetCurrentPosition( dsw->dsw_OutputBuffer, &playCursor, &writeCursor );
-    if( hr != DS_OK )
-    {
-        return hr;
-    }
-    bytesFilled = dsw->dsw_WriteOffset - playCursor;
-    if( bytesFilled < 0 ) bytesFilled += dsw->dsw_OutputSize; // unwrap offset
-    *bytesFilledPtr = bytesFilled;
-    return hr;
-}
-
-/************************************************************************************
- * Determine how much space can be safely written to in DS buffer.
- * Detect underflows and overflows.
- * Does not allow writing into safety gap maintained by DirectSound.
- */
-HRESULT DSW_QueryOutputSpace( DSoundWrapper *dsw, long *bytesEmpty )
-{
-    HRESULT hr;
-    DWORD   playCursor;
-    DWORD   writeCursor;
-    long    numBytesEmpty;
-    long    playWriteGap;
-    // Query to see how much room is in buffer.
-    hr = IDirectSoundBuffer_GetCurrentPosition( dsw->dsw_OutputBuffer, &playCursor, &writeCursor );
-    if( hr != DS_OK )
-    {
-        return hr;
-    }
-    // Determine size of gap between playIndex and WriteIndex that we cannot write into.
-    playWriteGap = writeCursor - playCursor;
-    if( playWriteGap < 0 ) playWriteGap += dsw->dsw_OutputSize; // unwrap
-    /* DirectSound doesn't have a large enough playCursor so we cannot detect wrap-around. */
-    /* Attempt to detect playCursor wrap-around and correct it. */
-    if( dsw->dsw_OutputRunning && (dsw->dsw_CounterTicksPerBuffer.QuadPart != 0) )
-    {
-        /* How much time has elapsed since last check. */
-        LARGE_INTEGER   currentTime;
-        LARGE_INTEGER   elapsedTime;
-        long            bytesPlayed;
-        long            bytesExpected;
-        long            buffersWrapped;
-        QueryPerformanceCounter( &currentTime );
-        elapsedTime.QuadPart = currentTime.QuadPart - dsw->dsw_LastPlayTime.QuadPart;
-        dsw->dsw_LastPlayTime = currentTime;
-        /* How many bytes does DirectSound say have been played. */
-        bytesPlayed = playCursor - dsw->dsw_LastPlayCursor;
-        if( bytesPlayed < 0 ) bytesPlayed += dsw->dsw_OutputSize; // unwrap
-        dsw->dsw_LastPlayCursor = playCursor;
-        /* Calculate how many bytes we would have expected to been played by now. */
-        bytesExpected = (long) ((elapsedTime.QuadPart * dsw->dsw_OutputSize) / dsw->dsw_CounterTicksPerBuffer.QuadPart);
-        buffersWrapped = (bytesExpected - bytesPlayed) / dsw->dsw_OutputSize;
-        if( buffersWrapped > 0 )
-        {
-            playCursor += (buffersWrapped * dsw->dsw_OutputSize);
-            bytesPlayed += (buffersWrapped * dsw->dsw_OutputSize);
-        }
-        /* Maintain frame output cursor. */
-        dsw->dsw_FramesPlayed += (bytesPlayed / dsw->dsw_BytesPerOutputFrame);
-    }
-    numBytesEmpty = playCursor - dsw->dsw_WriteOffset;
-    if( numBytesEmpty < 0 ) numBytesEmpty += dsw->dsw_OutputSize; // unwrap offset
-    /* Have we underflowed? */
-    if( numBytesEmpty > (dsw->dsw_OutputSize - playWriteGap) )
-    {
-        if( dsw->dsw_OutputRunning )
-        {
-            dsw->dsw_OutputUnderflows += 1;
-        }
-        dsw->dsw_WriteOffset = writeCursor;
-        numBytesEmpty = dsw->dsw_OutputSize - playWriteGap;
-    }
-    *bytesEmpty = numBytesEmpty;
-    return hr;
-}
-
-/************************************************************************************/
-HRESULT DSW_ZeroEmptySpace( DSoundWrapper *dsw )
-{
-    HRESULT hr;
-    LPBYTE lpbuf1 = NULL;
-    LPBYTE lpbuf2 = NULL;
-    DWORD dwsize1 = 0;
-    DWORD dwsize2 = 0;
-    long  bytesEmpty;
-    hr = DSW_QueryOutputSpace( dsw, &bytesEmpty ); // updates dsw_FramesPlayed
-    if (hr != DS_OK) return hr;
-    if( bytesEmpty == 0 ) return DS_OK;
-    // Lock free space in the DS
-    hr = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, dsw->dsw_WriteOffset, bytesEmpty, (void **) &lpbuf1, &dwsize1,
-                                  (void **) &lpbuf2, &dwsize2, 0);
-    if (hr == DS_OK)
-    {
-        // Copy the buffer into the DS
-        ZeroMemory(lpbuf1, dwsize1);
-        if(lpbuf2 != NULL)
-        {
-            ZeroMemory(lpbuf2, dwsize2);
-        }
-        // Update our buffer offset and unlock sound buffer
-        dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + dwsize1 + dwsize2) % dsw->dsw_OutputSize;
-        IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
-        dsw->dsw_FramesWritten += bytesEmpty / dsw->dsw_BytesPerOutputFrame;
-    }
-    return hr;
-}
-
-/************************************************************************************/
-HRESULT DSW_WriteBlock( DSoundWrapper *dsw, char *buf, long numBytes )
-{
-    HRESULT hr;
-    LPBYTE lpbuf1 = NULL;
-    LPBYTE lpbuf2 = NULL;
-    DWORD dwsize1 = 0;
-    DWORD dwsize2 = 0;
-    // Lock free space in the DS
-    hr = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, dsw->dsw_WriteOffset, numBytes, (void **) &lpbuf1, &dwsize1,
-                                  (void **) &lpbuf2, &dwsize2, 0);
-    if (hr == DS_OK)
-    {
-        // Copy the buffer into the DS
-        CopyMemory(lpbuf1, buf, dwsize1);
-        if(lpbuf2 != NULL)
-        {
-            CopyMemory(lpbuf2, buf+dwsize1, dwsize2);
-        }
-        // Update our buffer offset and unlock sound buffer
-        dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + dwsize1 + dwsize2) % dsw->dsw_OutputSize;
-        IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
-        dsw->dsw_FramesWritten += numBytes / dsw->dsw_BytesPerOutputFrame;
-    }
-    return hr;
-}
-
-/************************************************************************************/
-DWORD DSW_GetOutputStatus( DSoundWrapper *dsw )
-{
-    DWORD status;
-    if (IDirectSoundBuffer_GetStatus( dsw->dsw_OutputBuffer, &status ) != DS_OK)
-        return( DSERR_INVALIDPARAM );
-    else
-        return( status );
-}
-
-/* These routines are used to support audio input.
- * Do NOT compile these calls when using NT4 because it does
- * not support the entry points.
- */
-/************************************************************************************/
-HRESULT DSW_InitInputDevice( DSoundWrapper *dsw, LPGUID lpGUID )
-{
-    HRESULT hr = dswDSoundEntryPoints.DirectSoundCaptureCreate(  lpGUID, &dsw->dsw_pDirectSoundCapture,   NULL );
-    if( hr != DS_OK ) return hr;
-    return hr;
-}
-/************************************************************************************/
-HRESULT DSW_InitInputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate, WORD nChannels, int bytesPerBuffer )
-{
-    DSCBUFFERDESC  captureDesc;
-    WAVEFORMATEX   wfFormat;
-    HRESULT        result;
-    
-    dsw->dsw_BytesPerInputFrame = nChannels * sizeof(short);
-
-    // Define the buffer format
-    wfFormat.wFormatTag      = WAVE_FORMAT_PCM;
-    wfFormat.nChannels       = nChannels;
-    wfFormat.nSamplesPerSec  = nFrameRate;
-    wfFormat.wBitsPerSample  = 8 * sizeof(short);
-    wfFormat.nBlockAlign     = (WORD)(wfFormat.nChannels * (wfFormat.wBitsPerSample / 8));
-    wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
-    wfFormat.cbSize          = 0;   /* No extended format info. */
-    dsw->dsw_InputSize = bytesPerBuffer;
-    // ----------------------------------------------------------------------
-    // Setup the secondary buffer description
-    ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC));
-    captureDesc.dwSize = sizeof(DSCBUFFERDESC);
-    captureDesc.dwFlags =  0;
-    captureDesc.dwBufferBytes = bytesPerBuffer;
-    captureDesc.lpwfxFormat = &wfFormat;
-    // Create the capture buffer
-    if ((result = IDirectSoundCapture_CreateCaptureBuffer( dsw->dsw_pDirectSoundCapture,
-                  &captureDesc, &dsw->dsw_InputBuffer, NULL)) != DS_OK) return result;
-    dsw->dsw_ReadOffset = 0;  // reset last read position to start of buffer
-    return DS_OK;
-}
-
-/************************************************************************************/
-HRESULT DSW_StartInput( DSoundWrapper *dsw )
-{
-    // Start the buffer playback
-    if( dsw->dsw_InputBuffer != NULL )
-    {
-        return IDirectSoundCaptureBuffer_Start( dsw->dsw_InputBuffer, DSCBSTART_LOOPING );
-    }
-    else return 0;
-}
-
-/************************************************************************************/
-HRESULT DSW_StopInput( DSoundWrapper *dsw )
-{
-    // Stop the buffer playback
-    if( dsw->dsw_InputBuffer != NULL )
-    {
-        return IDirectSoundCaptureBuffer_Stop( dsw->dsw_InputBuffer );
-    }
-    else return 0;
-}
-
-/************************************************************************************/
-HRESULT DSW_QueryInputFilled( DSoundWrapper *dsw, long *bytesFilled )
-{
-    HRESULT hr;
-    DWORD capturePos;
-    DWORD readPos;
-    long  filled;
-    // Query to see how much data is in buffer.
-    // We don't need the capture position but sometimes DirectSound doesn't handle NULLS correctly
-    // so let's pass a pointer just to be safe.
-    hr = IDirectSoundCaptureBuffer_GetCurrentPosition( dsw->dsw_InputBuffer, &capturePos, &readPos );
-    if( hr != DS_OK )
-    {
-        return hr;
-    }
-    filled = readPos - dsw->dsw_ReadOffset;
-    if( filled < 0 ) filled += dsw->dsw_InputSize; // unwrap offset
-    *bytesFilled = filled;
-    return hr;
-}
-
-/************************************************************************************/
-HRESULT DSW_ReadBlock( DSoundWrapper *dsw, char *buf, long numBytes )
-{
-    HRESULT hr;
-    LPBYTE lpbuf1 = NULL;
-    LPBYTE lpbuf2 = NULL;
-    DWORD dwsize1 = 0;
-    DWORD dwsize2 = 0;
-    // Lock free space in the DS
-    hr = IDirectSoundCaptureBuffer_Lock ( dsw->dsw_InputBuffer, dsw->dsw_ReadOffset, numBytes, (void **) &lpbuf1, &dwsize1,
-                                          (void **) &lpbuf2, &dwsize2, 0);
-    if (hr == DS_OK)
-    {
-        // Copy from DS to the buffer
-        CopyMemory( buf, lpbuf1, dwsize1);
-        if(lpbuf2 != NULL)
-        {
-            CopyMemory( buf+dwsize1, lpbuf2, dwsize2);
-        }
-        // Update our buffer offset and unlock sound buffer
-        dsw->dsw_ReadOffset = (dsw->dsw_ReadOffset + dwsize1 + dwsize2) % dsw->dsw_InputSize;
-        IDirectSoundCaptureBuffer_Unlock ( dsw->dsw_InputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
-    }
-    return hr;
-}
-
diff --git a/portaudio/pa_win_ds/dsound_wrapper.h b/portaudio/pa_win_ds/dsound_wrapper.h
deleted file mode 100644
index 9e3f565f2..000000000
--- a/portaudio/pa_win_ds/dsound_wrapper.h
+++ /dev/null
@@ -1,130 +0,0 @@
-#ifndef __DSOUND_WRAPPER_H
-#define __DSOUND_WRAPPER_H
-/*
- * $Id: dsound_wrapper.h,v 1.1.1.1.2.8 2005/01/16 20:48:37 rossbencina Exp $
- * Simplified DirectSound interface.
- *
- * Author: Phil Burk & Robert Marsanyi
- *
- * For PortAudio Portable Real-Time Audio Library
- * For more information see: http://www.softsynth.com/portaudio/
- * DirectSound Implementation
- * Copyright (c) 1999-2000 Phil Burk & Robert Marsanyi
- *
- * 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.
- *
- */
-
-/* on Borland compilers, WIN32 doesn't seem to be defined by default, which
-    breaks DSound.h. Adding the define here fixes the problem. - rossb. */
-#ifdef __BORLANDC__
-#if !defined(WIN32)
-#define WIN32
-#endif
-#endif
-
-/*
-  We are only using DX3 in here, no need to polute the namespace - davidv
-*/
-#define DIRECTSOUND_VERSION 0x0300
-
-#include <DSound.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-typedef struct
-{
-    HINSTANCE hInstance_;
-    
-    HRESULT (WINAPI *DirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
-    HRESULT (WINAPI *DirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
-    HRESULT (WINAPI *DirectSoundEnumerateA)(LPDSENUMCALLBACKA, LPVOID);
-
-    HRESULT (WINAPI *DirectSoundCaptureCreate)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN);
-    HRESULT (WINAPI *DirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
-    HRESULT (WINAPI *DirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA, LPVOID);
-}DSoundEntryPoints;
-
-extern DSoundEntryPoints dswDSoundEntryPoints;
-
-void DSW_InitializeDSoundEntryPoints(void);
-void DSW_TerminateDSoundEntryPoints(void);
-
-#define DSW_NUM_POSITIONS     (4)
-#define DSW_NUM_EVENTS        (5)
-#define DSW_TERMINATION_EVENT     (DSW_NUM_POSITIONS)
-
-typedef struct
-{
-/* Output */
-    LPDIRECTSOUND        dsw_pDirectSound;
-    LPDIRECTSOUNDBUFFER  dsw_OutputBuffer;
-    DWORD                dsw_WriteOffset;     /* last write position */
-    INT                  dsw_OutputSize;
-    INT                  dsw_BytesPerOutputFrame;
-    /* Try to detect play buffer underflows. */
-    LARGE_INTEGER        dsw_CounterTicksPerBuffer; /* counter ticks it should take to play a full buffer */
-    LARGE_INTEGER        dsw_LastPlayTime;
-    UINT                 dsw_LastPlayCursor;
-    UINT                 dsw_OutputUnderflows;
-    BOOL                 dsw_OutputRunning;
-    /* use double which lets us can play for several thousand years with enough precision */
-    double               dsw_FramesWritten;
-    double               dsw_FramesPlayed;
-/* Input */
-    INT                  dsw_BytesPerInputFrame;
-    LPDIRECTSOUNDCAPTURE dsw_pDirectSoundCapture;
-    LPDIRECTSOUNDCAPTUREBUFFER   dsw_InputBuffer;
-    UINT                 dsw_ReadOffset;      /* last read position */
-    UINT                 dsw_InputSize;
-} DSoundWrapper;
-
-HRESULT DSW_Init( DSoundWrapper *dsw );
-void DSW_Term( DSoundWrapper *dsw );
-HRESULT DSW_InitOutputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate,
-                              WORD nChannels, int bufSize );
-HRESULT DSW_StartOutput( DSoundWrapper *dsw );
-HRESULT DSW_StopOutput( DSoundWrapper *dsw );
-DWORD   DSW_GetOutputStatus( DSoundWrapper *dsw );
-HRESULT DSW_WriteBlock( DSoundWrapper *dsw, char *buf, long numBytes );
-HRESULT DSW_ZeroEmptySpace( DSoundWrapper *dsw );
-HRESULT DSW_QueryOutputSpace( DSoundWrapper *dsw, long *bytesEmpty );
-HRESULT DSW_Enumerate( DSoundWrapper *dsw );
-
-HRESULT DSW_InitInputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate,
-                             WORD nChannels, int bufSize );
-HRESULT DSW_StartInput( DSoundWrapper *dsw );
-HRESULT DSW_StopInput( DSoundWrapper *dsw );
-HRESULT DSW_ReadBlock( DSoundWrapper *dsw, char *buf, long numBytes );
-HRESULT DSW_QueryInputFilled( DSoundWrapper *dsw, long *bytesFilled );
-HRESULT DSW_QueryOutputFilled( DSoundWrapper *dsw, long *bytesFilled );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif  /* __DSOUND_WRAPPER_H */
diff --git a/portaudio/pa_win_ds/pa_win_ds.c b/portaudio/pa_win_ds/pa_win_ds.c
deleted file mode 100644
index ef9709066..000000000
--- a/portaudio/pa_win_ds/pa_win_ds.c
+++ /dev/null
@@ -1,1864 +0,0 @@
-/*
- * $Id: pa_win_ds.c,v 1.1.2.51 2006/01/26 01:13:18 rossbencina Exp $
- * Portable Audio I/O Library DirectSound implementation
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, 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.
- */
-
-/** @file
-
-    @todo implement paInputOverflow callback status flag
-    
-    @todo implement paNeverDropInput.
-
-    @todo implement host api specific extension to set i/o buffer sizes in frames
-
-    @todo implement initialisation of PaDeviceInfo default*Latency fields (currently set to 0.)
-
-    @todo implement ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable
-
-    @todo audit handling of DirectSound result codes - in many cases we could convert a HRESULT into
-        a native portaudio error code. Standard DirectSound result codes are documented at msdn.
-
-    @todo implement IsFormatSupported
-
-    @todo check that CoInitialize() CoUninitialize() are always correctly
-        paired, even in error cases.
-
-    @todo call PaUtil_SetLastHostErrorInfo with a specific error string (currently just "DSound error").
-
-    @todo make sure all buffers have been played before stopping the stream
-        when the stream callback returns paComplete
-
-    old TODOs from phil, need to work out if these have been done:
-        O- fix "patest_stop.c"
-*/
-
-#include <stdio.h>
-#include <string.h> /* strlen() */
-
-#include "pa_util.h"
-#include "pa_allocation.h"
-#include "pa_hostapi.h"
-#include "pa_stream.h"
-#include "pa_cpuload.h"
-#include "pa_process.h"
-
-#include "dsound_wrapper.h"
-
-#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
-#pragma comment( lib, "dsound.lib" )
-#pragma comment( lib, "winmm.lib" )
-#endif
-
-/*
- provided in newer platform sdks and x64
- */
-#ifndef DWORD_PTR
-#define DWORD_PTR DWORD
-#endif
-
-#define PRINT(x) PA_DEBUG(x);
-#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)
-#define PA_WIN_NT_LATENCY     (600)
-#else
-#define PA_WIN_9X_LATENCY     (140)
-#define PA_WIN_NT_LATENCY     (280)
-#endif
-
-#define PA_WIN_WDM_LATENCY       (120)
-
-#define SECONDS_PER_MSEC      (0.001)
-#define MSEC_PER_SECOND       (1000)
-
-/* prototypes for functions declared in this file */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData );
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate );
-static PaError CloseStream( PaStream* stream );
-static PaError StartStream( PaStream *stream );
-static PaError StopStream( PaStream *stream );
-static PaError AbortStream( PaStream *stream );
-static PaError IsStreamStopped( PaStream *s );
-static PaError IsStreamActive( PaStream *stream );
-static PaTime GetStreamTime( PaStream *stream );
-static double GetStreamCpuLoad( PaStream* stream );
-static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
-static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
-static signed long GetStreamReadAvailable( PaStream* stream );
-static signed long GetStreamWriteAvailable( PaStream* stream );
-
-
-/* FIXME: should convert hr to a string */
-#define PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ) \
-    PaUtil_SetLastHostErrorInfo( paDirectSound, hr, "DirectSound error" )
-
-/************************************************* DX Prototypes **********/
-static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID,
-                                     LPCTSTR lpszDesc,
-                                     LPCTSTR lpszDrvName,
-                                     LPVOID lpContext );
-
-/************************************************************************************/
-/********************** Structures **************************************************/
-/************************************************************************************/
-/* PaWinDsHostApiRepresentation - host api datastructure specific to this implementation */
-
-typedef struct PaWinDsDeviceInfo
-{
-    GUID                             guid;
-    GUID                            *lpGUID;
-    double                           sampleRates[3];
-} PaWinDsDeviceInfo;
-
-typedef struct
-{
-    PaUtilHostApiRepresentation inheritedHostApiRep;
-    PaUtilStreamInterface    callbackStreamInterface;
-    PaUtilStreamInterface    blockingStreamInterface;
-
-    PaUtilAllocationGroup   *allocations;
-
-    /* implementation specific data goes here */
-    PaWinDsDeviceInfo       *winDsDeviceInfos;
-
-} PaWinDsHostApiRepresentation;
-
-/* PaWinDsStream - a stream data structure specifically for this implementation */
-
-typedef struct PaWinDsStream
-{
-    PaUtilStreamRepresentation streamRepresentation;
-    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
-    PaUtilBufferProcessor bufferProcessor;
-
-/* DirectSound specific data. */
-    DSoundWrapper    directSoundWrapper;
-    MMRESULT         timerID;
-    BOOL             ifInsideCallback;  /* Test for reentrancy. */
-    int              framesPerDSBuffer;
-    double           framesWritten;
-    double           secondsPerHostByte; /* Used to optimize latency calculation for outTime */
-
-    PaStreamCallbackFlags callbackFlags;
-    
-/* FIXME - move all below to PaUtilStreamRepresentation */
-    volatile int     isStarted;
-    volatile int     isActive;
-    volatile int     stopProcessing; /* stop thread once existing buffers have been returned */
-    volatile int     abortProcessing; /* stop thread immediately */
-} PaWinDsStream;
-
-
-/************************************************************************************
-** Duplicate the input string using the allocations allocator.
-** A NULL string is converted to a zero length string.
-** If memory cannot be allocated, NULL is returned.
-**/
-static char *DuplicateDeviceNameString( PaUtilAllocationGroup *allocations, const char* src )
-{
-    char *result = 0;
-    
-    if( src != NULL )
-    {
-        size_t len = strlen(src);
-        result = (char*)PaUtil_GroupAllocateMemory( allocations, (long)(len + 1) );
-        if( result )
-            memcpy( (void *) result, src, len+1 );
-    }
-    else
-    {
-        result = (char*)PaUtil_GroupAllocateMemory( allocations, 1 );
-        if( result )
-            result[0] = '\0';
-    }
-
-    return result;
-}
-
-/************************************************************************************
-** DSDeviceNameAndGUID, DSDeviceNameAndGUIDVector used for collecting preliminary
-** information during device enumeration.
-*/
-typedef struct DSDeviceNameAndGUID{
-    char *name; // allocated from parent's allocations, never deleted by this structure
-    GUID guid;
-    LPGUID lpGUID;
-} DSDeviceNameAndGUID;
-
-typedef struct DSDeviceNameAndGUIDVector{
-    PaUtilAllocationGroup *allocations;
-    PaError enumerationError;
-
-    int count;
-    int free;
-    DSDeviceNameAndGUID *items; // Allocated using LocalAlloc()
-} DSDeviceNameAndGUIDVector;
-
-static PaError InitializeDSDeviceNameAndGUIDVector(
-        DSDeviceNameAndGUIDVector *guidVector, PaUtilAllocationGroup *allocations )
-{
-    PaError result = paNoError;
-
-    guidVector->allocations = allocations;
-    guidVector->enumerationError = paNoError;
-
-    guidVector->count = 0;
-    guidVector->free = 8;
-    guidVector->items = (DSDeviceNameAndGUID*)LocalAlloc( LMEM_FIXED, sizeof(DSDeviceNameAndGUID) * guidVector->free );
-    if( guidVector->items == NULL )
-        result = paInsufficientMemory;
-    
-    return result;
-}
-
-static PaError ExpandDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidVector )
-{
-    PaError result = paNoError;
-    DSDeviceNameAndGUID *newItems;
-    int i;
-    
-    /* double size of vector */
-    int size = guidVector->count + guidVector->free;
-    guidVector->free += size;
-
-    newItems = (DSDeviceNameAndGUID*)LocalAlloc( LMEM_FIXED, sizeof(DSDeviceNameAndGUID) * size * 2 );
-    if( newItems == NULL )
-    {
-        result = paInsufficientMemory;
-    }
-    else
-    {
-        for( i=0; i < guidVector->count; ++i )
-        {
-            newItems[i].name = guidVector->items[i].name;
-            if( guidVector->items[i].lpGUID == NULL )
-            {
-                newItems[i].lpGUID = NULL;
-            }
-            else
-            {
-                newItems[i].lpGUID = &newItems[i].guid;
-                memcpy( &newItems[i].guid, guidVector->items[i].lpGUID, sizeof(GUID) );;
-            }
-        }
-
-        LocalFree( guidVector->items );
-        guidVector->items = newItems;
-    }                                
-
-    return result;
-}
-
-/*
-    it's safe to call DSDeviceNameAndGUIDVector multiple times
-*/
-static PaError TerminateDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidVector )
-{
-    PaError result = paNoError;
-
-    if( guidVector->items != NULL )
-    {
-        if( LocalFree( guidVector->items ) != NULL )
-            result = paInsufficientMemory;              /** @todo this isn't the correct error to return from a deallocation failure */
-
-        guidVector->items = NULL;
-    }
-
-    return result;
-}
-
-/************************************************************************************
-** Collect preliminary device information during DirectSound enumeration 
-*/
-static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID,
-                                     LPCTSTR lpszDesc,
-                                     LPCTSTR lpszDrvName,
-                                     LPVOID lpContext )
-{
-    DSDeviceNameAndGUIDVector *namesAndGUIDs = (DSDeviceNameAndGUIDVector*)lpContext;
-    PaError error;
-
-    (void) lpszDrvName; /* unused variable */
-
-    if( namesAndGUIDs->free == 0 )
-    {
-        error = ExpandDSDeviceNameAndGUIDVector( namesAndGUIDs );
-        if( error != paNoError )
-        {
-            namesAndGUIDs->enumerationError = error;
-            return FALSE;
-        }
-    }
-    
-    /* Set GUID pointer, copy GUID to storage in DSDeviceNameAndGUIDVector. */
-    if( lpGUID == NULL )
-    {
-        namesAndGUIDs->items[namesAndGUIDs->count].lpGUID = NULL;
-    }
-    else
-    {
-        namesAndGUIDs->items[namesAndGUIDs->count].lpGUID =
-                &namesAndGUIDs->items[namesAndGUIDs->count].guid;
-      
-        memcpy( &namesAndGUIDs->items[namesAndGUIDs->count].guid, lpGUID, sizeof(GUID) );
-    }
-
-    namesAndGUIDs->items[namesAndGUIDs->count].name =
-            DuplicateDeviceNameString( namesAndGUIDs->allocations, lpszDesc );
-    if( namesAndGUIDs->items[namesAndGUIDs->count].name == NULL )
-    {
-        namesAndGUIDs->enumerationError = paInsufficientMemory;
-        return FALSE;
-    }
-
-    ++namesAndGUIDs->count;
-    --namesAndGUIDs->free;
-    
-    return TRUE;
-}
-
-
-/* 
-    GUIDs for emulated devices which we blacklist below.
-    are there more than two of them??
-*/
-
-GUID IID_IRolandVSCEmulated1 = {0xc2ad1800, 0xb243, 0x11ce, 0xa8, 0xa4, 0x00, 0xaa, 0x00, 0x6c, 0x45, 0x01};
-GUID IID_IRolandVSCEmulated2 = {0xc2ad1800, 0xb243, 0x11ce, 0xa8, 0xa4, 0x00, 0xaa, 0x00, 0x6c, 0x45, 0x02};
-
-
-#define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_  (13) /* must match array length below */
-static double defaultSampleRateSearchOrder_[] =
-    { 44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0,
-        16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };
-
-
-/************************************************************************************
-** Extract capabilities from an output device, and add it to the device info list
-** if successful. This function assumes that there is enough room in the
-** device info list to accomodate all entries.
-**
-** The device will not be added to the device list if any errors are encountered.
-*/
-static PaError AddOutputDeviceInfoFromDirectSound(
-        PaWinDsHostApiRepresentation *winDsHostApi, char *name, LPGUID lpGUID )
-{
-    PaUtilHostApiRepresentation  *hostApi = &winDsHostApi->inheritedHostApiRep;
-    PaDeviceInfo                 *deviceInfo = hostApi->deviceInfos[hostApi->info.deviceCount];
-    PaWinDsDeviceInfo            *winDsDeviceInfo = &winDsHostApi->winDsDeviceInfos[hostApi->info.deviceCount];
-    HRESULT                       hr;
-    LPDIRECTSOUND                 lpDirectSound;
-    DSCAPS                        caps;
-    int                           deviceOK = TRUE;
-    PaError                       result = paNoError;
-    int                           i;
-    
-    /* Copy GUID to the device info structure. Set pointer. */
-    if( lpGUID == NULL )
-    {
-        winDsDeviceInfo->lpGUID = NULL;
-    }
-    else
-    {
-        memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) );
-        winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid;
-    }
-
-    
-    if( lpGUID )
-    {
-        if (IsEqualGUID (&IID_IRolandVSCEmulated1,lpGUID) ||
-            IsEqualGUID (&IID_IRolandVSCEmulated2,lpGUID) )
-        {
-            PA_DEBUG(("BLACKLISTED: %s \n",name));
-            return paNoError;
-        }
-    }
-
-    /* Create a DirectSound object for the specified GUID
-        Note that using CoCreateInstance doesn't work on windows CE.
-    */
-    hr = dswDSoundEntryPoints.DirectSoundCreate( lpGUID, &lpDirectSound, NULL );
-
-    /** try using CoCreateInstance because DirectSoundCreate was hanging under
-        some circumstances - note this was probably related to the
-        #define BOOL short bug which has now been fixed
-        @todo delete this comment and the following code once we've ensured
-        there is no bug.
-    */
-    /*
-    hr = CoCreateInstance( &CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER,
-            &IID_IDirectSound, (void**)&lpDirectSound );
-
-    if( hr == S_OK )
-    {
-        hr = IDirectSound_Initialize( lpDirectSound, lpGUID );
-    }
-    */
-    
-    if( hr != DS_OK )
-    {
-        if (hr == DSERR_ALLOCATED)
-            PA_DEBUG(("AddOutputDeviceInfoFromDirectSound %s DSERR_ALLOCATED\n",name));
-        DBUG(("Cannot create DirectSound for %s. Result = 0x%x\n", name, hr ));
-        if (lpGUID)
-            DBUG(("%s's GUID: {0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x, 0x%x} \n",
-                 name,
-                 lpGUID->Data1,
-                 lpGUID->Data2,
-                 lpGUID->Data3,
-                 lpGUID->Data4[0],
-                 lpGUID->Data4[1],
-                 lpGUID->Data4[2],
-                 lpGUID->Data4[3],
-                 lpGUID->Data4[4],
-                 lpGUID->Data4[5],
-                 lpGUID->Data4[6],
-                 lpGUID->Data4[7]));
-
-        deviceOK = FALSE;
-    }
-    else
-    {
-        /* Query device characteristics. */
-        memset( &caps, 0, sizeof(caps) ); 
-        caps.dwSize = sizeof(caps);
-        hr = IDirectSound_GetCaps( lpDirectSound, &caps );
-        if( hr != DS_OK )
-        {
-            DBUG(("Cannot GetCaps() for DirectSound device %s. Result = 0x%x\n", name, hr ));
-            deviceOK = FALSE;
-        }
-        else
-        {
-
-#ifndef PA_NO_WMME
-            if( caps.dwFlags & DSCAPS_EMULDRIVER )
-            {
-                /* If WMME supported, then reject Emulated drivers because they are lousy. */
-                deviceOK = FALSE;
-            }
-#endif
-
-            if( deviceOK )
-            {
-                deviceInfo->maxInputChannels = 0;
-                /* Mono or stereo device? */
-                deviceInfo->maxOutputChannels = ( caps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1;
-
-                deviceInfo->defaultLowInputLatency = 0.;    /** @todo IMPLEMENT ME */
-                deviceInfo->defaultLowOutputLatency = 0.;   /** @todo IMPLEMENT ME */
-                deviceInfo->defaultHighInputLatency = 0.;   /** @todo IMPLEMENT ME */
-                deviceInfo->defaultHighOutputLatency = 0.;  /** @todo IMPLEMENT ME */
-                
-                /* initialize defaultSampleRate */
-                
-                if( caps.dwFlags & DSCAPS_CONTINUOUSRATE )
-                {
-                    /* initialize to caps.dwMaxSecondarySampleRate incase none of the standard rates match */
-                    deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
-
-                    for( i = 0; i < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++i )
-                    {
-                        if( defaultSampleRateSearchOrder_[i] >= caps.dwMinSecondarySampleRate
-                                && defaultSampleRateSearchOrder_[i] <= caps.dwMaxSecondarySampleRate ){
-
-                            deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[i];
-                            break;
-                        }
-                    }
-                }
-                else if( caps.dwMinSecondarySampleRate == caps.dwMaxSecondarySampleRate )
-                {
-                    if( caps.dwMinSecondarySampleRate == 0 )
-                    {
-                        /*
-                        ** On my Thinkpad 380Z, DirectSoundV6 returns min-max=0 !!
-                        ** But it supports continuous sampling.
-                        ** So fake range of rates, and hope it really supports it.
-                        */
-                        deviceInfo->defaultSampleRate = 44100.0f;
-
-                        DBUG(("PA - Reported rates both zero. Setting to fake values for device #%s\n", name ));
-                    }
-                    else
-                    {
-	                    deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
-                    }
-                }
-                else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) )
-                {
-                    /* The EWS88MT drivers lie, lie, lie. The say they only support two rates, 100 & 100000.
-                    ** But we know that they really support a range of rates!
-                    ** So when we see a ridiculous set of rates, assume it is a range.
-                    */
-                  deviceInfo->defaultSampleRate = 44100.0f;
-                  DBUG(("PA - Sample rate range used instead of two odd values for device #%s\n", name ));
-                }
-                else deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
-
-
-                //printf( "min %d max %d\n", caps.dwMinSecondarySampleRate, caps.dwMaxSecondarySampleRate );
-                // dwFlags | DSCAPS_CONTINUOUSRATE 
-            }
-        }
-
-        IDirectSound_Release( lpDirectSound );
-    }
-
-    if( deviceOK )
-    {
-        deviceInfo->name = name;
-
-        if( lpGUID == NULL )
-            hostApi->info.defaultOutputDevice = hostApi->info.deviceCount;
-            
-        hostApi->info.deviceCount++;
-    }
-
-    return result;
-}
-
-
-/************************************************************************************
-** Extract capabilities from an input device, and add it to the device info list
-** if successful. This function assumes that there is enough room in the
-** device info list to accomodate all entries.
-**
-** The device will not be added to the device list if any errors are encountered.
-*/
-static PaError AddInputDeviceInfoFromDirectSoundCapture(
-        PaWinDsHostApiRepresentation *winDsHostApi, char *name, LPGUID lpGUID )
-{
-    PaUtilHostApiRepresentation  *hostApi = &winDsHostApi->inheritedHostApiRep;
-    PaDeviceInfo                 *deviceInfo = hostApi->deviceInfos[hostApi->info.deviceCount];
-    PaWinDsDeviceInfo            *winDsDeviceInfo = &winDsHostApi->winDsDeviceInfos[hostApi->info.deviceCount];
-    HRESULT                       hr;
-    LPDIRECTSOUNDCAPTURE          lpDirectSoundCapture;
-    DSCCAPS                       caps;
-    int                           deviceOK = TRUE;
-    PaError                       result = paNoError;
-    
-    /* Copy GUID to the device info structure. Set pointer. */
-    if( lpGUID == NULL )
-    {
-        winDsDeviceInfo->lpGUID = NULL;
-    }
-    else
-    {
-        winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid;
-        memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) );
-    }
-
-
-    hr = dswDSoundEntryPoints.DirectSoundCaptureCreate( lpGUID, &lpDirectSoundCapture, NULL );
-
-    /** try using CoCreateInstance because DirectSoundCreate was hanging under
-        some circumstances - note this was probably related to the
-        #define BOOL short bug which has now been fixed
-        @todo delete this comment and the following code once we've ensured
-        there is no bug.
-    */
-    /*
-    hr = CoCreateInstance( &CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
-            &IID_IDirectSoundCapture, (void**)&lpDirectSoundCapture );
-    */
-    if( hr != DS_OK )
-    {
-        DBUG(("Cannot create Capture for %s. Result = 0x%x\n", name, hr ));
-        deviceOK = FALSE;
-    }
-    else
-    {
-        /* Query device characteristics. */
-        memset( &caps, 0, sizeof(caps) );
-        caps.dwSize = sizeof(caps);
-        hr = IDirectSoundCapture_GetCaps( lpDirectSoundCapture, &caps );
-        if( hr != DS_OK )
-        {
-            DBUG(("Cannot GetCaps() for Capture device %s. Result = 0x%x\n", name, hr ));
-            deviceOK = FALSE;
-        }
-        else
-        {
-#ifndef PA_NO_WMME
-            if( caps.dwFlags & DSCAPS_EMULDRIVER )
-            {
-                /* If WMME supported, then reject Emulated drivers because they are lousy. */
-                deviceOK = FALSE;
-            }
-#endif
-
-            if( deviceOK )
-            {
-                deviceInfo->maxInputChannels = caps.dwChannels;
-                deviceInfo->maxOutputChannels = 0;
-
-                deviceInfo->defaultLowInputLatency = 0.;    /** @todo IMPLEMENT ME */
-                deviceInfo->defaultLowOutputLatency = 0.;   /** @todo IMPLEMENT ME */
-                deviceInfo->defaultHighInputLatency = 0.;   /** @todo IMPLEMENT ME */
-                deviceInfo->defaultHighOutputLatency = 0.;  /** @todo IMPLEMENT ME */
-
-/*  constants from a WINE patch by Francois Gouget, see:
-    http://www.winehq.com/hypermail/wine-patches/2003/01/0290.html
-
-    ---
-    Date: Fri, 14 May 2004 10:38:12 +0200 (CEST)
-    From: Francois Gouget <fgouget@ ... .fr>
-    To: Ross Bencina <rbencina@ ... .au>
-    Subject: Re: Permission to use wine 48/96 wave patch in BSD licensed library
-
-    [snip]
-
-    I give you permission to use the patch below under the BSD license.
-    http://www.winehq.com/hypermail/wine-patches/2003/01/0290.html
-
-    [snip]
-*/
-#ifndef WAVE_FORMAT_48M08
-#define WAVE_FORMAT_48M08      0x00001000    /* 48     kHz, Mono,   8-bit  */
-#define WAVE_FORMAT_48S08      0x00002000    /* 48     kHz, Stereo, 8-bit  */
-#define WAVE_FORMAT_48M16      0x00004000    /* 48     kHz, Mono,   16-bit */
-#define WAVE_FORMAT_48S16      0x00008000    /* 48     kHz, Stereo, 16-bit */
-#define WAVE_FORMAT_96M08      0x00010000    /* 96     kHz, Mono,   8-bit  */
-#define WAVE_FORMAT_96S08      0x00020000    /* 96     kHz, Stereo, 8-bit  */
-#define WAVE_FORMAT_96M16      0x00040000    /* 96     kHz, Mono,   16-bit */
-#define WAVE_FORMAT_96S16      0x00080000    /* 96     kHz, Stereo, 16-bit */
-#endif
-
-                /* defaultSampleRate */
-                if( caps.dwChannels == 2 )
-                {
-                    if( caps.dwFormats & WAVE_FORMAT_4S16 )
-                        deviceInfo->defaultSampleRate = 44100.0;
-                    else if( caps.dwFormats & WAVE_FORMAT_48S16 )
-                        deviceInfo->defaultSampleRate = 48000.0;
-                    else if( caps.dwFormats & WAVE_FORMAT_2S16 )
-                        deviceInfo->defaultSampleRate = 22050.0;
-                    else if( caps.dwFormats & WAVE_FORMAT_1S16 )
-                        deviceInfo->defaultSampleRate = 11025.0;
-                    else if( caps.dwFormats & WAVE_FORMAT_96S16 )
-                        deviceInfo->defaultSampleRate = 96000.0;
-                    else
-                        deviceInfo->defaultSampleRate = 0.;
-                }
-                else if( caps.dwChannels == 1 )
-                {
-                    if( caps.dwFormats & WAVE_FORMAT_4M16 )
-                        deviceInfo->defaultSampleRate = 44100.0;
-                    else if( caps.dwFormats & WAVE_FORMAT_48M16 )
-                        deviceInfo->defaultSampleRate = 48000.0;
-                    else if( caps.dwFormats & WAVE_FORMAT_2M16 )
-                        deviceInfo->defaultSampleRate = 22050.0;
-                    else if( caps.dwFormats & WAVE_FORMAT_1M16 )
-                        deviceInfo->defaultSampleRate = 11025.0;
-                    else if( caps.dwFormats & WAVE_FORMAT_96M16 )
-                        deviceInfo->defaultSampleRate = 96000.0;
-                    else
-                        deviceInfo->defaultSampleRate = 0.;
-                }
-                else deviceInfo->defaultSampleRate = 0.;
-            }
-        }
-        
-        IDirectSoundCapture_Release( lpDirectSoundCapture );
-    }
-
-    if( deviceOK )
-    {
-        deviceInfo->name = name;
-
-        if( lpGUID == NULL )
-            hostApi->info.defaultInputDevice = hostApi->info.deviceCount;
-
-        hostApi->info.deviceCount++;
-    }
-
-    return result;
-}
-
-
-/***********************************************************************************/
-PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
-{
-    PaError result = paNoError;
-    int i, deviceCount;
-    PaWinDsHostApiRepresentation *winDsHostApi;
-    DSDeviceNameAndGUIDVector inputNamesAndGUIDs, outputNamesAndGUIDs;
-    PaDeviceInfo *deviceInfoArray;
-
-    HRESULT hr = CoInitialize(NULL);        /** @todo: should uninitialize too */
-    if( FAILED(hr) ){
-        return paUnanticipatedHostError;
-    }            
-
-    /* initialise guid vectors so they can be safely deleted on error */
-    inputNamesAndGUIDs.items = NULL;
-    outputNamesAndGUIDs.items = NULL;
-
-    DSW_InitializeDSoundEntryPoints();
-
-    winDsHostApi = (PaWinDsHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinDsHostApiRepresentation) );
-    if( !winDsHostApi )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    winDsHostApi->allocations = PaUtil_CreateAllocationGroup();
-    if( !winDsHostApi->allocations )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    *hostApi = &winDsHostApi->inheritedHostApiRep;
-    (*hostApi)->info.structVersion = 1;
-    (*hostApi)->info.type = paDirectSound;
-    (*hostApi)->info.name = "Windows DirectSound";
-    
-    (*hostApi)->info.deviceCount = 0;
-    (*hostApi)->info.defaultInputDevice = paNoDevice;
-    (*hostApi)->info.defaultOutputDevice = paNoDevice;
-
-    
-/* DSound - enumerate devices to count them and to gather their GUIDs */
-
-
-    result = InitializeDSDeviceNameAndGUIDVector( &inputNamesAndGUIDs, winDsHostApi->allocations );
-    if( result != paNoError )
-        goto error;
-
-    result = InitializeDSDeviceNameAndGUIDVector( &outputNamesAndGUIDs, winDsHostApi->allocations );
-    if( result != paNoError )
-        goto error;
-
-    dswDSoundEntryPoints.DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)CollectGUIDsProc, (void *)&inputNamesAndGUIDs );
-
-    dswDSoundEntryPoints.DirectSoundEnumerate( (LPDSENUMCALLBACK)CollectGUIDsProc, (void *)&outputNamesAndGUIDs );
-
-    if( inputNamesAndGUIDs.enumerationError != paNoError )
-    {
-        result = inputNamesAndGUIDs.enumerationError;
-        goto error;
-    }
-
-    if( outputNamesAndGUIDs.enumerationError != paNoError )
-    {
-        result = outputNamesAndGUIDs.enumerationError;
-        goto error;
-    }
-
-    deviceCount = inputNamesAndGUIDs.count + outputNamesAndGUIDs.count;
-
-    if( deviceCount > 0 )
-    {
-        /* allocate array for pointers to PaDeviceInfo structs */
-        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
-                winDsHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount );
-        if( !(*hostApi)->deviceInfos )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        /* allocate all PaDeviceInfo structs in a contiguous block */
-        deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory(
-                winDsHostApi->allocations, sizeof(PaDeviceInfo) * deviceCount );
-        if( !deviceInfoArray )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        /* allocate all DSound specific info structs in a contiguous block */
-        winDsHostApi->winDsDeviceInfos = (PaWinDsDeviceInfo*)PaUtil_GroupAllocateMemory(
-                winDsHostApi->allocations, sizeof(PaWinDsDeviceInfo) * deviceCount );
-        if( !winDsHostApi->winDsDeviceInfos )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        for( i=0; i < deviceCount; ++i )
-        {
-            PaDeviceInfo *deviceInfo = &deviceInfoArray[i];
-            deviceInfo->structVersion = 2;
-            deviceInfo->hostApi = hostApiIndex;
-            deviceInfo->name = 0;
-            (*hostApi)->deviceInfos[i] = deviceInfo;
-        }
-
-        for( i=0; i< inputNamesAndGUIDs.count; ++i )
-        {
-            result = AddInputDeviceInfoFromDirectSoundCapture( winDsHostApi,
-                    inputNamesAndGUIDs.items[i].name,
-                    inputNamesAndGUIDs.items[i].lpGUID );
-            if( result != paNoError )
-                goto error;
-        }
-
-        for( i=0; i< outputNamesAndGUIDs.count; ++i )
-        {
-            result = AddOutputDeviceInfoFromDirectSound( winDsHostApi,
-                    outputNamesAndGUIDs.items[i].name,
-                    outputNamesAndGUIDs.items[i].lpGUID );
-            if( result != paNoError )
-                goto error;
-        }
-    }    
-
-    result = TerminateDSDeviceNameAndGUIDVector( &inputNamesAndGUIDs );
-    if( result != paNoError )
-        goto error;
-
-    result = TerminateDSDeviceNameAndGUIDVector( &outputNamesAndGUIDs );
-    if( result != paNoError )
-        goto error;
-
-    
-    (*hostApi)->Terminate = Terminate;
-    (*hostApi)->OpenStream = OpenStream;
-    (*hostApi)->IsFormatSupported = IsFormatSupported;
-
-    PaUtil_InitializeStreamInterface( &winDsHostApi->callbackStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, GetStreamCpuLoad,
-                                      PaUtil_DummyRead, PaUtil_DummyWrite,
-                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
-
-    PaUtil_InitializeStreamInterface( &winDsHostApi->blockingStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
-                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
-
-    return result;
-
-error:
-    if( winDsHostApi )
-    {
-        if( winDsHostApi->allocations )
-        {
-            PaUtil_FreeAllAllocations( winDsHostApi->allocations );
-            PaUtil_DestroyAllocationGroup( winDsHostApi->allocations );
-        }
-                
-        PaUtil_FreeMemory( winDsHostApi );
-    }
-
-    TerminateDSDeviceNameAndGUIDVector( &inputNamesAndGUIDs );
-    TerminateDSDeviceNameAndGUIDVector( &outputNamesAndGUIDs );
-
-    return result;
-}
-
-
-/***********************************************************************************/
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
-{
-    PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation*)hostApi;
-
-    /*
-        IMPLEMENT ME:
-            - clean up any resources not handled by the allocation group
-    */
-
-    if( winDsHostApi->allocations )
-    {
-        PaUtil_FreeAllAllocations( winDsHostApi->allocations );
-        PaUtil_DestroyAllocationGroup( winDsHostApi->allocations );
-    }
-
-    PaUtil_FreeMemory( winDsHostApi );
-
-    DSW_TerminateDSoundEntryPoints();
-
-    CoUninitialize();
-}
-
-
-/* Set minimal latency based on whether NT or Win95.
- * NT has higher latency.
- */
-static int PaWinDS_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;
-}
-
-/***********************************************************************************/
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate )
-{
-    int inputChannelCount, outputChannelCount;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that input device can support inputChannelCount */
-        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
-            return paInvalidChannelCount;
-
-        /* validate inputStreamInfo */
-        if( inputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        inputChannelCount = 0;
-    }
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-        
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that output device can support inputChannelCount */
-        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
-            return paInvalidChannelCount;
-
-        /* validate outputStreamInfo */
-        if( outputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        outputChannelCount = 0;
-    }
-    
-    /*
-        IMPLEMENT ME:
-
-            - if a full duplex stream is requested, check that the combination
-                of input and output parameters is supported if necessary
-
-            - check that the device supports sampleRate
-
-        Because the buffer adapter handles conversion between all standard
-        sample formats, the following checks are only required if paCustomFormat
-        is implemented, or under some other unusual conditions.
-
-            - check that input device can support inputSampleFormat, or that
-                we have the capability to convert from outputSampleFormat to
-                a native format
-
-            - check that output device can support outputSampleFormat, or that
-                we have the capability to convert from outputSampleFormat to
-                a native format
-    */
-
-    return paFormatIsSupported;
-}
-
-
-/*************************************************************************
-** 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")
-#define PA_ENV_BUF_SIZE  (32)
-
-static int PaWinDs_GetMinLatencyFrames( double sampleRate )
-{
-    char      envbuf[PA_ENV_BUF_SIZE];
-    DWORD     hresult;
-    int       minLatencyMsec = 0;
-
-    /* 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 );
-    }
-    else
-    {
-        minLatencyMsec = PaWinDS_GetMinSystemLatency();
-#if PA_USE_HIGH_LATENCY
-        PRINT(("PA - Minimum Latency set to %d msec!\n", minLatencyMsec ));
-#endif
-
-    }
-
-    return (int) (minLatencyMsec * sampleRate * SECONDS_PER_MSEC);
-}
-
-/***********************************************************************************/
-/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */
-
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData )
-{
-    PaError result = paNoError;
-    PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation*)hostApi;
-    PaWinDsStream *stream = 0;
-    int inputChannelCount, outputChannelCount;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
-    unsigned long suggestedInputLatencyFrames, suggestedOutputLatencyFrames;
-
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-        suggestedInputLatencyFrames = (unsigned long)(inputParameters->suggestedLatency * sampleRate);
-
-        /* IDEA: the following 3 checks could be performed by default by pa_front
-            unless some flag indicated otherwise */
-            
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that input device can support inputChannelCount */
-        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
-            return paInvalidChannelCount;
-            
-        /* validate hostApiSpecificStreamInfo */
-        if( inputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-    }
-    else
-    {
-        inputChannelCount = 0;
-        suggestedInputLatencyFrames = 0;
-    }
-
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-        suggestedOutputLatencyFrames = (unsigned long)(outputParameters->suggestedLatency * sampleRate);
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that output device can support inputChannelCount */
-        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
-            return paInvalidChannelCount;
-
-        /* validate hostApiSpecificStreamInfo */
-        if( outputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */            
-    }
-    else
-    {
-        outputChannelCount = 0;
-        suggestedOutputLatencyFrames = 0;
-    }
-
-
-    /*
-        IMPLEMENT ME:
-
-        ( the following two checks are taken care of by PaUtil_InitializeBufferProcessor() )
-
-            - check that input device can support inputSampleFormat, or that
-                we have the capability to convert from outputSampleFormat to
-                a native format
-
-            - check that output device can support outputSampleFormat, or that
-                we have the capability to convert from outputSampleFormat to
-                a native format
-
-            - if a full duplex stream is requested, check that the combination
-                of input and output parameters is supported
-
-            - check that the device supports sampleRate
-
-            - alter sampleRate to a close allowable rate if possible / necessary
-
-            - validate suggestedInputLatency and suggestedOutputLatency parameters,
-                use default values where necessary
-    */
-
-
-    /* validate platform specific flags */
-    if( (streamFlags & paPlatformSpecificFlags) != 0 )
-        return paInvalidFlag; /* unexpected platform specific flag */
-
-
-    stream = (PaWinDsStream*)PaUtil_AllocateMemory( sizeof(PaWinDsStream) );
-    if( !stream )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    if( streamCallback )
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &winDsHostApi->callbackStreamInterface, streamCallback, userData );
-    }
-    else
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &winDsHostApi->blockingStreamInterface, streamCallback, userData );
-    }
-    
-    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
-
-
-    if( inputParameters )
-    {
-        /* IMPLEMENT ME - establish which  host formats are available */
-        hostInputSampleFormat =
-            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputParameters->sampleFormat );
-    }
-
-    if( outputParameters )
-    {
-        /* IMPLEMENT ME - establish which  host formats are available */
-        hostOutputSampleFormat =
-            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputParameters->sampleFormat );
-    }
-    
-    result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
-                    inputChannelCount, inputSampleFormat, hostInputSampleFormat,
-                    outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
-                    sampleRate, streamFlags, framesPerBuffer,
-                    framesPerBuffer, /* ignored in paUtilVariableHostBufferSizePartialUsageAllowed mode. */
-                /* This next mode is required because DS can split the host buffer when it wraps around. */
-                    paUtilVariableHostBufferSizePartialUsageAllowed,
-                    streamCallback, userData );
-    if( result != paNoError )
-        goto error;
-
-
-    stream->streamRepresentation.streamInfo.inputLatency =
-            PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor);   /* FIXME: not initialised anywhere else */
-    stream->streamRepresentation.streamInfo.outputLatency =
-            PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor);    /* FIXME: not initialised anywhere else */
-    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
-
-    
-/* DirectSound specific initialization */
-    {
-        HRESULT          hr;
-        int              bytesPerDirectSoundBuffer;
-        DSoundWrapper   *dsw;
-        int              userLatencyFrames;
-        int              minLatencyFrames;
-
-        stream->timerID = 0;
-        dsw = &stream->directSoundWrapper;
-        DSW_Init( dsw );
-
-    /* Get system minimum latency. */
-        minLatencyFrames = PaWinDs_GetMinLatencyFrames( sampleRate );
-
-    /* Let user override latency by passing latency parameter. */
-        userLatencyFrames = (suggestedInputLatencyFrames > suggestedOutputLatencyFrames)
-                    ? suggestedInputLatencyFrames
-                    : suggestedOutputLatencyFrames;
-        if( userLatencyFrames > 0 ) minLatencyFrames = userLatencyFrames;
-
-    /* Calculate stream->framesPerDSBuffer depending on framesPerBuffer */
-        if( framesPerBuffer == paFramesPerBufferUnspecified )
-        {
-        /* App support variable framesPerBuffer */
-            stream->framesPerDSBuffer = minLatencyFrames;
-
-            stream->streamRepresentation.streamInfo.outputLatency = (double)(minLatencyFrames - 1) / sampleRate;
-        }
-        else
-        {
-        /* Round up to number of buffers needed to guarantee that latency. */
-            int numUserBuffers = (minLatencyFrames + framesPerBuffer - 1) / framesPerBuffer;
-            if( numUserBuffers < 1 ) numUserBuffers = 1;
-            numUserBuffers += 1; /* So we have latency worth of buffers ahead of current buffer. */
-            stream->framesPerDSBuffer = framesPerBuffer * numUserBuffers;
-
-            stream->streamRepresentation.streamInfo.outputLatency = (double)(framesPerBuffer * (numUserBuffers-1)) / sampleRate;
-        }
-
-        {
-            /** @todo REVIEW: this calculation seems incorrect to me - rossb. */
-            int msecLatency = (int) ((stream->framesPerDSBuffer * MSEC_PER_SECOND) / sampleRate);
-            PRINT(("PortAudio on DirectSound - Latency = %d frames, %d msec\n", stream->framesPerDSBuffer, msecLatency ));
-        }
-
-
-        /* ------------------ OUTPUT */
-        if( outputParameters )
-        {
-            /*
-            PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ outputParameters->device ];
-            DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", outputParameters->device));
-            */
-            
-            bytesPerDirectSoundBuffer = stream->framesPerDSBuffer * outputParameters->channelCount * sizeof(short);
-            if( bytesPerDirectSoundBuffer < DSBSIZE_MIN )
-            {
-                result = paBufferTooSmall;
-                goto error;
-            }
-            else if( bytesPerDirectSoundBuffer > DSBSIZE_MAX )
-            {
-                result = paBufferTooBig;
-                goto error;
-            }
-
-
-            hr = dswDSoundEntryPoints.DirectSoundCreate( winDsHostApi->winDsDeviceInfos[outputParameters->device].lpGUID,
-                &dsw->dsw_pDirectSound,   NULL );
-            if( hr != DS_OK )
-            {
-                ERR_RPT(("PortAudio: DirectSoundCreate() failed!\n"));
-                result = paUnanticipatedHostError;
-                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
-                goto error;
-            }
-            hr = DSW_InitOutputBuffer( dsw,
-                                       (unsigned long) (sampleRate + 0.5),
-                                       (WORD)outputParameters->channelCount, bytesPerDirectSoundBuffer );
-            DBUG(("DSW_InitOutputBuffer() returns %x\n", hr));
-            if( hr != DS_OK )
-            {
-                result = paUnanticipatedHostError;
-                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
-                goto error;
-            }
-            /* Calculate value used in latency calculation to avoid real-time divides. */
-            stream->secondsPerHostByte = 1.0 /
-                (stream->bufferProcessor.bytesPerHostOutputSample *
-                outputChannelCount * sampleRate);
-        }
-
-        /* ------------------ INPUT */
-        if( inputParameters )
-        {
-            /*
-            PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ inputParameters->device ];
-            DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", inputParameters->device));
-            */
-            
-            bytesPerDirectSoundBuffer = stream->framesPerDSBuffer * inputParameters->channelCount * sizeof(short);
-            if( bytesPerDirectSoundBuffer < DSBSIZE_MIN )
-            {
-                result = paBufferTooSmall;
-                goto error;
-            }
-            else if( bytesPerDirectSoundBuffer > DSBSIZE_MAX )
-            {
-                result = paBufferTooBig;
-                goto error;
-            }
-
-            hr = dswDSoundEntryPoints.DirectSoundCaptureCreate( winDsHostApi->winDsDeviceInfos[inputParameters->device].lpGUID,
-                &dsw->dsw_pDirectSoundCapture,   NULL );
-            if( hr != DS_OK )
-            {
-                ERR_RPT(("PortAudio: DirectSoundCaptureCreate() failed!\n"));
-                result = paUnanticipatedHostError;
-                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
-                goto error;
-            }
-            hr = DSW_InitInputBuffer( dsw,
-                                      (unsigned long) (sampleRate + 0.5),
-                                      (WORD)inputParameters->channelCount, bytesPerDirectSoundBuffer );
-            DBUG(("DSW_InitInputBuffer() returns %x\n", hr));
-            if( hr != DS_OK )
-            {
-                ERR_RPT(("PortAudio: DSW_InitInputBuffer() returns %x\n", hr));
-                result = paUnanticipatedHostError;
-                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
-                goto error;
-            }
-        }
-
-    }
-
-    *s = (PaStream*)stream;
-
-    return result;
-
-error:
-    if( stream )
-        PaUtil_FreeMemory( stream );
-
-    return result;
-}
-
-
-/***********************************************************************************/
-static PaError Pa_TimeSlice( PaWinDsStream *stream )
-{
-    PaError           result = 0;   /* FIXME: this should be declared int and this function should also return that type (same as stream callback return type)*/
-    DSoundWrapper    *dsw;
-    long              numFrames = 0;
-    long              bytesEmpty = 0;
-    long              bytesFilled = 0;
-    long              bytesToXfer = 0;
-    long              framesToXfer = 0;
-    long              numInFramesReady = 0;
-    long              numOutFramesReady = 0;
-    long              bytesProcessed;
-    HRESULT           hresult;
-    double            outputLatency = 0;
-    PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement inputBufferAdcTime */
-    
-/* Input */
-    LPBYTE            lpInBuf1 = NULL;
-    LPBYTE            lpInBuf2 = NULL;
-    DWORD             dwInSize1 = 0;
-    DWORD             dwInSize2 = 0;
-/* Output */
-    LPBYTE            lpOutBuf1 = NULL;
-    LPBYTE            lpOutBuf2 = NULL;
-    DWORD             dwOutSize1 = 0;
-    DWORD             dwOutSize2 = 0;
-
-    dsw = &stream->directSoundWrapper;
-
-    /* How much input data is available? */
-    if( stream->bufferProcessor.inputChannelCount > 0 )
-    {
-        DSW_QueryInputFilled( dsw, &bytesFilled );
-        framesToXfer = numInFramesReady = bytesFilled / dsw->dsw_BytesPerInputFrame;
-        outputLatency = ((double)bytesFilled) * stream->secondsPerHostByte;
-
-        /** @todo Check for overflow */
-    }
-
-    /* How much output room is available? */
-    if( stream->bufferProcessor.outputChannelCount > 0 )
-    {
-        UINT previousUnderflowCount = dsw->dsw_OutputUnderflows;
-        DSW_QueryOutputSpace( dsw, &bytesEmpty );
-        framesToXfer = numOutFramesReady = bytesEmpty / dsw->dsw_BytesPerOutputFrame;
-
-        /* Check for underflow */
-        if( dsw->dsw_OutputUnderflows != previousUnderflowCount )
-            stream->callbackFlags |= paOutputUnderflow;
-    }
-
-    if( (numInFramesReady > 0) && (numOutFramesReady > 0) )
-    {
-        framesToXfer = (numOutFramesReady < numInFramesReady) ? numOutFramesReady : numInFramesReady;
-    }
-
-    if( framesToXfer > 0 )
-    {
-
-        PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
-
-    /* The outputBufferDacTime parameter should indicates the time at which
-        the first sample of the output buffer is heard at the DACs. */
-        timeInfo.currentTime = PaUtil_GetTime();
-        timeInfo.outputBufferDacTime = timeInfo.currentTime + outputLatency;
-
-
-        PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, stream->callbackFlags );
-        stream->callbackFlags = 0;
-        
-    /* Input */
-        if( stream->bufferProcessor.inputChannelCount > 0 )
-        {
-            bytesToXfer = framesToXfer * dsw->dsw_BytesPerInputFrame;
-            hresult = IDirectSoundCaptureBuffer_Lock ( dsw->dsw_InputBuffer,
-                dsw->dsw_ReadOffset, bytesToXfer,
-                (void **) &lpInBuf1, &dwInSize1,
-                (void **) &lpInBuf2, &dwInSize2, 0);
-            if (hresult != DS_OK)
-            {
-                ERR_RPT(("DirectSound IDirectSoundCaptureBuffer_Lock failed, hresult = 0x%x\n",hresult));
-                result = paUnanticipatedHostError;
-                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hresult );
-                goto error2;
-            }
-
-            numFrames = dwInSize1 / dsw->dsw_BytesPerInputFrame;
-            PaUtil_SetInputFrameCount( &stream->bufferProcessor, numFrames );
-            PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, lpInBuf1, 0 );
-        /* Is input split into two regions. */
-            if( dwInSize2 > 0 )
-            {
-                numFrames = dwInSize2 / dsw->dsw_BytesPerInputFrame;
-                PaUtil_Set2ndInputFrameCount( &stream->bufferProcessor, numFrames );
-                PaUtil_Set2ndInterleavedInputChannels( &stream->bufferProcessor, 0, lpInBuf2, 0 );
-            }
-        }
-
-    /* Output */
-        if( stream->bufferProcessor.outputChannelCount > 0 )
-        {
-            bytesToXfer = framesToXfer * dsw->dsw_BytesPerOutputFrame;
-            hresult = IDirectSoundBuffer_Lock ( dsw->dsw_OutputBuffer,
-                dsw->dsw_WriteOffset, bytesToXfer,
-                (void **) &lpOutBuf1, &dwOutSize1,
-                (void **) &lpOutBuf2, &dwOutSize2, 0);
-            if (hresult != DS_OK)
-            {
-                ERR_RPT(("DirectSound IDirectSoundBuffer_Lock failed, hresult = 0x%x\n",hresult));
-                result = paUnanticipatedHostError;
-                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hresult );
-                goto error1;
-            }
-
-            numFrames = dwOutSize1 / dsw->dsw_BytesPerOutputFrame;
-            PaUtil_SetOutputFrameCount( &stream->bufferProcessor, numFrames );
-            PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, lpOutBuf1, 0 );
-
-        /* Is output split into two regions. */
-            if( dwOutSize2 > 0 )
-            {
-                numFrames = dwOutSize2 / dsw->dsw_BytesPerOutputFrame;
-                PaUtil_Set2ndOutputFrameCount( &stream->bufferProcessor, numFrames );
-                PaUtil_Set2ndInterleavedOutputChannels( &stream->bufferProcessor, 0, lpOutBuf2, 0 );
-            }
-        }
-
-        result = paContinue;
-        numFrames = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &result );
-        stream->framesWritten += numFrames;
-        
-        if( stream->bufferProcessor.outputChannelCount > 0 )
-        {
-        /* FIXME: an underflow could happen here */
-
-        /* Update our buffer offset and unlock sound buffer */
-            bytesProcessed = numFrames * dsw->dsw_BytesPerOutputFrame;
-            dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + bytesProcessed) % dsw->dsw_OutputSize;
-            IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpOutBuf1, dwOutSize1, lpOutBuf2, dwOutSize2);
-            dsw->dsw_FramesWritten += numFrames;
-        }
-
-error1:
-        if( stream->bufferProcessor.inputChannelCount > 0 )
-        {
-        /* FIXME: an overflow could happen here */
-
-        /* Update our buffer offset and unlock sound buffer */
-            bytesProcessed = numFrames * dsw->dsw_BytesPerInputFrame;
-            dsw->dsw_ReadOffset = (dsw->dsw_ReadOffset + bytesProcessed) % dsw->dsw_InputSize;
-            IDirectSoundCaptureBuffer_Unlock( dsw->dsw_InputBuffer, lpInBuf1, dwInSize1, lpInBuf2, dwInSize2);
-        }
-error2:
-
-        PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, numFrames );
-
-    }
-    
-    return result;
-}
-/*******************************************************************/
-static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD dw1, DWORD dw2)
-{
-    PaWinDsStream *stream;
-
-    /* suppress unused variable warnings */
-    (void) uID;
-    (void) uMsg;
-    (void) dw1;
-    (void) dw2;
-    
-    stream = (PaWinDsStream *) dwUser;
-    if( stream == NULL ) return;
-
-    if( stream->isActive )
-    {
-        if( stream->abortProcessing )
-        {
-            stream->isActive = 0;
-        }
-        else if( stream->stopProcessing )
-        {
-            DSoundWrapper   *dsw = &stream->directSoundWrapper;
-            if( stream->bufferProcessor.outputChannelCount > 0 )
-            {
-                DSW_ZeroEmptySpace( dsw );
-                /* clear isActive when all sound played */
-                if( dsw->dsw_FramesPlayed >= stream->framesWritten )
-                {
-                    stream->isActive = 0;
-                }
-            }
-            else
-            {
-                stream->isActive = 0;
-            }
-        }
-        else
-        {
-            if( Pa_TimeSlice( stream ) != 0)  /* Call time slice independant of timing method. */
-            {
-                /* FIXME implement handling of paComplete and paAbort if possible */
-                stream->stopProcessing = 1;
-            }
-        }
-
-        if( !stream->isActive ){
-            if( stream->streamRepresentation.streamFinishedCallback != 0 )
-                stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
-        }
-    }
-}
-
-/***********************************************************************************
-    When CloseStream() is called, the multi-api layer ensures that
-    the stream has already been stopped or aborted.
-*/
-static PaError CloseStream( PaStream* s )
-{
-    PaError result = paNoError;
-    PaWinDsStream *stream = (PaWinDsStream*)s;
-
-    DSW_Term( &stream->directSoundWrapper );
-
-    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
-    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
-    PaUtil_FreeMemory( stream );
-
-    return result;
-}
-
-/***********************************************************************************/
-static PaError StartStream( PaStream *s )
-{
-    PaError          result = paNoError;
-    PaWinDsStream   *stream = (PaWinDsStream*)s;
-    HRESULT          hr;
-
-    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
-    
-    if( stream->bufferProcessor.inputChannelCount > 0 )
-    {
-        hr = DSW_StartInput( &stream->directSoundWrapper );
-        DBUG(("StartStream: DSW_StartInput returned = 0x%X.\n", hr));
-        if( hr != DS_OK )
-        {
-            result = paUnanticipatedHostError;
-            PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
-            goto error;
-        }
-    }
-
-    stream->framesWritten = 0;
-    stream->callbackFlags = 0;
-
-    stream->abortProcessing = 0;
-    stream->stopProcessing = 0;
-    stream->isActive = 1;
-
-    if( stream->bufferProcessor.outputChannelCount > 0 )
-    {
-        /* Give user callback a chance to pre-fill buffer. REVIEW - i thought we weren't pre-filling, rb. */
-        result = Pa_TimeSlice( stream );
-        if( result != paNoError ) return result; // FIXME - what if finished?
-
-        hr = DSW_StartOutput( &stream->directSoundWrapper );
-        DBUG(("PaHost_StartOutput: DSW_StartOutput returned = 0x%X.\n", hr));
-        if( hr != DS_OK )
-        {
-            result = paUnanticipatedHostError;
-            PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
-            goto error;
-        }
-    }
-
-
-    /* Create timer that will wake us up so we can fill the DSound buffer. */
-    {
-        int resolution;
-        int framesPerWakeup = stream->framesPerDSBuffer / 4;
-        int msecPerWakeup = MSEC_PER_SECOND * framesPerWakeup / (int) stream->streamRepresentation.streamInfo.sampleRate;
-        if( msecPerWakeup < 10 ) msecPerWakeup = 10;
-        else if( msecPerWakeup > 100 ) msecPerWakeup = 100;
-        resolution = msecPerWakeup/4;
-        stream->timerID = timeSetEvent( msecPerWakeup, resolution, (LPTIMECALLBACK) Pa_TimerCallback,
-                                             (DWORD_PTR) stream, TIME_PERIODIC );
-    }
-    if( stream->timerID == 0 )
-    {
-        stream->isActive = 0;
-        result = paUnanticipatedHostError;
-        PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
-        goto error;
-    }
-
-    stream->isStarted = TRUE;
-
-error:
-    return result;
-}
-
-
-/***********************************************************************************/
-static PaError StopStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaWinDsStream *stream = (PaWinDsStream*)s;
-    HRESULT          hr;
-    int timeoutMsec;
-
-    stream->stopProcessing = 1;
-    /* Set timeout at 20% beyond maximum time we might wait. */
-    timeoutMsec = (int) (1200.0 * stream->framesPerDSBuffer / stream->streamRepresentation.streamInfo.sampleRate);
-    while( stream->isActive && (timeoutMsec > 0)  )
-    {
-        Sleep(10);
-        timeoutMsec -= 10;
-    }
-    if( stream->timerID != 0 )
-    {
-        timeKillEvent(stream->timerID);  /* Stop callback timer. */
-        stream->timerID = 0;
-    }
-
-
-    if( stream->bufferProcessor.outputChannelCount > 0 )
-    {
-        hr = DSW_StopOutput( &stream->directSoundWrapper );
-    }
-
-    if( stream->bufferProcessor.inputChannelCount > 0 )
-    {
-        hr = DSW_StopInput( &stream->directSoundWrapper );
-    }
-
-    stream->isStarted = FALSE;
-
-    return result;
-}
-
-
-/***********************************************************************************/
-static PaError AbortStream( PaStream *s )
-{
-    PaWinDsStream *stream = (PaWinDsStream*)s;
-
-    stream->abortProcessing = 1;
-    return StopStream( s );
-}
-
-
-/***********************************************************************************/
-static PaError IsStreamStopped( PaStream *s )
-{
-    PaWinDsStream *stream = (PaWinDsStream*)s;
-
-    return !stream->isStarted;
-}
-
-
-/***********************************************************************************/
-static PaError IsStreamActive( PaStream *s )
-{
-    PaWinDsStream *stream = (PaWinDsStream*)s;
-
-    return stream->isActive;
-}
-
-/***********************************************************************************/
-static PaTime GetStreamTime( PaStream *s )
-{
-    /* suppress unused variable warnings */
-    (void) s;
-
-    
-/*
-    new behavior for GetStreamTime is to return a stream based seconds clock
-    used for the outTime parameter to the callback.
-    FIXME: delete this comment when the other unnecessary related code has
-    been cleaned from this file.
-
-    PaWinDsStream *stream = (PaWinDsStream*)s;
-    DSoundWrapper   *dsw;
-    dsw = &stream->directSoundWrapper;
-    return dsw->dsw_FramesPlayed;
-*/
-    return PaUtil_GetTime();
-}
-
-
-/***********************************************************************************/
-static double GetStreamCpuLoad( PaStream* s )
-{
-    PaWinDsStream *stream = (PaWinDsStream*)s;
-
-    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
-}
-
-
-
-/***********************************************************************************
-    As separate stream interfaces are used for blocking and callback
-    streams, the following functions can be guaranteed to only be called
-    for blocking streams.
-*/
-
-static PaError ReadStream( PaStream* s,
-                           void *buffer,
-                           unsigned long frames )
-{
-    PaWinDsStream *stream = (PaWinDsStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) buffer;
-    (void) frames;
-    (void) stream;
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return paNoError;
-}
-
-
-/***********************************************************************************/
-static PaError WriteStream( PaStream* s,
-                            const void *buffer,
-                            unsigned long frames )
-{
-    PaWinDsStream *stream = (PaWinDsStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) buffer;
-    (void) frames;
-    (void) stream;
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return paNoError;
-}
-
-
-/***********************************************************************************/
-static signed long GetStreamReadAvailable( PaStream* s )
-{
-    PaWinDsStream *stream = (PaWinDsStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) stream;
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return 0;
-}
-
-
-/***********************************************************************************/
-static signed long GetStreamWriteAvailable( PaStream* s )
-{
-    PaWinDsStream *stream = (PaWinDsStream*)s;
-
-    /* suppress unused variable warnings */
-    (void) stream;
-    
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-
-    return 0;
-}
-
-
-
diff --git a/portaudio/pa_win_wdmks/CVS/Entries b/portaudio/pa_win_wdmks/CVS/Entries
deleted file mode 100644
index a41daa9c1..000000000
--- a/portaudio/pa_win_wdmks/CVS/Entries
+++ /dev/null
@@ -1,3 +0,0 @@
-/pa_win_wdmks.c/1.1.2.4/Sat Nov 19 10:14:01 2005//Tv19-devel
-/readme.txt/1.1.2.2/Wed Nov 16 04:39:53 2005//Tv19-devel
-D
diff --git a/portaudio/pa_win_wdmks/CVS/Repository b/portaudio/pa_win_wdmks/CVS/Repository
deleted file mode 100644
index 3e0293860..000000000
--- a/portaudio/pa_win_wdmks/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_win_wdmks
diff --git a/portaudio/pa_win_wdmks/CVS/Root b/portaudio/pa_win_wdmks/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_win_wdmks/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_win_wdmks/CVS/Tag b/portaudio/pa_win_wdmks/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_win_wdmks/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_win_wdmks/pa_win_wdmks.c b/portaudio/pa_win_wdmks/pa_win_wdmks.c
deleted file mode 100644
index 9f83b1b06..000000000
--- a/portaudio/pa_win_wdmks/pa_win_wdmks.c
+++ /dev/null
@@ -1,3269 +0,0 @@
-/*
- * $Id: pa_win_wdmks.c,v 1.1.2.4 2005/11/19 10:14:01 rossbencina Exp $
- * PortAudio Windows WDM-KS interface
- *
- * Author: Andrew Baldwin
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2004 Andrew Baldwin, Ross Bencina, 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.
- */
-
-/** @file
- @brief Portaudio WDM-KS host API.
-
- @note This is the implementation of the Portaudio host API using the
- Windows WDM/Kernel Streaming API in order to enable very low latency
- playback and recording on all modern Windows platforms (e.g. 2K, XP)
- Note: This API accesses the device drivers below the usual KMIXER
- component which is normally used to enable multi-client mixing and
- format conversion. That means that it will lock out all other users
- of a device for the duration of active stream using those devices
-*/
-
-#include <stdio.h>
-
-/* Debugging/tracing support */
-
-#define PA_LOGE_
-#define PA_LOGL_
-
-#ifdef __GNUC__
-    #include <initguid.h>
-    #define _WIN32_WINNT 0x0501
-    #define WINVER 0x0501
-#endif
-
-#include <string.h> /* strlen() */
-#include <assert.h>
-
-#include "pa_util.h"
-#include "pa_allocation.h"
-#include "pa_hostapi.h"
-#include "pa_stream.h"
-#include "pa_cpuload.h"
-#include "pa_process.h"
-#include "portaudio.h"
-
-#include <windows.h>
-#include <winioctl.h>
-
-
-#ifdef __GNUC__
-    #undef PA_LOGE_
-    #define PA_LOGE_ PA_DEBUG(("%s {\n",__FUNCTION__))
-    #undef PA_LOGL_
-    #define PA_LOGL_ PA_DEBUG(("} %s\n",__FUNCTION__))
-    /* These defines are set in order to allow the WIndows DirectX
-     * headers to compile with a GCC compiler such as MinGW
-     * NOTE: The headers may generate a few warning in GCC, but
-     * they should compile */
-    #define _INC_MMSYSTEM
-    #define _INC_MMREG
-    #define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */
-    #define DEFINE_GUID_THUNK(name,guid) DEFINE_GUID(name,guid)
-    #define DEFINE_GUIDEX(n) DEFINE_GUID_THUNK( n, STATIC_##n )
-    #if !defined( DEFINE_WAVEFORMATEX_GUID )
-        #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
-    #endif
-    #define  WAVE_FORMAT_ADPCM      0x0002
-    #define  WAVE_FORMAT_IEEE_FLOAT 0x0003
-    #define  WAVE_FORMAT_ALAW       0x0006
-    #define  WAVE_FORMAT_MULAW      0x0007
-    #define  WAVE_FORMAT_MPEG       0x0050
-    #define  WAVE_FORMAT_DRM        0x0009
-    #define DYNAMIC_GUID_THUNK(l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
-    #define DYNAMIC_GUID(data) DYNAMIC_GUID_THUNK(data)
-#endif
-
-#ifdef _MSC_VER
-    #define DYNAMIC_GUID(data) {data}
-    #define _INC_MMREG
-    #define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */
-    #undef DEFINE_GUID
-    #define DEFINE_GUID(n,data) EXTERN_C const GUID n = {data}
-    #define DEFINE_GUID_THUNK(n,data) DEFINE_GUID(n,data)
-    #define DEFINE_GUIDEX(n) DEFINE_GUID_THUNK(n, STATIC_##n)
-    #if !defined( DEFINE_WAVEFORMATEX_GUID )
-        #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
-    #endif
-    #define  WAVE_FORMAT_ADPCM      0x0002
-    #define  WAVE_FORMAT_IEEE_FLOAT 0x0003
-    #define  WAVE_FORMAT_ALAW       0x0006
-    #define  WAVE_FORMAT_MULAW      0x0007
-    #define  WAVE_FORMAT_MPEG       0x0050
-    #define  WAVE_FORMAT_DRM        0x0009
-#endif
-
-#include <ks.h>
-#include <ksmedia.h>
-#include <tchar.h>
-#include <assert.h>
-#include <stdio.h>
-
-/* These next definitions allow the use of the KSUSER DLL */
-typedef KSDDKAPI DWORD WINAPI KSCREATEPIN(HANDLE, PKSPIN_CONNECT, ACCESS_MASK, PHANDLE);
-extern HMODULE      DllKsUser;
-extern KSCREATEPIN* FunctionKsCreatePin;
-
-/* Forward definition to break circular type reference between pin and filter */
-struct __PaWinWdmFilter;
-typedef struct __PaWinWdmFilter PaWinWdmFilter;
-
-/* The Pin structure
- * A pin is an input or output node, e.g. for audio flow */
-typedef struct __PaWinWdmPin
-{
-    HANDLE                      handle;
-    PaWinWdmFilter*             parentFilter;
-    unsigned long               pinId;
-    KSPIN_CONNECT*              pinConnect;
-    unsigned long               pinConnectSize;
-    KSDATAFORMAT_WAVEFORMATEX*  ksDataFormatWfx;
-    KSPIN_COMMUNICATION         communication;
-    KSDATARANGE*                dataRanges;
-    KSMULTIPLE_ITEM*            dataRangesItem;
-    KSPIN_DATAFLOW              dataFlow;
-    KSPIN_CINSTANCES            instances;
-    unsigned long               frameSize;
-    int                         maxChannels;
-    unsigned long               formats;
-    int                         bestSampleRate;
-}
-PaWinWdmPin;
-
-/* The Filter structure
- * A filter has a number of pins and a "friendly name" */
-struct __PaWinWdmFilter
-{
-    HANDLE         handle;
-    int            pinCount;
-    PaWinWdmPin**  pins;
-    TCHAR          filterName[MAX_PATH];
-    TCHAR          friendlyName[MAX_PATH];
-    int            maxInputChannels;
-    int            maxOutputChannels;
-    unsigned long  formats;
-    int            usageCount;
-    int            bestSampleRate;
-};
-
-/* PaWinWdmHostApiRepresentation - host api datastructure specific to this implementation */
-typedef struct __PaWinWdmHostApiRepresentation
-{
-    PaUtilHostApiRepresentation  inheritedHostApiRep;
-    PaUtilStreamInterface        callbackStreamInterface;
-    PaUtilStreamInterface        blockingStreamInterface;
-
-    PaUtilAllocationGroup*       allocations;
-    PaWinWdmFilter**             filters;
-    int                          filterCount;
-}
-PaWinWdmHostApiRepresentation;
-
-typedef struct __PaWinWdmDeviceInfo
-{
-    PaDeviceInfo     inheritedDeviceInfo;
-    PaWinWdmFilter*  filter;
-}
-PaWinWdmDeviceInfo;
-
-typedef struct __DATAPACKET
-{
-    KSSTREAM_HEADER  Header;
-    OVERLAPPED       Signal;
-} DATAPACKET;
-
-/* PaWinWdmStream - a stream data structure specifically for this implementation */
-typedef struct __PaWinWdmStream
-{
-    PaUtilStreamRepresentation  streamRepresentation;
-    PaUtilCpuLoadMeasurer       cpuLoadMeasurer;
-    PaUtilBufferProcessor       bufferProcessor;
-
-    PaWinWdmPin*                recordingPin;
-    PaWinWdmPin*                playbackPin;
-    char*                       hostBuffer;
-    unsigned long               framesPerHostIBuffer;
-    unsigned long               framesPerHostOBuffer;
-    int                         bytesPerInputFrame;
-    int                         bytesPerOutputFrame;
-    int                         streamStarted;
-    int                         streamActive;
-    int                         streamStop;
-    int                         streamAbort;
-    int                         oldProcessPriority;
-    HANDLE                      streamThread;
-    HANDLE                      events[5];  /* 2 play + 2 record packets + abort events */
-    DATAPACKET                  packets[4]; /* 2 play + 2 record */
-    PaStreamFlags               streamFlags;
-    /* These values handle the case where the user wants to use fewer
-     * channels than the device has */
-    int                         userInputChannels;
-    int                         deviceInputChannels;
-    int                         userOutputChannels;
-    int                         deviceOutputChannels;
-    int                         inputSampleSize;
-    int                         outputSampleSize;
-}
-PaWinWdmStream;
-
-#include <setupapi.h>
-
-HMODULE      DllKsUser = NULL;
-KSCREATEPIN* FunctionKsCreatePin = NULL;
-
-/* prototypes for functions declared in this file */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-/* Low level I/O functions */
-static PaError WdmSyncIoctl(HANDLE handle,
-    unsigned long ioctlNumber,
-    void* inBuffer,
-    unsigned long inBufferCount,
-    void* outBuffer,
-    unsigned long outBufferCount,
-    unsigned long* bytesReturned);
-static PaError WdmGetPropertySimple(HANDLE handle,
-    const GUID* const guidPropertySet,
-    unsigned long property,
-    void* value,
-    unsigned long valueCount,
-    void* instance,
-    unsigned long instanceCount);
-static PaError WdmSetPropertySimple(HANDLE handle,
-    const GUID* const guidPropertySet,
-    unsigned long property,
-    void* value,
-    unsigned long valueCount,
-    void* instance,
-    unsigned long instanceCount);
-static PaError WdmGetPinPropertySimple(HANDLE  handle,
-    unsigned long pinId,
-    const GUID* const guidPropertySet,
-    unsigned long property,
-    void* value,
-    unsigned long valueCount);
-static PaError WdmGetPinPropertyMulti(HANDLE  handle,
-    unsigned long pinId,
-    const GUID* const guidPropertySet,
-    unsigned long property,
-    KSMULTIPLE_ITEM** ksMultipleItem);
-
-/** Pin management functions */
-static PaWinWdmPin* PinNew(PaWinWdmFilter* parentFilter, unsigned long pinId, PaError* error);
-static void PinFree(PaWinWdmPin* pin);
-static void PinClose(PaWinWdmPin* pin);
-static PaError PinInstantiate(PaWinWdmPin* pin);
-/*static PaError PinGetState(PaWinWdmPin* pin, KSSTATE* state); NOT USED */
-static PaError PinSetState(PaWinWdmPin* pin, KSSTATE state);
-static PaError PinSetFormat(PaWinWdmPin* pin, const WAVEFORMATEX* format);
-static PaError PinIsFormatSupported(PaWinWdmPin* pin, const WAVEFORMATEX* format);
-
-/* Filter management functions */
-static PaWinWdmFilter* FilterNew(
-    TCHAR* filterName,
-    TCHAR* friendlyName,
-    PaError* error);
-static void FilterFree(PaWinWdmFilter* filter);
-static PaWinWdmPin* FilterCreateRenderPin(
-    PaWinWdmFilter* filter,
-    const WAVEFORMATEX* wfex,
-    PaError* error);
-static PaWinWdmPin* FilterFindViableRenderPin(
-    PaWinWdmFilter* filter,
-    const WAVEFORMATEX* wfex,
-    PaError* error);
-static PaError FilterCanCreateRenderPin(
-    PaWinWdmFilter* filter,
-    const WAVEFORMATEX* wfex);
-static PaWinWdmPin* FilterCreateCapturePin(
-    PaWinWdmFilter* filter,
-    const WAVEFORMATEX* wfex,
-    PaError* error);
-static PaWinWdmPin* FilterFindViableCapturePin(
-    PaWinWdmFilter* filter,
-    const WAVEFORMATEX* wfex,
-    PaError* error);
-static PaError FilterCanCreateCapturePin(
-    PaWinWdmFilter* filter,
-    const WAVEFORMATEX* pwfx);
-static PaError FilterUse(
-    PaWinWdmFilter* filter);
-static void FilterRelease(
-    PaWinWdmFilter* filter);
-
-/* Interface functions */
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
-static PaError IsFormatSupported(
-    struct PaUtilHostApiRepresentation *hostApi,
-    const PaStreamParameters *inputParameters,
-    const PaStreamParameters *outputParameters,
-    double sampleRate );
-static PaError OpenStream(
-    struct PaUtilHostApiRepresentation *hostApi,
-    PaStream** s,
-    const PaStreamParameters *inputParameters,
-    const PaStreamParameters *outputParameters,
-    double sampleRate,
-    unsigned long framesPerBuffer,
-    PaStreamFlags streamFlags,
-    PaStreamCallback *streamCallback,
-    void *userData );
-static PaError CloseStream( PaStream* stream );
-static PaError StartStream( PaStream *stream );
-static PaError StopStream( PaStream *stream );
-static PaError AbortStream( PaStream *stream );
-static PaError IsStreamStopped( PaStream *s );
-static PaError IsStreamActive( PaStream *stream );
-static PaTime GetStreamTime( PaStream *stream );
-static double GetStreamCpuLoad( PaStream* stream );
-static PaError ReadStream(
-    PaStream* stream,
-    void *buffer,
-    unsigned long frames );
-static PaError WriteStream(
-    PaStream* stream,
-    const void *buffer,
-    unsigned long frames );
-static signed long GetStreamReadAvailable( PaStream* stream );
-static signed long GetStreamWriteAvailable( PaStream* stream );
-
-/* Utility functions */
-static unsigned long GetWfexSize(const WAVEFORMATEX* wfex);
-static PaError BuildFilterList(PaWinWdmHostApiRepresentation* wdmHostApi);
-static BOOL PinWrite(HANDLE h, DATAPACKET* p);
-static BOOL PinRead(HANDLE h, DATAPACKET* p);
-static void DuplicateFirstChannelInt16(void* buffer, int channels, int samples);
-static void DuplicateFirstChannelInt24(void* buffer, int channels, int samples);
-static DWORD WINAPI ProcessingThread(LPVOID pParam);
-
-/* Function bodies */
-
-static unsigned long GetWfexSize(const WAVEFORMATEX* wfex)
-{
-    if( wfex->wFormatTag == WAVE_FORMAT_PCM )
-    {
-        return sizeof( WAVEFORMATEX );
-    }
-    else
-    {
-        return (sizeof( WAVEFORMATEX ) + wfex->cbSize);
-    }
-}
-
-/*
-Low level pin/filter access functions
-*/
-static PaError WdmSyncIoctl(
-    HANDLE handle,
-    unsigned long ioctlNumber,
-    void* inBuffer,
-    unsigned long inBufferCount,
-    void* outBuffer,
-    unsigned long outBufferCount,
-    unsigned long* bytesReturned)
-{
-    PaError result = paNoError;
-    OVERLAPPED overlapped;
-    int boolResult;
-    unsigned long dummyBytesReturned;
-    unsigned long error;
-
-    if( !bytesReturned )
-    {
-        /* User a dummy as the caller hasn't supplied one */
-        bytesReturned = &dummyBytesReturned;
-    }
-
-    FillMemory((void *)&overlapped,sizeof(overlapped),0);
-    overlapped.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
-    if( !overlapped.hEvent )
-    {
-          result = paInsufficientMemory;
-        goto error;
-    }
-    overlapped.hEvent = (HANDLE)((DWORD_PTR)overlapped.hEvent | 0x1);
-
-    boolResult = DeviceIoControl(handle, ioctlNumber, inBuffer, inBufferCount,
-        outBuffer, outBufferCount, bytesReturned, &overlapped);
-    if( !boolResult )
-    {
-        error = GetLastError();
-        if( error == ERROR_IO_PENDING )
-        {
-            error = WaitForSingleObject(overlapped.hEvent,INFINITE);
-            if( error != WAIT_OBJECT_0 )
-            {
-                result = paUnanticipatedHostError;
-                goto error;
-            }
-        }
-        else if((( error == ERROR_INSUFFICIENT_BUFFER ) ||
-                  ( error == ERROR_MORE_DATA )) &&
-                  ( ioctlNumber == IOCTL_KS_PROPERTY ) &&
-                  ( outBufferCount == 0 ))
-        {
-            boolResult = TRUE;
-        }
-        else
-        {
-            result = paUnanticipatedHostError;
-        }
-    }
-    if( !boolResult )
-        *bytesReturned = 0;
-
-error:
-    if( overlapped.hEvent )
-    {
-            CloseHandle( overlapped.hEvent );
-    }
-    return result;
-}
-
-static PaError WdmGetPropertySimple(HANDLE handle,
-    const GUID* const guidPropertySet,
-    unsigned long property,
-    void* value,
-    unsigned long valueCount,
-    void* instance,
-    unsigned long instanceCount)
-{
-    PaError result;
-    KSPROPERTY* ksProperty;
-    unsigned long propertyCount;
-
-    propertyCount = sizeof(KSPROPERTY) + instanceCount;
-    ksProperty = (KSPROPERTY*)PaUtil_AllocateMemory( propertyCount );
-    if( !ksProperty )
-    {
-        return paInsufficientMemory;
-    }
-
-    FillMemory((void*)ksProperty,sizeof(ksProperty),0);
-    ksProperty->Set = *guidPropertySet;
-    ksProperty->Id = property;
-    ksProperty->Flags = KSPROPERTY_TYPE_GET;
-
-    if( instance )
-    {
-        memcpy( (void*)(((char*)ksProperty)+sizeof(KSPROPERTY)), instance, instanceCount );
-    }
-
-    result = WdmSyncIoctl(
-                handle,
-                IOCTL_KS_PROPERTY,
-                ksProperty,
-                propertyCount,
-                value,
-                valueCount,
-                NULL);
-
-    PaUtil_FreeMemory( ksProperty );
-    return result;
-}
-
-static PaError WdmSetPropertySimple(
-    HANDLE handle,
-    const GUID* const guidPropertySet,
-    unsigned long property,
-    void* value,
-    unsigned long valueCount,
-    void* instance,
-    unsigned long instanceCount)
-{
-    PaError result;
-    KSPROPERTY* ksProperty;
-    unsigned long propertyCount  = 0;
-
-    propertyCount = sizeof(KSPROPERTY) + instanceCount;
-    ksProperty = (KSPROPERTY*)PaUtil_AllocateMemory( propertyCount );
-    if( !ksProperty )
-    {
-        return paInsufficientMemory;
-    }
-
-    ksProperty->Set = *guidPropertySet;
-    ksProperty->Id = property;
-    ksProperty->Flags = KSPROPERTY_TYPE_SET;
-
-    if( instance )
-    {
-        memcpy((void*)((char*)ksProperty + sizeof(KSPROPERTY)), instance, instanceCount);
-    }
-
-    result = WdmSyncIoctl(
-                handle,
-                IOCTL_KS_PROPERTY,
-                ksProperty,
-                propertyCount,
-                value,
-                valueCount,
-                NULL);
-
-    PaUtil_FreeMemory( ksProperty );
-    return result;
-}
-
-static PaError WdmGetPinPropertySimple(
-    HANDLE  handle,
-    unsigned long pinId,
-    const GUID* const guidPropertySet,
-    unsigned long property,
-    void* value,
-    unsigned long valueCount)
-{
-    PaError result;
-
-    KSP_PIN ksPProp;
-    ksPProp.Property.Set = *guidPropertySet;
-    ksPProp.Property.Id = property;
-    ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
-    ksPProp.PinId = pinId;
-    ksPProp.Reserved = 0;
-
-    result = WdmSyncIoctl(
-                handle,
-                IOCTL_KS_PROPERTY,
-                &ksPProp,
-                sizeof(KSP_PIN),
-                value,
-                valueCount,
-                NULL);
-
-    return result;
-}
-
-static PaError WdmGetPinPropertyMulti(
-    HANDLE handle,
-    unsigned long pinId,
-    const GUID* const guidPropertySet,
-    unsigned long property,
-    KSMULTIPLE_ITEM** ksMultipleItem)
-{
-    PaError result;
-    unsigned long multipleItemSize = 0;
-    KSP_PIN ksPProp;
-
-    ksPProp.Property.Set = *guidPropertySet;
-    ksPProp.Property.Id = property;
-    ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
-    ksPProp.PinId = pinId;
-    ksPProp.Reserved = 0;
-
-    result = WdmSyncIoctl(
-                handle,
-                IOCTL_KS_PROPERTY,
-                &ksPProp.Property,
-                sizeof(KSP_PIN),
-                NULL,
-                0,
-                &multipleItemSize);
-    if( result != paNoError )
-    {
-        return result;
-    }
-
-    *ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize );
-    if( !*ksMultipleItem )
-    {
-        return paInsufficientMemory;
-    }
-
-    result = WdmSyncIoctl(
-                handle,
-                IOCTL_KS_PROPERTY,
-                &ksPProp,
-                sizeof(KSP_PIN),
-                (void*)*ksMultipleItem,
-                multipleItemSize,
-                NULL);
-
-    if( result != paNoError )
-    {
-        PaUtil_FreeMemory( ksMultipleItem );
-    }
-
-    return result;
-}
-
-
-/*
-Create a new pin object belonging to a filter
-The pin object holds all the configuration information about the pin
-before it is opened, and then the handle of the pin after is opened
-*/
-static PaWinWdmPin* PinNew(PaWinWdmFilter* parentFilter, unsigned long pinId, PaError* error)
-{
-    PaWinWdmPin* pin;
-    PaError result;
-    unsigned long i;
-    KSMULTIPLE_ITEM* item = NULL;
-    KSIDENTIFIER* identifier;
-    KSDATARANGE* dataRange;
-
-    PA_LOGE_;
-    PA_DEBUG(("Creating pin %d:\n",pinId));
-
-    /* Allocate the new PIN object */
-    pin = (PaWinWdmPin*)PaUtil_AllocateMemory( sizeof(PaWinWdmPin) );
-    if( !pin )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    /* Zero the pin object */
-    /* memset( (void*)pin, 0, sizeof(PaWinWdmPin) ); */
-
-    pin->parentFilter = parentFilter;
-    pin->pinId = pinId;
-
-    /* Allocate a connect structure */
-    pin->pinConnectSize = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX);
-    pin->pinConnect = (KSPIN_CONNECT*)PaUtil_AllocateMemory( pin->pinConnectSize );
-    if( !pin->pinConnect )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    /* Configure the connect structure with default values */
-    pin->pinConnect->Interface.Set               = KSINTERFACESETID_Standard;
-    pin->pinConnect->Interface.Id                = KSINTERFACE_STANDARD_STREAMING;
-    pin->pinConnect->Interface.Flags             = 0;
-    pin->pinConnect->Medium.Set                  = KSMEDIUMSETID_Standard;
-    pin->pinConnect->Medium.Id                   = KSMEDIUM_TYPE_ANYINSTANCE;
-    pin->pinConnect->Medium.Flags                = 0;
-    pin->pinConnect->PinId                       = pinId;
-    pin->pinConnect->PinToHandle                 = NULL;
-    pin->pinConnect->Priority.PriorityClass      = KSPRIORITY_NORMAL;
-    pin->pinConnect->Priority.PrioritySubClass   = 1;
-    pin->ksDataFormatWfx = (KSDATAFORMAT_WAVEFORMATEX*)(pin->pinConnect + 1);
-    pin->ksDataFormatWfx->DataFormat.FormatSize  = sizeof(KSDATAFORMAT_WAVEFORMATEX);
-    pin->ksDataFormatWfx->DataFormat.Flags       = 0;
-    pin->ksDataFormatWfx->DataFormat.Reserved    = 0;
-    pin->ksDataFormatWfx->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
-    pin->ksDataFormatWfx->DataFormat.SubFormat   = KSDATAFORMAT_SUBTYPE_PCM;
-    pin->ksDataFormatWfx->DataFormat.Specifier   = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
-
-    pin->frameSize = 0; /* Unknown until we instantiate pin */
-
-    /* Get the COMMUNICATION property */
-    result = WdmGetPinPropertySimple(
-        parentFilter->handle,
-        pinId,
-        &KSPROPSETID_Pin,
-        KSPROPERTY_PIN_COMMUNICATION,
-        &pin->communication,
-        sizeof(KSPIN_COMMUNICATION));
-    if( result != paNoError )
-        goto error;
-
-    if( /*(pin->communication != KSPIN_COMMUNICATION_SOURCE) &&*/
-         (pin->communication != KSPIN_COMMUNICATION_SINK) &&
-         (pin->communication != KSPIN_COMMUNICATION_BOTH) )
-    {
-        PA_DEBUG(("Not source/sink\n"));
-        result = paInvalidDevice;
-        goto error;
-    }
-
-    /* Get dataflow information */
-    result = WdmGetPinPropertySimple(
-        parentFilter->handle,
-        pinId,
-        &KSPROPSETID_Pin,
-        KSPROPERTY_PIN_DATAFLOW,
-        &pin->dataFlow,
-        sizeof(KSPIN_DATAFLOW));
-
-    if( result != paNoError )
-        goto error;
-
-    /* Get the INTERFACE property list */
-    result = WdmGetPinPropertyMulti(
-        parentFilter->handle,
-        pinId,
-        &KSPROPSETID_Pin,
-        KSPROPERTY_PIN_INTERFACES,
-        &item);
-
-    if( result != paNoError )
-        goto error;
-
-    identifier = (KSIDENTIFIER*)(item+1);
-
-    /* Check that at least one interface is STANDARD_STREAMING */
-    result = paUnanticipatedHostError;
-    for( i = 0; i < item->Count; i++ )
-    {
-        if( !memcmp( (void*)&identifier[i].Set, (void*)&KSINTERFACESETID_Standard, sizeof( GUID ) ) &&
-            ( identifier[i].Id == KSINTERFACE_STANDARD_STREAMING ) )
-        {
-            result = paNoError;
-            break;
-        }
-    }
-
-    if( result != paNoError )
-    {
-        PA_DEBUG(("No standard streaming\n"));
-        goto error;
-    }
-
-    /* Don't need interfaces any more */
-    PaUtil_FreeMemory( item );
-    item = NULL;
-
-    /* Get the MEDIUM properties list */
-    result = WdmGetPinPropertyMulti(
-        parentFilter->handle,
-        pinId,
-        &KSPROPSETID_Pin,
-        KSPROPERTY_PIN_MEDIUMS,
-        &item);
-
-    if( result != paNoError )
-        goto error;
-
-    identifier = (KSIDENTIFIER*)(item+1); /* Not actually necessary... */
-
-    /* Check that at least one medium is STANDARD_DEVIO */
-    result = paUnanticipatedHostError;
-    for( i = 0; i < item->Count; i++ )
-    {
-        if( !memcmp( (void*)&identifier[i].Set, (void*)&KSMEDIUMSETID_Standard, sizeof( GUID ) ) &&
-           ( identifier[i].Id == KSMEDIUM_STANDARD_DEVIO ) )
-        {
-            result = paNoError;
-            break;
-        }
-    }
-
-    if( result != paNoError )
-    {
-        PA_DEBUG(("No standard devio\n"));
-        goto error;
-    }
-    /* Don't need mediums any more */
-    PaUtil_FreeMemory( item );
-    item = NULL;
-
-    /* Get DATARANGES */
-    result = WdmGetPinPropertyMulti(
-        parentFilter->handle,
-        pinId,
-        &KSPROPSETID_Pin,
-        KSPROPERTY_PIN_DATARANGES,
-        &pin->dataRangesItem);
-
-    if( result != paNoError )
-        goto error;
-
-    pin->dataRanges = (KSDATARANGE*)(pin->dataRangesItem +1);
-
-    /* Check that at least one datarange supports audio */
-    result = paUnanticipatedHostError;
-    dataRange = pin->dataRanges;
-    pin->maxChannels = 0;
-    pin->bestSampleRate = 0;
-    pin->formats = 0;
-    for( i = 0; i <pin->dataRangesItem->Count; i++)
-    {
-        PA_DEBUG(("DR major format %x\n",*(unsigned long*)(&(dataRange->MajorFormat))));
-        /* Check that subformat is WAVEFORMATEX, PCM or WILDCARD */
-        if( IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat) ||
-            !memcmp((void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_PCM, sizeof ( GUID ) ) ||
-            ( !memcmp((void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof ( GUID ) ) &&
-            ( !memcmp((void*)&dataRange->MajorFormat, (void*)&KSDATAFORMAT_TYPE_AUDIO, sizeof ( GUID ) ) ) ) )
-        {
-            result = paNoError;
-            /* Record the maximum possible channels with this pin */
-            PA_DEBUG(("MaxChannel: %d\n",pin->maxChannels));
-            if( (int)((KSDATARANGE_AUDIO*)dataRange)->MaximumChannels > pin->maxChannels )
-            {
-                pin->maxChannels = ((KSDATARANGE_AUDIO*)dataRange)->MaximumChannels;
-                /*PA_DEBUG(("MaxChannel: %d\n",pin->maxChannels));*/
-            }
-            /* Record the formats (bit depths) that are supported */
-            if( ((KSDATARANGE_AUDIO*)dataRange)->MinimumBitsPerSample <= 16 )
-            {
-                pin->formats |= paInt16;
-                PA_DEBUG(("Format 16 bit supported\n"));
-            }
-            if( ((KSDATARANGE_AUDIO*)dataRange)->MaximumBitsPerSample >= 24 )
-            {
-                pin->formats |= paInt24;
-                PA_DEBUG(("Format 24 bit supported\n"));
-            }
-            if( ( pin->bestSampleRate != 48000) &&
-                (((KSDATARANGE_AUDIO*)dataRange)->MaximumSampleFrequency >= 48000) &&
-                (((KSDATARANGE_AUDIO*)dataRange)->MinimumSampleFrequency <= 48000) )
-            {
-                pin->bestSampleRate = 48000;
-                PA_DEBUG(("48kHz supported\n"));
-            }
-            else if(( pin->bestSampleRate != 48000) && ( pin->bestSampleRate != 44100 ) &&
-                (((KSDATARANGE_AUDIO*)dataRange)->MaximumSampleFrequency >= 44100) &&
-                (((KSDATARANGE_AUDIO*)dataRange)->MinimumSampleFrequency <= 44100) )
-            {
-                pin->bestSampleRate = 44100;
-                PA_DEBUG(("44.1kHz supported\n"));
-            }
-            else
-            {
-                pin->bestSampleRate = ((KSDATARANGE_AUDIO*)dataRange)->MaximumSampleFrequency;
-            }
-        }
-        dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize);
-    }
-
-    if( result != paNoError )
-        goto error;
-
-    /* Get instance information */
-    result = WdmGetPinPropertySimple(
-        parentFilter->handle,
-        pinId,
-        &KSPROPSETID_Pin,
-        KSPROPERTY_PIN_CINSTANCES,
-        &pin->instances,
-        sizeof(KSPIN_CINSTANCES));
-
-    if( result != paNoError )
-        goto error;
-
-    /* Success */
-    *error = paNoError;
-    PA_DEBUG(("Pin created successfully\n"));
-    PA_LOGL_;
-    return pin;
-
-error:
-    /*
-    Error cleanup
-    */
-    PaUtil_FreeMemory( item );
-    if( pin )
-    {
-        PaUtil_FreeMemory( pin->pinConnect );
-        PaUtil_FreeMemory( pin->dataRangesItem );
-        PaUtil_FreeMemory( pin );
-    }
-    *error = result;
-    PA_LOGL_;
-    return NULL;
-}
-
-/*
-Safely free all resources associated with the pin
-*/
-static void PinFree(PaWinWdmPin* pin)
-{
-    PA_LOGE_;
-    if( pin )
-    {
-        PinClose(pin);
-        if( pin->pinConnect )
-        {
-            PaUtil_FreeMemory( pin->pinConnect );
-        }
-        if( pin->dataRangesItem )
-        {
-            PaUtil_FreeMemory( pin->dataRangesItem );
-        }
-        PaUtil_FreeMemory( pin );
-    }
-    PA_LOGL_;
-}
-
-/*
-If the pin handle is open, close it
-*/
-static void PinClose(PaWinWdmPin* pin)
-{
-    PA_LOGE_;
-    if( pin == NULL )
-    {
-        PA_DEBUG(("Closing NULL pin!"));
-        PA_LOGL_;
-        return;
-    }
-    if( pin->handle != NULL )
-    {
-        PinSetState( pin, KSSTATE_PAUSE );
-        PinSetState( pin, KSSTATE_STOP );
-        CloseHandle( pin->handle );
-        pin->handle = NULL;
-        FilterRelease(pin->parentFilter);
-    }
-    PA_LOGL_;
-}
-
-/*
-Set the state of this (instantiated) pin
-*/
-static PaError PinSetState(PaWinWdmPin* pin, KSSTATE state)
-{
-    PaError result;
-
-    PA_LOGE_;
-    if( pin == NULL )
-        return paInternalError;
-    if( pin->handle == NULL )
-        return paInternalError;
-
-    result = WdmSetPropertySimple(
-        pin->handle,
-        &KSPROPSETID_Connection,
-        KSPROPERTY_CONNECTION_STATE,
-        &state,
-        sizeof(state),
-        NULL,
-        0);
-    PA_LOGL_;
-    return result;
-}
-
-static PaError PinInstantiate(PaWinWdmPin* pin)
-{
-    PaError result;
-    unsigned long createResult;
-    KSALLOCATOR_FRAMING ksaf;
-    KSALLOCATOR_FRAMING_EX ksafex;
-
-    PA_LOGE_;
-
-    if( pin == NULL )
-        return paInternalError;
-    if(!pin->pinConnect)
-        return paInternalError;
-
-    FilterUse(pin->parentFilter);
-
-    createResult = FunctionKsCreatePin(
-        pin->parentFilter->handle,
-        pin->pinConnect,
-        GENERIC_WRITE | GENERIC_READ,
-        &pin->handle
-        );
-
-    PA_DEBUG(("Pin create result = %x\n",createResult));
-    if( createResult != ERROR_SUCCESS )
-    {
-        FilterRelease(pin->parentFilter);
-        pin->handle = NULL;
-        return paInvalidDevice;
-    }
-
-    result = WdmGetPropertySimple(
-        pin->handle,
-        &KSPROPSETID_Connection,
-        KSPROPERTY_CONNECTION_ALLOCATORFRAMING,
-        &ksaf,
-        sizeof(ksaf),
-        NULL,
-        0);
-
-    if( result != paNoError )
-    {
-        result = WdmGetPropertySimple(
-            pin->handle,
-            &KSPROPSETID_Connection,
-            KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX,
-            &ksafex,
-            sizeof(ksafex),
-            NULL,
-            0);
-        if( result == paNoError )
-        {
-            pin->frameSize = ksafex.FramingItem[0].FramingRange.Range.MinFrameSize;
-        }
-    }
-    else
-    {
-        pin->frameSize = ksaf.FrameSize;
-    }
-
-    PA_LOGL_;
-
-    return paNoError;
-}
-
-/* NOT USED
-static PaError PinGetState(PaWinWdmPin* pin, KSSTATE* state)
-{
-    PaError result;
-
-    if( state == NULL )
-        return paInternalError;
-    if( pin == NULL )
-        return paInternalError;
-    if( pin->handle == NULL )
-        return paInternalError;
-
-    result = WdmGetPropertySimple(
-        pin->handle,
-        KSPROPSETID_Connection,
-        KSPROPERTY_CONNECTION_STATE,
-        state,
-        sizeof(KSSTATE),
-        NULL,
-        0);
-
-    return result;
-}
-*/
-static PaError PinSetFormat(PaWinWdmPin* pin, const WAVEFORMATEX* format)
-{
-    unsigned long size;
-    void* newConnect;
-
-    PA_LOGE_;
-
-    if( pin == NULL )
-        return paInternalError;
-    if( format == NULL )
-        return paInternalError;
-
-    size = GetWfexSize(format) + sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX) - sizeof(WAVEFORMATEX);
-
-    if( pin->pinConnectSize != size )
-    {
-        newConnect = PaUtil_AllocateMemory( size );
-        if( newConnect == NULL )
-            return paInsufficientMemory;
-        memcpy( newConnect, (void*)pin->pinConnect, min(pin->pinConnectSize,size) );
-        PaUtil_FreeMemory( pin->pinConnect );
-        pin->pinConnect = (KSPIN_CONNECT*)newConnect;
-        pin->pinConnectSize = size;
-        pin->ksDataFormatWfx = (KSDATAFORMAT_WAVEFORMATEX*)((KSPIN_CONNECT*)newConnect + 1);
-        pin->ksDataFormatWfx->DataFormat.FormatSize = size - sizeof(KSPIN_CONNECT);
-    }
-
-    memcpy( (void*)&(pin->ksDataFormatWfx->WaveFormatEx), format, GetWfexSize(format) );
-    pin->ksDataFormatWfx->DataFormat.SampleSize = (unsigned short)(format->nChannels * (format->wBitsPerSample / 8));
-
-    PA_LOGL_;
-
-    return paNoError;
-}
-
-static PaError PinIsFormatSupported(PaWinWdmPin* pin, const WAVEFORMATEX* format)
-{
-    KSDATARANGE_AUDIO* dataRange;
-    unsigned long count;
-    GUID guid = DYNAMIC_GUID( DEFINE_WAVEFORMATEX_GUID(format->wFormatTag) );
-    PaError result = paInvalidDevice;
-
-    PA_LOGE_;
-
-    if( format->wFormatTag == WAVE_FORMAT_EXTENSIBLE )
-    {
-        guid = ((WAVEFORMATEXTENSIBLE*)format)->SubFormat;
-    }
-    dataRange = (KSDATARANGE_AUDIO*)pin->dataRanges;
-    for(count = 0; count<pin->dataRangesItem->Count; count++)
-    {
-        if(( !memcmp(&(dataRange->DataRange.MajorFormat),&KSDATAFORMAT_TYPE_AUDIO,sizeof(GUID)) ) ||
-           ( !memcmp(&(dataRange->DataRange.MajorFormat),&KSDATAFORMAT_TYPE_WILDCARD,sizeof(GUID)) ))
-        {
-            /* This is an audio or wildcard datarange... */
-            if(( !memcmp(&(dataRange->DataRange.SubFormat),&KSDATAFORMAT_SUBTYPE_WILDCARD,sizeof(GUID)) ) ||
-                ( !memcmp(&(dataRange->DataRange.SubFormat),&guid,sizeof(GUID)) ))
-            {
-                if(( !memcmp(&(dataRange->DataRange.Specifier),&KSDATAFORMAT_SPECIFIER_WILDCARD,sizeof(GUID)) ) ||
-                  ( !memcmp(&(dataRange->DataRange.Specifier),&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX,sizeof(GUID) )))
-                {
-
-                    PA_DEBUG(("Pin:%x, DataRange:%d\n",(void*)pin,count));
-                    PA_DEBUG(("\tFormatSize:%d, SampleSize:%d\n",dataRange->DataRange.FormatSize,dataRange->DataRange.SampleSize));
-                    PA_DEBUG(("\tMaxChannels:%d\n",dataRange->MaximumChannels));
-                    PA_DEBUG(("\tBits:%d-%d\n",dataRange->MinimumBitsPerSample,dataRange->MaximumBitsPerSample));
-                    PA_DEBUG(("\tSampleRate:%d-%d\n",dataRange->MinimumSampleFrequency,dataRange->MaximumSampleFrequency));
-
-                    if( dataRange->MaximumChannels < format->nChannels )
-                    {
-                        result = paInvalidChannelCount;
-                        continue;
-                    }
-                    if( dataRange->MinimumBitsPerSample > format->wBitsPerSample )
-                    {
-                        result = paSampleFormatNotSupported;
-                        continue;
-                    }
-                    if( dataRange->MaximumBitsPerSample < format->wBitsPerSample )
-                    {
-                        result = paSampleFormatNotSupported;
-                        continue;
-                    }
-                    if( dataRange->MinimumSampleFrequency > format->nSamplesPerSec )
-                    {
-                        result = paInvalidSampleRate;
-                        continue;
-                    }
-                    if( dataRange->MaximumSampleFrequency < format->nSamplesPerSec )
-                    {
-                        result = paInvalidSampleRate;
-                        continue;
-                    }
-                    /* Success! */
-                    PA_LOGL_;
-                    return paNoError;
-                }
-            }
-        }
-        dataRange = (KSDATARANGE_AUDIO*)( ((char*)dataRange) + dataRange->DataRange.FormatSize);
-    }
-
-    PA_LOGL_;
-
-    return result;
-}
-
-/**
- * Create a new filter object
- */
-static PaWinWdmFilter* FilterNew(TCHAR* filterName, TCHAR* friendlyName, PaError* error)
-{
-    PaWinWdmFilter* filter;
-    PaError result;
-    int pinId;
-    int valid;
-
-
-    /* Allocate the new filter object */
-    filter = (PaWinWdmFilter*)PaUtil_AllocateMemory( sizeof(PaWinWdmFilter) );
-    if( !filter )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    /* Zero the filter object - done by AllocateMemory */
-    /* memset( (void*)filter, 0, sizeof(PaWinWdmFilter) ); */
-
-    /* Copy the filter name */
-    _tcsncpy(filter->filterName, filterName, MAX_PATH);
-
-    /* Copy the friendly name */
-    _tcsncpy(filter->friendlyName, friendlyName, MAX_PATH);
-
-    /* Open the filter handle */
-    result = FilterUse(filter);
-    if( result != paNoError )
-    {
-        goto error;
-    }
-
-    /* Get pin count */
-    result = WdmGetPinPropertySimple
-        (
-        filter->handle,
-        0,
-        &KSPROPSETID_Pin,
-        KSPROPERTY_PIN_CTYPES,
-        &filter->pinCount,
-        sizeof(filter->pinCount)
-        );
-
-    if( result != paNoError)
-    {
-        goto error;
-    }
-
-    /* Allocate pointer array to hold the pins */
-    filter->pins = (PaWinWdmPin**)PaUtil_AllocateMemory( sizeof(PaWinWdmPin*) * filter->pinCount );
-    if( !filter->pins )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    /* Create all the pins we can */
-    filter->maxInputChannels = 0;
-    filter->maxOutputChannels = 0;
-    filter->bestSampleRate = 0;
-
-    valid = 0;
-    for(pinId = 0; pinId < filter->pinCount; pinId++)
-    {
-        /* Create the pin with this Id */
-        PaWinWdmPin* newPin;
-        newPin = PinNew(filter, pinId, &result);
-        if( result == paInsufficientMemory )
-            goto error;
-        if( newPin != NULL )
-        {
-            filter->pins[pinId] = newPin;
-            valid = 1;
-
-            /* Get the max output channel count */
-            if(( newPin->dataFlow == KSPIN_DATAFLOW_IN ) &&
-                (( newPin->communication == KSPIN_COMMUNICATION_SINK) ||
-                 ( newPin->communication == KSPIN_COMMUNICATION_BOTH)))
-            {
-                if(newPin->maxChannels > filter->maxOutputChannels)
-                    filter->maxOutputChannels = newPin->maxChannels;
-                filter->formats |= newPin->formats;
-            }
-            /* Get the max input channel count */
-            if(( newPin->dataFlow == KSPIN_DATAFLOW_OUT ) &&
-                (( newPin->communication == KSPIN_COMMUNICATION_SINK) ||
-                 ( newPin->communication == KSPIN_COMMUNICATION_BOTH)))
-            {
-                if(newPin->maxChannels > filter->maxInputChannels)
-                    filter->maxInputChannels = newPin->maxChannels;
-                filter->formats |= newPin->formats;
-            }
-
-            if(newPin->bestSampleRate > filter->bestSampleRate)
-            {
-                filter->bestSampleRate = newPin->bestSampleRate;
-            }
-        }
-    }
-
-    if(( filter->maxInputChannels == 0) && ( filter->maxOutputChannels == 0))
-    {
-        /* No input or output... not valid */
-        valid = 0;
-    }
-
-    if( !valid )
-    {
-        /* No valid pin was found on this filter so we destroy it */
-        result = paDeviceUnavailable;
-        goto error;
-    }
-
-    /* Close the filter handle for now
-     * It will be opened later when needed */
-    FilterRelease(filter);
-
-    *error = paNoError;
-    return filter;
-
-error:
-    /*
-    Error cleanup
-    */
-    if( filter )
-    {
-        for( pinId = 0; pinId < filter->pinCount; pinId++ )
-            PinFree(filter->pins[pinId]);
-        PaUtil_FreeMemory( filter->pins );
-        if( filter->handle )
-            CloseHandle( filter->handle );
-        PaUtil_FreeMemory( filter );
-    }
-    *error = result;
-    return NULL;
-}
-
-/**
- * Free a previously created filter
- */
-static void FilterFree(PaWinWdmFilter* filter)
-{
-    int pinId;
-    PA_LOGL_;
-    if( filter )
-    {
-        for( pinId = 0; pinId < filter->pinCount; pinId++ )
-            PinFree(filter->pins[pinId]);
-        PaUtil_FreeMemory( filter->pins );
-        if( filter->handle )
-            CloseHandle( filter->handle );
-        PaUtil_FreeMemory( filter );
-    }
-    PA_LOGE_;
-}
-
-/**
- * Reopen the filter handle if necessary so it can be used
- **/
-static PaError FilterUse(PaWinWdmFilter* filter)
-{
-    assert( filter );
-
-    PA_LOGE_;
-    if( filter->handle == NULL )
-    {
-        /* Open the filter */
-        filter->handle = CreateFile(
-            filter->filterName,
-            GENERIC_READ | GENERIC_WRITE,
-            0,
-            NULL,
-            OPEN_EXISTING,
-            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
-            NULL);
-
-        if( filter->handle == NULL )
-        {
-            return paDeviceUnavailable;
-        }
-    }
-    filter->usageCount++;
-    PA_LOGL_;
-    return paNoError;
-}
-
-/**
- * Release the filter handle if nobody is using it
- **/
-static void FilterRelease(PaWinWdmFilter* filter)
-{
-    assert( filter );
-    assert( filter->usageCount > 0 );
-
-    PA_LOGE_;
-    filter->usageCount--;
-    if( filter->usageCount == 0 )
-    {
-        if( filter->handle != NULL )
-        {
-            CloseHandle( filter->handle );
-            filter->handle = NULL;
-        }
-    }
-    PA_LOGL_;
-}
-
-/**
- * Create a render (playback) Pin using the supplied format
- **/
-static PaWinWdmPin* FilterCreateRenderPin(PaWinWdmFilter* filter,
-    const WAVEFORMATEX* wfex,
-    PaError* error)
-{
-    PaError result;
-    PaWinWdmPin* pin;
-
-    assert( filter );
-
-    pin = FilterFindViableRenderPin(filter,wfex,&result);
-    if(!pin)
-    {
-        goto error;
-    }
-    result = PinSetFormat(pin,wfex);
-    if( result != paNoError )
-    {
-        goto error;
-    }
-    result = PinInstantiate(pin);
-    if( result != paNoError )
-    {
-        goto error;
-    }
-
-    *error = paNoError;
-    return pin;
-
-error:
-    *error = result;
-    return NULL;
-}
-
-/**
- * Find a pin that supports the given format
- **/
-static PaWinWdmPin* FilterFindViableRenderPin(PaWinWdmFilter* filter,
-    const WAVEFORMATEX* wfex,
-    PaError* error)
-{
-    int pinId;
-    PaWinWdmPin*  pin;
-    PaError result = paDeviceUnavailable;
-    *error = paNoError;
-
-    assert( filter );
-
-    for( pinId = 0; pinId<filter->pinCount; pinId++ )
-    {
-        pin = filter->pins[pinId];
-        if( pin != NULL )
-        {
-            if(( pin->dataFlow == KSPIN_DATAFLOW_IN ) &&
-                (( pin->communication == KSPIN_COMMUNICATION_SINK) ||
-                 ( pin->communication == KSPIN_COMMUNICATION_BOTH)))
-            {
-                result = PinIsFormatSupported( pin, wfex );
-                if( result == paNoError )
-                {
-                    return pin;
-                }
-            }
-        }
-    }
-
-    *error = result;
-    return NULL;
-}
-
-/**
- * Check if there is a pin that should playback
- * with the supplied format
- **/
-static PaError FilterCanCreateRenderPin(PaWinWdmFilter* filter,
-    const WAVEFORMATEX* wfex)
-{
-    PaWinWdmPin* pin;
-    PaError result;
-
-    assert ( filter );
-
-    pin = FilterFindViableRenderPin(filter,wfex,&result);
-    /* result will be paNoError if pin found
-     * or else an error code indicating what is wrong with the format
-     **/
-    return result;
-}
-
-/**
- * Create a capture (record) Pin using the supplied format
- **/
-static PaWinWdmPin* FilterCreateCapturePin(PaWinWdmFilter* filter,
-    const WAVEFORMATEX* wfex,
-    PaError* error)
-{
-    PaError result;
-    PaWinWdmPin* pin;
-
-    assert( filter );
-
-    pin = FilterFindViableCapturePin(filter,wfex,&result);
-    if(!pin)
-    {
-        goto error;
-    }
-
-    result = PinSetFormat(pin,wfex);
-    if( result != paNoError )
-    {
-        goto error;
-    }
-
-    result = PinInstantiate(pin);
-    if( result != paNoError )
-    {
-        goto error;
-    }
-
-    *error = paNoError;
-    return pin;
-
-error:
-    *error = result;
-    return NULL;
-}
-
-/**
- * Find a capture pin that supports the given format
- **/
-static PaWinWdmPin* FilterFindViableCapturePin(PaWinWdmFilter* filter,
-    const WAVEFORMATEX* wfex,
-    PaError* error)
-{
-    int pinId;
-    PaWinWdmPin*  pin;
-    PaError result = paDeviceUnavailable;
-    *error = paNoError;
-
-    assert( filter );
-
-    for( pinId = 0; pinId<filter->pinCount; pinId++ )
-    {
-        pin = filter->pins[pinId];
-        if( pin != NULL )
-        {
-            if(( pin->dataFlow == KSPIN_DATAFLOW_OUT ) &&
-                (( pin->communication == KSPIN_COMMUNICATION_SINK) ||
-                 ( pin->communication == KSPIN_COMMUNICATION_BOTH)))
-            {
-                result = PinIsFormatSupported( pin, wfex );
-                if( result == paNoError )
-                {
-                    return pin;
-                }
-            }
-        }
-    }
-
-    *error = result;
-    return NULL;
-}
-
-/**
- * Check if there is a pin that should playback
- * with the supplied format
- **/
-static PaError FilterCanCreateCapturePin(PaWinWdmFilter* filter,
-    const WAVEFORMATEX* wfex)
-{
-    PaWinWdmPin* pin;
-    PaError result;
-
-    assert ( filter );
-
-    pin = FilterFindViableCapturePin(filter,wfex,&result);
-    /* result will be paNoError if pin found
-     * or else an error code indicating what is wrong with the format
-     **/
-    return result;
-}
-
-/**
- * Build the list of available filters
- */
-static PaError BuildFilterList(PaWinWdmHostApiRepresentation* wdmHostApi)
-{
-    PaError result = paNoError;
-    HDEVINFO handle = NULL;
-    int device;
-    int invalidDevices;
-    int slot;
-    SP_DEVICE_INTERFACE_DATA interfaceData;
-    SP_DEVICE_INTERFACE_DATA aliasData;
-    SP_DEVINFO_DATA devInfoData;
-    int noError;
-    const int sizeInterface = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR));
-    unsigned char interfaceDetailsArray[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR))];
-    SP_DEVICE_INTERFACE_DETAIL_DATA* devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA*)interfaceDetailsArray;
-    TCHAR friendlyName[MAX_PATH];
-    HKEY hkey;
-    DWORD sizeFriendlyName;
-    DWORD type;
-    PaWinWdmFilter* newFilter;
-    GUID* category = (GUID*)&KSCATEGORY_AUDIO;
-    GUID* alias_render = (GUID*)&KSCATEGORY_RENDER;
-    GUID* alias_capture = (GUID*)&KSCATEGORY_CAPTURE;
-    DWORD hasAlias;
-
-    PA_LOGE_;
-
-    devInterfaceDetails->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
-
-    /* Open a handle to search for devices (filters) */
-    handle = SetupDiGetClassDevs(category,NULL,NULL,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
-    if( handle == NULL )
-    {
-        return paUnanticipatedHostError;
-    }
-    PA_DEBUG(("Setup called\n"));
-
-    /* First let's count the number of devices so we can allocate a list */
-    invalidDevices = 0;
-    for( device = 0;;device++ )
-    {
-        interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
-        interfaceData.Reserved = 0;
-        aliasData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
-        aliasData.Reserved = 0;
-        noError = SetupDiEnumDeviceInterfaces(handle,NULL,category,device,&interfaceData);
-        PA_DEBUG(("Enum called\n"));
-        if( !noError )
-            break; /* No more devices */
-
-        /* Check this one has the render or capture alias */
-        hasAlias = 0;
-        noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_render,&aliasData);
-        PA_DEBUG(("noError = %d\n",noError));
-        if(noError)
-        {
-            if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED)))
-            {
-                PA_DEBUG(("Device %d has render alias\n",device));
-                hasAlias |= 1; /* Has render alias */
-            }
-            else
-            {
-                PA_DEBUG(("Device %d has no render alias\n",device));
-            }
-        }
-        noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_capture,&aliasData);
-        if(noError)
-        {
-            if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED)))
-            {
-                PA_DEBUG(("Device %d has capture alias\n",device));
-                hasAlias |= 2; /* Has capture alias */
-            }
-            else
-            {
-                PA_DEBUG(("Device %d has no capture alias\n",device));
-            }
-        }
-        if(!hasAlias)
-            invalidDevices++; /* This was not a valid capture or render audio device */
-
-    }
-    /* Remember how many there are */
-    wdmHostApi->filterCount = device-invalidDevices;
-
-    PA_DEBUG(("Interfaces found: %d\n",device-invalidDevices));
-
-    /* Now allocate the list of pointers to devices */
-    wdmHostApi->filters  = (PaWinWdmFilter**)PaUtil_AllocateMemory( sizeof(PaWinWdmFilter*) * device );
-    if( !wdmHostApi->filters )
-    {
-        if(handle != NULL)
-            SetupDiDestroyDeviceInfoList(handle);
-        return paInsufficientMemory;
-    }
-
-    /* Now create filter objects for each interface found */
-    slot = 0;
-    for( device = 0;;device++ )
-    {
-        interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
-        interfaceData.Reserved = 0;
-        aliasData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
-        aliasData.Reserved = 0;
-        devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-        devInfoData.Reserved = 0;
-
-        noError = SetupDiEnumDeviceInterfaces(handle,NULL,category,device,&interfaceData);
-        if( !noError )
-            break; /* No more devices */
-
-        /* Check this one has the render or capture alias */
-        hasAlias = 0;
-        noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_render,&aliasData);
-        if(noError)
-        {
-            if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED)))
-            {
-                PA_DEBUG(("Device %d has render alias\n",device));
-                hasAlias |= 1; /* Has render alias */
-            }
-        }
-        noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_capture,&aliasData);
-        if(noError)
-        {
-            if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED)))
-            {
-                PA_DEBUG(("Device %d has capture alias\n",device));
-                hasAlias |= 2; /* Has capture alias */
-            }
-        }
-        if(!hasAlias)
-            continue; /* This was not a valid capture or render audio device */
-
-        noError = SetupDiGetDeviceInterfaceDetail(handle,&interfaceData,devInterfaceDetails,sizeInterface,NULL,&devInfoData);
-        if( noError )
-        {
-            /* Try to get the "friendly name" for this interface */
-            sizeFriendlyName = sizeof(friendlyName);
-            /* Fix contributed by Ben Allison
-             * Removed KEY_SET_VALUE from flags on following call
-             * as its causes failure when running without admin rights
-             * and it was not required */
-            hkey=SetupDiOpenDeviceInterfaceRegKey(handle,&interfaceData,0,KEY_QUERY_VALUE);
-            if(hkey!=INVALID_HANDLE_VALUE)
-            {
-                noError = RegQueryValueEx(hkey,TEXT("FriendlyName"),0,&type,(BYTE*)friendlyName,&sizeFriendlyName);
-                if( noError == ERROR_SUCCESS )
-                {
-                    PA_DEBUG(("Interface %d, Name: %s\n",device,friendlyName));
-                    RegCloseKey(hkey);
-                }
-                else
-                {
-                    friendlyName[0] = 0;
-                }
-            }
-            newFilter = FilterNew(devInterfaceDetails->DevicePath,friendlyName,&result);
-            if( result == paNoError )
-            {
-                PA_DEBUG(("Filter created\n"));
-                wdmHostApi->filters[slot] = newFilter;
-                slot++;
-            }
-            else
-            {
-                PA_DEBUG(("Filter NOT created\n"));
-                /* As there are now less filters than we initially thought
-                 * we must reduce the count by one */
-                wdmHostApi->filterCount--;
-            }
-        }
-    }
-
-    /* Clean up */
-    if(handle != NULL)
-        SetupDiDestroyDeviceInfoList(handle);
-
-    return paNoError;
-}
-
-PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
-{
-    PaError result = paNoError;
-    int i, deviceCount;
-    PaWinWdmHostApiRepresentation *wdmHostApi;
-    PaWinWdmDeviceInfo *deviceInfoArray;
-    PaWinWdmFilter* pFilter;
-    PaWinWdmDeviceInfo *wdmDeviceInfo;
-    PaDeviceInfo *deviceInfo;
-
-    PA_LOGE_;
-
-    /*
-    Attempt to load the KSUSER.DLL without which we cannot create pins
-    We will unload this on termination
-    */
-    if(DllKsUser == NULL)
-    {
-        DllKsUser = LoadLibrary(TEXT("ksuser.dll"));
-        if(DllKsUser == NULL)
-            goto error;
-    }
-
-    FunctionKsCreatePin = (KSCREATEPIN*)GetProcAddress(DllKsUser, "KsCreatePin");
-    if(FunctionKsCreatePin == NULL)
-        goto error;
-
-    wdmHostApi = (PaWinWdmHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinWdmHostApiRepresentation) );
-    if( !wdmHostApi )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    wdmHostApi->allocations = PaUtil_CreateAllocationGroup();
-    if( !wdmHostApi->allocations )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    result = BuildFilterList( wdmHostApi );
-    if( result != paNoError )
-    {
-        goto error;
-    }
-    deviceCount = wdmHostApi->filterCount;
-
-    *hostApi = &wdmHostApi->inheritedHostApiRep;
-    (*hostApi)->info.structVersion = 1;
-    (*hostApi)->info.type = paWDMKS;
-    (*hostApi)->info.name = "Windows WDM-KS";
-    (*hostApi)->info.defaultInputDevice = paNoDevice;
-    (*hostApi)->info.defaultOutputDevice = paNoDevice;
-
-    if( deviceCount > 0 )
-    {
-        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
-               wdmHostApi->allocations, sizeof(PaWinWdmDeviceInfo*) * deviceCount );
-        if( !(*hostApi)->deviceInfos )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        /* allocate all device info structs in a contiguous block */
-        deviceInfoArray = (PaWinWdmDeviceInfo*)PaUtil_GroupAllocateMemory(
-                wdmHostApi->allocations, sizeof(PaWinWdmDeviceInfo) * deviceCount );
-        if( !deviceInfoArray )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        for( i=0; i < deviceCount; ++i )
-        {
-            wdmDeviceInfo = &deviceInfoArray[i];
-            deviceInfo = &wdmDeviceInfo->inheritedDeviceInfo;
-            pFilter = wdmHostApi->filters[i];
-            if( pFilter == NULL )
-                continue;
-            wdmDeviceInfo->filter = pFilter;
-            deviceInfo->structVersion = 2;
-            deviceInfo->hostApi = hostApiIndex;
-            deviceInfo->name = (char*)pFilter->friendlyName;
-            PA_DEBUG(("Device found name: %s\n",(char*)pFilter->friendlyName));
-            deviceInfo->maxInputChannels = pFilter->maxInputChannels;
-            if(deviceInfo->maxInputChannels > 0)
-            {
-                /* Set the default input device to the first device we find with
-                 * more than zero input channels
-                 **/
-                if((*hostApi)->info.defaultInputDevice == paNoDevice)
-                {
-                    (*hostApi)->info.defaultInputDevice = i;
-                }
-            }
-
-            deviceInfo->maxOutputChannels = pFilter->maxOutputChannels;
-            if(deviceInfo->maxOutputChannels > 0)
-            {
-                /* Set the default output device to the first device we find with
-                 * more than zero output channels
-                 **/
-                if((*hostApi)->info.defaultOutputDevice == paNoDevice)
-                {
-                    (*hostApi)->info.defaultOutputDevice = i;
-                }
-            }
-
-            /* These low values are not very useful because
-             * a) The lowest latency we end up with can depend on many factors such
-             *    as the device buffer sizes/granularities, sample rate, channels and format
-             * b) We cannot know the device buffer sizes until we try to open/use it at
-             *    a particular setting
-             * So: we give 512x48000Hz frames as the default low input latency
-             **/
-            deviceInfo->defaultLowInputLatency = (512.0/48000.0);
-            deviceInfo->defaultLowOutputLatency = (512.0/48000.0);
-            deviceInfo->defaultHighInputLatency = (4096.0/48000.0);
-            deviceInfo->defaultHighOutputLatency = (4096.0/48000.0);
-            deviceInfo->defaultSampleRate = (double)(pFilter->bestSampleRate);
-
-            (*hostApi)->deviceInfos[i] = deviceInfo;
-        }
-    }
-
-    (*hostApi)->info.deviceCount = deviceCount;
-
-    (*hostApi)->Terminate = Terminate;
-    (*hostApi)->OpenStream = OpenStream;
-    (*hostApi)->IsFormatSupported = IsFormatSupported;
-
-    PaUtil_InitializeStreamInterface( &wdmHostApi->callbackStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, GetStreamCpuLoad,
-                                      PaUtil_DummyRead, PaUtil_DummyWrite,
-                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
-
-    PaUtil_InitializeStreamInterface( &wdmHostApi->blockingStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
-                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
-
-    PA_LOGL_;
-    return result;
-
-error:
-    if( DllKsUser != NULL )
-    {
-        FreeLibrary( DllKsUser );
-        DllKsUser = NULL;
-    }
-
-    if( wdmHostApi )
-    {
-        PaUtil_FreeMemory( wdmHostApi->filters );
-        if( wdmHostApi->allocations )
-        {
-            PaUtil_FreeAllAllocations( wdmHostApi->allocations );
-            PaUtil_DestroyAllocationGroup( wdmHostApi->allocations );
-        }
-        PaUtil_FreeMemory( wdmHostApi );
-    }
-    PA_LOGL_;
-    return result;
-}
-
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
-{
-    PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi;
-    int i;
-    PA_LOGE_;
-
-    if( wdmHostApi->filters )
-    {
-        for( i=0; i<wdmHostApi->filterCount; i++)
-        {
-            if( wdmHostApi->filters[i] != NULL )
-            {
-                FilterFree( wdmHostApi->filters[i] );
-                wdmHostApi->filters[i] = NULL;
-            }
-        }
-    }
-    PaUtil_FreeMemory( wdmHostApi->filters );
-    if( wdmHostApi->allocations )
-    {
-        PaUtil_FreeAllAllocations( wdmHostApi->allocations );
-        PaUtil_DestroyAllocationGroup( wdmHostApi->allocations );
-    }
-    PaUtil_FreeMemory( wdmHostApi );
-    PA_LOGL_;
-}
-
-static void FillWFEXT( WAVEFORMATEXTENSIBLE* pwfext, PaSampleFormat sampleFormat, double sampleRate, int channelCount)
-{
-    PA_LOGE_;
-    PA_DEBUG(( "sampleFormat = %lx\n" , sampleFormat ));
-    PA_DEBUG(( "sampleRate = %f\n" , sampleRate ));
-    PA_DEBUG(( "chanelCount = %d\n", channelCount ));
-
-    pwfext->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
-    pwfext->Format.nChannels = channelCount;
-    pwfext->Format.nSamplesPerSec = (int)sampleRate;
-    if(channelCount == 1)
-        pwfext->dwChannelMask = KSAUDIO_SPEAKER_DIRECTOUT;
-    else
-        pwfext->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
-    if(sampleFormat == paFloat32)
-    {
-        pwfext->Format.nBlockAlign = channelCount * 4;
-        pwfext->Format.wBitsPerSample = 32;
-        pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
-        pwfext->Samples.wValidBitsPerSample = 32;
-        pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
-    }
-    else if(sampleFormat == paInt32)
-    {
-        pwfext->Format.nBlockAlign = channelCount * 4;
-        pwfext->Format.wBitsPerSample = 32;
-        pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
-        pwfext->Samples.wValidBitsPerSample = 32;
-        pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
-    }
-    else if(sampleFormat == paInt24)
-    {
-        pwfext->Format.nBlockAlign = channelCount * 3;
-        pwfext->Format.wBitsPerSample = 24;
-        pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
-        pwfext->Samples.wValidBitsPerSample = 24;
-        pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
-    }
-    else if(sampleFormat == paInt16)
-    {
-        pwfext->Format.nBlockAlign = channelCount * 2;
-        pwfext->Format.wBitsPerSample = 16;
-        pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
-        pwfext->Samples.wValidBitsPerSample = 16;
-        pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
-    }
-    pwfext->Format.nAvgBytesPerSec = pwfext->Format.nSamplesPerSec * pwfext->Format.nBlockAlign;
-
-    PA_LOGL_;
-}
-
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate )
-{
-    int inputChannelCount, outputChannelCount;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi;
-    PaWinWdmFilter* pFilter;
-    int result = paFormatIsSupported;
-    WAVEFORMATEXTENSIBLE wfx;
-
-    PA_LOGE_;
-
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-
-        /* all standard sample formats are supported by the buffer adapter,
-            this implementation doesn't support any custom sample formats */
-        if( inputSampleFormat & paCustomFormat )
-            return paSampleFormatNotSupported;
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that input device can support inputChannelCount */
-        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
-            return paInvalidChannelCount;
-
-        /* validate inputStreamInfo */
-        if( inputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-
-        /* Check that the input format is supported */
-        FillWFEXT(&wfx,paInt16,sampleRate,inputChannelCount);
-
-        pFilter = wdmHostApi->filters[inputParameters->device];
-        result = FilterCanCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx);
-        if( result != paNoError )
-        {
-            /* Try a WAVE_FORMAT_PCM instead */
-            wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
-            wfx.Format.cbSize = 0;
-            wfx.Samples.wValidBitsPerSample = 0;
-            wfx.dwChannelMask = 0;
-            wfx.SubFormat = GUID_NULL;
-            result = FilterCanCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx);
-            if( result != paNoError )
-                 return result;
-        }
-    }
-    else
-    {
-        inputChannelCount = 0;
-    }
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-
-        /* all standard sample formats are supported by the buffer adapter,
-            this implementation doesn't support any custom sample formats */
-        if( outputSampleFormat & paCustomFormat )
-            return paSampleFormatNotSupported;
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that output device can support outputChannelCount */
-        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
-            return paInvalidChannelCount;
-
-        /* validate outputStreamInfo */
-        if( outputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-
-        /* Check that the output format is supported */
-        FillWFEXT(&wfx,paInt16,sampleRate,outputChannelCount);
-
-        pFilter = wdmHostApi->filters[outputParameters->device];
-        result = FilterCanCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx);
-        if( result != paNoError )
-        {
-            /* Try a WAVE_FORMAT_PCM instead */
-            wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
-            wfx.Format.cbSize = 0;
-            wfx.Samples.wValidBitsPerSample = 0;
-            wfx.dwChannelMask = 0;
-            wfx.SubFormat = GUID_NULL;
-            result = FilterCanCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx);
-            if( result != paNoError )
-                 return result;
-        }
-
-    }
-    else
-    {
-        outputChannelCount = 0;
-    }
-
-    /*
-        IMPLEMENT ME:
-
-            - if a full duplex stream is requested, check that the combination
-                of input and output parameters is supported if necessary
-
-            - check that the device supports sampleRate
-
-        Because the buffer adapter handles conversion between all standard
-        sample formats, the following checks are only required if paCustomFormat
-        is implemented, or under some other unusual conditions.
-
-            - check that input device can support inputSampleFormat, or that
-                we have the capability to convert from inputSampleFormat to
-                a native format
-
-            - check that output device can support outputSampleFormat, or that
-                we have the capability to convert from outputSampleFormat to
-                a native format
-    */
-    if((inputChannelCount == 0)&&(outputChannelCount == 0))
-            result = paSampleFormatNotSupported; /* Not right error */
-
-    PA_LOGL_;
-    return result;
-}
-
-/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */
-
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData )
-{
-    PaError result = paNoError;
-    PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi;
-    PaWinWdmStream *stream = 0;
-    /* unsigned long framesPerHostBuffer; these may not be equivalent for all implementations */
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
-    int userInputChannels,userOutputChannels;
-    int size;
-    PaWinWdmFilter* pFilter;
-    WAVEFORMATEXTENSIBLE wfx;
-
-    PA_LOGE_;
-    PA_DEBUG(("OpenStream:sampleRate = %f\n",sampleRate));
-    PA_DEBUG(("OpenStream:framesPerBuffer = %lu\n",framesPerBuffer));
-
-    if( inputParameters )
-    {
-        userInputChannels = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that input device can support stream->userInputChannels */
-        if( userInputChannels > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
-            return paInvalidChannelCount;
-
-        /* validate inputStreamInfo */
-        if( inputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-
-    }
-    else
-    {
-        userInputChannels = 0;
-        inputSampleFormat = hostInputSampleFormat = paInt16; /* Surpress 'uninitialised var' warnings. */
-    }
-
-    if( outputParameters )
-    {
-        userOutputChannels = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-
-        /* unless alternate device specification is supported, reject the use of
-            paUseHostApiSpecificDeviceSpecification */
-
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
-            return paInvalidDevice;
-
-        /* check that output device can support stream->userInputChannels */
-        if( userOutputChannels > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
-            return paInvalidChannelCount;
-
-        /* validate outputStreamInfo */
-        if( outputParameters->hostApiSpecificStreamInfo )
-            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
-
-    }
-    else
-    {
-        userOutputChannels = 0;
-        outputSampleFormat = hostOutputSampleFormat = paInt16; /* Surpress 'uninitialized var' warnings. */
-    }
-
-    /* validate platform specific flags */
-    if( (streamFlags & paPlatformSpecificFlags) != 0 )
-        return paInvalidFlag; /* unexpected platform specific flag */
-
-    stream = (PaWinWdmStream*)PaUtil_AllocateMemory( sizeof(PaWinWdmStream) );
-    if( !stream )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-    /* Zero the stream object */
-    /* memset((void*)stream,0,sizeof(PaWinWdmStream)); */
-
-    if( streamCallback )
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &wdmHostApi->callbackStreamInterface, streamCallback, userData );
-    }
-    else
-    {
-        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                               &wdmHostApi->blockingStreamInterface, streamCallback, userData );
-    }
-
-    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
-
-    /* Instantiate the input pin if necessary */
-    if(userInputChannels > 0)
-    {
-        result = paSampleFormatNotSupported;
-        pFilter = wdmHostApi->filters[inputParameters->device];
-        stream->userInputChannels = userInputChannels;
-
-        if(((inputSampleFormat & ~paNonInterleaved) & pFilter->formats) != 0)
-        {   /* inputSampleFormat is supported, so try to use it */
-            hostInputSampleFormat = inputSampleFormat;
-            FillWFEXT(&wfx, hostInputSampleFormat, sampleRate, stream->userInputChannels);
-            stream->bytesPerInputFrame = wfx.Format.nBlockAlign;
-            stream->recordingPin = FilterCreateCapturePin(pFilter, (const WAVEFORMATEX*)&wfx, &result);
-            stream->deviceInputChannels = stream->userInputChannels;
-        }
-        
-        if(result != paNoError)
-        {   /* Search through all PaSampleFormats to find one that works */
-            hostInputSampleFormat = paFloat32;
-
-            do {
-                FillWFEXT(&wfx, hostInputSampleFormat, sampleRate, stream->userInputChannels);
-                stream->bytesPerInputFrame = wfx.Format.nBlockAlign;
-                stream->recordingPin = FilterCreateCapturePin(pFilter, (const WAVEFORMATEX*)&wfx, &result);
-                stream->deviceInputChannels = stream->userInputChannels;
-                
-                if(stream->recordingPin == NULL) result = paSampleFormatNotSupported;
-                if(result != paNoError)    hostInputSampleFormat <<= 1;
-            }
-            while(result != paNoError && hostInputSampleFormat <= paUInt8);
-        }
-
-        if(result != paNoError)
-        {    /* None of the PaSampleFormats worked.  Set the hostInputSampleFormat to the best fit
-             * and try a PCM format.
-             **/
-            hostInputSampleFormat =
-                PaUtil_SelectClosestAvailableFormat( pFilter->formats, inputSampleFormat );
-
-            /* Try a WAVE_FORMAT_PCM instead */
-            wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
-            wfx.Format.cbSize = 0;
-            wfx.Samples.wValidBitsPerSample = 0;
-            wfx.dwChannelMask = 0;
-            wfx.SubFormat = GUID_NULL;
-            stream->recordingPin = FilterCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx,&result);
-            if(stream->recordingPin == NULL) result = paSampleFormatNotSupported;
-        }
-
-        if( result != paNoError )
-        {
-            /* Some or all KS devices can only handle the exact number of channels
-             * they specify. But PortAudio clients expect to be able to
-             * at least specify mono I/O on a multi-channel device
-             * If this is the case, then we will do the channel mapping internally
-             **/
-            if( stream->userInputChannels < pFilter->maxInputChannels )
-            {
-                FillWFEXT(&wfx,hostInputSampleFormat,sampleRate,pFilter->maxInputChannels);
-                stream->bytesPerInputFrame = wfx.Format.nBlockAlign;
-                stream->recordingPin = FilterCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx,&result);
-                stream->deviceInputChannels = pFilter->maxInputChannels;
-
-                if( result != paNoError )
-                {
-                    /* Try a WAVE_FORMAT_PCM instead */
-                    wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
-                    wfx.Format.cbSize = 0;
-                    wfx.Samples.wValidBitsPerSample = 0;
-                    wfx.dwChannelMask = 0;
-                    wfx.SubFormat = GUID_NULL;
-                    stream->recordingPin = FilterCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx,&result);
-                }
-            }
-        }
-
-        if(stream->recordingPin == NULL)
-        {
-            goto error;
-        }
-
-        switch(hostInputSampleFormat)
-        {
-            case paInt16: stream->inputSampleSize = 2; break;
-            case paInt24: stream->inputSampleSize = 3; break;
-            case paInt32:
-            case paFloat32:    stream->inputSampleSize = 4; break;
-        }
-
-        stream->recordingPin->frameSize /= stream->bytesPerInputFrame;
-        PA_DEBUG(("Pin output frames: %d\n",stream->recordingPin->frameSize));
-    }
-    else
-    {
-        stream->recordingPin = NULL;
-        stream->bytesPerInputFrame = 0;
-    }
-
-    /* Instantiate the output pin if necessary */
-    if(userOutputChannels > 0)
-    {
-        result = paSampleFormatNotSupported;
-        pFilter = wdmHostApi->filters[outputParameters->device];
-        stream->userOutputChannels = userOutputChannels;
-
-        if(((outputSampleFormat & ~paNonInterleaved) & pFilter->formats) != 0)
-        {
-            hostOutputSampleFormat = outputSampleFormat;
-            FillWFEXT(&wfx,hostOutputSampleFormat,sampleRate,stream->userOutputChannels);
-            stream->bytesPerOutputFrame = wfx.Format.nBlockAlign;
-            stream->playbackPin = FilterCreateRenderPin(pFilter,(WAVEFORMATEX*)&wfx,&result);
-            stream->deviceOutputChannels = stream->userOutputChannels;
-        }
-
-        if(result != paNoError)
-        {
-            hostOutputSampleFormat = paFloat32;
-
-            do {
-                FillWFEXT(&wfx,hostOutputSampleFormat,sampleRate,stream->userOutputChannels);
-                stream->bytesPerOutputFrame = wfx.Format.nBlockAlign;
-                stream->playbackPin = FilterCreateRenderPin(pFilter,(WAVEFORMATEX*)&wfx,&result);
-                stream->deviceOutputChannels = stream->userOutputChannels;
-
-                if(stream->playbackPin == NULL) result = paSampleFormatNotSupported;
-                if(result != paNoError)    hostOutputSampleFormat <<= 1;
-            }
-            while(result != paNoError && hostOutputSampleFormat <= paUInt8);
-        }
-
-        if(result != paNoError)
-        {
-            hostOutputSampleFormat =
-                PaUtil_SelectClosestAvailableFormat( pFilter->formats, outputSampleFormat );
-       
-            /* Try a WAVE_FORMAT_PCM instead */
-            wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
-            wfx.Format.cbSize = 0;
-            wfx.Samples.wValidBitsPerSample = 0;
-            wfx.dwChannelMask = 0;
-            wfx.SubFormat = GUID_NULL;
-            stream->playbackPin = FilterCreateRenderPin(pFilter,(WAVEFORMATEX*)&wfx,&result);
-            if(stream->playbackPin == NULL) result = paSampleFormatNotSupported;
-        }
-            
-        if( result != paNoError )
-        {
-            /* Some or all KS devices can only handle the exact number of channels
-             * they specify. But PortAudio clients expect to be able to
-             * at least specify mono I/O on a multi-channel device
-             * If this is the case, then we will do the channel mapping internally
-             **/
-            if( stream->userOutputChannels < pFilter->maxOutputChannels )
-            {
-                FillWFEXT(&wfx,hostOutputSampleFormat,sampleRate,pFilter->maxOutputChannels);
-                stream->bytesPerOutputFrame = wfx.Format.nBlockAlign;
-                stream->playbackPin = FilterCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx,&result);
-                stream->deviceOutputChannels = pFilter->maxOutputChannels;
-                if( result != paNoError )
-                {
-                    /* Try a WAVE_FORMAT_PCM instead */
-                    wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
-                    wfx.Format.cbSize = 0;
-                    wfx.Samples.wValidBitsPerSample = 0;
-                    wfx.dwChannelMask = 0;
-                    wfx.SubFormat = GUID_NULL;
-                    stream->playbackPin = FilterCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx,&result);
-                }
-            }
-        }
-
-        if(stream->playbackPin == NULL)
-        {
-            goto error;
-        }
-
-        switch(hostOutputSampleFormat)
-        {
-            case paInt16: stream->outputSampleSize = 2; break;
-            case paInt24: stream->outputSampleSize = 3; break;
-            case paInt32:
-            case paFloat32: stream->outputSampleSize = 4; break;
-        }
-
-        stream->playbackPin->frameSize /= stream->bytesPerOutputFrame;
-        PA_DEBUG(("Pin output frames: %d\n",stream->playbackPin->frameSize));
-    }
-    else
-    {
-        stream->playbackPin = NULL;
-        stream->bytesPerOutputFrame = 0;
-    }
-
-    /* Calculate the framesPerHostXxxxBuffer size based upon the suggested latency values */
-
-    /* Record the buffer length */
-    if(inputParameters)
-    {
-        /* Calculate the frames from the user's value - add a bit to round up */
-            stream->framesPerHostIBuffer = (unsigned long)((inputParameters->suggestedLatency*sampleRate)+0.0001);
-        if(stream->framesPerHostIBuffer > (unsigned long)sampleRate)
-        { /* Upper limit is 1 second */
-              stream->framesPerHostIBuffer = (unsigned long)sampleRate;
-        }
-        else if(stream->framesPerHostIBuffer < stream->recordingPin->frameSize)
-        {
-              stream->framesPerHostIBuffer = stream->recordingPin->frameSize;
-        }
-        PA_DEBUG(("Input frames chosen:%ld\n",stream->framesPerHostIBuffer));
-    }
-
-    if(outputParameters)
-    {
-        /* Calculate the frames from the user's value - add a bit to round up */
-        stream->framesPerHostOBuffer = (unsigned long)((outputParameters->suggestedLatency*sampleRate)+0.0001);
-        if(stream->framesPerHostOBuffer > (unsigned long)sampleRate)
-        { /* Upper limit is 1 second */
-                  stream->framesPerHostOBuffer = (unsigned long)sampleRate;
-        }
-        else if(stream->framesPerHostOBuffer < stream->playbackPin->frameSize)
-        {
-              stream->framesPerHostOBuffer = stream->playbackPin->frameSize;
-        }
-        PA_DEBUG(("Output frames chosen:%ld\n",stream->framesPerHostOBuffer));
-    }
-
-    /* Host buffer size is bounded to the largest of the input and output
-    frame sizes */
-
-    result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
-              stream->userInputChannels, inputSampleFormat, hostInputSampleFormat,
-              stream->userOutputChannels, outputSampleFormat, hostOutputSampleFormat,
-              sampleRate, streamFlags, framesPerBuffer,
-              max(stream->framesPerHostOBuffer,stream->framesPerHostIBuffer),
-              paUtilBoundedHostBufferSize,
-              streamCallback, userData );
-    if( result != paNoError )
-        goto error;
-
-    stream->streamRepresentation.streamInfo.inputLatency =
-            ((double)stream->framesPerHostIBuffer) / sampleRate;
-    stream->streamRepresentation.streamInfo.outputLatency =
-            ((double)stream->framesPerHostOBuffer) / sampleRate;
-    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
-
-      PA_DEBUG(("BytesPerInputFrame = %d\n",stream->bytesPerInputFrame));
-      PA_DEBUG(("BytesPerOutputFrame = %d\n",stream->bytesPerOutputFrame));
-
-    /* Allocate all the buffers for host I/O */
-    size = 2 * (stream->framesPerHostIBuffer*stream->bytesPerInputFrame +  stream->framesPerHostOBuffer*stream->bytesPerOutputFrame);
-    PA_DEBUG(("Buffer size = %d\n",size));
-    stream->hostBuffer = (char*)PaUtil_AllocateMemory(size);
-    PA_DEBUG(("Buffer allocated\n"));
-    if( !stream->hostBuffer )
-    {
-        PA_DEBUG(("Cannot allocate host buffer!\n"));
-        result = paInsufficientMemory;
-        goto error;
-    }
-    PA_DEBUG(("Buffer start = %p\n",stream->hostBuffer));
-    /* memset(stream->hostBuffer,0,size); */
-
-    /* Set up the packets */
-    stream->events[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
-    ResetEvent(stream->events[0]); /* Record buffer 1 */
-    stream->events[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
-    ResetEvent(stream->events[1]); /* Record buffer 2 */
-    stream->events[2] = CreateEvent(NULL, FALSE, FALSE, NULL);
-    ResetEvent(stream->events[2]); /* Play buffer 1 */
-    stream->events[3] = CreateEvent(NULL, FALSE, FALSE, NULL);
-    ResetEvent(stream->events[3]); /* Play buffer 2 */
-    stream->events[4] = CreateEvent(NULL, FALSE, FALSE, NULL);
-    ResetEvent(stream->events[4]); /* Abort event */
-    if(stream->userInputChannels > 0)
-    {
-        DATAPACKET *p = &(stream->packets[0]);
-        p->Signal.hEvent = stream->events[0];
-        p->Header.Data = stream->hostBuffer;
-        p->Header.FrameExtent = stream->framesPerHostIBuffer*stream->bytesPerInputFrame;
-        p->Header.DataUsed = 0;
-        p->Header.Size = sizeof(p->Header);
-        p->Header.PresentationTime.Numerator = 1;
-        p->Header.PresentationTime.Denominator = 1;
-
-        p = &(stream->packets[1]);
-        p->Signal.hEvent = stream->events[1];
-        p->Header.Data = stream->hostBuffer + stream->framesPerHostIBuffer*stream->bytesPerInputFrame;
-        p->Header.FrameExtent = stream->framesPerHostIBuffer*stream->bytesPerInputFrame;
-        p->Header.DataUsed = 0;
-        p->Header.Size = sizeof(p->Header);
-        p->Header.PresentationTime.Numerator = 1;
-        p->Header.PresentationTime.Denominator = 1;
-    }
-    if(stream->userOutputChannels > 0)
-    {
-        DATAPACKET *p = &(stream->packets[2]);
-        p->Signal.hEvent = stream->events[2];
-        p->Header.Data = stream->hostBuffer + 2*stream->framesPerHostIBuffer*stream->bytesPerInputFrame;
-        p->Header.FrameExtent = stream->framesPerHostOBuffer*stream->bytesPerOutputFrame;
-        p->Header.DataUsed = stream->framesPerHostOBuffer*stream->bytesPerOutputFrame;
-        p->Header.Size = sizeof(p->Header);
-        p->Header.PresentationTime.Numerator = 1;
-        p->Header.PresentationTime.Denominator = 1;
-    
-        p = &(stream->packets[3]);
-        p->Signal.hEvent = stream->events[3];
-        p->Header.Data = stream->hostBuffer + 2*stream->framesPerHostIBuffer*stream->bytesPerInputFrame + stream->framesPerHostOBuffer*stream->bytesPerOutputFrame;
-        p->Header.FrameExtent = stream->framesPerHostOBuffer*stream->bytesPerOutputFrame;
-        p->Header.DataUsed = stream->framesPerHostOBuffer*stream->bytesPerOutputFrame;
-        p->Header.Size = sizeof(p->Header);
-        p->Header.PresentationTime.Numerator = 1;
-        p->Header.PresentationTime.Denominator = 1;
-    }
-
-    stream->streamStarted = 0;
-    stream->streamActive = 0;
-    stream->streamStop = 0;
-    stream->streamAbort = 0;
-    stream->streamFlags = streamFlags;
-    stream->oldProcessPriority = REALTIME_PRIORITY_CLASS;
-
-    *s = (PaStream*)stream;
-
-    PA_LOGL_;
-    return result;
-
-error:
-    size = 5;
-    while(size--)
-    {
-        if(stream->events[size] != NULL)
-        {
-            CloseHandle(stream->events[size]);
-            stream->events[size] = NULL;
-        }
-    }
-    if(stream->hostBuffer)
-        PaUtil_FreeMemory( stream->hostBuffer );
-
-    if(stream->playbackPin)
-        PinClose(stream->playbackPin);
-    if(stream->recordingPin)
-        PinClose(stream->recordingPin);
-
-    if( stream )
-        PaUtil_FreeMemory( stream );
-
-    PA_LOGL_;
-    return result;
-}
-
-/*
-    When CloseStream() is called, the multi-api layer ensures that
-    the stream has already been stopped or aborted.
-*/
-static PaError CloseStream( PaStream* s )
-{
-    PaError result = paNoError;
-    PaWinWdmStream *stream = (PaWinWdmStream*)s;
-    int size;
-
-    PA_LOGE_;
-
-    assert(!stream->streamStarted);
-    assert(!stream->streamActive);
-
-    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
-    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
-    size = 5;
-    while(size--)
-    {
-        if(stream->events[size] != NULL)
-        {
-            CloseHandle(stream->events[size]);
-            stream->events[size] = NULL;
-        }
-    }
-    if(stream->hostBuffer)
-        PaUtil_FreeMemory( stream->hostBuffer );
-
-    if(stream->playbackPin)
-        PinClose(stream->playbackPin);
-    if(stream->recordingPin)
-        PinClose(stream->recordingPin);
-
-    PaUtil_FreeMemory( stream );
-
-    PA_LOGL_;
-    return result;
-}
-
-/*
-Write the supplied packet to the pin
-Asynchronous
-Should return false on success
-*/
-static BOOL PinWrite(HANDLE h, DATAPACKET* p)
-{
-    unsigned long cbReturned = 0;
-    return DeviceIoControl(h,IOCTL_KS_WRITE_STREAM,NULL,0,
-                            &p->Header,p->Header.Size,&cbReturned,&p->Signal);
-}
-
-/*
-Read to the supplied packet from the pin
-Asynchronous
-Should return false on success
-*/
-static BOOL PinRead(HANDLE h, DATAPACKET* p)
-{
-    unsigned long cbReturned = 0;
-    return DeviceIoControl(h,IOCTL_KS_READ_STREAM,NULL,0,
-                            &p->Header,p->Header.Size,&cbReturned,&p->Signal);
-}
-
-/*
-Copy the first interleaved channel of 16 bit data to the other channels
-*/
-static void DuplicateFirstChannelInt16(void* buffer, int channels, int samples)
-{
-    unsigned short* data = (unsigned short*)buffer;
-    int channel;
-    unsigned short sourceSample;
-    while( samples-- )
-    {
-        sourceSample = *data++;
-        channel = channels-1;
-        while( channel-- )
-        {
-            *data++ = sourceSample;
-        }
-    }
-}
-
-/*
-Copy the first interleaved channel of 24 bit data to the other channels
-*/
-static void DuplicateFirstChannelInt24(void* buffer, int channels, int samples)
-{
-    unsigned char* data = (unsigned char*)buffer;
-    int channel;
-    unsigned char sourceSample[3];
-    while( samples-- )
-    {
-        sourceSample[0] = data[0];
-        sourceSample[1] = data[1];
-        sourceSample[2] = data[2];
-        data += 3;
-        channel = channels-1;
-        while( channel-- )
-        {
-            data[0] = sourceSample[0];
-            data[1] = sourceSample[1];
-            data[2] = sourceSample[2];
-            data += 3;
-        }
-    }
-}
-
-/*
-Copy the first interleaved channel of 32 bit data to the other channels
-*/
-static void DuplicateFirstChannelInt32(void* buffer, int channels, int samples)
-{
-    unsigned long* data = (unsigned long*)buffer;
-    int channel;
-    unsigned long sourceSample;
-    while( samples-- )
-    {
-        sourceSample = *data++;
-        channel = channels-1;
-        while( channel-- )
-        {
-            *data++ = sourceSample;
-        }
-    }
-}
-
-static DWORD WINAPI ProcessingThread(LPVOID pParam)
-{
-    PaWinWdmStream *stream = (PaWinWdmStream*)pParam;
-    PaStreamCallbackTimeInfo ti;
-    int cbResult = paContinue;
-    int inbuf = 0;
-    int outbuf = 0;
-    int pending = 0;
-    PaError result;
-    unsigned long wait;
-    unsigned long eventSignaled;
-    int fillPlaybuf = 0;
-    int emptyRecordbuf = 0;
-    int framesProcessed;
-    unsigned long timeout;
-    int i;
-    int doChannelCopy;
-    int priming = 0;
-    PaStreamCallbackFlags underover = 0;
-
-    PA_LOGE_;
-
-    ti.inputBufferAdcTime = 0.0;
-    ti.currentTime = 0.0;
-    ti.outputBufferDacTime = 0.0;
-
-    /* Get double buffering going */
-
-    /* Submit buffers */
-    if(stream->playbackPin)
-    {
-        result = PinSetState(stream->playbackPin, KSSTATE_RUN);
-
-        PA_DEBUG(("play state run = %d;",(int)result));
-        SetEvent(stream->events[outbuf+2]);
-        outbuf = (outbuf+1)&1;
-        SetEvent(stream->events[outbuf+2]);
-        outbuf = (outbuf+1)&1;
-        pending += 2;
-        priming += 4;
-    }
-    if(stream->recordingPin)
-    {
-        result = PinSetState(stream->recordingPin, KSSTATE_RUN);
-
-        PA_DEBUG(("recording state run = %d;",(int)result));
-        PinRead(stream->recordingPin->handle,&stream->packets[inbuf]);
-        inbuf = (inbuf+1)&1; /* Increment and wrap */
-        PinRead(stream->recordingPin->handle,&stream->packets[inbuf]);
-        inbuf = (inbuf+1)&1; /* Increment and wrap */
-        /* FIXME - do error checking */
-        pending += 2;
-    }
-    PA_DEBUG(("Out buffer len:%f\n",(2000*stream->framesPerHostOBuffer) / stream->streamRepresentation.streamInfo.sampleRate));
-    PA_DEBUG(("In buffer len:%f\n",(2000*stream->framesPerHostIBuffer) / stream->streamRepresentation.streamInfo.sampleRate));
-    timeout = max(
-       ((2000*(DWORD)stream->framesPerHostOBuffer) / (DWORD)stream->streamRepresentation.streamInfo.sampleRate),
-       ((2000*(DWORD)stream->framesPerHostIBuffer) / (DWORD)stream->streamRepresentation.streamInfo.sampleRate));
-    timeout = max(timeout,1);
-    PA_DEBUG(("Timeout = %ld\n",timeout));
-
-    while(!stream->streamAbort)
-    {
-        fillPlaybuf = 0;
-        emptyRecordbuf = 0;
-
-        /* Wait for next input or output buffer to be finished with*/
-        assert(pending>0);
-
-        if(stream->streamStop)
-        {
-            PA_DEBUG(("ss1:pending=%d ",pending));
-        }
-        wait = WaitForMultipleObjects(5, stream->events, FALSE, 0);
-        if( wait == WAIT_TIMEOUT )
-        {
-            /* No (under|over)flow has ocurred */
-            wait = WaitForMultipleObjects(5, stream->events, FALSE, timeout);
-            eventSignaled = wait - WAIT_OBJECT_0;
-        }
-        else
-        {
-            eventSignaled = wait - WAIT_OBJECT_0;
-            if( eventSignaled < 2 )
-            {
-                underover |= paInputOverflow;
-                PA_DEBUG(("Input overflow\n"));
-            }
-            else if(( eventSignaled < 4 )&&(!priming))
-            {
-                underover |= paOutputUnderflow;
-                PA_DEBUG(("Output underflow\n"));
-            }
-        }
-
-        if(stream->streamStop)
-        {
-            PA_DEBUG(("ss2:wait=%ld",wait));
-        }
-        if(wait == WAIT_FAILED)
-        {
-            PA_DEBUG(("Wait fail = %ld! ",wait));
-            break;
-        }
-        if(wait == WAIT_TIMEOUT)
-        {
-            continue;
-        }
-
-        if(eventSignaled < 2)
-        { /* Recording input buffer has been filled */
-            if(stream->playbackPin)
-            {
-                /* First check if also the next playback buffer has been signaled */
-                wait = WaitForSingleObject(stream->events[outbuf+2],0);
-                if(wait == WAIT_OBJECT_0)
-                {
-                    /* Yes, so do both buffers at same time */
-                    fillPlaybuf = 1;
-                    pending--;
-                    /* Was this an underflow situation? */
-                    if( underover )
-                        underover |= paOutputUnderflow; /* Yes! */
-                }
-            }
-            emptyRecordbuf = 1;
-            pending--;
-        }
-        else if(eventSignaled < 4)
-        { /* Playback output buffer has been emptied */
-            if(stream->recordingPin)
-            {
-                /* First check if also the next recording buffer has been signaled */
-                wait = WaitForSingleObject(stream->events[inbuf],0);
-                if(wait == WAIT_OBJECT_0)
-                { /* Yes, so do both buffers at same time */
-                    emptyRecordbuf = 1;
-                    pending--;
-                    /* Was this an overflow situation? */
-                    if( underover )
-                        underover |= paInputOverflow; /* Yes! */
-                }
-            }
-            fillPlaybuf = 1;
-            pending--;
-        }
-        else
-        {
-            /* Abort event! */
-            assert(stream->streamAbort); /* Should have been set */
-            PA_DEBUG(("ABORTING "));
-            break;
-        }
-        ResetEvent(stream->events[eventSignaled]);
-
-        if(stream->streamStop)
-        {
-            PA_DEBUG(("Stream stop! pending=%d",pending));
-            cbResult = paComplete; /* Stop, but play remaining buffers */
-        }
-
-        /* Do necessary buffer processing (which will invoke user callback if necessary */
-        doChannelCopy = 0;
-        if(cbResult==paContinue)
-        {
-            PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
-            if((stream->bufferProcessor.hostInputFrameCount[0] + stream->bufferProcessor.hostInputFrameCount[1]) ==
-                (stream->bufferProcessor.hostOutputFrameCount[0] + stream->bufferProcessor.hostOutputFrameCount[1]) )
-                PaUtil_BeginBufferProcessing(&stream->bufferProcessor,&ti,underover);
-            underover = 0; /* Reset the (under|over)flow status */
-            if(fillPlaybuf)
-            {
-                PaUtil_SetOutputFrameCount(&stream->bufferProcessor,0);
-                if( stream->userOutputChannels == 1 )
-                {
-                    /* Write the single user channel to the first interleaved block */
-                    PaUtil_SetOutputChannel(&stream->bufferProcessor,0,stream->packets[outbuf+2].Header.Data,stream->deviceOutputChannels);
-                    /* We will do a copy to the other channels after the data has been written */
-                    doChannelCopy = 1;
-                }
-                else
-                {
-                    for(i=0;i<stream->userOutputChannels;i++)
-                    {
-                        /* Only write the user output channels. Leave the rest blank */
-                        PaUtil_SetOutputChannel(&stream->bufferProcessor,i,((unsigned char*)(stream->packets[outbuf+2].Header.Data))+(i*stream->outputSampleSize),stream->deviceOutputChannels);
-                    }
-                }
-            }
-            if(emptyRecordbuf)
-            {
-                PaUtil_SetInputFrameCount(&stream->bufferProcessor,stream->packets[inbuf].Header.DataUsed/stream->bytesPerInputFrame);
-                for(i=0;i<stream->userInputChannels;i++)
-                {
-                    /* Only read as many channels as the user wants */
-                    PaUtil_SetInputChannel(&stream->bufferProcessor,i,((unsigned char*)(stream->packets[inbuf].Header.Data))+(i*stream->inputSampleSize),stream->deviceInputChannels);
-                }
-            }
-            /* Only call the EndBufferProcessing function is the total input frames == total output frames */
-            if((stream->bufferProcessor.hostInputFrameCount[0] + stream->bufferProcessor.hostInputFrameCount[1]) ==
-                (stream->bufferProcessor.hostOutputFrameCount[0] + stream->bufferProcessor.hostOutputFrameCount[1]) )
-                framesProcessed = PaUtil_EndBufferProcessing(&stream->bufferProcessor,&cbResult);
-            else framesProcessed = 0;
-            if( doChannelCopy )
-            {
-                /* Copy the first output channel to the other channels */
-                switch(stream->outputSampleSize)
-                {
-                    case 2:
-                        DuplicateFirstChannelInt16(stream->packets[outbuf+2].Header.Data,stream->deviceOutputChannels,stream->framesPerHostOBuffer);
-                        break;
-                    case 3:
-                        DuplicateFirstChannelInt24(stream->packets[outbuf+2].Header.Data,stream->deviceOutputChannels,stream->framesPerHostOBuffer);
-                        break;
-                    case 4:
-                        DuplicateFirstChannelInt32(stream->packets[outbuf+2].Header.Data,stream->deviceOutputChannels,stream->framesPerHostOBuffer);
-                        break;
-                    default:
-                        assert(0); /* Unsupported format! */
-                        break;
-                }
-            }
-            PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
-        }
-        else
-        {
-            fillPlaybuf = 0;
-            emptyRecordbuf = 0;
-        }
-            
-        /*
-        if(cbResult != paContinue)
-        {
-            PA_DEBUG(("cbResult=%d, pending=%d:",cbResult,pending));
-        }
-        */
-        /* Submit buffers */
-        if((fillPlaybuf)&&(cbResult!=paAbort))
-        {
-            if(!PinWrite(stream->playbackPin->handle,&stream->packets[outbuf+2]))
-                outbuf = (outbuf+1)&1; /* Increment and wrap */
-            pending++;
-            if( priming )
-                priming--; /* Have to prime twice */
-        }
-        if((emptyRecordbuf)&&(cbResult==paContinue))
-        {
-            stream->packets[inbuf].Header.DataUsed = 0; /* Reset for reuse */
-            PinRead(stream->recordingPin->handle,&stream->packets[inbuf]);
-            inbuf = (inbuf+1)&1; /* Increment and wrap */
-            pending++;
-        }
-        if(pending==0)
-        {
-            PA_DEBUG(("pending==0 finished...;"));
-            break;
-        }
-        if((!stream->playbackPin)&&(cbResult!=paContinue))
-        {
-            PA_DEBUG(("record only cbResult=%d...;",cbResult));
-            break;
-        }
-    }
-
-    PA_DEBUG(("Finished thread"));
-
-    /* Finished, either normally or aborted */
-    if(stream->playbackPin)
-    {
-        result = PinSetState(stream->playbackPin, KSSTATE_PAUSE);
-        result = PinSetState(stream->playbackPin, KSSTATE_STOP);
-    }
-    if(stream->recordingPin)
-    {
-        result = PinSetState(stream->recordingPin, KSSTATE_PAUSE);
-        result = PinSetState(stream->recordingPin, KSSTATE_STOP);
-    }
-
-    stream->streamActive = 0;
-
-    if((!stream->streamStop)&&(!stream->streamAbort))
-    {
-          /* Invoke the user stream finished callback */
-          /* Only do it from here if not being stopped/aborted by user */
-          if( stream->streamRepresentation.streamFinishedCallback != 0 )
-              stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
-    }
-    stream->streamStop = 0;
-    stream->streamAbort = 0;
-
-    /* Reset process priority if necessary */
-    if(stream->oldProcessPriority != REALTIME_PRIORITY_CLASS)
-    {
-        SetPriorityClass(GetCurrentProcess(),stream->oldProcessPriority);
-        stream->oldProcessPriority = REALTIME_PRIORITY_CLASS;
-    }
-
-    PA_LOGL_;
-    ExitThread(0);
-    return 0;
-}
-
-static PaError StartStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaWinWdmStream *stream = (PaWinWdmStream*)s;
-    DWORD dwID;
-    BOOL ret;
-    int size;
-
-    PA_LOGE_;
-
-    stream->streamStop = 0;
-    stream->streamAbort = 0;
-    size = 5;
-    while(size--)
-    {
-        if(stream->events[size] != NULL)
-        {
-            ResetEvent(stream->events[size]);
-        }
-    }
-
-    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
-
-    stream->oldProcessPriority = GetPriorityClass(GetCurrentProcess());
-    /* Uncomment the following line to enable dynamic boosting of the process
-     * priority to real time for best low latency support
-     * Disabled by default because RT processes can easily block the OS */
-    /*ret = SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
-      PA_DEBUG(("Class ret = %d;",ret));*/
-
-    stream->streamStarted = 1;
-    stream->streamThread = CreateThread(NULL, 0, ProcessingThread, stream, 0, &dwID);
-    if(stream->streamThread == NULL)
-    {
-        stream->streamStarted = 0;
-        result = paInsufficientMemory;
-        goto end;
-    }
-    ret = SetThreadPriority(stream->streamThread,THREAD_PRIORITY_TIME_CRITICAL);
-    PA_DEBUG(("Priority ret = %d;",ret));
-    /* Make the stream active */
-    stream->streamActive = 1;
-
-end:
-    PA_LOGL_;
-    return result;
-}
-
-
-static PaError StopStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaWinWdmStream *stream = (PaWinWdmStream*)s;
-    int doCb = 0;
-
-    PA_LOGE_;
-
-    if(stream->streamActive)
-    {
-        doCb = 1;
-        stream->streamStop = 1;
-        while(stream->streamActive)
-        {
-            PA_DEBUG(("W."));
-            Sleep(10); /* Let thread sleep for 10 msec */
-        }
-    }
-
-    PA_DEBUG(("Terminating thread"));
-    if(stream->streamStarted && stream->streamThread)
-    {
-        TerminateThread(stream->streamThread,0);
-        stream->streamThread = NULL;
-    }
-
-    stream->streamStarted = 0;
-
-    if(stream->oldProcessPriority != REALTIME_PRIORITY_CLASS)
-    {
-        SetPriorityClass(GetCurrentProcess(),stream->oldProcessPriority);
-        stream->oldProcessPriority = REALTIME_PRIORITY_CLASS;
-    }
-
-    if(doCb)
-    {
-        /* Do user callback now after all state has been reset */
-        /* This means it should be safe for the called function */
-        /* to invoke e.g. StartStream */
-        if( stream->streamRepresentation.streamFinishedCallback != 0 )
-             stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
-    }
-
-    PA_LOGL_;
-    return result;
-}
-
-static PaError AbortStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaWinWdmStream *stream = (PaWinWdmStream*)s;
-    int doCb = 0;
-
-    PA_LOGE_;
-
-    if(stream->streamActive)
-    {
-        doCb = 1;
-        stream->streamAbort = 1;
-        SetEvent(stream->events[4]); /* Signal immediately */
-        while(stream->streamActive)
-        {
-            Sleep(10);
-        }
-    }
-
-    if(stream->streamStarted && stream->streamThread)
-    {
-        TerminateThread(stream->streamThread,0);
-        stream->streamThread = NULL;
-    }
-
-    stream->streamStarted = 0;
-
-    if(stream->oldProcessPriority != REALTIME_PRIORITY_CLASS)
-    {
-        SetPriorityClass(GetCurrentProcess(),stream->oldProcessPriority);
-        stream->oldProcessPriority = REALTIME_PRIORITY_CLASS;
-    }
-
-    if(doCb)
-    {
-        /* Do user callback now after all state has been reset */
-        /* This means it should be safe for the called function */
-        /* to invoke e.g. StartStream */
-        if( stream->streamRepresentation.streamFinishedCallback != 0 )
-            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
-    }
-
-    stream->streamActive = 0;
-    stream->streamStarted = 0;
-
-    PA_LOGL_;
-    return result;
-}
-
-
-static PaError IsStreamStopped( PaStream *s )
-{
-    PaWinWdmStream *stream = (PaWinWdmStream*)s;
-    int result = 0;
-
-    PA_LOGE_;
-
-    if(!stream->streamStarted)
-        result = 1;
-
-    PA_LOGL_;
-    return result;
-}
-
-
-static PaError IsStreamActive( PaStream *s )
-{
-    PaWinWdmStream *stream = (PaWinWdmStream*)s;
-    int result = 0;
-
-    PA_LOGE_;
-
-    if(stream->streamActive)
-        result = 1;
-
-    PA_LOGL_;
-    return result;
-}
-
-
-static PaTime GetStreamTime( PaStream* s )
-{
-    PA_LOGE_;
-    PA_LOGL_;
-    (void)s;
-    return PaUtil_GetTime();
-}
-
-
-static double GetStreamCpuLoad( PaStream* s )
-{
-    PaWinWdmStream *stream = (PaWinWdmStream*)s;
-    double result;
-    PA_LOGE_;
-    result = PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
-    PA_LOGL_;
-    return result;
-}
-
-
-/*
-    As separate stream interfaces are used for blocking and callback
-    streams, the following functions can be guaranteed to only be called
-    for blocking streams.
-*/
-
-static PaError ReadStream( PaStream* s,
-                           void *buffer,
-                           unsigned long frames )
-{
-    PaWinWdmStream *stream = (PaWinWdmStream*)s;
-
-    PA_LOGE_;
-
-    /* suppress unused variable warnings */
-    (void) buffer;
-    (void) frames;
-    (void) stream;
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-    PA_LOGL_;
-    return paNoError;
-}
-
-
-static PaError WriteStream( PaStream* s,
-                            const void *buffer,
-                            unsigned long frames )
-{
-    PaWinWdmStream *stream = (PaWinWdmStream*)s;
-
-    PA_LOGE_;
-
-    /* suppress unused variable warnings */
-    (void) buffer;
-    (void) frames;
-    (void) stream;
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-    PA_LOGL_;
-    return paNoError;
-}
-
-
-static signed long GetStreamReadAvailable( PaStream* s )
-{
-    PaWinWdmStream *stream = (PaWinWdmStream*)s;
-
-    PA_LOGE_;
-
-    /* suppress unused variable warnings */
-    (void) stream;
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-    PA_LOGL_;
-    return 0;
-}
-
-
-static signed long GetStreamWriteAvailable( PaStream* s )
-{
-    PaWinWdmStream *stream = (PaWinWdmStream*)s;
-
-    PA_LOGE_;
-    /* suppress unused variable warnings */
-    (void) stream;
-
-    /* IMPLEMENT ME, see portaudio.h for required behavior*/
-    PA_LOGL_;
-    return 0;
-}
\ No newline at end of file
diff --git a/portaudio/pa_win_wdmks/readme.txt b/portaudio/pa_win_wdmks/readme.txt
deleted file mode 100644
index 1a381fe79..000000000
--- a/portaudio/pa_win_wdmks/readme.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-Notes about WDM-KS host API
----------------------------
-
-Status history
---------------
-10th November 2005:
-Made following changes:
- * OpenStream: Try all PaSampleFormats internally if the the chosen
-     format is not supported natively.  This fixed several problems
-     with soundcards that soundcards that did not take kindly to
-     using 24-bit 3-byte formats.
- * OpenStream: Make the minimum framesPerHostIBuffer (and framesPerHostOBuffer)
-     the default frameSize for the playback/recording pin.
- * ProcessingThread: Added a switch to only call PaUtil_EndBufferProcessing
-     if the total input frames equals the total output frames
-
-5th September 2004:
-This is the first public version of the code. It should be considered
-an alpha release with zero guarantee not to crash on any particular 
-system. So far it has only been tested in the author's development
-environment, which means a Win2k/SP2 PIII laptop with integrated 
-SoundMAX driver and USB Tascam US-428 compiled with both MinGW
-(GCC 3.3) and MSVC++6 using the MS DirectX 9 SDK.
-It has been most widely tested with the MinGW build, with most of the
-test programs (particularly paqa_devs and paqa_errs) passing.
-There are some notable failures: patest_out_underflow and both of the
-blocking I/O tests (as blocking I/O is not implemented).
-At this point the code needs to be tested with a much wider variety 
-of configurations and feedback provided from testers regarding
-both working and failing cases.
-
-What is the WDM-KS host API?
-----------------------------
-PortAudio for Windows currently has 3 functional host implementations.
-MME uses the oldest Windows audio API which does not offer good
-play/record latency. 
-DirectX improves this, but still imposes a penalty
-of 10s of milliseconds due to the system mixing of streams from
-multiple applications. 
-ASIO offers very good latency, but requires special drivers which are
-not always available for cheaper audio hardware. Also, when ASIO 
-drivers are available, they are not always so robust because they 
-bypass all of the standardised Windows device driver architecture 
-and hit the hardware their own way.
-Alternatively there are a couple of free (but closed source) ASIO 
-implementations which connect to the lower level Windows 
-"Kernel Streaming" API, but again these require special installation 
-by the user, and can be limited in functionality or difficult to use. 
-
-This is where the PortAudio "WDM-KS" host implementation comes in.
-It directly connects PortAudio to the same Kernel Streaming API which
-those ASIO bridges use. This avoids the mixing penatly of DirectX, 
-giving at least as good latency as any ASIO driver, but it has the
-advantage of working with ANY Windows audio hardware which is available
-through the normal MME/DirectX routes without the user requiring 
-any additional device drivers to be installed, and allowing all 
-device selection to be done through the normal PortAudio API.
-
-Note that in general you should only be using this host API if your 
-application has a real requirement for very low latency audio (<20ms), 
-either because you are generating sounds in real-time based upon 
-user input, or you a processing recorded audio in real time.
-
-The only thing to be aware of is that using the KS interface will
-block that device from being used by the rest of system through
-the higher level APIs, or conversely, if the system is using
-a device, the KS API will not be able to use it. MS recommend that
-you should keep the device open only when your application has focus.
-In PortAudio terms, this means having a stream Open on a WDMKS device.
-
-Usage
------
-To add the WDMKS backend to your program which is already using 
-PortAudio, you must undefine PA_NO_WDMKS from your build file,
-and include the pa_win_wdmks\pa_win_wdmks.c into your build.
-The file should compile in both C and C++.
-You will need a DirectX SDK installed on your system for the
-ks.h and ksmedia.h header files.
-You will need to link to the system "setupapi" library.
-Note that if you use MinGW, you will get more warnings from 
-the DX header files when using GCC(C), and still a few warnings
-with G++(CPP).
\ No newline at end of file
diff --git a/portaudio/pa_win_wmme/CVS/Entries b/portaudio/pa_win_wmme/CVS/Entries
deleted file mode 100644
index a6d8aaf51..000000000
--- a/portaudio/pa_win_wmme/CVS/Entries
+++ /dev/null
@@ -1,3 +0,0 @@
-/pa_win_wmme.c/1.6.2.88/Thu Feb 16 01:56:45 2006//Tv19-devel
-/pa_win_wmme.h/1.1.2.14/Fri Feb 20 14:16:53 2004//Tv19-devel
-D
diff --git a/portaudio/pa_win_wmme/CVS/Repository b/portaudio/pa_win_wmme/CVS/Repository
deleted file mode 100644
index 3d371154e..000000000
--- a/portaudio/pa_win_wmme/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pa_win_wmme
diff --git a/portaudio/pa_win_wmme/CVS/Root b/portaudio/pa_win_wmme/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pa_win_wmme/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pa_win_wmme/CVS/Tag b/portaudio/pa_win_wmme/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pa_win_wmme/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pa_win_wmme/pa_win_wmme.c b/portaudio/pa_win_wmme/pa_win_wmme.c
deleted file mode 100644
index 1a9ea59e1..000000000
--- a/portaudio/pa_win_wmme/pa_win_wmme.c
+++ /dev/null
@@ -1,3634 +0,0 @@
-/*
- * $Id: pa_win_wmme.c,v 1.6.2.88 2006/02/16 01:56:45 rossbencina Exp $
- * pa_win_wmme.c
- * Implementation of PortAudio for Windows MultiMedia Extensions (WMME)       
- *                                                                                         
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com
- *
- * Authors: Ross Bencina and Phil Burk
- * 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.
- *
- */
-
-/* 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 conditional inclusion of memory.h,
-               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
- RDB20020531 - converted to V19 framework
- ** NOTE  maintanance history is now stored in CVS **
-*/
-
-/** @file
-	
-	@todo Fix buffer catch up code, can sometimes get stuck (perhaps fixed now,
-            needs to be reviewed and tested.)
-
-    @todo implement paInputUnderflow, paOutputOverflow streamCallback statusFlags, paNeverDropInput.
-
-    @todo BUG: PA_MME_SET_LAST_WAVEIN/OUT_ERROR is used in functions which may
-                be called asynchronously from the callback thread. this is bad.
-
-    @todo implement inputBufferAdcTime in callback thread
-
-    @todo review/fix error recovery and cleanup in marked functions
-
-    @todo implement timeInfo for stream priming
-
-    @todo handle the case where the callback returns paAbort or paComplete during stream priming.
-
-    @todo review input overflow and output underflow handling in ReadStream and WriteStream
-
-Non-critical stuff for the future:
-
-    @todo Investigate supporting host buffer formats > 16 bits
-    
-    @todo define UNICODE and _UNICODE in the project settings and see what breaks
-
-*/
-
-/*
-    How it works:
-
-    For both callback and blocking read/write streams we open the MME devices
-    in CALLBACK_EVENT mode. In this mode, MME signals an Event object whenever
-    it has finished with a buffer (either filled it for input, or played it
-    for output). Where necessary we block waiting for Event objects using
-    WaitMultipleObjects().
-
-    When implementing a PA callback stream, we set up a high priority thread
-    which waits on the MME buffer Events and drains/fills the buffers when
-    they are ready.
-
-    When implementing a PA blocking read/write stream, we simply wait on these
-    Events (when necessary) inside the ReadStream() and WriteStream() functions.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <windows.h>
-#include <mmsystem.h>
-#include <process.h>
-#include <assert.h>
-/* PLB20010422 - "memory.h" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */
-#ifndef __MWERKS__
-#include <malloc.h>
-#include <memory.h>
-#endif /* __MWERKS__ */
-
-#include "portaudio.h"
-#include "pa_trace.h"
-#include "pa_util.h"
-#include "pa_allocation.h"
-#include "pa_hostapi.h"
-#include "pa_stream.h"
-#include "pa_cpuload.h"
-#include "pa_process.h"
-
-#include "pa_win_wmme.h"
-
-#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
-#pragma comment(lib, "winmm.lib")
-#endif
-
-/*
- provided in newer platform sdks
- */
-#ifndef DWORD_PTR
-#define DWORD_PTR DWORD
-#endif
-
-/************************************************* Constants ********/
-
-#define PA_MME_USE_HIGH_DEFAULT_LATENCY_    (0)  /* For debugging glitches. */
-
-#if PA_MME_USE_HIGH_DEFAULT_LATENCY_
- #define PA_MME_WIN_9X_DEFAULT_LATENCY_                     (0.4)
- #define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_               (4)
- #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_	(4)
- #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_	(4)
- #define PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_	(16)
- #define PA_MME_MAX_HOST_BUFFER_SECS_				        (0.3)       /* Do not exceed unless user buffer exceeds */
- #define PA_MME_MAX_HOST_BUFFER_BYTES_				        (32 * 1024) /* Has precedence over PA_MME_MAX_HOST_BUFFER_SECS_, some drivers are known to crash with buffer sizes > 32k */
-#else
- #define PA_MME_WIN_9X_DEFAULT_LATENCY_                     (0.2)
- #define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_               (2)
- #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_	(3)
- #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_	(2)
- #define PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_	(16)
- #define PA_MME_MAX_HOST_BUFFER_SECS_				        (0.1)       /* Do not exceed unless user buffer exceeds */
- #define PA_MME_MAX_HOST_BUFFER_BYTES_				        (32 * 1024) /* Has precedence over PA_MME_MAX_HOST_BUFFER_SECS_, some drivers are known to crash with buffer sizes > 32k */
-#endif
-
-/* Use higher latency for NT because it is even worse at real-time
-   operation than Win9x.
-*/
-#define PA_MME_WIN_NT_DEFAULT_LATENCY_      (PA_MME_WIN_9X_DEFAULT_LATENCY_ * 2)
-#define PA_MME_WIN_WDM_DEFAULT_LATENCY_     (PA_MME_WIN_9X_DEFAULT_LATENCY_)
-
-
-#define PA_MME_MIN_TIMEOUT_MSEC_        (1000)
-
-static const char constInputMapperSuffix_[] = " - Input";
-static const char constOutputMapperSuffix_[] = " - Output";
-
-/********************************************************************/
-
-typedef struct PaWinMmeStream PaWinMmeStream;     /* forward declaration */
-
-/* prototypes for functions declared in this file */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** stream,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData );
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate );
-static PaError CloseStream( PaStream* stream );
-static PaError StartStream( PaStream *stream );
-static PaError StopStream( PaStream *stream );
-static PaError AbortStream( PaStream *stream );
-static PaError IsStreamStopped( PaStream *s );
-static PaError IsStreamActive( PaStream *stream );
-static PaTime GetStreamTime( PaStream *stream );
-static double GetStreamCpuLoad( PaStream* stream );
-static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
-static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
-static signed long GetStreamReadAvailable( PaStream* stream );
-static signed long GetStreamWriteAvailable( PaStream* stream );
-
-
-/* macros for setting last host error information */
-
-#ifdef UNICODE
-
-#define PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ) \
-    {                                                                   \
-        wchar_t mmeErrorTextWide[ MAXERRORLENGTH ];                     \
-        char mmeErrorText[ MAXERRORLENGTH ];                            \
-        waveInGetErrorText( mmresult, mmeErrorTextWide, MAXERRORLENGTH );   \
-        WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,\
-            mmeErrorTextWide, -1, mmeErrorText, MAXERRORLENGTH, NULL, NULL );  \
-        PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText );   \
-    }
-
-#define PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ) \
-    {                                                                   \
-        wchar_t mmeErrorTextWide[ MAXERRORLENGTH ];                     \
-        char mmeErrorText[ MAXERRORLENGTH ];                            \
-        waveOutGetErrorText( mmresult, mmeErrorTextWide, MAXERRORLENGTH );  \
-        WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,\
-            mmeErrorTextWide, -1, mmeErrorText, MAXERRORLENGTH, NULL, NULL );  \
-        PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText );   \
-    }
-    
-#else /* !UNICODE */
-
-#define PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ) \
-    {                                                                   \
-        char mmeErrorText[ MAXERRORLENGTH ];                            \
-        waveInGetErrorText( mmresult, mmeErrorText, MAXERRORLENGTH );   \
-        PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText );   \
-    }
-
-#define PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ) \
-    {                                                                   \
-        char mmeErrorText[ MAXERRORLENGTH ];                            \
-        waveOutGetErrorText( mmresult, mmeErrorText, MAXERRORLENGTH );  \
-        PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText );   \
-    }
-
-#endif /* UNICODE */
-
-
-static void PaMme_SetLastSystemError( DWORD errorCode )
-{
-    char *lpMsgBuf;
-    FormatMessage(
-        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-        NULL,
-        errorCode,
-        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-        (LPTSTR) &lpMsgBuf,
-        0,
-        NULL
-    );
-    PaUtil_SetLastHostErrorInfo( paMME, errorCode, lpMsgBuf );
-    LocalFree( lpMsgBuf );
-}
-
-#define PA_MME_SET_LAST_SYSTEM_ERROR( errorCode ) \
-    PaMme_SetLastSystemError( errorCode )
-
-
-/* PaError returning wrappers for some commonly used win32 functions
-    note that we allow passing a null ptr to have no effect.
-*/
-
-static PaError CreateEventWithPaError( HANDLE *handle,
-        LPSECURITY_ATTRIBUTES lpEventAttributes,
-        BOOL bManualReset,
-        BOOL bInitialState,
-        LPCTSTR lpName )
-{
-    PaError result = paNoError;
-
-    *handle = NULL;
-    
-    *handle = CreateEvent( lpEventAttributes, bManualReset, bInitialState, lpName );
-    if( *handle == NULL )
-    {
-        result = paUnanticipatedHostError;
-        PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() );
-    }
-
-    return result;
-}
-
-
-static PaError ResetEventWithPaError( HANDLE handle )
-{
-    PaError result = paNoError;
-
-    if( handle )
-    {
-        if( ResetEvent( handle ) == 0 )
-        {
-            result = paUnanticipatedHostError;
-            PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() );
-        }
-    }
-
-    return result;
-}
-
-
-static PaError CloseHandleWithPaError( HANDLE handle )
-{
-    PaError result = paNoError;
-    
-    if( handle )
-    {
-        if( CloseHandle( handle ) == 0 )
-        {
-            result = paUnanticipatedHostError;
-            PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() );
-        }
-    }
-    
-    return result;
-}
-
-
-/* PaWinMmeHostApiRepresentation - host api datastructure specific to this implementation */
-
-typedef struct
-{
-    PaUtilHostApiRepresentation inheritedHostApiRep;
-    PaUtilStreamInterface callbackStreamInterface;
-    PaUtilStreamInterface blockingStreamInterface;
-
-    PaUtilAllocationGroup *allocations;
-    
-    int inputDeviceCount, outputDeviceCount;
-
-    /** winMmeDeviceIds is an array of WinMme device ids.
-        fields in the range [0, inputDeviceCount) are input device ids,
-        and [inputDeviceCount, inputDeviceCount + outputDeviceCount) are output
-        device ids.
-     */ 
-    UINT *winMmeDeviceIds;
-}
-PaWinMmeHostApiRepresentation;
-
-
-typedef struct
-{
-    PaDeviceInfo inheritedDeviceInfo;
-    DWORD dwFormats; /**<< standard formats bitmask from the WAVEINCAPS and WAVEOUTCAPS structures */
-}
-PaWinMmeDeviceInfo;
-
-
-/*************************************************************************
- * 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")
-static PaDeviceIndex GetEnvDefaultDeviceID( char *envName )
-{
-    PaDeviceIndex recommendedIndex = paNoDevice;
-    DWORD   hresult;
-    char    envbuf[PA_ENV_BUF_SIZE_];
-
-#ifndef WIN32_PLATFORM_PSPC /* no GetEnvironmentVariable on PocketPC */
-
-    /* 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_) )
-    {
-        recommendedIndex = atoi( envbuf );
-    }
-#endif
-
-    return recommendedIndex;
-}
-
-
-static void InitializeDefaultDeviceIdsFromEnv( PaWinMmeHostApiRepresentation *hostApi )
-{
-    PaDeviceIndex device;
-
-    /* input */
-    device = GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME_ );
-    if( device != paNoDevice &&
-            ( device >= 0 && device < hostApi->inheritedHostApiRep.info.deviceCount ) &&
-            hostApi->inheritedHostApiRep.deviceInfos[ device ]->maxInputChannels > 0 )
-    {
-        hostApi->inheritedHostApiRep.info.defaultInputDevice = device;
-    }
-
-    /* output */
-    device = GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME_ );
-    if( device != paNoDevice &&
-            ( device >= 0 && device < hostApi->inheritedHostApiRep.info.deviceCount ) &&
-            hostApi->inheritedHostApiRep.deviceInfos[ device ]->maxOutputChannels > 0 )
-    {
-        hostApi->inheritedHostApiRep.info.defaultOutputDevice = device;
-    }
-}
-
-
-/** Convert external PA ID to a windows multimedia device ID
-*/
-static UINT LocalDeviceIndexToWinMmeDeviceId( PaWinMmeHostApiRepresentation *hostApi, PaDeviceIndex device )
-{
-    assert( device >= 0 && device < hostApi->inputDeviceCount + hostApi->outputDeviceCount );
-
-	return hostApi->winMmeDeviceIds[ device ];
-}
-
-
-static PaError QueryInputWaveFormatEx( int deviceId, WAVEFORMATEX *waveFormatEx )
-{
-    MMRESULT mmresult;
-    
-    switch( mmresult = waveInOpen( NULL, deviceId, waveFormatEx, 0, 0, WAVE_FORMAT_QUERY ) )
-    {
-        case MMSYSERR_NOERROR:
-            return paNoError;
-        case MMSYSERR_ALLOCATED:    /* Specified resource is already allocated. */
-            return paDeviceUnavailable;
-        case MMSYSERR_NODRIVER:	    /* No device driver is present. */
-            return paDeviceUnavailable;
-        case MMSYSERR_NOMEM:	    /* Unable to allocate or lock memory. */
-            return paInsufficientMemory;
-        case WAVERR_BADFORMAT:      /* Attempted to open with an unsupported waveform-audio format. */
-            return paSampleFormatNotSupported;
-                    
-        case MMSYSERR_BADDEVICEID:	/* Specified device identifier is out of range. */
-            /* falls through */
-        default:
-            PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
-            return paUnanticipatedHostError;
-    }
-}
-
-
-static PaError QueryOutputWaveFormatEx( int deviceId, WAVEFORMATEX *waveFormatEx )
-{
-    MMRESULT mmresult;
-    
-    switch( mmresult = waveOutOpen( NULL, deviceId, waveFormatEx, 0, 0, WAVE_FORMAT_QUERY ) )
-    {
-        case MMSYSERR_NOERROR:
-            return paNoError;
-        case MMSYSERR_ALLOCATED:    /* Specified resource is already allocated. */
-            return paDeviceUnavailable;
-        case MMSYSERR_NODRIVER:	    /* No device driver is present. */
-            return paDeviceUnavailable;
-        case MMSYSERR_NOMEM:	    /* Unable to allocate or lock memory. */
-            return paInsufficientMemory;
-        case WAVERR_BADFORMAT:      /* Attempted to open with an unsupported waveform-audio format. */
-            return paSampleFormatNotSupported;
-                    
-        case MMSYSERR_BADDEVICEID:	/* Specified device identifier is out of range. */
-            /* falls through */
-        default:
-            PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
-            return paUnanticipatedHostError;
-    }
-}
-
-
-static PaError QueryFormatSupported( PaDeviceInfo *deviceInfo,
-        PaError (*waveFormatExQueryFunction)(int, WAVEFORMATEX*),
-        int winMmeDeviceId, int channels, double sampleRate )
-{
-    PaWinMmeDeviceInfo *winMmeDeviceInfo = (PaWinMmeDeviceInfo*)deviceInfo;
-    WAVEFORMATEX waveFormatEx;
-    
-    if( sampleRate == 11025.0
-        && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_1M16))
-            || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_1S16)) ) ){
-
-        return paNoError;
-    }
-
-    if( sampleRate == 22050.0
-        && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_2M16))
-            || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_2S16)) ) ){
-
-        return paNoError;
-    }
-
-    if( sampleRate == 44100.0
-        && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_4M16))
-            || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_4S16)) ) ){
-
-        return paNoError;
-    }
-
-    waveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
-    waveFormatEx.nChannels = (WORD)channels;
-    waveFormatEx.nSamplesPerSec = (DWORD)sampleRate;
-    waveFormatEx.nAvgBytesPerSec = waveFormatEx.nSamplesPerSec * channels * sizeof(short);
-    waveFormatEx.nBlockAlign = (WORD)(channels * sizeof(short));
-    waveFormatEx.wBitsPerSample = 16;
-    waveFormatEx.cbSize = 0;
-
-    return waveFormatExQueryFunction( winMmeDeviceId, &waveFormatEx );
-}
-
-
-#define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_  (13) /* must match array length below */
-static double defaultSampleRateSearchOrder_[] =
-    { 44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0,
-        16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };
-
-static void DetectDefaultSampleRate( PaWinMmeDeviceInfo *winMmeDeviceInfo, int winMmeDeviceId,
-        PaError (*waveFormatExQueryFunction)(int, WAVEFORMATEX*), int maxChannels )
-{
-    PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
-    int i;
-    
-    deviceInfo->defaultSampleRate = 0.;
-
-    for( i=0; i < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++i )
-    {
-        double sampleRate = defaultSampleRateSearchOrder_[ i ]; 
-        PaError paerror = QueryFormatSupported( deviceInfo, waveFormatExQueryFunction, winMmeDeviceId, maxChannels, sampleRate );
-        if( paerror == paNoError )
-        {
-            deviceInfo->defaultSampleRate = sampleRate;
-            break;
-        }
-    }
-}
-
-
-static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi,
-        PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeInputDeviceId, int *success )
-{
-    PaError result = paNoError;
-    char *deviceName; /* non-const ptr */
-    MMRESULT mmresult;
-    WAVEINCAPS wic;
-    PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
-    
-    *success = 0;
-
-    mmresult = waveInGetDevCaps( winMmeInputDeviceId, &wic, sizeof( WAVEINCAPS ) );
-    if( mmresult == MMSYSERR_NOMEM )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-    else if( mmresult != MMSYSERR_NOERROR )
-    {
-        /* instead of returning paUnanticipatedHostError we return
-            paNoError, but leave success set as 0. This allows
-            Pa_Initialize to just ignore this device, without failing
-            the entire initialisation process.
-        */
-        return paNoError;
-    }           
-
-    if( winMmeInputDeviceId == WAVE_MAPPER )
-    {
-        /* Append I/O suffix to WAVE_MAPPER device. */
-        deviceName = (char *)PaUtil_GroupAllocateMemory(
-                    winMmeHostApi->allocations, strlen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_) );
-        if( !deviceName )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-        strcpy( deviceName, wic.szPname );
-        strcat( deviceName, constInputMapperSuffix_ );
-    }
-    else
-    {
-        deviceName = (char*)PaUtil_GroupAllocateMemory(
-                    winMmeHostApi->allocations, strlen( wic.szPname ) + 1 );
-        if( !deviceName )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-        strcpy( deviceName, wic.szPname  );
-    }
-    deviceInfo->name = deviceName;
-
-    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
-     */
-    if( (deviceInfo->maxInputChannels < 1) || (deviceInfo->maxInputChannels > 256) )
-    {
-        PA_DEBUG(("Pa_GetDeviceInfo: Num input channels reported as %d! Changed to 2.\n", deviceInfo->maxInputChannels ));
-        deviceInfo->maxInputChannels = 2;
-    }
-
-    winMmeDeviceInfo->dwFormats = wic.dwFormats;
-
-    DetectDefaultSampleRate( winMmeDeviceInfo, winMmeInputDeviceId,
-            QueryInputWaveFormatEx, deviceInfo->maxInputChannels );
-
-    *success = 1;
-    
-error:
-    return result;
-}
-
-
-static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi,
-        PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeOutputDeviceId, int *success )
-{
-    PaError result = paNoError;
-    char *deviceName; /* non-const ptr */
-    MMRESULT mmresult;
-    WAVEOUTCAPS woc;
-    PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
-    
-    *success = 0;
-
-    mmresult = waveOutGetDevCaps( winMmeOutputDeviceId, &woc, sizeof( WAVEOUTCAPS ) );
-    if( mmresult == MMSYSERR_NOMEM )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-    else if( mmresult != MMSYSERR_NOERROR )
-    {
-        /* instead of returning paUnanticipatedHostError we return
-            paNoError, but leave success set as 0. This allows
-            Pa_Initialize to just ignore this device, without failing
-            the entire initialisation process.
-        */
-        return paNoError;
-    }
-
-    if( winMmeOutputDeviceId == WAVE_MAPPER )
-    {
-        /* Append I/O suffix to WAVE_MAPPER device. */
-        deviceName = (char *)PaUtil_GroupAllocateMemory(
-                    winMmeHostApi->allocations, strlen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_) );
-        if( !deviceName )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-        strcpy( deviceName, woc.szPname );
-        strcat( deviceName, constOutputMapperSuffix_ );
-    }
-    else
-    {
-        deviceName = (char*)PaUtil_GroupAllocateMemory(
-                    winMmeHostApi->allocations, strlen( woc.szPname ) + 1 );
-        if( !deviceName )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-        strcpy( deviceName, woc.szPname  );
-    }
-    deviceInfo->name = deviceName;
-
-    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!
-     */
-    if( (deviceInfo->maxOutputChannels < 1) || (deviceInfo->maxOutputChannels > 256) )
-    {
-        PA_DEBUG(("Pa_GetDeviceInfo: Num output channels reported as %d! Changed to 2.\n", deviceInfo->maxOutputChannels ));
-        deviceInfo->maxOutputChannels = 2;
-    }
-
-    winMmeDeviceInfo->dwFormats = woc.dwFormats;
-
-    DetectDefaultSampleRate( winMmeDeviceInfo, winMmeOutputDeviceId,
-            QueryOutputWaveFormatEx, deviceInfo->maxOutputChannels );
-
-    *success = 1;
-    
-error:
-    return result;
-}
-
-
-static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighLatency )
-{
-    OSVERSIONINFO osvi;
-    osvi.dwOSVersionInfoSize = sizeof( osvi );
-	GetVersionEx( &osvi );
-
-    /* Check for NT */
-    if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
-    {
-        *defaultLowLatency = PA_MME_WIN_NT_DEFAULT_LATENCY_;
-    }
-    else if(osvi.dwMajorVersion >= 5)
-    {
-        *defaultLowLatency  = PA_MME_WIN_WDM_DEFAULT_LATENCY_;
-    }
-    else
-    {
-        *defaultLowLatency  = PA_MME_WIN_9X_DEFAULT_LATENCY_;
-    }     
-
-    *defaultHighLatency = *defaultLowLatency * 2;
-}
-
-
-PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
-{
-    PaError result = paNoError;
-    int i;
-    PaWinMmeHostApiRepresentation *winMmeHostApi;
-    int inputDeviceCount, outputDeviceCount, maximumPossibleDeviceCount;
-    PaWinMmeDeviceInfo *deviceInfoArray;
-    int deviceInfoInitializationSucceeded;
-    PaTime defaultLowLatency, defaultHighLatency;
-
-    winMmeHostApi = (PaWinMmeHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinMmeHostApiRepresentation) );
-    if( !winMmeHostApi )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    winMmeHostApi->allocations = PaUtil_CreateAllocationGroup();
-    if( !winMmeHostApi->allocations )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    *hostApi = &winMmeHostApi->inheritedHostApiRep;
-    (*hostApi)->info.structVersion = 1;
-    (*hostApi)->info.type = paMME;
-    (*hostApi)->info.name = "MME";
-
-    
-    /* initialise device counts and default devices under the assumption that
-        there are no devices. These values are incremented below if and when
-        devices are successfully initialized.
-    */
-    (*hostApi)->info.deviceCount = 0;
-    (*hostApi)->info.defaultInputDevice = paNoDevice;
-    (*hostApi)->info.defaultOutputDevice = paNoDevice;
-    winMmeHostApi->inputDeviceCount = 0;
-    winMmeHostApi->outputDeviceCount = 0;
-
-
-    maximumPossibleDeviceCount = 0;
-
-    inputDeviceCount = waveInGetNumDevs();
-    if( inputDeviceCount > 0 )
-    	maximumPossibleDeviceCount += inputDeviceCount + 1;	/* assume there is a WAVE_MAPPER */
-
-    outputDeviceCount = waveOutGetNumDevs();
-    if( outputDeviceCount > 0 )
-	    maximumPossibleDeviceCount += outputDeviceCount + 1;	/* assume there is a WAVE_MAPPER */
-
-
-    if( maximumPossibleDeviceCount > 0 ){
-
-        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
-                winMmeHostApi->allocations, sizeof(PaDeviceInfo*) * maximumPossibleDeviceCount );
-        if( !(*hostApi)->deviceInfos )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        /* allocate all device info structs in a contiguous block */
-        deviceInfoArray = (PaWinMmeDeviceInfo*)PaUtil_GroupAllocateMemory(
-                winMmeHostApi->allocations, sizeof(PaWinMmeDeviceInfo) * maximumPossibleDeviceCount );
-        if( !deviceInfoArray )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        winMmeHostApi->winMmeDeviceIds = (UINT*)PaUtil_GroupAllocateMemory(
-                winMmeHostApi->allocations, sizeof(int) * maximumPossibleDeviceCount );
-        if( !winMmeHostApi->winMmeDeviceIds )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        GetDefaultLatencies( &defaultLowLatency, &defaultHighLatency );
-
-        if( inputDeviceCount > 0 ){
-            /* -1 is the WAVE_MAPPER */
-            for( i = -1; i < inputDeviceCount; ++i ){
-                UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
-                PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
-                PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
-                deviceInfo->structVersion = 2;
-                deviceInfo->hostApi = hostApiIndex;
-
-                deviceInfo->maxInputChannels = 0;
-                deviceInfo->maxOutputChannels = 0;
-
-                deviceInfo->defaultLowInputLatency = defaultLowLatency;
-                deviceInfo->defaultLowOutputLatency = defaultLowLatency;
-                deviceInfo->defaultHighInputLatency = defaultHighLatency;
-                deviceInfo->defaultHighOutputLatency = defaultHighLatency;
-
-                result = InitializeInputDeviceInfo( winMmeHostApi, wmmeDeviceInfo,
-                        winMmeDeviceId, &deviceInfoInitializationSucceeded );
-                if( result != paNoError )
-                    goto error;
-
-                if( deviceInfoInitializationSucceeded ){
-                    if( (*hostApi)->info.defaultInputDevice == paNoDevice )
-                        (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount;
-
-                    winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId;
-                    (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
-
-                    winMmeHostApi->inputDeviceCount++;
-                    (*hostApi)->info.deviceCount++;
-                }
-            }
-        }
-
-        if( outputDeviceCount > 0 ){
-            /* -1 is the WAVE_MAPPER */
-            for( i = -1; i < outputDeviceCount; ++i ){
-                UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
-                PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
-                PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
-                deviceInfo->structVersion = 2;
-                deviceInfo->hostApi = hostApiIndex;
-
-                deviceInfo->maxInputChannels = 0;
-                deviceInfo->maxOutputChannels = 0;
-
-                deviceInfo->defaultLowInputLatency = defaultLowLatency;
-                deviceInfo->defaultLowOutputLatency = defaultLowLatency;
-                deviceInfo->defaultHighInputLatency = defaultHighLatency;
-                deviceInfo->defaultHighOutputLatency = defaultHighLatency; 
-
-                result = InitializeOutputDeviceInfo( winMmeHostApi, wmmeDeviceInfo,
-                        winMmeDeviceId, &deviceInfoInitializationSucceeded );
-                if( result != paNoError )
-                    goto error;
-
-                if( deviceInfoInitializationSucceeded ){
-                    if( (*hostApi)->info.defaultOutputDevice == paNoDevice )
-                        (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount;
-
-                    winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId;
-                    (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
-
-                    winMmeHostApi->outputDeviceCount++;
-                    (*hostApi)->info.deviceCount++;
-                }
-            }
-        }
-    }
-    
-
-    InitializeDefaultDeviceIdsFromEnv( winMmeHostApi );
-
-    (*hostApi)->Terminate = Terminate;
-    (*hostApi)->OpenStream = OpenStream;
-    (*hostApi)->IsFormatSupported = IsFormatSupported;
-
-    PaUtil_InitializeStreamInterface( &winMmeHostApi->callbackStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, GetStreamCpuLoad,
-                                      PaUtil_DummyRead, PaUtil_DummyWrite,
-                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
-
-    PaUtil_InitializeStreamInterface( &winMmeHostApi->blockingStreamInterface, CloseStream, StartStream,
-                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
-                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
-                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
-
-    return result;
-
-error:
-    if( winMmeHostApi )
-    {
-        if( winMmeHostApi->allocations )
-        {
-            PaUtil_FreeAllAllocations( winMmeHostApi->allocations );
-            PaUtil_DestroyAllocationGroup( winMmeHostApi->allocations );
-        }
-        
-        PaUtil_FreeMemory( winMmeHostApi );
-    }
-
-    return result;
-}
-
-
-static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
-{
-    PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
-
-    if( winMmeHostApi->allocations )
-    {
-        PaUtil_FreeAllAllocations( winMmeHostApi->allocations );
-        PaUtil_DestroyAllocationGroup( winMmeHostApi->allocations );
-    }
-
-    PaUtil_FreeMemory( winMmeHostApi );
-}
-
-
-static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
-                                  const PaStreamParameters *inputParameters,
-                                  const PaStreamParameters *outputParameters,
-                                  double sampleRate )
-{
-    PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
-    PaDeviceInfo *inputDeviceInfo, *outputDeviceInfo;
-    int inputChannelCount, outputChannelCount;
-    int inputMultipleDeviceChannelCount, outputMultipleDeviceChannelCount;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    PaWinMmeStreamInfo *inputStreamInfo, *outputStreamInfo;
-    UINT winMmeInputDeviceId, winMmeOutputDeviceId;
-    unsigned int i;
-    PaError paerror;
-
-    /* The calls to QueryFormatSupported below are intended to detect invalid
-        sample rates. If we assume that the channel count and format are OK,
-        then the only thing that could fail is the sample rate. This isn't
-        strictly true, but I can't think of a better way to test that the
-        sample rate is valid.
-    */  
-    
-    if( inputParameters )
-    {
-        inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-        inputStreamInfo = inputParameters->hostApiSpecificStreamInfo;
-        
-        /* all standard sample formats are supported by the buffer adapter,
-             this implementation doesn't support any custom sample formats */
-        if( inputSampleFormat & paCustomFormat )
-            return paSampleFormatNotSupported;
-
-        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification
-                && inputStreamInfo && (inputStreamInfo->flags & paWinMmeUseMultipleDevices) )
-        {
-            inputMultipleDeviceChannelCount = 0;
-            for( i=0; i< inputStreamInfo->deviceCount; ++i )
-            {
-                inputMultipleDeviceChannelCount += inputStreamInfo->devices[i].channelCount;
-                    
-                inputDeviceInfo = hostApi->deviceInfos[ inputStreamInfo->devices[i].device ];
-
-                /* check that input device can support inputChannelCount */
-                if( inputStreamInfo->devices[i].channelCount <= 0
-                        || inputStreamInfo->devices[i].channelCount > inputDeviceInfo->maxInputChannels )
-                    return paInvalidChannelCount;
-
-                /* test for valid sample rate, see comment above */
-                winMmeInputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, inputStreamInfo->devices[i].device );
-                paerror = QueryFormatSupported( inputDeviceInfo, QueryInputWaveFormatEx, winMmeInputDeviceId, inputStreamInfo->devices[i].channelCount, sampleRate );
-                if( paerror != paNoError )
-                    return paInvalidSampleRate;
-            }
-                
-            if( inputMultipleDeviceChannelCount != inputChannelCount )
-                return paIncompatibleHostApiSpecificStreamInfo;                  
-        }
-        else
-        {
-            if( inputStreamInfo && (inputStreamInfo->flags & paWinMmeUseMultipleDevices) )
-                return paIncompatibleHostApiSpecificStreamInfo; /* paUseHostApiSpecificDeviceSpecification was not supplied as the input device */
-
-            inputDeviceInfo = hostApi->deviceInfos[ inputParameters->device ];
-
-            /* check that input device can support inputChannelCount */
-            if( inputChannelCount > inputDeviceInfo->maxInputChannels )
-                return paInvalidChannelCount;
-
-            /* test for valid sample rate, see comment above */
-            winMmeInputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, inputParameters->device );
-            paerror = QueryFormatSupported( inputDeviceInfo, QueryInputWaveFormatEx, winMmeInputDeviceId, inputChannelCount, sampleRate );
-            if( paerror != paNoError )
-                return paInvalidSampleRate;
-        }
-    }
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-        outputStreamInfo = outputParameters->hostApiSpecificStreamInfo;
-
-        /* all standard sample formats are supported by the buffer adapter,
-            this implementation doesn't support any custom sample formats */
-        if( outputSampleFormat & paCustomFormat )
-            return paSampleFormatNotSupported;
-
-        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification
-                && outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) )
-        {
-            outputMultipleDeviceChannelCount = 0;
-            for( i=0; i< outputStreamInfo->deviceCount; ++i )
-            {
-                outputMultipleDeviceChannelCount += outputStreamInfo->devices[i].channelCount;
-                    
-                outputDeviceInfo = hostApi->deviceInfos[ outputStreamInfo->devices[i].device ];
-
-                /* check that output device can support outputChannelCount */
-                if( outputStreamInfo->devices[i].channelCount <= 0
-                        || outputStreamInfo->devices[i].channelCount > outputDeviceInfo->maxOutputChannels )
-                    return paInvalidChannelCount;
-
-                /* test for valid sample rate, see comment above */
-                winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputStreamInfo->devices[i].device );
-                paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputStreamInfo->devices[i].channelCount, sampleRate );
-                if( paerror != paNoError )
-                    return paInvalidSampleRate;
-            }
-                
-            if( outputMultipleDeviceChannelCount != outputChannelCount )
-                return paIncompatibleHostApiSpecificStreamInfo;            
-        }
-        else
-        {
-            if( outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) )
-                return paIncompatibleHostApiSpecificStreamInfo; /* paUseHostApiSpecificDeviceSpecification was not supplied as the output device */
-
-            outputDeviceInfo = hostApi->deviceInfos[ outputParameters->device ];
-
-            /* check that output device can support outputChannelCount */
-            if( outputChannelCount > outputDeviceInfo->maxOutputChannels )
-                return paInvalidChannelCount;
-
-            /* test for valid sample rate, see comment above */
-            winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputParameters->device );
-            paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputChannelCount, sampleRate );
-            if( paerror != paNoError )
-                return paInvalidSampleRate;
-        }
-    }
-    
-    /*
-            - if a full duplex stream is requested, check that the combination
-                of input and output parameters is supported
-
-            - check that the device supports sampleRate
-
-            for mme all we can do is test that the input and output devices
-            support the requested sample rate and number of channels. we
-            cannot test for full duplex compatibility.
-    */                                             
-
-    return paFormatIsSupported;
-}
-
-
-
-static void SelectBufferSizeAndCount( unsigned long baseBufferSize,
-    unsigned long requestedLatency,
-    unsigned long baseBufferCount, unsigned long minimumBufferCount,
-    unsigned long maximumBufferSize, unsigned long *hostBufferSize,
-    unsigned long *hostBufferCount )
-{
-    unsigned long sizeMultiplier, bufferCount, latency;
-    unsigned long nextLatency, nextBufferSize;
-    int baseBufferSizeIsPowerOfTwo;
-    
-    sizeMultiplier = 1;
-    bufferCount = baseBufferCount;
-
-    /* count-1 below because latency is always determined by one less
-        than the total number of buffers.
-    */
-    latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1);
-
-    if( latency > requestedLatency )
-    {
-
-        /* reduce number of buffers without falling below suggested latency */
-
-        nextLatency = (baseBufferSize * sizeMultiplier) * (bufferCount-2);
-        while( bufferCount > minimumBufferCount && nextLatency >= requestedLatency )
-        {
-            --bufferCount;
-            nextLatency = (baseBufferSize * sizeMultiplier) * (bufferCount-2);
-        }
-
-    }else if( latency < requestedLatency ){
-
-        baseBufferSizeIsPowerOfTwo = (! (baseBufferSize & (baseBufferSize - 1)));
-        if( baseBufferSizeIsPowerOfTwo ){
-
-            /* double size of buffers without exceeding requestedLatency */
-
-            nextBufferSize = (baseBufferSize * (sizeMultiplier*2));
-            nextLatency = nextBufferSize * (bufferCount-1);
-            while( nextBufferSize <= maximumBufferSize
-                    && nextLatency < requestedLatency )
-            {
-                sizeMultiplier *= 2;
-                nextBufferSize = (baseBufferSize * (sizeMultiplier*2));
-                nextLatency = nextBufferSize * (bufferCount-1);
-            }   
-
-        }else{
-
-            /* increase size of buffers upto first excess of requestedLatency */
-
-            nextBufferSize = (baseBufferSize * (sizeMultiplier+1));
-            nextLatency = nextBufferSize * (bufferCount-1);
-            while( nextBufferSize <= maximumBufferSize
-                    && nextLatency < requestedLatency )
-            {
-                ++sizeMultiplier;
-                nextBufferSize = (baseBufferSize * (sizeMultiplier+1));
-                nextLatency = nextBufferSize * (bufferCount-1);
-            }
-
-            if( nextLatency < requestedLatency )
-                ++sizeMultiplier;            
-        }
-
-        /* increase number of buffers until requestedLatency is reached */
-
-        latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1);
-        while( latency < requestedLatency )
-        {
-            ++bufferCount;
-            latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1);
-        }
-    }
-
-    *hostBufferSize = baseBufferSize * sizeMultiplier;
-    *hostBufferCount = bufferCount;
-}
-
-
-static void ReselectBufferCount( unsigned long bufferSize,
-    unsigned long requestedLatency,
-    unsigned long baseBufferCount, unsigned long minimumBufferCount,
-    unsigned long *hostBufferCount )
-{
-    unsigned long bufferCount, latency;
-    unsigned long nextLatency;
-
-    bufferCount = baseBufferCount;
-
-    /* count-1 below because latency is always determined by one less
-        than the total number of buffers.
-    */
-    latency = bufferSize * (bufferCount-1);
-
-    if( latency > requestedLatency )
-    {
-        /* reduce number of buffers without falling below suggested latency */
-
-        nextLatency = bufferSize * (bufferCount-2);
-        while( bufferCount > minimumBufferCount && nextLatency >= requestedLatency )
-        {
-            --bufferCount;
-            nextLatency = bufferSize * (bufferCount-2);
-        }
-
-    }else if( latency < requestedLatency ){
-
-        /* increase number of buffers until requestedLatency is reached */
-
-        latency = bufferSize * (bufferCount-1);
-        while( latency < requestedLatency )
-        {
-            ++bufferCount;
-            latency = bufferSize * (bufferCount-1);
-        }                                                         
-    }
-
-    *hostBufferCount = bufferCount;
-}
-
-
-/* CalculateBufferSettings() fills the framesPerHostInputBuffer, hostInputBufferCount,
-   framesPerHostOutputBuffer and hostOutputBufferCount parameters based on the values
-   of the other parameters.
-*/
-
-static PaError CalculateBufferSettings(
-        unsigned long *framesPerHostInputBuffer, unsigned long *hostInputBufferCount,
-        unsigned long *framesPerHostOutputBuffer, unsigned long *hostOutputBufferCount,
-        int inputChannelCount, PaSampleFormat hostInputSampleFormat,
-        PaTime suggestedInputLatency, PaWinMmeStreamInfo *inputStreamInfo,
-        int outputChannelCount, PaSampleFormat hostOutputSampleFormat,
-        PaTime suggestedOutputLatency, PaWinMmeStreamInfo *outputStreamInfo,
-        double sampleRate, unsigned long framesPerBuffer )
-{
-    PaError result = paNoError;
-    int effectiveInputChannelCount, effectiveOutputChannelCount;
-    int hostInputFrameSize = 0;
-    unsigned int i;
-    
-    if( inputChannelCount > 0 )
-    {
-        int hostInputSampleSize = Pa_GetSampleSize( hostInputSampleFormat );
-        if( hostInputSampleSize < 0 )
-        {
-            result = hostInputSampleSize;
-            goto error;
-        }
-
-        if( inputStreamInfo
-                && ( inputStreamInfo->flags & paWinMmeUseMultipleDevices ) )
-        {
-            /* set effectiveInputChannelCount to the largest number of
-                channels on any one device.
-            */
-            effectiveInputChannelCount = 0;
-            for( i=0; i< inputStreamInfo->deviceCount; ++i )
-            {
-                if( inputStreamInfo->devices[i].channelCount > effectiveInputChannelCount )
-                    effectiveInputChannelCount = inputStreamInfo->devices[i].channelCount;
-            }
-        }
-        else
-        {
-            effectiveInputChannelCount = inputChannelCount;
-        }
-
-        hostInputFrameSize = hostInputSampleSize * effectiveInputChannelCount;
-
-        if( inputStreamInfo
-                && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) )
-        {
-            if( inputStreamInfo->bufferCount <= 0
-                    || inputStreamInfo->framesPerBuffer <= 0 )
-            {
-                result = paIncompatibleHostApiSpecificStreamInfo;
-                goto error;
-            }
-
-            *framesPerHostInputBuffer = inputStreamInfo->framesPerBuffer;
-            *hostInputBufferCount = inputStreamInfo->bufferCount;
-        }
-        else
-        {
-            unsigned long hostBufferSizeBytes, hostBufferCount;
-            unsigned long minimumBufferCount = (outputChannelCount > 0)
-                    ? PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_
-                    : PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_;
-
-            unsigned long maximumBufferSize = (long) ((PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate) * hostInputFrameSize);
-            if( maximumBufferSize > PA_MME_MAX_HOST_BUFFER_BYTES_ )
-                maximumBufferSize = PA_MME_MAX_HOST_BUFFER_BYTES_;
-
-            /* compute the following in bytes, then convert back to frames */
-
-            SelectBufferSizeAndCount(
-                ((framesPerBuffer == paFramesPerBufferUnspecified)
-                    ? PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_
-                    : framesPerBuffer ) * hostInputFrameSize, /* baseBufferSize */
-                ((unsigned long)(suggestedInputLatency * sampleRate)) * hostInputFrameSize, /* suggestedLatency */
-                4, /* baseBufferCount */
-                minimumBufferCount, maximumBufferSize,
-                &hostBufferSizeBytes, &hostBufferCount );
-
-            *framesPerHostInputBuffer = hostBufferSizeBytes / hostInputFrameSize;
-            *hostInputBufferCount = hostBufferCount;
-        }
-    }
-    else
-    {
-        *framesPerHostInputBuffer = 0;
-        *hostInputBufferCount = 0;
-    }
-
-    if( outputChannelCount > 0 )
-    {
-        if( outputStreamInfo
-                && ( outputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) )
-        {
-            if( outputStreamInfo->bufferCount <= 0
-                    || outputStreamInfo->framesPerBuffer <= 0 )
-            {
-                result = paIncompatibleHostApiSpecificStreamInfo;
-                goto error;
-            }
-
-            *framesPerHostOutputBuffer = outputStreamInfo->framesPerBuffer;
-            *hostOutputBufferCount = outputStreamInfo->bufferCount;
-
-            
-            if( inputChannelCount > 0 ) /* full duplex */
-            {
-                if( *framesPerHostInputBuffer != *framesPerHostOutputBuffer )
-                {
-                    if( inputStreamInfo
-                            && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) )
-                    { 
-                        /* a custom StreamInfo was used for specifying both input
-                            and output buffer sizes, the larger buffer size
-                            must be a multiple of the smaller buffer size */
-
-                        if( *framesPerHostInputBuffer < *framesPerHostOutputBuffer )
-                        {
-                            if( *framesPerHostOutputBuffer % *framesPerHostInputBuffer != 0 )
-                            {
-                                result = paIncompatibleHostApiSpecificStreamInfo;
-                                goto error;
-                            }
-                        }
-                        else
-                        {
-                            assert( *framesPerHostInputBuffer > *framesPerHostOutputBuffer );
-                            if( *framesPerHostInputBuffer % *framesPerHostOutputBuffer != 0 )
-                            {
-                                result = paIncompatibleHostApiSpecificStreamInfo;
-                                goto error;
-                            }
-                        }                        
-                    }
-                    else
-                    {
-                        /* a custom StreamInfo was not used for specifying the input buffer size,
-                            so use the output buffer size, and approximately the same latency. */
-
-                        *framesPerHostInputBuffer = *framesPerHostOutputBuffer;
-                        *hostInputBufferCount = (((unsigned long)(suggestedInputLatency * sampleRate)) / *framesPerHostInputBuffer) + 1;
-
-                        if( *hostInputBufferCount < PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ )
-                            *hostInputBufferCount = PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_;
-                    }
-                }
-            }
-        }
-        else
-        {
-            unsigned long hostBufferSizeBytes, hostBufferCount;
-            unsigned long minimumBufferCount = PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_;
-            unsigned long maximumBufferSize;
-            int hostOutputFrameSize;
-            int hostOutputSampleSize;
-
-            hostOutputSampleSize = Pa_GetSampleSize( hostOutputSampleFormat );
-            if( hostOutputSampleSize < 0 )
-            {
-                result = hostOutputSampleSize;
-                goto error;
-            }
-
-            if( outputStreamInfo
-                && ( outputStreamInfo->flags & paWinMmeUseMultipleDevices ) )
-            {
-                /* set effectiveOutputChannelCount to the largest number of
-                    channels on any one device.
-                */
-                effectiveOutputChannelCount = 0;
-                for( i=0; i< outputStreamInfo->deviceCount; ++i )
-                {
-                    if( outputStreamInfo->devices[i].channelCount > effectiveOutputChannelCount )
-                        effectiveOutputChannelCount = outputStreamInfo->devices[i].channelCount;
-                }
-            }
-            else
-            {
-                effectiveOutputChannelCount = outputChannelCount;
-            }
-
-            hostOutputFrameSize = hostOutputSampleSize * effectiveOutputChannelCount;
-            
-            maximumBufferSize = (long) ((PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate) * hostOutputFrameSize);
-            if( maximumBufferSize > PA_MME_MAX_HOST_BUFFER_BYTES_ )
-                maximumBufferSize = PA_MME_MAX_HOST_BUFFER_BYTES_;
-
-
-            /* compute the following in bytes, then convert back to frames */
-
-            SelectBufferSizeAndCount(
-                ((framesPerBuffer == paFramesPerBufferUnspecified)
-                    ? PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_
-                    : framesPerBuffer ) * hostOutputFrameSize, /* baseBufferSize */
-                ((unsigned long)(suggestedOutputLatency * sampleRate)) * hostOutputFrameSize, /* suggestedLatency */
-                4, /* baseBufferCount */
-                minimumBufferCount,
-                maximumBufferSize,
-                &hostBufferSizeBytes, &hostBufferCount );
-
-            *framesPerHostOutputBuffer = hostBufferSizeBytes / hostOutputFrameSize;
-            *hostOutputBufferCount = hostBufferCount;
-
-
-            if( inputChannelCount > 0 )
-            {
-                /* ensure that both input and output buffer sizes are the same.
-                    if they don't match at this stage, choose the smallest one
-                    and use that for input and output
-                */
-
-                if( *framesPerHostOutputBuffer != *framesPerHostInputBuffer )
-                {
-                    if( framesPerHostInputBuffer < framesPerHostOutputBuffer )
-                    {
-                        unsigned long framesPerHostBuffer = *framesPerHostInputBuffer;
-                        
-                        minimumBufferCount = PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_;
-                        ReselectBufferCount(
-                            framesPerHostBuffer * hostOutputFrameSize, /* bufferSize */
-                            ((unsigned long)(suggestedOutputLatency * sampleRate)) * hostOutputFrameSize, /* suggestedLatency */
-                            4, /* baseBufferCount */
-                            minimumBufferCount,
-                            &hostBufferCount );
-
-                        *framesPerHostOutputBuffer = framesPerHostBuffer;
-                        *hostOutputBufferCount = hostBufferCount;
-                    }
-                    else
-                    {
-                        unsigned long framesPerHostBuffer = *framesPerHostOutputBuffer;
-                        
-                        minimumBufferCount = PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_;
-                        ReselectBufferCount(
-                            framesPerHostBuffer * hostInputFrameSize, /* bufferSize */
-                            ((unsigned long)(suggestedInputLatency * sampleRate)) * hostInputFrameSize, /* suggestedLatency */
-                            4, /* baseBufferCount */
-                            minimumBufferCount,
-                            &hostBufferCount );
-
-                        *framesPerHostInputBuffer = framesPerHostBuffer;
-                        *hostInputBufferCount = hostBufferCount;
-                    }
-                }   
-            }
-        }
-    }
-    else
-    {
-        *framesPerHostOutputBuffer = 0;
-        *hostOutputBufferCount = 0;
-    }
-
-error:
-    return result;
-}
-
-
-typedef struct
-{
-    HANDLE bufferEvent;
-    void *waveHandles;
-    unsigned int deviceCount;
-    /* unsigned int channelCount; */
-    WAVEHDR **waveHeaders;                  /* waveHeaders[device][buffer] */
-    unsigned int bufferCount;
-    unsigned int currentBufferIndex;
-    unsigned int framesPerBuffer;
-    unsigned int framesUsedInCurrentBuffer;
-}PaWinMmeSingleDirectionHandlesAndBuffers;
-
-/* prototypes for functions operating on PaWinMmeSingleDirectionHandlesAndBuffers */
-
-static void InitializeSingleDirectionHandlesAndBuffers( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers );
-static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostApi,
-        PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers,
-        unsigned long bytesPerHostSample,
-        double sampleRate, PaWinMmeDeviceAndChannelCount *devices,
-        unsigned int deviceCount, int isInput );
-static PaError TerminateWaveHandles( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput, int currentlyProcessingAnError );
-static PaError InitializeWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers,
-        unsigned long hostBufferCount,
-        PaSampleFormat hostSampleFormat,
-        unsigned long framesPerHostBuffer,
-        PaWinMmeDeviceAndChannelCount *devices,
-        int isInput );
-static void TerminateWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput );
-
-
-static void InitializeSingleDirectionHandlesAndBuffers( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers )
-{
-    handlesAndBuffers->bufferEvent = 0;
-    handlesAndBuffers->waveHandles = 0;
-    handlesAndBuffers->deviceCount = 0;
-    handlesAndBuffers->waveHeaders = 0;
-    handlesAndBuffers->bufferCount = 0;
-}    
-
-static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostApi,
-        PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers,
-        unsigned long bytesPerHostSample,
-        double sampleRate, PaWinMmeDeviceAndChannelCount *devices,
-        unsigned int deviceCount, int isInput )
-{
-    PaError result;
-    MMRESULT mmresult;
-    unsigned long bytesPerFrame;
-    WAVEFORMATEX wfx;
-    signed int i;
-
-    /* for error cleanup we expect that InitializeSingleDirectionHandlesAndBuffers()
-        has already been called to zero some fields */       
-
-    result = CreateEventWithPaError( &handlesAndBuffers->bufferEvent, NULL, FALSE, FALSE, NULL );
-    if( result != paNoError ) goto error;
-
-    if( isInput )
-        handlesAndBuffers->waveHandles = (void*)PaUtil_AllocateMemory( sizeof(HWAVEIN) * deviceCount );
-    else
-        handlesAndBuffers->waveHandles = (void*)PaUtil_AllocateMemory( sizeof(HWAVEOUT) * deviceCount );
-    if( !handlesAndBuffers->waveHandles )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    handlesAndBuffers->deviceCount = deviceCount;
-
-    for( i = 0; i < (signed int)deviceCount; ++i )
-    {
-        if( isInput )
-            ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] = 0;
-        else
-            ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] = 0;
-    }
-
-    wfx.wFormatTag = WAVE_FORMAT_PCM;
-    wfx.nSamplesPerSec = (DWORD) sampleRate;
-    wfx.cbSize = 0;
-    
-    for( i = 0; i < (signed int)deviceCount; ++i )
-    {
-        UINT winMmeDeviceId;
-
-        winMmeDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, devices[i].device );
-        wfx.nChannels = (WORD)devices[i].channelCount;
-
-        bytesPerFrame = wfx.nChannels * bytesPerHostSample;
-
-        wfx.nAvgBytesPerSec = (DWORD)(bytesPerFrame * sampleRate);
-        wfx.nBlockAlign = (WORD)bytesPerFrame;
-        wfx.wBitsPerSample = (WORD)((bytesPerFrame/wfx.nChannels) * 8);
-
-        /* REVIEW: consider not firing an event for input when a full duplex
-            stream is being used. this would probably depend on the
-            neverDropInput flag. */
-
-        if( isInput )
-            mmresult = waveInOpen( &((HWAVEIN*)handlesAndBuffers->waveHandles)[i], winMmeDeviceId, &wfx,
-                               (DWORD_PTR)handlesAndBuffers->bufferEvent, (DWORD_PTR)0, CALLBACK_EVENT );
-        else
-            mmresult = waveOutOpen( &((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], winMmeDeviceId, &wfx,
-                                (DWORD_PTR)handlesAndBuffers->bufferEvent, (DWORD_PTR)0, CALLBACK_EVENT );
-
-        if( mmresult != MMSYSERR_NOERROR )
-        {
-            switch( mmresult )
-            {
-                case MMSYSERR_ALLOCATED:    /* Specified resource is already allocated. */
-                    result = paDeviceUnavailable;
-                    break;
-                case MMSYSERR_NODRIVER:	    /* No device driver is present. */
-                    result = paDeviceUnavailable;
-                    break;
-                case MMSYSERR_NOMEM:	    /* Unable to allocate or lock memory. */
-                    result = paInsufficientMemory;
-                    break;
-
-                case MMSYSERR_BADDEVICEID:	/* Specified device identifier is out of range. */
-                    /* falls through */
-                case WAVERR_BADFORMAT:      /* Attempted to open with an unsupported waveform-audio format. */
-                    /* falls through */
-                default:
-                    result = paUnanticipatedHostError;
-                    if( isInput )
-                    {
-                        PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
-                    }
-                    else
-                    {
-                        PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
-                    }
-            }
-            goto error;
-        }
-    }
-
-    return result;
-
-error:
-    TerminateWaveHandles( handlesAndBuffers, isInput, 1 /* currentlyProcessingAnError */ );
-
-    return result;
-}
-
-
-static PaError TerminateWaveHandles( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput, int currentlyProcessingAnError )
-{
-    PaError result = paNoError;
-    MMRESULT mmresult;
-    signed int i;
-    
-    if( handlesAndBuffers->waveHandles )
-    {
-        for( i = handlesAndBuffers->deviceCount-1; i >= 0; --i )
-        {
-            if( isInput )
-            {
-                if( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] )
-                    mmresult = waveInClose( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] );
-                else
-                    mmresult = MMSYSERR_NOERROR;
-            }
-            else
-            {
-                if( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] )
-                    mmresult = waveOutClose( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] );
-                else
-                    mmresult = MMSYSERR_NOERROR;
-            }
-
-            if( mmresult != MMSYSERR_NOERROR &&
-                !currentlyProcessingAnError ) /* don't update the error state if we're already processing an error */
-            {
-                result = paUnanticipatedHostError;
-                if( isInput )
-                {
-                    PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
-                }
-                else
-                {
-                    PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
-                }
-                /* note that we don't break here, we try to continue closing devices */
-            }
-        }
-
-        PaUtil_FreeMemory( handlesAndBuffers->waveHandles );
-        handlesAndBuffers->waveHandles = 0;
-    }
-
-    if( handlesAndBuffers->bufferEvent )
-    {
-        result = CloseHandleWithPaError( handlesAndBuffers->bufferEvent );
-        handlesAndBuffers->bufferEvent = 0;
-    }
-    
-    return result;
-}
-
-
-static PaError InitializeWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers,
-        unsigned long hostBufferCount,
-        PaSampleFormat hostSampleFormat,
-        unsigned long framesPerHostBuffer,
-        PaWinMmeDeviceAndChannelCount *devices,
-        int isInput )
-{
-    PaError result = paNoError;
-    MMRESULT mmresult;
-    WAVEHDR *deviceWaveHeaders;
-    signed int i, j;
-
-    /* for error cleanup we expect that InitializeSingleDirectionHandlesAndBuffers()
-        has already been called to zero some fields */
-        
-
-    /* allocate an array of pointers to arrays of wave headers, one array of
-        wave headers per device */
-    handlesAndBuffers->waveHeaders = (WAVEHDR**)PaUtil_AllocateMemory( sizeof(WAVEHDR*) * handlesAndBuffers->deviceCount );
-    if( !handlesAndBuffers->waveHeaders )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-    
-    for( i = 0; i < (signed int)handlesAndBuffers->deviceCount; ++i )
-        handlesAndBuffers->waveHeaders[i] = 0;
-
-    handlesAndBuffers->bufferCount = hostBufferCount;
-
-    for( i = 0; i < (signed int)handlesAndBuffers->deviceCount; ++i )
-    {
-        int bufferBytes = Pa_GetSampleSize( hostSampleFormat ) *
-                framesPerHostBuffer * devices[i].channelCount;
-        if( bufferBytes < 0 )
-        {
-            result = paInternalError;
-            goto error;
-        }
-
-        /* Allocate an array of wave headers for device i */
-        deviceWaveHeaders = (WAVEHDR *) PaUtil_AllocateMemory( sizeof(WAVEHDR)*hostBufferCount );
-        if( !deviceWaveHeaders )
-        {
-            result = paInsufficientMemory;
-            goto error;
-        }
-
-        for( j=0; j < (signed int)hostBufferCount; ++j )
-            deviceWaveHeaders[j].lpData = 0;
-
-        handlesAndBuffers->waveHeaders[i] = deviceWaveHeaders;
-
-        /* Allocate a buffer for each wave header */
-        for( j=0; j < (signed int)hostBufferCount; ++j )
-        {
-            deviceWaveHeaders[j].lpData = (char *)PaUtil_AllocateMemory( bufferBytes );
-            if( !deviceWaveHeaders[j].lpData )
-            {
-                result = paInsufficientMemory;
-                goto error;
-            }
-            deviceWaveHeaders[j].dwBufferLength = bufferBytes;
-            deviceWaveHeaders[j].dwUser = 0xFFFFFFFF; /* indicates that *PrepareHeader() has not yet been called, for error clean up code */
-
-            if( isInput )
-            {
-                mmresult = waveInPrepareHeader( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) );
-                if( mmresult != MMSYSERR_NOERROR )
-                {
-                    result = paUnanticipatedHostError;
-                    PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
-                    goto error;
-                }
-            }
-            else /* output */
-            {
-                mmresult = waveOutPrepareHeader( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) );
-                if( mmresult != MMSYSERR_NOERROR )
-                {
-                    result = paUnanticipatedHostError;
-                    PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
-                    goto error;
-                }
-            }
-            deviceWaveHeaders[j].dwUser = devices[i].channelCount;
-        }
-    }
-
-    return result;
-
-error:
-    TerminateWaveHeaders( handlesAndBuffers, isInput );
-    
-    return result;
-}
-
-
-static void TerminateWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput )
-{
-    signed int i, j;
-    WAVEHDR *deviceWaveHeaders;
-    
-    if( handlesAndBuffers->waveHeaders )
-    {
-        for( i = handlesAndBuffers->deviceCount-1; i >= 0 ; --i )
-        {
-            deviceWaveHeaders = handlesAndBuffers->waveHeaders[i];  /* wave headers for device i */
-            if( deviceWaveHeaders )
-            {
-                for( j = handlesAndBuffers->bufferCount-1; j >= 0; --j )
-                {
-                    if( deviceWaveHeaders[j].lpData )
-                    {
-                        if( deviceWaveHeaders[j].dwUser != 0xFFFFFFFF )
-                        {
-                            if( isInput )
-                                waveInUnprepareHeader( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) );
-                            else
-                                waveOutUnprepareHeader( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) );
-                        }
-
-                        PaUtil_FreeMemory( deviceWaveHeaders[j].lpData );
-                    }
-                }
-
-                PaUtil_FreeMemory( deviceWaveHeaders );
-            }
-        }
-
-        PaUtil_FreeMemory( handlesAndBuffers->waveHeaders );
-        handlesAndBuffers->waveHeaders = 0;
-    }
-}
-
-
-
-/* PaWinMmeStream - a stream data structure specifically for this implementation */
-/* note that struct PaWinMmeStream is typedeffed to PaWinMmeStream above. */
-struct PaWinMmeStream
-{
-    PaUtilStreamRepresentation streamRepresentation;
-    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
-    PaUtilBufferProcessor bufferProcessor;
-
-    int primeStreamUsingCallback;
-
-    PaWinMmeSingleDirectionHandlesAndBuffers input;
-    PaWinMmeSingleDirectionHandlesAndBuffers output;
-
-    /* Processing thread management -------------- */
-    HANDLE abortEvent;
-    HANDLE processingThread;
-    DWORD processingThreadId;
-
-    char throttleProcessingThreadOnOverload; /* 0 -> don't throtte, non-0 -> throttle */
-    int processingThreadPriority;
-    int highThreadPriority;
-    int throttledThreadPriority;
-    unsigned long throttledSleepMsecs;
-
-    int isStopped;
-    volatile int isActive;
-    volatile int stopProcessing; /* stop thread once existing buffers have been returned */
-    volatile int abortProcessing; /* stop thread immediately */
-
-    DWORD allBuffersDurationMs; /* used to calculate timeouts */
-};
-
-/* updates deviceCount if PaWinMmeUseMultipleDevices is used */
-
-static PaError ValidateWinMmeSpecificStreamInfo(
-        const PaStreamParameters *streamParameters,
-        const PaWinMmeStreamInfo *streamInfo,
-        char *throttleProcessingThreadOnOverload,
-        unsigned long *deviceCount )
-{
-	if( streamInfo )
-	{
-	    if( streamInfo->size != sizeof( PaWinMmeStreamInfo )
-	            || streamInfo->version != 1 )
-	    {
-	        return paIncompatibleHostApiSpecificStreamInfo;
-	    }
-
-	    if( streamInfo->flags & paWinMmeDontThrottleOverloadedProcessingThread )
-	        *throttleProcessingThreadOnOverload = 0;
-            
-	    if( streamInfo->flags & paWinMmeUseMultipleDevices )
-	    {
-	        if( streamParameters->device != paUseHostApiSpecificDeviceSpecification )
-	            return paInvalidDevice;
-	
-			*deviceCount = streamInfo->deviceCount;
-		}	
-	}
-
-	return paNoError;
-}
-
-static PaError RetrieveDevicesFromStreamParameters(
-        struct PaUtilHostApiRepresentation *hostApi,
-        const PaStreamParameters *streamParameters,
-        const PaWinMmeStreamInfo *streamInfo,
-        PaWinMmeDeviceAndChannelCount *devices,
-        unsigned long deviceCount )
-{
-    PaError result = paNoError;
-    unsigned int i;
-    int totalChannelCount;
-    PaDeviceIndex hostApiDevice;
-    
-	if( streamInfo && streamInfo->flags & paWinMmeUseMultipleDevices )
-	{
-		totalChannelCount = 0;
-	    for( i=0; i < deviceCount; ++i )
-	    {
-	        /* validate that the device number is within range */
-	        result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice,
-	                        streamInfo->devices[i].device, hostApi );
-	        if( result != paNoError )
-	            return result;
-	        
-	        devices[i].device = hostApiDevice;
-	        devices[i].channelCount = streamInfo->devices[i].channelCount;
-	
-	        totalChannelCount += devices[i].channelCount;
-	    }
-	
-	    if( totalChannelCount != streamParameters->channelCount )
-	    {
-	        /* channelCount must match total channels specified by multiple devices */
-	        return paInvalidChannelCount; /* REVIEW use of this error code */
-	    }
-	}	
-	else
-	{		
-	    devices[0].device = streamParameters->device;
-	    devices[0].channelCount = streamParameters->channelCount;
-	}
-
-    return result;
-}
-
-static PaError ValidateInputChannelCounts(
-        struct PaUtilHostApiRepresentation *hostApi,
-        PaWinMmeDeviceAndChannelCount *devices,
-        unsigned long deviceCount )
-{
-    unsigned int i;
-
-	for( i=0; i < deviceCount; ++i )
-	{
-		if( devices[i].channelCount < 1 || devices[i].channelCount
-					> hostApi->deviceInfos[ devices[i].device ]->maxInputChannels )
-        	return paInvalidChannelCount;
-	}
-
-    return paNoError;
-}
-
-static PaError ValidateOutputChannelCounts(
-        struct PaUtilHostApiRepresentation *hostApi,
-        PaWinMmeDeviceAndChannelCount *devices,
-        unsigned long deviceCount )
-{
-    unsigned int i;
-
-	for( i=0; i < deviceCount; ++i )
-	{
-		if( devices[i].channelCount < 1 || devices[i].channelCount
-					> hostApi->deviceInfos[ devices[i].device ]->maxOutputChannels )
-        	return paInvalidChannelCount;
-	}
-
-    return paNoError;
-}
-
-
-/* the following macros are intended to improve the readability of the following code */
-#define PA_IS_INPUT_STREAM_( stream ) ( stream ->input.waveHandles )
-#define PA_IS_OUTPUT_STREAM_( stream ) ( stream ->output.waveHandles )
-#define PA_IS_FULL_DUPLEX_STREAM_( stream ) ( stream ->input.waveHandles && stream ->output.waveHandles )
-#define PA_IS_HALF_DUPLEX_STREAM_( stream ) ( !(stream ->input.waveHandles && stream ->output.waveHandles) )
-
-static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
-                           PaStream** s,
-                           const PaStreamParameters *inputParameters,
-                           const PaStreamParameters *outputParameters,
-                           double sampleRate,
-                           unsigned long framesPerBuffer,
-                           PaStreamFlags streamFlags,
-                           PaStreamCallback *streamCallback,
-                           void *userData )
-{
-    PaError result;
-    PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
-    PaWinMmeStream *stream = 0;
-    int bufferProcessorIsInitialized = 0;
-    int streamRepresentationIsInitialized = 0;
-    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
-    int inputChannelCount, outputChannelCount;
-    PaSampleFormat inputSampleFormat, outputSampleFormat;
-    double suggestedInputLatency, suggestedOutputLatency;
-    PaWinMmeStreamInfo *inputStreamInfo, *outputStreamInfo;
-    unsigned long framesPerHostInputBuffer;
-    unsigned long hostInputBufferCount;
-    unsigned long framesPerHostOutputBuffer;
-    unsigned long hostOutputBufferCount;
-    unsigned long framesPerBufferProcessorCall;
-    PaWinMmeDeviceAndChannelCount *inputDevices = 0;  /* contains all devices and channel counts as local host api ids, even when PaWinMmeUseMultipleDevices is not used */
-    unsigned long inputDeviceCount = 0;            
-    PaWinMmeDeviceAndChannelCount *outputDevices = 0;
-    unsigned long outputDeviceCount = 0;                /* contains all devices and channel counts as local host api ids, even when PaWinMmeUseMultipleDevices is not used */
-    char throttleProcessingThreadOnOverload = 1;
-
-    
-    if( inputParameters )
-    {
-		inputChannelCount = inputParameters->channelCount;
-        inputSampleFormat = inputParameters->sampleFormat;
-        suggestedInputLatency = inputParameters->suggestedLatency;
-
-      	inputDeviceCount = 1;
-
-		/* validate input hostApiSpecificStreamInfo */
-        inputStreamInfo = (PaWinMmeStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
-		result = ValidateWinMmeSpecificStreamInfo( inputParameters, inputStreamInfo,
-				&throttleProcessingThreadOnOverload,
-				&inputDeviceCount );
-		if( result != paNoError ) return result;
-
-		inputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * inputDeviceCount );
-        if( !inputDevices ) return paInsufficientMemory;
-
-		result = RetrieveDevicesFromStreamParameters( hostApi, inputParameters, inputStreamInfo, inputDevices, inputDeviceCount );
-		if( result != paNoError ) return result;
-
-		result = ValidateInputChannelCounts( hostApi, inputDevices, inputDeviceCount );
-		if( result != paNoError ) return result;
-
-        hostInputSampleFormat =
-            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat );
-	}
-    else
-    {
-        inputChannelCount = 0;
-        inputSampleFormat = 0;
-        suggestedInputLatency = 0.;
-        inputStreamInfo = 0;
-        hostInputSampleFormat = 0;
-    }
-
-
-    if( outputParameters )
-    {
-        outputChannelCount = outputParameters->channelCount;
-        outputSampleFormat = outputParameters->sampleFormat;
-        suggestedOutputLatency = outputParameters->suggestedLatency;
-
-        outputDeviceCount = 1;
-
-		/* validate output hostApiSpecificStreamInfo */
-        outputStreamInfo = (PaWinMmeStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
-		result = ValidateWinMmeSpecificStreamInfo( outputParameters, outputStreamInfo,
-				&throttleProcessingThreadOnOverload,
-				&outputDeviceCount );
-		if( result != paNoError ) return result;
-
-		outputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * outputDeviceCount );
-        if( !outputDevices ) return paInsufficientMemory;
-
-		result = RetrieveDevicesFromStreamParameters( hostApi, outputParameters, outputStreamInfo, outputDevices, outputDeviceCount );
-		if( result != paNoError ) return result;
-
-		result = ValidateOutputChannelCounts( hostApi, outputDevices, outputDeviceCount );
-		if( result != paNoError ) return result;
-
-        hostOutputSampleFormat =
-            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat );
-    }
-    else
-    {
-        outputChannelCount = 0;
-        outputSampleFormat = 0;
-        outputStreamInfo = 0;
-        hostOutputSampleFormat = 0;
-        suggestedOutputLatency = 0.;
-    }
-
-
-    /*
-        IMPLEMENT ME:
-            - alter sampleRate to a close allowable rate if possible / necessary
-    */
-
-
-    /* validate platform specific flags */
-    if( (streamFlags & paPlatformSpecificFlags) != 0 )
-        return paInvalidFlag; /* unexpected platform specific flag */
-
-
-    result = CalculateBufferSettings( &framesPerHostInputBuffer, &hostInputBufferCount,
-                &framesPerHostOutputBuffer, &hostOutputBufferCount,
-                inputChannelCount, hostInputSampleFormat, suggestedInputLatency, inputStreamInfo,
-                outputChannelCount, hostOutputSampleFormat, suggestedOutputLatency, outputStreamInfo,
-                sampleRate, framesPerBuffer );
-    if( result != paNoError ) goto error;
-
-
-    stream = (PaWinMmeStream*)PaUtil_AllocateMemory( sizeof(PaWinMmeStream) );
-    if( !stream )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-
-    InitializeSingleDirectionHandlesAndBuffers( &stream->input );
-    InitializeSingleDirectionHandlesAndBuffers( &stream->output );
-
-    stream->abortEvent = 0;
-    stream->processingThread = 0;
-
-    stream->throttleProcessingThreadOnOverload = throttleProcessingThreadOnOverload;
-
-    PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
-                                           ( (streamCallback)
-                                            ? &winMmeHostApi->callbackStreamInterface
-                                            : &winMmeHostApi->blockingStreamInterface ),
-                                           streamCallback, userData );
-    streamRepresentationIsInitialized = 1;
-
-    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
-
-
-    if( inputParameters && outputParameters ) /* full duplex */
-    {
-        if( framesPerHostInputBuffer < framesPerHostOutputBuffer )
-        {
-            assert( (framesPerHostOutputBuffer % framesPerHostInputBuffer) == 0 ); /* CalculateBufferSettings() should guarantee this condition */
-
-            framesPerBufferProcessorCall = framesPerHostInputBuffer;
-        }
-        else
-        {
-            assert( (framesPerHostInputBuffer % framesPerHostOutputBuffer) == 0 ); /* CalculateBufferSettings() should guarantee this condition */
-            
-            framesPerBufferProcessorCall = framesPerHostOutputBuffer;
-        }
-    }
-    else if( inputParameters )
-    {
-        framesPerBufferProcessorCall = framesPerHostInputBuffer;
-    }
-    else if( outputParameters )
-    {
-        framesPerBufferProcessorCall = framesPerHostOutputBuffer;
-    }
-
-    stream->input.framesPerBuffer = framesPerHostInputBuffer;
-    stream->output.framesPerBuffer = framesPerHostOutputBuffer;
-
-    result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
-                    inputChannelCount, inputSampleFormat, hostInputSampleFormat,
-                    outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
-                    sampleRate, streamFlags, framesPerBuffer,
-                    framesPerBufferProcessorCall, paUtilFixedHostBufferSize,
-                    streamCallback, userData );
-    if( result != paNoError ) goto error;
-    
-    bufferProcessorIsInitialized = 1;
-
-    stream->streamRepresentation.streamInfo.inputLatency =
-            (double)(PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)
-                +(framesPerHostInputBuffer * (hostInputBufferCount-1))) / sampleRate;
-    stream->streamRepresentation.streamInfo.outputLatency =
-            (double)(PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)
-                +(framesPerHostOutputBuffer * (hostOutputBufferCount-1))) / sampleRate;
-    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
-
-    stream->primeStreamUsingCallback = ( (streamFlags&paPrimeOutputBuffersUsingStreamCallback) && streamCallback ) ? 1 : 0;
-
-    /* time to sleep when throttling due to >100% cpu usage.
-        -a quater of a buffer's duration */
-    stream->throttledSleepMsecs =
-            (unsigned long)(stream->bufferProcessor.framesPerHostBuffer *
-             stream->bufferProcessor.samplePeriod * .25 * 1000);
-
-    stream->isStopped = 1;
-    stream->isActive = 0;
-
-
-    /* for maximum compatibility with multi-device multichannel drivers,
-        we first open all devices, then we prepare all buffers, finally
-        we start all devices ( in StartStream() ). teardown in reverse order.
-    */
-
-    if( inputParameters )
-    {
-        result = InitializeWaveHandles( winMmeHostApi, &stream->input,
-                stream->bufferProcessor.bytesPerHostInputSample, sampleRate,
-                inputDevices, inputDeviceCount, 1 /* isInput */ );
-        if( result != paNoError ) goto error;
-    }
-    
-    if( outputParameters )
-    {
-        result = InitializeWaveHandles( winMmeHostApi, &stream->output,
-                stream->bufferProcessor.bytesPerHostOutputSample, sampleRate,
-                outputDevices, outputDeviceCount, 0 /* isInput */ );
-        if( result != paNoError ) goto error;
-    }
-
-    if( inputParameters )
-    {
-        result = InitializeWaveHeaders( &stream->input, hostInputBufferCount,
-                hostInputSampleFormat, framesPerHostInputBuffer, inputDevices, 1 /* isInput */ );
-        if( result != paNoError ) goto error;
-    }
-
-    if( outputParameters )
-    {
-        result = InitializeWaveHeaders( &stream->output, hostOutputBufferCount,
-                hostOutputSampleFormat, framesPerHostOutputBuffer, outputDevices, 0 /* not isInput */ );
-        if( result != paNoError ) goto error;
-
-        stream->allBuffersDurationMs = (DWORD) (1000.0 * (framesPerHostOutputBuffer * stream->output.bufferCount) / sampleRate);
-    }
-    else
-    {
-        stream->allBuffersDurationMs = (DWORD) (1000.0 * (framesPerHostInputBuffer * stream->input.bufferCount) / sampleRate);
-    }
-
-    
-    if( streamCallback )
-    {
-        /* abort event is only needed for callback streams */
-        result = CreateEventWithPaError( &stream->abortEvent, NULL, TRUE, FALSE, NULL );
-        if( result != paNoError ) goto error;
-    }
-
-    *s = (PaStream*)stream;
-
-    return result;
-
-error:
-
-    if( stream )
-    {
-        if( stream->abortEvent )
-            CloseHandle( stream->abortEvent );
-            
-        TerminateWaveHeaders( &stream->output, 0 /* not isInput */ );
-        TerminateWaveHeaders( &stream->input, 1 /* isInput */ );
-
-        TerminateWaveHandles( &stream->output, 0 /* not isInput */, 1 /* currentlyProcessingAnError */ );
-        TerminateWaveHandles( &stream->input, 1 /* isInput */, 1 /* currentlyProcessingAnError */ );
-
-        if( bufferProcessorIsInitialized )
-            PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
-
-        if( streamRepresentationIsInitialized )
-            PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
-
-        PaUtil_FreeMemory( stream );
-    }
-
-    return result;
-}
-
-
-/* return non-zero if all current buffers are done */
-static int BuffersAreDone( WAVEHDR **waveHeaders, unsigned int deviceCount, int bufferIndex )
-{
-    unsigned int i;
-    
-    for( i=0; i < deviceCount; ++i )
-    {
-        if( !(waveHeaders[i][ bufferIndex ].dwFlags & WHDR_DONE) )
-        {
-            return 0;
-        }         
-    }
-
-    return 1;
-}
-
-static int CurrentInputBuffersAreDone( PaWinMmeStream *stream )
-{
-    return BuffersAreDone( stream->input.waveHeaders, stream->input.deviceCount, stream->input.currentBufferIndex );
-}
-
-static int CurrentOutputBuffersAreDone( PaWinMmeStream *stream )
-{
-    return BuffersAreDone( stream->output.waveHeaders, stream->output.deviceCount, stream->output.currentBufferIndex );
-}
-
-
-/* return non-zero if any buffers are queued */
-static int NoBuffersAreQueued( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers )
-{
-    unsigned int i, j;
-
-    if( handlesAndBuffers->waveHandles )
-    {
-        for( i=0; i < handlesAndBuffers->bufferCount; ++i )
-        {
-            for( j=0; j < handlesAndBuffers->deviceCount; ++j )
-            {
-                if( !( handlesAndBuffers->waveHeaders[ j ][ i ].dwFlags & WHDR_DONE) )
-                {
-                    return 0;
-                }
-            }
-        }
-    }
-
-    return 1;
-}
-
-
-#define PA_CIRCULAR_INCREMENT_( current, max )\
-    ( (((current) + 1) >= (max)) ? (0) : (current+1) )
-
-#define PA_CIRCULAR_DECREMENT_( current, max )\
-    ( ((current) == 0) ? ((max)-1) : (current-1) )
-    
-
-static signed long GetAvailableFrames( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers )
-{
-    signed long result = 0;
-    unsigned int i;
-    
-    if( BuffersAreDone( handlesAndBuffers->waveHeaders, handlesAndBuffers->deviceCount, handlesAndBuffers->currentBufferIndex ) )
-    {
-        /* we could calculate the following in O(1) if we kept track of the
-            last done buffer */
-        result = handlesAndBuffers->framesPerBuffer - handlesAndBuffers->framesUsedInCurrentBuffer;
-
-        i = PA_CIRCULAR_INCREMENT_( handlesAndBuffers->currentBufferIndex, handlesAndBuffers->bufferCount );
-        while( i != handlesAndBuffers->currentBufferIndex )
-        {
-            if( BuffersAreDone( handlesAndBuffers->waveHeaders, handlesAndBuffers->deviceCount, i ) )
-            {
-                result += handlesAndBuffers->framesPerBuffer;
-                i = PA_CIRCULAR_INCREMENT_( i, handlesAndBuffers->bufferCount );
-            }
-            else
-                break;
-        }
-    }
-
-    return result;
-}
-
-
-static PaError AdvanceToNextInputBuffer( PaWinMmeStream *stream )
-{
-    PaError result = paNoError;
-    MMRESULT mmresult;
-    unsigned int i;
-
-    for( i=0; i < stream->input.deviceCount; ++i )
-    {
-        mmresult = waveInAddBuffer( ((HWAVEIN*)stream->input.waveHandles)[i],
-                                    &stream->input.waveHeaders[i][ stream->input.currentBufferIndex ],
-                                    sizeof(WAVEHDR) );
-        if( mmresult != MMSYSERR_NOERROR )
-        {
-            result = paUnanticipatedHostError;
-            PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
-        }
-    }
-
-    stream->input.currentBufferIndex =
-            PA_CIRCULAR_INCREMENT_( stream->input.currentBufferIndex, stream->input.bufferCount );
-
-    stream->input.framesUsedInCurrentBuffer = 0;
-
-    return result;
-}
-
-
-static PaError AdvanceToNextOutputBuffer( PaWinMmeStream *stream )
-{
-    PaError result = paNoError;
-    MMRESULT mmresult;
-    unsigned int i;
-
-    for( i=0; i < stream->output.deviceCount; ++i )
-    {
-        mmresult = waveOutWrite( ((HWAVEOUT*)stream->output.waveHandles)[i],
-                                 &stream->output.waveHeaders[i][ stream->output.currentBufferIndex ],
-                                 sizeof(WAVEHDR) );
-        if( mmresult != MMSYSERR_NOERROR )
-        {
-            result = paUnanticipatedHostError;
-            PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
-        }
-    }
-
-    stream->output.currentBufferIndex =
-            PA_CIRCULAR_INCREMENT_( stream->output.currentBufferIndex, stream->output.bufferCount );
-
-    stream->output.framesUsedInCurrentBuffer = 0;
-    
-    return result;
-}
-
-
-/* requeue all but the most recent input with the driver. Used for catching
-    up after a total input buffer underrun */
-static PaError CatchUpInputBuffers( PaWinMmeStream *stream )
-{
-    PaError result = paNoError;
-    unsigned int i;
-    
-    for( i=0; i < stream->input.bufferCount - 1; ++i )
-    {
-        result = AdvanceToNextInputBuffer( stream );
-        if( result != paNoError )
-            break;
-    }
-
-    return result;
-}
-
-
-/* take the most recent output and duplicate it to all other output buffers
-    and requeue them. Used for catching up after a total output buffer underrun.
-*/
-static PaError CatchUpOutputBuffers( PaWinMmeStream *stream )
-{
-    PaError result = paNoError;
-    unsigned int i, j;
-    unsigned int previousBufferIndex =
-            PA_CIRCULAR_DECREMENT_( stream->output.currentBufferIndex, stream->output.bufferCount );
-
-    for( i=0; i < stream->output.bufferCount - 1; ++i )
-    {
-        for( j=0; j < stream->output.deviceCount; ++j )
-        {
-            if( stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].lpData
-                    != stream->output.waveHeaders[j][ previousBufferIndex ].lpData )
-            {
-                CopyMemory( stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].lpData,
-                            stream->output.waveHeaders[j][ previousBufferIndex ].lpData,
-                            stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].dwBufferLength );
-            }
-        }
-
-        result = AdvanceToNextOutputBuffer( stream );
-        if( result != paNoError )
-            break;
-    }
-
-    return result;
-}
-
-
-static DWORD WINAPI ProcessingThreadProc( void *pArg )
-{
-    PaWinMmeStream *stream = (PaWinMmeStream *)pArg;
-    HANDLE events[3];
-    int eventCount = 0;
-    DWORD result = paNoError;
-    DWORD waitResult;
-    DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5);
-    int hostBuffersAvailable;
-    signed int hostInputBufferIndex, hostOutputBufferIndex;
-    PaStreamCallbackFlags statusFlags;
-    int callbackResult;
-    int done = 0;
-    unsigned int channel, i;
-    unsigned long framesProcessed;
-    
-    /* prepare event array for call to WaitForMultipleObjects() */
-    if( stream->input.bufferEvent )
-        events[eventCount++] = stream->input.bufferEvent;
-    if( stream->output.bufferEvent )
-        events[eventCount++] = stream->output.bufferEvent;
-    events[eventCount++] = stream->abortEvent;
-
-    statusFlags = 0; /** @todo support paInputUnderflow, paOutputOverflow and paNeverDropInput */
-    
-    /* loop until something causes us to stop */
-    do{
-        /* wait for MME to signal that a buffer is available, or for
-            the PA abort event to be signaled.
-
-          When this indicates that one or more buffers are available
-          NoBuffersAreQueued() and Current*BuffersAreDone are used below to
-          poll for additional done buffers. NoBuffersAreQueued() will fail
-          to identify an underrun/overflow if the driver doesn't mark all done
-          buffers prior to signalling the event. Some drivers do this
-          (eg RME Digi96, and others don't eg VIA PC 97 input). This isn't a
-          huge problem, it just means that we won't always be able to detect
-          underflow/overflow.
-        */
-        waitResult = WaitForMultipleObjects( eventCount, events, FALSE /* wait all = FALSE */, timeout );
-        if( waitResult == WAIT_FAILED )
-        {
-            result = paUnanticipatedHostError;
-            /** @todo FIXME/REVIEW: can't return host error info from an asyncronous thread */
-            done = 1;
-        }
-        else if( waitResult == WAIT_TIMEOUT )
-        {
-            /* if a timeout is encountered, continue */
-        }
-
-        if( stream->abortProcessing )
-        {
-            /* Pa_AbortStream() has been called, stop processing immediately */
-            done = 1;
-        }
-        else if( stream->stopProcessing )
-        {
-            /* Pa_StopStream() has been called or the user callback returned
-                non-zero, processing will continue until all output buffers
-                are marked as done. The stream will stop immediately if it
-                is input-only.
-            */
-
-            if( PA_IS_OUTPUT_STREAM_(stream) )
-            {
-                if( NoBuffersAreQueued( &stream->output ) )
-                    done = 1; /* Will cause thread to return. */
-            }
-            else
-            {
-                /* input only stream */
-                done = 1; /* Will cause thread to return. */
-            }
-        }
-        else
-        {
-            hostBuffersAvailable = 1;
-
-            /* process all available host buffers */
-            do
-            {
-                hostInputBufferIndex = -1;
-                hostOutputBufferIndex = -1;
-                
-                if( PA_IS_INPUT_STREAM_(stream) )
-                {
-                    if( CurrentInputBuffersAreDone( stream ) )
-                    {
-                        if( NoBuffersAreQueued( &stream->input ) )
-                        {
-                            /** @todo
-                               if all of the other buffers are also ready then
-                               we discard all but the most recent. This is an
-                               input buffer overflow. FIXME: these buffers should
-                               be passed to the callback in a paNeverDropInput
-                               stream.
-
-                               note that it is also possible for an input overflow
-                               to happen while the callback is processing a buffer.
-                               that is handled further down.
-                            */
-                            result = CatchUpInputBuffers( stream );
-                            if( result != paNoError )
-                                done = 1;
-
-                            statusFlags |= paInputOverflow;
-                        }
-
-                        hostInputBufferIndex = stream->input.currentBufferIndex;
-                    }
-                }
-
-                if( PA_IS_OUTPUT_STREAM_(stream) )
-                {
-                    if( CurrentOutputBuffersAreDone( stream ) )
-                    {
-                        /* ok, we have an output buffer */
-                        
-                        if( NoBuffersAreQueued( &stream->output ) )
-                        {
-                            /*
-                            if all of the other buffers are also ready, catch up by copying
-                            the most recently generated buffer into all but one of the output
-                            buffers.
-
-                            note that this catch up code only handles the case where all
-                            buffers have been played out due to this thread not having
-                            woken up at all. a more common case occurs when this thread
-                            is woken up, processes one buffer, but takes too long, and as
-                            a result all the other buffers have become un-queued. that
-                            case is handled further down.
-                            */
-
-                            result = CatchUpOutputBuffers( stream );
-                            if( result != paNoError )
-                                done = 1;
-
-                            statusFlags |= paOutputUnderflow;
-                        }
-
-                        hostOutputBufferIndex = stream->output.currentBufferIndex;
-                    }
-                }
-
-               
-                if( (PA_IS_FULL_DUPLEX_STREAM_(stream) && hostInputBufferIndex != -1 && hostOutputBufferIndex != -1) ||
-                        (PA_IS_HALF_DUPLEX_STREAM_(stream) && ( hostInputBufferIndex != -1 || hostOutputBufferIndex != -1 ) ) )
-                {
-                    PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement inputBufferAdcTime */
-
-
-                    if( PA_IS_OUTPUT_STREAM_(stream) )
-                    {
-                        /* set timeInfo.currentTime and calculate timeInfo.outputBufferDacTime
-                            from the current wave out position */
-                        MMTIME mmtime;
-                        double timeBeforeGetPosition, timeAfterGetPosition;
-                        double time;
-                        long framesInBufferRing; 		
-                        long writePosition;
-                        long playbackPosition;
-                        HWAVEOUT firstWaveOutDevice = ((HWAVEOUT*)stream->output.waveHandles)[0];
-                        
-                        mmtime.wType = TIME_SAMPLES;
-                        timeBeforeGetPosition = PaUtil_GetTime();
-                        waveOutGetPosition( firstWaveOutDevice, &mmtime, sizeof(MMTIME) );
-                        timeAfterGetPosition = PaUtil_GetTime();
-
-                        timeInfo.currentTime = timeAfterGetPosition;
-
-                        /* approximate time at which wave out position was measured
-                            as half way between timeBeforeGetPosition and timeAfterGetPosition */
-                        time = timeBeforeGetPosition + (timeAfterGetPosition - timeBeforeGetPosition) * .5;
-                        
-                        framesInBufferRing = stream->output.bufferCount * stream->bufferProcessor.framesPerHostBuffer;
-                        playbackPosition = mmtime.u.sample % framesInBufferRing;
-
-                        writePosition = stream->output.currentBufferIndex * stream->bufferProcessor.framesPerHostBuffer
-                                + stream->output.framesUsedInCurrentBuffer;
-                       
-                        if( playbackPosition >= writePosition ){
-                            timeInfo.outputBufferDacTime =
-                                    time + ((double)( writePosition + (framesInBufferRing - playbackPosition) ) * stream->bufferProcessor.samplePeriod );
-                        }else{
-                            timeInfo.outputBufferDacTime =
-                                    time + ((double)( writePosition - playbackPosition ) * stream->bufferProcessor.samplePeriod );
-                        }
-                    }
-
-
-                    PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
-
-                    PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, statusFlags  );
-
-                    /* reset status flags once they have been passed to the buffer processor */
-                    statusFlags = 0;
-
-                    if( PA_IS_INPUT_STREAM_(stream) )
-                    {
-                        PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
-
-                        channel = 0;
-                        for( i=0; i<stream->input.deviceCount; ++i )
-                        {
-                             /* we have stored the number of channels in the buffer in dwUser */
-                            int channelCount = stream->input.waveHeaders[i][ hostInputBufferIndex ].dwUser;
-                            
-                            PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, channel,
-                                    stream->input.waveHeaders[i][ hostInputBufferIndex ].lpData +
-                                        stream->input.framesUsedInCurrentBuffer * channelCount *
-                                        stream->bufferProcessor.bytesPerHostInputSample,
-                                    channelCount );
-                                    
-
-                            channel += channelCount;
-                        }
-                    }
-
-                    if( PA_IS_OUTPUT_STREAM_(stream) )
-                    {
-                        PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
-                        
-                        channel = 0;
-                        for( i=0; i<stream->output.deviceCount; ++i )
-                        {
-                            /* we have stored the number of channels in the buffer in dwUser */
-                            int channelCount = stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser;
-
-                            PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel,
-                                    stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData +
-                                        stream->output.framesUsedInCurrentBuffer * channelCount *
-                                        stream->bufferProcessor.bytesPerHostOutputSample,
-                                    channelCount );
-
-                            channel += channelCount;
-                        }
-                    }
-
-                    callbackResult = paContinue;
-                    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );
-
-                    stream->input.framesUsedInCurrentBuffer += framesProcessed;
-                    stream->output.framesUsedInCurrentBuffer += framesProcessed;
-
-                    PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
-
-                    if( callbackResult == paContinue )
-                    {
-                        /* nothing special to do */
-                    }
-                    else if( callbackResult == paAbort )
-                    {
-                        stream->abortProcessing = 1;
-                        done = 1;
-                        /** @todo FIXME: should probably reset the output device immediately once the callback returns paAbort */
-                        result = paNoError;
-                    }
-                    else
-                    {
-                        /* User callback has asked us to stop with paComplete or other non-zero value */
-                        stream->stopProcessing = 1; /* stop once currently queued audio has finished */
-                        result = paNoError;
-                    }
-
-
-                    if( PA_IS_INPUT_STREAM_(stream)
-                            && stream->stopProcessing == 0 && stream->abortProcessing == 0
-                            && stream->input.framesUsedInCurrentBuffer == stream->input.framesPerBuffer )
-                    {
-                        if( NoBuffersAreQueued( &stream->input ) )
-                        {
-                            /** @todo need to handle PaNeverDropInput here where necessary */
-                            result = CatchUpInputBuffers( stream );
-                            if( result != paNoError )
-                                done = 1;
-
-                            statusFlags |= paInputOverflow;
-                        }
-
-                        result = AdvanceToNextInputBuffer( stream );
-                        if( result != paNoError )
-                            done = 1;
-                    }
-
-                    
-                    if( PA_IS_OUTPUT_STREAM_(stream) && !stream->abortProcessing )
-                    {
-                        if( stream->stopProcessing &&
-                                stream->output.framesUsedInCurrentBuffer < stream->output.framesPerBuffer )
-                        {
-                            /* zero remaining samples in output output buffer and flush */
-
-                            stream->output.framesUsedInCurrentBuffer += PaUtil_ZeroOutput( &stream->bufferProcessor,
-                                    stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer );
-
-                            /* we send the entire buffer to the output devices, but we could
-                                just send a partial buffer, rather than zeroing the unused
-                                samples.
-                            */
-                        }
-
-                        if( stream->output.framesUsedInCurrentBuffer == stream->output.framesPerBuffer )
-                        {
-                            /* check for underflow before enquing the just-generated buffer,
-                                but recover from underflow after enquing it. This ensures
-                                that the most recent audio segment is repeated */
-                            int outputUnderflow = NoBuffersAreQueued( &stream->output );
-
-                            result = AdvanceToNextOutputBuffer( stream );
-                            if( result != paNoError )
-                                done = 1;
-
-                            if( outputUnderflow && !done && !stream->stopProcessing )
-                            {
-                                /* Recover from underflow in the case where the
-                                    underflow occured while processing the buffer
-                                    we just finished */
-
-                                result = CatchUpOutputBuffers( stream );
-                                if( result != paNoError )
-                                    done = 1;
-
-                                statusFlags |= paOutputUnderflow;
-                            }
-                        }
-                    }
-                    
-                    if( stream->throttleProcessingThreadOnOverload != 0 )
-                    {
-                        if( stream->stopProcessing || stream->abortProcessing )
-                        {
-                            if( stream->processingThreadPriority != stream->highThreadPriority )
-                            {
-                                SetThreadPriority( stream->processingThread, stream->highThreadPriority );
-                                stream->processingThreadPriority = stream->highThreadPriority;
-                            }
-                        }
-                        else if( PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ) > 1. )
-                        {
-                            if( stream->processingThreadPriority != stream->throttledThreadPriority )
-                            {
-                                SetThreadPriority( stream->processingThread, stream->throttledThreadPriority );
-                                stream->processingThreadPriority = stream->throttledThreadPriority;
-                            }
-
-                            /* sleep to give other processes a go */
-                            Sleep( stream->throttledSleepMsecs );
-                        }
-                        else
-                        {
-                            if( stream->processingThreadPriority != stream->highThreadPriority )
-                            {
-                                SetThreadPriority( stream->processingThread, stream->highThreadPriority );
-                                stream->processingThreadPriority = stream->highThreadPriority;
-                            }
-                        }
-                    }
-                }
-                else
-                {
-                    hostBuffersAvailable = 0;
-                }
-            }
-            while( hostBuffersAvailable &&
-                    stream->stopProcessing == 0 &&
-                    stream->abortProcessing == 0 &&
-                    !done );
-        }
-    }
-    while( !done );
-
-    stream->isActive = 0;
-
-    if( stream->streamRepresentation.streamFinishedCallback != 0 )
-        stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
-
-    PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer );
-    
-    return result;
-}
-
-
-/*
-    When CloseStream() is called, the multi-api layer ensures that
-    the stream has already been stopped or aborted.
-*/
-static PaError CloseStream( PaStream* s )
-{
-    PaError result;
-    PaWinMmeStream *stream = (PaWinMmeStream*)s;
-
-    result = CloseHandleWithPaError( stream->abortEvent );
-    if( result != paNoError ) goto error;
-    
-    TerminateWaveHeaders( &stream->output, 0 /* not isInput */ );
-    TerminateWaveHeaders( &stream->input, 1 /* isInput */ );
-
-    TerminateWaveHandles( &stream->output, 0 /* not isInput */, 0 /* not currentlyProcessingAnError */ );
-    TerminateWaveHandles( &stream->input, 1 /* isInput */, 0 /* not currentlyProcessingAnError */ );
-    
-    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
-    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
-    PaUtil_FreeMemory( stream );
-
-error:
-    /** @todo REVIEW: what is the best way to clean up a stream if an error is detected? */
-    return result;
-}
-
-
-static PaError StartStream( PaStream *s )
-{
-    PaError result;
-    PaWinMmeStream *stream = (PaWinMmeStream*)s;
-    MMRESULT mmresult;
-    unsigned int i, j;
-    int callbackResult;
-	unsigned int channel;
- 	unsigned long framesProcessed;
-	PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement this for stream priming */
-    
-    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
-    
-    if( PA_IS_INPUT_STREAM_(stream) )
-    {
-        for( i=0; i<stream->input.bufferCount; ++i )
-        {
-            for( j=0; j<stream->input.deviceCount; ++j )
-            {
-                mmresult = waveInAddBuffer( ((HWAVEIN*)stream->input.waveHandles)[j], &stream->input.waveHeaders[j][i], sizeof(WAVEHDR) );
-                if( mmresult != MMSYSERR_NOERROR )
-                {
-                    result = paUnanticipatedHostError;
-                    PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
-                    goto error;
-                }
-            }
-        }
-        stream->input.currentBufferIndex = 0;
-        stream->input.framesUsedInCurrentBuffer = 0;
-    }
-
-    if( PA_IS_OUTPUT_STREAM_(stream) )
-    {
-        for( i=0; i<stream->output.deviceCount; ++i )
-        {
-            if( (mmresult = waveOutPause( ((HWAVEOUT*)stream->output.waveHandles)[i] )) != MMSYSERR_NOERROR )
-            {
-                result = paUnanticipatedHostError;
-                PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
-                goto error;
-            }
-        }
-
-        for( i=0; i<stream->output.bufferCount; ++i )
-        {
-            if( stream->primeStreamUsingCallback )
-            {
-
-                stream->output.framesUsedInCurrentBuffer = 0;
-                do{
-
-                    PaUtil_BeginBufferProcessing( &stream->bufferProcessor,
-                            &timeInfo,
-                            paPrimingOutput | ((stream->input.bufferCount > 0 ) ? paInputUnderflow : 0));
-
-                    if( stream->input.bufferCount > 0 )
-                        PaUtil_SetNoInput( &stream->bufferProcessor );
-
-                    PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
-
-                    channel = 0;
-                    for( j=0; j<stream->output.deviceCount; ++j )
-                    {
-                        /* we have stored the number of channels in the buffer in dwUser */
-                        int channelCount = stream->output.waveHeaders[j][i].dwUser;
-
-                        PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel,
-                                stream->output.waveHeaders[j][i].lpData +
-                                stream->output.framesUsedInCurrentBuffer * channelCount *
-                                stream->bufferProcessor.bytesPerHostOutputSample,
-                                channelCount );
-
-                        /* we have stored the number of channels in the buffer in dwUser */
-                        channel += channelCount;
-                    }
-
-                    callbackResult = paContinue;
-                    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );
-                    stream->output.framesUsedInCurrentBuffer += framesProcessed;
-
-                    if( callbackResult != paContinue )
-                    {
-                        /** @todo fix this, what do we do if callback result is non-zero during stream
-                            priming?
-
-                            for complete: play out primed waveHeaders as usual
-                            for abort: clean up immediately.
-                       */
-                    }
-
-                }while( stream->output.framesUsedInCurrentBuffer != stream->output.framesPerBuffer );
-
-            }
-            else
-            {
-                for( j=0; j<stream->output.deviceCount; ++j )
-                {
-                    ZeroMemory( stream->output.waveHeaders[j][i].lpData, stream->output.waveHeaders[j][i].dwBufferLength );
-                }
-            }   
-
-            /* we queue all channels of a single buffer frame (accross all
-                devices, because some multidevice multichannel drivers work
-                better this way */
-            for( j=0; j<stream->output.deviceCount; ++j )
-            {
-                mmresult = waveOutWrite( ((HWAVEOUT*)stream->output.waveHandles)[j], &stream->output.waveHeaders[j][i], sizeof(WAVEHDR) );
-                if( mmresult != MMSYSERR_NOERROR )
-                {
-                    result = paUnanticipatedHostError;
-                    PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
-                    goto error;
-                }
-            }
-        }
-        stream->output.currentBufferIndex = 0;
-        stream->output.framesUsedInCurrentBuffer = 0;
-    }
-
-
-    stream->isStopped = 0;
-    stream->isActive = 1;
-    stream->stopProcessing = 0;
-    stream->abortProcessing = 0;
-
-    result = ResetEventWithPaError( stream->input.bufferEvent );
-    if( result != paNoError ) goto error;
-
-    result = ResetEventWithPaError( stream->output.bufferEvent );
-    if( result != paNoError ) goto error;
-    
-    
-    if( stream->streamRepresentation.streamCallback )
-    {
-        /* callback stream */
-
-        result = ResetEventWithPaError( stream->abortEvent );
-        if( result != paNoError ) goto error;
-
-        /* Create thread that waits for audio buffers to be ready for processing. */
-        stream->processingThread = CreateThread( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId );
-        if( !stream->processingThread )
-        {
-            result = paUnanticipatedHostError;
-            PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() );
-            goto error;
-        }
-
-        /** @todo could have mme specific stream parameters to allow the user
-            to set the callback thread priorities */
-        stream->highThreadPriority = THREAD_PRIORITY_TIME_CRITICAL;
-        stream->throttledThreadPriority = THREAD_PRIORITY_NORMAL;
-
-        if( !SetThreadPriority( stream->processingThread, stream->highThreadPriority ) )
-        {
-            result = paUnanticipatedHostError;
-            PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() );
-            goto error;
-        }
-        stream->processingThreadPriority = stream->highThreadPriority;
-    }
-    else
-    {
-        /* blocking read/write stream */
-
-    }
-
-    if( PA_IS_INPUT_STREAM_(stream) )
-    {
-        for( i=0; i < stream->input.deviceCount; ++i )
-        {
-            mmresult = waveInStart( ((HWAVEIN*)stream->input.waveHandles)[i] );
-            PA_DEBUG(("Pa_StartStream: waveInStart returned = 0x%X.\n", mmresult));
-            if( mmresult != MMSYSERR_NOERROR )
-            {
-                result = paUnanticipatedHostError;
-                PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
-                goto error;
-            }
-        }
-    }
-
-    if( PA_IS_OUTPUT_STREAM_(stream) )
-    {
-        for( i=0; i < stream->output.deviceCount; ++i )
-        {
-            if( (mmresult = waveOutRestart( ((HWAVEOUT*)stream->output.waveHandles)[i] )) != MMSYSERR_NOERROR )
-            {
-                result = paUnanticipatedHostError;
-                PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
-                goto error;
-            }
-        }
-    }
-
-    return result;
-
-error:
-    /** @todo FIXME: implement recovery as best we can
-    This should involve rolling back to a state as-if this function had never been called
-    */
-    return result;
-}
-
-
-static PaError StopStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaWinMmeStream *stream = (PaWinMmeStream*)s;
-    int timeout;
-    DWORD waitResult;
-    MMRESULT mmresult;
-    signed int hostOutputBufferIndex;
-    unsigned int channel, waitCount, i;                  
-    
-    /** @todo
-        REVIEW: the error checking in this function needs review. the basic
-        idea is to return from this function in a known state - for example
-        there is no point avoiding calling waveInReset just because
-        the thread times out.
-    */
-
-    if( stream->processingThread )
-    {
-        /* callback stream */
-
-        /* Tell processing thread to stop generating more data and to let current data play out. */
-        stream->stopProcessing = 1;
-
-        /* Calculate timeOut longer than longest time it could take to return all buffers. */
-        timeout = (int)(stream->allBuffersDurationMs * 1.5);
-        if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ )
-            timeout = PA_MME_MIN_TIMEOUT_MSEC_;
-
-        PA_DEBUG(("WinMME StopStream: waiting for background thread.\n"));
-
-        waitResult = WaitForSingleObject( stream->processingThread, timeout );
-        if( waitResult == WAIT_TIMEOUT )
-        {
-            /* try to abort */
-            stream->abortProcessing = 1;
-            SetEvent( stream->abortEvent );
-            waitResult = WaitForSingleObject( stream->processingThread, timeout );
-            if( waitResult == WAIT_TIMEOUT )
-            {
-                PA_DEBUG(("WinMME StopStream: timed out while waiting for background thread to finish.\n"));
-                result = paTimedOut;
-            }
-        }
-
-        CloseHandle( stream->processingThread );
-        stream->processingThread = NULL;
-    }
-    else
-    {
-        /* blocking read / write stream */
-
-        if( PA_IS_OUTPUT_STREAM_(stream) )
-        {
-            if( stream->output.framesUsedInCurrentBuffer > 0 )
-            {
-                /* there are still unqueued frames in the current buffer, so flush them */
-
-                hostOutputBufferIndex = stream->output.currentBufferIndex;
-
-                PaUtil_SetOutputFrameCount( &stream->bufferProcessor,
-                        stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer );
-                
-                channel = 0;
-                for( i=0; i<stream->output.deviceCount; ++i )
-                {
-                    /* we have stored the number of channels in the buffer in dwUser */
-                    int channelCount = stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser;
-
-                    PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel,
-                            stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData +
-                                stream->output.framesUsedInCurrentBuffer * channelCount *
-                                stream->bufferProcessor.bytesPerHostOutputSample,
-                            channelCount );
-
-                    channel += channelCount;
-                }
-
-                PaUtil_ZeroOutput( &stream->bufferProcessor,
-                        stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer );
-
-                /* we send the entire buffer to the output devices, but we could
-                    just send a partial buffer, rather than zeroing the unused
-                    samples.
-                */
-                AdvanceToNextOutputBuffer( stream );
-            }
-            
-
-            timeout = (stream->allBuffersDurationMs / stream->output.bufferCount) + 1;
-            if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ )
-                timeout = PA_MME_MIN_TIMEOUT_MSEC_;
-
-            waitCount = 0;
-            while( !NoBuffersAreQueued( &stream->output ) && waitCount <= stream->output.bufferCount )
-            {
-                /* wait for MME to signal that a buffer is available */
-                waitResult = WaitForSingleObject( stream->output.bufferEvent, timeout );
-                if( waitResult == WAIT_FAILED )
-                {
-                    break;
-                }
-                else if( waitResult == WAIT_TIMEOUT )
-                {
-                    /* keep waiting */
-                }
-
-                ++waitCount;
-            }
-        }
-    }
-
-    if( PA_IS_OUTPUT_STREAM_(stream) )
-    {
-        for( i =0; i < stream->output.deviceCount; ++i )
-        {
-            mmresult = waveOutReset( ((HWAVEOUT*)stream->output.waveHandles)[i] );
-            if( mmresult != MMSYSERR_NOERROR )
-            {
-                result = paUnanticipatedHostError;
-                PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
-            }
-        }
-    }
-
-    if( PA_IS_INPUT_STREAM_(stream) )
-    {
-        for( i=0; i < stream->input.deviceCount; ++i )
-        {
-            mmresult = waveInReset( ((HWAVEIN*)stream->input.waveHandles)[i] );
-            if( mmresult != MMSYSERR_NOERROR )
-            {
-                result = paUnanticipatedHostError;
-                PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
-            }
-        }
-    }
-
-    stream->isStopped = 1;
-    stream->isActive = 0;
-
-    return result;
-}
-
-
-static PaError AbortStream( PaStream *s )
-{
-    PaError result = paNoError;
-    PaWinMmeStream *stream = (PaWinMmeStream*)s;
-    int timeout;
-    DWORD waitResult;
-    MMRESULT mmresult;
-    unsigned int i;
-    
-    /** @todo
-        REVIEW: the error checking in this function needs review. the basic
-        idea is to return from this function in a known state - for example
-        there is no point avoiding calling waveInReset just because
-        the thread times out.
-    */
-
-    if( stream->processingThread )
-    {
-        /* callback stream */
-        
-        /* Tell processing thread to abort immediately */
-        stream->abortProcessing = 1;
-        SetEvent( stream->abortEvent );
-    }
-
-
-    if( PA_IS_OUTPUT_STREAM_(stream) )
-    {
-        for( i =0; i < stream->output.deviceCount; ++i )
-        {
-            mmresult = waveOutReset( ((HWAVEOUT*)stream->output.waveHandles)[i] );
-            if( mmresult != MMSYSERR_NOERROR )
-            {
-                PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
-                return paUnanticipatedHostError;
-            }
-        }
-    }
-
-    if( PA_IS_INPUT_STREAM_(stream) )
-    {
-        for( i=0; i < stream->input.deviceCount; ++i )
-        {
-            mmresult = waveInReset( ((HWAVEIN*)stream->input.waveHandles)[i] );
-            if( mmresult != MMSYSERR_NOERROR )
-            {
-                PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
-                return paUnanticipatedHostError;
-            }
-        }
-    }
-
-
-    if( stream->processingThread )
-    {
-        /* callback stream */
-        
-        PA_DEBUG(("WinMME AbortStream: waiting for background thread.\n"));
-
-        /* Calculate timeOut longer than longest time it could take to return all buffers. */
-        timeout = (int)(stream->allBuffersDurationMs * 1.5);
-        if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ )
-            timeout = PA_MME_MIN_TIMEOUT_MSEC_;
-            
-        waitResult = WaitForSingleObject( stream->processingThread, timeout );
-        if( waitResult == WAIT_TIMEOUT )
-        {
-            PA_DEBUG(("WinMME AbortStream: timed out while waiting for background thread to finish.\n"));
-            return paTimedOut;
-        }
-
-        CloseHandle( stream->processingThread );
-        stream->processingThread = NULL;
-    }
-
-    stream->isStopped = 1;
-    stream->isActive = 0;
-
-    return result;
-}
-
-
-static PaError IsStreamStopped( PaStream *s )
-{
-    PaWinMmeStream *stream = (PaWinMmeStream*)s;
-
-    return stream->isStopped;
-}
-
-
-static PaError IsStreamActive( PaStream *s )
-{
-    PaWinMmeStream *stream = (PaWinMmeStream*)s;
-
-    return stream->isActive;
-}
-
-
-static PaTime GetStreamTime( PaStream *s )
-{
-    (void) s; /* unused parameter */
-    
-    return PaUtil_GetTime();
-}
-
-
-static double GetStreamCpuLoad( PaStream* s )
-{
-    PaWinMmeStream *stream = (PaWinMmeStream*)s;
-
-    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
-}
-
-
-/*
-    As separate stream interfaces are used for blocking and callback
-    streams, the following functions can be guaranteed to only be called
-    for blocking streams.
-*/
-
-static PaError ReadStream( PaStream* s,
-                           void *buffer,
-                           unsigned long frames )
-{
-    PaError result = paNoError;
-    PaWinMmeStream *stream = (PaWinMmeStream*)s;
-    void *userBuffer;
-    unsigned long framesRead = 0;
-    unsigned long framesProcessed;
-    signed int hostInputBufferIndex;
-    DWORD waitResult;
-    DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5);
-    unsigned int channel, i;
-    
-    if( PA_IS_INPUT_STREAM_(stream) )
-    {
-        /* make a local copy of the user buffer pointer(s). this is necessary
-            because PaUtil_CopyInput() advances these pointers every time
-            it is called.
-        */
-        if( stream->bufferProcessor.userInputIsInterleaved )
-        {
-            userBuffer = buffer;
-        }
-        else
-        {
-            userBuffer = alloca( sizeof(void*) * stream->bufferProcessor.inputChannelCount );
-            if( !userBuffer )
-                return paInsufficientMemory;
-            for( i = 0; i<stream->bufferProcessor.inputChannelCount; ++i )
-                ((void**)userBuffer)[i] = ((void**)buffer)[i];
-        }
-        
-        do{
-            if( CurrentInputBuffersAreDone( stream ) )
-            {
-                if( NoBuffersAreQueued( &stream->input ) )
-                {
-                    /** @todo REVIEW: consider what to do if the input overflows.
-                        do we requeue all of the buffers? should we be running
-                        a thread to make sure they are always queued? */
-
-                    result = paInputOverflowed;
-                }
-
-                hostInputBufferIndex = stream->input.currentBufferIndex;
-
-                PaUtil_SetInputFrameCount( &stream->bufferProcessor,
-                        stream->input.framesPerBuffer - stream->input.framesUsedInCurrentBuffer );
-                
-                channel = 0;
-                for( i=0; i<stream->input.deviceCount; ++i )
-                {
-                    /* we have stored the number of channels in the buffer in dwUser */
-                    int channelCount = stream->input.waveHeaders[i][ hostInputBufferIndex ].dwUser;
-
-                    PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, channel,
-                            stream->input.waveHeaders[i][ hostInputBufferIndex ].lpData +
-                                stream->input.framesUsedInCurrentBuffer * channelCount *
-                                stream->bufferProcessor.bytesPerHostInputSample,
-                            channelCount );
-
-                    channel += channelCount;
-                }
-                
-                framesProcessed = PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, frames - framesRead );
-
-                stream->input.framesUsedInCurrentBuffer += framesProcessed;
-                if( stream->input.framesUsedInCurrentBuffer == stream->input.framesPerBuffer )
-                {
-                    result = AdvanceToNextInputBuffer( stream );
-                    if( result != paNoError )
-                        break;
-                }
-
-                framesRead += framesProcessed;      
-
-            }else{
-                /* wait for MME to signal that a buffer is available */
-                waitResult = WaitForSingleObject( stream->input.bufferEvent, timeout );
-                if( waitResult == WAIT_FAILED )
-                {
-                    result = paUnanticipatedHostError;
-                    break;
-                }
-                else if( waitResult == WAIT_TIMEOUT )
-                {
-                    /* if a timeout is encountered, continue,
-                        perhaps we should give up eventually
-                    */
-                }         
-            }
-        }while( framesRead < frames );
-    }
-    else
-    {
-        result = paCanNotReadFromAnOutputOnlyStream;
-    }
-
-    return result;
-}
-
-
-static PaError WriteStream( PaStream* s,
-                            const void *buffer,
-                            unsigned long frames )
-{
-    PaError result = paNoError;
-    PaWinMmeStream *stream = (PaWinMmeStream*)s;
-    const void *userBuffer;
-    unsigned long framesWritten = 0;
-    unsigned long framesProcessed;
-    signed int hostOutputBufferIndex;
-    DWORD waitResult;
-    DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5);
-    unsigned int channel, i;
-
-        
-    if( PA_IS_OUTPUT_STREAM_(stream) )
-    {
-        /* make a local copy of the user buffer pointer(s). this is necessary
-            because PaUtil_CopyOutput() advances these pointers every time
-            it is called.
-        */
-        if( stream->bufferProcessor.userOutputIsInterleaved )
-        {
-            userBuffer = buffer;
-        }
-        else
-        {
-            userBuffer = alloca( sizeof(void*) * stream->bufferProcessor.outputChannelCount );
-            if( !userBuffer )
-                return paInsufficientMemory;
-            for( i = 0; i<stream->bufferProcessor.outputChannelCount; ++i )
-                ((const void**)userBuffer)[i] = ((const void**)buffer)[i];
-        }
-
-        do{
-            if( CurrentOutputBuffersAreDone( stream ) )
-            {
-                if( NoBuffersAreQueued( &stream->output ) )
-                {
-                    /** @todo REVIEW: consider what to do if the output
-                    underflows. do we requeue all the existing buffers with
-                    zeros? should we run a separate thread to keep the buffers
-                    enqueued at all times? */
-
-                    result = paOutputUnderflowed;
-                }
-
-                hostOutputBufferIndex = stream->output.currentBufferIndex;
-
-                PaUtil_SetOutputFrameCount( &stream->bufferProcessor,
-                        stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer );
-                
-                channel = 0;
-                for( i=0; i<stream->output.deviceCount; ++i )
-                {
-                    /* we have stored the number of channels in the buffer in dwUser */
-                    int channelCount = stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser;
-
-                    PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel,
-                            stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData +
-                                stream->output.framesUsedInCurrentBuffer * channelCount *
-                                stream->bufferProcessor.bytesPerHostOutputSample,
-                            channelCount );
-
-                    channel += channelCount;
-                }
-                
-                framesProcessed = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, frames - framesWritten );
-
-                stream->output.framesUsedInCurrentBuffer += framesProcessed;
-                if( stream->output.framesUsedInCurrentBuffer == stream->output.framesPerBuffer )
-                {
-                    result = AdvanceToNextOutputBuffer( stream );
-                    if( result != paNoError )
-                        break;
-                }
-
-                framesWritten += framesProcessed;
-            }
-            else
-            {
-                /* wait for MME to signal that a buffer is available */
-                waitResult = WaitForSingleObject( stream->output.bufferEvent, timeout );
-                if( waitResult == WAIT_FAILED )
-                {
-                    result = paUnanticipatedHostError;
-                    break;
-                }
-                else if( waitResult == WAIT_TIMEOUT )
-                {
-                    /* if a timeout is encountered, continue,
-                        perhaps we should give up eventually
-                    */
-                }             
-            }        
-        }while( framesWritten < frames );
-    }
-    else
-    {
-        result = paCanNotWriteToAnInputOnlyStream;
-    }
-    
-    return result;
-}
-
-
-static signed long GetStreamReadAvailable( PaStream* s )
-{
-    PaWinMmeStream *stream = (PaWinMmeStream*)s;
-    
-    if( PA_IS_INPUT_STREAM_(stream) )
-        return GetAvailableFrames( &stream->input );
-    else
-        return paCanNotReadFromAnOutputOnlyStream;
-}
-
-
-static signed long GetStreamWriteAvailable( PaStream* s )
-{
-    PaWinMmeStream *stream = (PaWinMmeStream*)s;
-    
-    if( PA_IS_OUTPUT_STREAM_(stream) )
-        return GetAvailableFrames( &stream->output );
-    else
-        return paCanNotWriteToAnInputOnlyStream;
-}
-
-
-/* NOTE: the following functions are MME-stream specific, and are called directly
-    by client code. We need to check for many more error conditions here because
-    we don't have the benefit of pa_front.c's parameter checking.
-*/
-
-static PaError GetWinMMEStreamPointer( PaWinMmeStream **stream, PaStream *s )
-{
-    PaError result;
-    PaUtilHostApiRepresentation *hostApi;
-    PaWinMmeHostApiRepresentation *winMmeHostApi;
-    
-    result = PaUtil_ValidateStreamPointer( s );
-    if( result != paNoError )
-        return result;
-
-    result = PaUtil_GetHostApiRepresentation( &hostApi, paMME );
-    if( result != paNoError )
-        return result;
-
-    winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
-    
-    /* note, the following would be easier if there was a generic way of testing
-        that a stream belongs to a specific host API */
-    
-    if( PA_STREAM_REP( s )->streamInterface == &winMmeHostApi->callbackStreamInterface
-            || PA_STREAM_REP( s )->streamInterface == &winMmeHostApi->blockingStreamInterface )
-    {
-        /* s is a WinMME stream */
-        *stream = (PaWinMmeStream *)s;
-        return paNoError;
-    }
-    else
-    {
-        return paIncompatibleStreamHostApi;
-    }
-}
-
-
-int PaWinMME_GetStreamInputHandleCount( PaStream* s )
-{
-    PaWinMmeStream *stream;
-    PaError result = GetWinMMEStreamPointer( &stream, s );
-
-    if( result == paNoError )
-        return (PA_IS_INPUT_STREAM_(stream)) ? stream->input.deviceCount : 0;
-    else
-        return result;
-}
-
-
-HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* s, int handleIndex )
-{
-    PaWinMmeStream *stream;
-    PaError result = GetWinMMEStreamPointer( &stream, s );
-
-    if( result == paNoError
-            && PA_IS_INPUT_STREAM_(stream)
-            && handleIndex >= 0
-            && (unsigned int)handleIndex < stream->input.deviceCount )
-        return ((HWAVEIN*)stream->input.waveHandles)[handleIndex];
-    else
-        return 0;
-}
-
-
-int PaWinMME_GetStreamOutputHandleCount( PaStream* s)
-{
-    PaWinMmeStream *stream;
-    PaError result = GetWinMMEStreamPointer( &stream, s );
-
-    if( result == paNoError )
-        return (PA_IS_OUTPUT_STREAM_(stream)) ? stream->output.deviceCount : 0;
-    else
-        return result;
-}
-
-
-HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* s, int handleIndex )
-{
-    PaWinMmeStream *stream;
-    PaError result = GetWinMMEStreamPointer( &stream, s );
-
-    if( result == paNoError
-            && PA_IS_OUTPUT_STREAM_(stream)
-            && handleIndex >= 0
-            && (unsigned int)handleIndex < stream->output.deviceCount )
-        return ((HWAVEOUT*)stream->output.waveHandles)[handleIndex];
-    else
-        return 0;
-}
-
-
-
-
-
diff --git a/portaudio/pa_win_wmme/pa_win_wmme.h b/portaudio/pa_win_wmme/pa_win_wmme.h
deleted file mode 100644
index 1a71633ad..000000000
--- a/portaudio/pa_win_wmme/pa_win_wmme.h
+++ /dev/null
@@ -1,160 +0,0 @@
-#ifndef PA_WIN_WMME_H
-#define PA_WIN_WMME_H
-/*
- * $Id: pa_win_wmme.h,v 1.1.2.14 2004/02/20 14:16:53 rossbencina Exp $
- * PortAudio Portable Real-Time Audio Library
- * MME specific extensions
- *
- * 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.
- *
- */
-
-/** @file
- @brief WMME-specific PortAudio API extension header file.
-*/
-
-
-#include "portaudio.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-#define paWinMmeUseLowLevelLatencyParameters            (0x01)
-#define paWinMmeUseMultipleDevices                      (0x02)  /* use mme specific multiple device feature */
-
-
-/* By default, the mme implementation drops the processing thread's priority
-    to THREAD_PRIORITY_NORMAL and sleeps the thread if the CPU load exceeds 100%
-    This flag disables any priority throttling. The processing thread will always
-    run at THREAD_PRIORITY_TIME_CRITICAL.
-*/
-#define paWinMmeDontThrottleOverloadedProcessingThread  (0x08)
-
-
-typedef struct PaWinMmeDeviceAndChannelCount{
-    PaDeviceIndex device;
-    int channelCount;
-}PaWinMmeDeviceAndChannelCount;
-
-
-typedef struct PaWinMmeStreamInfo{
-    unsigned long size;             /**< sizeof(PaWinMmeStreamInfo) */
-    PaHostApiTypeId hostApiType;    /**< paMME */
-    unsigned long version;          /**< 1 */
-
-    unsigned long flags;
-
-    /* low-level latency setting support
-        These settings control the number and size of host buffers in order
-        to set latency. They will be used instead of the generic parameters
-        to Pa_OpenStream() if flags contains the PaWinMmeUseLowLevelLatencyParameters
-        flag.
-
-        If PaWinMmeStreamInfo structures with PaWinMmeUseLowLevelLatencyParameters
-        are supplied for both input and output in a full duplex stream, then the
-        input and output framesPerBuffer must be the same, or the larger of the
-        two must be a multiple of the smaller, otherwise a
-        paIncompatibleHostApiSpecificStreamInfo error will be returned from
-        Pa_OpenStream().
-    */
-    unsigned long framesPerBuffer;
-    unsigned long bufferCount;  /* formerly numBuffers */ 
-
-    /* multiple devices per direction support
-        If flags contains the PaWinMmeUseMultipleDevices flag,
-        this functionality will be used, otherwise the device parameter to
-        Pa_OpenStream() will be used instead.
-        If devices are specified here, the corresponding device parameter
-        to Pa_OpenStream() should be set to paUseHostApiSpecificDeviceSpecification,
-        otherwise an paInvalidDevice error will result.
-        The total number of channels accross all specified devices
-        must agree with the corresponding channelCount parameter to
-        Pa_OpenStream() otherwise a paInvalidChannelCount error will result.
-    */
-    PaWinMmeDeviceAndChannelCount *devices;
-    unsigned long deviceCount;
-
-}PaWinMmeStreamInfo;
-
-
-/** Retrieve the number of wave in handles used by a PortAudio WinMME stream.
- Returns zero if the stream is output only.
-
- @return A non-negative value indicating the number of wave in handles
- or, a PaErrorCode (which are always negative) if PortAudio is not initialized
- or an error is encountered.
-
- @see PaWinMME_GetStreamInputHandle
-*/
-int PaWinMME_GetStreamInputHandleCount( PaStream* stream );
-
-
-/** Retrieve a wave in handle used by a PortAudio WinMME stream.
-
- @param stream The stream to query.
- @param handleIndex The zero based index of the wave in handle to retrieve. This
-    should be in the range [0, PaWinMME_GetStreamInputHandle(stream)-1].
-
- @return A valid wave in handle, or NULL if an error occurred.
-
- @see PaWinMME_GetStreamInputHandle
-*/
-HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* stream, int handleIndex );
-
-
-/** Retrieve the number of wave out handles used by a PortAudio WinMME stream.
- Returns zero if the stream is input only.
- 
- @return A non-negative value indicating the number of wave out handles
- or, a PaErrorCode (which are always negative) if PortAudio is not initialized
- or an error is encountered.
-
- @see PaWinMME_GetStreamOutputHandle
-*/
-int PaWinMME_GetStreamOutputHandleCount( PaStream* stream );
-
-
-/** Retrieve a wave out handle used by a PortAudio WinMME stream.
-
- @param stream The stream to query.
- @param handleIndex The zero based index of the wave out handle to retrieve.
-    This should be in the range [0, PaWinMME_GetStreamOutputHandleCount(stream)-1].
-
- @return A valid wave out handle, or NULL if an error occurred.
-
- @see PaWinMME_GetStreamOutputHandleCount
-*/
-HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* stream, int handleIndex );
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* PA_WIN_WMME_H */                                  
diff --git a/portaudio/pablio/CVS/Entries b/portaudio/pablio/CVS/Entries
deleted file mode 100644
index 22a4c8e8d..000000000
--- a/portaudio/pablio/CVS/Entries
+++ /dev/null
@@ -1,11 +0,0 @@
-/README.txt/1.1.1.1/Tue Jan 22 00:52:52 2002//Tv19-devel
-/pablio.c/1.1.1.1/Tue Jan 22 00:52:53 2002//Tv19-devel
-/pablio.def/1.1.1.1/Tue Jan 22 00:52:53 2002//Tv19-devel
-/pablio.h/1.1.1.1/Tue Jan 22 00:52:53 2002//Tv19-devel
-/ringbuffer.c/1.1.1.1/Tue Jan 22 00:52:53 2002//Tv19-devel
-/ringbuffer.h/1.1.1.1/Tue Jan 22 00:52:54 2002//Tv19-devel
-/test_rw.c/1.2/Fri Feb 22 22:06:23 2002//Tv19-devel
-/test_rw_echo.c/1.1.1.1/Tue Jan 22 00:52:54 2002//Tv19-devel
-/test_w_saw.c/1.1.1.1/Tue Jan 22 00:52:54 2002//Tv19-devel
-/test_w_saw8.c/1.1.1.1/Tue Jan 22 00:52:55 2002//Tv19-devel
-D
diff --git a/portaudio/pablio/CVS/Repository b/portaudio/pablio/CVS/Repository
deleted file mode 100644
index 71b9cbc0a..000000000
--- a/portaudio/pablio/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-portaudio/pablio
diff --git a/portaudio/pablio/CVS/Root b/portaudio/pablio/CVS/Root
deleted file mode 100644
index 815fa569f..000000000
--- a/portaudio/pablio/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@www.portaudio.com:/home/cvs
diff --git a/portaudio/pablio/CVS/Tag b/portaudio/pablio/CVS/Tag
deleted file mode 100644
index 8e6595a07..000000000
--- a/portaudio/pablio/CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Tv19-devel
diff --git a/portaudio/pablio/README.txt b/portaudio/pablio/README.txt
deleted file mode 100644
index 99c7d146e..000000000
--- a/portaudio/pablio/README.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-README for PABLIO
-Portable Audio Blocking I/O Library
-Author: Phil Burk
-
-PABLIO is a simplified interface to PortAudio that provide
-read/write style blocking I/O.
-
-Please see the .DOC file for documentation.
-
-/*
- * More information on PortAudio at: http://www.portaudio.com
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-
diff --git a/portaudio/pablio/pablio.c b/portaudio/pablio/pablio.c
deleted file mode 100644
index dca995a6e..000000000
--- a/portaudio/pablio/pablio.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * $Id: pablio.c,v 1.1.1.1 2002/01/22 00:52:53 phil Exp $
- * pablio.c
- * Portable Audio Blocking Input/Output utility.
- *
- * Author: Phil Burk, http://www.softsynth.com
- *
- * This program uses the PortAudio Portable Audio Library.
- * For more information see: http://www.audiomulch.com/portaudio/
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include "portaudio.h"
-#include "ringbuffer.h"
-#include "pablio.h"
-#include <string.h>
-
-/************************************************************************/
-/******** Constants *****************************************************/
-/************************************************************************/
-
-#define FRAMES_PER_BUFFER    (256)
-
-/************************************************************************/
-/******** Prototypes ****************************************************/
-/************************************************************************/
-
-static int blockingIOCallback( void *inputBuffer, void *outputBuffer,
-                               unsigned long framesPerBuffer,
-                               PaTimestamp outTime, void *userData );
-static PaError PABLIO_InitFIFO( RingBuffer *rbuf, long numFrames, long bytesPerFrame );
-static PaError PABLIO_TermFIFO( RingBuffer *rbuf );
-
-/************************************************************************/
-/******** Functions *****************************************************/
-/************************************************************************/
-
-/* Called from PortAudio.
- * Read and write data only if there is room in FIFOs.
- */
-static int blockingIOCallback( void *inputBuffer, void *outputBuffer,
-                               unsigned long framesPerBuffer,
-                               PaTimestamp outTime, void *userData )
-{
-    PABLIO_Stream *data = (PABLIO_Stream*)userData;
-    long numBytes = data->bytesPerFrame * framesPerBuffer;
-    (void) outTime;
-
-    /* This may get called with NULL inputBuffer during initial setup. */
-    if( inputBuffer != NULL )
-    {
-        RingBuffer_Write( &data->inFIFO, inputBuffer, numBytes );
-    }
-    if( outputBuffer != NULL )
-    {
-        int i;
-        int numRead = RingBuffer_Read( &data->outFIFO, outputBuffer, numBytes );
-        /* Zero out remainder of buffer if we run out of data. */
-        for( i=numRead; i<numBytes; i++ )
-        {
-            ((char *)outputBuffer)[i] = 0;
-        }
-    }
-
-    return 0;
-}
-
-/* Allocate buffer. */
-static PaError PABLIO_InitFIFO( RingBuffer *rbuf, long numFrames, long bytesPerFrame )
-{
-    long numBytes = numFrames * bytesPerFrame;
-    char *buffer = (char *) malloc( numBytes );
-    if( buffer == NULL ) return paInsufficientMemory;
-    memset( buffer, 0, numBytes );
-    return (PaError) RingBuffer_Init( rbuf, numBytes, buffer );
-}
-
-/* Free buffer. */
-static PaError PABLIO_TermFIFO( RingBuffer *rbuf )
-{
-    if( rbuf->buffer ) free( rbuf->buffer );
-    rbuf->buffer = NULL;
-    return paNoError;
-}
-
-/************************************************************
- * Write data to ring buffer.
- * Will not return until all the data has been written.
- */
-long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
-{
-    long bytesWritten;
-    char *p = (char *) data;
-    long numBytes = aStream->bytesPerFrame * numFrames;
-    while( numBytes > 0)
-    {
-        bytesWritten = RingBuffer_Write( &aStream->outFIFO, p, numBytes );
-        numBytes -= bytesWritten;
-        p += bytesWritten;
-        if( numBytes > 0) Pa_Sleep(10);
-    }
-    return numFrames;
-}
-
-/************************************************************
- * Read data from ring buffer.
- * Will not return until all the data has been read.
- */
-long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
-{
-    long bytesRead;
-    char *p = (char *) data;
-    long numBytes = aStream->bytesPerFrame * numFrames;
-    while( numBytes > 0)
-    {
-        bytesRead = RingBuffer_Read( &aStream->inFIFO, p, numBytes );
-        numBytes -= bytesRead;
-        p += bytesRead;
-        if( numBytes > 0) Pa_Sleep(10);
-    }
-    return numFrames;
-}
-
-/************************************************************
- * Return the number of frames that could be written to the stream without
- * having to wait.
- */
-long GetAudioStreamWriteable( PABLIO_Stream *aStream )
-{
-    int bytesEmpty = RingBuffer_GetWriteAvailable( &aStream->outFIFO );
-    return bytesEmpty / aStream->bytesPerFrame;
-}
-
-/************************************************************
- * Return the number of frames that are available to be read from the
- * stream without having to wait.
- */
-long GetAudioStreamReadable( PABLIO_Stream *aStream )
-{
-    int bytesFull = RingBuffer_GetReadAvailable( &aStream->inFIFO );
-    return bytesFull / aStream->bytesPerFrame;
-}
-
-/************************************************************/
-static unsigned long RoundUpToNextPowerOf2( unsigned long n )
-{
-    long numBits = 0;
-    if( ((n-1) & n) == 0) return n; /* Already Power of two. */
-    while( n > 0 )
-    {
-        n= n>>1;
-        numBits++;
-    }
-    return (1<<numBits);
-}
-
-/************************************************************
- * Opens a PortAudio stream with default characteristics.
- * Allocates PABLIO_Stream structure.
- *
- * flags parameter can be an ORed combination of:
- *    PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,
- *    and either PABLIO_MONO or PABLIO_STEREO
- */
-PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate,
-                         PaSampleFormat format, long flags )
-{
-    long   bytesPerSample;
-    long   doRead = 0;
-    long   doWrite = 0;
-    PaError err;
-    PABLIO_Stream *aStream;
-    long   minNumBuffers;
-    long   numFrames;
-
-    /* Allocate PABLIO_Stream structure for caller. */
-    aStream = (PABLIO_Stream *) malloc( sizeof(PABLIO_Stream) );
-    if( aStream == NULL ) return paInsufficientMemory;
-    memset( aStream, 0, sizeof(PABLIO_Stream) );
-
-    /* Determine size of a sample. */
-    bytesPerSample = Pa_GetSampleSize( format );
-    if( bytesPerSample < 0 )
-    {
-        err = (PaError) bytesPerSample;
-        goto error;
-    }
-    aStream->samplesPerFrame = ((flags&PABLIO_MONO) != 0) ? 1 : 2;
-    aStream->bytesPerFrame = bytesPerSample * aStream->samplesPerFrame;
-
-    /* Initialize PortAudio  */
-    err = Pa_Initialize();
-    if( err != paNoError ) goto error;
-
-    /* Warning: numFrames must be larger than amount of data processed per interrupt
-     *    inside PA to prevent glitches. Just to be safe, adjust size upwards.
-     */
-    minNumBuffers = 2 * Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, sampleRate );
-    numFrames = minNumBuffers * FRAMES_PER_BUFFER;
-    numFrames = RoundUpToNextPowerOf2( numFrames );
-
-    /* Initialize Ring Buffers */
-    doRead = ((flags & PABLIO_READ) != 0);
-    doWrite = ((flags & PABLIO_WRITE) != 0);
-    if(doRead)
-    {
-        err = PABLIO_InitFIFO( &aStream->inFIFO, numFrames, aStream->bytesPerFrame );
-        if( err != paNoError ) goto error;
-    }
-    if(doWrite)
-    {
-        long numBytes;
-        err = PABLIO_InitFIFO( &aStream->outFIFO, numFrames, aStream->bytesPerFrame );
-        if( err != paNoError ) goto error;
-        /* Make Write FIFO appear full initially. */
-        numBytes = RingBuffer_GetWriteAvailable( &aStream->outFIFO );
-        RingBuffer_AdvanceWriteIndex( &aStream->outFIFO, numBytes );
-    }
-
-    /* Open a PortAudio stream that we will use to communicate with the underlying
-     * audio drivers. */
-    err = Pa_OpenStream(
-              &aStream->stream,
-              (doRead ? Pa_GetDefaultInputDeviceID() : paNoDevice),
-              (doRead ? aStream->samplesPerFrame : 0 ),
-              format,
-              NULL,
-              (doWrite ? Pa_GetDefaultOutputDeviceID() : paNoDevice),
-              (doWrite ? aStream->samplesPerFrame : 0 ),
-              format,
-              NULL,
-              sampleRate,
-              FRAMES_PER_BUFFER,
-              minNumBuffers,
-              paClipOff,       /* we won't output out of range samples so don't bother clipping them */
-              blockingIOCallback,
-              aStream );
-    if( err != paNoError ) goto error;
-
-    err = Pa_StartStream( aStream->stream );
-    if( err != paNoError ) goto error;
-
-    *rwblPtr = aStream;
-    return paNoError;
-
-error:
-    CloseAudioStream( aStream );
-    *rwblPtr = NULL;
-    return err;
-}
-
-/************************************************************/
-PaError CloseAudioStream( PABLIO_Stream *aStream )
-{
-    PaError err;
-    int bytesEmpty;
-    int byteSize = aStream->outFIFO.bufferSize;
-
-    /* If we are writing data, make sure we play everything written. */
-    if( byteSize > 0 )
-    {
-        bytesEmpty = RingBuffer_GetWriteAvailable( &aStream->outFIFO );
-        while( bytesEmpty < byteSize )
-        {
-            Pa_Sleep( 10 );
-            bytesEmpty = RingBuffer_GetWriteAvailable( &aStream->outFIFO );
-        }
-    }
-
-    err = Pa_StopStream( aStream->stream );
-    if( err != paNoError ) goto error;
-    err = Pa_CloseStream( aStream->stream );
-    if( err != paNoError ) goto error;
-    Pa_Terminate();
-
-error:
-    PABLIO_TermFIFO( &aStream->inFIFO );
-    PABLIO_TermFIFO( &aStream->outFIFO );
-    free( aStream );
-    return err;
-}
diff --git a/portaudio/pablio/pablio.def b/portaudio/pablio/pablio.def
deleted file mode 100644
index a10f95291..000000000
--- a/portaudio/pablio/pablio.def
+++ /dev/null
@@ -1,35 +0,0 @@
-LIBRARY      PABLIO
-DESCRIPTION  'PABLIO   Portable Audio Blocking I/O'
-
-EXPORTS
-    ; Explicit exports can go here
-	Pa_Initialize                   @1
-	Pa_Terminate                    @2
-	Pa_GetHostError                 @3
-	Pa_GetErrorText                 @4
-	Pa_CountDevices                 @5
-	Pa_GetDefaultInputDeviceID      @6
-	Pa_GetDefaultOutputDeviceID     @7
-	Pa_GetDeviceInfo                @8
-	Pa_OpenStream                   @9
-	Pa_OpenDefaultStream            @10
-	Pa_CloseStream                  @11
-	Pa_StartStream                  @12
-	Pa_StopStream                   @13
-	Pa_StreamActive                 @14
-	Pa_StreamTime                   @15
-	Pa_GetCPULoad                   @16
-	Pa_GetMinNumBuffers             @17
-	Pa_Sleep                        @18
-
-	OpenAudioStream                 @19
-	CloseAudioStream                @20
-	WriteAudioStream                @21
-	ReadAudioStream                 @22
-
-	Pa_GetSampleSize                @23
-
-   ;123456789012345678901234567890123456
-   ;000000000111111111122222222223333333
-
-
diff --git a/portaudio/pablio/pablio.h b/portaudio/pablio/pablio.h
deleted file mode 100644
index a4871f38b..000000000
--- a/portaudio/pablio/pablio.h
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifndef _PABLIO_H
-#define _PABLIO_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/*
- * $Id: pablio.h,v 1.1.1.1 2002/01/22 00:52:53 phil Exp $
- * PABLIO.h
- * Portable Audio Blocking read/write utility.
- *
- * Author: Phil Burk, http://www.softsynth.com/portaudio/
- *
- * Include file for PABLIO, the Portable Audio Blocking I/O Library.
- * PABLIO is built on top of PortAudio, the Portable Audio Library.
- * For more information see: http://www.audiomulch.com/portaudio/
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include "portaudio.h"
-#include "ringbuffer.h"
-#include <string.h>
-
-typedef struct
-{
-    RingBuffer   inFIFO;
-    RingBuffer   outFIFO;
-    PortAudioStream *stream;
-    int          bytesPerFrame;
-    int          samplesPerFrame;
-}
-PABLIO_Stream;
-
-/* Values for flags for OpenAudioStream(). */
-#define PABLIO_READ     (1<<0)
-#define PABLIO_WRITE    (1<<1)
-#define PABLIO_READ_WRITE    (PABLIO_READ|PABLIO_WRITE)
-#define PABLIO_MONO     (1<<2)
-#define PABLIO_STEREO   (1<<3)
-
-/************************************************************
- * Write data to ring buffer.
- * Will not return until all the data has been written.
- */
-long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );
-
-/************************************************************
- * Read data from ring buffer.
- * Will not return until all the data has been read.
- */
-long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );
-
-/************************************************************
- * Return the number of frames that could be written to the stream without
- * having to wait.
- */
-long GetAudioStreamWriteable( PABLIO_Stream *aStream );
-
-/************************************************************
- * Return the number of frames that are available to be read from the
- * stream without having to wait.
- */
-long GetAudioStreamReadable( PABLIO_Stream *aStream );
-
-/************************************************************
- * Opens a PortAudio stream with default characteristics.
- * Allocates PABLIO_Stream structure.
- *
- * flags parameter can be an ORed combination of:
- *    PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,
- *    and either PABLIO_MONO or PABLIO_STEREO
- */
-PaError OpenAudioStream( PABLIO_Stream **aStreamPtr, double sampleRate,
-                         PaSampleFormat format, long flags );
-
-PaError CloseAudioStream( PABLIO_Stream *aStream );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* _PABLIO_H */
diff --git a/portaudio/pablio/ringbuffer.c b/portaudio/pablio/ringbuffer.c
deleted file mode 100644
index e0c028909..000000000
--- a/portaudio/pablio/ringbuffer.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * $Id: ringbuffer.c,v 1.1.1.1 2002/01/22 00:52:53 phil Exp $
- * ringbuffer.c
- * Ring Buffer utility..
- *
- * Author: Phil Burk, http://www.softsynth.com
- *
- * This program uses the PortAudio Portable Audio Library.
- * For more information see: http://www.audiomulch.com/portaudio/
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include "ringbuffer.h"
-#include <string.h>
-
-/***************************************************************************
- * Initialize FIFO.
- * numBytes must be power of 2, returns -1 if not.
- */
-long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr )
-{
-    if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */
-    rbuf->bufferSize = numBytes;
-    rbuf->buffer = (char *)dataPtr;
-    RingBuffer_Flush( rbuf );
-    rbuf->bigMask = (numBytes*2)-1;
-    rbuf->smallMask = (numBytes)-1;
-    return 0;
-}
-/***************************************************************************
-** Return number of bytes available for reading. */
-long RingBuffer_GetReadAvailable( RingBuffer *rbuf )
-{
-    return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
-}
-/***************************************************************************
-** Return number of bytes available for writing. */
-long RingBuffer_GetWriteAvailable( RingBuffer *rbuf )
-{
-    return ( rbuf->bufferSize - RingBuffer_GetReadAvailable(rbuf));
-}
-
-/***************************************************************************
-** Clear buffer. Should only be called when buffer is NOT being read. */
-void RingBuffer_Flush( RingBuffer *rbuf )
-{
-    rbuf->writeIndex = rbuf->readIndex = 0;
-}
-
-/***************************************************************************
-** Get address of region(s) to which we can write data.
-** If the region is contiguous, size2 will be zero.
-** If non-contiguous, size2 will be the size of second region.
-** Returns room available to be written or numBytes, whichever is smaller.
-*/
-long RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes,
-                                 void **dataPtr1, long *sizePtr1,
-                                 void **dataPtr2, long *sizePtr2 )
-{
-    long   index;
-    long   available = RingBuffer_GetWriteAvailable( rbuf );
-    if( numBytes > available ) numBytes = available;
-    /* Check to see if write is not contiguous. */
-    index = rbuf->writeIndex & rbuf->smallMask;
-    if( (index + numBytes) > rbuf->bufferSize )
-    {
-        /* Write data in two blocks that wrap the buffer. */
-        long   firstHalf = rbuf->bufferSize - index;
-        *dataPtr1 = &rbuf->buffer[index];
-        *sizePtr1 = firstHalf;
-        *dataPtr2 = &rbuf->buffer[0];
-        *sizePtr2 = numBytes - firstHalf;
-    }
-    else
-    {
-        *dataPtr1 = &rbuf->buffer[index];
-        *sizePtr1 = numBytes;
-        *dataPtr2 = NULL;
-        *sizePtr2 = 0;
-    }
-    return numBytes;
-}
-
-
-/***************************************************************************
-*/
-long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes )
-{
-    return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
-}
-
-/***************************************************************************
-** Get address of region(s) from which we can read data.
-** If the region is contiguous, size2 will be zero.
-** If non-contiguous, size2 will be the size of second region.
-** Returns room available to be written or numBytes, whichever is smaller.
-*/
-long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes,
-                                void **dataPtr1, long *sizePtr1,
-                                void **dataPtr2, long *sizePtr2 )
-{
-    long   index;
-    long   available = RingBuffer_GetReadAvailable( rbuf );
-    if( numBytes > available ) numBytes = available;
-    /* Check to see if read is not contiguous. */
-    index = rbuf->readIndex & rbuf->smallMask;
-    if( (index + numBytes) > rbuf->bufferSize )
-    {
-        /* Write data in two blocks that wrap the buffer. */
-        long firstHalf = rbuf->bufferSize - index;
-        *dataPtr1 = &rbuf->buffer[index];
-        *sizePtr1 = firstHalf;
-        *dataPtr2 = &rbuf->buffer[0];
-        *sizePtr2 = numBytes - firstHalf;
-    }
-    else
-    {
-        *dataPtr1 = &rbuf->buffer[index];
-        *sizePtr1 = numBytes;
-        *dataPtr2 = NULL;
-        *sizePtr2 = 0;
-    }
-    return numBytes;
-}
-/***************************************************************************
-*/
-long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes )
-{
-    return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
-}
-
-/***************************************************************************
-** Return bytes written. */
-long RingBuffer_Write( RingBuffer *rbuf, void *data, long numBytes )
-{
-    long size1, size2, numWritten;
-    void *data1, *data2;
-    numWritten = RingBuffer_GetWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
-    if( size2 > 0 )
-    {
-
-        memcpy( data1, data, size1 );
-        data = ((char *)data) + size1;
-        memcpy( data2, data, size2 );
-    }
-    else
-    {
-        memcpy( data1, data, size1 );
-    }
-    RingBuffer_AdvanceWriteIndex( rbuf, numWritten );
-    return numWritten;
-}
-
-/***************************************************************************
-** Return bytes read. */
-long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes )
-{
-    long size1, size2, numRead;
-    void *data1, *data2;
-    numRead = RingBuffer_GetReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
-    if( size2 > 0 )
-    {
-        memcpy( data, data1, size1 );
-        data = ((char *)data) + size1;
-        memcpy( data, data2, size2 );
-    }
-    else
-    {
-        memcpy( data, data1, size1 );
-    }
-    RingBuffer_AdvanceReadIndex( rbuf, numRead );
-    return numRead;
-}
diff --git a/portaudio/pablio/ringbuffer.h b/portaudio/pablio/ringbuffer.h
deleted file mode 100644
index eb46a5f86..000000000
--- a/portaudio/pablio/ringbuffer.h
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef _RINGBUFFER_H
-#define _RINGBUFFER_H
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/*
- * $Id: ringbuffer.h,v 1.1.1.1 2002/01/22 00:52:54 phil Exp $
- * ringbuffer.h
- * Ring Buffer utility..
- *
- * Author: Phil Burk, http://www.softsynth.com
- *
- * This program is distributed with the PortAudio Portable Audio Library.
- * For more information see: http://www.audiomulch.com/portaudio/
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include "ringbuffer.h"
-#include <string.h>
-
-typedef struct
-{
-    long   bufferSize; /* Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init. */
-    long   writeIndex; /* Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex. */
-    long   readIndex;  /* Index of next readable byte. Set by RingBuffer_AdvanceReadIndex. */
-    long   bigMask;    /* Used for wrapping indices with extra bit to distinguish full/empty. */
-    long   smallMask;  /* Used for fitting indices to buffer. */
-    char *buffer;
-}
-RingBuffer;
-/*
- * Initialize Ring Buffer.
- * numBytes must be power of 2, returns -1 if not.
- */
-long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr );
-
-/* Clear buffer. Should only be called when buffer is NOT being read. */
-void RingBuffer_Flush( RingBuffer *rbuf );
-
-/* Return number of bytes available for writing. */
-long RingBuffer_GetWriteAvailable( RingBuffer *rbuf );
-/* Return number of bytes available for read. */
-long RingBuffer_GetReadAvailable( RingBuffer *rbuf );
-/* Return bytes written. */
-long RingBuffer_Write( RingBuffer *rbuf, void *data, long numBytes );
-/* Return bytes read. */
-long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes );
-
-/* Get address of region(s) to which we can write data.
-** If the region is contiguous, size2 will be zero.
-** If non-contiguous, size2 will be the size of second region.
-** Returns room available to be written or numBytes, whichever is smaller.
-*/
-long RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes,
-                                 void **dataPtr1, long *sizePtr1,
-                                 void **dataPtr2, long *sizePtr2 );
-long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes );
-
-/* Get address of region(s) from which we can read data.
-** If the region is contiguous, size2 will be zero.
-** If non-contiguous, size2 will be the size of second region.
-** Returns room available to be written or numBytes, whichever is smaller.
-*/
-long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes,
-                                void **dataPtr1, long *sizePtr1,
-                                void **dataPtr2, long *sizePtr2 );
-
-long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* _RINGBUFFER_H */
diff --git a/portaudio/pablio/test_rw.c b/portaudio/pablio/test_rw.c
deleted file mode 100644
index 27a94b433..000000000
--- a/portaudio/pablio/test_rw.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * $Id: test_rw.c,v 1.2 2002/02/22 22:06:23 philburk Exp $
- * test_rw.c
- * Read input from one stream and write it to another.
- *
- * Author: Phil Burk, http://www.softsynth.com/portaudio/
- *
- * This program uses PABLIO, the Portable Audio Blocking I/O Library.
- * PABLIO is built on top of PortAudio, the Portable Audio Library.
- * For more information see: http://www.audiomulch.com/portaudio/
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "pablio.h"
-
-/*
-** Note that many of the older ISA sound cards on PCs do NOT support
-** 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)
-
-/* Select whether we will use floats or shorts. */
-#if 1
-#define SAMPLE_TYPE  paFloat32
-typedef float SAMPLE;
-#else
-#define SAMPLE_TYPE  paInt16
-typedef short SAMPLE;
-#endif
-
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    int      i;
-    SAMPLE   samples[SAMPLES_PER_FRAME * FRAMES_PER_BLOCK];
-    PaError  err;
-    PABLIO_Stream     *aStream;
-
-    printf("Full duplex sound test using PortAudio and RingBuffers\n");
-    fflush(stdout);
-
-    /* Open simplified blocking I/O layer on top of PortAudio. */
-    err = OpenAudioStream( &aStream, SAMPLE_RATE, SAMPLE_TYPE,
-                           (PABLIO_READ_WRITE | PABLIO_STEREO) );
-    if( err != paNoError ) goto error;
-
-    /* Process samples in the foreground. */
-    for( i=0; i<(NUM_SECONDS * SAMPLE_RATE); i += FRAMES_PER_BLOCK )
-    {
-        /* 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 );
-    }
-
-    CloseAudioStream( aStream );
-
-    printf("Full duplex sound 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 ) );
-    return -1;
-}
diff --git a/portaudio/pablio/test_rw_echo.c b/portaudio/pablio/test_rw_echo.c
deleted file mode 100644
index 7bc4e9b41..000000000
--- a/portaudio/pablio/test_rw_echo.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * $Id: test_rw_echo.c,v 1.1.1.1 2002/01/22 00:52:54 phil Exp $
- * test_rw_echo.c
- * Echo delayed input to output.
- *
- * Author: Phil Burk, http://www.softsynth.com/portaudio/
- *
- * This program uses PABLIO, the Portable Audio Blocking I/O Library.
- * PABLIO is built on top of PortAudio, the Portable Audio Library.
- *
- * Note that if you need low latency, you should not use PABLIO.
- * Use the PA_OpenStream callback technique which is lower level
- * than PABLIO.
- *
- * For more information see: http://www.audiomulch.com/portaudio/
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include "pablio.h"
-#include <string.h>
-
-/*
-** Note that many of the older ISA sound cards on PCs do NOT support
-** full duplex audio (simultaneous record and playback).
-** And some only support full duplex at lower sample rates.
-*/
-#define SAMPLE_RATE         (22050)
-#define NUM_SECONDS            (20)
-#define SAMPLES_PER_FRAME       (2)
-
-/* Select whether we will use floats or shorts. */
-#if 1
-#define SAMPLE_TYPE  paFloat32
-typedef float SAMPLE;
-#else
-#define SAMPLE_TYPE  paInt16
-typedef short SAMPLE;
-#endif
-
-#define NUM_ECHO_FRAMES   (2*SAMPLE_RATE)
-SAMPLE   samples[NUM_ECHO_FRAMES][SAMPLES_PER_FRAME] = {0.0};
-
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    int      i;
-    PaError  err;
-    PABLIO_Stream     *aInStream;
-    PABLIO_Stream     *aOutStream;
-    int      index;
-
-    printf("Full duplex sound test using PABLIO\n");
-    fflush(stdout);
-
-    /* Open simplified blocking I/O layer on top of PortAudio. */
-    /* Open input first so it can start to fill buffers. */
-    err = OpenAudioStream( &aInStream, SAMPLE_RATE, SAMPLE_TYPE,
-                           (PABLIO_READ | PABLIO_STEREO) );
-    if( err != paNoError ) goto error;
-    /* printf("opened input\n");  fflush(stdout); /**/
-
-    err = OpenAudioStream( &aOutStream, SAMPLE_RATE, SAMPLE_TYPE,
-                           (PABLIO_WRITE | PABLIO_STEREO) );
-    if( err != paNoError ) goto error;
-    /* printf("opened output\n");  fflush(stdout); /**/
-
-    /* Process samples in the foreground. */
-    index = 0;
-    for( i=0; i<(NUM_SECONDS * SAMPLE_RATE); i++ )
-    {
-        /* Write old frame of data to output. */
-        /* samples[index][1] = (i&256) * (1.0f/256.0f); /* sawtooth */
-        WriteAudioStream( aOutStream, &samples[index][0], 1 );
-
-        /* Read one frame of data into sample array for later output. */
-        ReadAudioStream( aInStream, &samples[index][0], 1 );
-        index += 1;
-        if( index >= NUM_ECHO_FRAMES ) index = 0;
-
-        if( (i & 0xFFFF) == 0 ) printf("i = %d\n", i ); fflush(stdout); /**/
-    }
-
-    CloseAudioStream( aOutStream );
-    CloseAudioStream( aInStream );
-
-    printf("R/W echo sound test complete.\n" );
-    fflush(stdout);
-    return 0;
-
-error:
-    fprintf( stderr, "An error occured while using PortAudio\n" );
-    fprintf( stderr, "Error number: %d\n", err );
-    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
-    return -1;
-}
diff --git a/portaudio/pablio/test_w_saw.c b/portaudio/pablio/test_w_saw.c
deleted file mode 100644
index f333cff17..000000000
--- a/portaudio/pablio/test_w_saw.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * $Id: test_w_saw.c,v 1.1.1.1 2002/01/22 00:52:54 phil Exp $
- * test_w_saw.c
- * Generate stereo sawtooth waveforms.
- *
- * Author: Phil Burk, http://www.softsynth.com
- *
- * This program uses PABLIO, the Portable Audio Blocking I/O Library.
- * PABLIO is built on top of PortAudio, the Portable Audio Library.
- *
- * For more information see: http://www.audiomulch.com/portaudio/
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include "pablio.h"
-#include <string.h>
-
-#define SAMPLE_RATE         (44100)
-#define NUM_SECONDS             (6)
-#define SAMPLES_PER_FRAME       (2)
-
-#define FREQUENCY           (220.0f)
-#define PHASE_INCREMENT     (2.0f * FREQUENCY / SAMPLE_RATE)
-#define FRAMES_PER_BLOCK    (100)
-
-float   samples[FRAMES_PER_BLOCK][SAMPLES_PER_FRAME];
-float   phases[SAMPLES_PER_FRAME];
-
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    int             i,j;
-    PaError         err;
-    PABLIO_Stream  *aOutStream;
-
-    printf("Generate sawtooth waves using PABLIO.\n");
-    fflush(stdout);
-
-    /* Open simplified blocking I/O layer on top of PortAudio. */
-    err = OpenAudioStream( &aOutStream, SAMPLE_RATE, paFloat32,
-                           (PABLIO_WRITE | PABLIO_STEREO) );
-    if( err != paNoError ) goto error;
-
-    /* Initialize oscillator phases. */
-    phases[0] = 0.0;
-    phases[1] = 0.0;
-
-    for( i=0; i<(NUM_SECONDS * SAMPLE_RATE); i += FRAMES_PER_BLOCK )
-    {
-        /* Generate sawtooth waveforms in a block for efficiency. */
-        for( j=0; j<FRAMES_PER_BLOCK; j++ )
-        {
-            /* Generate a sawtooth wave by incrementing a variable. */
-            phases[0] += PHASE_INCREMENT;
-            /* The signal range is -1.0 to +1.0 so wrap around if we go over. */
-            if( phases[0] > 1.0f ) phases[0] -= 2.0f;
-            samples[j][0] = phases[0];
-
-            /* On the second channel, generate a sawtooth wave a fifth higher. */
-            phases[1] += PHASE_INCREMENT * (3.0f / 2.0f);
-            if( phases[1] > 1.0f ) phases[1] -= 2.0f;
-            samples[j][1] = phases[1];
-        }
-
-        /* Write samples to output. */
-        WriteAudioStream( aOutStream, samples, FRAMES_PER_BLOCK );
-    }
-
-    CloseAudioStream( aOutStream );
-
-    printf("Sawtooth sound test complete.\n" );
-    fflush(stdout);
-    return 0;
-
-error:
-    fprintf( stderr, "An error occured while using PABLIO\n" );
-    fprintf( stderr, "Error number: %d\n", err );
-    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
-    return -1;
-}
diff --git a/portaudio/pablio/test_w_saw8.c b/portaudio/pablio/test_w_saw8.c
deleted file mode 100644
index 0f7e02e34..000000000
--- a/portaudio/pablio/test_w_saw8.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * $Id: test_w_saw8.c,v 1.1.1.1 2002/01/22 00:52:55 phil Exp $
- * test_w_saw8.c
- * Generate stereo 8 bit sawtooth waveforms.
- *
- * Author: Phil Burk, http://www.softsynth.com
- *
- * This program uses PABLIO, the Portable Audio Blocking I/O Library.
- * PABLIO is built on top of PortAudio, the Portable Audio Library.
- *
- * For more information see: http://www.audiomulch.com/portaudio/
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include "pablio.h"
-#include <string.h>
-
-#define SAMPLE_RATE         (22050)
-#define NUM_SECONDS             (6)
-#define SAMPLES_PER_FRAME       (2)
-
-
-#define FRAMES_PER_BLOCK    (100)
-
-unsigned char   samples[FRAMES_PER_BLOCK][SAMPLES_PER_FRAME];
-unsigned char   phases[SAMPLES_PER_FRAME];
-
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    int             i,j;
-    PaError         err;
-    PABLIO_Stream  *aOutStream;
-
-    printf("Generate unsigned 8 bit sawtooth waves using PABLIO.\n");
-    fflush(stdout);
-
-    /* Open simplified blocking I/O layer on top of PortAudio. */
-    err = OpenAudioStream( &aOutStream, SAMPLE_RATE, paUInt8,
-                           (PABLIO_WRITE | PABLIO_STEREO) );
-    if( err != paNoError ) goto error;
-
-    /* Initialize oscillator phases to "ground" level for paUInt8. */
-    phases[0] = 128;
-    phases[1] = 128;
-
-    for( i=0; i<(NUM_SECONDS * SAMPLE_RATE); i += FRAMES_PER_BLOCK )
-    {
-        /* Generate sawtooth waveforms in a block for efficiency. */
-        for( j=0; j<FRAMES_PER_BLOCK; j++ )
-        {
-            /* Generate a sawtooth wave by incrementing a variable. */
-            phases[0] += 1;
-            /* We don't have to do anything special to wrap when using paUint8 because
-             * 8 bit arithmetic automatically wraps. */
-            samples[j][0] = phases[0];
-
-            /* On the second channel, generate a higher sawtooth wave. */
-            phases[1] += 3;
-            samples[j][1] = phases[1];
-        }
-
-        /* Write samples to output. */
-        WriteAudioStream( aOutStream, samples, FRAMES_PER_BLOCK );
-    }
-
-    CloseAudioStream( aOutStream );
-
-    printf("Sawtooth sound test complete.\n" );
-    fflush(stdout);
-    return 0;
-
-error:
-    fprintf( stderr, "An error occured while using PABLIO\n" );
-    fprintf( stderr, "Error number: %d\n", err );
-    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
-    return -1;
-}
diff --git a/portmidi/Makefile b/portmidi/Makefile
deleted file mode 100644
index 7a87606d3..000000000
--- a/portmidi/Makefile
+++ /dev/null
@@ -1,77 +0,0 @@
-# MAKEFILE FOR PORTMIDI AND PORTTIME
-
-
-# For debugging, define PM_CHECK_ERRORS
-PMFLAGS = -DPM_CHECK_ERRORS
-# Otherwise do not define PM_CHECK_ERRORS
-# PMFLAGS = 
-
-# Use this for linux alsa (0.9x) version
-versions = pm_linux/pmlinuxalsa.o
-ALSALIB = -lasound
-VFLAGS = -DPMALSA
-
-# Use this for null (a dummy implementation for no Midi I/O:
-# versions = pmlinuxnull.o
-# ALSALIB = 
-# VFLAGS = -DPMNULL
-
-pmlib = pm_linux/libportmidi.a
-
-ptlib = porttime/libporttime.a
-
-CC = gcc $(VFLAGS) $(PMFLAGS) -g -Ipm_common -Iporttime
-
-pmobjects = pm_common/pmutil.o $(versions) pm_linux/pmlinux.o  \
-	pm_common/portmidi.o pm_linux/pmlinuxalsa.o
-
-ptobjects = porttime/porttime.o porttime/ptlinux.o 
-
-current: all
-
-all: $(pmlib) $(ptlib) pm_test/test pm_test/sysex pm_test/midithread \
-	pm_test/latency pm_test/midithru
-
-$(pmlib): Makefile $(pmobjects)
-	ar -cr $(pmlib) $(pmobjects)
-
-$(ptlib): Makefile $(ptobjects)
-	ar -cr $(ptlib) $(ptobjects)
-
-pm_linux/pmlinuxalsa.o: Makefile pm_linux/pmlinuxalsa.c pm_linux/pmlinuxalsa.h
-	$(CC) -c pm_linux/pmlinuxalsa.c -o pm_linux/pmlinuxalsa.o
-
-pm_test/test: Makefile pm_test/test.o $(pmlib) $(ptlib)
-	$(CC) pm_test/test.c -o pm_test/test $(pmlib) $(ptlib) $(ALSALIB)
-
-pm_test/sysex: Makefile pm_test/sysex.o $(pmlib) $(ptlib)
-	$(CC) pm_test/sysex.c -o pm_test/sysex $(pmlib) $(ptlib) $(ALSALIB)
-
-pm_test/midithread: Makefile pm_test/midithread.o $(pmlib) $(ptlib)
-	$(CC) pm_test/midithread.c -o pm_test/midithread \
-        $(pmlib) $(ptlib) $(ALSALIB)
-
-pm_test/latency: Makefile $(ptlib) pm_test/latency.o 
-	$(CC) pm_test/latency.c -o pm_test/latency $(pmlib) $(ptlib) \
-        $(ALSALIB) -lpthread -lm
-
-pm_test/midithru: Makefile $(ptlib) pm_test/midithru.o 
-	$(CC) pm_test/midithru.c -o pm_test/midithru $(pmlib) $(ptlib) \
-        $(ALSALIB) -lpthread -lm
-
-porttime/ptlinux.o: Makefile porttime/ptlinux.c
-	$(CC) -c porttime/ptlinux.c -o porttime/ptlinux.o
-
-clean:
-	rm -f *.o *~ core* */*.o */*~ */core* pm_test/*/pm_dll.dll 
-	rm -f *.opt *.ncb *.plg pm_win/Debug/pm_dll.lib pm_win/Release/pm_dll.lib
-	rm -f pm_test/*.opt pm_test/*.ncb
-
-cleaner: clean
-
-cleanest: cleaner
-	rm -f $(pmlib) $(ptlib) pm_test/test pm_test/sysex pm_test/midithread
-	rm -f pm_test/latency pm_test/midithru
-
-backup: cleanest
-	cd ..; zip -r portmidi.zip portmidi
diff --git a/portmidi/README.txt b/portmidi/README.txt
deleted file mode 100644
index 76412efd0..000000000
--- a/portmidi/README.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-README for PortMidi
-Roger Dannenberg
-6 April 2003
-revised May 2004
-
-For Windows, please see also README_WIN.txt and debugging_dlls.txt
-in pm_win.
-
-For Linux, please see also README_LINUX.txt in pm_linux.
-
-POINTERS VS DEVICE NUMBERS
-
-When you open a MIDI port, PortMidi allocates a structure to
-maintain the state of the open device. Since every device is
-also listed in a table, you might think it would be simpler to
-use the table index rather than a pointer to identify a device.
-This would also help with error checking (it's hard to make
-sure a pointer is valid). PortMidi's design parallels that of
-PortAudio.
-
-ERROR HANDLING
-
-Error handling turned out to be much more complicated than expected.
-PortMidi functions return error codes that the caller can check.
-In addition, errors may occur asynchronously due to MIDI input. In
-this case, the error code is transferred to the next call to
-Pm_Read or Pm_Write. Furthermore, an error can arise during a MIDI THRU
-operation that is also invoked as a side effect of polling for input.
-
-Ordinarily, the caller checks for an error code. If the error is
-system-dependent, pmHostError is returned and the caller can
-call Pm_GetHostErrorText to get a text description of the error.
-
-Host errors are recorded in the system-specific data allocated for
-each open MIDI port. However, if an error occurs on open or close,
-we cannot store the error with the device because there will be
-no device data (assuming PortMidi cleans up after devices that
-are not open). For open and close, we will store the host error
-in a global variable. The PortMidi is smart enough to look here
-first when the user asks for ErrorText.
-
-Because output to a MIDI Thru stream can be invoked as a side-effect
-of a MIDI read operation, some errors normally associated with
-writing MIDI can be returned from Pm_Read.
-
-DEBUGGING
-
-If you are building a console application for research, we suggest
-compiling with the option PM_CHECK_ERRORS. This will insert a
-check for error return values at the end of each PortMidi 
-function. If an error is encountered, a text message is printed
-using printf(), the user is asked to type ENTER, and then exit(-1)
-is called to clean up and terminate the program.
-
-You should not use PM_CHECK_ERRORS if printf() does not work
-(e.g. this is not a console application under Windows, or there
-is no visible console on some other OS), and you should not use
-PM_CHECK_ERRORS if you intend to recover from errors rather than
-abruptly terminate the program.
-
-The Windows version (and perhaps others) also offers a DEBUG
-compile-time option. See README_WIN.txt.
diff --git a/portmidi/pm_common/pminternal.h b/portmidi/pm_common/pminternal.h
deleted file mode 100644
index 20677308b..000000000
--- a/portmidi/pm_common/pminternal.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* pminternal.h -- header for interface implementations */
-
-/* this file is included by files that implement library internals */
-/* Here is a guide to implementers:
-     provide an initialization function similar to pm_winmm_init()
-     add your initialization function to pm_init()
-     Note that your init function should never require not-standard
-         libraries or fail in any way. If the interface is not available,
-         simply do not call pm_add_device. This means that non-standard
-         libraries should try to do dynamic linking at runtime using a DLL
-         and return without error if the DLL cannot be found or if there
-         is any other failure.
-     implement functions as indicated in pm_fns_type to open, read, write,
-         close, etc.
-     call pm_add_device() for each input and output device, passing it a
-         pm_fns_type structure.
-     assumptions about pm_fns_type functions are given below.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* these are defined in system-specific file */
-void *pm_alloc(size_t s);
-void pm_free(void *ptr);
-
-/* if an error occurs while opening or closing a midi stream, set these: */
-extern int pm_hosterror;
-extern char pm_hosterror_text[PM_HOST_ERROR_MSG_LEN];
-
-struct pm_internal_struct;
-
-/* these do not use PmInternal because it is not defined yet... */
-typedef PmError (*pm_write_short_fn)(struct pm_internal_struct *midi,
-                                     PmEvent *buffer);
-typedef PmError (*pm_begin_sysex_fn)(struct pm_internal_struct *midi,
-                                     PmTimestamp timestamp);
-typedef PmError (*pm_end_sysex_fn)(struct pm_internal_struct *midi,
-                                   PmTimestamp timestamp);
-typedef PmError (*pm_write_byte_fn)(struct pm_internal_struct *midi,
-                                    unsigned char byte, PmTimestamp timestamp);
-typedef PmError (*pm_write_realtime_fn)(struct pm_internal_struct *midi,
-                                        PmEvent *buffer);
-typedef PmError (*pm_write_flush_fn)(struct pm_internal_struct *midi);
-typedef PmTimestamp (*pm_synchronize_fn)(struct pm_internal_struct *midi);
-/* pm_open_fn should clean up all memory and close the device if any part
-   of the open fails */
-typedef PmError (*pm_open_fn)(struct pm_internal_struct *midi,
-                              void *driverInfo);
-typedef PmError (*pm_abort_fn)(struct pm_internal_struct *midi);
-/* pm_close_fn should clean up all memory and close the device if any
-   part of the close fails. */
-typedef PmError (*pm_close_fn)(struct pm_internal_struct *midi);
-typedef PmError (*pm_poll_fn)(struct pm_internal_struct *midi);
-typedef void (*pm_host_error_fn)(struct pm_internal_struct *midi, char * msg,
-                                 unsigned int len);
-typedef unsigned int (*pm_has_host_error_fn)(struct pm_internal_struct *midi);
-
-typedef struct {
-    pm_write_short_fn write_short; /* output short MIDI msg */
-    pm_begin_sysex_fn begin_sysex; /* prepare to send a sysex message */
-    pm_end_sysex_fn end_sysex; /* marks end of sysex message */
-    pm_write_byte_fn write_byte; /* accumulate one more sysex byte */
-    pm_write_realtime_fn write_realtime; /* send real-time message within sysex */
-    pm_write_flush_fn write_flush; /* send any accumulated but unsent data */
-    pm_synchronize_fn synchronize; /* synchronize portmidi time to stream time */
-    pm_open_fn open;   /* open MIDI device */
-    pm_abort_fn abort; /* abort */
-    pm_close_fn close; /* close device */
-    pm_poll_fn poll;   /* read pending midi events into portmidi buffer */
-    pm_has_host_error_fn has_host_error; /* true when device has had host
-                                            error message */
-    pm_host_error_fn host_error; /* provide text readable host error message
-                                    for device (clears and resets) */
-} pm_fns_node, *pm_fns_type;
-
-
-/* when open fails, the dictionary gets this set of functions: */
-extern pm_fns_node pm_none_dictionary;
-
-typedef struct {
-    PmDeviceInfo pub; /* some portmidi state also saved in here (for autmatic
-                         device closing (see PmDeviceInfo struct) */
-    void *descriptor; /* ID number passed to win32 multimedia API open */
-    void *internalDescriptor; /* points to PmInternal device, allows automatic
-                                 device closing */
-    pm_fns_type dictionary;
-} descriptor_node, *descriptor_type;
-
-extern int pm_descriptor_max;
-extern descriptor_type descriptors;
-extern int pm_descriptor_index;
-
-typedef unsigned long (*time_get_proc_type)(void *time_info);
-
-typedef struct pm_internal_struct {
-    int device_id; /* which device is open (index to descriptors) */
-    short write_flag; /* MIDI_IN, or MIDI_OUT */
-
-    PmTimeProcPtr time_proc; /* where to get the time */
-    void *time_info; /* pass this to get_time() */
-
-    long buffer_len; /* how big is the buffer */
-    PmEvent *buffer; /* storage for:
-                        - midi input
-                        - midi output w/latency != 0 */
-    long head;
-    long tail;
-
-    long latency; /* time delay in ms between timestamps and actual output */
-                  /* set to zero to get immediate, simple blocking output */
-                  /* if latency is zero, timestamps will be ignored; */
-                  /* if midi input device, this field ignored */
-
-    int overflow; /* set to non-zero if input is dropped */
-    int flush; /* flag to drop incoming sysex data because of overflow */
-    int sysex_in_progress; /* use for overflow management */
-    PmMessage sysex_message; /* buffer for 4 bytes of sysex data */
-    int sysex_message_count; /* how many bytes in sysex_message so far */
-
-    long filters; /* flags that filter incoming message classes */
-    int channel_mask; /* filter incoming messages based on channel */
-    PmTimestamp last_msg_time; /* timestamp of last message */
-    PmTimestamp sync_time; /* time of last synchronization */
-    PmTimestamp now; /* set by PmWrite to current time */
-    int first_message; /* initially true, used to run first synchronization */
-    pm_fns_type dictionary; /* implementation functions */
-    void *descriptor; /* system-dependent state */
-
-} PmInternal;
-
-typedef struct {
-    long head;
-    long tail;
-    long len;
-    long msg_size;
-    long overflow;
-    char *buffer;
-} PmQueueRep;
-
-/* defined by system specific implementation, e.g. pmwinmm, used by PortMidi */
-void pm_init(void);
-void pm_term(void);
-
-/* defined by portMidi, used by pmwinmm */
-PmError none_write_short(PmInternal *midi, PmEvent *buffer);
-PmError none_sysex(PmInternal *midi, PmTimestamp timestamp);
-PmError none_write_byte(PmInternal *midi, unsigned char byte,
-                        PmTimestamp timestamp);
-PmTimestamp none_synchronize(PmInternal *midi);
-
-PmError pm_fail_fn(PmInternal *midi);
-PmError pm_success_fn(PmInternal *midi);
-PmError pm_add_device(char *interf, char *name, int input, void *descriptor,
-                      pm_fns_type dictionary);
-void pm_read_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp);
-void pm_begin_sysex(PmInternal *midi);
-void pm_end_sysex(PmInternal *midi);
-void pm_read_short(PmInternal *midi, PmEvent *event);
-
-#define none_write_flush pm_fail_fn
-#define none_poll pm_fail_fn
-#define success_poll pm_success_fn
-
-#define MIDI_REALTIME_MASK 0xf8
-#define is_real_time(msg) \
-    ((Pm_MessageStatus(msg) & MIDI_REALTIME_MASK) == MIDI_REALTIME_MASK)
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/portmidi/pm_common/pmutil.c b/portmidi/pm_common/pmutil.c
deleted file mode 100644
index 1178b80b9..000000000
--- a/portmidi/pm_common/pmutil.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* pmutil.c -- some helpful utilities for building midi
-               applications that use PortMidi
- */
-#include "stdlib.h"
-#include "memory.h"
-#include "portmidi.h"
-#include "pmutil.h"
-#include "pminternal.h"
-
-
-PmQueue *Pm_QueueCreate(long num_msgs, long bytes_per_msg)
-{
-    PmQueueRep *queue = (PmQueueRep *) pm_alloc(sizeof(PmQueueRep));
-
-	/* arg checking */
-    if (!queue) 
-		return NULL;
-    
-	queue->len = num_msgs * bytes_per_msg;
-    queue->buffer = pm_alloc(queue->len);
-    if (!queue->buffer) {
-        pm_free(queue);
-        return NULL;
-    }
-    queue->head = 0;
-    queue->tail = 0;
-    queue->msg_size = bytes_per_msg;
-    queue->overflow = FALSE;
-    return queue;
-}
-
-
-PmError Pm_QueueDestroy(PmQueue *q)
-{
-    PmQueueRep *queue = (PmQueueRep *) q;
-	
-	/* arg checking */
-    if (!queue || !queue->buffer) 
-		return pmBadPtr;
-    
-	pm_free(queue->buffer);
-    pm_free(queue);
-    return pmNoError;
-}
-
-
-PmError Pm_Dequeue(PmQueue *q, void *msg)
-{
-    long head;
-    PmQueueRep *queue = (PmQueueRep *) q;
-
-	/* arg checking */
-    if(!queue)
-		return pmBadPtr;
-
-    if (queue->overflow) {
-        queue->overflow = FALSE;
-        return pmBufferOverflow;
-    }
-
-    head = queue->head; /* make sure this is written after access */
-    if (head == queue->tail) return 0;
-    memcpy(msg, queue->buffer + head, queue->msg_size);
-    head += queue->msg_size;
-    if (head == queue->len) head = 0;
-    queue->head = head;
-    return 1; /* success */
-}
-
-
-/* source should not enqueue data if overflow is set */
-/**/
-PmError Pm_Enqueue(PmQueue *q, void *msg)
-{
-    PmQueueRep *queue = (PmQueueRep *) q;
-    long tail;
-
-	/* arg checking */
-	if (!queue)
-		return pmBadPtr;
-
-	tail = queue->tail;
-    memcpy(queue->buffer + tail, msg, queue->msg_size);
-    tail += queue->msg_size;
-    if (tail == queue->len) tail = 0;
-    if (tail == queue->head) {
-        queue->overflow = TRUE;
-        /* do not update tail, so message is lost */
-        return pmBufferOverflow;
-    }
-    queue->tail = tail;
-    return pmNoError;
-}
-
-int Pm_QueueEmpty(PmQueue *q)
-{ 
-    PmQueueRep *queue = (PmQueueRep *) q;
-    if (!queue) return TRUE;
-    return (queue->head == queue->tail);
-}
-
-int Pm_QueueFull(PmQueue *q)
-{
-    PmQueueRep *queue = (PmQueueRep *) q;
-	long tail;
-	
-	/* arg checking */
-	if(!queue)
-		return pmBadPtr;
-	
-	tail = queue->tail;
-    tail += queue->msg_size;
-    if (tail == queue->len) {
-        tail = 0;
-    }
-    return (tail == queue->head);
-}
-
-void *Pm_QueuePeek(PmQueue *q)
-{
-    long head;
-    PmQueueRep *queue = (PmQueueRep *) q;
-
-	/* arg checking */
-    if(!queue)
-		return NULL;
-
-    head = queue->head; /* make sure this is written after access */
-    if (head == queue->tail) return NULL;
-    return queue->buffer + head;
-}
-
diff --git a/portmidi/pm_common/pmutil.h b/portmidi/pm_common/pmutil.h
deleted file mode 100644
index a7fb3ebfa..000000000
--- a/portmidi/pm_common/pmutil.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* pmutil.h -- some helpful utilities for building midi 
-               applications that use PortMidi 
- */
-
-typedef void PmQueue;
-
-/*
-    A single-reader, single-writer queue is created by
-    Pm_QueueCreate(), which takes the number of messages and
-    the message size as parameters. The queue only accepts
-    fixed sized messages. Returns NULL if memory cannot be allocated.
-
-    Pm_QueueDestroy() destroys the queue and frees its storage.
- */
-
-PmQueue *Pm_QueueCreate(long num_msgs, long bytes_per_msg);
-PmError Pm_QueueDestroy(PmQueue *queue);
-
-/* 
-    Pm_Dequeue() removes one item from the queue, copying it into msg.
-    Returns 1 if successful, and 0 if the queue is empty.
-    Returns pmBufferOverflow, clears the overflow flag, and does not
-    return a data item if the overflow flag is set. (This protocol
-    ensures that the reader will be notified when data is lost due 
-    to overflow.)
- */
-PmError Pm_Dequeue(PmQueue *queue, void *msg);
-
-
-/*
-    Pm_Enqueue() inserts one item into the queue, copying it from msg.
-    Returns pmNoError if successful and pmBufferOverflow if the queue was 
-    already full. If pmBufferOverflow is returned, the overflow flag is set.
- */
-PmError Pm_Enqueue(PmQueue *queue, void *msg);
-
-
-/*
-    Pm_QueueFull() returns non-zero if the queue is full
-    Pm_QueueEmpty() returns non-zero if the queue is empty
-
-    Either condition may change immediately because a parallel
-    enqueue or dequeue operation could be in progress.
- */
-int Pm_QueueFull(PmQueue *queue);
-int Pm_QueueEmpty(PmQueue *queue);
-
-
-/*
-    Pm_QueuePeek() returns a pointer to the item at the head of the queue,
-    or NULL if the queue is empty. The item is not removed from the queue.
-    If queue is in an overflow state, a valid pointer is returned and the
-    queue remains in the overflow state.
- */
-void *Pm_QueuePeek(PmQueue *queue);
-
diff --git a/portmidi/pm_common/portmidi.c b/portmidi/pm_common/portmidi.c
deleted file mode 100644
index e1b962d75..000000000
--- a/portmidi/pm_common/portmidi.c
+++ /dev/null
@@ -1,980 +0,0 @@
-#include "stdlib.h"
-#include "string.h"
-#include "portmidi.h"
-#include "porttime.h"
-#include "pminternal.h"
-#include <assert.h>
-
-#define MIDI_CLOCK      0xf8
-#define MIDI_ACTIVE     0xfe
-#define MIDI_STATUS_MASK 0x80
-#define MIDI_SYSEX      0xf0
-#define MIDI_EOX        0xf7
-#define MIDI_START      0xFA
-#define MIDI_STOP       0xFC
-#define MIDI_CONTINUE   0xFB
-#define MIDI_F9         0xF9
-#define MIDI_FD         0xFD
-#define MIDI_RESET      0xFF
-#define MIDI_NOTE_ON    0x90
-#define MIDI_NOTE_OFF   0x80
-#define MIDI_CHANNEL_AT 0xD0
-#define MIDI_POLY_AT    0xA0
-#define MIDI_PROGRAM    0xC0
-#define MIDI_CONTROL    0xB0
-#define MIDI_PITCHBEND  0xE0
-#define MIDI_MTC        0xF1
-#define MIDI_SONGPOS    0xF2
-#define MIDI_SONGSEL    0xF3
-#define MIDI_TUNE       0xF6
-
-#define is_empty(midi) ((midi)->tail == (midi)->head)
-
-static int pm_initialized = FALSE;
-int pm_hosterror = FALSE;
-char pm_hosterror_text[PM_HOST_ERROR_MSG_LEN];
-
-#ifdef PM_CHECK_ERRORS
-
-#include <stdio.h>
-
-#define STRING_MAX 80
-
-static void prompt_and_exit(void)
-{
-    char line[STRING_MAX];
-    printf("type ENTER...");
-    fgets(line, STRING_MAX, stdin);
-    /* this will clean up open ports: */
-    exit(-1);
-}
-
-
-static PmError pm_errmsg(PmError err)
-{
-    if (err == pmHostError) {
-        /* it seems pointless to allocate memory and copy the string,
-         * so I will do the work of Pm_GetHostErrorText directly
-         */
-        printf("PortMidi found host error...\n  %s\n", pm_hosterror_text);
-        pm_hosterror = FALSE;
-        pm_hosterror_text[0] = 0; /* clear the message */
-        prompt_and_exit();
-    } else if (err < 0) {
-        printf("PortMidi call failed...\n  %s\n", Pm_GetErrorText(err));
-        prompt_and_exit();
-    }
-    return err;
-}
-#else
-#define pm_errmsg(err) err
-#endif
-
-/*
-====================================================================
-system implementation of portmidi interface
-====================================================================
-*/
-
-int pm_descriptor_max = 0;
-int pm_descriptor_index = 0;
-descriptor_type descriptors = NULL;
-
-/* pm_add_device -- describe interface/device pair to library
- *
- * This is called at intialization time, once for each
- * interface (e.g. DirectSound) and device (e.g. SoundBlaster 1)
- * The strings are retained but NOT COPIED, so do not destroy them!
- *
- * returns pmInvalidDeviceId if device memory is exceeded
- * otherwise returns pmNoError
- */
-PmError pm_add_device(char *interf, char *name, int input,
-                      void *descriptor, pm_fns_type dictionary) {
-    if (pm_descriptor_index >= pm_descriptor_max) {
-        // expand descriptors
-        descriptor_type new_descriptors =
-                pm_alloc(sizeof(descriptor_node) * (pm_descriptor_max + 32));
-        if (!new_descriptors) return pmInsufficientMemory;
-        if (descriptors) {
-            memcpy(new_descriptors, descriptors,
-                   sizeof(descriptor_node) * pm_descriptor_max);
-            free(descriptors);
-        }
-        pm_descriptor_max += 32;
-        descriptors = new_descriptors;
-    }
-    descriptors[pm_descriptor_index].pub.interf = interf;
-    descriptors[pm_descriptor_index].pub.name = name;
-    descriptors[pm_descriptor_index].pub.input = input;
-    descriptors[pm_descriptor_index].pub.output = !input;
-
-    /* default state: nothing to close (for automatic device closing) */
-    descriptors[pm_descriptor_index].pub.opened = FALSE;
-
-    /* ID number passed to win32 multimedia API open */
-    descriptors[pm_descriptor_index].descriptor = descriptor;
-
-    /* points to PmInternal, allows automatic device closing */
-    descriptors[pm_descriptor_index].internalDescriptor = NULL;
-
-    descriptors[pm_descriptor_index].dictionary = dictionary;
-
-    pm_descriptor_index++;
-
-    return pmNoError;
-}
-
-
-/*
-====================================================================
-portmidi implementation
-====================================================================
-*/
-
-int Pm_CountDevices( void )
-{
-    PmError err = Pm_Initialize();
-    if (err)
-        return pm_errmsg(err);
-    return pm_descriptor_index;
-}
-
-
-const PmDeviceInfo* Pm_GetDeviceInfo( PmDeviceID id )
-{
-    PmError err = Pm_Initialize();
-    if (err)
-        return NULL;
-    if (id >= 0 && id < pm_descriptor_index) {
-        return &descriptors[id].pub;
-    }
-    return NULL;
-}
-
-/* pm_success_fn -- "noop" function pointer */
-PmError pm_success_fn(PmInternal *midi) {
-    return pmNoError;
-}
-
-/* none_write -- returns an error if called */
-PmError none_write_short(PmInternal *midi, PmEvent *buffer)
-{
-    return pmBadPtr;
-}
-
-/* none_sysex -- placeholder for begin_sysex and end_sysex */
-PmError none_sysex(PmInternal *midi, PmTimestamp timestamp)
-{
-    return pmBadPtr;
-}
-
-PmError none_write_byte(PmInternal *midi, unsigned char byte,
-                        PmTimestamp timestamp)
-{
-    return pmBadPtr;
-}
-
-/* pm_fail_fn -- generic function, returns error if called */
-PmError pm_fail_fn(PmInternal *midi)
-{
-    return pmBadPtr;
-}
-
-static PmError none_open(PmInternal *midi, void *driverInfo)
-{
-    return pmBadPtr;
-}
-static void none_get_host_error(PmInternal * midi, char * msg, unsigned int len) {
-    strcpy(msg,"");
-}
-static unsigned int none_has_host_error(PmInternal * midi) {
-    return FALSE;
-}
-PmTimestamp none_synchronize(PmInternal *midi) {
-    return 0;
-}
-
-#define none_abort pm_fail_fn
-#define none_close pm_fail_fn
-
-pm_fns_node pm_none_dictionary = {
-    none_write_short,
-    none_sysex,
-    none_sysex,
-    none_write_byte,
-    none_write_short,
-    none_write_flush,
-    none_synchronize,
-    none_open,
-    none_abort,
-    none_close,
-    none_poll,
-    none_has_host_error,
-    none_get_host_error
-};
-
-
-const char *Pm_GetErrorText( PmError errnum ) {
-    const char *msg;
-
-    switch(errnum)
-    {
-    case pmNoError:
-        msg = "";
-        break;
-    case pmHostError:
-        msg = "PortMidi: `Host error'";
-        break;
-    case pmInvalidDeviceId:
-        msg = "PortMidi: `Invalid device ID'";
-        break;
-    case pmInsufficientMemory:
-        msg = "PortMidi: `Insufficient memory'";
-        break;
-    case pmBufferTooSmall:
-        msg = "PortMidi: `Buffer too small'";
-        break;
-    case pmBadPtr:
-        msg = "PortMidi: `Bad pointer'";
-        break;
-    case pmInternalError:
-        msg = "PortMidi: `Internal PortMidi Error'";
-        break;
-    case pmBufferOverflow:
-        msg = "PortMidi: `Buffer overflow'";
-        break;
-    case pmBadData:
-        msg = "PortMidi: `Invalid MIDI message Data'";
-    default:
-        msg = "PortMidi: `Illegal error number'";
-        break;
-    }
-    return msg;
-}
-
-
-/* This can be called whenever you get a pmHostError return value.
- * The error will always be in the global pm_hosterror_text.
- */
-void Pm_GetHostErrorText(char * msg, unsigned int len) {
-    assert(msg);
-    assert(len > 0);
-    if (pm_hosterror) { /* we have the string already from open or close */
-        strncpy(msg, (char *) pm_hosterror_text, len);
-        pm_hosterror = FALSE;
-        pm_hosterror_text[0] = 0; /* clear the message; not necessary, but it
-                                 might help with debugging */
-        msg[len - 1] = 0; /* make sure string is terminated */
-    } else {
-        msg[0] = 0; /* no string to return */
-    }
-}
-
-
-int Pm_HasHostError(PortMidiStream * stream) {
-    if (stream) {
-        PmInternal * midi = (PmInternal *) stream;
-        pm_hosterror = (*midi->dictionary->has_host_error)(midi);
-        if (pm_hosterror) {
-            midi->dictionary->host_error(midi, pm_hosterror_text,
-                                         PM_HOST_ERROR_MSG_LEN);
-            /* now error message is global */
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-
-PmError Pm_Initialize( void ) {
-    pm_hosterror_text[0] = 0; /* the null string */
-    if (!pm_initialized) {
-        pm_init();
-        pm_initialized = TRUE;
-    }
-    return pmNoError;
-}
-
-
-PmError Pm_Terminate( void ) {
-    if (pm_initialized) {
-        pm_term();
-        pm_initialized = FALSE;
-    }
-    return pmNoError;
-}
-
-
-/* Pm_Read -- read up to length longs from source into buffer */
-/*
-   returns number of longs actually read, or error code
-
-   When the reader wants data:
-     if overflow_flag:
-         do not get anything
-         empty the buffer (read_ptr = write_ptr)
-         clear overflow_flag
-         return pmBufferOverflow
-     get data
-     return number of messages
-*/
-PmError Pm_Read(PortMidiStream *stream, PmEvent *buffer, long length) {
-    PmInternal *midi = (PmInternal *) stream;
-    int n = 0;
-    long head;
-    PmError err = pmNoError;
-
-    /* arg checking */
-    if(midi == NULL)
-        err = pmBadPtr;
-    else if(Pm_HasHostError(midi))
-        err = pmHostError;
-    else if(!descriptors[midi->device_id].pub.opened)
-        err = pmBadPtr;
-    else if(!descriptors[midi->device_id].pub.input)
-        err = pmBadPtr;
-
-    /* First poll for data in the buffer...
-     * This either simply checks for data, or attempts first to fill the buffer
-     * with data from the MIDI hardware; this depends on the implementation.
-     * We could call Pm_Poll here, but that would redo a lot of redundant
-     * parameter checking, so I copied some code from Pm_Poll to here: */
-    else err = (*(midi->dictionary->poll))(midi);
-
-    if (err != pmNoError) {
-        return pm_errmsg(err);
-    }
-
-    head = midi->head;
-    while (head != midi->tail && n < length) {
-        PmEvent event = midi->buffer[head++];
-        *buffer++ = event;
-        if (head == midi->buffer_len) head = 0;
-        n++;
-    }
-    midi->head = head;
-    if (midi->overflow) {
-        midi->head = midi->tail;
-        midi->overflow = FALSE;
-        return pm_errmsg(pmBufferOverflow);
-    }
-    return n;
-}
-
-PmError Pm_Poll( PortMidiStream *stream )
-{
-    PmInternal *midi = (PmInternal *) stream;
-    PmError err;
-
-    /* arg checking */
-    if(midi == NULL)
-        err = pmBadPtr;
-    else if(Pm_HasHostError(midi))
-        err = pmHostError;
-    else if(!descriptors[midi->device_id].pub.opened)
-        err = pmBadPtr;
-    else if(!descriptors[midi->device_id].pub.input)
-        err = pmBadPtr;
-    else
-        err = (*(midi->dictionary->poll))(midi);
-
-    if (err != pmNoError)
-        return pm_errmsg(err);
-    else
-        return midi->head != midi->tail;
-}
-
-/* to facilitate correct error-handling, Pm_Write, Pm_WriteShort, and
-   Pm_WriteSysEx all operate a state machine that "outputs" calls to
-   write_short, begin_sysex, write_byte, end_sysex, and write_realtime */
-
-PmError Pm_Write( PortMidiStream *stream, PmEvent *buffer, long length)
-{
-    PmInternal *midi = (PmInternal *) stream;
-    PmError err;
-    int i;
-    int bits;
-
-    /* arg checking */
-    if(midi == NULL)
-        err = pmBadPtr;
-    else if(Pm_HasHostError(midi))
-        err = pmHostError;
-    else if(!descriptors[midi->device_id].pub.opened)
-        err = pmBadPtr;
-    else if(!descriptors[midi->device_id].pub.output)
-        err = pmBadPtr;
-    else
-        err = pmNoError;
-
-    if (err != pmNoError) goto pm_write_error;
-
-    if (midi->latency == 0) {
-        midi->now = 0;
-    } else {
-        midi->now = (*(midi->time_proc))(midi->time_info);
-        if (midi->first_message || midi->sync_time + 100 /*ms*/ < midi->now) {
-            /* time to resync */
-            midi->now = (*midi->dictionary->synchronize)(midi);
-            midi->first_message = FALSE;
-        }
-    }
-
-    for (i = 0; i < length; i++) {
-        unsigned long msg = buffer[i].message;
-        bits = 0;
-        /* is this a sysex message? */
-        if (Pm_MessageStatus(msg) == MIDI_SYSEX) {
-            if (midi->sysex_in_progress) {
-                /* error: previous sysex was not terminated by EOX */
-                midi->sysex_in_progress = FALSE;
-                err = pmBadData;
-                goto pm_write_error;
-            }
-            midi->sysex_in_progress = TRUE;
-            if ((err = (*midi->dictionary->begin_sysex)(midi,
-                               buffer[i].timestamp)) != pmNoError)
-                goto pm_write_error;
-            if ((err = (*midi->dictionary->write_byte)(midi, MIDI_SYSEX,
-                               buffer[i].timestamp)) != pmNoError)
-                goto pm_write_error;
-            bits = 8;
-            /* fall through to continue sysex processing */
-        } else if ((msg & MIDI_STATUS_MASK) &&
-                   (Pm_MessageStatus(msg) != MIDI_EOX)) {
-            /* a non-sysex message */
-            if (midi->sysex_in_progress) {
-                /* this should be a non-realtime message */
-                if (is_real_time(msg)) {
-                    if ((err = (*midi->dictionary->write_realtime)(midi,
-                                       &(buffer[i]))) != pmNoError)
-                        goto pm_write_error;
-                } else {
-                    midi->sysex_in_progress = FALSE;
-                    err = pmBadData;
-                    /* ignore any error from this, because we already have one */
-                    /* pass 0 as timestamp -- it's ignored */
-                    (*midi->dictionary->end_sysex)(midi, 0);
-                    goto pm_write_error;
-                }
-            } else { /* regular short midi message */
-                if ((err = (*midi->dictionary->write_short)(midi,
-                                   &(buffer[i]))) != pmNoError)
-                    goto pm_write_error;
-                continue;
-            }
-        }
-        if (midi->sysex_in_progress) { /* send sysex bytes until EOX */
-            while (bits < 32) {
-                unsigned char midi_byte = (unsigned char) (msg >> bits);
-                if ((err = (*midi->dictionary->write_byte)(midi, midi_byte,
-                                   buffer[i].timestamp)) != pmNoError)
-                    goto pm_write_error;
-                if (midi_byte == MIDI_EOX) {
-                    midi->sysex_in_progress = FALSE;
-                    if ((err = (*midi->dictionary->end_sysex)(midi,
-                                       buffer[i].timestamp)) != pmNoError)
-                        goto pm_write_error;
-                    break; /* from while loop */
-                }
-                bits += 8;
-            }
-        } else {
-            /* not in sysex mode, but message did not start with status */
-            err = pmBadData;
-            goto pm_write_error;
-        }
-    }
-    /* after all messages are processed, send the data */
-    err = (*midi->dictionary->write_flush)(midi);
-pm_write_error:
-    return pm_errmsg(err);
-}
-
-
-PmError Pm_WriteShort( PortMidiStream *stream, long when, long msg)
-{
-    PmEvent event;
-
-    event.timestamp = when;
-    event.message = msg;
-    return Pm_Write(stream, &event, 1);
-}
-
-
-PmError Pm_WriteSysEx(PortMidiStream *stream, PmTimestamp when,
-                      unsigned char *msg)
-{
-    /* allocate buffer space for PM_DEFAULT_SYSEX_BUFFER_SIZE bytes */
-    /* each PmEvent holds sizeof(PmMessage) bytes of sysex data */
-#define BUFLEN (PM_DEFAULT_SYSEX_BUFFER_SIZE / sizeof(PmMessage))
-    PmEvent buffer[BUFLEN];
-    /* the next byte in the buffer is represented by an index, bufx, and
-       a shift in bits */
-    int shift = 0;
-    int bufx = 0;
-    buffer[0].message = 0;
-    buffer[0].timestamp = when;
-
-    while (1) {
-        /* insert next byte into buffer */
-        buffer[bufx].message |= ((*msg) << shift);
-        shift += 8;
-        if (shift == 32) {
-            shift = 0;
-            bufx++;
-            if (bufx == BUFLEN) {
-                PmError err = Pm_Write(stream, buffer, BUFLEN);
-                if (err) return err;
-                /* prepare to fill another buffer */
-                bufx = 0;
-            }
-            buffer[bufx].message = 0;
-            buffer[bufx].timestamp = when;
-        }
-        /* keep inserting bytes until you find MIDI_EOX */
-        if (*msg++ == MIDI_EOX) break;
-    }
-
-    /* we're finished sending full buffers, but there may
-     * be a partial one left.
-     */
-    if (shift != 0) bufx++; /* add partial message to buffer len */
-    if (bufx) { /* bufx is number of PmEvents to send from buffer */
-        return Pm_Write(stream, buffer, bufx);
-    }
-    return pmNoError;
-}
-
-
-
-PmError Pm_OpenInput(PortMidiStream** stream,
-                     PmDeviceID inputDevice,
-                     void *inputDriverInfo,
-                     long bufferSize,
-                     PmTimeProcPtr time_proc,
-                     void *time_info)
-{
-    PmInternal *midi;
-    PmError err = pmNoError;
-    pm_hosterror = FALSE;
-    *stream = NULL;
-
-    /* arg checking */
-    if (inputDevice < 0 || inputDevice >= pm_descriptor_index)
-        err = pmInvalidDeviceId;
-    else if (!descriptors[inputDevice].pub.input)
-        err =  pmBadPtr;
-    else if(descriptors[inputDevice].pub.opened)
-        err =  pmBadPtr;
-
-    if (err != pmNoError)
-        goto error_return;
-
-    /* create portMidi internal data */
-    midi = (PmInternal *) pm_alloc(sizeof(PmInternal));
-    *stream = midi;
-    if (!midi) {
-        err = pmInsufficientMemory;
-        goto error_return;
-    }
-    midi->device_id = inputDevice;
-    midi->write_flag = FALSE;
-    midi->time_proc = time_proc;
-    midi->time_info = time_info;
-    /* windows adds timestamps in the driver and these are more accurate than
-       using a time_proc, so do not automatically provide a time proc. Non-win
-       implementations may want to provide a default time_proc in their
-       system-specific midi_out_open() method.
-     */
-    if (bufferSize <= 0) bufferSize = 256; /* default buffer size */
-    else bufferSize++; /* buffer holds N-1 msgs, so increase request by 1 */
-    midi->buffer_len = bufferSize; /* portMidi input storage */
-    midi->buffer = (PmEvent *) pm_alloc(sizeof(PmEvent) * midi->buffer_len);
-    if (!midi->buffer) {
-        /* free portMidi data */
-        *stream = NULL;
-        pm_free(midi);
-        err = pmInsufficientMemory;
-        goto error_return;
-    }
-    midi->head = 0;
-    midi->tail = 0;
-    midi->latency = 0; /* not used */
-    midi->overflow = FALSE;
-    midi->flush = FALSE;
-    midi->sysex_in_progress = FALSE;
-    midi->sysex_message = 0;
-    midi->sysex_message_count = 0;
-    midi->filters = PM_FILT_ACTIVE;
-    midi->channel_mask = 0xFFFF;
-    midi->sync_time = 0;
-    midi->first_message = TRUE;
-    midi->dictionary = descriptors[inputDevice].dictionary;
-    descriptors[inputDevice].internalDescriptor = midi;
-    /* open system dependent input device */
-    err = (*midi->dictionary->open)(midi, inputDriverInfo);
-    if (err) {
-        *stream = NULL;
-        descriptors[inputDevice].internalDescriptor = NULL;
-        /* free portMidi data */
-        pm_free(midi->buffer);
-        pm_free(midi);
-    } else {
-        /* portMidi input open successful */
-        descriptors[inputDevice].pub.opened = TRUE;
-    }
-error_return:
-    return pm_errmsg(err);
-}
-
-
-PmError Pm_OpenOutput(PortMidiStream** stream,
-                      PmDeviceID outputDevice,
-                      void *outputDriverInfo,
-                      long bufferSize,
-                      PmTimeProcPtr time_proc,
-                      void *time_info,
-                      long latency)
-{
-    PmInternal *midi;
-    PmError err = pmNoError;
-    pm_hosterror = FALSE;
-    *stream =  NULL;
-
-    /* arg checking */
-    if (outputDevice < 0 || outputDevice >= pm_descriptor_index)
-        err = pmInvalidDeviceId;
-    else if (!descriptors[outputDevice].pub.output)
-        err = pmBadPtr;
-    else if (descriptors[outputDevice].pub.opened)
-        err = pmBadPtr;
-    if (err != pmNoError)
-        goto error_return;
-
-    /* create portMidi internal data */
-    midi = (PmInternal *) pm_alloc(sizeof(PmInternal));
-    *stream = midi;
-    if (!midi) {
-        err = pmInsufficientMemory;
-        goto error_return;
-    }
-    midi->device_id = outputDevice;
-    midi->write_flag = TRUE;
-    midi->time_proc = time_proc;
-    /* if latency > 0, we need a time reference. If none is provided,
-       use PortTime library */
-    if (time_proc == NULL && latency != 0) {
-        if (!Pt_Started())
-            Pt_Start(1, 0, 0);
-        /* time_get does not take a parameter, so coerce */
-        midi->time_proc = (PmTimeProcPtr) Pt_Time;
-    }
-    midi->time_info = time_info;
-    /* when stream used, this buffer allocated and used by
-        winmm_out_open; deleted by winmm_out_close */
-    midi->buffer_len = bufferSize;
-    midi->buffer = NULL;
-    midi->head = 0; /* unused by output */
-    midi->tail = 0; /* unused by output */
-    /* if latency zero, output immediate (timestamps ignored) */
-    /* if latency < 0, use 0 but don't return an error */
-    if (latency < 0) latency = 0;
-    midi->latency = latency;
-    midi->overflow = FALSE; /* not used */
-    midi->flush = FALSE; /* not used */
-    midi->sysex_in_progress = FALSE;
-    midi->sysex_message = 0; /* unused by output */
-    midi->sysex_message_count = 0; /* unused by output */
-    midi->filters = 0; /* not used for output */
-    midi->channel_mask = 0xFFFF; /* not used for output */
-    midi->sync_time = 0;
-    midi->first_message = TRUE;
-    midi->dictionary = descriptors[outputDevice].dictionary;
-    descriptors[outputDevice].internalDescriptor = midi;
-    /* open system dependent output device */
-    err = (*midi->dictionary->open)(midi, outputDriverInfo);
-    if (err) {
-        *stream = NULL;
-        descriptors[outputDevice].internalDescriptor = NULL;
-        /* free portMidi data */
-        pm_free(midi);
-    } else {
-        /* portMidi input open successful */
-        descriptors[outputDevice].pub.opened = TRUE;
-    }
-error_return:
-    return pm_errmsg(err);
-}
-
-PmError Pm_SetChannelMask(PortMidiStream *stream, int mask)
-{
-    PmInternal *midi = (PmInternal *) stream;
-    PmError err = pmNoError;
-
-    if (midi == NULL)
-        err = pmBadPtr;
-    else
-        midi->channel_mask = mask;
-
-    return pm_errmsg(err);
-}
-
-PmError Pm_SetFilter(PortMidiStream *stream, long filters)
-{
-    PmInternal *midi = (PmInternal *) stream;
-    PmError err = pmNoError;
-
-    /* arg checking */
-    if (midi == NULL)
-        err = pmBadPtr;
-    else if (!descriptors[midi->device_id].pub.opened)
-        err = pmBadPtr;
-    else
-        midi->filters = filters;
-    return pm_errmsg(err);
-}
-
-
-PmError Pm_Close( PortMidiStream *stream )
-{
-    PmInternal *midi = (PmInternal *) stream;
-    PmError err = pmNoError;
-
-    /* arg checking */
-    if (midi == NULL) /* midi must point to something */
-        err = pmBadPtr;
-    /* if it is an open device, the device_id will be valid */
-    else if (midi->device_id < 0 || midi->device_id >= pm_descriptor_index)
-        err = pmBadPtr;
-    /* and the device should be in the opened state */
-    else if (!descriptors[midi->device_id].pub.opened)
-        err = pmBadPtr;
-
-    if (err != pmNoError)
-        goto error_return;
-
-    /* close the device */
-    err = (*midi->dictionary->close)(midi);
-    /* even if an error occurred, continue with cleanup */
-    descriptors[midi->device_id].internalDescriptor = NULL;
-    descriptors[midi->device_id].pub.opened = FALSE;
-    pm_free(midi->buffer);
-    pm_free(midi);
-error_return:
-    return pm_errmsg(err);
-}
-
-
-PmError Pm_Abort( PortMidiStream* stream )
-{
-    PmInternal *midi = (PmInternal *) stream;
-    PmError err;
-    /* arg checking */
-    if (midi == NULL)
-        err = pmBadPtr;
-    if (!descriptors[midi->device_id].pub.output)
-        err = pmBadPtr;
-    if (!descriptors[midi->device_id].pub.opened)
-        err = pmBadPtr;
-    else
-        err = (*midi->dictionary->abort)(midi);
-    return pm_errmsg(err);
-}
-
-/* in win32 multimedia API (via callbacks) some of these functions used; assume never fail */
-long pm_next_time(PmInternal *midi) {
-
-    /* arg checking */
-    assert(midi != NULL);
-    assert(!Pm_HasHostError(midi));
-
-    return midi->buffer[midi->head].timestamp;
-}
-/* pm_channel_filtered returns non-zero if the channel mask is blocking the current channel */
-static int pm_channel_filtered(int status, int mask)
-{
-    if ((status & 0xF0) == 0xF0) /* 0xF? messages don't have a channel */
-        return 0;
-    return !(Pm_Channel(status & 0x0F) & mask);
-    /* it'd be easier to return 0 for filtered, 1 for allowed,
-       but it would different from the other filtering functions
-    */
-
-}
-/* The following two functions will checks to see if a MIDI message matches
-   the filtering criteria.  Since the sysex routines only want to filter realtime messages,
-   we need to have separate routines.
- */
-
-/* pm_realtime_filtered returns non-zero if the filter will kill the current message.
-   Note that only realtime messages are checked here.
- */
-static int pm_realtime_filtered(int status, long filters)
-{
-    return ((status == MIDI_ACTIVE) && (filters & PM_FILT_ACTIVE))
-            ||  ((status == MIDI_CLOCK) && (filters & PM_FILT_CLOCK))
-            ||  ((status == MIDI_START) && (filters & PM_FILT_PLAY))
-            ||  ((status == MIDI_STOP) && (filters & PM_FILT_PLAY))
-            ||  ((status == MIDI_CONTINUE) && (filters & PM_FILT_PLAY))
-            ||  ((status == MIDI_F9) && (filters & PM_FILT_F9))
-            ||  ((status == MIDI_FD) && (filters & PM_FILT_FD))
-            ||  ((status == MIDI_RESET) && (filters & PM_FILT_RESET))
-            ||  ((status == MIDI_MTC) && (filters & PM_FILT_MTC))
-            ||  ((status == MIDI_SONGPOS) && (filters & PM_FILT_SONG_POSITION))
-            ||  ((status == MIDI_SONGSEL) && (filters & PM_FILT_SONG_SELECT))
-            ||  ((status == MIDI_TUNE) && (filters & PM_FILT_TUNE));
-}
-/* pm_status_filtered returns non-zero if a filter will kill the current message, based on status.
-   Note that sysex and real time are not checked.  It is up to the subsystem (winmm, core midi, alsa)
-   to filter sysex, as it is handled more easily and efficiently at that level.
-   Realtime message are filtered in pm_realtime_filtered.
- */
-
-static int pm_status_filtered(int status, long filters)
-{
-    status &= 0xF0; /* remove channel information */
-    return  ((status == MIDI_NOTE_ON) && (filters & PM_FILT_NOTE))
-            ||  ((status == MIDI_NOTE_OFF) && (filters & PM_FILT_NOTE))
-            ||  ((status == MIDI_CHANNEL_AT) && (filters & PM_FILT_CHANNEL_AFTERTOUCH))
-            ||  ((status == MIDI_POLY_AT) && (filters & PM_FILT_POLY_AFTERTOUCH))
-            ||  ((status == MIDI_PROGRAM) && (filters & PM_FILT_PROGRAM))
-            ||  ((status == MIDI_CONTROL) && (filters & PM_FILT_CONTROL))
-            ||  ((status == MIDI_PITCHBEND) && (filters & PM_FILT_PITCHBEND));
-
-}
-
-/* pm_read_short and pm_read_byte
-   are the interface between system-dependent MIDI input handlers
-   and the system-independent PortMIDI code.
-   The input handler MUST obey these rules:
-   1) all short input messages must be sent to pm_read_short, which
-      enqueues them to a FIFO for the application.
-   2) eash sysex byte should be reported by calling pm_read_byte
-      (which sets midi->sysex_in_progress). After the eox byte,
-      pm_read_byte will clear sysex_in_progress and midi->flush
-   (Note that the overflow flag is managed by pm_read_short
-    and Pm_Read, so the supplier should not read or write it.)
- */
-
-/* pm_read_short is the place where all input messages arrive from
-   system-dependent code such as pmwinmm.c. Here, the messages
-   are entered into the PortMidi input buffer.
- */
-
- /* Algorithnm:
-    if overflow or flush, return
-    ATOMIC:
-        enqueue data
-        if buffer overflow, set overflow
-        if buffer overflow and sysex_in_progress, set flush
-  */
-void pm_read_short(PmInternal *midi, PmEvent *event)
-{
-    long tail;
-    int status;
-    /* arg checking */
-    assert(midi != NULL);
-    assert(!Pm_HasHostError(midi));
-    /* midi filtering is applied here */
-    status = Pm_MessageStatus(event->message);
-    if (!pm_status_filtered(status, midi->filters)
-        && !pm_realtime_filtered(status, midi->filters)
-        && !pm_channel_filtered(status, midi->channel_mask)) {
-        /* if sysex is in progress and we get a status byte, it had
-           better be a realtime message or the starting SYSEX byte;
-           otherwise, we exit the sysex_in_progress state
-         */
-        if (midi->sysex_in_progress && (status & MIDI_STATUS_MASK) &&
-            !is_real_time(status) && status != MIDI_SYSEX ) {
-            midi->sysex_in_progress = FALSE;
-            midi->flush = FALSE;
-        }
-
-        /* don't try to do anything more in an overflow state */
-        if (midi->overflow || midi->flush) return;
-
-        /* insert the message */
-        tail = midi->tail;
-        midi->buffer[tail++] = *event;
-        if (tail == midi->buffer_len) tail = 0;
-        if (tail == midi->head || midi->overflow) {
-             midi->overflow = TRUE;
-            if (midi->sysex_in_progress) midi->flush = TRUE;
-            /* drop the rest of the message, this must be cleared
-               by caller when EOX is received */
-               return;
-        }
-        midi->tail = tail; /* complete the write */
-    }
-}
-
-
-void pm_flush_sysex(PmInternal *midi, PmTimestamp timestamp)
-{
-    PmEvent event;
-
-    /* there may be nothing in the buffer */
-    if (midi->sysex_message_count == 0) return; /* nothing to flush */
-
-    event.message = midi->sysex_message;
-    event.timestamp = timestamp;
-    pm_read_short(midi, &event);
-    midi->sysex_message_count = 0;
-    midi->sysex_message = 0;
-}
-
-
-void pm_read_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp)
-{
-    assert(midi);
-    assert(!Pm_HasHostError(midi));
-    /* here is the logic for controlling sysex_in_progress */
-    if (midi->sysex_in_progress) {
-        if (byte == MIDI_EOX) midi->sysex_in_progress = FALSE;
-        else if (byte == MIDI_SYSEX) {
-            /* problem: need to terminate the current sysex and start
-               a new one
-             */
-            pm_flush_sysex(midi, timestamp);
-        }
-    } else if (byte == MIDI_SYSEX) {
-        midi->sysex_in_progress = TRUE;
-    } else {
-        /* error: we're getting data bytes or EOX but we're no sysex is
-           in progress. Drop the data. (Would it be better to report an
-           error? Is this a host error or a pmBadData error? Is this
-           ever possible?
-         */
-#ifdef DEBUG
-        printf("PortMidi debug msg: unexpected sysex data or EOX\n");
-#endif
-        return;
-    }
-
-    if (pm_realtime_filtered(byte, midi->filters))
-        return;
-    /* this awkward expression places the bytes in increasingly higher-
-       order bytes of the long message */
-    midi->sysex_message |= (byte << (8 * midi->sysex_message_count++));
-    if (midi->sysex_message_count == 4 || !midi->sysex_in_progress) {
-        pm_flush_sysex(midi, timestamp);
-        if (!midi->sysex_in_progress) midi->flush = FALSE;
-    }
-}
-
-
-int pm_queue_full(PmInternal *midi)
-{
-    long tail;
-
-    /* arg checking */
-    assert(midi != NULL);
-    assert(!Pm_HasHostError(midi));
-
-    tail = midi->tail + 1;
-    if (tail == midi->buffer_len) tail = 0;
-    return tail == midi->head;
-}
-
diff --git a/portmidi/pm_common/portmidi.h b/portmidi/pm_common/portmidi.h
deleted file mode 100644
index 8c9c04c2a..000000000
--- a/portmidi/pm_common/portmidi.h
+++ /dev/null
@@ -1,692 +0,0 @@
-#ifndef PORT_MIDI_H
-#define PORT_MIDI_H
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/*
- * PortMidi Portable Real-Time MIDI Library
- * PortMidi API Header File
- * Latest version available at: http://www.cs.cmu.edu/~music/portmidi/
- *
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- * Copyright (c) 2001 Roger B. Dannenberg
- *
- * 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.
- *
- */
-
-/* CHANGELOG FOR PORTMIDI
- *
- * 15Nov04 Ben Allison
- *  - sysex output now uses one buffer/message and reallocates buffer
- *  -    if needed
- *  - filters expanded for many message types and channels
- *  - detailed changes are as follows:
- *  ------------- in pmwinmm.c --------------
- *  - new #define symbol: OUTPUT_BYTES_PER_BUFFER
- *  - change SYSEX_BYTES_PER_BUFFER to 1024
- *  - added MIDIHDR_BUFFER_LENGTH(x) to correctly count midihdr buffer length
- *  - change MIDIHDR_SIZE(x) to (MIDIHDR_BUFFER_LENGTH(x) + sizeof(MIDIHDR))
- *  - change allocate_buffer to use new MIDIHDR_BUFFER_LENGTH macro
- *  - new macros for MIDIHDR_SYSEX_SIZE and MIDIHDR_SYSEX_BUFFER_LENGTH 
- *  -    similar to above, but counts appropriately for sysex messages
- *  - added the following members to midiwinmm_struct for sysex data:
- *  -    LPMIDIHDR *sysex_buffers;   ** pool of buffers for sysex data **
- *  -    int num_sysex_buffers;      ** how many sysex buffers **
- *  -    int next_sysex_buffer;      ** index of next sysexbuffer to send **
- *  -    HANDLE sysex_buffer_signal; ** to wait for free sysex buffer **
- *  - duplicated allocate_buffer, alocate_buffers and get_free_output_buffer 
- *  -    into equivalent sysex_buffer form
- *  - changed winmm_in_open to initialize new midiwinmm_struct members and 
- *  -    to use the new allocate_sysex_buffer() function instead of 
- *  -    allocate_buffer()
- *  - changed winmm_out_open to initialize new members, create sysex buffer 
- *  -    signal, and allocate 2 sysex buffers
- *  - changed winmm_out_delete to free sysex buffers and shut down the sysex
- *  -    buffer signal
- *  - create new function resize_sysex_buffer which resizes m->hdr to the 
- *  -    passed size, and corrects the midiwinmm_struct accordingly.
- *  - changed winmm_write_byte to use new resize_sysex_buffer function,
- *  -    if resize fails, write current buffer to output and continue
- *  - changed winmm_out_callback to use buffer_signal or sysex_buffer_signal
- *  -    depending on which buffer was finished
- *  ------------- in portmidi.h --------------
- *  - added pmBufferMaxSize to PmError to indicate that the buffer would be
- *  -    too large for the underlying API
- *  - added additional filters
- *  - added prototype, documentation, and helper macro for Pm_SetChannelMask
- *  ------------- in portmidi.c --------------
- *  - added pm_status_filtered() and pm_realtime_filtered() functions to
- *       separate filtering logic from buffer logic in pm_read_short
- *  - added Pm_SetChannelMask function
- *  - added pm_channel_filtered() function
- *  ------------- in pminternal.h --------------
- *  - added member to PortMidiStream for channel mask
- *
- * 25May04 RBD
- *  - removed support for MIDI THRU
- *  - moved filtering from Pm_Read to pm_enqueue to avoid buffer ovfl
- *  - extensive work on Mac OS X port, especially sysex and error handling
- *
- * 18May04 RBD
- *  - removed side-effects from assert() calls. Now you can disable assert().
- *  - no longer check pm_hosterror everywhere, fixing a bug where an open
- *    failure could cause a write not to work on a previously opened port
- *    until you call Pm_GetHostErrorText().
- * 16May04 RBD and Chris Roberts
- *  - Some documentation wordsmithing in portmidi.h
- *  - Dynamically allocate port descriptor structures
- *  - Fixed parameter error in midiInPrepareBuffer and midiInAddBuffer.
- *
- * 09Oct03 RBD
- *  - Changed Thru handling. Now the client does all the work and the client
- *    must poll or read to keep thru messages flowing.
- *
- * 31May03 RBD
- *  - Fixed various bugs.
- *  - Added linux ALSA support with help from Clemens Ladisch
- *  - Added Mac OS X support, implemented by Jon Parise, updated and 
- *       integrated by Andrew Zeldis and Zico Kolter
- *  - Added latency program to build histogram of system latency using PortTime.
- *
- * 30Jun02 RBD Extensive rewrite of sysex handling. It works now.
- *             Extensive reworking of error reporting and error text -- no
- *             longer use dictionary call to delete data; instead, Pm_Open
- *             and Pm_Close clean up before returning an error code, and
- *             error text is saved in a system-independent location.
- *             Wrote sysex.c to test sysex message handling.
- *
- * 15Jun02 BCT changes:
- *  - Added pmHostError text handling.
- *  - For robustness, check PortMidi stream args not NULL.
- *  - Re-C-ANSI-fied code (changed many C++ comments to C style)
- *  - Reorganized code in pmwinmm according to input/output functionality (made
- *    cleanup handling easier to reason about)
- *  - Fixed Pm_Write calls (portmidi.h says these should not return length but Pm_Error)
- *  - Cleaned up memory handling (now system specific data deleted via dictionary
- *    call in PortMidi, allows client to query host errors).
- *  - Added explicit asserts to verify various aspects of pmwinmm implementation behaves as
- *    logic implies it should. Specifically: verified callback routines not reentrant and
- *    all verified status for all unchecked Win32 MMedia API calls perform successfully
- *  - Moved portmidi initialization and clean-up routines into DLL to fix Win32 MMedia API
- *    bug (i.e. if devices not explicitly closed, must reboot to debug application further).
- *    With this change, clients no longer need explicitly call Pm_Initialize, Pm_Terminate, or
- *    explicitly Pm_Close open devices when using WinMM version of PortMidi.
- *
- * 23Jan02 RBD Fixed bug in pmwinmm.c thru handling
- *
- * 21Jan02 RBD Added tests in Pm_OpenInput() and Pm_OpenOutput() to prevent
- *               opening an input as output and vice versa.
- *             Added comments and documentation.
- *             Implemented Pm_Terminate().
- *
- *
- * IMPORTANT INFORMATION ABOUT A WIN32 BUG:
- *
- *    Windows apparently has a serious midi bug -- if you do not close ports, Windows
- *    may crash. PortMidi tries to protect against this by using a DLL to clean up.
- *
- *    If client exits for example with:
- *      i)  assert
- *      ii) Ctrl^c,
- *    then DLL clean-up routine called. However, when client does something
- *    really bad (e.g. assigns value to NULL pointer) then DLL CLEANUP ROUTINE
- *    NEVER RUNS! In this state, if you wait around long enough, you will
- *    probably get the blue screen of death. Can also go into Pview and there will
- *    exist zombie process that you can't kill.
- *
- * NOTES ON HOST ERROR REPORTING:
- *
- *    PortMidi errors (of type PmError) are generic, system-independent errors.
- *    When an error does not map to one of the more specific PmErrors, the
- *    catch-all code pmHostError is returned. This means that PortMidi has
- *    retained a more specific system-dependent error code. The caller can
- *    get more information by calling Pm_HasHostError() to test if there is
- *    a pending host error, and Pm_GetHostErrorText() to get a text string
- *    describing the error. Host errors are reported on a per-device basis
- *    because only after you open a device does PortMidi have a place to
- *    record the host error code. I.e. only
- *    those routines that receive a (PortMidiStream *) argument check and
- *    report errors. One exception to this is that Pm_OpenInput() and
- *    Pm_OpenOutput() can report errors even though when an error occurs,
- *    there is no PortMidiStream* to hold the error. Fortunately, both
- *    of these functions return any error immediately, so we do not really
- *    need per-device error memory. Instead, any host error code is stored
- *    in a global, pmHostError is returned, and the user can call
- *    Pm_GetHostErrorText() to get the error message (and the invalid stream
- *    parameter will be ignored.) The functions
- *    pm_init and pm_term do not fail or raise
- *    errors. The job of pm_init is to locate all available devices so that
- *    the caller can get information via PmDeviceInfo(). If an error occurs,
- *    the device is simply not listed as available.
- *
- *    Host errors come in two flavors:
- *      a) host error
- *      b) host error during callback
- *    These can occur w/midi input or output devices. (b) can only happen
- *    asynchronously (during callback routines), whereas (a) only occurs while
- *    synchronously running PortMidi and any resulting system dependent calls
- *
- *    Host-error reporting relies on following assumptions:
- *      1) PortMidi routines won't allow system dependent routines to be
- *         called when args are bogus.
- *         Thus, in pmwinmm.c it is safe to assume:
- *          - stream ptr valid
- *          - currently not operating in "has host error" state
- *      2) Host-error reporting relies on a staged delivery of error messages.
- *         When a host error occurs, the error code is saved with the stream.
- *         The error is reported as a return code from the next operation on
- *         the stream. This could be immediately if the error is synchronous,
- *         or delayed if the error is an asynchronous callback problem. In
- *         any case, when pmHostError is returned, the error is copied to
- *         a global, pm_hosterror and the error code stored with the stream
- *         is cleared. If the user chooses to inquire about the error using
- *         Pm_GetHostErrorText(), the error will be reported as text. If the
- *         user ignores the error and makes another call on the stream, the
- *         call will proceed because the error code associated with the stream
- *         has been cleared.
- *
- */
-
-#ifndef FALSE
-    #define FALSE 0
-#endif
-#ifndef TRUE
-    #define TRUE 1
-#endif
-
-/* default size of buffers for sysex transmission: */
-#define PM_DEFAULT_SYSEX_BUFFER_SIZE 1024
-
-
-typedef enum {
-    pmNoError = 0,
-    pmHostError = -10000,
-    pmInvalidDeviceId, /* out of range or output device when input is requested or vice versa */
-    pmInsufficientMemory,
-    pmBufferTooSmall,
-    pmBufferOverflow,
-    pmBadPtr,
-    pmBadData, /* illegal midi data, e.g. missing EOX */
-    pmInternalError,
-    pmBufferMaxSize, /* buffer is already as large as it can be */
-} PmError;
-
-/*
-    Pm_Initialize() is the library initialisation function - call this before
-    using the library.
-*/
-
-PmError Pm_Initialize( void );
-
-/*
-    Pm_Terminate() is the library termination function - call this after
-    using the library.
-*/
-
-PmError Pm_Terminate( void );
-
-/*  A single PortMidiStream is a descriptor for an open MIDI device.
-*/
-typedef void PortMidiStream;
-#define PmStream PortMidiStream
-
-/*
-    Test whether stream has a pending host error. Normally, the client finds
-	out about errors through returned error codes, but some errors can occur
-	asynchronously where the client does not
-	explicitly call a function, and therefore cannot receive an error code.
-	The client can test for a pending error using Pm_HasHostError(). If true,
-	the error can be accessed and cleared by calling Pm_GetErrorText(). The
-	client does not need to call Pm_HasHostError(). Any pending error will be
-	reported the next time the client performs an explicit function call on
-	the stream, e.g. an input or output operation.
-*/
-int Pm_HasHostError( PortMidiStream * stream );
-
-
-/*  Translate portmidi error number into human readable message.
-    These strings are constants (set at compile time) so client has
-	no need to allocate storage
-*/
-const char *Pm_GetErrorText( PmError errnum );
-
-/*  Translate portmidi host error into human readable message.
-    These strings are computed at run time, so client has to allocate storage.
-	After this routine executes, the host error is cleared.
-*/
-void Pm_GetHostErrorText(char * msg, unsigned int len);
-
-#define HDRLENGTH 50
-#define PM_HOST_ERROR_MSG_LEN 256u /* any host error msg will occupy less
-                                      than this number of characters */
-
-/*
-    Device enumeration mechanism.
-
-    Device ids range from 0 to Pm_CountDevices()-1.
-
-*/
-typedef int PmDeviceID;
-#define pmNoDevice -1
-typedef struct {
-    int structVersion;
-    const char *interf; /* underlying MIDI API, e.g. MMSystem or DirectX */
-    const char *name;   /* device name, e.g. USB MidiSport 1x1 */
-    int input; /* true iff input is available */
-    int output; /* true iff output is available */
-    int opened; /* used by generic PortMidi code to do error checking on arguments */
-
-} PmDeviceInfo;
-
-
-int Pm_CountDevices( void );
-/*
-    Pm_GetDefaultInputDeviceID(), Pm_GetDefaultOutputDeviceID()
-
-    Return the default device ID or pmNoDevice if there are no devices.
-    The result can be passed to Pm_OpenMidi().
-
-    On the PC, the user can specify a default device by
-    setting an environment variable. For example, to use device #1.
-
-        set PM_RECOMMENDED_OUTPUT_DEVICE=1
-
-    The user should first determine the available device ID by using
-    the supplied application "testin" or "testout".
-
-    In general, the registry is a better place for this kind of info,
-    and with USB devices that can come and go, using integers is not
-    very reliable for device identification. Under Windows, if
-    PM_RECOMMENDED_OUTPUT_DEVICE (or PM_RECOMMENDED_INPUT_DEVICE) is
-    *NOT* found in the environment, then the default device is obtained
-    by looking for a string in the registry under:
-        HKEY_LOCAL_MACHINE/SOFTWARE/PortMidi/Recommended_Input_Device
-    and HKEY_LOCAL_MACHINE/SOFTWARE/PortMidi/Recommended_Output_Device
-    for a string. The number of the first device with a substring that
-    matches the string exactly is returned. For example, if the string
-    in the registry is "USB", and device 1 is named
-    "In USB MidiSport 1x1", then that will be the default
-    input because it contains the string "USB".
-
-    In addition to the name, PmDeviceInfo has the member "interf", which
-    is the interface name. (The "interface" is the underlying software
-	system or API used by PortMidi to access devices. Examples are
-	MMSystem, DirectX (not implemented), ALSA, OSS (not implemented), etc.)
-	At present, the only Win32 interface is "MMSystem", the only Linux
-	interface is "ALSA", and the only Max OS X interface is "CoreMIDI".
-    To specify both the interface and the device name in the registry,
-    separate the two with a comma and a space, e.g.:
-        MMSystem, In USB MidiSport 1x1
-    In this case, the string before the comma must be a substring of
-    the "interf" string, and the string after the space must be a
-    substring of the "name" name string in order to match the device.
-
-    Note: in the current release, the default is simply the first device
-	(the input or output device with the lowest PmDeviceID).
-*/
-PmDeviceID Pm_GetDefaultInputDeviceID( void );
-PmDeviceID Pm_GetDefaultOutputDeviceID( void );
-
-/*
-    PmTimestamp is used to represent a millisecond clock with arbitrary
-    start time. The type is used for all MIDI timestampes and clocks.
-*/
-typedef long PmTimestamp;
-typedef PmTimestamp (*PmTimeProcPtr)(void *time_info);
-
-/* TRUE if t1 before t2 */
-#define PmBefore(t1,t2) ((t1-t2) < 0)
-
-/*
-    Pm_GetDeviceInfo() returns a pointer to a PmDeviceInfo 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 PortMidi implementation and must
-    not be manipulated or freed. The pointer is guaranteed to be valid
-    between calls to Pm_Initialize() and Pm_Terminate().
-*/
-const PmDeviceInfo* Pm_GetDeviceInfo( PmDeviceID id );
-
-/*
-    Pm_OpenInput() and Pm_OpenOutput() open devices.
-
-    stream is the address of a PortMidiStream pointer which will receive
-    a pointer to the newly opened stream.
-
-    inputDevice is the id of the device used for input (see PmDeviceID above).
-
-    inputDriverInfo is a pointer to an optional driver specific data structure
-    containing additional information for device setup or handle 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 PmDeviceID above.)
-
-    outputDriverInfo is a pointer to an optional driver specific data structure
-    containing additional information for device setup or handle processing.
-    outputDriverInfo is never required for correct operation. If not used
-    outputDriverInfo should be NULL.
-
-    For input, the buffersize specifies the number of input events to be
-    buffered waiting to be read using Pm_Read(). For output, buffersize
-    specifies the number of output events to be buffered waiting for output.
-    (In some cases -- see below -- PortMidi does not buffer output at all
-	and merely passes data to a lower-level API, in which case buffersize
-	is ignored.)
-
-    latency is the delay in milliseconds applied to timestamps to determine
-    when the output should actually occur. (If latency is < 0, 0 is assumed.)
-    If latency is zero, timestamps are ignored and all output is delivered
-    immediately. If latency is greater than zero, output is delayed until
-    the message timestamp plus the latency. (NOTE: time is measured relative
-    to the time source indicated by time_proc. Timestamps are absolute, not
-    relative delays or offsets.) In some cases, PortMidi can obtain
-	better timing than your application by passing timestamps along to the
-	device driver or hardware. Latency may also help you to synchronize midi
-	data to audio data by matching midi latency to the audio buffer latency.
-
-    time_proc is a pointer to a procedure that returns time in milliseconds. It
-    may be NULL, in which case a default millisecond timebase (PortTime) is
-    used. If the application wants to use PortTime, it should start the timer
-    (call Pt_Start) before calling Pm_OpenInput or Pm_OpenOutput. If the
-    application tries to start the timer *after* Pm_OpenInput or Pm_OpenOutput,
-    it may get a ptAlreadyStarted error from Pt_Start, and the application's
-    preferred time resolution and callback function will be ignored.
-    time_proc result values are appended to incoming MIDI data, and time_proc
-    times are used to schedule outgoing MIDI data (when latency is non-zero).
-
-    time_info is a pointer passed to time_proc.
-
-    return value:
-    Upon success Pm_Open() returns PmNoError and places a pointer to a
-    valid PortMidiStream in the stream argument.
-    If a call to Pm_Open() fails a nonzero error code is returned (see
-    PMError above) and the value of port is invalid.
-
-    Any stream that is successfully opened should eventually be closed
-	by calling Pm_Close().
-
-*/
-PmError Pm_OpenInput( PortMidiStream** stream,
-                PmDeviceID inputDevice,
-                void *inputDriverInfo,
-                long bufferSize,
-                PmTimeProcPtr time_proc,
-                void *time_info );
-
-PmError Pm_OpenOutput( PortMidiStream** stream,
-                PmDeviceID outputDevice,
-                void *outputDriverInfo,
-                long bufferSize,
-                PmTimeProcPtr time_proc,
-                void *time_info,
-                long latency );
-
-/*
-    Pm_SetFilter() sets filters on an open input stream to drop selected
-    input types. By default, only active sensing messages are filtered.
-    To prohibit, say, active sensing and sysex messages, call
-    Pm_SetFilter(stream, PM_FILT_ACTIVE | PM_FILT_SYSEX);
-
-    Filtering is useful when midi routing or midi thru functionality is being
-    provided by the user application.
-    For example, you may want to exclude timing messages (clock, MTC, start/stop/continue),
-    while allowing note-related messages to pass.
-    Or you may be using a sequencer or drum-machine for MIDI clock information but want to
-    exclude any notes it may play.
- */
-
-/* filter active sensing messages (0xFE): */
-#define PM_FILT_ACTIVE 0x1
-/* filter system exclusive messages (0xF0): */
-#define PM_FILT_SYSEX 0x2
-/* filter clock messages (0xF8 only, does not filter clock start, etc.): */
-#define PM_FILT_CLOCK 0x4
-/* filter play messages (start 0xFA, stop 0xFC, continue 0xFB) */
-#define PM_FILT_PLAY 0x8
-/* filter undefined F9 messages (some equipment uses this as a 10ms 'tick') */
-#define PM_FILT_F9 0x10
-#define PM_FILT_TICK PM_FILT_F9
-/* filter undefined FD messages */
-#define PM_FILT_FD 0x20
-/* filter undefined real-time messages */
-#define PM_FILT_UNDEFINED (PM_FILT_F9 | PM_FILT_FD)
-/* filter reset messages (0xFF) */
-#define PM_FILT_RESET 0x40
-/* filter all real-time messages */
-#define PM_FILT_REALTIME (PM_FILT_ACTIVE | PM_FILT_SYSEX | PM_FILT_CLOCK | PM_FILT_PLAY | PM_FILT_UNDEFINED | PM_FILT_RESET)
-/* filter note-on and note-off (0x90-0x9F and 0x80-0x8F */
-#define PM_FILT_NOTE 0x80
-/* filter channel aftertouch (most midi controllers use this) (0xD0-0xDF)*/
-#define PM_FILT_CHANNEL_AFTERTOUCH 0x100
-/* per-note aftertouch (Ensoniq holds a patent on generating this on keyboards until June 2006) (0xA0-0xAF) */
-#define PM_FILT_POLY_AFTERTOUCH 0x200
-/* filter both channel and poly aftertouch */
-#define PM_FILT_AFTERTOUCH (PM_FILT_CHANNEL_AFTERTOUCH | PM_FILT_POLY_AFTERTOUCH)
-/* Program changes (0xC0-0xCF) */
-#define PM_FILT_PROGRAM 0x400
-/* Control Changes (CC's) (0xB0-0xBF)*/
-#define PM_FILT_CONTROL 0x800
-/* Pitch Bender (0xE0-0xEF*/
-#define PM_FILT_PITCHBEND 0x1000
-/* MIDI Time Code (0xF1)*/
-#define PM_FILT_MTC 0x2000
-/* Song Position (0xF2) */
-#define PM_FILT_SONG_POSITION 0x4000
-/* Song Select (0xF3)*/
-#define PM_FILT_SONG_SELECT 0x8000
-/* Tuning request (0xF6)*/
-#define PM_FILT_TUNE 0x10000
-/* All System Common messages (mtc, song position, song select, tune request) */
-#define PM_FILT_SYSTEMCOMMON (PM_FILT_MTC | PM_FILT_SONG_POSITION | PM_FILT_SONG_SELECT | PM_FILT_TUNE)
-
-
-PmError Pm_SetFilter( PortMidiStream* stream, long filters );
-
-
-/*
-    Pm_SetChannelMask() filters incoming messages based on channel.
-    The mask is a 16-bit bitfield corresponding to appropriate channels
-    The Pm_Channel macro can assist in calling this function.
-    i.e. to set receive only input on channel 1, call with
-    Pm_SetChannelMask(Pm_Channel(1));
-    Multiple channels should be OR'd together, like
-    Pm_SetChannelMask(Pm_Channel(10) | Pm_Channel(11))
-
-    All channels are allowed by default
-*/
-#define Pm_Channel(channel) (1<<(channel))
-
-PmError Pm_SetChannelMask(PortMidiStream *stream, int mask);
-
-/*
-    Pm_Abort() terminates outgoing messages immediately
-    The caller should immediately close the output port;
-    this call may result in transmission of a partial midi message.
-    There is no abort for Midi input because the user can simply
-    ignore messages in the buffer and close an input device at
-    any time.
- */
-PmError Pm_Abort( PortMidiStream* stream );
-
-/*
-    Pm_Close() closes a midi stream, flushing any pending buffers.
-	(PortMidi attempts to close open streams when the application
-	exits -- this is particularly difficult under Windows.)
-*/
-PmError Pm_Close( PortMidiStream* stream );
-
-/*
-    Pm_Message() encodes a short Midi message into a long word. If data1
-    and/or data2 are not present, use zero.
-
-    Pm_MessageStatus(), Pm_MessageData1(), and
-    Pm_MessageData2() extract fields from a long-encoded midi message.
-*/
-#define Pm_Message(status, data1, data2) \
-         ((((data2) << 16) & 0xFF0000) | \
-          (((data1) << 8) & 0xFF00) | \
-          ((status) & 0xFF))
-#define Pm_MessageStatus(msg) ((msg) & 0xFF)
-#define Pm_MessageData1(msg) (((msg) >> 8) & 0xFF)
-#define Pm_MessageData2(msg) (((msg) >> 16) & 0xFF)
-
-/* All midi data comes in the form of PmEvent structures. A sysex
-   message is encoded as a sequence of PmEvent structures, with each
-   structure carrying 4 bytes of the message, i.e. only the first
-   PmEvent carries the status byte.
-
-   Note that MIDI allows nested messages: the so-called "real-time" MIDI
-   messages can be inserted into the MIDI byte stream at any location,
-   including within a sysex message. MIDI real-time messages are one-byte
-   messages used mainly for timing (see the MIDI spec). PortMidi retains
-   the order of non-real-time MIDI messages on both input and output, but
-   it does not specify exactly how real-time messages are processed. This
-   is particulary problematic for MIDI input, because the input parser
-   must either prepare to buffer an unlimited number of sysex message
-   bytes or to buffer an unlimited number of real-time messages that
-   arrive embedded in a long sysex message. To simplify things, the input
-   parser is allowed to pass real-time MIDI messages embedded within a
-   sysex message, and it is up to the client to detect, process, and
-   remove these messages as they arrive.
-
-   When receiving sysex messages, the sysex message is terminated
-   by either an EOX status byte (anywhere in the 4 byte messages) or
-   by a non-real-time status byte in the low order byte of the message.
-   If you get a non-real-time status byte but there was no EOX byte, it
-   means the sysex message was somehow truncated. This is not
-   considered an error; e.g., a missing EOX can result from the user
-   disconnecting a MIDI cable during sysex transmission.
-
-   A real-time message can occur within a sysex message. A real-time
-   message will always occupy a full PmEvent with the status byte in
-   the low-order byte of the PmEvent message field. (This implies that
-   the byte-order of sysex bytes and real-time message bytes may not
-   be preserved -- for example, if a real-time message arrives after
-   3 bytes of a sysex message, the real-time message will be delivered
-   first. The first word of the sysex message will be delivered only
-   after the 4th byte arrives, filling the 4-byte PmEvent message field.
-
-   The timestamp field is observed when the output port is opened with
-   a non-zero latency. A timestamp of zero means "use the current time",
-   which in turn means to deliver the message with a delay of
-   latency (the latency parameter used when opening the output port.)
-   Do not expect PortMidi to sort data according to timestamps --
-   messages should be sent in the correct order, and timestamps MUST
-   be non-decreasing.
-
-   A sysex message will generally fill many PmEvent structures. On
-   output to a PortMidiStream with non-zero latency, the first timestamp
-   on sysex message data will determine the time to begin sending the
-   message. PortMidi implementations may ignore timestamps for the
-   remainder of the sysex message.
-
-   On input, the timestamp ideally denotes the arrival time of the
-   status byte of the message. The first timestamp on sysex message
-   data will be valid. Subsequent timestamps may denote
-   when message bytes were actually received, or they may be simply
-   copies of the first timestamp.
-
-   Timestamps for nested messages: If a real-time message arrives in
-   the middle of some other message, it is enqueued immediately with
-   the timestamp corresponding to its arrival time. The interrupted
-   non-real-time message or 4-byte packet of sysex data will be enqueued
-   later. The timestamp of interrupted data will be equal to that of
-   the interrupting real-time message to insure that timestamps are
-   non-decreasing.
- */
-typedef long PmMessage;
-typedef struct {
-    PmMessage      message;
-    PmTimestamp    timestamp;
-} PmEvent;
-
-/*
-    Pm_Read() retrieves midi data into a buffer, and returns the number
-    of events read. Result is a non-negative number unless an error occurs,
-    in which case a PmError value will be returned.
-
-    Buffer Overflow
-
-    The problem: if an input overflow occurs, data will be lost, ultimately
-    because there is no flow control all the way back to the data source.
-    When data is lost, the receiver should be notified and some sort of
-    graceful recovery should take place, e.g. you shouldn't resume receiving
-    in the middle of a long sysex message.
-
-    With a lock-free fifo, which is pretty much what we're stuck with to
-    enable portability to the Mac, it's tricky for the producer and consumer
-    to synchronously reset the buffer and resume normal operation.
-
-    Solution: the buffer managed by PortMidi will be flushed when an overflow
-    occurs. The consumer (Pm_Read()) gets an error message (pmBufferOverflow)
-    and ordinary processing resumes as soon as a new message arrives. The
-    remainder of a partial sysex message is not considered to be a "new
-    message" and will be flushed as well.
-
-*/
-PmError Pm_Read( PortMidiStream *stream, PmEvent *buffer, long length );
-
-/*
-    Pm_Poll() tests whether input is available,
-    returning TRUE, FALSE, or an error value.
-*/
-PmError Pm_Poll( PortMidiStream *stream);
-
-/*
-    Pm_Write() writes midi data from a buffer. This may contain:
-        - short messages
-    or
-        - sysex messages that are converted into a sequence of PmEvent
-          structures, e.g. sending data from a file or forwarding them
-          from midi input.
-
-    Use Pm_WriteSysEx() to write a sysex message stored as a contiguous
-    array of bytes.
-
-    Sysex data may contain embedded real-time messages.
-*/
-PmError Pm_Write( PortMidiStream *stream, PmEvent *buffer, long length );
-
-/*
-    Pm_WriteShort() writes a timestamped non-system-exclusive midi message.
-	Messages are delivered in order as received, and timestamps must be
-	non-decreasing. (But timestamps are ignored if the stream was opened
-	with latency = 0.)
-*/
-PmError Pm_WriteShort( PortMidiStream *stream, PmTimestamp when, long msg);
-
-/*
-    Pm_WriteSysEx() writes a timestamped system-exclusive midi message.
-*/
-PmError Pm_WriteSysEx( PortMidiStream *stream, PmTimestamp when, unsigned char *msg);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PORT_MIDI_H */
diff --git a/portmidi/pm_linux/README_LINUX.txt b/portmidi/pm_linux/README_LINUX.txt
deleted file mode 100644
index e8a4332f0..000000000
--- a/portmidi/pm_linux/README_LINUX.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-README_LINUX.txt for PortMidi
-Roger Dannenberg
-8 June 2004
-
-To make PortMidi and PortTime, go back up to the portmidi
-directory and type make.
-
-The Makefile will build all test programs and the portmidi
-library. You may want to modify the Makefile to remove the
-PM_CHECK_ERRORS definition. For experimental software,
-especially programs running from the command line, we 
-recommend using PM_CHECK_ERRORS -- it will terminate your
-program and print a helpful message if any PortMidi 
-function returns an error code.
-
-If you do not compile with PM_CHECK_ERRORS, you should 
-check for errors yourself.
-
-This code has not been carefully tested; however, 
-all test programs in pm_test seem to run properly.
-
-CHANGELOG
-
-08-Jun-2004 Roger B. Dannenberg
-      Updated code to use new system abstraction.
-
-12-Apr-2003 Roger B. Dannenberg
-      Fixed pm_test/test.c to filter clocks and active messages.
-      Integrated changes from Clemens Ladisch:
-          cleaned up pmlinuxalsa.c
-          record timestamp on sysex input
-          deallocate some resources previously left open
diff --git a/portmidi/pm_linux/pmlinux.c b/portmidi/pm_linux/pmlinux.c
deleted file mode 100644
index 8c70319f2..000000000
--- a/portmidi/pm_linux/pmlinux.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* pmlinux.c -- PortMidi os-dependent code */
-
-/* This file only needs to implement pm_init(), which calls various
-   routines to register the available midi devices. This file must
-   be separate from the main portmidi.c file because it is system
-   dependent, and it is separate from, pmlinuxalsa.c, because it
-   might need to register non-alsa devices as well.
- */
-
-#include "stdlib.h"
-#include "portmidi.h"
-#ifdef PMALSA
-  #include "pmlinuxalsa.h"
-#endif
-
-#ifdef PMNULL
-  #include "pmlinuxnull.h"
-#endif
-
-PmError pm_init()
-{
-    #ifdef PMALSA
-	pm_linuxalsa_init();
-    #endif
-    #ifdef PMNULL
-        pm_linuxnull_init();
-    #endif
-}
-
-void pm_term(void)
-{
-    #ifdef PMALSA
-        pm_linuxalsa_term();
-    #endif
-}
-
-PmDeviceID pm_default_input_device_id = -1;
-PmDeviceID pm_default_output_device_id = -1;
-
-PmDeviceID Pm_GetDefaultInputDeviceID() { 
-    return pm_default_input_device_id; 
-}
-
-PmDeviceID Pm_GetDefaultOutputDeviceID() { 
-    return pm_default_output_device_id; 
-}
-
-void *pm_alloc(size_t s) { return malloc(s); }
-
-void pm_free(void *ptr) { free(ptr); }
-
diff --git a/portmidi/pm_linux/pmlinux.h b/portmidi/pm_linux/pmlinux.h
deleted file mode 100644
index 75c91f142..000000000
--- a/portmidi/pm_linux/pmlinux.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/* pmlinux.h */
-
-extern PmDeviceID pm_default_input_device_id;
-extern PmDeviceID pm_default_output_device_id;
-
diff --git a/portmidi/pm_linux/pmlinuxalsa.c b/portmidi/pm_linux/pmlinuxalsa.c
deleted file mode 100644
index 9b0eee75c..000000000
--- a/portmidi/pm_linux/pmlinuxalsa.c
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * pmlinuxalsa.c -- system specific definitions
- * 
- * written by:
- *  Roger Dannenberg (port to Alsa 0.9.x)
- *  Clemens Ladisch (provided code examples and invaluable consulting)
- *  Jason Cohen, Rico Colon, Matt Filippone (Alsa 0.5.x implementation)
- */ 
-
-#include "stdlib.h"
-#include "portmidi.h"
-#include "pminternal.h"
-#include "pmlinuxalsa.h"
-#include "string.h"
-#include "porttime.h"
-#include "pmlinux.h"
-
-#include <alsa/asoundlib.h>
-
-/* I used many print statements to debug this code. I left them in the
- * source, and you can turn them on by changing false to true below:
- */
-#define VERBOSE_ON 0
-#define VERBOSE if (VERBOSE_ON)
-
-#define MIDI_SYSEX      0xf0
-#define MIDI_EOX        0xf7
-
-#if SND_LIB_MAJOR == 0 && SND_LIB_MINOR < 9
-#error needs ALSA 0.9.0 or later
-#endif
-
-/* to store client/port in the device descriptor */
-#define MAKE_DESCRIPTOR(client, port) ((void*)(((client) << 8) | (port)))
-#define GET_DESCRIPTOR_CLIENT(info) ((((int)(info)) >> 8) & 0xff)
-#define GET_DESCRIPTOR_PORT(info) (((int)(info)) & 0xff)
-
-#define BYTE unsigned char
-#define UINT unsigned long
-
-extern pm_fns_node pm_linuxalsa_in_dictionary;
-extern pm_fns_node pm_linuxalsa_out_dictionary;
-
-static snd_seq_t *seq; // all input comes here, output queue allocated on seq
-static int queue, queue_used; /* one for all ports, reference counted */
-
-typedef struct alsa_descriptor_struct {
-    int client;
-    int port;
-    int this_port;
-    int in_sysex;
-    snd_midi_event_t *parser;
-    int error; /* host error code */
-} alsa_descriptor_node, *alsa_descriptor_type;
-
-
-/* get_alsa_error_text -- copy error text to potentially short string */
-/**/
-static void get_alsa_error_text(char *msg, int len, int err)
-{
-    int errlen = strlen(snd_strerror(err));
-    if (errlen < len) {
-        strcpy(msg, snd_strerror(err));
-    } else if (len > 20) {
-        sprintf(msg, "Alsa error %d", err);
-    } else if (len > 4) {
-        strcpy(msg, "Alsa");
-    } else {
-        msg[0] = 0;
-    }
-}
-
-
-/* queue is shared by both input and output, reference counted */
-static PmError alsa_use_queue(void)
-{
-    if (queue_used == 0) {
-        snd_seq_queue_tempo_t *tempo;
-
-        queue = snd_seq_alloc_queue(seq);
-        if (queue < 0) {
-            pm_hosterror = queue;
-            return pmHostError;
-        }
-        snd_seq_queue_tempo_alloca(&tempo);
-        snd_seq_queue_tempo_set_tempo(tempo, 480000);
-        snd_seq_queue_tempo_set_ppq(tempo, 480);
-        pm_hosterror = snd_seq_set_queue_tempo(seq, queue, tempo);
-        if (pm_hosterror < 0)
-            return pmHostError;
-
-        snd_seq_start_queue(seq, queue, NULL);
-        snd_seq_drain_output(seq);
-    }
-    ++queue_used;
-    return pmNoError;
-}
-
-
-static void alsa_unuse_queue(void)
-{
-    if (--queue_used == 0) {
-        snd_seq_stop_queue(seq, queue, NULL);
-        snd_seq_drain_output(seq);
-        snd_seq_free_queue(seq, queue);
-        VERBOSE printf("queue freed\n");
-    }
-}
-
-
-/* midi_message_length -- how many bytes in a message? */
-static int midi_message_length(PmMessage message)
-{
-    message &= 0xff;
-    if (message < 0x80) {
-        return 0;
-    } else if (message < 0xf0) {
-        static const int length[] = {3, 3, 3, 3, 2, 2, 3};
-        return length[(message - 0x80) >> 4];
-    } else {
-        static const int length[] = {
-            -1, 2, 3, 2, 0, 0, 1, -1, 1, 0, 1, 1, 1, 0, 1, 1};
-        return length[message - 0xf0];
-    }
-}
-
-
-static PmError alsa_out_open(PmInternal *midi, void *driverInfo) 
-{
-    void *client_port = descriptors[midi->device_id].descriptor;
-    alsa_descriptor_type desc = (alsa_descriptor_type) 
-        pm_alloc(sizeof(alsa_descriptor_node));
-    snd_seq_port_info_t *info;
-    int err;
-
-    if (!desc) return pmInsufficientMemory;
-    
-    snd_seq_port_info_alloca(&info);
-    snd_seq_port_info_set_port(info, midi->device_id);
-    snd_seq_port_info_set_capability(info, SND_SEQ_PORT_CAP_WRITE |
-                                     SND_SEQ_PORT_CAP_READ);
-    snd_seq_port_info_set_type(info, SND_SEQ_PORT_TYPE_MIDI_GENERIC | 
-                                     SND_SEQ_PORT_TYPE_APPLICATION);
-    snd_seq_port_info_set_port_specified(info, 1);
-    err = snd_seq_create_port(seq, info);
-    if (err < 0) goto free_desc;
-
-    /* fill in fields of desc, which is passed to pm_write routines */
-    midi->descriptor = desc;
-    desc->client = GET_DESCRIPTOR_CLIENT(client_port);
-    desc->port = GET_DESCRIPTOR_PORT(client_port);
-    desc->this_port = midi->device_id;
-    desc->in_sysex = 0;
-
-    desc->error = 0;
-
-    err = snd_midi_event_new(PM_DEFAULT_SYSEX_BUFFER_SIZE, &desc->parser);
-    if (err < 0) goto free_this_port;
-
-    if (midi->latency > 0) { /* must delay output using a queue */
-        err = alsa_use_queue();
-        if (err < 0) goto free_parser;
-
-        err = snd_seq_connect_to(seq, desc->this_port, desc->client, desc->port);
-        if (err < 0) goto unuse_queue;  /* clean up and return on error */
-    } else {
-        err = snd_seq_connect_to(seq, desc->this_port, desc->client, desc->port);
-        if (err < 0) goto free_parser;  /* clean up and return on error */
-    }        
-    return pmNoError;
-
- unuse_queue:
-    alsa_unuse_queue();
- free_parser:
-    snd_midi_event_free(desc->parser);
- free_this_port:
-    snd_seq_delete_port(seq, desc->this_port);
- free_desc:
-    pm_free(desc);
-    pm_hosterror = err;
-    if (err < 0) {
-        get_alsa_error_text(pm_hosterror_text, PM_HOST_ERROR_MSG_LEN, err);
-    }
-    return pmHostError;
-}
-    
-
-static PmError alsa_write_byte(PmInternal *midi, unsigned char byte, 
-                        PmTimestamp timestamp)
-{
-    alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
-    snd_seq_event_t ev;
-    int err;
-
-    snd_seq_ev_clear(&ev);
-    if (snd_midi_event_encode_byte(desc->parser, byte, &ev) == 1) {
-        snd_seq_ev_set_dest(&ev, desc->client, desc->port);
-        snd_seq_ev_set_source(&ev, desc->this_port);
-        if (midi->latency > 0) {
-            /* compute relative time of event = timestamp - now + latency */
-            PmTimestamp now = (midi->time_proc ? 
-                               midi->time_proc(midi->time_info) : 
-                               Pt_Time(NULL));
-            int when = timestamp;
-            /* if timestamp is zero, send immediately */
-            /* otherwise compute time delay and use delay if positive */
-            if (when == 0) when = now;
-            when = (when - now) + midi->latency;
-            if (when < 0) when = 0;
-            VERBOSE printf("timestamp %d now %d latency %d, ", 
-                           timestamp, now, midi->latency);
-            VERBOSE printf("scheduling event after %d\n", when);
-            /* message is sent in relative ticks, where 1 tick = 1 ms */
-            snd_seq_ev_schedule_tick(&ev, queue, 1, when);
-            /* NOTE: for cases where the user does not supply a time function,
-               we could optimize the code by not starting Pt_Time and using
-               the alsa tick time instead. I didn't do this because it would
-               entail changing the queue management to start the queue tick
-               count when PortMidi is initialized and keep it running until
-               PortMidi is terminated. (This should be simple, but it's not
-               how the code works now.) -RBD */
-        } else { /* send event out without queueing */
-            VERBOSE printf("direct\n");
-            /* ev.queue = SND_SEQ_QUEUE_DIRECT;
-               ev.dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS; */
-            snd_seq_ev_set_direct(&ev);
-        }
-        VERBOSE printf("sending event\n");
-        err = snd_seq_event_output(seq, &ev);
-        if (err < 0) {
-            desc->error = err;
-            return pmHostError;
-        }
-    }
-    return pmNoError;
-}
-
-
-static PmError alsa_out_close(PmInternal *midi)
-{
-    int err;
-    alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
-    if (!desc) return pmBadPtr;
-
-    if (pm_hosterror = snd_seq_disconnect_to(seq, desc->this_port, 
-                                             desc->client, desc->port)) {
-        // if there's an error, try to delete the port anyway, but don't
-        // change the pm_hosterror value so we retain the first error
-        snd_seq_delete_port(seq, desc->this_port);
-    } else { // if there's no error, delete the port and retain any error
-        pm_hosterror = snd_seq_delete_port(seq, desc->this_port);
-    }
-    if (midi->latency > 0) alsa_unuse_queue();
-    snd_midi_event_free(desc->parser);
-    pm_free(desc);
-    if (pm_hosterror) {
-        get_alsa_error_text(pm_hosterror_text, PM_HOST_ERROR_MSG_LEN, 
-                            pm_hosterror);
-        return pmHostError;
-    }
-    return pmNoError;
-}
-
-
-static PmError alsa_in_open(PmInternal *midi, void *driverInfo)
-{
-    void *client_port = descriptors[midi->device_id].descriptor;
-    alsa_descriptor_type desc = (alsa_descriptor_type) 
-        pm_alloc(sizeof(alsa_descriptor_node));
-    snd_seq_port_info_t *info;
-    snd_seq_port_subscribe_t *sub;
-    snd_seq_addr_t addr;
-    int err;
-
-    if (!desc) return pmInsufficientMemory;
-    
-    err = alsa_use_queue();
-    if (err < 0) goto free_desc;
-
-    snd_seq_port_info_alloca(&info);
-    snd_seq_port_info_set_port(info, midi->device_id);
-    snd_seq_port_info_set_capability(info, SND_SEQ_PORT_CAP_WRITE |
-                                     SND_SEQ_PORT_CAP_READ);
-    snd_seq_port_info_set_type(info, SND_SEQ_PORT_TYPE_MIDI_GENERIC | 
-                                     SND_SEQ_PORT_TYPE_APPLICATION);
-    snd_seq_port_info_set_port_specified(info, 1);
-    err = snd_seq_create_port(seq, info);
-    if (err < 0) goto free_queue;
-
-    /* fill in fields of desc, which is passed to pm_write routines */
-    midi->descriptor = desc;
-    desc->client = GET_DESCRIPTOR_CLIENT(client_port);
-    desc->port = GET_DESCRIPTOR_PORT(client_port);
-    desc->this_port = midi->device_id;
-    desc->in_sysex = 0;
-
-    desc->error = 0;
-
-    VERBOSE printf("snd_seq_connect_from: %d %d %d\n", 
-                   desc->this_port, desc->client, desc->port);
-    snd_seq_port_subscribe_alloca(&sub);
-    addr.client = snd_seq_client_id(seq);
-    addr.port = desc->this_port;
-    snd_seq_port_subscribe_set_dest(sub, &addr);
-    addr.client = desc->client;
-    addr.port = desc->port;
-    snd_seq_port_subscribe_set_sender(sub, &addr);
-    snd_seq_port_subscribe_set_time_update(sub, 1);
-    /* this doesn't seem to work: messages come in with real timestamps */
-    snd_seq_port_subscribe_set_time_real(sub, 0);
-    err = snd_seq_subscribe_port(seq, sub);
-    /* err = 
-       snd_seq_connect_from(seq, desc->this_port, desc->client, desc->port); */
-    if (err < 0) goto free_this_port;  /* clean up and return on error */
-    return pmNoError;
-
- free_this_port:
-    snd_seq_delete_port(seq, desc->this_port);
- free_queue:
-    alsa_unuse_queue();
- free_desc:
-    pm_free(desc);
-    pm_hosterror = err;
-    if (err < 0) {
-        get_alsa_error_text(pm_hosterror_text, PM_HOST_ERROR_MSG_LEN, err);
-    }
-    return pmHostError;
-}
-
-static PmError alsa_in_close(PmInternal *midi)
-{
-    int err;
-    alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
-    if (!desc) return pmBadPtr;
-    if (pm_hosterror = snd_seq_disconnect_from(seq, desc->this_port, 
-                                               desc->client, desc->port)) {
-        snd_seq_delete_port(seq, desc->this_port); /* try to close port */
-    } else {
-        pm_hosterror = snd_seq_delete_port(seq, desc->this_port);
-    }
-    alsa_unuse_queue();
-    pm_free(desc);
-    if (pm_hosterror) {
-        get_alsa_error_text(pm_hosterror_text, PM_HOST_ERROR_MSG_LEN, 
-                            pm_hosterror);
-        return pmHostError;
-    }
-    return pmNoError;
-}
-        
-
-static PmError alsa_abort(PmInternal *midi)
-{
-    alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
-    /* This is supposed to flush any pending output. */
-    printf("WARNING: alsa_abort not implemented\n");
-    return pmNoError;
-}
-
-
-#ifdef GARBAGE
-This is old code here temporarily for reference
-static PmError alsa_write(PmInternal *midi, PmEvent *buffer, long length)
-{
-    alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
-    int i, bytes;
-    unsigned char byte;
-    long msg;
-
-    desc->error = 0;
-    for (; length > 0; length--, buffer++) {
-        VERBOSE printf("message 0x%x\n", buffer->message);
-        if (Pm_MessageStatus(buffer->message) == MIDI_SYSEX)
-            desc->in_sysex = TRUE;
-        if (desc->in_sysex) {
-            msg = buffer->message;
-            for (i = 0; i < 4; i++) {
-                byte = msg;  /* extract next byte to send */
-                alsa_write_byte(midi, byte, buffer->timestamp);
-                if (byte == MIDI_EOX) {
-                    desc->in_sysex = FALSE;
-                    break;
-                }
-                if (desc->error < 0) break;
-                msg >>= 8; /* shift next byte into position */
-            }
-        } else {
-            bytes = midi_message_length(buffer->message);
-            msg = buffer->message;
-            for (i = 0; i < bytes; i++) {
-                byte = msg; /* extract next byte to send */
-                VERBOSE printf("sending 0x%x\n", byte);
-                alsa_write_byte(midi, byte, buffer->timestamp);
-                if (desc->error < 0) break;
-                msg >>= 8; /* shift next byte into position */
-            }
-        }
-    }
-    if (desc->error < 0) return pmHostError;
-
-    VERBOSE printf("snd_seq_drain_output: 0x%x\n", seq);
-    desc->error = snd_seq_drain_output(seq);
-    if (desc->error < 0) return pmHostError;
-
-    desc->error = pmNoError;
-    return pmNoError;
-}
-#endif
-
-
-static PmError alsa_write_flush(PmInternal *midi)
-{
-    alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
-    VERBOSE printf("snd_seq_drain_output: 0x%x\n", seq);
-    desc->error = snd_seq_drain_output(seq);
-    if (desc->error < 0) return pmHostError;
-
-    desc->error = pmNoError;
-    return pmNoError;
-}
-
-
-static PmError alsa_write_short(PmInternal *midi, PmEvent *event)
-{
-    int bytes = midi_message_length(event->message);
-    long msg = event->message;
-    int i;
-    alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
-    for (i = 0; i < bytes; i++) {
-        unsigned char byte = msg;
-        VERBOSE printf("sending 0x%x\n", byte);
-        alsa_write_byte(midi, byte, event->timestamp);
-        if (desc->error < 0) break;
-        msg >>= 8; /* shift next byte into position */
-    }
-    if (desc->error < 0) return pmHostError;
-    desc->error = pmNoError;
-    return pmNoError;
-}
-
-
-/* alsa_sysex -- implements begin_sysex and end_sysex */
-PmError alsa_sysex(PmInternal *midi, PmTimestamp timestamp) {
-    return pmNoError;
-}
-
-
-static PmTimestamp alsa_synchronize(PmInternal *midi)
-{
-    return 0; /* linux implementation does not use this synchronize function */
-    /* Apparently, Alsa data is relative to the time you send it, and there
-       is no reference. If this is true, this is a serious shortcoming of
-       Alsa. If not true, then PortMidi has a serious shortcoming -- it 
-       should be scheduling relative to Alsa's time reference. */
-}
-
-
-static void handle_event(snd_seq_event_t *ev)
-{
-    int device_id = ev->dest.port;
-    PmInternal *midi = descriptors[device_id].internalDescriptor;
-    PmEvent pm_ev;
-    PmTimeProcPtr time_proc = midi->time_proc;
-    PmTimestamp timestamp;
-
-    /* time stamp should be in ticks, using our queue where 1 tick = 1ms */
-    assert((ev->flags & SND_SEQ_TIME_STAMP_MASK) == SND_SEQ_TIME_STAMP_TICK);
-
-    /* if no time_proc, just return "native" ticks (ms) */
-    if (time_proc == NULL) {
-        timestamp = ev->time.tick;
-    } else { /* translate time to time_proc basis */
-        snd_seq_queue_status_t *queue_status;
-        snd_seq_queue_status_alloca(&queue_status);
-        snd_seq_get_queue_status(seq, queue, queue_status);
-        /* return (now - alsa_now) + alsa_timestamp */
-        timestamp = (*time_proc)(midi->time_info) + ev->time.tick -
-                    snd_seq_queue_status_get_tick_time(queue_status);
-    }
-    pm_ev.timestamp = timestamp;
-    switch (ev->type) {
-    case SND_SEQ_EVENT_NOTEON:
-        pm_ev.message = Pm_Message(0x90 | ev->data.note.channel,
-                                   ev->data.note.note & 0x7f,
-                                   ev->data.note.velocity & 0x7f);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_NOTEOFF:
-        pm_ev.message = Pm_Message(0x80 | ev->data.note.channel,
-                                   ev->data.note.note & 0x7f,
-                                   ev->data.note.velocity & 0x7f);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_KEYPRESS:
-        pm_ev.message = Pm_Message(0xa0 | ev->data.note.channel,
-                                   ev->data.note.note & 0x7f,
-                                   ev->data.note.velocity & 0x7f);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_CONTROLLER:
-        pm_ev.message = Pm_Message(0xb0 | ev->data.note.channel,
-                                   ev->data.control.param & 0x7f,
-                                   ev->data.control.value & 0x7f);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_PGMCHANGE:
-        pm_ev.message = Pm_Message(0xc0 | ev->data.note.channel,
-                                   ev->data.control.value & 0x7f, 0);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_CHANPRESS:
-        pm_ev.message = Pm_Message(0xd0 | ev->data.note.channel,
-                                   ev->data.control.value & 0x7f, 0);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_PITCHBEND:
-        pm_ev.message = Pm_Message(0xe0 | ev->data.note.channel,
-                            (ev->data.control.value + 0x2000) & 0x7f,
-                            ((ev->data.control.value + 0x2000) >> 7) & 0x7f);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_CONTROL14:
-        if (ev->data.control.param < 0x20) {
-            pm_ev.message = Pm_Message(0xb0 | ev->data.note.channel,
-                                       ev->data.control.param,
-                                       (ev->data.control.value >> 7) & 0x7f);
-            pm_read_short(midi, &pm_ev);
-            pm_ev.message = Pm_Message(0xb0 | ev->data.note.channel,
-                                       ev->data.control.param + 0x20,
-                                       ev->data.control.value & 0x7f);
-            pm_read_short(midi, &pm_ev);
-        } else {
-            pm_ev.message = Pm_Message(0xb0 | ev->data.note.channel,
-                                       ev->data.control.param & 0x7f,
-                                       ev->data.control.value & 0x7f);
-
-            pm_read_short(midi, &pm_ev);
-        }
-        break;
-    case SND_SEQ_EVENT_SONGPOS:
-        pm_ev.message = Pm_Message(0xf2,
-                                   ev->data.control.value & 0x7f,
-                                   (ev->data.control.value >> 7) & 0x7f);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_SONGSEL:
-        pm_ev.message = Pm_Message(0xf3,
-                                   ev->data.control.value & 0x7f, 0);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_QFRAME:
-        pm_ev.message = Pm_Message(0xf1,
-                                   ev->data.control.value & 0x7f, 0);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_START:
-        pm_ev.message = Pm_Message(0xfa, 0, 0);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_CONTINUE:
-        pm_ev.message = Pm_Message(0xfb, 0, 0);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_STOP:
-        pm_ev.message = Pm_Message(0xfc, 0, 0);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_CLOCK:
-        pm_ev.message = Pm_Message(0xf8, 0, 0);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_TUNE_REQUEST:
-        pm_ev.message = Pm_Message(0xf6, 0, 0);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_RESET:
-        pm_ev.message = Pm_Message(0xff, 0, 0);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_SENSING:
-        pm_ev.message = Pm_Message(0xfe, 0, 0);
-        pm_read_short(midi, &pm_ev);
-        break;
-    case SND_SEQ_EVENT_SYSEX: {
-        const BYTE *ptr = (const BYTE *) ev->data.ext.ptr;
-        int i;
-        long msg = 0;
-        int shift = 0;
-        if (!(midi->filters & PM_FILT_SYSEX)) {
-            for (i = 0; i < ev->data.ext.len; i++) {
-                pm_read_byte(midi, *ptr++, timestamp);
-            }
-        }
-        break;
-    }
-    }
-}
-
-static PmError alsa_poll(PmInternal *midi)
-{
-    snd_seq_event_t *ev;
-    while (snd_seq_event_input(seq, &ev) >= 0) {
-        if (ev) {
-            handle_event(ev);
-        }
-    }
-    return pmNoError;
-}
-
-
-static unsigned int alsa_has_host_error(PmInternal *midi)
-{
-    alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
-    return desc->error;
-}
-
-
-static void alsa_get_host_error(PmInternal *midi, char *msg, unsigned int len)
-{
-    alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
-    int err = (pm_hosterror || desc->error);
-    get_alsa_error_text(msg, len, err);
-}
-
-
-pm_fns_node pm_linuxalsa_in_dictionary = {
-    none_write_short,
-    none_sysex,
-    none_sysex,
-    none_write_byte,
-    none_write_short,
-    none_write_flush,
-    alsa_synchronize,
-    alsa_in_open,
-    alsa_abort,
-    alsa_in_close,
-    alsa_poll,
-    alsa_has_host_error,
-    alsa_get_host_error
-};
-
-pm_fns_node pm_linuxalsa_out_dictionary = {
-    alsa_write_short,
-    alsa_sysex,
-    alsa_sysex,
-    alsa_write_byte,
-    alsa_write_short, /* short realtime message */
-    alsa_write_flush,
-    alsa_synchronize,
-    alsa_out_open, 
-    alsa_abort, 
-    alsa_out_close,
-    none_poll,
-    alsa_has_host_error,
-    alsa_get_host_error
-};
-
-
-/* pm_strdup -- copy a string to the heap. Use this rather than strdup so 
- *    that we call pm_alloc, not malloc. This allows portmidi to avoid 
- *    malloc which might cause priority inversion. Probably ALSA is going
- *    to call malloc anyway, so this extra work here may be pointless.
- */
-char *pm_strdup(const char *s)
-{
-    int len = strlen(s);
-    char *dup = (char *) pm_alloc(len + 1);
-    strcpy(dup, s);
-    return dup;
-}
-
-
-PmError pm_linuxalsa_init( void )
-{
-    int  err;
-    snd_seq_client_info_t *cinfo;
-    snd_seq_port_info_t *pinfo;
-    unsigned int caps;
-
-    err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK);
-    if (err < 0) return;
-    
-    snd_seq_client_info_alloca(&cinfo);
-    snd_seq_port_info_alloca(&pinfo);
-
-    snd_seq_client_info_set_client(cinfo, -1);
-    while (snd_seq_query_next_client(seq, cinfo) == 0) {
-        snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
-        snd_seq_port_info_set_port(pinfo, -1);
-        while (snd_seq_query_next_port(seq, pinfo) == 0) {
-            if (snd_seq_port_info_get_client(pinfo) == SND_SEQ_CLIENT_SYSTEM)
-                continue; /* ignore Timer and Announce ports on client 0 */
-            caps = snd_seq_port_info_get_capability(pinfo);
-            if (!(caps & (SND_SEQ_PORT_CAP_SUBS_READ | SND_SEQ_PORT_CAP_SUBS_WRITE)))
-                continue; /* ignore if you cannot read or write port */
-            if (caps & SND_SEQ_PORT_CAP_SUBS_WRITE) {
-                if (pm_default_output_device_id == -1) 
-                    pm_default_output_device_id = pm_descriptor_index;
-                pm_add_device("ALSA",
-                              pm_strdup(snd_seq_port_info_get_name(pinfo)),
-                              FALSE,
-                              MAKE_DESCRIPTOR(snd_seq_port_info_get_client(pinfo),
-                                              snd_seq_port_info_get_port(pinfo)),
-                              &pm_linuxalsa_out_dictionary);
-            }
-            if (caps & SND_SEQ_PORT_CAP_SUBS_READ) {
-                if (pm_default_input_device_id == -1) 
-                    pm_default_input_device_id = pm_descriptor_index;
-                pm_add_device("ALSA",
-                              pm_strdup(snd_seq_port_info_get_name(pinfo)),
-                              TRUE,
-                              MAKE_DESCRIPTOR(snd_seq_port_info_get_client(pinfo),
-                                              snd_seq_port_info_get_port(pinfo)),
-                              &pm_linuxalsa_in_dictionary);
-            }
-        }
-    }
-}
-    
-
-void pm_linuxalsa_term(void)
-{
-    snd_seq_close(seq);
-}
diff --git a/portmidi/pm_linux/pmlinuxalsa.h b/portmidi/pm_linux/pmlinuxalsa.h
deleted file mode 100644
index d4bff16cd..000000000
--- a/portmidi/pm_linux/pmlinuxalsa.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* pmlinuxalsa.h -- system-specific definitions */
-
-PmError pm_linuxalsa_init(void);
-void pm_linuxalsa_term(void);
-
-
diff --git a/portmidi/pm_mac/pmmac.c b/portmidi/pm_mac/pmmac.c
deleted file mode 100644
index fbf31c83d..000000000
--- a/portmidi/pm_mac/pmmac.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* pmmac.c -- PortMidi os-dependent code */
-
-/* This file only needs to implement:
-pm_init(), which calls various routines to register the 
-available midi devices,
-Pm_GetDefaultInputDeviceID(), and
-Pm_GetDefaultOutputDeviceID().
-It is seperate from pmmacosxcm because we might want to register
-non-CoreMIDI devices.
-*/
-
-#include "stdlib.h"
-#include "portmidi.h"
-#include "pmmacosxcm.h"
-
-PmError pm_init()
-{
-    return pm_macosxcm_init();
-}
-
-void pm_term(void)
-{
-    pm_macosxcm_term();
-}
-
-PmDeviceID pm_default_input_device_id = -1;
-PmDeviceID pm_default_output_device_id = -1;
-
-PmDeviceID Pm_GetDefaultInputDeviceID()
-{
-    return pm_default_input_device_id;
-}
-
-PmDeviceID Pm_GetDefaultOutputDeviceID() {
-    return pm_default_output_device_id;
-}
-
-void *pm_alloc(size_t s) { return malloc(s); }
-
-void pm_free(void *ptr) { free(ptr); }
-
-
diff --git a/portmidi/pm_mac/pmmac.h b/portmidi/pm_mac/pmmac.h
deleted file mode 100644
index 2d714254e..000000000
--- a/portmidi/pm_mac/pmmac.h
+++ /dev/null
@@ -1,4 +0,0 @@
-/* pmmac.h */
-
-extern PmDeviceID pm_default_input_device_id;
-extern PmDeviceID pm_default_output_device_id;
\ No newline at end of file
diff --git a/portmidi/pm_mac/pmmacosxcm.c b/portmidi/pm_mac/pmmacosxcm.c
deleted file mode 100644
index 5cb5a277f..000000000
--- a/portmidi/pm_mac/pmmacosxcm.c
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- * Platform interface to the MacOS X CoreMIDI framework
- * 
- * Jon Parise <jparise@cmu.edu>
- * and subsequent work by Andrew Zeldis and Zico Kolter
- * and Roger B. Dannenberg
- *
- * $Id: pmmacosx.c,v 1.17 2002/01/27 02:40:40 jon Exp $
- */
- 
-/* Notes:
-    since the input and output streams are represented by MIDIEndpointRef
-    values and almost no other state, we store the MIDIEndpointRef on
-    descriptors[midi->device_id].descriptor. The only other state we need
-    is for errors: we need to know if there is an error and if so, what is
-    the error text. As in pmwinmm.c, we use a structure with two kinds of
-    host error: "error" and "callback_error". That way, asynchronous callbacks
-    do not interfere with other error information.
-    
-    OS X does not seem to have an error-code-to-text function, so we will
-    just use text messages instead of error codes.
- */
-
-#include <stdlib.h>
-
-#include "portmidi.h"
-#include "pminternal.h"
-#include "porttime.h"
-#include "pmmac.h"
-#include "pmmacosxcm.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include <CoreServices/CoreServices.h>
-#include <CoreMIDI/MIDIServices.h>
-#include <CoreAudio/HostTime.h>
-
-#define PACKET_BUFFER_SIZE 1024
-
-/* this is very strange: if I put in a reasonable 
-   number here, e.g. 128, which would allow sysex data
-   to be sent 128 bytes at a time, then I lose sysex
-   data in my loopback test. With a buffer size of 4,
-   we put at most 4 bytes in a packet (but maybe many
-   packets in a packetList), and everything works fine.
- */
-#define SYSEX_BUFFER_SIZE 4
-
-#define VERBOSE_ON 1
-#define VERBOSE if (VERBOSE_ON)
-
-#define MIDI_SYSEX      0xf0
-#define MIDI_EOX        0xf7
-#define MIDI_STATUS_MASK 0x80
-
-static MIDIClientRef	client = NULL;	/* Client handle to the MIDI server */
-static MIDIPortRef	portIn = NULL;	/* Input port handle */
-static MIDIPortRef	portOut = NULL;	/* Output port handle */
-
-extern pm_fns_node pm_macosx_in_dictionary;
-extern pm_fns_node pm_macosx_out_dictionary;
-
-typedef struct midi_macosxcm_struct {
-    unsigned long sync_time; /* when did we last determine delta? */
-    UInt64 delta;	/* difference between stream time and real time in ns */
-    UInt64 last_time;	/* last output time */
-    int first_message;  /* tells midi_write to sychronize timestamps */
-    int sysex_mode;     /* middle of sending sysex */
-    unsigned long sysex_word; /* accumulate data when receiving sysex */
-    unsigned int sysex_byte_count; /* count how many received */
-    char error[PM_HOST_ERROR_MSG_LEN];
-    char callback_error[PM_HOST_ERROR_MSG_LEN];
-    Byte packetBuffer[PACKET_BUFFER_SIZE];
-    MIDIPacketList *packetList; /* a pointer to packetBuffer */
-    MIDIPacket *packet;
-    Byte sysex_buffer[SYSEX_BUFFER_SIZE]; /* temp storage for sysex data */
-    MIDITimeStamp sysex_timestamp; /* timestamp to use with sysex data */
-} midi_macosxcm_node, *midi_macosxcm_type;
-
-/* private function declarations */
-MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp);
-PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp);
-
-char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint);
-
-
-static int
-midi_length(long msg)
-{
-    int status, high, low;
-    static int high_lengths[] = {
-        1, 1, 1, 1, 1, 1, 1, 1,         /* 0x00 through 0x70 */
-        3, 3, 3, 3, 2, 2, 3, 1          /* 0x80 through 0xf0 */
-    };
-    static int low_lengths[] = {
-        1, 1, 3, 2, 1, 1, 1, 1,         /* 0xf0 through 0xf8 */
-        1, 1, 1, 1, 1, 1, 1, 1          /* 0xf9 through 0xff */
-    };
-
-    status = msg & 0xFF;
-    high = status >> 4;
-    low = status & 15;
-
-    return (high != 0xF0) ? high_lengths[high] : low_lengths[low];
-}
-
-static PmTimestamp midi_synchronize(PmInternal *midi)
-{
-    midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor;
-    UInt64 pm_stream_time_2 = 
-            AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
-    PmTimestamp real_time;
-    UInt64 pm_stream_time;
-    /* if latency is zero and this is an output, there is no 
-       time reference and midi_synchronize should never be called */
-    assert(midi->time_proc);
-    assert(!(midi->write_flag && midi->latency == 0));
-    do {
-         /* read real_time between two reads of stream time */
-         pm_stream_time = pm_stream_time_2;
-         real_time = (*midi->time_proc)(midi->time_info);
-         pm_stream_time_2 = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
-         /* repeat if more than 0.5 ms has elapsed */
-    } while (pm_stream_time_2 > pm_stream_time + 500000);
-    m->delta = pm_stream_time - ((UInt64) real_time * (UInt64) 1000000);
-    m->sync_time = real_time;
-    return real_time;
-}
-
-
-/* called when MIDI packets are received */
-static void
-readProc(const MIDIPacketList *newPackets, void *refCon, void *connRefCon)
-{
-    PmInternal *midi;
-    midi_macosxcm_type m;
-    PmEvent event;
-    MIDIPacket *packet;
-    unsigned int packetIndex;
-    unsigned long now;
-    unsigned int status;
-    
-    /* Retrieve the context for this connection */
-    midi = (PmInternal *) connRefCon;
-    m = (midi_macosxcm_type) midi->descriptor;
-    assert(m);
-    
-    /* synchronize time references every 100ms */
-    now = (*midi->time_proc)(midi->time_info);
-    if (m->first_message || m->sync_time + 100 /*ms*/ < now) { 
-        /* time to resync */
-        now = midi_synchronize(midi);
-        m->first_message = FALSE;
-    }
-    
-    packet = (MIDIPacket *) &newPackets->packet[0];
-    /* printf("readproc packet status %x length %d\n", packet->data[0], packet->length); */
-    for (packetIndex = 0; packetIndex < newPackets->numPackets; packetIndex++) {
-        /* Set the timestamp and dispatch this message */
-        event.timestamp = 
-                (AudioConvertHostTimeToNanos(packet->timeStamp) - m->delta) / 
-                (UInt64) 1000000;
-        status = packet->data[0];
-        /* process packet as sysex data if it begins with MIDI_SYSEX, or
-           MIDI_EOX or non-status byte */
-        if (status == MIDI_SYSEX || status == MIDI_EOX ||
-            !(status & MIDI_STATUS_MASK)) {
-            int i = 0;
-            while (i < packet->length) {
-                pm_read_byte(midi, packet->data[i], event.timestamp);
-                i++;
-            }
-        } else {
-            /* Build the PmMessage for the PmEvent structure */
-            switch (packet->length) {
-                case 1:
-                    event.message = Pm_Message(packet->data[0], 0, 0);
-                    break; 
-                case 2:
-                    event.message = Pm_Message(packet->data[0], 
-                                               packet->data[1], 0);
-                    break;
-                case 3:
-                    event.message = Pm_Message(packet->data[0],
-                                               packet->data[1], 
-                                               packet->data[2]);
-                    break;
-                default:
-                    /* Skip packets that are too large to fit in a PmMessage */
-#ifdef DEBUG
-                    printf("PortMidi debug msg: large packet skipped\n");
-#endif
-                    continue;
-            }
-            pm_read_short(midi, &event);
-        }
-        packet = MIDIPacketNext(packet);
-    }
-}
-
-static PmError
-midi_in_open(PmInternal *midi, void *driverInfo)
-{
-    MIDIEndpointRef endpoint;
-    midi_macosxcm_type m;
-    OSStatus macHostError;
-    
-    /* insure that we have a time_proc for timing */
-    if (midi->time_proc == NULL) {
-        if (!Pt_Started()) 
-            Pt_Start(1, 0, 0);
-        /* time_get does not take a parameter, so coerce */
-        midi->time_proc = (PmTimeProcPtr) Pt_Time;
-    }
-    
-    endpoint = (MIDIEndpointRef) descriptors[midi->device_id].descriptor;
-    if (endpoint == NULL) {
-        return pmInvalidDeviceId;
-    }
-
-    m = (midi_macosxcm_type) pm_alloc(sizeof(midi_macosxcm_node)); /* create */
-    midi->descriptor = m;
-    if (!m) {
-        return pmInsufficientMemory;
-    }
-    m->error[0] = 0;
-    m->callback_error[0] = 0;
-    m->sync_time = 0;
-    m->delta = 0;
-    m->last_time = 0;
-    m->first_message = TRUE;
-    m->sysex_mode = FALSE;
-    m->sysex_word = 0;
-    m->sysex_byte_count = 0;
-    m->packetList = NULL;
-    m->packet = NULL;
-    
-    macHostError = MIDIPortConnectSource(portIn, endpoint, midi);
-    if (macHostError != noErr) {
-        pm_hosterror = macHostError;
-        sprintf(pm_hosterror_text, 
-                "Host error %ld: MIDIPortConnectSource() in midi_in_open()",
-                macHostError);
-        midi->descriptor = NULL;
-        pm_free(m);
-        return pmHostError;
-    }
-    
-    return pmNoError;
-}
-
-static PmError
-midi_in_close(PmInternal *midi)
-{
-    MIDIEndpointRef endpoint;
-    OSStatus macHostError;
-    PmError err = pmNoError;
-    
-    midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor;
-    
-    if (!m) return pmBadPtr;
-
-    endpoint = (MIDIEndpointRef) descriptors[midi->device_id].descriptor;
-    if (endpoint == NULL) {
-        pm_hosterror = pmBadPtr;
-    }
-    
-    /* shut off the incoming messages before freeing data structures */
-    macHostError = MIDIPortDisconnectSource(portIn, endpoint);
-    if (macHostError != noErr) {
-        pm_hosterror = macHostError;
-        sprintf(pm_hosterror_text, 
-                "Host error %ld: MIDIPortDisconnectSource() in midi_in_close()",
-                macHostError);
-        err = pmHostError;
-    }
-    
-    midi->descriptor = NULL;
-    pm_free(midi->descriptor);
-    
-    return err;
-}
-
-
-static PmError
-midi_out_open(PmInternal *midi, void *driverInfo)
-{
-    midi_macosxcm_type m;
-
-    m = (midi_macosxcm_type) pm_alloc(sizeof(midi_macosxcm_node)); /* create */
-    midi->descriptor = m;
-    if (!m) {
-        return pmInsufficientMemory;
-    }
-    m->error[0] = 0;
-    m->callback_error[0] = 0;
-    m->sync_time = 0;
-    m->delta = 0;
-    m->last_time = 0;
-    m->first_message = TRUE;
-    m->sysex_mode = FALSE;
-    m->sysex_word = 0;
-    m->sysex_byte_count = 0;
-    m->packetList = (MIDIPacketList *) m->packetBuffer;
-    m->packet = NULL;
-
-    return pmNoError;
-}
-
-static PmError
-midi_out_close(PmInternal *midi)
-{
-    midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor;
-    if (!m) return pmBadPtr;
-    
-    midi->descriptor = NULL;
-    pm_free(midi->descriptor);
-    
-    return pmNoError;
-}
-
-static PmError
-midi_abort(PmInternal *midi)
-{
-    return pmNoError;
-}
-
-
-static PmError
-midi_write_flush(PmInternal *midi)
-{
-    OSStatus macHostError;
-    midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor;
-    MIDIEndpointRef endpoint = 
-            (MIDIEndpointRef) descriptors[midi->device_id].descriptor;
-    assert(m);
-    assert(endpoint);
-    if (m->packet != NULL) {
-        /* out of space, send the buffer and start refilling it */
-        macHostError = MIDISend(portOut, endpoint, m->packetList);
-        m->packet = NULL; /* indicate no data in packetList now */
-        if (macHostError != noErr) goto send_packet_error;
-    }
-    return pmNoError;
-    
-send_packet_error:
-    pm_hosterror = macHostError;
-    sprintf(pm_hosterror_text, 
-            "Host error %ld: MIDISend() in midi_write()",
-            macHostError);
-    return pmHostError;
-
-}
-
-
-static PmError
-send_packet(PmInternal *midi, Byte *message, unsigned int messageLength, 
-            MIDITimeStamp timestamp)
-{
-    PmError err;
-    midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor;
-    assert(m);
-    
-    /* printf("add %d to packet %lx len %d\n", message[0], m->packet, messageLength); */
-    m->packet = MIDIPacketListAdd(m->packetList, sizeof(m->packetBuffer), 
-                                  m->packet, timestamp, messageLength, 
-                                  message);
-    if (m->packet == NULL) {
-        /* out of space, send the buffer and start refilling it */
-        /* make midi->packet non-null to fool midi_write_flush into sending */
-        m->packet = (MIDIPacket *) 4; 
-        if ((err = midi_write_flush(midi)) != pmNoError) return err;
-        m->packet = MIDIPacketListInit(m->packetList);
-        assert(m->packet); /* if this fails, it's a programming error */
-        m->packet = MIDIPacketListAdd(m->packetList, sizeof(m->packetBuffer),
-                                      m->packet, timestamp, messageLength, 
-                                      message);
-        assert(m->packet); /* can't run out of space on first message */           
-    }
-    return pmNoError;
-}    
-
-
-static PmError
-midi_write_short(PmInternal *midi, PmEvent *event)
-{
-    long when = event->timestamp;
-    long what = event->message;
-    MIDITimeStamp timestamp;
-    UInt64 when_ns;
-    midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor;
-    Byte message[4];
-    unsigned int messageLength;
-
-    if (m->packet == NULL) {
-        m->packet = MIDIPacketListInit(m->packetList);
-        /* this can never fail, right? failure would indicate something 
-           unrecoverable */
-        assert(m->packet);
-    }
-    
-    /* compute timestamp */
-    if (when == 0) when = midi->now;
-    /* if latency == 0, midi->now is not valid. We will just set it to zero */
-    if (midi->latency == 0) when = 0;
-    when_ns = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + m->delta;
-    /* make sure we don't go backward in time */
-    if (when_ns < m->last_time) when_ns = m->last_time;
-    m->last_time = when_ns;
-    timestamp = (MIDITimeStamp) AudioConvertNanosToHostTime(when_ns);
-
-    message[0] = Pm_MessageStatus(what);
-    message[1] = Pm_MessageData1(what);
-    message[2] = Pm_MessageData2(what);
-    messageLength = midi_length(what);
-        
-    /* Add this message to the packet list */
-    return send_packet(midi, message, messageLength, timestamp);
-}
-
-
-static PmError 
-midi_begin_sysex(PmInternal *midi, PmTimestamp when)
-{
-    UInt64 when_ns;
-    midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor;
-    assert(m);
-    m->sysex_byte_count = 0;
-    
-    /* compute timestamp */
-    if (when == 0) when = midi->now;
-    /* if latency == 0, midi->now is not valid. We will just set it to zero */
-    if (midi->latency == 0) when = 0;
-    when_ns = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + m->delta;
-    m->sysex_timestamp = (MIDITimeStamp) AudioConvertNanosToHostTime(when_ns);
-
-    if (m->packet == NULL) {
-        m->packet = MIDIPacketListInit(m->packetList);
-        /* this can never fail, right? failure would indicate something 
-           unrecoverable */
-        assert(m->packet);
-    }
-    return pmNoError;
-}
-
-
-static PmError
-midi_end_sysex(PmInternal *midi, PmTimestamp when)
-{
-    PmError err;
-    midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor;
-    assert(m);
-    
-    /* make sure we don't go backward in time */
-    if (m->sysex_timestamp < m->last_time) m->sysex_timestamp = m->last_time;
-    
-    /* now send what's in the buffer */
-    if (m->packet == NULL) {
-        /* if flush has been called in the meantime, packet list is NULL */
-        m->packet = MIDIPacketListInit(m->packetList);
-        /* this can never fail, right? failure would indicate something 
-           unrecoverable */
-        assert(m->packet);
-    }
-
-    err = send_packet(midi, m->sysex_buffer, m->sysex_byte_count,
-                      m->sysex_timestamp);
-    m->sysex_byte_count = 0;
-    if (err != pmNoError) {
-        m->packet = NULL; /* flush everything in the packet list */
-        return err;
-    }
-    return pmNoError;
-}
-
-
-static PmError
-midi_write_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp)
-{
-    midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor;
-    assert(m);
-    if (m->sysex_byte_count >= SYSEX_BUFFER_SIZE) {
-        PmError err = midi_end_sysex(midi, timestamp);
-        if (err != pmNoError) return err;
-    }
-    m->sysex_buffer[m->sysex_byte_count++] = byte;
-    return pmNoError;
-}
-
-
-static PmError
-midi_write_realtime(PmInternal *midi, PmEvent *event)
-{
-    /* to send a realtime message during a sysex message, first
-       flush all pending sysex bytes into packet list */
-    PmError err = midi_end_sysex(midi, 0);
-    if (err != pmNoError) return err;
-    /* then we can just do a normal midi_write_short */
-    return midi_write_short(midi, event);
-}
-
-static unsigned int midi_has_host_error(PmInternal *midi)
-{
-    midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor;
-    return (m->callback_error[0] != 0) || (m->error[0] != 0);
-}
-
-
-static void midi_get_host_error(PmInternal *midi, char *msg, unsigned int len)
-{
-    midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor;
-    msg[0] = 0; /* initialize to empty string */
-    if (m) { /* make sure there is an open device to examine */
-        if (m->error[0]) {
-            strncpy(msg, m->error, len);
-            m->error[0] = 0; /* clear the error */
-        } else if (m->callback_error[0]) {
-            strncpy(msg, m->callback_error, len);
-            m->callback_error[0] = 0; /* clear the error */
-        }
-        msg[len - 1] = 0; /* make sure string is terminated */
-    }
-}
-
-
-MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp)
-{
-    UInt64 nanos;
-    if (timestamp <= 0) {
-        return (MIDITimeStamp)0;
-    } else {
-        nanos = (UInt64)timestamp * (UInt64)1000000;
-        return (MIDITimeStamp)AudioConvertNanosToHostTime(nanos);
-    }
-}
-
-PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp)
-{
-    UInt64 nanos;
-    nanos = AudioConvertHostTimeToNanos(timestamp);
-    return (PmTimestamp)(nanos / (UInt64)1000000);
-}
-
-
-char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint)
-{
-    MIDIEntityRef entity;
-    MIDIDeviceRef device;
-    CFStringRef endpointName = NULL, deviceName = NULL, fullName = NULL;
-    CFStringEncoding defaultEncoding;
-    char* newName;
-
-    /* get the default string encoding */
-    defaultEncoding = CFStringGetSystemEncoding();
-
-    /* get the entity and device info */
-    MIDIEndpointGetEntity(endpoint, &entity);
-    MIDIEntityGetDevice(entity, &device);
-
-    /* create the nicely formated name */
-    MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &endpointName);
-    MIDIObjectGetStringProperty(device, kMIDIPropertyName, &deviceName);
-    if (deviceName != NULL) {
-        fullName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@: %@"),
-                                            deviceName, endpointName);
-    } else {
-        fullName = endpointName;
-    }
-    
-    /* copy the string into our buffer */
-    newName = (char*)malloc(CFStringGetLength(fullName) + 1);
-    CFStringGetCString(fullName, newName, CFStringGetLength(fullName) + 1,
-                        defaultEncoding);
-
-    /* clean up */
-    if (endpointName) CFRelease(endpointName);
-    if (deviceName) CFRelease(deviceName);
-    if (fullName) CFRelease(fullName);
-
-    return newName;
-}
-
- 
-
-pm_fns_node pm_macosx_in_dictionary = {
-    none_write_short,
-    none_sysex,
-    none_sysex,
-    none_write_byte,
-    none_write_short,
-    none_write_flush,
-    none_synchronize,
-    midi_in_open,
-    midi_abort,
-    midi_in_close,
-    success_poll,
-    midi_has_host_error,
-    midi_get_host_error,
-};
-
-pm_fns_node pm_macosx_out_dictionary = {
-    midi_write_short,
-    midi_begin_sysex,
-    midi_end_sysex,
-    midi_write_byte,
-    midi_write_realtime,
-    midi_write_flush,
-    midi_synchronize,
-    midi_out_open,
-    midi_abort,
-    midi_out_close,
-    success_poll,
-    midi_has_host_error,
-    midi_get_host_error,
-};
-
-
-PmError pm_macosxcm_init(void)
-{
-    ItemCount numInputs, numOutputs, numDevices;
-    MIDIEndpointRef endpoint;
-    int i;
-    OSStatus macHostError;
-    char *error_text;
-
-    /* Determine the number of MIDI devices on the system */
-    numDevices = MIDIGetNumberOfDevices();
-    numInputs = MIDIGetNumberOfSources();
-    numOutputs = MIDIGetNumberOfDestinations();
-
-    /* Return prematurely if no devices exist on the system
-       Note that this is not an error. There may be no devices.
-       Pm_CountDevices() will return zero, which is correct and
-       useful information
-     */
-    if (numDevices <= 0) {
-        return pmNoError;
-    }
-
-
-    /* Initialize the client handle */
-    macHostError = MIDIClientCreate(CFSTR("PortMidi"), NULL, NULL, &client);
-    if (macHostError != noErr) {
-        error_text = "MIDIClientCreate() in pm_macosxcm_init()";
-        goto error_return;
-    }
-
-    /* Create the input port */
-    macHostError = MIDIInputPortCreate(client, CFSTR("Input port"), readProc,
-                                          NULL, &portIn);
-    if (macHostError != noErr) {
-        error_text = "MIDIInputPortCreate() in pm_macosxcm_init()";
-        goto error_return;
-    }
-        
-    /* Create the output port */
-    macHostError = MIDIOutputPortCreate(client, CFSTR("Output port"), &portOut);
-    if (macHostError != noErr) {
-        error_text = "MIDIOutputPortCreate() in pm_macosxcm_init()";
-        goto error_return;
-    }
-
-    /* Iterate over the MIDI input devices */
-    for (i = 0; i < numInputs; i++) {
-        endpoint = MIDIGetSource(i);
-        if (endpoint == NULL) {
-            continue;
-        }
-
-        /* set the first input we see to the default */
-        if (pm_default_input_device_id == -1)
-            pm_default_input_device_id = pm_descriptor_index;
-        
-        /* Register this device with PortMidi */
-        pm_add_device("CoreMIDI", cm_get_full_endpoint_name(endpoint),
-                      TRUE, (void*)endpoint, &pm_macosx_in_dictionary);
-    }
-
-    /* Iterate over the MIDI output devices */
-    for (i = 0; i < numOutputs; i++) {
-        endpoint = MIDIGetDestination(i);
-        if (endpoint == NULL) {
-            continue;
-        }
-
-        /* set the first output we see to the default */
-        if (pm_default_output_device_id == -1)
-            pm_default_output_device_id = pm_descriptor_index;
-
-        /* Register this device with PortMidi */
-        pm_add_device("CoreMIDI", cm_get_full_endpoint_name(endpoint),
-                      FALSE, (void*)endpoint, &pm_macosx_out_dictionary);
-    }
-    return pmNoError;
-    
-error_return:
-    pm_hosterror = macHostError;
-    sprintf(pm_hosterror_text, "Host error %ld: %s\n", macHostError, error_text);
-    pm_macosxcm_term(); /* clear out any opened ports */
-    return pmHostError;
-}
-
-void pm_macosxcm_term(void)
-{
-    if (client != NULL)	 MIDIClientDispose(client);
-    if (portIn != NULL)	 MIDIPortDispose(portIn);
-    if (portOut != NULL) MIDIPortDispose(portOut);
-}
diff --git a/portmidi/pm_mac/pmmacosxcm.h b/portmidi/pm_mac/pmmacosxcm.h
deleted file mode 100644
index 172593595..000000000
--- a/portmidi/pm_mac/pmmacosxcm.h
+++ /dev/null
@@ -1,4 +0,0 @@
-/* system-specific definitions */
-
-PmError pm_macosxcm_init(void);
-void pm_macosxcm_term(void);
\ No newline at end of file
diff --git a/portmidi/pm_test/latency.c b/portmidi/pm_test/latency.c
deleted file mode 100644
index 87b1965b8..000000000
--- a/portmidi/pm_test/latency.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/* latency.c -- measure latency of OS */
-
-#include "porttime.h"
-#include "portmidi.h"
-#include "stdlib.h"
-#include "stdio.h"
-#include "string.h"
-#include "assert.h"
-
-/* Latency is defined here to mean the time starting when a
-   process becomes ready to run, and ending when the process
-   actually runs. Latency is due to contention for the
-   processor, usually due to other processes, OS activity
-   including device drivers handling interrupts, and
-   waiting for the scheduler to suspend the currently running
-   process and activate the one that is waiting.
-
-   Latency can affect PortMidi applications: if a process fails
-   to wake up promptly, MIDI input may sit in the input buffer
-   waiting to be handled, and MIDI output may not be generated
-   with accurate timing. Using the latency parameter when 
-   opening a MIDI output port allows the caller to defer timing
-   to PortMidi, which in most implementations will pass the
-   data on to the OS. By passing timestamps and data to the
-   OS kernel, device driver, or even hardware, there are fewer
-   sources of latency that can affect the ultimate timing of
-   the data. On the other hand, the application must generate
-   and deliver the data ahead of the timestamp. The amount by 
-   which data is computed early must be at least as large as
-   the worst-case latency to avoid timing problems.
-
-   Latency is even more important in audio applications. If an
-   application lets an audio output buffer underflow, an audible
-   pop or click is produced. Audio input buffers can overflow,
-   causing data to be lost. In general the audio buffers must
-   be large enough to buffer the worst-case latency that the
-   application will encounter.
-
-   This program measures latency by recording the difference
-   between the scheduled callback time and the current real time.
-   We do not really know the scheduled callback time, so we will
-   record the differences between the real time of each callback
-   and the real time of the previous callback. Differences that
-   are larger than the scheduled difference are recorded. Smaller
-   differences indicate the system is recovering from an earlier
-   latency, so these are ignored.
-   Since printing by the callback process can cause all sorts of
-   delays, this program records latency observations in a
-   histogram. When the program is stopped, the histogram is
-   printed to the console.
-
-   Optionally the system can be tested under a load of MIDI input,
-   MIDI output, or both.  If MIDI input is selected, the callback
-   thread will read any waiting MIDI events each iteration.  You
-   must generate events on this interface for the test to actually
-   put any appreciable load on PortMidi.  If MIDI output is
-   selected, alternating note on and note off events are sent each
-   X iterations, where you specify X.  For example, with a timer
-   callback period of 2ms and X=1, a MIDI event is sent every 2ms.
-
-
-   INTERPRETING RESULTS: Time is quantized to 1ms, so there is
-   some uncertainty due to rounding. A microsecond latency that
-   spans the time when the clock is incremented will be reported
-   as a latency of 1. On the other hand, a latency of almost
-   1ms that falls between two clock ticks will be reported as 
-   zero. In general, if the highest nonzero bin is numbered N,
-   then the maximum latency is N+1.
-
-CHANGE LOG
-
-18-Jul-03 Mark Nelson -- Added code to generate MIDI or receive
-            MIDI during test, and made period user-settable.
- */
-
-#define HIST_LEN 21 /* how many 1ms bins in the histogram */
-
-#define STRING_MAX 80 /* used for console input */
-
-#define INPUT_BUFFER_SIZE 100
-#define OUTPUT_BUFFER_SIZE 0
-
-#ifndef max
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#endif
-#ifndef min
-#define min(a, b) ((a) <= (b) ? (a) : (b))
-#endif
-
-int get_number(char *prompt);
-
-PtTimestamp previous_callback_time = 0;
-
-int period;            /* milliseconds per callback */
-
-long histogram[HIST_LEN];
-long max_latency = 0;  /* worst latency observed */
-long out_of_range = 0; /* how many points outside of HIST_LEN? */
-
-int test_in, test_out; /* test MIDI in and/or out? */
-int output_period;     /* output MIDI every __ iterations if test_out true */
-int iteration = 0;
-PmStream *in, *out;
-int note_on = 0;       /* is the note currently on? */
-
-/* callback function for PortTime -- computes histogram */
-void pt_callback(PtTimestamp timestamp, void *userData)
-{
-    PtTimestamp difference = timestamp - previous_callback_time - period;
-    previous_callback_time = timestamp;
-
-    /* allow 5 seconds for the system to settle down */
-    if (timestamp < 5000) return;
-
-    iteration++;
-    /* send a note on/off if user requested it */
-    if (test_out && (iteration % output_period == 0)) {
-        PmEvent buffer[1];
-        buffer[0].timestamp = Pt_Time(NULL);
-        if (note_on) {
-            /* note off */
-            buffer[0].message = Pm_Message(0x90, 60, 0);
-            note_on = 0;
-        } else {
-            /* note on */
-            buffer[0].message = Pm_Message(0x90, 60, 100);
-            note_on = 1;
-        }
-        Pm_Write(out, buffer, 1);
-        iteration = 0;
-    }
-
-    /* read all waiting events (if user requested) */
-    if (test_in) {
-       PmError status;
-       PmEvent buffer[1];
-       do {
-          status = Pm_Poll(in);
-          if (status == TRUE) {
-              Pm_Read(in,buffer,1);
-          }
-       } while (status == TRUE);
-    }
-
-    if (difference < 0) return; /* ignore when system is "catching up" */
-
-    /* update the histogram */
-    if (difference < HIST_LEN) {
-        histogram[difference]++;
-    } else {
-        out_of_range++;
-    }
-
-    if (max_latency < difference) max_latency = difference;
-}
-
-
-int main()
-{
-    char line[STRING_MAX];
-    int i;
-    int len;
-    int choice;
-    PtTimestamp stop;
-    printf("Latency histogram.\n");
-    period = get_number("Choose timer period (in ms): ");
-    assert(period >= 1);
-    printf("Benchmark with:\n\t%s\n\t%s\n\t%s\n\t%s\n",
-           "1. No MIDI traffic",
-           "2. MIDI input",
-           "3. MIDI output",
-           "4. MIDI input and output");
-    choice = get_number("? ");
-    switch (choice) {
-      case 1: test_in = 0; test_out = 0; break;
-      case 2: test_in = 1; test_out = 0; break;
-      case 3: test_in = 0; test_out = 1; break;
-      case 4: test_in = 1; test_out = 1; break;
-      default: assert(0);
-    }
-    if (test_in || test_out) {
-        /* list device information */
-        for (i = 0; i < Pm_CountDevices(); i++) {
-            const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
-            if ((test_in && info->input) ||
-                (test_out && info->output)) {
-                printf("%d: %s, %s", i, info->interf, info->name);
-                if (info->input) printf(" (input)");
-                if (info->output) printf(" (output)");
-                printf("\n");
-            }
-        }
-        /* open stream(s) */
-        if (test_in) {
-            int i = get_number("MIDI input device number: ");
-            Pm_OpenInput(&in, 
-                  i,
-                  NULL, 
-                  INPUT_BUFFER_SIZE, 
-                  (long (*)(void *)) Pt_Time, 
-                  NULL);
-            /* turn on filtering; otherwise, input might overflow in the 
-               5-second period before timer callback starts reading midi */
-            Pm_SetFilter(in, PM_FILT_ACTIVE | PM_FILT_CLOCK);
-        }
-        if (test_out) {
-            int i = get_number("MIDI output device number: ");
-            PmEvent buffer[1];
-            Pm_OpenOutput(&out, 
-                  i,
-                  NULL,
-                  OUTPUT_BUFFER_SIZE,
-                  (long (*)(void *)) Pt_Time,
-                  NULL, 
-                  0); /* no latency scheduling */
-
-            /* send a program change to force a status byte -- this fixes
-               a problem with a buggy linux MidiSport driver, and shouldn't
-               hurt anything else
-             */
-            buffer[0].timestamp = 0;
-            buffer[0].message = Pm_Message(0xC0, 0, 0); /* program change */
-            Pm_Write(out, buffer, 1);
-
-            output_period = get_number(
-                "MIDI out should be sent every __ callback iterations: ");
-
-            assert(output_period >= 1);
-        }
-    }
-
-    printf("%s%s", "Latency measurements will start in 5 seconds. ",
-                   "Type return to stop: ");
-    Pt_Start(period, &pt_callback, 0);
-    fgets(line, STRING_MAX, stdin);
-    stop = Pt_Time();
-    Pt_Stop();
-
-    /* courteously turn off the last note, if necessary */
-    if (note_on) {
-       PmEvent buffer[1];
-       buffer[0].timestamp = Pt_Time(NULL);
-       buffer[0].message = Pm_Message(0x90, 60, 0);
-       Pm_Write(out, buffer, 1);
-    }
-
-    /* print the histogram */
-    printf("Duration of test: %g seconds\n\n", max(0, stop - 5000) * 0.001);
-    printf("Latency(ms)  Number of occurrences\n");
-    /* avoid printing beyond last non-zero histogram entry */
-    len = min(HIST_LEN, max_latency + 1);
-    for (i = 0; i < len; i++) {
-        printf("%2d      %10ld\n", i, histogram[i]);
-    }
-    printf("Number of points greater than %dms: %ld\n", 
-           HIST_LEN - 1, out_of_range);
-    printf("Maximum latency: %ld milliseconds\n", max_latency);
-    printf("\nNote that due to rounding, actual latency can be 1ms higher\n");
-    printf("than the numbers reported here.\n");
-    printf("Type return to exit...");
-    fgets(line, STRING_MAX, stdin);
-    return 0;
-}
-
-
-/* read a number from console */
-int get_number(char *prompt)
-{
-    char line[STRING_MAX];
-    int n = 0, i;
-    printf(prompt);
-    while (n != 1) {
-        n = scanf("%d", &i);
-        fgets(line, STRING_MAX, stdin);
-
-    }
-    return i;
-}
diff --git a/portmidi/pm_test/latency.dsp b/portmidi/pm_test/latency.dsp
deleted file mode 100644
index ff6bbbd71..000000000
--- a/portmidi/pm_test/latency.dsp
+++ /dev/null
@@ -1,102 +0,0 @@
-# Microsoft Developer Studio Project File - Name="latency" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=latency - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "latency.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "latency.mak" CFG="latency - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "latency - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "latency - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "latency - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "latency___Win32_Release"
-# PROP BASE Intermediate_Dir "latency___Win32_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "latencyRelease"
-# PROP Intermediate_Dir "latencyRelease"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../porttime" /I "../pm_common" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ..\Release\portmidi.lib ..\porttime\Release\porttime.lib winmm.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "latency - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "latency___Win32_Debug"
-# PROP BASE Intermediate_Dir "latency___Win32_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "latencyDebug"
-# PROP Intermediate_Dir "latencyDebug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../porttime" /I "../pm_common" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "USE_DLL_FOR_CLEANUP" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 ..\pm_win\Debug\portmidi.lib ..\porttime\Debug\porttime.lib ..\pm_win\Debug\pm_dll.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "latency - Win32 Release"
-# Name "latency - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\latency.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/portmidi/pm_test/midithread.c b/portmidi/pm_test/midithread.c
deleted file mode 100644
index 861b347cd..000000000
--- a/portmidi/pm_test/midithread.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/* midithread.c -- example program showing how to do midi processing 
-                   in a preemptive thread
-
-  Notes: if you handle midi I/O from your main program, there will be
-  some delay before handling midi messages whenever the program is
-  doing something like file I/O, graphical interface updates, etc.
-
-  To handle midi with minimal delay, you should do all midi processing
-  in a separate, high priority thread. A convenient way to get a high
-  priority thread in windows is to use the timer callback provided by
-  the PortTime library. That is what we show here.
-
-  If the high priority thread writes to a file, prints to the console,
-  or does just about anything other than midi processing, this may 
-  create delays, so all this processing should be off-loaded to the
-  "main" process or thread. Communication between threads can be tricky.
-  If one thread is writing at the same time the other is reading, very
-  tricky race conditions can arise, causing programs to behave
-  incorrectly, but only under certain timing conditions -- a terrible
-  thing to debug. Advanced programmers know this as a synchronization
-  problem. See any operating systems textbook for the complete story.
-
-  To avoid synchronization problems, a simple, reliable approach is
-  to communicate via messages. PortMidi offers a message queue as a
-  datatype, and operations to insert and remove messages. Use two 
-  queues as follows: midi_to_main transfers messages from the midi
-  thread to the main thread, and main_to_midi transfers messages from
-  the main thread to the midi thread. Queues are safe for use between
-  threads as long as ONE thread writes and ONE thread reads. You must 
-  NEVER allow two threads to write to the same queue.
-
-  This program transposes incoming midi data by an amount controlled
-  by the main program. To change the transposition, type an integer
-  followed by return. The main program sends this via a message queue
-  to the midi thread. To quit, type 'q' followed by return.
-
-  The midi thread can also send a pitch to the main program on request.
-  Type 'm' followed by return to wait for the next midi message and
-  print the pitch.
-
-  This program illustrates:
-    Midi processing in a high-priority thread.
-    Communication with a main process via message queues.
-
- */
-
-#include "stdio.h"
-#include "stdlib.h"
-#include "string.h"
-#include "assert.h"
-#include "portmidi.h"
-#include "pmutil.h"
-#include "porttime.h"
-
-/* if INPUT_BUFFER_SIZE is 0, PortMidi uses a default value */
-#define INPUT_BUFFER_SIZE 0
-
-#define OUTPUT_BUFFER_SIZE 100
-#define DRIVER_INFO NULL
-#define TIME_PROC NULL
-#define TIME_INFO NULL
-/* use zero latency because we want output to be immediate */
-#define LATENCY 0
-
-#define STRING_MAX 80
-
-/**********************************/
-/* DATA USED ONLY BY process_midi */
-/* (except during initialization) */
-/**********************************/
-
-int active = FALSE;
-int monitor = FALSE;
-int midi_thru = TRUE;
-
-long transpose;
-PmStream *midi_in;
-PmStream *midi_out;
-
-/****************************/
-/* END OF process_midi DATA */
-/****************************/
-
-/* shared queues */
-PmQueue *midi_to_main;
-PmQueue *main_to_midi;
-
-#define QUIT_MSG 1000
-#define MONITOR_MSG 1001
-#define THRU_MSG 1002
-
-/* timer interrupt for processing midi data */
-void process_midi(PtTimestamp timestamp, void *userData)
-{
-    PmError result;
-    PmEvent buffer; /* just one message at a time */
-    long msg;
-
-    /* do nothing until initialization completes */
-    if (!active) 
-        return;
-
-    /* check for messages */
-    do { 
-        result = Pm_Dequeue(main_to_midi, &msg); 
-        if (result) {
-            if (msg >= -127 && msg <= 127) 
-                transpose = msg;
-            else if (msg == QUIT_MSG) {
-                /* acknowledge receipt of quit message */
-                Pm_Enqueue(midi_to_main, &msg);
-                active = FALSE;
-                return;
-            } else if (msg == MONITOR_MSG) {
-                /* main has requested a pitch. monitor is a flag that
-                 * records the request:
-                 */
-                monitor = TRUE;
-            } else if (msg == THRU_MSG) {
-                /* toggle Thru on or off */
-                midi_thru = !midi_thru;
-            }
-        }
-    } while (result);         
-    
-    /* see if there is any midi input to process */
-    do {
-		result = Pm_Poll(midi_in);
-        if (result) {
-            long status, data1, data2;
-            if (Pm_Read(midi_in, &buffer, 1) == pmBufferOverflow) 
-                continue;
-            if (midi_thru) 
-                Pm_Write(midi_out, &buffer, 1);
-            /* unless there was overflow, we should have a message now */
-            status = Pm_MessageStatus(buffer.message);
-            data1 = Pm_MessageData1(buffer.message);
-            data2 = Pm_MessageData2(buffer.message);
-            if ((status & 0xF0) == 0x90 ||
-                (status & 0xF0) == 0x80) {
-                
-                /* this is a note-on or note-off, so transpose and send */
-                data1 += transpose;
-                
-                /* keep within midi pitch range, keep proper pitch class */
-                while (data1 > 127) 
-                    data1 -= 12;
-                while (data1 < 0) 
-                    data1 += 12;
-                
-                /* send the message */
-                buffer.message = Pm_Message(status, data1, data2);
-                Pm_Write(midi_out, &buffer, 1);
-                
-                /* if monitor is set, send the pitch to the main thread */
-                if (monitor) {
-                    Pm_Enqueue(midi_to_main, &data1);
-                    monitor = FALSE; /* only send one pitch per request */
-                }
-            }
-        }
-    } while (result);
-}
-
-void exit_with_message(char *msg)
-{
-    char line[STRING_MAX];
-    printf("%s\n", msg);
-    fgets(line, STRING_MAX, stdin);
-    exit(1);
-}
-
-int main()
-{
-    int id;
-    long n;
-    const PmDeviceInfo *info;
-    char line[STRING_MAX];
-    int spin;
-    int done = FALSE;
-
-    /* determine what type of test to run */
-    printf("begin PortMidi multithread test...\n");
-	
-    /* note that it is safe to call PortMidi from the main thread for
-       initialization and opening devices. You should not make any
-       calls to PortMidi from this thread once the midi thread begins.
-       to make PortMidi calls.
-     */
-
-    /* make the message queues */
-    /* messages can be of any size and any type, but all messages in
-     * a given queue must have the same size. We'll just use long's
-     * for our messages in this simple example
-     */
-    midi_to_main = Pm_QueueCreate(32, sizeof(long));
-    assert(midi_to_main != NULL);
-    main_to_midi = Pm_QueueCreate(32, sizeof(long));
-    assert(main_to_midi != NULL);
-
-    /* a little test of enqueue and dequeue operations. Ordinarily, 
-     * you would call Pm_Enqueue from one thread and Pm_Dequeue from
-     * the other. Since the midi thread is not running, this is safe.
-     */
-    n = 1234567890;
-    Pm_Enqueue(midi_to_main, &n);
-    n = 987654321;
-    Pm_Enqueue(midi_to_main, &n);
-	Pm_Dequeue(midi_to_main, &n);
-	if (n != 1234567890) {
-        exit_with_message("Pm_Dequeue produced unexpected result.");
-    }
-    Pm_Dequeue(midi_to_main, &n);
-	if(n != 987654321) {
-        exit_with_message("Pm_Dequeue produced unexpected result.");
-    }
-
-    /* always start the timer before you start midi */
-    Pt_Start(1, &process_midi, 0); /* start a timer with millisecond accuracy */
-    /* the timer will call our function, process_midi() every millisecond */
-    
-	Pm_Initialize();
-
-    id = Pm_GetDefaultOutputDeviceID();
-    info = Pm_GetDeviceInfo(id);
-    if (info == NULL) {
-        printf("Could not open default output device (%d).", id);
-        exit_with_message("");
-    }
-    printf("Opening output device %s %s\n", info->interf, info->name);
-
-    /* use zero latency because we want output to be immediate */
-    Pm_OpenOutput(&midi_out, 
-                  id, 
-                  DRIVER_INFO,
-                  OUTPUT_BUFFER_SIZE,
-                  TIME_PROC,
-                  TIME_INFO,
-                  LATENCY);
-
-    id = Pm_GetDefaultInputDeviceID();
-    info = Pm_GetDeviceInfo(id);
-    if (info == NULL) {
-        printf("Could not open default input device (%d).", id);
-        exit_with_message("");
-    }
-    printf("Opening input device %s %s\n", info->interf, info->name);
-    Pm_OpenInput(&midi_in, 
-                 id, 
-                 DRIVER_INFO,
-                 INPUT_BUFFER_SIZE,
-                 TIME_PROC,
-                 TIME_INFO);
-
-    active = TRUE; /* enable processing in the midi thread -- yes, this
-                      is a shared variable without synchronization, but
-                      this simple assignment is safe */
-
-    printf("Enter midi input; it will be transformed as specified by...\n");
-    printf("%s\n%s\n%s\n",
-           "Type 'q' to quit, 'm' to monitor next pitch, t to toggle thru or",
-           "type a number to specify transposition.",
-		   "Must terminate with [ENTER]");
-
-    while (!done) {
-        long msg;
-        int len;
-        fgets(line, STRING_MAX, stdin);
-        /* remove the newline: */
-        len = strlen(line);
-        if (len > 0) line[len - 1] = 0; /* overwrite the newline char */
-        if (strcmp(line, "q") == 0) {
-            msg = QUIT_MSG;
-            Pm_Enqueue(main_to_midi, &msg);
-            /* wait for acknowlegement */
-            do {
-                spin = Pm_Dequeue(midi_to_main, &msg);
-            } while (spin == 0); /* spin */ ;
-            done = TRUE; /* leave the command loop and wrap up */
-        } else if (strcmp(line, "m") == 0) {
-            msg = MONITOR_MSG;
-            Pm_Enqueue(main_to_midi, &msg);
-            printf("Waiting for note...\n");
-            do {
-                spin = Pm_Dequeue(midi_to_main, &msg);
-            } while (spin == 0); /* spin */ ;
-            printf("... pitch is %ld\n", msg);
-        } else if (strcmp(line, "t") == 0) {
-            /* reading midi_thru asynchronously could give incorrect results,
-               e.g. if you type "t" twice before the midi thread responds to
-               the first one, but we'll do it this way anyway. Perhaps a more
-               correct way would be to wait for an acknowledgement message
-               containing the new state. */
-            printf("Setting THRU %s\n", (midi_thru ? "off" : "on"));
-            msg = THRU_MSG;
-            Pm_Enqueue(main_to_midi, &msg);
-        } else if (sscanf(line, "%ld", &msg) == 1) {
-            if (msg >= -127 && msg <= 127) {
-                /* send transposition value */
-                printf("Transposing by %ld\n", msg);
-                Pm_Enqueue(main_to_midi, &msg);
-            } else {
-                printf("Transposition must be within -127...127\n");
-            }
-        } else {
-            printf("%s\n%s\n%s\n",
-                   "Type 'q' to quit, 'm' to monitor next pitch, or",
-                   "type a number to specify transposition.",
-				   "Must terminate with [ENTER]");
-        }
-    }
-
-    /* at this point, midi thread is inactive and we need to shut down
-     * the midi input and output
-     */
-    Pt_Stop(); /* stop the timer */
-    Pm_QueueDestroy(midi_to_main);
-    Pm_QueueDestroy(main_to_midi);
-
-    /* Belinda! if close fails here, some memory is deleted, right??? */
-    Pm_Close(midi_in);
-    Pm_Close(midi_out);
-    
-    printf("finished portMidi multithread test...enter any character to quit [RETURN]...");
-    fgets(line, STRING_MAX, stdin);
-    return 0;
-}
diff --git a/portmidi/pm_test/midithread.dsp b/portmidi/pm_test/midithread.dsp
deleted file mode 100644
index 7dc0a16f4..000000000
--- a/portmidi/pm_test/midithread.dsp
+++ /dev/null
@@ -1,102 +0,0 @@
-# Microsoft Developer Studio Project File - Name="midithread" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=midithread - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "midithread.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "midithread.mak" CFG="midithread - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "midithread - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "midithread - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "midithread - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "midithreadRelease"
-# PROP Intermediate_Dir "midithreadRelease"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../pm_common" /I "../porttime" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ..\Release\portmidi.lib ..\porttime\Release\porttime.lib winmm.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "midithread - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "midithreadDebug"
-# PROP BASE Intermediate_Dir "midithreadDebug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "midithreadDebug"
-# PROP Intermediate_Dir "midithreadDebug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../pm_common" /I "../porttime" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "USE_DLL_FOR_CLEANUP" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 ..\pm_win\Debug\portmidi.lib ..\porttime\Debug\porttime.lib ..\pm_win\Debug\pm_dll.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "midithread - Win32 Release"
-# Name "midithread - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\midithread.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/portmidi/pm_test/midithru.c b/portmidi/pm_test/midithru.c
deleted file mode 100644
index 270246fbf..000000000
--- a/portmidi/pm_test/midithru.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/* midithru.c -- example program implementing background thru processing */
-
-/* suppose you want low-latency midi-thru processing, but your application
-   wants to take advantage of the input buffer and timestamped data so that
-   it does not have to operate with very low latency.
-
-   This program illustrates how to use a timer callback from PortTime to 
-   implement a low-latency process that handles midi thru, including correctly
-   merging midi data from the application with midi data from the input port.
-
-   The main application, which runs in the main program thread, will use an
-   interface similar to that of PortMidi, but since PortMidi does not allow
-   concurrent threads to share access to a stream, the application will
-   call private methods that transfer MIDI messages to and from the timer 
-   thread. All PortMidi API calls are made from the timer thread.
- */
-
-/* DESIGN
-
-All setup will be done by the main thread. Then, all direct access to 
-PortMidi will be handed off to the timer callback thread.
-
-After this hand-off, the main thread will get/send messages via a queue.
-
-The goal is to send incoming messages to the midi output while merging
-any midi data generated by the application. Sysex is a problem here
-because you cannot insert (merge) a midi message while a sysex is in
-progress. There are at least three ways to implement midi thru with 
-sysex messages:
-
-1) Turn them off. If your application does not need them, turn them off
-   with Pm_SetFilter(midi_in, PM_FILT_ACTIVE | PM_FILT_SYSEX). You will
-   not receive sysex (or active sensing messages), so you will not have 
-   to handle them.
-
-2) Make them atomic. As you receive sysex messages, copy the data into
-   a (big) buffer. Ideally, expand the buffer as needed -- sysex messages
-   do not have any maximum length. Even more ideally, use a list structure
-   and real-time memory allocation to avoid latency in the timer thread.
-   When a full sysex message is received, send it to the midi output all
-   at once.
-
-3) Process sysex incrementally. Send sysex data to midi output as it
-   arrives. Block any non-real-time messages from the application until
-   the sysex message completes. There is the risk that an incomplete
-   sysex message will block messages forever, so implement a 5-second
-   timeout: if no sysex data is seen for 5 seconds, release the block,
-   possibly losing the rest of the sysex message. 
-
-   Application messages must be processed similarly: once started, a
-   sysex message will block MIDI THRU processing. We will assume that
-   the application will not abort a sysex message, so timeouts are not
-   necessary here.
-
-This code implements (3).
-
-Latency is also an issue. PortMidi requires timestamps to be in 
-non-decreasing order. Since we'll be operating with a low-latency
-timer thread, we can just set the latency to zero meaning timestamps
-are ignored by PortMidi. This will allow thru to go through with
-minimal latency. The application, however, needs to use timestamps
-because we assume it is high latency (the whole purpose of this
-example is to illustrate how to get low-latency thru with a high-latency
-application.) So the callback thread will implement midi timing by
-observing timestamps. The current timestamp will be available in the
-global variable current_timestamp.
-
-*/
-
-
-#include "stdio.h"
-#include "stdlib.h"
-#include "string.h"
-#include "assert.h"
-#include "portmidi.h"
-#include "pmutil.h"
-#include "porttime.h"
-
-#define MIDI_SYSEX 0xf0
-#define MIDI_EOX 0xf7
-
-/* active is set true when midi processing should start */
-int active = FALSE;
-/* process_midi_exit_flag is set when the timer thread shuts down */
-int process_midi_exit_flag;
-
-PmStream *midi_in;
-PmStream *midi_out;
-
-/* shared queues */
-#define IN_QUEUE_SIZE 1024
-#define OUT_QUEUE_SIZE 1024
-PmQueue *in_queue;
-PmQueue *out_queue;
-PmTimestamp current_timestamp = 0;
-int thru_sysex_in_progress = FALSE;
-int app_sysex_in_progress = FALSE;
-PmTimestamp last_timestamp = 0;
-
-
-/* time proc parameter for Pm_MidiOpen */
-long midithru_time_proc(void *info)
-{
-    return current_timestamp;
-}
-
-
-/* timer interrupt for processing midi data.
-   Incoming data is delivered to main program via in_queue.
-   Outgoing data from main program is delivered via out_queue.
-   Incoming data from midi_in is copied with low latency to  midi_out.
-   Sysex messages from either source block messages from the other.
- */
-void process_midi(PtTimestamp timestamp, void *userData)
-{
-    PmError result;
-    PmEvent buffer; /* just one message at a time */
-
-    current_timestamp++; /* update every millisecond */
-    /* if (current_timestamp % 1000 == 0) 
-        printf("time %d\n", current_timestamp); */
-
-    /* do nothing until initialization completes */
-    if (!active) {
-        /* this flag signals that no more midi processing will be done */
-        process_midi_exit_flag = TRUE;
-        return;
-    }
-
-    /* see if there is any midi input to process */
-    if (!app_sysex_in_progress) {
-        do {
-	    result = Pm_Poll(midi_in);
-            if (result) {
-                long status;
-                if (Pm_Read(midi_in, &buffer, 1) == pmBufferOverflow) 
-                    continue;
-            
-                /* record timestamp of most recent data */
-                last_timestamp = current_timestamp;
-
-                /* the data might be the end of a sysex message that
-                   has timed out, in which case we must ignore it.
-                   It's a continuation of a sysex message if status
-                   is actually a data byte (high-order bit is zero). */
-                status = Pm_MessageStatus(buffer.message);
-                if (((status & 0x80) == 0) && !thru_sysex_in_progress) {
-                    continue; /* ignore this data */
-                }
-
-                /* implement midi thru */
-                /* note that you could output to multiple ports or do other
-                   processing here if you wanted
-                 */
-                /* printf("thru: %x\n", buffer.message); */
-                Pm_Write(midi_out, &buffer, 1);
-
-                /* send the message to the application */
-                /* you might want to filter clock or active sense messages here
-                   to avoid sending a bunch of junk to the application even if
-                   you want to send it to MIDI THRU
-                 */
-                Pm_Enqueue(in_queue, &buffer);
-
-                /* sysex processing */
-                if (status == MIDI_SYSEX) thru_sysex_in_progress = TRUE;
-                else if ((status & 0xF8) != 0xF8) {
-                    /* not MIDI_SYSEX and not real-time, so */
-                    thru_sysex_in_progress = FALSE;
-                }
-                if (thru_sysex_in_progress && /* look for EOX */
-                    (((buffer.message & 0xFF) == MIDI_EOX) ||
-                     (((buffer.message >> 8) & 0xFF) == MIDI_EOX) ||
-                     (((buffer.message >> 16) & 0xFF) == MIDI_EOX) ||
-                     (((buffer.message >> 24) & 0xFF) == MIDI_EOX))) {
-                    thru_sysex_in_progress = FALSE;
-                }
-            }
-        } while (result);
-    }
-
-
-    /* see if there is application midi data to process */
-    while (!Pm_QueueEmpty(out_queue)) {
-        /* see if it is time to output the next message */
-        PmEvent *next = (PmEvent *) Pm_QueuePeek(out_queue);
-        assert(next); /* must be non-null because queue is not empty */
-        if (next->timestamp <= current_timestamp) {
-            /* time to send a message, first make sure it's not blocked */
-            long status = Pm_MessageStatus(buffer.message);
-            if ((status & 0xF8) == 0xF8) {
-                ; /* real-time messages are not blocked */
-            } else if (thru_sysex_in_progress) {
-                /* maybe sysex has timed out (output becomes unblocked) */
-                if (last_timestamp + 5000 < current_timestamp) {
-                    thru_sysex_in_progress = FALSE;
-                } else break; /* output is blocked, so exit loop */
-            }
-            Pm_Dequeue(out_queue, &buffer);
-            Pm_Write(midi_out, &buffer, 1);
-
-            /* inspect message to update app_sysex_in_progress */
-            if (status == MIDI_SYSEX) app_sysex_in_progress = TRUE;
-            else if ((status & 0xF8) != 0xF8) {
-                /* not MIDI_SYSEX and not real-time, so */
-                app_sysex_in_progress = FALSE;
-            }
-            if (app_sysex_in_progress && /* look for EOX */
-                (((buffer.message & 0xFF) == MIDI_EOX) ||
-                 (((buffer.message >> 8) & 0xFF) == MIDI_EOX) ||
-                 (((buffer.message >> 16) & 0xFF) == MIDI_EOX) ||
-                 (((buffer.message >> 24) & 0xFF) == MIDI_EOX))) {
-                app_sysex_in_progress = FALSE;
-            }
-        } else break; /* wait until indicated timestamp */
-    }
-}
-
-
-void exit_with_message(char *msg)
-{
-#define STRING_MAX 80
-    char line[STRING_MAX];
-    printf("%s\nType ENTER...", msg);
-    fgets(line, STRING_MAX, stdin);
-    exit(1);
-}
-
-
-void initialize()
-/* set up midi processing thread and open midi streams */
-{
-    /* note that it is safe to call PortMidi from the main thread for
-       initialization and opening devices. You should not make any
-       calls to PortMidi from this thread once the midi thread begins.
-       to make PortMidi calls.
-     */
-
-    /* note that this routine provides minimal error checking. If
-       you use the PortMidi library compiled with PM_CHECK_ERRORS,
-       then error messages will be printed and the program will exit
-       if an error is encountered. Otherwise, you should add some
-       error checking to this code.
-     */
-
-    const PmDeviceInfo *info;
-    int id;
-
-    /* make the message queues */
-    in_queue = Pm_QueueCreate(IN_QUEUE_SIZE, sizeof(PmEvent));
-    assert(in_queue != NULL);
-    out_queue = Pm_QueueCreate(OUT_QUEUE_SIZE, sizeof(PmEvent));
-    assert(out_queue != NULL);
-
-    /* always start the timer before you start midi */
-    Pt_Start(1, &process_midi, 0); /* start a timer with millisecond accuracy */
-    /* the timer will call our function, process_midi() every millisecond */
-    
-    Pm_Initialize();
-
-    id = Pm_GetDefaultOutputDeviceID();
-    info = Pm_GetDeviceInfo(id);
-    if (info == NULL) {
-        printf("Could not open default output device (%d).", id);
-        exit_with_message("");
-    }
-    printf("Opening output device %s %s\n", info->interf, info->name);
-
-    /* use zero latency because we want output to be immediate */
-    Pm_OpenOutput(&midi_out, 
-                  id, 
-                  NULL /* driver info */,
-                  OUT_QUEUE_SIZE,
-                  &midithru_time_proc,
-                  NULL /* time info */,
-                  0 /* Latency */);
-
-    id = Pm_GetDefaultInputDeviceID();
-    info = Pm_GetDeviceInfo(id);
-    if (info == NULL) {
-        printf("Could not open default input device (%d).", id);
-        exit_with_message("");
-    }
-    printf("Opening input device %s %s\n", info->interf, info->name);
-    Pm_OpenInput(&midi_in, 
-                 id, 
-                 NULL /* driver info */,
-                 0 /* use default input size */,
-                 &midithru_time_proc,
-                 NULL /* time info */);
-    /* Note: if you set a filter here, then this will filter what goes
-       to the MIDI THRU port. You may not want to do this.
-     */
-    Pm_SetFilter(midi_in, PM_FILT_ACTIVE | PM_FILT_CLOCK);
-
-    active = TRUE; /* enable processing in the midi thread -- yes, this
-                      is a shared variable without synchronization, but
-                      this simple assignment is safe */
-
-}
-
-
-void finalize()
-{
-    /* the timer thread could be in the middle of accessing PortMidi stuff */
-    /* to detect that it is done, we first clear process_midi_exit_flag and
-       then wait for the timer thread to set it
-     */
-    process_midi_exit_flag = FALSE;
-    active = FALSE;
-    /* busy wait for flag from timer thread that it is done */
-    while (!process_midi_exit_flag) ;
-    /* at this point, midi thread is inactive and we need to shut down
-     * the midi input and output
-     */
-    Pt_Stop(); /* stop the timer */
-    Pm_QueueDestroy(in_queue);
-    Pm_QueueDestroy(out_queue);
-
-    Pm_Close(midi_in);
-    Pm_Close(midi_out);
-
-    Pm_Terminate();    
-}
-
-
-int main(int argc, char *argv[])
-{
-    PmTimestamp last_time = 0;
-    PmEvent buffer;
-
-    /* determine what type of test to run */
-    printf("begin PortMidi midithru program...\n");
-
-    initialize(); /* set up and start midi processing */
-	
-    printf("%s\n%s\n",
-           "This program will run for 60 seconds, or until you play middle C,",
-           "echoing all input with a 2 second delay.");
-
-    while (current_timestamp < 60000) {
-        /* just to make the point that this is not a low-latency process,
-           spin until half a second has elapsed */
-        last_time = last_time + 500;
-        while (last_time > current_timestamp) ;
-
-        /* now read data and send it after changing timestamps */
-        while (Pm_Dequeue(in_queue, &buffer) == 1) {
-            /* printf("timestamp %d\n", buffer.timestamp); */
-            /* printf("message %x\n", buffer.message); */
-            buffer.timestamp = buffer.timestamp + 2000; /* delay */
-            Pm_Enqueue(out_queue, &buffer);
-            /* play middle C to break out of loop */
-            if (Pm_MessageStatus(buffer.message) == 0x90 &&
-                Pm_MessageData1(buffer.message) == 60) {
-                goto quit_now;
-            }
-        }
-    }
-quit_now:
-    finalize();
-    exit_with_message("finished PortMidi midithru program.");
-    return 0; /* never executed, but keeps the compiler happy */
-}
diff --git a/portmidi/pm_test/midithru.dsp b/portmidi/pm_test/midithru.dsp
deleted file mode 100644
index 83f28cfcf..000000000
--- a/portmidi/pm_test/midithru.dsp
+++ /dev/null
@@ -1,102 +0,0 @@
-# Microsoft Developer Studio Project File - Name="midithru" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=midithru - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "midithru.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "midithru.mak" CFG="midithru - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "midithru - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "midithru - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "midithru - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "midithruRelease"
-# PROP Intermediate_Dir "midithruRelease"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../pm_common" /I "../porttime" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ..\Release\portmidi.lib ..\porttime\Release\porttime.lib winmm.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "midithru - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "midithruDebug"
-# PROP BASE Intermediate_Dir "midithruDebug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "midithruDebug"
-# PROP Intermediate_Dir "midithruDebug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../pm_common" /I "../porttime" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "USE_DLL_FOR_CLEANUP" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 ..\pm_win\Debug\portmidi.lib ..\porttime\Debug\porttime.lib ..\pm_win\Debug\pm_dll.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "midithru - Win32 Release"
-# Name "midithru - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\midithru.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/portmidi/pm_test/midithru.dsw b/portmidi/pm_test/midithru.dsw
deleted file mode 100644
index b244a1044..000000000
--- a/portmidi/pm_test/midithru.dsw
+++ /dev/null
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "midithread"=.\midithru.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/portmidi/pm_test/sysex.c b/portmidi/pm_test/sysex.c
deleted file mode 100644
index f49bf962f..000000000
--- a/portmidi/pm_test/sysex.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/* sysex.c -- example program showing how to send and receive sysex
-    messages
-
-   Messages are stored in a file using 2-digit hexadecimal numbers,
-   one per byte, separated by blanks, with up to 32 numbers per line:
-   F0 14 A7 4B ...
-
- */
-
-#include "stdio.h"
-#include "stdlib.h"
-#include "assert.h"
-#include "portmidi.h"
-#include "porttime.h"
-#include "string.h"
-
-#define MIDI_SYSEX 0xf0
-#define MIDI_EOX 0xf7
-
-#define STRING_MAX 80
-
-int latency = 0;
-
-/* read a number from console */
-/**/
-int get_number(char *prompt)
-{
-    char line[STRING_MAX];
-    int n = 0, i;
-    printf(prompt);
-    while (n != 1) {
-        n = scanf("%d", &i);
-        fgets(line, STRING_MAX, stdin);
-
-    }
-    return i;
-}
-
-
-/* loopback test -- send/rcv from 2 to 1000 bytes of random midi data */
-/**/
-void loopback_test()
-{
-    int outp;
-    int inp;
-    PmStream *midi_in;
-    PmStream *midi_out;
-    unsigned char msg[1024];
-    char line[80];
-    long len;
-    int i;
-    int data;
-    PmEvent event;
-    int shift;
-
-    Pt_Start(1, 0, 0);
-    
-    printf("Connect a midi cable from an output port to an input port.\n");
-    printf("This test will send random data via sysex message from output\n");
-    printf("to input and check that the correct data was received.\n");
-    outp = get_number("Type output device number: ");
-    /* Open output with 1ms latency -- when latency is non-zero, the Win32
-       implementation supports sending sysex messages incrementally in a 
-       series of buffers. This is nicer than allocating a big buffer for the
-       message, and it also seems to work better. Either way works.
-     */
-    Pm_OpenOutput(&midi_out, outp, NULL, 0, NULL, NULL, latency);
-    inp = get_number("Type input device number: ");
-    /* since we are going to send and then receive, make sure the input buffer
-       is large enough for the entire message */
-    Pm_OpenInput(&midi_in, inp, NULL, 512, NULL, NULL);
-
-    srand((unsigned int) Pt_Time()); /* seed for random numbers */
-
-    while (1) {
-        PmError count;
-        long start_time;
-        long error_position;
-        long expected = 0;
-        long actual = 0;
-        printf("Type return to send message, q to quit: ");
-        fgets(line, STRING_MAX, stdin);
-        if (line[0] == 'q') goto cleanup;
-
-        /* compose the message */
-        len = rand() % 998 + 2; /* len only counts data bytes */
-        msg[0] = (char) MIDI_SYSEX; /* start of SYSEX message */
-        /* data bytes go from 1 to len */
-        for (i = 0; i < len; i++) {
-            msg[i + 1] = rand() & 0x7f; /* MIDI data */
-        }
-        /* final EOX goes in len+1, total of len+2 bytes in msg */
-        msg[len + 1] = (char) MIDI_EOX;
-
-        /* sanity check: before we send, there should be no queued data */
-        count = Pm_Read(midi_in, &event, 1);
-
-        if (count != 0) {
-			printf("Before sending anything, a MIDI message was found in\n");
-			printf("the input buffer. Please try again.\n");
-			break;
-		}
-
-        /* send the message */
-        printf("Sending %ld byte sysex message.\n", len + 2);
-        Pm_WriteSysEx(midi_out, 0, msg);
-
-        /* receive the message and compare to msg[] */
-        data = 0;
-        shift = 0;
-        i = 0;
-        start_time = Pt_Time();
-        error_position = -1;
-        /* allow up to 2 seconds for transmission */
-        while (data != MIDI_EOX && start_time + 2000 > Pt_Time()) {
-            count = Pm_Read(midi_in, &event, 1);
-            /* CAUTION: this causes busy waiting. It would be better to 
-               be in a polling loop to avoid being compute bound. PortMidi
-               does not support a blocking read since this is so seldom
-               useful. There is no timeout, so if we don't receive a sysex
-               message, or at least an EOX, the program will hang here.
-             */
-            if (count == 0) continue;
-            
-            /* printf("read %lx ", event.message);
-               fflush(stdout); */
-            
-            /* compare 4 bytes of data until you reach an eox */
-            for (shift = 0; shift < 32 && (data != MIDI_EOX); shift += 8) {
-                data = (event.message >> shift) & 0xFF;
-                if (data != msg[i] && error_position < 0) {
-                    error_position = i;
-                    expected = msg[i];
-                    actual = data;
-                }
-                i++;
-            }
-        }
-        if (error_position >= 0) {
-            printf("Error at byte %ld: sent %lx recd %lx\n", error_position, expected, actual);
-        } else if (i != len + 2) {
-            printf("Error: byte %d not received\n", i);
-        } else {
-            printf("Correctly ");
-        }
-        printf("received %d byte sysex message.\n", i);
-    }
-cleanup:
-    Pm_Close(midi_out);
-    Pm_Close(midi_in);
-    return;
-}
-
-
-#define is_real_time_msg(msg) ((0xF0 & Pm_MessageStatus(msg)) == 0xF8)
-
-
-void receive_sysex()
-{
-    char line[80];
-    FILE *f;
-    PmStream *midi;
-    int shift = 0;
-    int data = 0;
-    int bytes_on_line = 0;
-    PmEvent msg;
-
-    /* determine which output device to use */
-    int i = get_number("Type input device number: ");
-
-    /* open input device */
-    Pm_OpenInput(&midi, i, NULL, 512, NULL, NULL);
-    printf("Midi Input opened, type file for sysex data: ");
-
-    /* open file */
-    fgets(line, STRING_MAX, stdin);
-    /* remove the newline character */
-    if (strlen(line) > 0) line[strlen(line) - 1] = 0;
-    f = fopen(line, "w");
-    if (!f) {
-        printf("Could not open %s\n", line);
-        Pm_Close(midi);
-        return;
-    }
-
-    printf("Ready to receive a sysex message\n");
-
-    /* read data and write to file */
-    while (data != MIDI_EOX) {
-        PmError count;
-        count = Pm_Read(midi, &msg, 1);
-        /* CAUTION: this causes busy waiting. It would be better to 
-           be in a polling loop to avoid being compute bound. PortMidi
-           does not support a blocking read since this is so seldom
-           useful.
-         */
-        if (count == 0) continue;
-        /* ignore real-time messages */
-        if (is_real_time_msg(Pm_MessageStatus(msg.message))) continue;
-
-        /* write 4 bytes of data until you reach an eox */
-        for (shift = 0; shift < 32 && (data != MIDI_EOX); shift += 8) {
-            data = (msg.message >> shift) & 0xFF;
-            /* if this is a status byte that's not MIDI_EOX, the sysex
-               message is incomplete and there is no more sysex data */
-            if (data & 0x80 && data != MIDI_EOX) break;
-            fprintf(f, "%2x ", data);
-            if (++bytes_on_line >= 16) {
-                fprintf(f, "\n");
-                bytes_on_line = 0;
-            }
-        }
-    }
-	fclose(f);
-    Pm_Close(midi);
-}
-
-
-void send_sysex()
-{
-    char line[80];
-    FILE *f;
-    PmStream *midi;
-    int data;
-    int shift = 0;
-    PmEvent msg;
-
-	/* determine which output device to use */
-    int i = get_number("Type output device number: ");
-
-    msg.timestamp = 0; /* no need for timestamp */
-
-	/* open output device */
-    Pm_OpenOutput(&midi, i, NULL, 0, NULL, NULL, latency);
-	printf("Midi Output opened, type file with sysex data: ");
-
-    /* open file */
-    fgets(line, STRING_MAX, stdin);
-    /* remove the newline character */
-    if (strlen(line) > 0) line[strlen(line) - 1] = 0;
-    f = fopen(line, "r");
-    if (!f) {
-        printf("Could not open %s\n", line);
-        Pm_Close(midi);
-        return;
-    }
-
-    /* read file and send data */
-    msg.message = 0;
-    while (1) {
-        /* get next byte from file */
-
-        if (fscanf(f, "%x", &data) == 1) {
-            /* printf("read %x, ", data); */
-            /* OR byte into message at proper offset */
-            msg.message |= (data << shift);
-            shift += 8;
-        }
-        /* send the message if it's full (shift == 32) or if we are at end */
-        if (shift == 32 || data == MIDI_EOX) {
-            /* this will send sysex data 4 bytes at a time -- it would
-               be much more efficient to send multiple PmEvents at once
-               but this method is simpler. See Pm_WriteSysex for a more
-               efficient code example.
-             */
-            Pm_Write(midi, &msg, 1);
-            msg.message = 0;
-            shift = 0;
-        }
-        if (data == MIDI_EOX) { /* end of message */
-            fclose(f);
-            Pm_Close(midi);
-            return;
-        }
-    }
-}
-
-
-int main()
-{
-    int i;
-    char line[80];
-    
-	/* list device information */
-	for (i = 0; i < Pm_CountDevices(); i++) {
-        const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
-        printf("%d: %s, %s", i, info->interf, info->name);
-        if (info->input) printf(" (input)");
-        if (info->output) printf(" (output)");
-        printf("\n");
-    }
-	latency = get_number("Latency in milliseconds (0 to send data immediatedly,\n"
-		                 "  >0 to send timestamped messages): ");    
-    while (1) {
-        printf("Type r to receive sysex, s to send,"
-               " l for loopback test, q to quit: ");
-        fgets(line, STRING_MAX, stdin);
-        switch (line[0]) {
-          case 'r':
-            receive_sysex();
-            break;
-          case 's':
-            send_sysex();
-            break;
-          case 'l':
-            loopback_test();
-          case 'q':
-            exit(0);
-          default:
-            break;
-        }
-    }
-    return 0;
-}
-
-
-     
-
-            
diff --git a/portmidi/pm_test/sysex.dsp b/portmidi/pm_test/sysex.dsp
deleted file mode 100644
index 329d3ef96..000000000
--- a/portmidi/pm_test/sysex.dsp
+++ /dev/null
@@ -1,102 +0,0 @@
-# Microsoft Developer Studio Project File - Name="sysex" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=sysex - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "sysex.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "sysex.mak" CFG="sysex - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "sysex - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "sysex - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "sysex - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "sysexRelease"
-# PROP Intermediate_Dir "sysexRelease"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\pm_common" /I "..\porttime" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib ..\Release\portmidi.lib ..\porttime\Release\porttime.lib ..\pm_win\Release\pm_dll.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "sysex - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "sysexDebug"
-# PROP Intermediate_Dir "sysexDebug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\pm_common" /I "..\porttime" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib ..\pm_win\Debug\portmidi.lib ..\porttime\Debug\porttime.lib ..\pm_win\Debug\pm_dll.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "sysex - Win32 Release"
-# Name "sysex - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\sysex.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/portmidi/pm_test/test.c b/portmidi/pm_test/test.c
deleted file mode 100644
index ade8564d2..000000000
--- a/portmidi/pm_test/test.c
+++ /dev/null
@@ -1,469 +0,0 @@
-#include "portmidi.h"
-#include "porttime.h"
-#include "stdlib.h"
-#include "stdio.h"
-#include "string.h"
-#include "assert.h"
-
-#define INPUT_BUFFER_SIZE 100
-#define OUTPUT_BUFFER_SIZE 0
-#define DRIVER_INFO NULL
-#define TIME_PROC ((long (*)(void *)) Pt_Time)
-#define TIME_INFO NULL
-#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
-
-#define STRING_MAX 80 /* used for console input */
-
-long latency = 0;
-
-/* crash the program to test whether midi ports are closed */
-/**/
-void doSomethingReallyStupid() {
-	int * tmp = NULL;
-	*tmp = 5;
-}
-
-
-/* exit the program without any explicit cleanup */
-/**/
-void doSomethingStupid() {
-	assert(0);
-}
-
-
-/* read a number from console */
-/**/
-int get_number(char *prompt)
-{
-    char line[STRING_MAX];
-    int n = 0, i;
-    printf(prompt);
-    while (n != 1) {
-        n = scanf("%d", &i);
-        fgets(line, STRING_MAX, stdin);
-
-    }
-    return i;
-}
-
-
-/*
- * the somethingStupid parameter can be set to simulate a program crash.
- * We want PortMidi to close Midi ports automatically in the event of a
- * crash because Windows does not (and this may cause an OS crash)
- */
-void main_test_input(unsigned int somethingStupid) {
-    PmStream * midi;
-    PmError status, length;
-    PmEvent buffer[1];
-    int num = 10;
-    int i = get_number("Type input number: ");
-    /* It is recommended to start timer before Midi; otherwise, PortMidi may
-       start the timer with its (default) parameters
-     */
-    TIME_START;
-
-    /* open input device */
-    Pm_OpenInput(&midi, 
-                 i,
-                 DRIVER_INFO, 
-                 INPUT_BUFFER_SIZE, 
-                 TIME_PROC, 
-                 TIME_INFO);
-
-    printf("Midi Input opened. Reading %d Midi messages...\n",num);
-    Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK);
-    /* empty the buffer after setting filter, just in case anything
-       got through */
-    while (Pm_Poll(midi)) {
-        Pm_Read(midi, buffer, 1);
-    }
-    /* now start paying attention to messages */
-    i = 0; /* count messages as they arrive */
-    while (i < num) {
-        status = Pm_Poll(midi);
-        if (status == TRUE) {
-            length = Pm_Read(midi,buffer, 1);
-            if (length > 0) {
-                printf("Got message %d: time %ld, %2lx %2lx %2lx\n",
-                       i,
-                       buffer[0].timestamp,
-                       Pm_MessageStatus(buffer[0].message),
-                       Pm_MessageData1(buffer[0].message),
-                       Pm_MessageData2(buffer[0].message));
-                i++;
-            } else {
-                assert(0);
-            }
-        }
-        /* simulate crash if somethingStupid is 1 or 2 */
-        if ((i > (num/2)) && (somethingStupid == 1)) {
-            doSomethingStupid();
-        } else if ((i > (num/2)) && (somethingStupid == 2)) {
-            doSomethingReallyStupid();
-        }
-    }
-
-    /* close device (this not explicitly needed in most implementations) */
-    printf("ready to close...");
-
-    Pm_Close(midi);
-    printf("done closing...");
-}
-
-
-
-void main_test_output() {
-    PmStream * midi;
-	char line[80];
-    long off_time;
-    int chord[] = { 60, 67, 76, 83, 90 };
-    #define chord_size 5 
-    PmEvent buffer[chord_size];
-    PmTimestamp timestamp;
-
-    /* determine which output device to use */
-    int i = get_number("Type output number: ");
-
-    /* It is recommended to start timer before PortMidi */
-    TIME_START;
-
-    /* open output device -- since PortMidi avoids opening a timer
-       when latency is zero, we will pass in a NULL timer pointer
-       for that case. If PortMidi tries to access the time_proc,
-       we will crash, so this test will tell us something. */
-    Pm_OpenOutput(&midi, 
-                  i, 
-                  DRIVER_INFO,
-                  OUTPUT_BUFFER_SIZE, 
-                  (latency == 0 ? NULL : TIME_PROC),
-                  (latency == 0 ? NULL : TIME_INFO), 
-                  latency);
-    printf("Midi Output opened with %ld ms latency.\n", latency);
-
-    /* output note on/off w/latency offset; hold until user prompts */
-    printf("ready to send program 1 change... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-    /* if we were writing midi for immediate output, we could always use
-       timestamps of zero, but since we may be writing with latency, we
-       will explicitly set the timestamp to "now" by getting the time.
-       The source of timestamps should always correspond to the TIME_PROC
-       and TIME_INFO parameters used in Pm_OpenOutput(). */
-    buffer[0].timestamp = TIME_PROC(TIME_INFO);
-    buffer[0].message = Pm_Message(0xC0, 0, 0);
-    Pm_Write(midi, buffer, 1);
-
-    printf("ready to note-on... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-    buffer[0].timestamp = TIME_PROC(TIME_INFO);
-    buffer[0].message = Pm_Message(0x90, 60, 100);
-    Pm_Write(midi, buffer, 1);
-    printf("ready to note-off... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-    buffer[0].timestamp = TIME_PROC(TIME_INFO);
-    buffer[0].message = Pm_Message(0x90, 60, 0);
-    Pm_Write(midi, buffer, 1);
-
-    /* output short note on/off w/latency offset; hold until user prompts */
-    printf("ready to note-on (short form)... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-    Pm_WriteShort(midi, TIME_PROC(TIME_INFO),
-                  Pm_Message(0x90, 60, 100));
-    printf("ready to note-off (short form)... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-    Pm_WriteShort(midi, TIME_PROC(TIME_INFO),
-                  Pm_Message(0x90, 60, 0));
-
-    /* output several note on/offs to test timing. 
-       Should be 1s between notes */
-    printf("chord will arpeggiate if latency > 0\n");
-    printf("ready to chord-on/chord-off... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-    timestamp = TIME_PROC(TIME_INFO);
-    for (i = 0; i < chord_size; i++) {
-        buffer[i].timestamp = timestamp + 1000 * i;
-        buffer[i].message = Pm_Message(0x90, chord[i], 100);
-    }
-    Pm_Write(midi, buffer, chord_size);
-
-    off_time = timestamp + 1000 + chord_size * 1000; 
-    while (TIME_PROC(TIME_INFO) < off_time) 
-		/* busy wait */;
-    for (i = 0; i < chord_size; i++) {
-        buffer[i].timestamp = timestamp + 1000 * i;
-        buffer[i].message = Pm_Message(0x90, chord[i], 0);
-    }
-    Pm_Write(midi, buffer, chord_size);    
-
-    /* close device (this not explicitly needed in most implementations) */
-    printf("ready to close and terminate... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-	
-    Pm_Close(midi);
-    Pm_Terminate();
-    printf("done closing and terminating...\n");
-}
-
-
-void main_test_both()
-{
-    int i = 0;
-    int in, out;
-    PmStream * midi, * midiOut;
-    PmEvent buffer[1];
-    PmError status, length;
-    int num = 10;
-    
-    in = get_number("Type input number: ");
-    out = get_number("Type output number: ");
-
-    /* In is recommended to start timer before PortMidi */
-    TIME_START;
-
-    Pm_OpenOutput(&midiOut, 
-                  out, 
-                  DRIVER_INFO,
-                  OUTPUT_BUFFER_SIZE, 
-                  TIME_PROC,
-                  TIME_INFO, 
-                  latency);
-    printf("Midi Output opened with %ld ms latency.\n", latency);
-    /* open input device */
-    Pm_OpenInput(&midi, 
-                 in,
-                 DRIVER_INFO, 
-                 INPUT_BUFFER_SIZE, 
-                 TIME_PROC, 
-                 TIME_INFO);
-    printf("Midi Input opened. Reading %d Midi messages...\n",num);
-    Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK);
-    /* empty the buffer after setting filter, just in case anything
-       got through */
-    while (Pm_Poll(midi)) {
-        Pm_Read(midi, buffer, 1);
-    }
-    i = 0;
-    while (i < num) {
-        status = Pm_Poll(midi);
-        if (status == TRUE) {
-            length = Pm_Read(midi,buffer,1);
-            if (length > 0) {
-                Pm_Write(midiOut, buffer, 1);
-                printf("Got message %d: time %ld, %2lx %2lx %2lx\n",
-					   i,
-                       buffer[0].timestamp,
-                       Pm_MessageStatus(buffer[0].message),
-                       Pm_MessageData1(buffer[0].message),
-                       Pm_MessageData2(buffer[0].message));
-                i++;
-            } else {
-                assert(0);
-            }
-        }
-    }
-
-    /* since close device should not needed, lets get
-       rid of it just to make sure program exit closes MIDI devices */
-	/* Pm_Close(midi);
-	  Pm_Close(midiOut);
-	  Pm_Terminate(); */
-}
-
-
-/* main_test_stream exercises windows winmm API's stream mode */
-/*    The winmm stream mode is used for latency>0, and sends
-   timestamped messages. The timestamps are relative (delta) 
-   times, whereas PortMidi times are absolute. Since peculiar
-   things happen when messages are not always sent in advance,
-   this function allows us to exercise the system and test it.
- */
-void main_test_stream() {
-    PmStream * midi;
-	char line[80];
-    PmEvent buffer[16];
-
-	/* determine which output device to use */
-    int i = get_number("Type output number: ");
-
-	latency = 500; /* ignore LATENCY for this test and
-				      fix the latency at 500ms */
-
-    /* It is recommended to start timer before PortMidi */
-    TIME_START;
-
-	/* open output device */
-    Pm_OpenOutput(&midi, 
-                  i, 
-                  DRIVER_INFO,
-                  OUTPUT_BUFFER_SIZE, 
-                  TIME_PROC,
-                  TIME_INFO, 
-                  latency);
-    printf("Midi Output opened with %ld ms latency.\n", latency);
-
-    /* output note on/off w/latency offset; hold until user prompts */
-    printf("ready to send output... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-
-    /* if we were writing midi for immediate output, we could always use
-       timestamps of zero, but since we may be writing with latency, we
-       will explicitly set the timestamp to "now" by getting the time.
-       The source of timestamps should always correspond to the TIME_PROC
-       and TIME_INFO parameters used in Pm_OpenOutput(). */
-    buffer[0].timestamp = TIME_PROC(TIME_INFO);
-    buffer[0].message = Pm_Message(0xC0, 0, 0);
-	buffer[1].timestamp = buffer[0].timestamp;
-	buffer[1].message = Pm_Message(0x90, 60, 100);
-	buffer[2].timestamp = buffer[0].timestamp + 1000;
-	buffer[2].message = Pm_Message(0x90, 62, 100);
-	buffer[3].timestamp = buffer[0].timestamp + 2000;
-	buffer[3].message = Pm_Message(0x90, 64, 100);
-	buffer[4].timestamp = buffer[0].timestamp + 3000;
-	buffer[4].message = Pm_Message(0x90, 66, 100);
-	buffer[5].timestamp = buffer[0].timestamp + 4000;
-	buffer[5].message = Pm_Message(0x90, 60, 0);
-	buffer[6].timestamp = buffer[0].timestamp + 4000;
-	buffer[6].message = Pm_Message(0x90, 62, 0);
-	buffer[7].timestamp = buffer[0].timestamp + 4000;
-	buffer[7].message = Pm_Message(0x90, 64, 0);
-	buffer[8].timestamp = buffer[0].timestamp + 4000;
-	buffer[8].message = Pm_Message(0x90, 66, 0);
-
-    Pm_Write(midi, buffer, 9);
-#ifdef SEND8
-	/* Now, we're ready for the real test.
-	   Play 4 notes at now, now+500, now+1000, and now+1500
-	   Then wait until now+2000.
-	   Play 4 more notes as before.
-	   We should hear 8 evenly spaced notes. */
-	now = TIME_PROC(TIME_INFO);
-	for (i = 0; i < 4; i++) {
-		buffer[i * 2].timestamp = now + (i * 500);
-		buffer[i * 2].message = Pm_Message(0x90, 60, 100);
-		buffer[i * 2 + 1].timestamp = now + 250 + (i * 500);
-		buffer[i * 2 + 1].message = Pm_Message(0x90, 60, 0);
-	}
-    Pm_Write(midi, buffer, 8);
-
-    while (Pt_Time() < now + 2500) 
-		/* busy wait */;
-	/* now we are 500 ms behind schedule, but since the latency
-	   is 500, the delay should not be audible */
-	now += 2000;
-	for (i = 0; i < 4; i++) {
-		buffer[i * 2].timestamp = now + (i * 500);
-		buffer[i * 2].message = Pm_Message(0x90, 60, 100);
-		buffer[i * 2 + 1].timestamp = now + 250 + (i * 500);
-		buffer[i * 2 + 1].message = Pm_Message(0x90, 60, 0);
-	}
-    Pm_Write(midi, buffer, 8);
-#endif
-    /* close device (this not explicitly needed in most implementations) */
-    printf("ready to close and terminate... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-	
-    Pm_Close(midi);
-    Pm_Terminate();
-    printf("done closing and terminating...\n");
-}
-
-
-void show_usage()
-{
-    printf("Usage: test [-h] [-l latency-in-ms]\n");
-    exit(0);
-}
-
-int main(int argc, char *argv[])
-{
-    int i = 0, n = 0;
-    char line[STRING_MAX];
-    int test_input = 0, test_output = 0, test_both = 0, somethingStupid = 0;
-	int stream_test = 0;
-	int latency_valid = FALSE;
-    
-    for (i = 1; i < argc; i++) {
-        if (strcmp(argv[i], "-h") == 0) {
-            show_usage();
-        } else if (strcmp(argv[i], "-l") == 0 && (i + 1 < argc)) {
-            i = i + 1;
-            latency = atoi(argv[i]);
-            printf("Latency will be %ld\n", latency);
-			latency_valid = TRUE;
-        } else {
-            show_usage();
-        }
-    }
-
-	while (!latency_valid) {
-		printf("Latency in ms: ");
-		if (scanf("%ld", &latency) == 1) {
-			latency_valid = TRUE;
-		}
-	}
-
-    /* determine what type of test to run */
-    printf("begin portMidi test...\n");
-    printf("%s%s%s%s%s",
-           "enter your choice...\n    1: test input\n",
-           "    2: test input (fail w/assert)\n",
-           "    3: test input (fail w/NULL assign)\n",
-           "    4: test output\n    5: test both\n",
-	       "    6: stream test\n");
-    while (n != 1) {
-        n = scanf("%d", &i);
-        fgets(line, STRING_MAX, stdin);
-        switch(i) {
-        case 1: 
-            test_input = 1;
-            break;
-        case 2: 
-            test_input = 1;
-            somethingStupid = 1;
-            break;
-        case 3: 
-            test_input = 1;
-            somethingStupid = 2;
-            break;
-        case 4: 
-            test_output = 1;
-            break;
-        case 5:
-            test_both = 1;
-            break;
-		case 6:
-			stream_test = 1;
-			break;
-        default:
-            printf("got %d (invalid input)\n", n);
-            break;
-        }
-    }
-    
-    /* list device information */
-    for (i = 0; i < Pm_CountDevices(); i++) {
-        const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
-        if (((test_input  | test_both) & info->input) |
-            ((test_output | test_both | stream_test) & info->output)) {
-            printf("%d: %s, %s", i, info->interf, info->name);
-            if (info->input) printf(" (input)");
-            if (info->output) printf(" (output)");
-            printf("\n");
-        }
-    }
-    
-    /* run test */
-	if (stream_test) {
-		main_test_stream();
-	} else if (test_input) {
-        main_test_input(somethingStupid);
-    } else if (test_output) {
-        main_test_output();
-    } else if (test_both) {
-        main_test_both();
-    }
-    
-    printf("finished portMidi test...type ENTER to quit...");
-    fgets(line, STRING_MAX, stdin);
-    return 0;
-}
diff --git a/portmidi/pm_test/test.dsp b/portmidi/pm_test/test.dsp
deleted file mode 100644
index 66ba3e913..000000000
--- a/portmidi/pm_test/test.dsp
+++ /dev/null
@@ -1,102 +0,0 @@
-# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=test - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "test.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "test.mak" CFG="test - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "test - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "test - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "testRelease"
-# PROP Intermediate_Dir "testRelease"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../pm_common" /I "../porttime" /D "WIN32" /D "DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib ..\Release\portmidi.lib ..\porttime\Release\porttime.lib ..\pm_win\Release\pm_dll.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "test - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "testDebug"
-# PROP Intermediate_Dir "testDebug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../pm_common" /I "../porttime" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "USE_DLL_FOR_CLEANUP" /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib ..\pm_win\Debug\portmidi.lib ..\porttime\Debug\porttime.lib ..\pm_win\Debug\pm_dll.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "test - Win32 Release"
-# Name "test - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\test.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/portmidi/pm_test/txdata.syx b/portmidi/pm_test/txdata.syx
deleted file mode 100644
index 1e06e5a6e..000000000
--- a/portmidi/pm_test/txdata.syx
+++ /dev/null
@@ -1,257 +0,0 @@
-20  0 1d  4  c  6  0 34  1 4d  4  d 1f  7  3  6 
- c 5e  4 4d  d  b 18  5  3  6  0 3d  1 4a 16 18 
-1f  8  3  6  d  0  1 63  4 13 3a 23  0  0  0  2 
- c  2  4  0 63 32  0  0  0 32  0 47 72 61 6e 64 
-50 69 61 6e 6f 63 63 63 32 32 32  0  0  0  0  0 
-10  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f  9  9  f  c 27  2 35 37 10 1f  4  3  4 
- d 19  4 56  5 16 1f  f  8  d  c  0 43 60  4  e 
-1f  c  3  7  e  0 43 63  5 10 3c 14  8  2 1b 56 
- 5  2  4  0 63 32  0  0  0 32  0 4c 6f 54 69 6e 
-65 38 31 5a 20 63 63 63 32 32 32  0 7f  0  1  0 
-18  0  1  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f  e  f  e  9  0  3 43 2d  e 1f  f  5  7 
- f 16 43 5a  0  0 1f 12  6  8  d  0  3 63  4  0 
-1f 12  6  8  f  0  2 63  4  6 34 14  0  1  2 4e 
-18  2  4  0 63 32  0 32  0 32  0 44 79 6e 6f 6d 
-69 74 65 45 50 63 63 63 32 32 32  0 70  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f  b  1  b  8 18 40 5f  a  e 1f 1f  0  a 
- f  0 40 5f  4  0 1f 1f  0  a  f  0 40 63  5  6 
-1f 1f  0  a  f  0 40 5f  0  8 1f 20  0  3  0 5a 
-18  4  4  0 63 32 32  0  0 32  0 50 65 72 63 4f 
-72 67 61 6e 20 63 63 63 32 32 32  0  0  0  0  0 
- 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f  b  7  f  9  0  4 49 13 13 1f  8  7  5 
- e  0  2 58  0  c 1f  6  4  6  f 23  3 46 10  a 
-1f  7  8  c  d  0  2 63  8  b  2 1c  0  0  0 52 
-18  4  4  0 63 32  0 32  0 32  0 54 68 69 6e 20 
-43 6c 61 76 20 63 63 63 32 32 32  0 70  0 20  0 
-10  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f  c  0  6  1  a  4 50 20  e 1f  c  0  6 
- 1  a  4 50 1f  8 1f  b  9  5  e  0  2 63  5  e 
-1f  b  9  5  e  0  3 63  4  8  4 1a  0  0  0 52 
-1d  2  4  0 63 32  0 32  0 32  0 42 72 69 74 65 
-43 65 6c 73 74 63 63 63 32 32 32  0 20  0 26  0 
- 1  0  8  4  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  f 1f  4  8  f  0 3a 51  4  b  e 1f  0  8 
- f  0 22 4b  4  3  f 1a  b  8  d  0 3b 36  9  3 
-12 1f  0  8  f  0 22 5d  4  b 3a 1e 19  5  0 52 
-18  4  4  0 63 32  0  0  0 32  0 54 72 75 6d 70 
-65 74 38 31 5a 63 63 63 32 32 32  0  0  0 50  0 
-51  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  c  5  0  8  0  0  2 4a  4  b  f 1f  0  8 
- f  0  2 3f  4  3 1f  f  0  8  0 23  3 44  b  3 
-10 1f  0  9  f  0  2 5e  4  c 3a 1f 19  7  0 52 
-18  4  4  0 63 32  0  0  0 32  0 46 6c 75 67 65 
-6c 68 6f 72 6e 63 63 63 32 32 32  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 10 1f  0  8  f  0 42 4a  0  3 11 1f  0  8 
- f  a 43 51  0  3 11  9  0  8  d  0 42 2b 16  6 
-10 1f  0  9  f  0 42 63  4  b 3a 1e  9  9  0 5a 
-24  4  4  0 63 32 31  0  0 32  0 52 61 73 70 41 
-6c 74 6f 20 20 63 63 63 32 32 32  0 10  0 20  0 
-54  0 20  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 10  9  2  6  d  0 41 3e  4 15  c  b  2  3 
- e  0 41 4f  4 12  c  e  2  8  d  0 42 4b  a 1c 
- d  b  1  9  e  0  3 63  a 14  0 23  f  2 1b 5e 
-18  4  5  0 63 28 50 32  0 32  0 48 61 72 6d 6f 
-6e 69 63 61 20 63 63 63 32 32 32  0 50 10 50  0 
-50  0 10  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1c  2  0  4  e 63  0 4e  4  3  d  5  0  6 
- e 63  1 56  a  8 12  7  0  6  9 63  2 47 1b  e 
- a  a  0  5  f  0  1 63  4  b 32 1a  8  d  0 52 
- c  4  4  0 63 32  0  0  0 32  0 44 6f 75 62 6c 
-65 42 61 73 73 63 63 63 32 32 32  0 10  0  0  0 
- 3  0  0  5  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  b  4  0  4  f 14  2 49  9  6  a  7  0  4 
- f 14  2 51  a  0  8 1f  0  5  f  0  1 63  9  6 
- a 1f  0  5  f  0  1 63  a  0 3c 1f  6  9  0 52 
- 5  4  4  0 63 32  0  0  0 32  0 48 69 53 74 72 
-69 6e 67 20 31 63 63 63 32 32 32  0  2  0 30  0 
-32  0 10  5  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 10 13  f  4  a  0  3 3b 14 14 1f  e  8  7 
- 9  0  2 42  5  e 18 13  d  9  c  0  2 3c 13  8 
-1f 11  7  4  f  0 42 63  4 10 3a 1b  0  0  0 52 
-1d  4  4  0 63 32  0  0  0 32  0 48 61 72 70 20 
-20 20 20 20 20 63 63 63 32 32 32  8  0  0 21  0 
- 0  0  8  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f  6  6  4  f  0 40 48  5  0  c  8  7  5 
- f  5  0 52  4  0  f  7  3  7  e  8  3 63  4  6 
- f  8  4  5  f  0  3 63  4  6 7c 1f  0  6  0 4a 
-11  2  4  0 63 32  0  0  0 32  0 46 61 6e 66 61 
-72 54 70 74 73 63 63 63 32 32 32  6  1  0 38  0 
- 8  0 48  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  d  b  0  1  c  0  2 2c 3d  3  d  7  0  1 
- c  0  2 1f 3c  3  d 1f  0  5  f  0  2 63  5  6 
- d 1f  0  5  f  0  2 63  4  0 3c 63  0 2f  0 53 
-11  4  4  0 63 32  0  0  0 32  0 42 72 65 61 74 
-68 4f 72 67 6e 63 63 63 32 32 32  4 30  5 50  0 
-11  0 18  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f  9  0  6  0 27  2 51 19  b 1c  6  0  8 
- 0 37  2 47  a  3 1f  a  0  9  0 3d  2 4d  a  e 
-1f 12  8  8  f  0  3 61  4  b 28 1f  0  3  0 52 
- c  3  4  0 63 32  1 32  0 32  0 4e 79 6c 6f 6e 
-47 75 69 74 20 63 63 63 32 32 32  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f  e  e  f  f  0  3 48 2d  6 1f  f  4  f 
- f 25  3 5b  0  0 1f 12  6  c  e 1c  3 55  0 10 
-1f 13  7  8  e  6  4 62  4  e 3b 14  0  0  0 42 
-18  2  4  0 63 32  0 32  0 32  0 47 75 69 74 61 
-72 20 23 31 20 63 63 63 32 32 32  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f 19  8  a  3  0  3 63 10 18 1f  c  5  b 
- 5  0  3 52  0  b 1f 19  6  b  5  0  3 63  a 16 
-1f  f 11  9  7  0  4 63  4  3 3a 14  0  0  0 42 
-18  2  4  0 63 32  0 32  0 32  0 46 75 6e 6b 79 
-20 50 69 63 6b 63 63 63 32 32 32  0 30  0  0  0 
- 0  0  0  7  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f  1  0  8  4  0  3 3d  a 1e 1f  1  0  8 
- 0  0  0 43  0 10 1f  9  6  8  c 1b  7 46 1c 1e 
-1f  9  0  9  9  0  1 63  4  3 3a 1c  0  0  0 52 
- c  4  5  0 63 4b  0  0  0 32  0 45 6c 65 63 42 
-61 73 73 20 31 63 63 63 32 32 32  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f  f  f  e  9  0  3 46 1d 16 1f  f  5  e 
- e  d  3 63  0  b 1f 13  6  5  d 1c  3 63  0  0 
-1f 13  6  8  f  0  4 63  4  6 3b 1f  0  0  0 42 
- c  4  4  0 63 32  0 32  0 32  0 53 79 6e 46 75 
-6e 6b 42 61 73 63 63 63 32 32 32  d 6c  0  0  0 
-70  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f 10  7  8  3  0  3 4f  4  3 1f  9  0  8 
- 0  0  1 4a  0  b 1f 11  0  8  0  0  1 47  4  8 
-1f  9  0  8  0  0  0 63  0  b 39 19  0  7  0 52 
- c  2  4  0 63 32  0 32  0 32  0 4c 61 74 65 6c 
-79 42 61 73 73 63 63 63 32 32 32  2  0  0  0  0 
-40  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 13 12  0  9  d 22  0 51  0  b 1f 14  0  5 
- 8 24 40 5c  0  3 1f 11  0  6  c 2c  0 53  9  0 
-10 1f  0  b  f  0  0 5c  a  e 3a 22 11  e 1e 5e 
-18  7  4  0 63 32  0 32  0 32  0 53 79 6e 63 20 
-4c 65 61 64 20 63 63 63 32 32 32  0 70  0 40  0 
- 2  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 13 1e  0  9  e  0  0 63 3f  b 1f 14  0  5 
- e 24  1 51  4  3 1f 14  0  f  1  0 41 4d  8  3 
- f 1f  0  b  f  0  2 63  4  b 3b 20 11 12 33 56 
-18  4  4  0 63 37  e  0  0 32  0 4a 61 7a 7a 20 
-46 6c 75 74 65 63 63 63 32 32 32  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 15 13  d  3  d 1e  2 50 18  e 15 14  9  4 
- c 1e  2 56 11  8 1b 1f  f  7  f  0  1 63  4  6 
-1a 1f  e  6  f  0  2 63  4  0 7c  b  0  8  0 62 
-18  4  4  0 63 32  0  0  0 32  0 4a 61 76 61 20 
-4a 69 76 65 20 63 63 63 32 32 32  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f  0  0  4  f  0 40 63 3c  0  b  8  7  7 
- f  5  0 63  4  6  f  5  3  7  f  8  0 3b  5  6 
- e  8  4  5  f  0  3 63  3  0 7e 1d  6  f  0 4a 
-11  0  4  0 63 32  0  0  0 32  0 42 61 61 64 42 
-72 65 61 74 68 63 63 63 32 32 32  6 30  0 38  0 
- 1  0 46  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f  0  0  4  f  0 40 47 2f  0  e  8  7  7 
- f  5  0 4c  0  6 13 1c  d  c  6  8  0 63  5  6 
-14 11  d  b  0  0  3 63  4  0 7a 10  0 51  0 68 
-17  0  4  0 63 32  0  0  0 32  0 56 6f 63 61 6c 
-4e 75 74 73 20 63 63 63 32 32 32  6 30  0 30  0 
- 1  0 10  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f 1f  0  5  f  0  0 41 32  3 1f 14 10  5 
- 5  1  2 63  7  3 1f  b 12  8  f  0  1 63  c  3 
-1f 1f  f  8  f  0  1 63  4  3 39 23  0  0  0 62 
-18  7  4  0 63 32  0  0  0 32  0 57 61 74 65 72 
-47 6c 61 73 73 63 63 63 32 32 32  0  0  0  0  0 
- 0  0  0  7  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 16  2  0  4  6  9  1 4f  8  0 19  e  1  4 
- 0 20  1 43 19  0 1f 12 10  6  7  0  0 54 3d  3 
-16  d  6  6  2 1e  3 61  8  e 3a 20  1 14  0 42 
- c  2  4  2 63 63 63  0  0 32  0 46 75 7a 7a 79 
-20 4b 6f 74 6f 63 63 63 32 32 32  0  0  0  0  b 
-50  0  0  5  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1c  8  0  3  e  0  1 55 12  3 1c  7  0  1 
- e 2e  1 58 27  b  e  4  0  2  a  0  2 63  4  a 
- d  9  0  2  c  1  2 63 10  b  4 54  0 47  0 53 
-18  7  4  0 63 32  0  0  0 32  0 42 72 74 68 62 
-65 6c 6c 73 20 63 63 63 32 32 32  0  4  0 40  0 
-40  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1a  4  1  1  b 16  0 47  5  3 15  e  0  1 
- d  0  0 4c  5 16 1c  6  4  2  7  0  0 63  4 16 
-18 18  3  1  e  0  0 5e  4 10 24  7  0  4  0 62 
-24  4  4  0 63 32  0  0  0 32  0 54 75 62 65 20 
-42 65 6c 6c 73 63 63 63 32 32 32  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f 1f 13  3  0  0  0 5f 3d  6 1f 12 13  2 
- 0  0  1 52  5  2 1f 14 13  3  0  0  1 56 28  5 
-1e  b 13  f  9  0  0 63  6  3 3b 63  0 63  0 73 
-23  7  4  0 63 32  0  0  0 32  0 4e 6f 69 73 65 
-20 53 68 6f 74 63 63 63 32 32 32  8  0  0  0  8 
- 0  0  0  6  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 1f 16  0  3  7  0  1 50  0  3 1f 18  3  3 
- 3 22  0 63  0 14 1d  7  6  3  6  0  1 3c  8  3 
-1f  5  7  3  0  0  1 63  4 1b 39 23  0  8  0 42 
-18  4  4  0 63 32  0  0  0 32  0 48 61 6e 64 20 
-44 72 75 6d 20 63 63 63 32 32 32  0  1  0  3  0 
- 1  0  1  3  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
- 0  0 7d f7 
\ No newline at end of file
diff --git a/portmidi/pm_win/README_WIN.txt b/portmidi/pm_win/README_WIN.txt
deleted file mode 100644
index df120e960..000000000
--- a/portmidi/pm_win/README_WIN.txt
+++ /dev/null
@@ -1,183 +0,0 @@
-File: PortMidi Win32 Readme
-Author: Belinda Thom, June 16 2002
-Revised by: Roger Dannenberg, June 2002, May 2004
-
-=============================================================================
-USING PORTMIDI:
-=============================================================================
-
-PortMidi has been created using a DLL because the Win32 MMedia API doesn't 
-handle midiInput properly in the debugger. Specifically, it doesn't clean up
-after itself if the user (i.e. you, a PortMidi application) hasn't explicitly
-closed all open midi input devices. This lack of cleanup can lead to much
-pain and agony, including the blue-screen-of-death. This situation becomes
-increasingly unacceptable when you are debugging your code, so a portMidi DLL
-seemed to be the most elegant solution.
-
-Using Microsoft Visual C++ project files (provided with PortMidi), there
-are two configurations of the PortMidi library. The Debug version is 
-intended for debugging, especially in a console application. The Debug
-version enables some extra error checking and outputs some text as well
-as a prompt to type ENTER so that you don't lose any debugging text when
-the program exits. You can turn off this extra debugging info by taking
-out the compile-time definition for DEBUG. This debugging version also
-defines PM_CHECK_ERRORS, which forces a check for error return codes from
-every call to PortMidi. You can disable this checking (especially if you
-want to handle error codes in your own way) by removing PM_CHECK_ERRORS
-from the predefined symbols list in the Settings dialog box.
-
-PortMidi is designed to run without a console and should work perfectly 
-well within a graphical user interface application. The Release version
-is both optimized and lacking the debugging printout code of the Debug
-version.
-
-Read the portmidi.h file for PortMidi API details on using the PortMidi API.
-See <...>\pm_dll_test\test.c or <...>\multithread\test.c for usage examples.
-
-=============================================================================
-TO INSTALL PORTMIDI:
-=============================================================================
-1)  download portmidi.zip
-
-2)  unzip portmidi.zip into directory: <...>\portmidi
-
-=============================================================================
-TO COMPILE PORTMIDI:
-=============================================================================
-
-3)  go to this directory
-
-4)  click on the portmidi.dsw workspace
-
-5)  the following projects exist within this workspace:
-    - portmidi (the PortMidi library)
-	- pm_dll (the dll library used to close midi ports on program exit)
-	- porttime (a small portable library implementing timer facilities)
-	- test (simple midi I/O testing)
-	- multithread (an example illustrating low-latency MIDI processing
-            using a dedicated low-latency thread)
-	- sysex (simple sysex message I/O testing)
-	- latency (uses porttime to measure system latency)
-
-6)  verify that all project settings are for Win32 Debug release:
-	- hit Alt-F7
-	- highlight all three projects in left part of Project Settings window; 
-	- "Settings For" should say "Win32 Debug"
-
-7)  set pm_dll as the active project (e.g. Project->Select Active Project)
-
-8)  use Build->Batch Build ... to build everything in the project
-
-9)  The settings for these projects were distributed in the zip file, so
-    compile should just work.
-
-10) IMPORTANT! PortMidi uses a DLL, pm_dll.dll, but there is no simple way
-    to set up projects to use pm_dll. THEREFORE, you need to copy DLLs
-    as follows (you can do this with <...>\portmidi\pm_win\copy-dll.bat):
-        copy <...>\portmidi\pm_win\Debug\pm_dll.dll to:
-            <...>\portmidi\pm_test\latencyDebug\pm_dll.dll
-            <...>\portmidi\pm_test\midithreadDebug\pm_dll.dll
-            <...>\portmidi\pm_test\sysexDebug\pm_dll.dll
-            <...>\portmidi\pm_test\testDebug\pm_dll.dll
-            <...>\portmidi\pm_test\midithruDebug\pm_dll.dll
-        and copy <...>\portmidi\pm_win\Release\pm_dll.dll to:
-            <...>\portmidi\pm_test\latencyRelease\pm_dll.dll
-            <...>\portmidi\pm_test\midithreadRelease\pm_dll.dll
-            <...>\portmidi\pm_test\sysexRelease\pm_dll.dll
-            <...>\portmidi\pm_test\testRelease\pm_dll.dll
-            <...>\portmidi\pm_test\midithruRelease\pm_dll.dll
-    each time you rebuild the pm_dll project, these copies must be redone!
-
-    Since Windows will look in the executable directory for DLLs, we 
-    recommend that you always install a copy of pm_dll.dll (either the
-    debug version or the release version) in the same directory as the
-    application using PortMidi. The release DLL is about 40KB. This will 
-    ensure that the application uses the correct DLL.
-
-11) run test project; use the menu that shows up from the command prompt to
-    test that portMidi works on your system. tests include: 
-		- verify midi output works
-		- verify midi input works
-		- verify midi input w/midi thru works
-
-12) run other projects if you wish: sysex, latency, and midithread
-
-============================================================================
-TO CREATE YOUR OWN PORTMIDI CLIENT APPLICATION:
-============================================================================
-
-NOTE: this section needs to be reviewed and tested. My suggestion would
-be to copy the test project file (test.dsp) and modify it. -RBD
-
-The easiest way is to start a new project w/in the portMidi workspace:
-
-1) To open new project: 
-	- File->New->Projects
-	- Location: <...>\portmidi\<yourProjectName>
-	- check Add to current workspace
-	- select Win32 Console Application (recommended for now)
-	- do *NOT* select the "make dependency" box (you will explicitly do this
-      in the next step)
-	- Click OK
-	- Select "An Empty Project" and click Finish
-
-2) Now this project will be the active project. Make it explicitly depend
-   on PortMidi dll:
-	- Project->Dependencies
-	- Click pm_dll
-
-3) Important! in order to be able to use portMidi DLL from your new project
-   and set breakpoints,	copy following files from <...>\pm_dll\Debug into 
-   <...>\<yourProjectName>\Debug directory:
-		pm_dll.lib
-		pm_dll.dll
-    each time you rebuild pm_dll, these copies must be redone!
-
-4) add whatever files you wish to add to your new project, using portMidi
-   calls as desired (see USING PORTMIDI at top of this readme)
-
-5) when you include portMidi files, do so like this:
-	- #include "..\pm_dll\portmidi.h"
-	- etc.
-
-6) build and run your project
-
-============================================================================
-DESIGN NOTES
-============================================================================
-
-The DLL is used so that PortMidi can (usually) close open devices when the
-program terminates. Failure to close input devices under WinNT, Win2K, and
-probably later systems causes the OS to crash.
-
-This is accomplished with a .LIB/.DLL pair, linking to the .LIB
-in order to access functions in the .DLL. 
-
-PortMidi for Win32 exists as a simple library,
-with Win32-specific code in pmwin.c and MM-specific code in pmwinmm.c.
-pmwin.c uses a DLL in pmdll.c to call Pm_Terminate() when the program
-exits to make sure that all MIDI ports are closed.
-
-Orderly cleanup after errors are encountered is based on a fixed order of
-steps and state changes to reflect each step. Here's the order:
-
-To open input:
-    initialize return value to NULL
-    - allocate the PmInternal strucure (representation of PortMidiStream)
-    return value is (non-null) PmInternal structure
-    - allocate midi buffer
-    set buffer field of PmInternal structure
-    - call system-dependent open code
-        - allocate midiwinmm_type for winmm dependent data
-        set descriptor field of PmInternal structure
-        - open device
-        set handle field of midiwinmm_type structure
-        - allocate buffer 1 for sysex
-        buffer is added to input port
-        - allocate buffer 2 for sysex
-        buffer is added to input port
-        - return
-    - return
-
-
-
diff --git a/portmidi/pm_win/copy-dll.bat b/portmidi/pm_win/copy-dll.bat
deleted file mode 100644
index 34ccbeddf..000000000
--- a/portmidi/pm_win/copy-dll.bat
+++ /dev/null
@@ -1,13 +0,0 @@
-copy Debug\pm_dll.dll ..\pm_test\testDebug\pm_dll.dll
-copy Debug\pm_dll.dll ..\pm_test\sysexDebug\pm_dll.dll
-copy Debug\pm_dll.dll ..\pm_test\midithreadDebug\pm_dll.dll
-copy Debug\pm_dll.dll ..\pm_test\latencyDebug\pm_dll.dll
-copy Debug\pm_dll.dll ..\pm_test\midithruDebug\pm_dll.dll
-
-copy Release\pm_dll.dll ..\pm_test\testRelease\pm_dll.dll
-copy Release\pm_dll.dll ..\pm_test\sysexRelease\pm_dll.dll
-copy Release\pm_dll.dll ..\pm_test\midithreadRelease\pm_dll.dll
-copy Release\pm_dll.dll ..\pm_test\latencyRelease\pm_dll.dll
-copy Release\pm_dll.dll ..\pm_test\midithruRelease\pm_dll.dll
-
-
diff --git a/portmidi/pm_win/debugging_dlls.txt b/portmidi/pm_win/debugging_dlls.txt
deleted file mode 100644
index 82b81a5b5..000000000
--- a/portmidi/pm_win/debugging_dlls.txt
+++ /dev/null
@@ -1,145 +0,0 @@
-========================================================================================================================
-Methods for Debugging DLLs
-========================================================================================================================
-If you have the source for both the DLL and the calling program, open the project for the calling executable file and 
-debug the DLL from there. If you load a DLL dynamically, you must specify it in the Additional DLLs category of the 
-Debug tab in the Project Settings dialog box. 
-
-If you have the source for the DLL only, open the project that builds the DLL. Use the Debug tab in the Project 
-Settings dialog box to specify the executable file that calls the DLL.
-
-You can also debug a DLL without a project. For example, maybe you just picked up a DLL and source code but you 
-don’t have an associated project or workspace. You can use the Open command on the File menu to select the .DLL 
-file you want to debug. The debug information should be in either the .DLL or the related .PDB file. After 
-Visual C++ opens the file, on the Build menu click Start Debug and Go to begin debugging.
-
-To debug a DLL using the project for the executable file 
-
-From the Project menu, click Settings. 
-The Project Settings dialog box appears.
-
-Choose the Debug tab.
-
-
-In the Category drop-down list box, select General. 
-
-
-In the Program Arguments text box, type any command-line arguments required by the executable file.
-
-
-In the Category drop-down list box, select Additional DLLs.
-
-
-In the Local Name column, type the names of DLLs to debug. 
-If you are debugging remotely, the Remote Name column appears. In this column, type the complete path for the 
-remote module to map to the local module name.
-
-In the Preload column, select the check box if you want to load the module before debugging begins.
-
-
-Click OK to store the information in your project.
-
-
-From the Build menu, click Start Debug and Go to start the debugger. 
-You can set breakpoints in the DLL or the calling program. You can open a source file for the DLL and set breakpoints 
-in that file, even though it is not a part of the executable file’s project.
-
-To debug a DLL using the project for the DLL 
-
-From the Project menu, click Settings. 
-The Project Settings dialog box appears.
-
-Choose the Debug tab.
-
-
-In the Category drop-down list box, select General. 
-
-
-In the Executable For Debug Session text box, type the name of the executable file that calls the DLL.
-
-
-In the Category list box, select Additional DLLs.
-
-
-In the Local Module Name column, type the name of the DLLs you want to debug.
-
-
-Click OK to store the information in your project.
-
-
-Set breakpoints as required in your DLL source files or on function symbols in the DLL.
-
-
-From the Build menu, click Start Debug and Go to start the debugger. 
-To debug a DLL created with an external project 
-
-From the Project menu, click Settings. 
-The Project Settings dialog box appears.
-
-Choose the Debug tab.
-
-
-In the Category drop-down list box, select General.
-
-
-In the Executable For Debug Session text box, type the name of the DLL that your external makefile builds. 
-
-
-Click OK to store the information in your project.
-
-
-Build a debug version of the DLL with symbolic debugging information, if you don’t already have one.
-
-
-Follow one of the two procedures immediately preceding this one to debug the DLL. 
-
-========================================================================================================================
-Why Don’t My DLL Breakpoints Work?
-========================================================================================================================
-Some reasons why your breakpoints don’t work as expected are listed here, along with solutions or work-arounds for each. 
-If you follow the instructions in one topic and are still having breakpoint problems, look at some of the other topics. 
-Often breakpoint problems result from a combination of conditions. 
-
-You can't set a breakpoint in a source file when the corresponding symbolic information isn't loaded into memory by 
-the debugger. 
-You cannot set a breakpoint in any source file when the corresponding symbolic information will not be loaded into memory 
-by the debugger. 
-Symptoms include messages such as "the breakpoint cannot be set" or a simple, noninformational beep.
-
-When setting breakpoints before the code to be debugged has been started, the debugger uses a breakpoint list to keep 
-track of how and where to set breakpoints. When you actually begin the debugging session, the debugger loads the symbolic 
-information for all the code to be debugged and then walks through its breakpoint list, attempting to set the 
-breakpoints. 
-
-However, if one or more of the code modules have not been designated to the debugger, there will be no symbolic 
-information for the debugger to use when walking through its breakpoint list. Situations where this is likely to 
-occur include: 
-
-Attempts to set breakpoints in a DLL before the call to LoadLibrary.
-
-Setting a breakpoint in an ActiveX server before the container has started the server.
-
-Other similar cases. 
-
-To prevent this behavior in Visual C++, specify all additional DLLs and COM servers in the Additional DLLs field 
-in the Debug/Options dialog box to notify the debugger that you want it to load symbolic debug information for 
-additional .DLL files. When this has been done, breakpoints set in code that has not yet been loaded into memory 
-will be "virtual" breakpoints. When the code is actually loaded into memory by the loader, these become physical 
-breakpoints. Make sure that these additional debugging processes are not already running when you start your 
-debugging session. The debugging process and these additional processes must be sychronized at the same beginning 
-point to work correctly, hitting all breakpoints. 
-
-Breakpoints are missed when more than one copy of a DLL is on your hard disk. 
-Having more than one copy of a DLL on your hard drive, especially if it is in your Windows directory, can cause 
-debugger confusion. The debugger will load the symbolic information for the DLL specified to it at run time (with the 
-Additional DLLs field in the Debug/Options dialog box), while Windows has actually loaded a different copy of the 
-DLL itself into memory. Because there is no way to force the debugger to load a specific DLL, it is a good idea to 
-keep only one version of a DLL at a time in your path, current directory, and Windows directory. 
-
-You can’t set "Break When Expression Has Changed" breakpoints on a variable local to a DLL. 
-Setting a "Break When Expression Has Changed" breakpoint on a variable local to a DLL function before the call 
-to LoadLibrary causes the breakpoint to be virtual (there are no physical addresses for the DLL in memory yet). 
-Virtual breakpoints involving expressions pose a special problem. The DLL must be specified to the debugger at 
-startup (causing its symbolic information to be loaded). In addition, the DLL's executable code must also be loaded 
-into memory before this kind of breakpoint can be set. This means that the calling application's code must be 
-executed to the point after its call to LoadLibrary before the debugger will allow this type of breakpoint to be set. 
diff --git a/portmidi/pm_win/pm_dll.dsp b/portmidi/pm_win/pm_dll.dsp
deleted file mode 100644
index d08e2de77..000000000
--- a/portmidi/pm_win/pm_dll.dsp
+++ /dev/null
@@ -1,107 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pm_dll" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=pm_dll - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "pm_dll.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "pm_dll.mak" CFG="pm_dll - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "pm_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "pm_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "pm_dll - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "pm_win\Release"
-# PROP Intermediate_Dir "pm_win\Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PM_DLL_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PM_DLL_EXPORTS" /YX /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-
-!ELSEIF  "$(CFG)" == "pm_dll - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "pm_win\Debug"
-# PROP Intermediate_Dir "pm_win\Debug"
-# PROP Ignore_Export_Lib 1
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PM_DLL_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "pm_common" /D "_WINDOWS" /D "_USRDLL" /D "PM_DLL_EXPORTS" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "USE_DLL_FOR_CLEANUP" /FR /YX /FD /GZ /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "pm_dll - Win32 Release"
-# Name "pm_dll - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\pmdll.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\pmdll.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/portmidi/pm_win/pmdll.c b/portmidi/pm_win/pmdll.c
deleted file mode 100644
index c3acba33e..000000000
--- a/portmidi/pm_win/pmdll.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-====================================================================
-DLL to perform action when program shuts down
-====================================================================
-*/
-
-#include "windows.h"
-#include "pmdll.h"
-
-static close_fn_ptr_type close_function = NULL;
-
-
-DLL_EXPORT pm_set_close_function(close_fn_ptr_type close_fn_ptr)
-{
-    close_function = close_fn_ptr;
-}
-
-
-static void Initialize( void ) {
-    return;
-}
-
-static void Terminate( void ) {
-    if (close_function) {
-        (*close_function)();
-    }
-}
-
-
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, //DLL module handle
-					DWORD fdwReason,	//for calling function
-					LPVOID lbpvReserved)//reserved
-{
-	switch(fdwReason) {
-		case DLL_PROCESS_ATTACH:
-			/* when DLL starts, run this */
-			Initialize();
-			break;
-		case DLL_PROCESS_DETACH:
-			/* when DLL ends, this run (note: verified this	run */
-			Terminate();
-			break;
-		default:
-			break;
-	}
-	return TRUE;
-}
-
-
diff --git a/portmidi/pm_win/pmdll.h b/portmidi/pm_win/pmdll.h
deleted file mode 100644
index e5ad1c5bd..000000000
--- a/portmidi/pm_win/pmdll.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#define DLL_EXPORT __declspec( dllexport )
-
-typedef void (*close_fn_ptr_type)();
-
-DLL_EXPORT pm_set_close_function(close_fn_ptr_type close_fn_ptr);
diff --git a/portmidi/pm_win/pmwin.c b/portmidi/pm_win/pmwin.c
deleted file mode 100644
index b289194b6..000000000
--- a/portmidi/pm_win/pmwin.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* pmwin.c -- PortMidi os-dependent code */
-
-/* This file only needs to implement:
-       pm_init(), which calls various routines to register the 
-           available midi devices,
-       Pm_GetDefaultInputDeviceID(), and
-       Pm_GetDefaultOutputDeviceID().
-   This file must
-   be separate from the main portmidi.c file because it is system
-   dependent, and it is separate from, say, pmwinmm.c, because it
-   might need to register devices for winmm, directx, and others.
- */
-
-#include "stdlib.h"
-#include "portmidi.h"
-#include "pminternal.h"
-#include "pmwinmm.h"
-#ifdef USE_DLL_FOR_CLEANUP
-#include "pmdll.h" /* used to close ports on exit */
-#endif
-#ifdef DEBUG
-#include "stdio.h"
-#endif
-
-/* pm_exit is called when the program exits.
-   It calls pm_term to make sure PortMidi is properly closed.
-   If DEBUG is on, we prompt for input to avoid losing error messages.
- */
-static void pm_exit(void) {
-    pm_term();
-#ifdef DEBUG
-#define STRING_MAX 80
-    {
-        char line[STRING_MAX];
-        printf("Type ENTER...\n");
-        /* note, w/o this prompting, client console application can not see one
-           of its errors before closing. */
-        fgets(line, STRING_MAX, stdin);
-    }
-#endif
-}
-
-
-/* pm_init is the windows-dependent initialization.*/
-void pm_init(void)
-{
-#ifdef USE_DLL_FOR_CLEANUP
-    /* we were hoping a DLL could offer more robust cleanup after errors,
-       but the DLL does not seem to run after crashes. Thus, the atexit()
-       mechanism is just as powerful, and simpler to implement.
-     */
-    pm_set_close_function(pm_exit);
-#ifdef DEBUG
-    printf("registered pm_term with cleanup DLL\n");
-#endif
-#else
-    atexit(pm_exit);
-#ifdef DEBUG
-    printf("registered pm_exit with atexit()\n");
-#endif
-#endif
-    pm_winmm_init();
-    /* initialize other APIs (DirectX?) here */
-}
-
-
-void pm_term(void) {
-    pm_winmm_term();
-}
-
-
-PmDeviceID Pm_GetDefaultInputDeviceID() {
-    /* This routine should check the environment and the registry
-       as specified in portmidi.h, but for now, it just returns
-       the first device of the proper input/output flavor.
-     */
-    int i;
-    Pm_Initialize(); /* make sure descriptors exist! */
-    for (i = 0; i < pm_descriptor_index; i++) {
-        if (descriptors[i].pub.input) {
-            return i;
-        }
-    }
-    return pmNoDevice;
-}
-
-PmDeviceID Pm_GetDefaultOutputDeviceID() {
-    /* This routine should check the environment and the registry
-       as specified in portmidi.h, but for now, it just returns
-       the first device of the proper input/output flavor.
-     */
-    int i;
-    Pm_Initialize(); /* make sure descriptors exist! */
-    for (i = 0; i < pm_descriptor_index; i++) {
-        if (descriptors[i].pub.output) {
-            return i;
-        }
-    }
-    return pmNoDevice;
-    return 0;
-}
-
-#include "stdio.h" 
-
-void *pm_alloc(size_t s) {
-    return malloc(s); 
-}
-
-
-void pm_free(void *ptr) { 
-    free(ptr); 
-}
-
diff --git a/portmidi/pm_win/pmwinmm.c b/portmidi/pm_win/pmwinmm.c
deleted file mode 100644
index 5bfb0cff2..000000000
--- a/portmidi/pm_win/pmwinmm.c
+++ /dev/null
@@ -1,1547 +0,0 @@
-/* pmwinmm.c -- system specific definitions */
-
-#include "windows.h"
-#include "mmsystem.h"
-#include "portmidi.h"
-#include "pminternal.h"
-#include "pmwinmm.h"
-#include "string.h"
-#include "porttime.h"
-
-/* asserts used to verify portMidi code logic is sound; later may want
-    something more graceful */
-#include <assert.h>
-
-#ifdef DEBUG
-/* this printf stuff really important for debugging client app w/host errors.
-    probably want to do something else besides read/write from/to console
-    for portability, however */
-#define STRING_MAX 80
-#include "stdio.h"
-#endif
-
-#define streql(x, y) (strcmp(x, y) == 0)
-
-#define MIDI_SYSEX      0xf0
-#define MIDI_EOX        0xf7
-
-/* callback routines */
-static void CALLBACK winmm_in_callback(HMIDIIN hMidiIn,
-                                       WORD wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
-static void CALLBACK winmm_streamout_callback(HMIDIOUT hmo, UINT wMsg,
-        DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
-static void CALLBACK winmm_out_callback(HMIDIOUT hmo, UINT wMsg,
-                                        DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
-
-extern pm_fns_node pm_winmm_in_dictionary;
-extern pm_fns_node pm_winmm_out_dictionary;
-
-static void winmm_out_delete(PmInternal *midi); /* forward reference */
-
-#define SYSEX_BYTES_PER_BUFFER 1024
-/* 3 midi messages per buffer */
-#define OUTPUT_BYTES_PER_BUFFER 36
-
-#define MIDIHDR_SYSEX_BUFFER_LENGTH(x) ((x) + sizeof(long)*3)
-#define MIDIHDR_SYSEX_SIZE(x) (MIDIHDR_SYSEX_BUFFER_LENGTH(x) + sizeof(MIDIHDR))
-#define MIDIHDR_BUFFER_LENGTH(x) (x)
-#define MIDIHDR_SIZE(x) (MIDIHDR_BUFFER_LENGTH(x) + sizeof(MIDIHDR))
-
-/*
-==============================================================================
-win32 mmedia system specific structure passed to midi callbacks
-==============================================================================
-*/
-
-/* global winmm device info */
-MIDIINCAPS *midi_in_caps = NULL;
-MIDIINCAPS midi_in_mapper_caps;
-UINT midi_num_inputs = 0;
-MIDIOUTCAPS *midi_out_caps = NULL;
-MIDIOUTCAPS midi_out_mapper_caps;
-UINT midi_num_outputs = 0;
-
-/* per device info */
-typedef struct midiwinmm_struct
-{
-
-    union {
-        HMIDISTRM stream;   /* windows handle for stream */
-        HMIDIOUT out;       /* windows handle for out calls */
-        HMIDIIN in;         /* windows handle for in calls */
-    } handle;
-
-    /* midi output messages are sent in these buffers, which are allocated
-     * in a round-robin fashion, using next_buffer as an index
-     */
-    LPMIDIHDR *buffers;     /* pool of buffers for midi in or out data */
-    int num_buffers;        /* how many buffers */
-    int next_buffer;        /* index of next buffer to send */
-    HANDLE buffer_signal;   /* used to wait for buffer to become free */
-
-    LPMIDIHDR *sysex_buffers;   /* pool of buffers for sysex data */
-    int num_sysex_buffers;      /* how many sysex buffers */
-    int next_sysex_buffer;      /* index of next sysexbuffer to send */
-    HANDLE sysex_buffer_signal; /* used to wait for sysex buffer to become free */
-
-    unsigned long last_time;    /* last output time */
-    int first_message;          /* flag: treat first message differently */
-    int sysex_mode;             /* middle of sending sysex */
-    unsigned long sysex_word;   /* accumulate data when receiving sysex */
-    unsigned int sysex_byte_count; /* count how many received or to send */
-    LPMIDIHDR hdr;              /* the message accumulating sysex to send */
-    unsigned long sync_time;    /* when did we last determine delta? */
-    long delta;                 /* difference between stream time and
-                                       real time */
-    int error;                  /* host error from doing port midi call */
-    int callback_error;         /* host error from midi in or out callback */
-}
-midiwinmm_node, *midiwinmm_type;
-
-
-/*
-=============================================================================
-general MIDI device queries
-=============================================================================
-*/
-static void pm_winmm_general_inputs()
-{
-    UINT i;
-    WORD wRtn;
-    midi_num_inputs = midiInGetNumDevs();
-    midi_in_caps = pm_alloc(sizeof(MIDIINCAPS) * midi_num_inputs);
-
-    if (midi_in_caps == NULL) {
-        // if you can't open a particular system-level midi interface
-        // (such as winmm), we just consider that system or API to be
-        // unavailable and move on without reporting an error. This
-        // may be the wrong thing to do, especially in this case.
-        return ;
-    }
-
-    for (i = 0; i < midi_num_inputs; i++) {
-        wRtn = midiInGetDevCaps(i, (LPMIDIINCAPS) & midi_in_caps[i],
-                                sizeof(MIDIINCAPS));
-        if (wRtn == MMSYSERR_NOERROR) {
-            /* ignore errors here -- if pm_descriptor_max is exceeded, some
-               devices will not be accessible. */
-            pm_add_device("MMSystem", midi_in_caps[i].szPname, TRUE,
-                          (void *) i, &pm_winmm_in_dictionary);
-        }
-    }
-}
-
-
-static void pm_winmm_mapper_input()
-{
-    WORD wRtn;
-    /* Note: if MIDIMAPPER opened as input (documentation implies you
-        can, but current system fails to retrieve input mapper
-        capabilities) then you still should retrieve some formof
-        setup info. */
-    wRtn = midiInGetDevCaps((UINT) MIDIMAPPER,
-                            (LPMIDIINCAPS) & midi_in_mapper_caps, sizeof(MIDIINCAPS));
-    if (wRtn == MMSYSERR_NOERROR) {
-        pm_add_device("MMSystem", midi_in_mapper_caps.szPname, TRUE,
-                      (void *) MIDIMAPPER, &pm_winmm_in_dictionary);
-    }
-}
-
-
-static void pm_winmm_general_outputs()
-{
-    UINT i;
-    DWORD wRtn;
-    midi_num_outputs = midiOutGetNumDevs();
-    midi_out_caps = pm_alloc( sizeof(MIDIOUTCAPS) * midi_num_outputs );
-
-    if (midi_out_caps == NULL) {
-        // no error is reported -- see pm_winmm_general_inputs
-        return ;
-    }
-
-    for (i = 0; i < midi_num_outputs; i++) {
-        wRtn = midiOutGetDevCaps(i, (LPMIDIOUTCAPS) & midi_out_caps[i],
-                                 sizeof(MIDIOUTCAPS));
-        if (wRtn == MMSYSERR_NOERROR) {
-            pm_add_device("MMSystem", midi_out_caps[i].szPname, FALSE,
-                          (void *) i, &pm_winmm_out_dictionary);
-        }
-    }
-}
-
-
-static void pm_winmm_mapper_output()
-{
-    WORD wRtn;
-    /* Note: if MIDIMAPPER opened as output (pseudo MIDI device
-        maps device independent messages into device dependant ones,
-        via NT midimapper program) you still should get some setup info */
-    wRtn = midiOutGetDevCaps((UINT) MIDIMAPPER, (LPMIDIOUTCAPS)
-                             & midi_out_mapper_caps, sizeof(MIDIOUTCAPS));
-    if (wRtn == MMSYSERR_NOERROR) {
-        pm_add_device("MMSystem", midi_out_mapper_caps.szPname, FALSE,
-                      (void *) MIDIMAPPER, &pm_winmm_out_dictionary);
-    }
-}
-
-
-/*
-=========================================================================================
-host error handling
-=========================================================================================
-*/
-static unsigned int winmm_has_host_error(PmInternal * midi)
-{
-    midiwinmm_type m = (midiwinmm_type)midi->descriptor;
-    return m->callback_error || m->error;
-}
-
-
-/* str_copy_len -- like strcat, but won't overrun the destination string */
-/*
- * returns length of resulting string
- */
-static int str_copy_len(char *dst, char *src, int len)
-{
-    strncpy(dst, src, len);
-    /* just in case suffex is greater then len, terminate with zero */
-    dst[len - 1] = 0;
-    return strlen(dst);
-}
-
-
-static void winmm_get_host_error(PmInternal * midi, char * msg, UINT len)
-{
-    /* precondition: midi != NULL */
-    midiwinmm_node * m = (midiwinmm_node *) midi->descriptor;
-    char *hdr1 = "Host error: ";
-    char *hdr2 = "Host callback error: ";
-
-    msg[0] = 0; /* initialize result string to empty */
-
-    if (descriptors[midi->device_id].pub.input) {
-        /* input and output use different winmm API calls */
-        if (m) { /* make sure there is an open device to examine */
-            if (m->error != MMSYSERR_NOERROR) {
-                int n = str_copy_len(msg, hdr1, len);
-                /* read and record host error */
-                int err = midiInGetErrorText(m->error, msg + n, len - n);
-                assert(err == MMSYSERR_NOERROR);
-                m->error = MMSYSERR_NOERROR;
-            } else if (m->callback_error != MMSYSERR_NOERROR) {
-                int n = str_copy_len(msg, hdr2, len);
-                int err = midiInGetErrorText(m->callback_error, msg + n,
-                                             len - n);
-                assert(err == MMSYSERR_NOERROR);
-                m->callback_error = MMSYSERR_NOERROR;
-            }
-        }
-    } else { /* output port */
-        if (m) {
-            if (m->error != MMSYSERR_NOERROR) {
-                int n = str_copy_len(msg, hdr1, len);
-                int err = midiOutGetErrorText(m->error, msg + n, len - n);
-                assert(err == MMSYSERR_NOERROR);
-                m->error = MMSYSERR_NOERROR;
-            } else if (m->callback_error != MMSYSERR_NOERROR) {
-                int n = str_copy_len(msg, hdr2, len);
-                int err = midiOutGetErrorText(m->callback_error, msg + n,
-                                              len = n);
-                assert(err == MMSYSERR_NOERROR);
-                m->callback_error = MMSYSERR_NOERROR;
-            }
-        }
-    }
-}
-
-
-/*
-=============================================================================
-buffer handling
-=============================================================================
-*/
-static MIDIHDR *allocate_buffer(long data_size)
-{
-    /*
-     * with short messages, the MIDIEVENT structure contains the midi message,
-     * so there is no need for additional data
-     */
-
-    LPMIDIHDR hdr = (LPMIDIHDR) pm_alloc(MIDIHDR_SIZE(data_size));
-    MIDIEVENT *evt;
-    if (!hdr) return NULL;
-    evt = (MIDIEVENT *) (hdr + 1); /* place MIDIEVENT after header */
-    hdr->lpData = (LPSTR) evt;
-    hdr->dwBufferLength = MIDIHDR_BUFFER_LENGTH(data_size); /* was: sizeof(MIDIEVENT) + data_size; */
-    hdr->dwFlags = 0;
-    hdr->dwUser = 0;
-    return hdr;
-}
-
-static MIDIHDR *allocate_sysex_buffer(long data_size)
-{
-    /* we're actually allocating slightly more than data_size because one more word of
-     * data is contained in MIDIEVENT. We include the size of MIDIEVENT because we need
-     * the MIDIEVENT header in addition to the data
-     */
-    LPMIDIHDR hdr = (LPMIDIHDR) pm_alloc(MIDIHDR_SYSEX_SIZE(data_size));
-    MIDIEVENT *evt;
-    if (!hdr) return NULL;
-    evt = (MIDIEVENT *) (hdr + 1); /* place MIDIEVENT after header */
-    hdr->lpData = (LPSTR) evt;
-    hdr->dwBufferLength = MIDIHDR_SYSEX_BUFFER_LENGTH(data_size); /* was: sizeof(MIDIEVENT) + data_size; */
-    hdr->dwFlags = 0;
-    hdr->dwUser = 0;
-    return hdr;
-}
-
-static PmError allocate_buffers(midiwinmm_type m, long data_size, long count)
-{
-    PmError rslt = pmNoError;
-    /* buffers is an array of count pointers to MIDIHDR/MIDIEVENT struct */
-    m->buffers = (LPMIDIHDR *) pm_alloc(sizeof(LPMIDIHDR) * count);
-    if (!m->buffers) return pmInsufficientMemory;
-    m->num_buffers = count;
-    while (count > 0) {
-        LPMIDIHDR hdr = allocate_buffer(data_size);
-        if (!hdr) rslt = pmInsufficientMemory;
-        count--;
-        m->buffers[count] = hdr; /* this may be NULL if allocation fails */
-    }
-    return rslt;
-}
-
-static PmError allocate_sysex_buffers(midiwinmm_type m, long data_size, long count)
-{
-    PmError rslt = pmNoError;
-    /* buffers is an array of count pointers to MIDIHDR/MIDIEVENT struct */
-    m->sysex_buffers = (LPMIDIHDR *) pm_alloc(sizeof(LPMIDIHDR) * count);
-    if (!m->sysex_buffers) return pmInsufficientMemory;
-    m->num_sysex_buffers = count;
-    while (count > 0) {
-        LPMIDIHDR hdr = allocate_sysex_buffer(data_size);
-        if (!hdr) rslt = pmInsufficientMemory;
-        count--;
-        m->sysex_buffers[count] = hdr; /* this may be NULL if allocation fails */
-    }
-    return rslt;
-}
-
-static LPMIDIHDR get_free_sysex_buffer(PmInternal *midi)
-{
-    LPMIDIHDR r = NULL;
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    if (!m->sysex_buffers) {
-        if (allocate_sysex_buffers(m, SYSEX_BYTES_PER_BUFFER, 2)) {
-            return NULL;
-        }
-    }
-    /* busy wait until we find a free buffer */
-    while (TRUE) {
-        int i;
-        for (i = 0; i < m->num_sysex_buffers; i++) {
-            m->next_sysex_buffer++;
-            if (m->next_sysex_buffer >= m->num_sysex_buffers) m->next_sysex_buffer = 0;
-            r = m->sysex_buffers[m->next_sysex_buffer];
-            if ((r->dwFlags & MHDR_PREPARED) == 0) goto found_sysex_buffer;
-        }
-        /* after scanning every buffer and not finding anything, block */
-        WaitForSingleObject(m->sysex_buffer_signal, INFINITE);
-    }
-found_sysex_buffer:
-    r->dwBytesRecorded = 0;
-    m->error = midiOutPrepareHeader(m->handle.out, r, sizeof(MIDIHDR));
-    return r;
-}
-
-
-static LPMIDIHDR get_free_output_buffer(PmInternal *midi)
-{
-    LPMIDIHDR r = NULL;
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    if (!m->buffers) {
-        if (allocate_buffers(m, OUTPUT_BYTES_PER_BUFFER, 2)) {
-            return NULL;
-        }
-    }
-    /* busy wait until we find a free buffer */
-    while (TRUE) {
-        int i;
-        for (i = 0; i < m->num_buffers; i++) {
-            m->next_buffer++;
-            if (m->next_buffer >= m->num_buffers) m->next_buffer = 0;
-            r = m->buffers[m->next_buffer];
-            if ((r->dwFlags & MHDR_PREPARED) == 0) goto found_buffer;
-        }
-        /* after scanning every buffer and not finding anything, block */
-        WaitForSingleObject(m->buffer_signal, INFINITE);
-    }
-found_buffer:
-    r->dwBytesRecorded = 0;
-    m->error = midiOutPrepareHeader(m->handle.out, r, sizeof(MIDIHDR));
-    return r;
-}
-
-static PmError resize_sysex_buffer(PmInternal *midi, long old_size, long new_size)
-{
-    LPMIDIHDR big;
-    int i;
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    /* buffer must be smaller than 64k, but be also be a multiple of 4 */
-    if (new_size > 65520) {
-        if (old_size >= 65520)
-            return pmBufferMaxSize;
-        else
-            new_size = 65520;
-    }
-    /* allocate a bigger message  */
-    big = allocate_sysex_buffer(new_size);
-    /* printf("expand to %d bytes\n", new_size);*/
-    if (!big) return pmInsufficientMemory;
-    m->error = midiOutPrepareHeader(m->handle.out, big, sizeof(MIDIHDR));
-    if (m->error) {
-        pm_free(big);
-        return pmHostError;
-    }
-    /* make sure we're not going to overwrite any memory */
-    assert(old_size <= new_size);
-    memcpy(big->lpData, m->hdr->lpData, old_size);
-
-    /* find which buffer this was, and replace it */
-
-    for (i = 0;i < m->num_sysex_buffers;i++) {
-        if (m->sysex_buffers[i] == m->hdr) {
-            m->sysex_buffers[i] = big;
-            pm_free(m->hdr);
-            m->hdr = big;
-            break;
-        }
-    }
-    assert(i != m->num_sysex_buffers);
-
-    return pmNoError;
-
-}
-/*
-=========================================================================================
-begin midi input implementation
-=========================================================================================
-*/
-
-static PmError winmm_in_open(PmInternal *midi, void *driverInfo)
-{
-    DWORD dwDevice;
-    int i = midi->device_id;
-    midiwinmm_type m;
-    LPMIDIHDR hdr;
-    long buffer_len;
-    dwDevice = (DWORD) descriptors[i].descriptor;
-
-    /* create system dependent device data */
-    m = (midiwinmm_type) pm_alloc(sizeof(midiwinmm_node)); /* create */
-    midi->descriptor = m;
-    if (!m) goto no_memory;
-    m->handle.in = NULL;
-    m->buffers = NULL;
-    m->num_buffers = 0;
-    m->next_buffer = 0;
-    m->sysex_buffers = NULL;
-    m->num_sysex_buffers = 0;
-    m->next_sysex_buffer = 0;
-    m->last_time = 0;
-    m->first_message = TRUE; /* not used for input */
-    m->sysex_mode = FALSE;
-    m->sysex_word = 0;
-    m->sysex_byte_count = 0;
-    m->sync_time = 0;
-    m->delta = 0;
-    m->error = MMSYSERR_NOERROR;
-    m->callback_error = MMSYSERR_NOERROR;
-
-    /* open device */
-    pm_hosterror = midiInOpen(&(m->handle.in),  /* input device handle */
-                              dwDevice,  /* device ID */
-                              (DWORD) winmm_in_callback,  /* callback address */
-                              (DWORD) midi,  /* callback instance data */
-                              CALLBACK_FUNCTION); /* callback is a procedure */
-    if (pm_hosterror) goto free_descriptor;
-
-    /* allocate first buffer for sysex data */
-    buffer_len = midi->buffer_len - 1;
-    if (midi->buffer_len < 32)
-        buffer_len = PM_DEFAULT_SYSEX_BUFFER_SIZE;
-
-    hdr = allocate_sysex_buffer(buffer_len);
-    if (!hdr) goto close_device;
-    pm_hosterror = midiInPrepareHeader(m->handle.in, hdr, sizeof(MIDIHDR));
-    if (pm_hosterror) {
-        pm_free(hdr);
-        goto close_device;
-    }
-    pm_hosterror = midiInAddBuffer(m->handle.in, hdr, sizeof(MIDIHDR));
-    if (pm_hosterror) goto close_device;
-
-    /* allocate second buffer */
-    hdr = allocate_sysex_buffer(buffer_len);
-    if (!hdr) goto close_device;
-    pm_hosterror = midiInPrepareHeader(m->handle.in, hdr, sizeof(MIDIHDR));
-    if (pm_hosterror) {
-        pm_free(hdr);
-        goto reset_device; /* because first buffer was added */
-    }
-    pm_hosterror = midiInAddBuffer(m->handle.in, hdr, sizeof(MIDIHDR));
-    if (pm_hosterror) goto reset_device;
-
-    /* start device */
-    pm_hosterror = midiInStart(m->handle.in);
-    if (pm_hosterror) goto reset_device;
-    return pmNoError;
-
-    /* undo steps leading up to the detected error */
-reset_device:
-    /* ignore return code (we already have an error to report) */
-    midiInReset(m->handle.in);
-close_device:
-    midiInClose(m->handle.in); /* ignore return code */
-free_descriptor:
-    midi->descriptor = NULL;
-    pm_free(m);
-no_memory:
-    if (pm_hosterror) {
-        int err = midiInGetErrorText(pm_hosterror, (char *) pm_hosterror_text,
-                                     PM_HOST_ERROR_MSG_LEN);
-        assert(err == MMSYSERR_NOERROR);
-        return pmHostError;
-    }
-    /* if !pm_hosterror, then the error must be pmInsufficientMemory */
-    return pmInsufficientMemory;
-    /* note: if we return an error code, the device will be
-       closed and memory will be freed. It's up to the caller
-       to free the parameter midi */
-}
-
-
-/* winmm_in_close -- close an open midi input device */
-/*
- * assume midi is non-null (checked by caller)
- */
-static PmError winmm_in_close(PmInternal *midi)
-{
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    if (!m) return pmBadPtr;
-    /* device to close */
-    if (pm_hosterror = midiInStop(m->handle.in)) {
-        midiInReset(m->handle.in); /* try to reset and close port */
-        midiInClose(m->handle.in);
-    } else if (pm_hosterror = midiInReset(m->handle.in)) {
-        midiInClose(m->handle.in); /* best effort to close midi port */
-    } else {
-        pm_hosterror = midiInClose(m->handle.in);
-    }
-    midi->descriptor = NULL;
-    pm_free(m); /* delete */
-    if (pm_hosterror) {
-        int err = midiInGetErrorText(pm_hosterror, (char *) pm_hosterror_text,
-                                     PM_HOST_ERROR_MSG_LEN);
-        assert(err == MMSYSERR_NOERROR);
-        return pmHostError;
-    }
-    return pmNoError;
-}
-
-
-/* Callback function executed via midiInput SW interrupt (via midiInOpen). */
-static void FAR PASCAL winmm_in_callback(
-    HMIDIIN hMidiIn,    /* midiInput device Handle */
-    WORD wMsg,          /* midi msg */
-    DWORD dwInstance,   /* application data */
-    DWORD dwParam1,     /* MIDI data */
-    DWORD dwParam2)    /* device timestamp (wrt most recent midiInStart) */
-{
-    static int entry = 0;
-    PmInternal *midi = (PmInternal *) dwInstance;
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-
-    if (++entry > 1) {
-        assert(FALSE);
-    }
-
-    /* for simplicity, this logic perhaps overly conservative */
-    /* note also that this might leak memory if buffers are being
-       returned as a result of midiInReset */
-    if (m->callback_error) {
-        entry--;
-        return ;
-    }
-
-    switch (wMsg) {
-    case MIM_DATA: {
-            /* dwParam1 is MIDI data received, packed into DWORD w/ 1st byte of
-                    message LOB;
-               dwParam2 is time message received by input device driver, specified
-                in [ms] from when midiInStart called.
-               each message is expanded to include the status byte */
-
-            long new_driver_time = dwParam2;
-
-            if ((dwParam1 & 0x80) == 0) {
-                /* not a status byte -- ignore it. This happens running the
-                   sysex.c test under Win2K with MidiMan USB 1x1 interface.
-                   Is it a driver bug or a Win32 bug? If not, there's a bug
-                   here somewhere. -RBD
-                 */
-            } else { /* data to process */
-                PmEvent event;
-                if (midi->time_proc)
-                    dwParam2 = (*midi->time_proc)(midi->time_info);
-                event.timestamp = dwParam2;
-                event.message = dwParam1;
-                pm_read_short(midi, &event);
-            }
-            break;
-        }
-    case MIM_LONGDATA: {
-            MIDIHDR *lpMidiHdr = (MIDIHDR *) dwParam1;
-            unsigned char *data = lpMidiHdr->lpData;
-            unsigned int i = 0;
-            long size = sizeof(MIDIHDR) + lpMidiHdr->dwBufferLength;
-            /* ignore sysex data, but free returned buffers */
-            if (lpMidiHdr->dwBytesRecorded > 0 &&
-                    midi->filters & PM_FILT_SYSEX) {
-                m->callback_error = midiInAddBuffer(hMidiIn, lpMidiHdr,
-                                                    sizeof(MIDIHDR));
-                break;
-            }
-            if (midi->time_proc)
-                dwParam2 = (*midi->time_proc)(midi->time_info);
-
-            while (i < lpMidiHdr->dwBytesRecorded) {
-                /* collect bytes from *data into a word */
-                pm_read_byte(midi, *data, dwParam2);
-                data++;
-                i++;
-            }
-            /* when a device is closed, the pending MIM_LONGDATA buffers are
-               returned to this callback with dwBytesRecorded == 0. In this
-               case, we do not want to send them back to the interface (if
-               we do, the interface will not close, and Windows OS may hang). */
-            if (lpMidiHdr->dwBytesRecorded > 0) {
-                m->callback_error = midiInAddBuffer(hMidiIn, lpMidiHdr,
-                                                    sizeof(MIDIHDR));
-            } else {
-                pm_free(lpMidiHdr);
-            }
-            break;
-        }
-    case MIM_OPEN:  /* fall thru */
-    case MIM_CLOSE:
-    case MIM_ERROR:
-    case MIM_LONGERROR:
-    default:
-        break;
-    }
-    entry--;
-}
-
-/*
-=========================================================================================
-begin midi output implementation
-=========================================================================================
-*/
-
-/* begin helper routines used by midiOutStream interface */
-
-/* add_to_buffer -- adds timestamped short msg to buffer, returns fullp */
-static int add_to_buffer(midiwinmm_type m, LPMIDIHDR hdr,
-                         unsigned long delta, unsigned long msg)
-{
-    unsigned long *ptr = (unsigned long *)
-                         (hdr->lpData + hdr->dwBytesRecorded);
-    *ptr++ = delta; /* dwDeltaTime */
-    *ptr++ = 0;     /* dwStream */
-    *ptr++ = msg;   /* dwEvent */
-    hdr->dwBytesRecorded += 3 * sizeof(long);
-    /* if the addition of three more words (a message) would extend beyond
-       the buffer length, then return TRUE (full)
-     */
-    return hdr->dwBytesRecorded + 3 * sizeof(long) > hdr->dwBufferLength;
-}
-
-#ifdef GARBAGE
-static void start_sysex_buffer(LPMIDIHDR hdr, unsigned long delta)
-{
-    unsigned long *ptr = (unsigned long *) hdr->lpData;
-    *ptr++ = delta;
-    *ptr++ = 0;
-    *ptr = MEVT_F_LONG;
-    hdr->dwBytesRecorded = 3 * sizeof(long);
-}
-
-static int add_byte_to_buffer(midiwinmm_type m, LPMIDIHDR hdr,
-                              unsigned char midi_byte)
-{
-    allocate message if hdr is null
-    send message if it is full
-        add byte to non - full message
-            unsigned char *ptr = (unsigned char *) (hdr->lpData + hdr->dwBytesRecorded);
-    *ptr = midi_byte;
-    return ++hdr->dwBytesRecorded >= hdr->dwBufferLength;
-}
-#endif
-
-
-static PmTimestamp pm_time_get(midiwinmm_type m)
-{
-    MMTIME mmtime;
-    MMRESULT wRtn;
-    mmtime.wType = TIME_TICKS;
-    mmtime.u.ticks = 0;
-    wRtn = midiStreamPosition(m->handle.stream, &mmtime, sizeof(mmtime));
-    assert(wRtn == MMSYSERR_NOERROR);
-    return mmtime.u.ticks;
-}
-
-#ifdef GARBAGE
-static unsigned long synchronize(PmInternal *midi, midiwinmm_type m)
-{
-    unsigned long pm_stream_time_2 = pm_time_get(m);
-    unsigned long real_time;
-    unsigned long pm_stream_time;
-    /* figure out the time */
-    do {
-        /* read real_time between two reads of stream time */
-        pm_stream_time = pm_stream_time_2;
-        real_time = (*midi->time_proc)(midi->time_info);
-        pm_stream_time_2 = pm_time_get(m);
-        /* repeat if more than 1ms elapsed */
-    } while (pm_stream_time_2 > pm_stream_time + 1);
-    m->delta = pm_stream_time - real_time;
-    m->sync_time = real_time;
-    return real_time;
-}
-#endif
-
-
-/* end helper routines used by midiOutStream interface */
-
-
-static PmError winmm_out_open(PmInternal *midi, void *driverInfo)
-{
-    DWORD dwDevice;
-    int i = midi->device_id;
-    midiwinmm_type m;
-    MIDIPROPTEMPO propdata;
-    MIDIPROPTIMEDIV divdata;
-    dwDevice = (DWORD) descriptors[i].descriptor;
-
-    /* create system dependent device data */
-    m = (midiwinmm_type) pm_alloc(sizeof(midiwinmm_node)); /* create */
-    midi->descriptor = m;
-    if (!m) goto no_memory;
-    m->handle.out = NULL;
-    m->buffers = NULL;
-    m->num_buffers = 0;
-    m->next_buffer = 0;
-    m->sysex_buffers = NULL;
-    m->num_sysex_buffers = 0;
-    m->next_sysex_buffer = 0;
-    m->last_time = 0;
-    m->first_message = TRUE; /* we treat first message as special case */
-    m->sysex_mode = FALSE;
-    m->sysex_word = 0;
-    m->sysex_byte_count = 0;
-    m->hdr = NULL;
-    m->sync_time = 0;
-    m->delta = 0;
-    m->error = MMSYSERR_NOERROR;
-    m->callback_error = MMSYSERR_NOERROR;
-
-    /* create a signal */
-    m->buffer_signal = CreateEvent(NULL, FALSE, FALSE, NULL);
-    m->sysex_buffer_signal = CreateEvent(NULL, FALSE, FALSE, NULL);
-
-    /* this should only fail when there are very serious problems */
-    assert(m->buffer_signal);
-    assert(m->sysex_buffer_signal);
-
-    /* open device */
-    if (midi->latency == 0) {
-        /* use simple midi out calls */
-        pm_hosterror = midiOutOpen((LPHMIDIOUT) & m->handle.out,  /* device Handle */
-                                   dwDevice,  /* device ID  */
-                                   (DWORD) winmm_out_callback,
-                                   (DWORD) midi,  /* callback instance data */
-                                   CALLBACK_FUNCTION); /* callback type */
-    } else {
-        /* use stream-based midi output (schedulable in future) */
-        pm_hosterror = midiStreamOpen(&m->handle.stream,  /* device Handle */
-                                      (LPUINT) & dwDevice,  /* device ID pointer */
-                                      1,  /* reserved, must be 1 */
-                                      (DWORD) winmm_streamout_callback,
-                                      (DWORD) midi,  /* callback instance data */
-                                      CALLBACK_FUNCTION);
-    }
-    if (pm_hosterror != MMSYSERR_NOERROR) {
-        goto free_descriptor;
-    }
-
-    if (midi->latency != 0) {
-        long dur = 0;
-        /* with stream output, specified number of buffers allocated here */
-        int count = midi->buffer_len;
-        if (count == 0)
-            count = midi->latency / 2; /* how many buffers to get */
-
-        propdata.cbStruct = sizeof(MIDIPROPTEMPO);
-        propdata.dwTempo = 480000; /* microseconds per quarter */
-        pm_hosterror = midiStreamProperty(m->handle.stream,
-                                          (LPBYTE) & propdata,
-                                          MIDIPROP_SET | MIDIPROP_TEMPO);
-        if (pm_hosterror) goto close_device;
-
-        divdata.cbStruct = sizeof(MIDIPROPTEMPO);
-        divdata.dwTimeDiv = 480;   /* divisions per quarter */
-        pm_hosterror = midiStreamProperty(m->handle.stream,
-                                          (LPBYTE) & divdata,
-                                          MIDIPROP_SET | MIDIPROP_TIMEDIV);
-        if (pm_hosterror) goto close_device;
-
-        /* allocate at least 3 buffers */
-        if (count < 3) count = 3;
-        if (allocate_buffers(m, OUTPUT_BYTES_PER_BUFFER, count)) goto free_buffers;
-        if (allocate_sysex_buffers(m, SYSEX_BYTES_PER_BUFFER, 2)) goto free_buffers;
-        /* start device */
-        pm_hosterror = midiStreamRestart(m->handle.stream);
-        if (pm_hosterror != MMSYSERR_NOERROR) goto free_buffers;
-    }
-    return pmNoError;
-
-free_buffers:
-    /* buffers are freed below by winmm_out_delete */
-close_device:
-    midiOutClose(m->handle.out);
-free_descriptor:
-    midi->descriptor = NULL;
-    winmm_out_delete(midi); /* frees buffers and m */
-no_memory:
-    if (pm_hosterror) {
-        int err = midiOutGetErrorText(pm_hosterror, (char *) pm_hosterror_text,
-                                      PM_HOST_ERROR_MSG_LEN);
-        assert(err == MMSYSERR_NOERROR);
-        return pmHostError;
-    }
-    return pmInsufficientMemory;
-}
-
-
-/* winmm_out_delete -- carefully free data associated with midi */
-/**/
-static void winmm_out_delete(PmInternal *midi)
-{
-    /* delete system dependent device data */
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    if (m) {
-        if (m->buffer_signal) {
-            /* don't report errors -- better not to stop cleanup */
-            CloseHandle(m->buffer_signal);
-        }
-        if (m->sysex_buffer_signal) {
-            /* don't report errors -- better not to stop cleanup */
-            CloseHandle(m->sysex_buffer_signal);
-        }
-        if (m->buffers) {
-            /* if using stream output, free buffers */
-            int i;
-            for (i = 0; i < m->num_buffers; i++) {
-                if (m->buffers[i]) pm_free(m->buffers[i]);
-            }
-            pm_free(m->buffers);
-        }
-
-        if (m->sysex_buffers) {
-            /* free sysex buffers */
-            int i;
-            for (i = 0; i < m->num_sysex_buffers; i++) {
-                if (m->sysex_buffers[i]) pm_free(m->sysex_buffers[i]);
-            }
-            pm_free(m->sysex_buffers);
-        }
-    }
-    midi->descriptor = NULL;
-    pm_free(m); /* delete */
-}
-
-
-/* see comments for winmm_in_close */
-static PmError winmm_out_close(PmInternal *midi)
-{
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    if (m->handle.out) {
-        /* device to close */
-        if (midi->latency == 0) {
-            pm_hosterror = midiOutClose(m->handle.out);
-        } else {
-            pm_hosterror = midiStreamClose(m->handle.stream);
-        }
-        /* regardless of outcome, free memory */
-        winmm_out_delete(midi);
-    }
-    if (pm_hosterror) {
-        int err = midiOutGetErrorText(pm_hosterror,
-                                      (char *) pm_hosterror_text,
-                                      PM_HOST_ERROR_MSG_LEN);
-        assert(err == MMSYSERR_NOERROR);
-        return pmHostError;
-    }
-    return pmNoError;
-}
-
-
-static PmError winmm_out_abort(PmInternal *midi)
-{
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    m->error = MMSYSERR_NOERROR;
-
-    /* only stop output streams */
-    if (midi->latency > 0) {
-        m->error = midiStreamStop(m->handle.stream);
-    }
-    return m->error ? pmHostError : pmNoError;
-}
-
-#ifdef GARBAGE
-static PmError winmm_write_sysex_byte(PmInternal *midi, unsigned char byte)
-{
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    unsigned char *msg_buffer;
-
-    /* at the beginning of sysex, m->hdr is NULL */
-    if (!m->hdr) { /* allocate a buffer if none allocated yet */
-        m->hdr = get_free_output_buffer(midi);
-        if (!m->hdr) return pmInsufficientMemory;
-        m->sysex_byte_count = 0;
-    }
-    /* figure out where to write byte */
-    msg_buffer = (unsigned char *) (m->hdr->lpData);
-    assert(m->hdr->lpData == (char *) (m->hdr + 1));
-
-    /* check for overflow */
-    if (m->sysex_byte_count >= m->hdr->dwBufferLength) {
-        /* allocate a bigger message -- double it every time */
-        LPMIDIHDR big = allocate_buffer(m->sysex_byte_count * 2);
-        /* printf("expand to %d bytes\n", m->sysex_byte_count * 2); */
-        if (!big) return pmInsufficientMemory;
-        m->error = midiOutPrepareHeader(m->handle.out, big,
-                                        sizeof(MIDIHDR));
-        if (m->error) {
-            m->hdr = NULL;
-            return pmHostError;
-        }
-        memcpy(big->lpData, msg_buffer, m->sysex_byte_count);
-        msg_buffer = (unsigned char *) (big->lpData);
-        if (m->buffers[0] == m->hdr) {
-            m->buffers[0] = big;
-            pm_free(m->hdr);
-            /* printf("freed m->hdr\n"); */
-        } else if (m->buffers[1] == m->hdr) {
-            m->buffers[1] = big;
-            pm_free(m->hdr);
-            /* printf("freed m->hdr\n"); */
-        }
-        m->hdr = big;
-    }
-
-    /* append byte to message */
-    msg_buffer[m->sysex_byte_count++] = byte;
-
-    /* see if we have a complete message */
-    if (byte == MIDI_EOX) {
-        m->hdr->dwBytesRecorded = m->sysex_byte_count;
-        /*
-        { int i; int len = m->hdr->dwBytesRecorded;
-          printf("OutLongMsg %d ", len);
-          for (i = 0; i < len; i++) {
-              printf("%2x ", msg_buffer[i]);
-          }
-        }
-        */
-        m->error = midiOutLongMsg(m->handle.out, m->hdr, sizeof(MIDIHDR));
-        m->hdr = NULL; /* stop using this message buffer */
-        if (m->error) return pmHostError;
-    }
-    return pmNoError;
-}
-#endif
-
-
-static PmError winmm_write_short(PmInternal *midi, PmEvent *event)
-{
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    PmError rslt = pmNoError;
-    assert(m);
-    if (midi->latency == 0) { /* use midiOut interface, ignore timestamps */
-        m->error = midiOutShortMsg(m->handle.out, event->message);
-        if (m->error) rslt = pmHostError;
-    } else {  /* use midiStream interface -- pass data through buffers */
-        unsigned long when = event->timestamp;
-        unsigned long delta;
-        int full;
-        if (when == 0) when = midi->now;
-        /* when is in real_time; translate to intended stream time */
-        when = when + m->delta + midi->latency;
-        /* make sure we don't go backward in time */
-        if (when < m->last_time) when = m->last_time;
-        delta = when - m->last_time;
-        m->last_time = when;
-        /* before we insert any data, we must have a buffer */
-        if (m->hdr == NULL) {
-            /* stream interface: buffers allocated when stream is opened */
-            m->hdr = get_free_output_buffer(midi);
-        }
-        full = add_to_buffer(m, m->hdr, delta, event->message);
-        if (full) {
-            m->error = midiStreamOut(m->handle.stream, m->hdr,
-                                     sizeof(MIDIHDR));
-            if (m->error) rslt = pmHostError;
-            m->hdr = NULL;
-        }
-    }
-    return rslt;
-}
-
-
-static PmError winmm_begin_sysex(PmInternal *midi, PmTimestamp timestamp)
-{
-    PmError rslt = pmNoError;
-    if (midi->latency == 0) {
-        /* do nothing -- it's handled in winmm_write_byte */
-    } else {
-        midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-        /* sysex expects an empty buffer */
-        if (m->hdr) {
-            m->error = midiStreamOut(m->handle.stream, m->hdr, sizeof(MIDIHDR));
-            if (m->error) rslt = pmHostError;
-        }
-        m->hdr = NULL;
-    }
-    return rslt;
-}
-
-
-static PmError winmm_end_sysex(PmInternal *midi, PmTimestamp timestamp)
-{
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    PmError rslt = pmNoError;
-    assert(m);
-
-    if (midi->latency == 0) {
-        /* Not using the stream interface. The entire sysex message is
-           in m->hdr, and we send it using midiOutLongMsg.
-         */
-        m->hdr->dwBytesRecorded = m->sysex_byte_count;
-        /*
-        { int i; int len = m->hdr->dwBytesRecorded;
-          printf("OutLongMsg %d ", len);
-          for (i = 0; i < len; i++) {
-              printf("%2x ", msg_buffer[i]);
-          }
-        }
-        */
-
-        m->error = midiOutLongMsg(m->handle.out, m->hdr, sizeof(MIDIHDR));
-        if (m->error) rslt = pmHostError;
-    } else if (m->hdr) {
-        /* Using stream interface. There are accumulated bytes in m->hdr
-           to send using midiStreamOut
-         */
-        /* add bytes recorded to MIDIEVENT length, but don't
-           count the MIDIEVENT data (3 longs) */
-        MIDIEVENT *evt = (MIDIEVENT *) m->hdr->lpData;
-        evt->dwEvent += m->hdr->dwBytesRecorded - 3 * sizeof(long);
-        /* round up BytesRecorded to multiple of 4 */
-        m->hdr->dwBytesRecorded = (m->hdr->dwBytesRecorded + 3) & ~3;
-
-        m->error = midiStreamOut(m->handle.stream, m->hdr,
-                                 sizeof(MIDIHDR));
-        if (m->error) rslt = pmHostError;
-    }
-    m->hdr = NULL; /* make sure we don't send it again */
-    return rslt;
-}
-
-
-static PmError winmm_write_byte(PmInternal *midi, unsigned char byte,
-                                PmTimestamp timestamp)
-{
-    /* write a sysex byte */
-    PmError rslt = pmNoError;
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    assert(m);
-    if (midi->latency == 0) {
-        /* Not using stream interface. Accumulate the entire message into
-           m->hdr */
-        unsigned char *msg_buffer;
-        /* at the beginning of sysex, m->hdr is NULL */
-        if (!m->hdr) { /* allocate a buffer if none allocated yet */
-            m->hdr = get_free_sysex_buffer(midi);
-            if (!m->hdr) return pmInsufficientMemory;
-            m->sysex_byte_count = 0;
-        }
-        /* figure out where to write byte */
-        msg_buffer = (unsigned char *) (m->hdr->lpData);
-        assert(m->hdr->lpData == (char *) (m->hdr + 1));
-
-        /* append byte to message */
-        msg_buffer[m->sysex_byte_count++] = byte;
-
-        /* check for overflow */
-        if (m->sysex_byte_count >= m->hdr->dwBufferLength) {
-            rslt = resize_sysex_buffer(midi, m->sysex_byte_count, m->sysex_byte_count * 2);
-
-            if (rslt == pmBufferMaxSize) /* if the buffer can't be resized */
-                rslt = winmm_end_sysex(midi, timestamp); /* write what we've got and continue */
-
-        }
-
-    } else { /* latency is not zero, use stream interface: accumulate
-                        sysex data in m->hdr and send whenever the buffer fills */
-        int full;
-        unsigned char *ptr;
-
-        /* if m->hdr does not exist, allocate it */
-        if (m->hdr == NULL) {
-            unsigned long when = (unsigned long) timestamp;
-            unsigned long delta;
-            unsigned long *ptr;
-            if (when == 0) when = midi->now;
-            /* when is in real_time; translate to intended stream time */
-            when = when + m->delta + midi->latency;
-            /* make sure we don't go backward in time */
-            if (when < m->last_time) when = m->last_time;
-            delta = when - m->last_time;
-            m->last_time = when;
-
-            m->hdr = get_free_sysex_buffer(midi);
-            assert(m->hdr);
-            ptr = (unsigned long *) m->hdr->lpData;
-            *ptr++ = delta;
-            *ptr++ = 0;
-            *ptr = MEVT_F_LONG;
-            m->hdr->dwBytesRecorded = 3 * sizeof(long);
-        }
-
-        /* add the data byte */
-        ptr = (unsigned char *) (m->hdr->lpData + m->hdr->dwBytesRecorded);
-        *ptr = byte;
-        full = ++m->hdr->dwBytesRecorded >= m->hdr->dwBufferLength;
-
-        /* see if we need to resize */
-        if (full) {
-            int bytesRecorded = m->hdr->dwBytesRecorded; /* this field gets wiped out, so we'll save it */
-            rslt = resize_sysex_buffer(midi, bytesRecorded, 2 * bytesRecorded);
-            m->hdr->dwBytesRecorded = bytesRecorded;
-
-            if (rslt == pmBufferMaxSize) /* if buffer can't be resized */
-                rslt = winmm_end_sysex(midi, timestamp); /* write what we've got and continue */
-        }
-    }
-    return rslt;
-}
-
-
-
-static PmError winmm_write_flush(PmInternal *midi)
-{
-    PmError rslt = pmNoError;
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    assert(m);
-    if (midi->latency == 0) {
-        /* all messages are sent immediately */
-    } else if ((m->hdr) && (!midi->sysex_in_progress)) {
-        /* sysex messages are sent upon completion, but ordinary messages
-           may be sitting in a buffer
-         */
-        m->error = midiStreamOut(m->handle.stream, m->hdr, sizeof(MIDIHDR));
-        m->hdr = NULL;
-        if (m->error) rslt = pmHostError;
-    }
-    return rslt;
-}
-
-static PmTimestamp winmm_synchronize(PmInternal *midi)
-{
-    midiwinmm_type m;
-    unsigned long pm_stream_time_2;
-    unsigned long real_time;
-    unsigned long pm_stream_time;
-
-    /* only synchronize if we are using stream interface */
-    if (midi->latency == 0) return 0;
-
-    /* figure out the time */
-    m = (midiwinmm_type) midi->descriptor;
-    pm_stream_time_2 = pm_time_get(m);
-
-    do {
-        /* read real_time between two reads of stream time */
-        pm_stream_time = pm_stream_time_2;
-        real_time = (*midi->time_proc)(midi->time_info);
-        pm_stream_time_2 = pm_time_get(m);
-        /* repeat if more than 1ms elapsed */
-    } while (pm_stream_time_2 > pm_stream_time + 1);
-    m->delta = pm_stream_time - real_time;
-    m->sync_time = real_time;
-    return real_time;
-}
-
-
-#ifdef GARBAGE
-static PmError winmm_write(PmInternal *midi,
-                           PmEvent *buffer,
-                           long length)
-{
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    unsigned long now;
-    int i;
-    long msg;
-    PmError rslt = pmNoError;
-
-    m->error = MMSYSERR_NOERROR;
-    if (midi->latency == 0) { /* use midiOut interface, ignore timestamps */
-        for (i = 0; (i < length) && (rslt == pmNoError); i++) {
-            int b = 0; /* count sysex bytes as they are handled */
-            msg = buffer[i].message;
-            if ((msg & 0xFF) == MIDI_SYSEX) {
-                /* start a sysex message */
-                m->sysex_mode = TRUE;
-                unsigned char midi_byte = (unsigned char) msg;
-                rslt = winmm_write_sysex_byte(midi, midi_byte);
-                b = 8;
-            } else if ((msg & 0x80) && ((msg & 0xFF) != MIDI_EOX)) {
-                /* a non-sysex message */
-                m->error = midiOutShortMsg(m->handle.out, msg);
-                if (m->error) rslt = pmHostError;
-                /* any non-real-time message will terminate sysex message */
-                if (!is_real_time(msg)) m->sysex_mode = FALSE;
-            }
-            /* transmit sysex bytes until we find EOX */
-            if (m->sysex_mode) {
-                while (b < 32 /*bits*/ && (rslt == pmNoError)) {
-                    unsigned char midi_byte = (unsigned char) (msg >> b);
-                    rslt = winmm_write_sysex_byte(midi, midi_byte);
-                    if (midi_byte == MIDI_EOX) {
-                        b = 24; /* end of message */
-                        m->sysex_mode = FALSE;
-                    }
-                    b += 8;
-                }
-            }
-        }
-    } else { /* use midiStream interface -- pass data through buffers */
-        LPMIDIHDR hdr = NULL;
-        now = (*midi->time_proc)(midi->time_info);
-        if (m->first_message || m->sync_time + 100 /*ms*/ < now) {
-            /* time to resync */
-            now = synchronize(midi, m);
-            m->first_message = FALSE;
-        }
-        for (i = 0; i < length && rslt == pmNoError; i++) {
-            unsigned long when = buffer[i].timestamp;
-            unsigned long delta;
-            if (when == 0) when = now;
-            /* when is in real_time; translate to intended stream time */
-            when = when + m->delta + midi->latency;
-            /* make sure we don't go backward in time */
-            if (when < m->last_time) when = m->last_time;
-            delta = when - m->last_time;
-            m->last_time = when;
-            /* before we insert any data, we must have a buffer */
-            if (hdr == NULL) {
-                /* stream interface: buffers allocated when stream is opened */
-                hdr = get_free_output_buffer(midi);
-                assert(hdr);
-                if (m->sysex_mode) {
-                    /* we are in the middle of a sysex message */
-                    start_sysex_buffer(hdr, delta);
-                }
-            }
-            msg = buffer[i].message;
-            if ((msg & 0xFF) == MIDI_SYSEX) {
-                /* sysex expects an empty buffer */
-                if (hdr->dwBytesRecorded != 0) {
-                    m->error = midiStreamOut(m->handle.stream, hdr, sizeof(MIDIHDR));
-                    if (m->error) rslt = pmHostError;
-                    hdr = get_free_output_buffer(midi);
-                    assert(hdr);
-                }
-                /* when we see a MIDI_SYSEX, we always enter sysex mode and call
-                   start_sysex_buffer() */
-                start_sysex_buffer(hdr, delta);
-                m->sysex_mode = TRUE;
-            }
-            /* allow a non-real-time status byte to terminate sysex message */
-            if (m->sysex_mode && (msg & 0x80) && (msg & 0xFF) != MIDI_SYSEX &&
-                    !is_real_time(msg)) {
-                /* I'm not sure what WinMM does if you send an incomplete sysex
-                   message, but the best way out of this mess seems to be to
-                   recreate the code used when you encounter an EOX, so ...
-                 */
-                MIDIEVENT *evt = (MIDIEVENT) hdr->lpData;
-                evt->dwEvent += hdr->dwBytesRecorded - 3 * sizeof(long);
-                /* round up BytesRecorded to multiple of 4 */
-                hdr->dwBytesRecorded = (hdr->dwBytesRecorded + 3) & ~3;
-                m->error = midiStreamOut(m->handle.stream, hdr,
-                                         sizeof(MIDIHDR));
-                if (m->error) {
-                    rslt = pmHostError;
-                }
-                hdr = NULL; /* make sure we don't send it again */
-                m->sysex_mode = FALSE; /* skip to normal message send code */
-            }
-            if (m->sysex_mode) {
-                int b = 0; /* count bytes as they are handled */
-                while (b < 32 /* bits per word */ && (rslt == pmNoError)) {
-                    int full;
-                    unsigned char midi_byte = (unsigned char) (msg >> b);
-                    if (!hdr) {
-                        hdr = get_free_output_buffer(midi);
-                        assert(hdr);
-                        /* get ready to put sysex bytes in buffer */
-                        start_sysex_buffer(hdr, delta);
-                    }
-                    full = add_byte_to_buffer(m, hdr, midi_byte);
-                    if (midi_byte == MIDI_EOX) {
-                        b = 24; /* pretend this is last byte to exit loop */
-                        m->sysex_mode = FALSE;
-                    }
-                    /* see if it's time to send buffer, note that by always
-                       sending complete sysex message right away, we can use
-                       this code to set up the MIDIEVENT properly
-                     */
-                    if (full || midi_byte == MIDI_EOX) {
-                        /* add bytes recorded to MIDIEVENT length, but don't
-                           count the MIDIEVENT data (3 longs) */
-                        MIDIEVENT *evt = (MIDIEVENT *) hdr->lpData;
-                        evt->dwEvent += hdr->dwBytesRecorded - 3 * sizeof(long);
-                        /* round up BytesRecorded to multiple of 4 */
-                        hdr->dwBytesRecorded = (hdr->dwBytesRecorded + 3) & ~3;
-                        m->error = midiStreamOut(m->handle.stream, hdr,
-                                                 sizeof(MIDIHDR));
-                        if (m->error) {
-                            rslt = pmHostError;
-                        }
-                        hdr = NULL; /* make sure we don't send it again */
-                    }
-                    b += 8; /* shift to next byte */
-                }
-                /* test rslt here in case it was set when we terminated a sysex early
-                   (see above) */
-            } else if (rslt == pmNoError) {
-                int full = add_to_buffer(m, hdr, delta, msg);
-                if (full) {
-                    m->error = midiStreamOut(m->handle.stream, hdr,
-                                             sizeof(MIDIHDR));
-                    if (m->error) rslt = pmHostError;
-                    hdr = NULL;
-                }
-            }
-        }
-        if (hdr && rslt == pmNoError) {
-            if (m->sysex_mode) {
-                MIDIEVENT *evt = (MIDIEVENT *) hdr->lpData;
-                evt->dwEvent += hdr->dwBytesRecorded - 3 * sizeof(long);
-                /* round up BytesRecorded to multiple of 4 */
-                hdr->dwBytesRecorded = (hdr->dwBytesRecorded + 3) & ~3;
-            }
-            m->error = midiStreamOut(m->handle.stream, hdr, sizeof(MIDIHDR));
-            if (m->error) rslt = pmHostError;
-        }
-    }
-    return rslt;
-}
-#endif
-
-
-/* winmm_out_callback -- recycle sysex buffers */
-static void CALLBACK winmm_out_callback(HMIDIOUT hmo, UINT wMsg,
-                                        DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
-{
-    int i;
-    PmInternal *midi = (PmInternal *) dwInstance;
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    LPMIDIHDR hdr = (LPMIDIHDR) dwParam1;
-    int err = 0;  /* set to 0 so that no buffer match will also be an error */
-    static int entry = 0;
-    if (++entry > 1) {
-        assert(FALSE);
-    }
-    if (m->callback_error || wMsg != MOM_DONE) {
-        entry--;
-        return ;
-    }
-    /* Future optimization: eliminate UnprepareHeader calls -- they aren't
-       necessary; however, this code uses the prepared-flag to indicate which
-       buffers are free, so we need to do something to flag empty buffers if
-       we leave them prepared
-     */
-    m->callback_error = midiOutUnprepareHeader(m->handle.out, hdr,
-                        sizeof(MIDIHDR));
-    /* notify waiting sender that a buffer is available */
-    /* any errors could be reported via callback_error, but this is always
-       treated as a Midi error, so we'd have to write a lot more code to
-       detect that a non-Midi error occurred and do the right thing to find
-       the corresponding error message text. Therefore, just use assert()
-     */
-
-    /* determine if this is an output buffer or a sysex buffer */
-
-    for (i = 0 ;i < m->num_buffers;i++) {
-        if (hdr == m->buffers[i]) {
-            err = SetEvent(m->buffer_signal);
-            break;
-        }
-    }
-    for (i = 0 ;i < m->num_sysex_buffers;i++) {
-        if (hdr == m->sysex_buffers[i]) {
-            err = SetEvent(m->sysex_buffer_signal);
-            break;
-        }
-    }
-    assert(err); /* false -> error */
-    entry--;
-}
-
-
-/* winmm_streamout_callback -- unprepare (free) buffer header */
-static void CALLBACK winmm_streamout_callback(HMIDIOUT hmo, UINT wMsg,
-        DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
-{
-    PmInternal *midi = (PmInternal *) dwInstance;
-    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-    LPMIDIHDR hdr = (LPMIDIHDR) dwParam1;
-    int err;
-    static int entry = 0;
-    if (++entry > 1) {
-        /* We've reentered this routine. I assume this never happens, but
-           check to make sure. Apparently, it is possible that this callback
-           can be called reentrantly because it happened once while debugging.
-           It looks like this routine is actually reentrant so we can remove
-           the assertion if necessary. */
-        assert(FALSE);
-    }
-    if (m->callback_error || wMsg != MOM_DONE) {
-        entry--;
-        return ;
-    }
-    m->callback_error = midiOutUnprepareHeader(m->handle.out, hdr,
-                        sizeof(MIDIHDR));
-    err = SetEvent(m->buffer_signal);
-    assert(err); /* false -> error */
-    entry--;
-}
-
-
-/*
-=========================================================================================
-begin exported functions
-=========================================================================================
-*/
-
-#define winmm_in_abort pm_fail_fn
-pm_fns_node pm_winmm_in_dictionary = {
-                                         none_write_short,
-                                         none_sysex,
-                                         none_sysex,
-                                         none_write_byte,
-                                         none_write_short,
-                                         none_write_flush,
-                                         winmm_synchronize,
-                                         winmm_in_open,
-                                         winmm_in_abort,
-                                         winmm_in_close,
-                                         success_poll,
-                                         winmm_has_host_error,
-                                         winmm_get_host_error
-                                     };
-
-pm_fns_node pm_winmm_out_dictionary = {
-                                          winmm_write_short,
-                                          winmm_begin_sysex,
-                                          winmm_end_sysex,
-                                          winmm_write_byte,
-                                          winmm_write_short,  /* short realtime message */
-                                          winmm_write_flush,
-                                          winmm_synchronize,
-                                          winmm_out_open,
-                                          winmm_out_abort,
-                                          winmm_out_close,
-                                          none_poll,
-                                          winmm_has_host_error,
-                                          winmm_get_host_error
-                                      };
-
-
-/* initialize winmm interface. Note that if there is something wrong
-   with winmm (e.g. it is not supported or installed), it is not an
-   error. We should simply return without having added any devices to
-   the table. Hence, no error code is returned. Furthermore, this init
-   code is called along with every other supported interface, so the
-   user would have a very hard time figuring out what hardware and API
-   generated the error. Finally, it would add complexity to pmwin.c to
-   remember where the error code came from in order to convert to text.
- */
-void pm_winmm_init( void )
-{
-    pm_winmm_mapper_input();
-    pm_winmm_mapper_output();
-    pm_winmm_general_inputs();
-    pm_winmm_general_outputs();
-}
-
-
-/* no error codes are returned, even if errors are encountered, because
-   there is probably nothing the user could do (e.g. it would be an error
-   to retry.
- */
-void pm_winmm_term( void )
-{
-    int i;
-#ifdef DEBUG
-    char msg[PM_HOST_ERROR_MSG_LEN];
-#endif
-    int doneAny = 0;
-#ifdef DEBUG
-    printf("pm_winmm_term called\n");
-#endif
-    for (i = 0; i < pm_descriptor_index; i++) {
-        PmInternal * midi = descriptors[i].internalDescriptor;
-        if (midi) {
-            midiwinmm_type m = (midiwinmm_type) midi->descriptor;
-            if (m->handle.out) {
-                /* close next open device*/
-#ifdef DEBUG
-                if (doneAny == 0) {
-                    printf("begin closing open devices...\n");
-                    doneAny = 1;
-                }
-                /* report any host errors; this EXTEREMELY useful when
-                   trying to debug client app */
-                if (winmm_has_host_error(midi)) {
-                    winmm_get_host_error(midi, msg, PM_HOST_ERROR_MSG_LEN);
-                    printf(msg);
-                }
-#endif
-                /* close all open ports */
-                (*midi->dictionary->close)(midi);
-            }
-        }
-    }
-#ifdef DEBUG
-    if (doneAny) {
-        printf("warning: devices were left open. They have been closed.\n");
-    }
-    printf("pm_winmm_term exiting\n");
-#endif
-    pm_descriptor_index = 0;
-}
diff --git a/portmidi/pm_win/pmwinmm.h b/portmidi/pm_win/pmwinmm.h
deleted file mode 100644
index 53c5fe284..000000000
--- a/portmidi/pm_win/pmwinmm.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/* midiwin32.h -- system-specific definitions */
-
-void pm_winmm_init( void );
-void pm_winmm_term( void );
-
diff --git a/portmidi/portmidi.dsp b/portmidi/portmidi.dsp
deleted file mode 100644
index 699cc120e..000000000
--- a/portmidi/portmidi.dsp
+++ /dev/null
@@ -1,124 +0,0 @@
-# Microsoft Developer Studio Project File - Name="portmidi" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=portmidi - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "portmidi.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "portmidi.mak" CFG="portmidi - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "portmidi - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "portmidi - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "portmidi - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "pm_win\Release"
-# PROP Intermediate_Dir "pm_win\Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "pm_common" /I "porttime" /I "pm_win" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF  "$(CFG)" == "portmidi - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "pm_win\Debug"
-# PROP Intermediate_Dir "pm_win\Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "pm_common" /I "porttime" /I "pm_win" /D "_LIB" /D "DEBUG" /D "PM_CHECK_ERRORS" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "USE_DLL_FOR_CLEANUP" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ENDIF 
-
-# Begin Target
-
-# Name "portmidi - Win32 Release"
-# Name "portmidi - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\pm_common\pmutil.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\pm_win\pmwin.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\pm_win\pmwinmm.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\pm_common\portmidi.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\pm_common\pminternal.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\pm_common\pmutil.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\pm_win\pmwinmm.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\pm_common\portmidi.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/portmidi/portmidi.dsw b/portmidi/portmidi.dsw
deleted file mode 100644
index 1ccfb5bf2..000000000
--- a/portmidi/portmidi.dsw
+++ /dev/null
@@ -1,158 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "latency"=.\PM_TEST\latency.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-    Begin Project Dependency
-    Project_Dep_Name portmidi
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name porttime
-    End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "midithread"=.\pm_test\midithread.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-    Begin Project Dependency
-    Project_Dep_Name pm_dll
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name portmidi
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name porttime
-    End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "midithru"=.\pm_test\midithru.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-    Begin Project Dependency
-    Project_Dep_Name pm_dll
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name portmidi
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name porttime
-    End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pm_dll"=.\pm_win\pm_dll.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "portmidi"=.\portmidi.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-    Begin Project Dependency
-    Project_Dep_Name porttime
-    End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "porttime"=.\porttime\porttime.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "sysex"=.\pm_test\sysex.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-    Begin Project Dependency
-    Project_Dep_Name pm_dll
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name portmidi
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name porttime
-    End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "test"=.\pm_test\test.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-    Begin Project Dependency
-    Project_Dep_Name pm_dll
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name portmidi
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name porttime
-    End Project Dependency
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/portmidi/porttime/porttime.c b/portmidi/porttime/porttime.c
deleted file mode 100644
index 71b06f4ab..000000000
--- a/portmidi/porttime/porttime.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* porttime.c -- portable API for millisecond timer */
-
-/* There is no machine-independent implementation code to put here */
diff --git a/portmidi/porttime/porttime.dsp b/portmidi/porttime/porttime.dsp
deleted file mode 100644
index 364373c97..000000000
--- a/portmidi/porttime/porttime.dsp
+++ /dev/null
@@ -1,104 +0,0 @@
-# Microsoft Developer Studio Project File - Name="porttime" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=porttime - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "porttime.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "porttime.mak" CFG="porttime - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "porttime - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "porttime - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "porttime - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF  "$(CFG)" == "porttime - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_LIB" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "USE_DLL_FOR_CLEANUP" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ENDIF 
-
-# Begin Target
-
-# Name "porttime - Win32 Release"
-# Name "porttime - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\porttime.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\ptwinmm.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\porttime.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/portmidi/porttime/porttime.h b/portmidi/porttime/porttime.h
deleted file mode 100644
index 762a71af8..000000000
--- a/portmidi/porttime/porttime.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* porttime.h -- portable interface to millisecond timer */
-
-/* CHANGE LOG FOR PORTTIME
-  10-Jun-03 Mark Nelson & RBD
-    boost priority of timer thread in ptlinux.c implementation
- */
-
-/* Should there be a way to choose the source of time here? */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-typedef enum {
-    ptNoError = 0,
-    ptHostError = -10000,
-    ptAlreadyStarted,
-    ptAlreadyStopped,
-    ptInsufficientMemory
-} PtError;
-
-
-typedef long PtTimestamp;
-
-typedef void (PtCallback)( PtTimestamp timestamp, void *userData );
-
-
-PtError Pt_Start(int resolution, PtCallback *callback, void *userData);
-PtError Pt_Stop( void);
-int Pt_Started( void);
-PtTimestamp Pt_Time( void);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/portmidi/porttime/ptlinux.c b/portmidi/porttime/ptlinux.c
deleted file mode 100644
index c99abf04d..000000000
--- a/portmidi/porttime/ptlinux.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* ptlinux.c -- portable timer implementation for linux */
-
-
-/* IMPLEMENTATION NOTES (by Mark Nelson): 
-
-Unlike Windows, Linux has no system call to request a periodic callback,
-so if Pt_Start() receives a callback parameter, it must create a thread
-that wakes up periodically and calls the provided callback function.
-If running as superuser, use setpriority() to renice thread to -20.  
-One could also set the timer thread to a real-time priority (SCHED_FIFO
-and SCHED_RR), but this is dangerous for This is necessary because  
-if the callback hangs it'll never return. A more serious reason
-is that the current scheduler implementation busy-waits instead 
-of sleeping when realtime threads request a sleep of <=2ms (as a way 
-to get around the 10ms granularity), which means the thread would never 
-let anyone else on the CPU.
-
-CHANGE LOG
-
-18-Jul-03 Roger Dannenberg -- Simplified code to set priority of timer
-            thread. Simplified implementation notes. 
-
-*/
-
-#include "porttime.h"
-#include "sys/time.h"
-#include "sys/resource.h"
-#include "sys/timeb.h"
-#include "pthread.h"
-
-#define TRUE 1
-#define FALSE 0
-
-static int time_started_flag = FALSE;
-static struct timeb time_offset = {0, 0, 0, 0};
-static pthread_t pt_thread_pid;
-
-/* note that this is static data -- we only need one copy */
-typedef struct {
-    int id;
-    int resolution;
-    PtCallback *callback;
-    void *userData;
-} pt_callback_parameters;
-
-static int pt_callback_proc_id = 0;
-
-static void *Pt_CallbackProc(void *p)
-{
-    pt_callback_parameters *parameters = (pt_callback_parameters *) p;
-    int mytime = 1;
-    /* to kill a process, just increment the pt_callback_proc_id */
-    /* printf("pt_callback_proc_id %d, id %d\n", pt_callback_proc_id,
-           parameters->id); */
-    if (geteuid() == 0) setpriority(PRIO_PROCESS, 0, -20);
-	while (pt_callback_proc_id == parameters->id) {
-        /* wait for a multiple of resolution ms */
-        struct timeval timeout;
-        int delay = mytime++ * parameters->resolution - Pt_Time();
-        if (delay < 0) delay = 0;
-        timeout.tv_sec = 0;
-        timeout.tv_usec = delay * 1000;
-        select(0, NULL, NULL, NULL, &timeout);
-        (*(parameters->callback))(Pt_Time(), parameters->userData);
-    }
-    printf("Pt_CallbackProc exiting\n");
-//    free(parameters);
-    return NULL;
-}
-
-
-PtError Pt_Start(int resolution, PtCallback *callback, void *userData)
-{
-    if (time_started_flag) return ptNoError;
-    ftime(&time_offset); /* need this set before process runs */
-    if (callback) {
-        int res;
-        pt_callback_parameters *parms = (pt_callback_parameters *) 
-            malloc(sizeof(pt_callback_parameters));
-        if (!parms) return ptInsufficientMemory;
-        parms->id = pt_callback_proc_id;
-        parms->resolution = resolution;
-        parms->callback = callback;
-        parms->userData = userData;
-        res = pthread_create(&pt_thread_pid, NULL, 
-                             Pt_CallbackProc, parms);
-        if (res != 0) return ptHostError;
-    }
-    time_started_flag = TRUE;
-    return ptNoError;
-}
-
-
-PtError Pt_Stop()
-{
-    printf("Pt_Stop called\n");
-    pt_callback_proc_id++;
-    time_started_flag = FALSE;
-    return ptNoError;
-}
-
-
-int Pt_Started()
-{
-    return time_started_flag;
-}
-
-
-PtTimestamp Pt_Time()
-{
-    long seconds, milliseconds;
-    struct timeb now;
-    ftime(&now);
-    seconds = now.time - time_offset.time;
-    milliseconds = now.millitm - time_offset.millitm;
-    return seconds * 1000 + milliseconds;
-}
-
-
-
diff --git a/portmidi/porttime/ptmacosx_cf.c b/portmidi/porttime/ptmacosx_cf.c
deleted file mode 100644
index 1837246bd..000000000
--- a/portmidi/porttime/ptmacosx_cf.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* ptmacosx.c -- portable timer implementation for mac os x */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <pthread.h>
-#include <CoreFoundation/CoreFoundation.h>
-
-#import <mach/mach.h>
-#import <mach/mach_error.h>
-#import <mach/mach_time.h>
-#import <mach/clock.h>
-
-#include "porttime.h"
-
-#define THREAD_IMPORTANCE 30
-#define LONG_TIME 1000000000.0
-
-static int time_started_flag = FALSE;
-static CFAbsoluteTime startTime = 0.0;
-static CFRunLoopRef timerRunLoop;
-
-typedef struct {
-    int resolution;
-    PtCallback *callback;
-    void *userData;
-} PtThreadParams;
-
-
-void Pt_CFTimerCallback(CFRunLoopTimerRef timer, void *info)
-{
-    PtThreadParams *params = (PtThreadParams*)info;
-    (*params->callback)(Pt_Time(), params->userData);
-}
-
-static void* Pt_Thread(void *p)
-{
-    CFTimeInterval timerInterval;
-    CFRunLoopTimerContext timerContext;
-    CFRunLoopTimerRef timer;
-    PtThreadParams *params = (PtThreadParams*)p;
-    //CFTimeInterval timeout;
-
-    /* raise the thread's priority */
-    kern_return_t error;
-    thread_extended_policy_data_t extendedPolicy;
-    thread_precedence_policy_data_t precedencePolicy;
-
-    extendedPolicy.timeshare = 0;
-    error = thread_policy_set(mach_thread_self(), THREAD_EXTENDED_POLICY,
-                              (thread_policy_t)&extendedPolicy,
-                              THREAD_EXTENDED_POLICY_COUNT);
-    if (error != KERN_SUCCESS) {
-        mach_error("Couldn't set thread timeshare policy", error);
-    }
-
-    precedencePolicy.importance = THREAD_IMPORTANCE;
-    error = thread_policy_set(mach_thread_self(), THREAD_PRECEDENCE_POLICY,
-                              (thread_policy_t)&precedencePolicy,
-                              THREAD_PRECEDENCE_POLICY_COUNT);
-    if (error != KERN_SUCCESS) {
-        mach_error("Couldn't set thread precedence policy", error);
-    }
-
-    /* set up the timer context */
-    timerContext.version = 0;
-    timerContext.info = params;
-    timerContext.retain = NULL;
-    timerContext.release = NULL;
-    timerContext.copyDescription = NULL;
-
-    /* create a new timer */
-    timerInterval = (double)params->resolution / 1000.0;
-    timer = CFRunLoopTimerCreate(NULL, startTime+timerInterval, timerInterval,
-                                 0, 0, Pt_CFTimerCallback, &timerContext);
-
-    timerRunLoop = CFRunLoopGetCurrent();
-    CFRunLoopAddTimer(timerRunLoop, timer, CFSTR("PtTimeMode"));
-
-    /* run until we're told to stop by Pt_Stop() */
-    CFRunLoopRunInMode(CFSTR("PtTimeMode"), LONG_TIME, false);
-    
-    CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), timer, CFSTR("PtTimeMode"));
-    CFRelease(timer);
-    free(params);
-
-    return NULL;
-}
-
-PtError Pt_Start(int resolution, PtCallback *callback, void *userData)
-{
-    PtThreadParams *params = (PtThreadParams*)malloc(sizeof(PtThreadParams));
-    pthread_t pthread_id;
-
-    // /* make sure we're not already playing */
-    if (time_started_flag) return ptAlreadyStarted;
-    startTime = CFAbsoluteTimeGetCurrent();
-
-    if (callback) {
-    
-        params->resolution = resolution;
-        params->callback = callback;
-        params->userData = userData;
-    
-        pthread_create(&pthread_id, NULL, Pt_Thread, params);
-    }
-
-    time_started_flag = TRUE;
-    return ptNoError;
-}
-
-
-PtError Pt_Stop()
-{
-
-    CFRunLoopStop(timerRunLoop);
-    time_started_flag = FALSE;
-    return ptNoError;
-}
-
-
-int Pt_Started()
-{
-    return time_started_flag;
-}
-
-
-PtTimestamp Pt_Time()
-{
-    CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
-    return (PtTimestamp) ((now - startTime) * 1000.0);
-}
-
diff --git a/portmidi/porttime/ptmacosx_mach.c b/portmidi/porttime/ptmacosx_mach.c
deleted file mode 100644
index 935d99bb7..000000000
--- a/portmidi/porttime/ptmacosx_mach.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* ptmacosx.c -- portable timer implementation for mac os x */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <CoreAudio/HostTime.h>
-
-#import <mach/mach.h>
-#import <mach/mach_error.h>
-#import <mach/mach_time.h>
-#import <mach/clock.h>
-
-#include "porttime.h"
-#include "sys/time.h"
-#include "pthread.h"
-
-#define NSEC_PER_MSEC 1000000
-#define THREAD_IMPORTANCE 30
-
-static int time_started_flag = FALSE;
-static UInt64 start_time;
-static pthread_t pt_thread_pid;
-
-/* note that this is static data -- we only need one copy */
-typedef struct {
-    int id;
-    int resolution;
-    PtCallback *callback;
-    void *userData;
-} pt_callback_parameters;
-
-static int pt_callback_proc_id = 0;
-
-static void *Pt_CallbackProc(void *p)
-{
-    pt_callback_parameters *parameters = (pt_callback_parameters *) p;
-    int mytime = 1;
-
-    kern_return_t error;
-    thread_extended_policy_data_t extendedPolicy;
-    thread_precedence_policy_data_t precedencePolicy;
-
-    extendedPolicy.timeshare = 0;
-    error = thread_policy_set(mach_thread_self(), THREAD_EXTENDED_POLICY,
-                              (thread_policy_t)&extendedPolicy,
-                              THREAD_EXTENDED_POLICY_COUNT);
-    if (error != KERN_SUCCESS) {
-        mach_error("Couldn't set thread timeshare policy", error);
-    }
-
-    precedencePolicy.importance = THREAD_IMPORTANCE;
-    error = thread_policy_set(mach_thread_self(), THREAD_PRECEDENCE_POLICY,
-                              (thread_policy_t)&precedencePolicy,
-                              THREAD_PRECEDENCE_POLICY_COUNT);
-    if (error != KERN_SUCCESS) {
-        mach_error("Couldn't set thread precedence policy", error);
-    }
-    
-    
-    /* to kill a process, just increment the pt_callback_proc_id */
-    printf("pt_callback_proc_id %d, id %d\n", pt_callback_proc_id, parameters->id);
-    while (pt_callback_proc_id == parameters->id) {
-        /* wait for a multiple of resolution ms */
-        UInt64 wait_time;
-        int delay = mytime++ * parameters->resolution - Pt_Time();
-        if (delay < 0) delay = 0;
-        wait_time = AudioConvertNanosToHostTime((UInt64)delay * NSEC_PER_MSEC);
-        wait_time += AudioGetCurrentHostTime();
-        error = mach_wait_until(wait_time);
-        (*(parameters->callback))(Pt_Time(), parameters->userData);
-    }
-    printf("Pt_CallbackProc exiting\n");
-    free(parameters);
-    return NULL;
-}
-
-
-PtError Pt_Start(int resolution, PtCallback *callback, void *userData)
-{
-    if (time_started_flag) return ptAlreadyStarted;
-    start_time = AudioGetCurrentHostTime();
-    
-    if (callback) {
-        int res;
-        pt_callback_parameters *parms;
-
-        parms = (pt_callback_parameters *) malloc(sizeof(pt_callback_parameters));
-        if (!parms) return ptInsufficientMemory;
-        parms->id = pt_callback_proc_id;
-        parms->resolution = resolution;
-        parms->callback = callback;
-        parms->userData = userData;
-        res = pthread_create(&pt_thread_pid, NULL, Pt_CallbackProc, parms);
-        if (res != 0) return ptHostError;
-    }
-    
-    time_started_flag = TRUE;
-    return ptNoError;
-}
-
-
-PtError Pt_Stop()
-{
-    printf("Pt_Stop called\n");
-    pt_callback_proc_id++;
-    time_started_flag = FALSE;
-    return ptNoError;
-}
-
-
-int Pt_Started()
-{
-    return time_started_flag;
-}
-
-
-PtTimestamp Pt_Time()
-{
-    UInt64 clock_time, nsec_time;
-    clock_time = AudioGetCurrentHostTime() - start_time;
-    nsec_time = AudioConvertHostTimeToNanos(clock_time);
-    return (PtTimestamp)(nsec_time / NSEC_PER_MSEC);
-}
-
diff --git a/portmidi/porttime/ptwinmm.c b/portmidi/porttime/ptwinmm.c
deleted file mode 100644
index bbfebb0ec..000000000
--- a/portmidi/porttime/ptwinmm.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* ptwinmm.c -- portable timer implementation for win32 */
-
-
-#include "porttime.h"
-#include "windows.h"
-#include "time.h"
-
-
-TIMECAPS caps;
-
-static long time_offset = 0;
-static int time_started_flag = FALSE;
-static long time_resolution;
-static MMRESULT timer_id;
-static PtCallback *time_callback;
-
-void CALLBACK winmm_time_callback(UINT uID, UINT uMsg, DWORD dwUser, 
-                                  DWORD dw1, DWORD dw2)
-{
-    (*time_callback)(Pt_Time(), (void *) dwUser);
-}
- 
-
-PtError Pt_Start(int resolution, PtCallback *callback, void *userData)
-{
-    if (time_started_flag) return ptAlreadyStarted;
-    timeBeginPeriod(resolution);
-    time_resolution = resolution;
-    time_offset = timeGetTime();
-    time_started_flag = TRUE;
-    time_callback = callback;
-    if (callback) {
-        timer_id = timeSetEvent(resolution, 1, winmm_time_callback, 
-            (DWORD) userData, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
-        if (!timer_id) return ptHostError;
-    }
-    return ptNoError;
-}
-
-
-PtError Pt_Stop()
-{
-    if (!time_started_flag) return ptAlreadyStopped;
-    if (time_callback && timer_id) {
-        timeKillEvent(timer_id);
-        time_callback = NULL;
-        timer_id = 0;
-    }
-    time_started_flag = FALSE;
-    timeEndPeriod(time_resolution);
-    return ptNoError;
-}
-
-
-int Pt_Started()
-{
-    return time_started_flag;
-}
-
-
-PtTimestamp Pt_Time()
-{
-    return timeGetTime() - time_offset;
-}
-
diff --git a/src/s_midi_sgi.c b/src/s_midi_sgi.c
deleted file mode 100644
index 4634b5712..000000000
--- a/src/s_midi_sgi.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* Copyright (c) 1997-1999 Miller Puckette.
-* For information on usage and redistribution, and for a DISCLAIMER OF ALL
-* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */
-
-#include "m_pd.h"
-#include "s_stuff.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#ifdef HAVE_BSTRING_H
-#include <bstring.h>
-#endif
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include <dmedia/audio.h>
-#include <sys/fpu.h>
-#include <dmedia/midi.h>
-int mdInit(void);               /* prototype was messed up in midi.h */
-/* #include "sys/select.h" */
-
-
-  /*
-    set the special "flush zero" but (FS, bit 24) in the
-    Control Status Register of the FPU of R4k and beyond
-    so that the result of any underflowing operation will
-    be clamped to zero, and no exception of any kind will
-    be generated on the CPU.
-    
-    thanks to cpirazzi@cp.esd.sgi.com (Chris Pirazzi).
-  */
-
-static void sgi_flush_all_underflows_to_zero(void)
-{
-    union fpc_csr f;
-    f.fc_word = get_fpc_csr();
-    f.fc_struct.flush = 1;
-    set_fpc_csr(f.fc_word);
-}
-
-#define NPORT 2
-
-static MDport sgi_inport[NPORT];
-static MDport sgi_outport[NPORT];
-
-void sgi_open_midi(int midiin, int midiout)
-{
-    int i;
-    int sgi_nports = mdInit();
-    if (sgi_nports < 0) sgi_nports = 0;
-    else if (sgi_nports > NPORT) sgi_nports = NPORT;
-    if (sys_verbose)
-    {
-        if (!sgi_nports) 
-        {
-            post("no serial ports are configured for MIDI;");
-            post("if you want to use MIDI, try exiting Pd, typing");
-            post("'startmidi -d /dev/ttyd2' to a shell, and restarting Pd.");
-        }
-        else if (sgi_nports == 1)
-            post("Found one MIDI port on %s", mdGetName(0));
-        else if (sgi_nports == 2)
-            post("Found MIDI ports on %s and %s",
-                mdGetName(0), mdGetName(1));
-    }
-    if (midiin)
-    {
-        for (i = 0; i < sgi_nports; i++)
-        {
-            if (!(sgi_inport[i] = mdOpenInPort(mdGetName(i)))) 
-                error("MIDI input port %d: open failed", i+1);;
-        }
-    }
-    if (midiout)
-    {
-        for (i = 0; i < sgi_nports; i++)
-        {
-            if (!(sgi_outport[i] = mdOpenOutPort(mdGetName(i))))
-                error("MIDI output port %d: open failed", i+1);;
-        }
-    }
-    return;
-}
-
-void sys_putmidimess(int portno, int a, int b, int c)
-{
-    MDevent mdv;
-    if (portno >= NPORT || portno < 0 || !sgi_outport[portno]) return;
-    mdv.msg[0] = a;
-    mdv.msg[1] = b;
-    mdv.msg[2] = c;
-    mdv.msg[3] = 0;
-    mdv.sysexmsg = 0;
-    mdv.stamp = 0;
-    mdv.msglen = 0;
-    if (mdSend(sgi_outport[portno], &mdv, 1) < 0)
-        error("MIDI output error\n");
-    post("msg out %d %d %d", a, b, c);
-}
-
-void sys_putmidibyte(int portno, int foo)
-{
-    error("MIDI raw byte output not available on SGI");
-}
-
-void inmidi_noteon(int portno, int channel, int pitch, int velo);
-void inmidi_controlchange(int portno, int channel, int ctlnumber, int value);
-void inmidi_programchange(int portno, int channel, int value);
-void inmidi_pitchbend(int portno, int channel, int value);
-void inmidi_aftertouch(int portno, int channel, int value);
-void inmidi_polyaftertouch(int portno, int channel, int pitch, int value);
-
-void sys_poll_midi(void)
-{
-    int i;
-    MDport *mp;
-    for (i = 0, mp = sgi_inport; i < NPORT; i++, mp++)
-    {
-        int ret,  status,  b1,  b2, nfds;
-        MDevent mdv;
-        fd_set inports;
-        struct timeval timeout;
-        timeout.tv_sec = 0;
-        timeout.tv_usec = 0;
-        if (!*mp) continue;
-        FD_ZERO(&inports);
-        FD_SET(mdGetFd(*mp), &inports);
-
-        if (select(mdGetFd(*mp)+1 , &inports, 0, 0, &timeout) < 0)
-            perror("midi select");
-        if (FD_ISSET(mdGetFd(*mp),&inports))
-        {
-            if (mdReceive(*mp, &mdv, 1) < 0)
-                error("failure receiving message\n");
-            else if (mdv.msg[0] == MD_SYSEX) mdFree(mdv.sysexmsg);
-
-            else
-            {
-                int status = mdv.msg[0];
-                int channel = (status & 0xf) + 1;
-                int b1 = mdv.msg[1];
-                int b2 = mdv.msg[2];
-                switch(status & 0xf0)
-                {
-                case MD_NOTEOFF:
-                    inmidi_noteon(i, channel, b1, 0);
-                    break;
-                case MD_NOTEON:
-                    inmidi_noteon(i, channel, b1, b2);
-                    break;
-                case MD_POLYKEYPRESSURE:
-                    inmidi_polyaftertouch(i, channel, b1, b2);
-                    break;
-                case MD_CONTROLCHANGE:
-                    inmidi_controlchange(i, channel, b1, b2);
-                    break;
-                case MD_PITCHBENDCHANGE:
-                    inmidi_pitchbend(i, channel, ((b2 << 7) + b1));
-                    break;
-                case MD_PROGRAMCHANGE:
-                    inmidi_programchange(i, channel, b1);
-                    break;
-                case MD_CHANNELPRESSURE:
-                    inmidi_aftertouch(i, channel, b1);
-                    break;
-                }
-            }
-        }
-    }
-}
-
-void sys_do_open_midi(int nmidiin, int *midiinvec,
-    int nmidiout, int *midioutvec)
-{
-    sgi_open_midi(nmidiin!=0, nmidiout!=0);
-}
-
-
-void sys_close_midi( void)
-{
-    /* ??? */
-}
-
-
-void midi_getdevs(char *indevlist, int *nindevs,
-    char *outdevlist, int *noutdevs, int maxndev, int devdescsize)
-{
-    int i, nindev = 0, noutdev = 0;
-    for (i = 0; i < mdInit(); i++)
-    {
-                if (nindev < maxndev)
-                {
-                    strcpy(indevlist + nindev * devdescsize, mdGetName(i));
-                    nindev++;
-
-                    strcpy(outdevlist + noutdev * devdescsize, mdGetName(i));
-                    noutdev++;
-                }
-    }
-    *nindevs = nindev;
-    *noutdevs = noutdev;
-}
-- 
GitLab