diff options
Diffstat (limited to 'pd/portaudio')
179 files changed, 0 insertions, 51453 deletions
diff --git a/pd/portaudio/LICENSE.txt b/pd/portaudio/LICENSE.txt deleted file mode 100644 index 105da3f7..00000000 --- a/pd/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/pd/portaudio/MSP-README.txt b/pd/portaudio/MSP-README.txt deleted file mode 100644 index bd75626b..00000000 --- a/pd/portaudio/MSP-README.txt +++ /dev/null @@ -1,6 +0,0 @@ -These files are from the V19 branch, a CVS snapshot, around 2003.03.21. - -I had to hack up "pablio" a fair bit... my copies are named "pablio_pd.c" -and so on. - --MSP diff --git a/pd/portaudio/Makefile.in b/pd/portaudio/Makefile.in deleted file mode 100644 index 18c2707f..00000000 --- a/pd/portaudio/Makefile.in +++ /dev/null @@ -1,132 +0,0 @@ -# -# PortAudio V19 Makefile.in -# -# Dominic Mazzoni -# - -PREFIX = @prefix@ -CC = @CC@ -CFLAGS = @CFLAGS@ -Ipa_common @DEFS@ -LIBS = @LIBS@ -AR = @AR@ -RANLIB = @RANLIB@ -INSTALL = @INSTALL@ -SHARED_FLAGS = @SHARED_FLAGS@ -DLL_LIBS = @DLL_LIBS@ - -OTHER_OBJS = @OTHER_OBJS@ - -PALIB = libportaudio.a -PADLL = @PADLL@ -PADLLV = $(PADLL).0.0.19 -PAINC = pa_common/portaudio.h - -COMMON_OBJS = \ - pa_common/pa_allocation.o \ - pa_common/pa_converters.o \ - pa_common/pa_cpuload.o \ - pa_common/pa_dither.o \ - pa_common/pa_front.o \ - pa_common/pa_process.o \ - pa_common/pa_skeleton.o \ - pa_common/pa_stream.o \ - pa_common/pa_trace.o - -TESTS = \ - bin/pa_devs \ - bin/pa_fuzz \ - bin/patest_sine \ - bin/patest1 - -# Most of these don't compile yet. Put them in TESTS, above, if -# you want to try to compile them... -ALL_TESTS = \ - bin/debug_convert \ - bin/debug_dither_calc \ - bin/debug_dual \ - bin/debug_multi_in \ - bin/debug_multi_out \ - bin/debug_record \ - bin/debug_record_reuse \ - bin/debug_sine_amp \ - bin/debug_sine \ - bin/debug_sine_formats \ - bin/debug_srate \ - bin/debug_test1 \ - bin/pa_devs \ - bin/pa_fuzz \ - bin/pa_minlat \ - bin/paqa_devs \ - bin/paqa_errs \ - bin/patest1 \ - bin/patest_buffer \ - bin/patest_clip \ - bin/patest_dither \ - bin/patest_hang \ - bin/patest_latency \ - bin/patest_leftright \ - bin/patest_longsine \ - bin/patest_many \ - bin/patest_maxsines \ - bin/patest_multi_sine \ - bin/patest_pink \ - bin/patest_record \ - bin/patest_ringmix \ - bin/patest_saw \ - bin/patest_sine8 \ - bin/patest_sine \ - bin/patest_sine_formats \ - bin/patest_sine_time \ - bin/patest_start_stop \ - bin/patest_stop \ - bin/patest_sync \ - bin/patest_toomanysines \ - bin/patest_underflow \ - bin/patest_wire - -OBJS = $(COMMON_OBJS) $(OTHER_OBJS) - -all: lib/$(PALIB) lib/$(PADLLV) tests - -tests: bin/ $(TESTS) - -lib/$(PALIB): lib/ $(OBJS) Makefile $(PAINC) - $(AR) ruv lib/$(PALIB) $(OBJS) - $(RANLIB) lib/$(PALIB) - -lib/$(PADLLV): lib/ $(OBJS) Makefile $(PAINC) - $(CC) $(SHARED_FLAGS) -o lib/$(PADLLV) $(OBJS) $(DLL_LIBS) - -$(TESTS): bin/%: lib/$(PALIB) Makefile $(PAINC) pa_tests/%.c - $(CC) -o $@ $(CFLAGS) pa_tests/$*.c lib/$(PALIB) $(LIBS) - -install: lib/$(PALIB) lib/$(PADLLV) - $(INSTALL) -m 644 lib/$(PADLLV) $(PREFIX)/lib/$(PADLLV) - $(INSTALL) -m 644 lib/$(PALIB) $(PREFIX)/lib/$(PALIB) - cd $(PREFIX)/lib && rm -f $(PADLL) && ln -s $(PADLLV) $(PADLL) - $(INSTALL) -m 644 pa_common/portaudio.h $(PREFIX)/include/portaudio.h - @echo "" - @echo "------------------------------------------------------------" - @echo "PortAudio was successfully installed." - @echo "" - @echo "On some systems (e.g. Linux) you should run 'ldconfig' now" - @echo "to make the shared object available. You may also need to" - @echo "modify your LD_LIBRARY_PATH environment variable to include" - @echo "the directory $(PREFIX)/lib" - @echo "------------------------------------------------------------" - @echo "" - -clean: - rm -f $(OBJS) $(TESTS) lib/$(PALIB) - -%.o: %.c Makefile $(PAINC) - $(CC) -c $(CFLAGS) $< -o $@ - -bin: - mkdir bin - -lib: - mkdir lib - - - diff --git a/pd/portaudio/Makefile.linux b/pd/portaudio/Makefile.linux deleted file mode 100644 index 4deee60a..00000000 --- a/pd/portaudio/Makefile.linux +++ /dev/null @@ -1,59 +0,0 @@ -# Make PortAudio for Linux -# Updated 2001/08/25 Bill Eldridge bill@rfa.org -# Updated 2001/10/16, philburk@softsynth.com, s/unix_oss/unix_oss/ -# Updated 2002/04/30 Bill Eldridge bill@rfa.org -# Made the libinstall and tests compile a bit cleaner - -# A pretty bare makefile, that figures out all the test files -# and compiles them against the library in the pa_unix_oss directory. - -# Do "make all" and then when happy, "make libinstall" -# (if not happy, "make clean") - -# The ldconfig stuff in libinstall is the wrong way to do it - -# someone tell me the right way, please - - -LIBS = -lm -lpthread - -CDEFINES = -I../pa_common -CFLAGS = -g -LIBINST = /usr/local/lib - -TESTS:= $(wildcard pa_tests/pa*.c pa_tests/debug*.c) -TESTO:= $(wildcard pa_tests/pa*.o pa_tests/debug*.o) - -LIBFILES:= ./pa_common/pa_lib.c ./pa_unix_oss/pa_unix_oss.c - -#all: sharedlib libinstall tests -all: sharedlib libinstall testo testq - -.c.o: - -gcc -c -I./pa_common $< -o $*.o - -.o: - -gcc $*.o -o $* -Lpa_unix_oss $(LIBS) -lportaudio - -#.c.o: -# -gcc -c -I./pa_common $< -o $*.o -# -gcc $*.o -o $* -Lpa_unix_oss $(LIBS) -lportaudio - - -sharedlib: $(LIBFILES:.c=.o) - gcc -shared -o ./pa_unix_oss/libportaudio.so ./pa_common/pa_lib.o ./pa_unix_oss/pa_unix_oss.o - -libinstall: ./pa_unix_oss/libportaudio.so - @cp -f ./pa_unix_oss/libportaudio.so $(LIBINST) - @/sbin/ldconfig - -testo: $(TESTS:.c=.o) - -testq: $(TESTO:.o=) - -clean: - -@rm -f $(TESTS:.c=.o) - -@rm -f $(TESTS:.c=) - -@rm -f $(LIBFILES:.c=.o) - -@rm -f ./pa_unix_oss/libportaudio.so - - diff --git a/pd/portaudio/Makefile.mingw b/pd/portaudio/Makefile.mingw deleted file mode 100644 index 2043a161..00000000 --- a/pd/portaudio/Makefile.mingw +++ /dev/null @@ -1,57 +0,0 @@ - -# Makefile for PortAudio on mingw (http://mingw.sourceforge.net) - -# Contributed by Bill Eldridge, bill@rfa.org, Radio Free Asia -# Copyright 2002/02/20, GPL - -# Uses a common mingw32 cross-compiler that defaults -# to everything in /usr/local/cross-tools - -# First edit your path with -# export PATH=/usr/local/cross-tools/bin:$PATH - -# Usage: make -f Makefile.mingw all -# or make -f Makefile.mingw sharedlib -# make -f Makefile.mingw tests -# -# Then copy executables & portaudio.dll to your Windows machine -# -# To make work with pa_win_ds, you'll have to substitue -# all the pa_win_wmme files with pa_win_ds files, no biggie. - -CC= i586-mingw32msvc-gcc -DLLTOOL= i586-mingw32msvc-dlltool -DLLWRAP= i586-mingw32msvc-dllwrap - -ARCH= pa_win_wmme - -TESTS:= $(wildcard pa_tests/pa*.c pa_tests/debug*.c) - -.c.o: - -$(CC) -c -I./pa_common $< -o $*.o - -$(CC) $*.o -o $*.exe -L/usr/local/lib -L$(ARCH) -lportaudio.dll -lwinmm - -all: sharedlib tests - -sharedlib: ./pa_common/pa_lib.c - $(CC) -c -I./pa_common pa_common/pa_lib.c -o pa_common/pa_lib.o - $(CC) -c -I./pa_common pa_win_wmme/pa_win_wmme.c -o pa_win_wmme/pa_win_wmme.o - $(CC) -shared -mthreads -o portaudio.dll pa_common/pa_lib.o pa_win_wmme/pa_win_wmme.o -L/usr/local/cross-tools/i586-win32msvc/lib -lwinmm -lm - $(DLLWRAP) --export-all --output-def=libportaudio.def --output-lib=libportaudio.a --dllname=portaudio.dll --drivername=i586-mingw32msvc-gcc pa_common/pa_lib.o pa_win_wmme/pa_win_wmme.o -L/usr/local/cross-tools/i586-win32msvc/lib -lwinmm -lm - $(CC) -shared -Wl,--enable-auto-image-base -o portaudio.dll -Wl,--out-implib=pa_win_wmme/libportaudio.dll.a pa_common/pa_lib.o pa_win_wmme/pa_win_wmme.o -L/usr/local/cross-tools/i586-win32msvc/lib -lwinmm - - -tests: $(TESTS:.c=.o) - -sine: - $(CC) -c -I./pa_common pa_tests/patest_sine.c -o pa_tests/patest_sine.o - $(CC) pa_tests/patest_sine.o -o pa_tests/patest_sine.exe -L/usr/local/lib -lportaudio.dll -lwinmm - -clean: - -rm ./pa_tests/*.exe - -rm ./pa_tests/*.o - -nothing: - $(CC) pa_tests/patest_sine.o -L/usr/lib/w32api -L./pa_win_wmme -lportaudio.dll -lwinmm - - diff --git a/pd/portaudio/README.txt b/pd/portaudio/README.txt deleted file mode 100644 index 4cfc6166..00000000 --- a/pd/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/pd/portaudio/V19-devel-readme.txt b/pd/portaudio/V19-devel-readme.txt deleted file mode 100644 index a6bca780..00000000 --- a/pd/portaudio/V19-devel-readme.txt +++ /dev/null @@ -1,230 +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 following tests might run if you're lucky: - tests/pa_devs.c - tests/patest_sine.c - tests/pa_fuzz.c - - tests/patest1.c - -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_byteswappers.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_byteswappers.c/h - byte swapping 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/pd/portaudio/aclocal.m4 b/pd/portaudio/aclocal.m4 deleted file mode 100644 index c80e0acf..00000000 --- a/pd/portaudio/aclocal.m4 +++ /dev/null @@ -1,57 +0,0 @@ - -dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) -dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page -dnl also defines GSTUFF_PKG_ERRORS on error -AC_DEFUN(PKG_CHECK_MODULES, [ - succeeded=no - - if test -z "$PKG_CONFIG"; then - AC_PATH_PROG(PKG_CONFIG, pkg-config, no) - fi - - if test "$PKG_CONFIG" = "no" ; then - echo "*** The pkg-config script could not be found. Make sure it is" - echo "*** in your path, or set the PKG_CONFIG environment variable" - echo "*** to the full path to pkg-config." - echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." - else - PKG_CONFIG_MIN_VERSION=0.9.0 - if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then - AC_MSG_CHECKING(for $2) - - if $PKG_CONFIG --exists "$2" ; then - AC_MSG_RESULT(yes) - succeeded=yes - - AC_MSG_CHECKING($1_CFLAGS) - $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` - AC_MSG_RESULT($$1_CFLAGS) - - AC_MSG_CHECKING($1_LIBS) - $1_LIBS=`$PKG_CONFIG --libs "$2"` - AC_MSG_RESULT($$1_LIBS) - else - $1_CFLAGS="" - $1_LIBS="" - ## If we have a custom action on failure, don't print errors, but - ## do set a variable so people can do so. - $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` - ifelse([$4], ,echo $$1_PKG_ERRORS,) - fi - - AC_SUBST($1_CFLAGS) - AC_SUBST($1_LIBS) - else - echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." - echo "*** See http://www.freedesktop.org/software/pkgconfig" - fi - fi - - if test $succeeded = yes; then - ifelse([$3], , :, [$3]) - else - ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) - fi -]) - - diff --git a/pd/portaudio/config.doxy b/pd/portaudio/config.doxy deleted file mode 100644 index 98342765..00000000 --- a/pd/portaudio/config.doxy +++ /dev/null @@ -1,185 +0,0 @@ -# Doxyfile 1.2.13-20020210 - -#--------------------------------------------------------------------------- -# General configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = PortAudio -PROJECT_NUMBER = 2.0 -OUTPUT_DIRECTORY = "./docs/" -OUTPUT_LANGUAGE = English -EXTRACT_ALL = YES -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = YES -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = NO -STRIP_FROM_PATH = -INTERNAL_DOCS = NO -STRIP_CODE_COMMENTS = YES -CASE_SENSE_NAMES = YES -SHORT_NAMES = NO -HIDE_SCOPE_NAMES = NO -VERBATIM_HEADERS = YES -SHOW_INCLUDE_FILES = YES -JAVADOC_AUTOBRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -DISTRIBUTE_GROUP_DOC = NO -TAB_SIZE = 8 -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -ALIASES = -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO -SHOW_USED_FILES = YES -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = ./pa_common ./pa_win_wmme ./pa_asio ./pa_win_ds -FILE_PATTERNS = *.h *.c *.cpp -RECURSIVE = YES -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_SOURCE_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = NO -INLINE_SOURCES = NO -REFERENCED_BY_RELATION = YES -REFERENCES_RELATION = YES -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = doxygen_html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NO -TREEVIEW_WIDTH = 250 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO -LATEX_BATCHMODE = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::addtions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = NO -HIDE_UNDOC_RELATIONS = NO -HAVE_DOT = NO -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -TEMPLATE_RELATIONS = YES -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -GRAPHICAL_HIERARCHY = YES -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1024 -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::addtions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO -CGI_NAME = search.cgi -CGI_URL = -DOC_URL = -DOC_ABSPATH = -BIN_ABSPATH = /usr/local/bin/ -EXT_DOC_PATHS = diff --git a/pd/portaudio/config.guess b/pd/portaudio/config.guess deleted file mode 100755 index 297e5c30..00000000 --- a/pd/portaudio/config.guess +++ /dev/null @@ -1,1308 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. - -timestamp='2001-10-05' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Per Bothner <bothner@cygnus.com>. -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - - -dummy=dummy-$$ -trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int dummy(){}" > $dummy.c ; - for c in cc gcc c89 ; do - ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; - if test $? = 0 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - rm -f $dummy.c $dummy.o $dummy.rel ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # Determine the machine/vendor (is the vendor relevant). - case "${UNAME_MACHINE}" in - amiga) machine=m68k-unknown ;; - arm32) machine=arm-unknown ;; - atari*) machine=m68k-atari ;; - sun3*) machine=m68k-sun ;; - mac68k) machine=m68k-apple ;; - macppc) machine=powerpc-apple ;; - hp3[0-9][05]) machine=m68k-hp ;; - ibmrt|romp-ibm) machine=romp-ibm ;; - sparc*) machine=`uname -p`-unknown ;; - *) machine=${UNAME_MACHINE}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE}" in - i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit 0 ;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - arc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - macppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvmeppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - pmax:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mipseb-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sun3:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - wgrisc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - alpha:OSF1:*:*) - if test $UNAME_RELEASE = "V4.0"; then - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - fi - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - cat <<EOF >$dummy.s - .data -\$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main -main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - eval $set_cc_for_build - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `./$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - 2-1307) - UNAME_MACHINE="alphaev68" - ;; - esac - fi - rm -f $dummy.s $dummy - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit 0 ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit 0 ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit 0 ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit 0;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit 0 ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit 0 ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit 0;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit 0;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit 0 ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit 0 ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit 0 ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit 0 ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit 0 ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit 0 ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit 0 ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit 0 ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit 0 ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include <stdio.h> /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy \ - && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo mips-mips-riscos${UNAME_RELEASE} - exit 0 ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit 0 ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit 0 ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit 0 ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit 0 ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit 0 ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit 0 ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit 0 ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit 0 ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit 0 ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit 0 ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit 0 ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit 0 ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <sys/systemcfg.h> - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo rs6000-ibm-aix3.2.5 - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit 0 ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit 0 ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit 0 ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit 0 ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit 0 ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit 0 ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit 0 ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include <stdlib.h> - #include <unistd.h> - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` - if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi - rm -f $dummy.c $dummy - fi ;; - esac - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit 0 ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit 0 ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <unistd.h> - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo unknown-hitachi-hiuxwe2 - exit 0 ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit 0 ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit 0 ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit 0 ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit 0 ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit 0 ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit 0 ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit 0 ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit 0 ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit 0 ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit 0 ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit 0 ;; - CRAY*X-MP:*:*:*) - echo xmp-cray-unicos - exit 0 ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3D:*:*:*) - echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY-2:*:*:*) - echo cray2-cray-unicos - exit 0 ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit 0 ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit 0 ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit 0 ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit 0 ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit 0 ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i386-pc-interix - exit 0 ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit 0 ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit 0 ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit 0 ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux - exit 0 ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - mips:Linux:*:*) - case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in - big) echo mips-unknown-linux-gnu && exit 0 ;; - little) echo mipsel-unknown-linux-gnu && exit 0 ;; - esac - ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit 0 ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit 0 ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit 0 ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit 0 ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit 0 ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit 0 ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit 0 ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - ld_supported_targets=`cd /; ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit 0 ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - cat >$dummy.c <<EOF -#include <features.h> -#ifdef __cplusplus -#include <stdio.h> /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif -#ifdef __ELF__ -# ifdef __GLIBC__ -# if __GLIBC__ >= 2 - printf ("%s-pc-linux-gnu\n", argv[1]); -# else - printf ("%s-pc-linux-gnulibc1\n", argv[1]); -# endif -# else - printf ("%s-pc-linux-gnulibc1\n", argv[1]); -# endif -#else - printf ("%s-pc-linux-gnuaout\n", argv[1]); -#endif - return 0; -} -EOF - $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit 0 ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit 0 ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit 0 ;; - i*86:*:5:[78]*) - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit 0 ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` - echo ${UNAME_MACHINE}-pc-isc$UNAME_REL - elif /bin/uname -X 2>/dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` - (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit 0 ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit 0 ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit 0 ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit 0 ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit 0 ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit 0 ;; - M68*:*:R3V[567]*:*) - test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4.3${OS_REL} && exit 0 - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit 0 ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit 0 ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit 0 ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <Richard.M.Bartel@ccMail.Census.GOV> - echo i586-unisys-sysv4 - exit 0 ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes <hewes@openmarket.com>. - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit 0 ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit 0 ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit 0 ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit 0 ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit 0 ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit 0 ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit 0 ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit 0 ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit 0 ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit 0 ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit 0 ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Darwin:*:*) - echo `uname -p`-apple-darwin${UNAME_RELEASE} - exit 0 ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - if test "${UNAME_MACHINE}" = "x86pc"; then - UNAME_MACHINE=pc - fi - echo `uname -p`-${UNAME_MACHINE}-nto-qnx - exit 0 ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit 0 ;; - NSR-[KW]:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit 0 ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit 0 ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit 0 ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit 0 ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit 0 ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit 0 ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit 0 ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit 0 ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit 0 ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit 0 ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit 0 ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit 0 ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c <<EOF -#ifdef _SEQUENT_ -# include <sys/types.h> -# include <sys/utsname.h> -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include <sys/param.h> - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include <sys/param.h> -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 -rm -f $dummy.c $dummy - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit 0 ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - c34*) - echo c34-convex-bsd - exit 0 ;; - c38*) - echo c38-convex-bsd - exit 0 ;; - c4*) - echo c4-convex-bsd - exit 0 ;; - esac -fi - -cat >&2 <<EOF -$0: unable to guess system type - -This script, last modified $timestamp, has failed to recognize -the operating system you are using. It is advised that you -download the most up to date version of the config scripts from - - ftp://ftp.gnu.org/pub/gnu/config/ - -If the version you run ($0) is already up to date, please -send the following data and any information you think might be -pertinent to <config-patches@gnu.org> in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/pd/portaudio/configure b/pd/portaudio/configure deleted file mode 100755 index fb7bed04..00000000 --- a/pd/portaudio/configure +++ /dev/null @@ -1,3496 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.53. -# -# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - - -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi - -# NLS nuisances. -# Support unset when possible. -if (FOO=FOO; unset FOO) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - -(set +x; test -n "`(LANG=C; export LANG) 2>&1`") && - { $as_unset LANG || test "${LANG+set}" != set; } || - { LANG=C; export LANG; } -(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") && - { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } || - { LC_ALL=C; export LC_ALL; } -(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") && - { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } || - { LC_TIME=C; export LC_TIME; } -(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") && - { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } || - { LC_CTYPE=C; export LC_CTYPE; } -(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") && - { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } || - { LANGUAGE=C; export LANGUAGE; } -(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") && - { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } || - { LC_COLLATE=C; export LC_COLLATE; } -(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") && - { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } || - { LC_NUMERIC=C; export LC_NUMERIC; } -(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") && - { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } || - { LC_MESSAGES=C; export LC_MESSAGES; } - - -# Name of the executable. -as_me=`(basename "$0") 2>/dev/null || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conftest.sh - echo "exit 0" >>conftest.sh - chmod +x conftest.sh - if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conftest.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; } - - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -exec 6>&1 - -# -# Initializations. -# -ac_default_prefix=/usr/local -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Maximum number of lines to put in a shell here document. -# This variable seems obsolete. It should probably be removed, and -# only ac_max_sed_lines should be used. -: ${ac_max_here_lines=38} - -# Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= - -ac_unique_file="pa_common/portaudio.h" - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -ac_prev= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_option in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval "enable_$ac_feature=no" ;; - - -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "enable_$ac_feature='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "with_$ac_package='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval "with_$ac_package=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` - eval "$ac_envvar='$ac_optarg'" - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -# Be sure to have absolute paths. -for ac_var in exec_prefix prefix -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* | NONE | '' ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# Be sure to have absolute paths. -for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir infodir mandir -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_confdir=`(dirname "$0") 2>/dev/null || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 - { (exit 1); exit 1; }; } - else - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } - fi -fi -srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` -ac_env_build_alias_set=${build_alias+set} -ac_env_build_alias_value=$build_alias -ac_cv_env_build_alias_set=${build_alias+set} -ac_cv_env_build_alias_value=$build_alias -ac_env_host_alias_set=${host_alias+set} -ac_env_host_alias_value=$host_alias -ac_cv_env_host_alias_set=${host_alias+set} -ac_cv_env_host_alias_value=$host_alias -ac_env_target_alias_set=${target_alias+set} -ac_env_target_alias_value=$target_alias -ac_cv_env_target_alias_set=${target_alias+set} -ac_cv_env_target_alias_value=$target_alias -ac_env_CC_set=${CC+set} -ac_env_CC_value=$CC -ac_cv_env_CC_set=${CC+set} -ac_cv_env_CC_value=$CC -ac_env_CFLAGS_set=${CFLAGS+set} -ac_env_CFLAGS_value=$CFLAGS -ac_cv_env_CFLAGS_set=${CFLAGS+set} -ac_cv_env_CFLAGS_value=$CFLAGS -ac_env_LDFLAGS_set=${LDFLAGS+set} -ac_env_LDFLAGS_value=$LDFLAGS -ac_cv_env_LDFLAGS_set=${LDFLAGS+set} -ac_cv_env_LDFLAGS_value=$LDFLAGS -ac_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_env_CPPFLAGS_value=$CPPFLAGS -ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_cv_env_CPPFLAGS_value=$CPPFLAGS - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -_ACEOF - - cat <<_ACEOF -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data [PREFIX/share] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --infodir=DIR info documentation [PREFIX/info] - --mandir=DIR man documentation [PREFIX/man] -_ACEOF - - cat <<\_ACEOF -_ACEOF -fi - -if test -n "$ac_init_help"; then - - cat <<\_ACEOF - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-alsa (default=auto) - --with-jack (default=auto) - --with-oss (default=yes) - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a - nonstandard directory <lib dir> - CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have - headers in a nonstandard directory <include dir> - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -_ACEOF -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - ac_popdir=`pwd` - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d $ac_dir || continue - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac -# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -# absolute. -ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd` -ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` - - cd $ac_dir - # Check for guested configure; otherwise get Cygnus style configure. - if test -f $ac_srcdir/configure.gnu; then - echo - $SHELL $ac_srcdir/configure.gnu --help=recursive - elif test -f $ac_srcdir/configure; then - echo - $SHELL $ac_srcdir/configure --help=recursive - elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then - echo - $ac_configure --help - else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi - cd $ac_popdir - done -fi - -test -n "$ac_init_help" && exit 0 -if $ac_init_version; then - cat <<\_ACEOF - -Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit 0 -fi -exec 5>config.log -cat >&5 <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by $as_me, which was -generated by GNU Autoconf 2.53. Invocation command line was - - $ $0 $@ - -_ACEOF -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -hostinfo = `(hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" -done - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell meta-characters. -ac_configure_args= -ac_sep= -for ac_arg -do - case $ac_arg in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n ) continue ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - continue ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" - ac_sep=" " ;; - esac - # Get rid of the leading space. -done - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Be sure not to use single quotes in there, as some shells, -# such as our DU 5.0 friend, will then `close' the trap. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -{ - (set) 2>&1 | - case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in - *ac_space=\ *) - sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" - ;; - *) - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} - echo - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - sed "/^$/d" confdefs.h - echo - fi - test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" - } >&5 - rm -f core core.* *.core && - rm -rf conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status - ' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo >confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . $cache_file;; - *) . ./$cache_file;; - esac - fi -else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val="\$ac_cv_env_${ac_var}_value" - eval ac_new_val="\$ac_env_${ac_var}_value" - case $ac_old_set,$ac_new_set in - set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - - - - - - - - - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - set dummy "$as_dir/$ac_word" ${1+"$@"} - shift - ac_cv_prog_CC="$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_CC" && break -done - - CC=$ac_ct_CC -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5 - (eval $ac_compiler --version </dev/null >&5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5 - (eval $ac_compiler -v </dev/null >&5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5 - (eval $ac_compiler -V </dev/null >&5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -echo "$as_me:$LINENO: checking for C compiler default output" >&5 -echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 - (eval $ac_link_default) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Find the output, starting from the most likely. This scheme is -# not robust to junk in `.', hence go to wildcards (a.*) only as a last -# resort. - -# Be careful to initialize this variable, since it used to be cached. -# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. -ac_cv_exeext= -for ac_file in `ls a_out.exe a.exe conftest.exe 2>/dev/null; - ls a.out conftest 2>/dev/null; - ls a.* conftest.* 2>/dev/null`; do - case $ac_file in - *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb | *.xSYM ) ;; - a.out ) # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - # FIXME: I believe we export ac_cv_exeext for Libtool --akim. - export ac_cv_exeext - break;; - * ) break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables" >&5 -echo "$as_me: error: C compiler cannot create executables" >&2;} - { (exit 77); exit 77; }; } -fi - -ac_exeext=$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6 - -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - -rm -f a.out a.exe conftest$ac_cv_exeext -ac_clean_files=$ac_clean_files_save -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6 - -echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do - case $ac_file in - *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - export ac_cv_exeext - break;; - * ) break;; - esac -done -else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6 - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6 -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_compiler_gnu=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -CFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_prog_cc_g=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -# Some people use a C++ compiler to compile C. Since we use `exit', -# in C++ we need to declare it. In case someone uses the same compiler -# for both compiling C and C++ we need to have the C++ compiler decide -# the declaration of exit, since it's the most demanding environment. -cat >conftest.$ac_ext <<_ACEOF -#ifndef __cplusplus - choke me -#endif -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - for ac_declaration in \ - ''\ - '#include <stdlib.h>' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include <stdlib.h> -$ac_declaration -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -continue -fi -rm -f conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_declaration -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest.$ac_ext -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - RANLIB=$ac_ct_RANLIB -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -ac_aux_dir= -for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f $ac_dir/shtool; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 -echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} - { (exit 1); exit 1; }; } -fi -ac_config_guess="$SHELL $ac_aux_dir/config.guess" -ac_config_sub="$SHELL $ac_aux_dir/config.sub" -ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# ./install, which can be erroneously created by make from ./install.sh. -echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in - ./ | .// | /cC/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - done - done - ;; -esac -done - - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL=$ac_install_sh - fi -fi -echo "$as_me:$LINENO: result: $INSTALL" >&5 -echo "${ECHO_T}$INSTALL" >&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -# Extract the first word of "ar", so it can be a program name with args. -set dummy ar; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_AR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $AR in - [\\/]* | ?:[\\/]*) - ac_cv_path_AR="$AR" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_path_AR" && ac_cv_path_AR="no" - ;; -esac -fi -AR=$ac_cv_path_AR - -if test -n "$AR"; then - echo "$as_me:$LINENO: result: $AR" >&5 -echo "${ECHO_T}$AR" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -if [ $AR = "no" ] ; then - { { echo "$as_me:$LINENO: error: \"Could not find ar - needed to create a library\"" >&5 -echo "$as_me: error: \"Could not find ar - needed to create a library\"" >&2;} - { (exit 1); exit 1; }; }; -fi - - -echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 -echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 -if test "${ac_cv_c_bigendian+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # See if sys/param.h defines the BYTE_ORDER macro. -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include <sys/types.h> -#include <sys/param.h> - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN - bogus endian macros -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - # It does; now see whether it defined to BIG_ENDIAN or not. -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include <sys/types.h> -#include <sys/param.h> - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -#if BYTE_ORDER != BIG_ENDIAN - not big endian -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_bigendian=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_c_bigendian=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -# It does not; compile a test program. -if test "$cross_compiling" = yes; then - # try to guess the endianess by grep'ing values into an object file - ac_cv_c_bigendian=unknown - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; -short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; -void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } -short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; -short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; -void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - _ascii (); _ebcdic (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - if fgrep BIGenDianSyS conftest.$ac_objext >/dev/null ; then - ac_cv_c_bigendian=yes -fi -if fgrep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi -fi -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest.$ac_ext -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -int -main () -{ - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long l; - char c[sizeof (long)]; - } u; - u.l = 1; - exit (u.c[sizeof (long) - 1] == 1); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_bigendian=no -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) -ac_cv_c_bigendian=yes -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 -echo "${ECHO_T}$ac_cv_c_bigendian" >&6 -case $ac_cv_c_bigendian in - yes) - -cat >>confdefs.h <<\_ACEOF -#define WORDS_BIGENDIAN 1 -_ACEOF - ;; - no) - ;; - *) - { { echo "$as_me:$LINENO: error: unknown endianess -presetting ac_cv_c_bigendian=no (or yes) will help" >&5 -echo "$as_me: error: unknown endianess -presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} - { (exit 1); exit 1; }; } ;; -esac - - - - - - - - -echo "$as_me:$LINENO: checking for snd_pcm_open in -lasound" >&5 -echo $ECHO_N "checking for snd_pcm_open in -lasound... $ECHO_C" >&6 -if test "${ac_cv_lib_asound_snd_pcm_open+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lasound $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char snd_pcm_open (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -snd_pcm_open (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_asound_snd_pcm_open=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_asound_snd_pcm_open=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_asound_snd_pcm_open" >&5 -echo "${ECHO_T}$ac_cv_lib_asound_snd_pcm_open" >&6 -if test $ac_cv_lib_asound_snd_pcm_open = yes; then - have_alsa=yes -else - have_alsa=no -fi - - - - succeeded=no - - if test -z "$PKG_CONFIG"; then - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_PKG_CONFIG+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" - ;; -esac -fi -PKG_CONFIG=$ac_cv_path_PKG_CONFIG - -if test -n "$PKG_CONFIG"; then - echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 -echo "${ECHO_T}$PKG_CONFIG" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - fi - - if test "$PKG_CONFIG" = "no" ; then - echo "*** The pkg-config script could not be found. Make sure it is" - echo "*** in your path, or set the PKG_CONFIG environment variable" - echo "*** to the full path to pkg-config." - echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." - else - PKG_CONFIG_MIN_VERSION=0.9.0 - if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then - echo "$as_me:$LINENO: checking for jack" >&5 -echo $ECHO_N "checking for jack... $ECHO_C" >&6 - - if $PKG_CONFIG --exists "jack" ; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - succeeded=yes - - echo "$as_me:$LINENO: checking JACK_CFLAGS" >&5 -echo $ECHO_N "checking JACK_CFLAGS... $ECHO_C" >&6 - JACK_CFLAGS=`$PKG_CONFIG --cflags "jack"` - echo "$as_me:$LINENO: result: $JACK_CFLAGS" >&5 -echo "${ECHO_T}$JACK_CFLAGS" >&6 - - echo "$as_me:$LINENO: checking JACK_LIBS" >&5 -echo $ECHO_N "checking JACK_LIBS... $ECHO_C" >&6 - JACK_LIBS=`$PKG_CONFIG --libs "jack"` - echo "$as_me:$LINENO: result: $JACK_LIBS" >&5 -echo "${ECHO_T}$JACK_LIBS" >&6 - else - JACK_CFLAGS="" - JACK_LIBS="" - ## If we have a custom action on failure, don't print errors, but - ## do set a variable so people can do so. - JACK_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "jack"` - - fi - - - - else - echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." - echo "*** See http://www.freedesktop.org/software/pkgconfig" - fi - fi - - if test $succeeded = yes; then - have_jack=yes - else - have_jack=no - fi - - - -# Check whether --with-alsa or --without-alsa was given. -if test "${with_alsa+set}" = set; then - withval="$with_alsa" - with_alsa=$withval -else - with_alsa="yes" -fi; - - -# Check whether --with-jack or --without-jack was given. -if test "${with_jack+set}" = set; then - withval="$with_jack" - with_jack=$withval -else - with_jack="yes" -fi; - - -# Check whether --with-oss or --without-oss was given. -if test "${with_oss+set}" = set; then - withval="$with_oss" - with_oss=$withval -else - with_oss="yes" -fi; - -CFLAGS="-g -O2 -Wall" - -if [ $ac_cv_c_bigendian = "yes" ] ; then - CFLAGS="$CFLAGS -DPA_BIG_ENDIAN" -else - CFLAGS="$CFLAGS -DPA_LITTLE_ENDIAN" -fi - -case "${host_os}" in - darwin* ) - - OTHER_OBJS="pa_mac_core/pa_mac_core.o"; - LIBS="-framework AudioUnit -framework AudioToolbox -framework CoreAudio"; - PADLL="libportaudio.dylib"; - SHARED_FLAGS="-framework AudioUnit -framework AudioToolbox"; - SHARED_FLAGS="$SHARED_FLAGS -framework CoreAudio -dynamiclib"; - ;; - - mingw* ) - - OTHER_OBJS="pa_win_wmme/pa_win_wmme.o"; - LIBS="-lwinmm -lm"; - PADLL="portaudio.dll"; - SHARED_FLAGS="-shared -mthreads"; - DLL_LIBS="-lwinmm"; - ;; - - cygwin* ) - - OTHER_OBJS="pa_win_wmme/pa_win_wmme.o"; - LIBS="-lwinmm -lm"; - PADLL="portaudio.dll"; - SHARED_FLAGS="-shared -mthreads"; - DLL_LIBS="-lwinmm"; - ;; - - *) - - LIBS="$LIBS -L/usr/local/lib -L/usr/local/lib/pth/" - -echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5 -echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6 -if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char pthread_create (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -pthread_create (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_pthread_pthread_create=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_pthread_pthread_create=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5 -echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6 -if test $ac_cv_lib_pthread_pthread_create = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBPTHREAD 1 -_ACEOF - - LIBS="-lpthread $LIBS" - -else - { { echo "$as_me:$LINENO: error: libpthread not found!" >&5 -echo "$as_me: error: libpthread not found!" >&2;} - { (exit 1); exit 1; }; } -fi - - - if [ $have_alsa = "yes" ] && [ $with_alsa != "no" ] ; then - LIBS="$LIBS -lasound" - OTHER_OBJS="$OTHER_OBJS pa_linux_alsa/pa_linux_alsa.o" - OTHER_OBJS="$OTHER_OBJS pa_linux_alsa/callback_thread.o" - OTHER_OBJS="$OTHER_OBJS pa_linux_alsa/blocking_calls.o" - cat >>confdefs.h <<\_ACEOF -#define PA_USE_ALSA 1 -_ACEOF - - fi - - if [ $have_jack = "yes" ] && [ $with_jack != "no" ] ; then - LIBS="$LIBS $JACK_LIBS" - CFLAGS="$CFLAGS $JACK_CFLAGS" - OTHER_OBJS="$OTHER_OBJS pa_jack/pa_jack.o" - cat >>confdefs.h <<\_ACEOF -#define PA_USE_JACK 1 -_ACEOF - - fi - - if [ $with_oss != "no" ] ; then - OTHER_OBJS="$OTHER_OBJS pa_unix_oss/pa_unix_oss.o" - cat >>confdefs.h <<\_ACEOF -#define PA_USE_OSS 1 -_ACEOF - - fi - LIBS="$LIBS -lm -lpthread"; - PADLL="libportaudio.so"; - SHARED_FLAGS="-shared"; - - OTHER_OBJS="$OTHER_OBJS pa_unix/pa_unix_hostapis.o pa_unix/pa_unix_util.o" -esac - -ac_config_files="$ac_config_files Makefile" -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overriden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -{ - (set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} | - sed ' - t clear - : clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - : end' >>confcache -if cmp -s $cache_file confcache; then :; else - if test -w $cache_file; then - test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" - cat confcache >$cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/; -s/:*\${srcdir}:*/:/; -s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; -s/:*$//; -s/^[^=]*=[ ]*$//; -}' -fi - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then we branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -cat >confdef2opt.sed <<\_ACEOF -t clear -: clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g -t quote -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g -t quote -d -: quote -s,[ `~#$^&*(){}\\|;'"<>?],\\&,g -s,\[,\\&,g -s,\],\\&,g -s,\$,$$,g -p -_ACEOF -# We use echo to avoid assuming a particular line-breaking character. -# The extra dot is to prevent the shell from consuming trailing -# line-breaks from the sub-command output. A line-break within -# single-quotes doesn't work because, if this script is created in a -# platform that uses two characters for line-breaks (e.g., DOS), tr -# would break. -ac_LF_and_DOT=`echo; echo .` -DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` -rm -f confdef2opt.sed - - - -: ${CONFIG_STATUS=./config.status} -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi - -# NLS nuisances. -# Support unset when possible. -if (FOO=FOO; unset FOO) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - -(set +x; test -n "`(LANG=C; export LANG) 2>&1`") && - { $as_unset LANG || test "${LANG+set}" != set; } || - { LANG=C; export LANG; } -(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") && - { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } || - { LC_ALL=C; export LC_ALL; } -(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") && - { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } || - { LC_TIME=C; export LC_TIME; } -(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") && - { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } || - { LC_CTYPE=C; export LC_CTYPE; } -(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") && - { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } || - { LANGUAGE=C; export LANGUAGE; } -(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") && - { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } || - { LC_COLLATE=C; export LC_COLLATE; } -(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") && - { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } || - { LC_NUMERIC=C; export LC_NUMERIC; } -(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") && - { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } || - { LC_MESSAGES=C; export LC_MESSAGES; } - - -# Name of the executable. -as_me=`(basename "$0") 2>/dev/null || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conftest.sh - echo "exit 0" >>conftest.sh - chmod +x conftest.sh - if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conftest.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; } - -exec 6>&1 - -# Open the log real soon, to keep \$[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. Logging --version etc. is OK. -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 -cat >&5 <<_CSEOF - -This file was extended by $as_me, which was -generated by GNU Autoconf 2.53. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -_CSEOF -echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -echo >&5 -_ACEOF - -# Files that config.status was made for. -if test -n "$ac_config_files"; then - echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_headers"; then - echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_links"; then - echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_commands"; then - echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS -fi - -cat >>$CONFIG_STATUS <<\_ACEOF - -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -h, --help print this help, then exit - -V, --version print version number, then exit - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - -Configuration files: -$config_files - -Report bugs to <bug-autoconf@gnu.org>." -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF -ac_cs_version="\\ -config.status -configured by $0, generated by GNU Autoconf 2.53, - with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" - -Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." -srcdir=$srcdir -INSTALL="$INSTALL" -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "x$1" : 'x\([^=]*\)='` - ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` - shift - set dummy "$ac_option" "$ac_optarg" ${1+"$@"} - shift - ;; - -*);; - *) # This is not an option, so the user has probably given explicit - # arguments. - ac_need_defaults=false;; - esac - - case $1 in - # Handling of the options. -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion" - exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;; -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - --version | --vers* | -V ) - echo "$ac_cs_version"; exit 0 ;; - --he | --h) - # Conflict between --help and --header - { { echo "$as_me:$LINENO: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - shift - CONFIG_FILES="$CONFIG_FILES $1" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - shift - CONFIG_HEADERS="$CONFIG_HEADERS $1" - ac_need_defaults=false;; - - # This is an error. - -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" ;; - - esac - shift -done - -_ACEOF - - - - - -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_config_target in $ac_config_targets -do - case "$ac_config_target" in - # Handling of arguments. - "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files -fi - -# Create a temporary directory, and hook for its removal unless debugging. -$debug || -{ - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} - -# Create a (secure) tmp directory for tmp files. -: ${TMPDIR=/tmp} -{ - tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=$TMPDIR/cs$$-$RANDOM - (umask 077 && mkdir $tmp) -} || -{ - echo "$me: cannot create a temporary directory in $TMPDIR" >&2 - { (exit 1); exit 1; } -} - -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF - -# -# CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "\$CONFIG_FILES"; then - # Protect against being on the right side of a sed subst in config.status. - sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; - s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF -s,@SHELL@,$SHELL,;t t -s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t -s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t -s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t -s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t -s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t -s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t -s,@exec_prefix@,$exec_prefix,;t t -s,@prefix@,$prefix,;t t -s,@program_transform_name@,$program_transform_name,;t t -s,@bindir@,$bindir,;t t -s,@sbindir@,$sbindir,;t t -s,@libexecdir@,$libexecdir,;t t -s,@datadir@,$datadir,;t t -s,@sysconfdir@,$sysconfdir,;t t -s,@sharedstatedir@,$sharedstatedir,;t t -s,@localstatedir@,$localstatedir,;t t -s,@libdir@,$libdir,;t t -s,@includedir@,$includedir,;t t -s,@oldincludedir@,$oldincludedir,;t t -s,@infodir@,$infodir,;t t -s,@mandir@,$mandir,;t t -s,@build_alias@,$build_alias,;t t -s,@host_alias@,$host_alias,;t t -s,@target_alias@,$target_alias,;t t -s,@DEFS@,$DEFS,;t t -s,@ECHO_C@,$ECHO_C,;t t -s,@ECHO_N@,$ECHO_N,;t t -s,@ECHO_T@,$ECHO_T,;t t -s,@LIBS@,$LIBS,;t t -s,@CC@,$CC,;t t -s,@CFLAGS@,$CFLAGS,;t t -s,@LDFLAGS@,$LDFLAGS,;t t -s,@CPPFLAGS@,$CPPFLAGS,;t t -s,@ac_ct_CC@,$ac_ct_CC,;t t -s,@EXEEXT@,$EXEEXT,;t t -s,@OBJEXT@,$OBJEXT,;t t -s,@RANLIB@,$RANLIB,;t t -s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t -s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t -s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t -s,@INSTALL_DATA@,$INSTALL_DATA,;t t -s,@AR@,$AR,;t t -s,@OTHER_OBJS@,$OTHER_OBJS,;t t -s,@PADLL@,$PADLL,;t t -s,@SHARED_FLAGS@,$SHARED_FLAGS,;t t -s,@DLL_LIBS@,$DLL_LIBS,;t t -s,@PKG_CONFIG@,$PKG_CONFIG,;t t -s,@JACK_CFLAGS@,$JACK_CFLAGS,;t t -s,@JACK_LIBS@,$JACK_LIBS,;t t -CEOF - -_ACEOF - - cat >>$CONFIG_STATUS <<\_ACEOF - # Split the substitutions into bite-sized pieces for seds with - # small command number limits, like on Digital OSF/1 and HP-UX. - ac_max_sed_lines=48 - ac_sed_frag=1 # Number of current file. - ac_beg=1 # First line for current file. - ac_end=$ac_max_sed_lines # Line after last line for current file. - ac_more_lines=: - ac_sed_cmds= - while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - else - sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - fi - if test ! -s $tmp/subs.frag; then - ac_more_lines=false - else - # The purpose of the label and of the branching condition is to - # speed up the sed processing (if there are no `@' at all, there - # is no need to browse any of the substitutions). - # These are the two extra sed commands mentioned above. - (echo ':t - /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" - else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" - fi - ac_sed_frag=`expr $ac_sed_frag + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_lines` - fi - done - if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat - fi -fi # test -n "$CONFIG_FILES" - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; - esac - - # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. - ac_dir=`(dirname "$ac_file") 2>/dev/null || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { case "$ac_dir" in - [\\/]* | ?:[\\/]* ) as_incr_dir=;; - *) as_incr_dir=.;; -esac -as_dummy="$ac_dir" -for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do - case $as_mkdir_dir in - # Skip DOS drivespec - ?:) as_incr_dir=$as_mkdir_dir ;; - *) - as_incr_dir=$as_incr_dir/$as_mkdir_dir - test -d "$as_incr_dir" || - mkdir "$as_incr_dir" || - { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; } - ;; - esac -done; } - - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac -# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -# absolute. -ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd` -ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` - - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_builddir$INSTALL ;; - esac - - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - configure_input= - else - configure_input="$ac_file. " - fi - configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo $f;; - *) # Relative - if test -f "$f"; then - # Build tree - echo $f - elif test -f "$srcdir/$f"; then - # Source tree - echo $srcdir/$f - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@configure_input@,$configure_input,;t t -s,@srcdir@,$ac_srcdir,;t t -s,@abs_srcdir@,$ac_abs_srcdir,;t t -s,@top_srcdir@,$ac_top_srcdir,;t t -s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t -s,@builddir@,$ac_builddir,;t t -s,@abs_builddir@,$ac_abs_builddir,;t t -s,@top_builddir@,$ac_top_builddir,;t t -s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -s,@INSTALL@,$ac_INSTALL,;t t -" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out - rm -f $tmp/stdin - if test x"$ac_file" != x-; then - mv $tmp/out $ac_file - else - cat $tmp/out - rm -f $tmp/out - fi - -done -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - exec 5>/dev/null - $SHELL $CONFIG_STATUS || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } -fi - diff --git a/pd/portaudio/configure.in b/pd/portaudio/configure.in deleted file mode 100644 index 238d8fd0..00000000 --- a/pd/portaudio/configure.in +++ /dev/null @@ -1,124 +0,0 @@ -dnl -dnl portaudio V19 configure.in script -dnl -dnl Dominic Mazzoni -dnl - -dnl Require autoconf >= 2.13 -AC_PREREQ(2.13) - -dnl Init autoconf and make sure configure is being called -dnl from the right directory -AC_INIT([pa_common/portaudio.h]) - -dnl Checks for programs. -AC_PROG_CC -AC_PROG_RANLIB -AC_PROG_INSTALL -AC_PATH_PROG(AR, ar, no) -if [[ $AR = "no" ]] ; then - AC_MSG_ERROR("Could not find ar - needed to create a library"); -fi - -dnl This must be one of the first tests we do or it will fail... -AC_C_BIGENDIAN - -dnl extra variables -AC_SUBST(OTHER_OBJS) -AC_SUBST(PADLL) -AC_SUBST(SHARED_FLAGS) -AC_SUBST(DLL_LIBS) - -dnl checks for various host APIs and arguments to configure that -dnl turn them on or off - -AC_CHECK_LIB(asound, snd_pcm_open, have_alsa=yes, have_alsa=no) - -PKG_CHECK_MODULES(JACK, jack, have_jack=yes, have_jack=no) - -AC_ARG_WITH(alsa, - [ --with-alsa (default=auto)], - with_alsa=$withval, with_alsa="yes") - -AC_ARG_WITH(jack, - [ --with-jack (default=auto)], - with_jack=$withval, with_jack="yes") - -AC_ARG_WITH(oss, - [ --with-oss (default=yes)], - with_oss=$withval, with_oss="yes") - -CFLAGS="-g -O2 -Wall" - -if [[ $ac_cv_c_bigendian = "yes" ]] ; then - CFLAGS="$CFLAGS -DPA_BIG_ENDIAN" -else - CFLAGS="$CFLAGS -DPA_LITTLE_ENDIAN" -fi - -case "${host_os}" in - darwin* ) - dnl Mac OS X configuration - - OTHER_OBJS="pa_mac_core/pa_mac_core.o"; - LIBS="-framework AudioUnit -framework AudioToolbox -framework CoreAudio"; - PADLL="libportaudio.dylib"; - SHARED_FLAGS="-framework AudioUnit -framework AudioToolbox"; - SHARED_FLAGS="$SHARED_FLAGS -framework CoreAudio -dynamiclib"; - ;; - - mingw* ) - dnl MingW configuration - - OTHER_OBJS="pa_win_wmme/pa_win_wmme.o"; - LIBS="-lwinmm -lm"; - PADLL="portaudio.dll"; - SHARED_FLAGS="-shared -mthreads"; - DLL_LIBS="-lwinmm"; - ;; - - cygwin* ) - dnl Cygwin configuration - - OTHER_OBJS="pa_win_wmme/pa_win_wmme.o"; - LIBS="-lwinmm -lm"; - PADLL="portaudio.dll"; - SHARED_FLAGS="-shared -mthreads"; - DLL_LIBS="-lwinmm"; - ;; - - *) - dnl Unix OSS configuration - - LIBS="$LIBS -L/usr/local/lib -L/usr/local/lib/pth/" - AC_CHECK_LIB(pthread, pthread_create, - , - AC_MSG_ERROR([libpthread not found!])) - - if [[ $have_alsa = "yes" ] && [ $with_alsa != "no" ]] ; then - LIBS="$LIBS -lasound" - OTHER_OBJS="$OTHER_OBJS pa_linux_alsa/pa_linux_alsa.o" - OTHER_OBJS="$OTHER_OBJS pa_linux_alsa/callback_thread.o" - OTHER_OBJS="$OTHER_OBJS pa_linux_alsa/blocking_calls.o" - AC_DEFINE(PA_USE_ALSA) - fi - - if [[ $have_jack = "yes" ] && [ $with_jack != "no" ]] ; then - LIBS="$LIBS $JACK_LIBS" - CFLAGS="$CFLAGS $JACK_CFLAGS" - OTHER_OBJS="$OTHER_OBJS pa_jack/pa_jack.o" - AC_DEFINE(PA_USE_JACK) - fi - - if [[ $with_oss != "no" ]] ; then - OTHER_OBJS="$OTHER_OBJS pa_unix_oss/pa_unix_oss.o" - AC_DEFINE(PA_USE_OSS) - fi - LIBS="$LIBS -lm -lpthread"; - PADLL="libportaudio.so"; - SHARED_FLAGS="-shared"; - - OTHER_OBJS="$OTHER_OBJS pa_unix/pa_unix_hostapis.o pa_unix/pa_unix_util.o" -esac - -AC_OUTPUT([Makefile]) diff --git a/pd/portaudio/docs/index.html b/pd/portaudio/docs/index.html deleted file mode 100644 index 7d9b248d..00000000 --- a/pd/portaudio/docs/index.html +++ /dev/null @@ -1,60 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="PortAudio Docs, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Docs</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Documentation</h1></center> -</td> -</tr> -</table></center> - -<p>Copyright 2000 Phil Burk and Ross Bencina -<br> -<h3> -<a href="portaudio_h.txt">API Reference</a></h3> - -<blockquote>The Application Programmer Interface is documented in "portaudio.h".</blockquote> - -<h3> -<a href="pa_tutorial.html">Tutorial</a></h3> - -<blockquote>Describes how to write audio programs using the PortAudio API.</blockquote> - -<h3> -<a href="pa_impl_guide.html">Implementation Guide</a></h3> - -<blockquote>Describes how to write an implementation of PortAudio for a -new computer platform.</blockquote> - -<h3> -<a href="portaudio_icmc2001.pdf">Paper Presented at ICMC2001</a> (PDF)</h3> - -<blockquote>Describes the PortAudio API and discusses implementation issues. -Written July 2001.</blockquote> - -<h3> -<a href="latency.html">Improving Latency</a></h3> - -<blockquote>How to tune your computer to achieve the lowest possible audio -delay.</blockquote> - -<h3> -<a href="proposals.html">Proposed Changes</a></h3> - -<blockquote>Describes API changes being considered by the developer community. -Feedback welcome.</blockquote> -<a href="http://www.portaudio.com/">Return to PortAudio Home Page</a> -</body> -</html> diff --git a/pd/portaudio/docs/latency.html b/pd/portaudio/docs/latency.html deleted file mode 100644 index 87f1d122..00000000 --- a/pd/portaudio/docs/latency.html +++ /dev/null @@ -1,192 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Internal docs. How a stream is started or stopped."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Implementation - Start/Stop</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -<a href="http://www.portaudio.com">PortAudio</a> Latency</h1></center> -</td> -</tr> -</table></center> - -<p>This page discusses the issues of audio latency for <a href="http://www.portaudio.com">PortAudio</a> -. It offers suggestions on how to lower latency to improve the responsiveness -of applications. -<blockquote><b><a href="#what">What is Latency?</a></b> -<br><b><a href="#portaudio">PortAudio and Latency</a></b> -<br><b><a href="#macintosh">Macintosh</a></b> -<br><b><a href="#unix">Unix</a></b> -<br><b><a href="#windows">WIndows</a></b></blockquote> -By Phil Burk, Copyright 2002 Phil Burk and Ross Bencina -<h2> -<a NAME="what"></a>What is Latency?</h2> -Latency is basically longest time that you have to wait before you obtain -a desired result. For digital audio output it is the time between making -a sound in software and finally hearing it. -<p>Consider the example of pressing a key on the ASCII keyboard to play -a note. There are several stages in this process which each contribute -their own latency. First the operating system must respond to the keypress. -Then the audio signal generated must work its way through the PortAudio -buffers. Then it must work its way through the audio card hardware. Then -it must go through the audio amplifier which is very quick and then travel -through the air. Sound travels at abous one foot per millisecond through -air so placing speakers across the room can add 5-20 msec of delay. -<p>The reverse process occurs when recording or responding to audio input. -If you are processing audio, for example if you implement a software guitar -fuzz box, then you have both the audio input and audio output latencies -added together. -<p>The audio buffers are used to prevent glitches in the audio stream. -The user software writes audio into the output buffers. That audio is read -by the low level audio driver or by DMA and sent to the DAC. If the computer -gets busy doing something like reading the disk or redrawing the screen, -then it may not have time to fill the audio buffer. The audio hardware -then runs out of audio data, which causes a glitch. By using a large enough -buffer we can ensure that there is always enough audio data for the audio -hardware to play. But if the buffer is too large then the latency is high -and the system feels sluggish. If you play notes on the keyboard then the -"instrument" will feel unresponsive. So you want the buffers to be as small -as possible without glitching. -<h2> -<a NAME="portaudio"></a>PortAudio and Latency</h2> -The only delay that PortAudio can control is the total length of its buffers. -The Pa_OpenStream() call takes two parameters: numBuffers and framesPerBuffer. -The latency is also affected by the sample rate which we will call framesPerSecond. -A frame is a set of samples that occur simultaneously. For a stereo stream, -a frame is two samples. -<p>The latency in milliseconds due to this buffering is: -<blockquote><tt>latency_msec = 1000 * numBuffers * framesPerBuffer / framesPerSecond</tt></blockquote> -This is not the total latency, as we have seen, but it is the part we can -control. -<p>If you call Pa_OpenStream() with numBuffers equal to zero, then PortAudio -will select a conservative number that will prevent audio glitches. If -you still get glitches, then you can pass a larger value for numBuffers -until the glitching stops. if you try to pass a numBuffers value that is -too small, then PortAudio will use its own idea of the minimum value. -<p>PortAudio decides on the minimum number of buffers in a conservative -way based on the frameRate, operating system and other variables. You can -query the value that PortAudio will use by calling: -<blockquote><tt>int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate -);</tt></blockquote> -On some systems you can override the PortAudio minimum if you know your -system can handle a lower value. You do this by setting an environment -variable called PA_MIN_LATENCY_MSEC which is read by PortAudio when it -starts up. This is supported on the PortAudio implementations for Windows -MME, Windows DirectSound, and Unix OSS. -<h2> -<a NAME="macintosh"></a>Macintosh</h2> -The best thing you can do to improve latency on Mac OS 8 and 9 is to turn -off Virtual Memory. PortAudio V18 will detect that Virtual Memory is turned -off and use a very low latency. -<p>For Mac OS X the latency is very low because Apple Core Audio is so -well written. You can set the PA_MIN_LATENCY_MSEC variable using: -<blockquote><tt>setenv PA_MIN_LATENCY_MSEC 4</tt></blockquote> - -<h2> -<a NAME="unix"></a>Unix</h2> -PortAudio under Unix currently uses a backgroud thread that reads and writes -to OSS. This gives you decent but not great latency. But if you raise the -priority of the background thread to a very priority then you can get under -10 milliseconds latency. In order to raise your priority you must run the -PortAudio program as root! You must also set PA_MIN_LATENCY_MSEC using -the appropriate command for your shell. -<h2> -<a NAME="windows"></a>Windows</h2> -Latency under Windows is a complex issue because of all the alternative -operating system versions and device drivers. I have seen latency range -from 8 milliseconds to 400 milliseconds. The worst case is when using Windows -NT. Windows 98 is a little better, and Windows XP can be quite good if -properly tuned. -<p>The underlying audio API also makes a lot of difference. If the audio -device has its own DirectSound driver then DirectSound can often provide -better latency than WMME. But if a real DirectSound driver is not available -for your device then it is emulated using WMME and the latency can be very -high. That's where I saw the 400 millisecond latency. The ASIO implementation -is generally very good and will give the lowest latency if available. -<p>You can set the PA_MIN_LATENCY_MSEC variable to 50, for example, by -entering in MS-DOS: -<blockquote><tt>set PA_MIN_LATENCY_MSEC=50</tt></blockquote> -If you enter this in a DOS window then you must run the PortAudio program -from that same window for the variable to have an effect. You can add that -line to your C:\AUTOEXEC.BAT file and reboot if you want it to affect any -PortAudio based program. -<p>For Windows XP, you can set environment variables as follows: -<ol> -<li> -Select "Control Panel" from the "Start Menu".</li> - -<li> -Launch the "System" Control Panel</li> - -<li> -Click on the "Advanced" tab.</li> - -<li> -Click on the "Environment Variables" button.</li> - -<li> -Click "New" button under User Variables.</li> - -<li> -Enter PA_MIN_LATENCY_MSEC for the name and some optimistic number for the -value.</li> - -<li> -Click OK, OK, OK.</li> -</ol> - -<h3> -Improving Latency on Windows</h3> -There are several steps you can take to improve latency under windows. -<ol> -<li> -Avoid reading or writng to disk when doing audio.</li> - -<li> -Turn off all automated background tasks such as email clients, virus scanners, -backup programs, FTP servers, web servers, etc. when doing audio.</li> - -<li> -Disconnect from the network to prevent network traffic from interrupting -your CPU.</li> -</ol> -<b>Important: </b>Windows XP users can also tune the OS to favor background -tasks, such as audio, over foreground tasks, such as word processing. I -lowered my latency from 40 to 10 milliseconds using this simple technique. -<ol> -<li> -Select "Control Panel" from the "Start Menu".</li> - -<li> -Launch the "System" Control Panel</li> - -<li> -Click on the "Advanced" tab.</li> - -<li> -Click on the "Settings" button in the Performance area.</li> - -<li> -Click on the "Advanced" tab.</li> - -<li> -Select "Background services" in the Processor Scheduling area.</li> - -<li> -Click OK, OK.</li> -</ol> -Please let us know if you have others sugestions for lowering latency. -<br> -<br> -</body> -</html> diff --git a/pd/portaudio/docs/pa_impl_guide.html b/pd/portaudio/docs/pa_impl_guide.html deleted file mode 100644 index 50abc304..00000000 --- a/pd/portaudio/docs/pa_impl_guide.html +++ /dev/null @@ -1,197 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Internal docs. How a stream is started or stopped."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Implementation - Start/Stop</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -<a href="http://www.portaudio.com">PortAudio</a> Implementation Guide</h1></center> -</td> -</tr> -</table></center> - -<p>This document describes how to implement the PortAudio API on a new -computer platform. Implementing PortAudio on a new platform, makes it possible -to port many existing audio applications to that platform. -<p>By Phil Burk -<br>Copyright 2000 Phil Burk and Ross Bencina -<p>Note that the license says: <b>"Any person wishing to distribute modifications -to the Software is requested to send the modifications to the original -developer so that they can be incorporated into the canonical version."</b>. -So when you have finished a new implementation, please send it back to -us at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>" -so that we can make it available for other users. Thank you! -<h2> -Download the Latest PortAudio Implementation</h2> -Always start with the latest implementation available at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>". -Look for the nightly snapshot under the CVS section. -<h2> -Select an Existing Implementation as a Basis</h2> -The fastest way to get started is to take an existing implementation and -translate it for your new platform. Choose an implementation whose architecture -is as close as possible to your target. -<ul> -<li> -DirectSound Implementation - pa_win_ds - Uses a timer callback for the -background "thread". Polls a circular buffer and writes blocks of data -to keep it full.</li> - -<li> -Windows MME - pa_win_wmme - Spawns an actual Win32 thread. Writes blocks -of data to the HW device and waits for events that signal buffer completion.</li> - -<li> -Linux OSS - pa_linux - Spawns a real thread that writes to the "/dev/dsp" -stream using blocking I/O calls.</li> -</ul> -When you write a new implementation, you will be using some code that is -in common with all implementations. This code is in the folder "pa_common". -It provides various functions such as parameter checking, error code to -text conversion, sample format conversion, clipping and dithering, etc. -<p>The code that you write will go into a separate folder called "pa_{os}_{api}". -For example, code specific to the DirectSound interface for Windows goes -in "pa_win_ds". -<h2> -Read Docs and Code</h2> -Famialiarize yourself with the system by reading the documentation provided. -here is a suggested order: -<ol> -<li> -User Programming <a href="pa_tutorial.html">Tutorial</a></li> - -<li> -Header file "pa_common/portaudio.h" which defines API.</li> - -<li> -Header file "pa_common/pa_host.h" for host dependant code. This definces -the routine you will need to provide.</li> - -<li> -Shared code in "pa_common/pa_lib.c".</li> - -<li> -Docs on Implementation of <a href="pa_impl_startstop.html">Start/Stop</a> -code.</li> -</ol> - -<h2> -Implement Output to Default Device</h2> -Now we are ready to crank some code. For instant gratification, let's try -to play a sine wave. -<ol> -<li> -Link the test program "pa_tests/patest_sine.c" with the file "pa_lib.c" -and the implementation specific file you are creating.</li> - -<li> -For now, just stub out the device query code and the audio input code.</li> - -<li> -Modify PaHost_OpenStream() to open your default target device and get everything -setup.</li> - -<li> -Modify PaHost_StartOutput() to start playing audio.</li> - -<li> -Modify PaHost_StopOutput() to stop audio.</li> - -<li> -Modify PaHost_CloseStream() to clean up. Free all memory that you allocated -in PaHost_OpenStream().</li> - -<li> -Keep cranking until you can play a sine wave using "patest_sine.c".</li> - -<li> -Once that works, try "patest_pink.c", "patest_clip.c", "patest_sine8.c".</li> - -<li> -To test your Open and Close code, try "patest_many.c".</li> - -<li> -Now test to make sure that the three modes of stopping are properly supported -by running "patest_stop.c".</li> - -<li> -Test your implementation of time stamping with "patest_sync.c".</li> -</ol> - -<h2> -Implement Device Queries</h2> -Now that output is working, lets implement the code for querying what devices -are available to the user. Run "pa_tests/pa_devs.c". It should print all -of the devices available and their characteristics. -<h2> -Implement Input</h2> -Implement audio input and test it with: -<ol> -<li> -patest_record.c - record in half duplex, play back as recorded.</li> - -<li> -patest_wire.c - full duplex, copies input to output. Note that some HW -may not support full duplex.</li> - -<li> -patest_fuzz.c - plug in your guitar and get a feel for why latency is an -important issue in computer music.</li> - -<li> -paqa_devs.c - try to open every device and use it with every possible format</li> -</ol> - -<h2> -Debugging Tools</h2> -You generally cannot use printf() calls to debug real-time processes because -they disturb the timing. Also calling printf() from your background thread -or interrupt could crash the machine. So PA includes a tool for capturing -events and storing the information while it is running. It then prints -the events when Pa_Terminate() is called. -<ol> -<li> -To enable trace mode, change TRACE_REALTIME_EVENTS in "pa_common/pa_trace.h" -from a (0) to a (1).</li> - -<li> -Link with "pa_common/pa_trace.c".</li> - -<li> -Add trace messages to your code by calling:</li> - -<br><tt> void AddTraceMessage( char *msg, int data );</tt> -<br><tt>for example</tt> -<br><tt> AddTraceMessage("Pa_TimeSlice: past_NumCallbacks ", -past->past_NumCallbacks );</tt> -<li> -Run your program. You will get a dump of events at the end.</li> - -<li> -You can leave the trace messages in your code. They will turn to NOOPs -when you change TRACE_REALTIME_EVENTS back to (0).</li> -</ol> - -<h2> -Delivery</h2> -Please send your new code along with notes on the implementation back to -us at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>". -We will review the implementation and post it with your name. If you had -to make any modifications to the code in "pa_common" or "pa_tests" <b>please</b> -send us those modifications and your notes. We will try to merge your changes -so that the "pa_common" code works with <b>all</b> implementations. -<p>If you have suggestions for how to make future implementations easier, -please let us know. -<br>THANKS! -<br> -</body> -</html> diff --git a/pd/portaudio/docs/pa_impl_startstop.html b/pd/portaudio/docs/pa_impl_startstop.html deleted file mode 100644 index 0f2d0ce5..00000000 --- a/pd/portaudio/docs/pa_impl_startstop.html +++ /dev/null @@ -1,190 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.75 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Internal docs. How a stream is started or stopped."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Implementation - Start/Stop</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Implementation</h1></center> -</td> -</tr> -</table></center> - -<h2> -Starting and Stopping Streams</h2> -PortAudio is generally executed in two "threads". The foreground thread -is the application thread. The background "thread" may be implemented as -an actual thread, an interrupt handler, or a callback from a timer thread. -<p>There are three ways that PortAudio can stop a stream. In each case -we look at the sequence of events and the messages sent between the two -threads. The following variables are contained in the internalPortAudioStream. -<blockquote><tt>int past_IsActive; -/* Background is still playing. */</tt> -<br><tt>int past_StopSoon; /* Stop -when last buffer done. */</tt> -<br><tt>int past_StopNow; /* -Stop IMMEDIATELY. */</tt></blockquote> - -<h3> -Pa_AbortStream()</h3> -This function causes the background thread to terminate as soon as possible -and audio I/O to stop abruptly. -<br> -<table BORDER COLS=2 WIDTH="60%" > -<tr> -<td><b>Foreground Thread</b></td> - -<td><b>Background Thread</b></td> -</tr> - -<tr> -<td>sets <tt>StopNow</tt></td> - -<td></td> -</tr> - -<tr> -<td></td> - -<td>sees <tt>StopNow</tt>, </td> -</tr> - -<tr> -<td></td> - -<td>clears IsActive, stops thread</td> -</tr> - -<tr> -<td>waits for thread to exit</td> - -<td></td> -</tr> - -<tr> -<td>turns off audio I/O</td> - -<td></td> -</tr> -</table> - -<h3> -Pa_StopStream()</h3> -This function stops the user callback function from being called and then -waits for all audio data written to the output buffer to be played. In -a system with very low latency, you may not hear any difference between -<br> -<table BORDER COLS=2 WIDTH="60%" > -<tr> -<td><b>Foreground Thread</b></td> - -<td><b>Background Thread</b></td> -</tr> - -<tr> -<td>sets StopSoon</td> - -<td></td> -</tr> - -<tr> -<td></td> - -<td>stops calling user callback</td> -</tr> - -<tr> -<td></td> - -<td>continues until output buffer empty</td> -</tr> - -<tr> -<td></td> - -<td>clears IsActive, stops thread</td> -</tr> - -<tr> -<td>waits for thread to exit</td> - -<td></td> -</tr> - -<tr> -<td>turns off audio I/O</td> - -<td></td> -</tr> -</table> - -<h3> -User callback returns one.</h3> -If the user callback returns one then the user callback function will no -longer be called. Audio output will continue until all audio data written -to the output buffer has been played. Then the audio I/O is stopped, the -background thread terminates, and the stream becomes inactive. -<br> -<table BORDER COLS=2 WIDTH="60%" > -<tr> -<td><b>Foreground Thread</b></td> - -<td><b>Background Thread</b></td> -</tr> - -<tr> -<td></td> - -<td>callback returns 1</td> -</tr> - -<tr> -<td></td> - -<td>sets StopSoon</td> -</tr> - -<tr> -<td></td> - -<td>stops calling user callback</td> -</tr> - -<tr> -<td></td> - -<td>continues until output buffer empty</td> -</tr> - -<tr> -<td></td> - -<td>clears IsActive, stops thread</td> -</tr> - -<tr> -<td>waits for thread to exit</td> - -<td></td> -</tr> - -<tr> -<td>turns off audio I/O</td> - -<td></td> -</tr> -</table> - -<br> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_asio.html b/pd/portaudio/docs/pa_tut_asio.html deleted file mode 100644 index 1c3e5bfa..00000000 --- a/pd/portaudio/docs/pa_tut_asio.html +++ /dev/null @@ -1,55 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Compiling for ASIO (Windows or Macintosh)</h2> - -<blockquote>ASIO is a low latency audio API from Steinberg. To compile -an ASIO application, you must first <a href="http://www.steinberg.net/developers/ASIO2SDKAbout.phtml">download -the ASIO SDK</a> from Steinberg. You also need to obtain ASIO drivers for -your audio device. -<p>Note: I am using '/' as a file separator below. On Macintosh replace -'/' with ':'. On Windows, replace '/' with '\'. -<p> To use ASIO with the PortAudio library add the following source -files to your project: -<blockquote> -<pre>pa_asio/pa_asio.cpp</pre> -</blockquote> -and also these files from the ASIO SDK: -<blockquote> -<pre>common/asio.cpp -host/asiodrivers.cpp -host/asiolist.cpp</pre> -</blockquote> -and add these directories to the path for include files -<blockquote> -<pre>asiosdk2/host/pc (for Windows) -asiosdk2/common -asiosdk2/host</pre> -</blockquote> -You may try compiling the "pa_tests/patest_saw.c" file first because it -is the simplest.</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | -<a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_over.html">previous</a> | <a href="pa_tut_callback.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_callback.html b/pd/portaudio/docs/pa_tut_callback.html deleted file mode 100644 index f5ccaf0f..00000000 --- a/pd/portaudio/docs/pa_tut_callback.html +++ /dev/null @@ -1,91 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Writing a Callback Function</h2> - -<blockquote>To write a program using PortAudio, you must include the "portaudio.h" -include file. You may wish to read "<a href="portaudio_h.txt">portaudio.h</a>" -because it contains a complete description of the PortAudio functions and -constants. -<blockquote> -<pre>#include "portaudio.h"</pre> -</blockquote> -The next task is to write your custom callback function. It is a function -that is called by the PortAudio engine whenever it has captured audio data, -or when it needs more audio data for output. -<p>Your callback function is often called by an interrupt, or low level -process so you should not do any complex system activities like allocating -memory, or reading or writing files, or printf(). Just crunch numbers and -generate audio signals. What is safe or not safe will vary from platform -to platform. On the Macintosh, for example, you can only call "interrupt -safe" routines. Also do not call any PortAudio functions in the callback -except for Pa_StreamTime() and Pa_GetCPULoad(). -<p>Your callback function must return an int and accept the exact parameters -specified in this typedef: -<blockquote> -<pre>typedef int (PortAudioCallback)( - void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData );</pre> -</blockquote> -Here is an example callback function from the test file "patests/patest_saw.c". -It calculates a simple left and right sawtooth signal and writes it to -the output buffer. Notice that in this example, the signals are of <tt>float</tt> -data type. The signals must be between -1.0 and +1.0. You can also use -16 bit integers or other formats which are specified during setup. You -can pass a pointer to your data structure through PortAudio which will -appear as <tt>userData</tt>. -<blockquote> -<pre>int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - unsigned int i; -/* Cast data passed through stream to our structure type. */ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - - for( i=0; i<framesPerBuffer; i++ ) - { - /* Stereo channels are interleaved. */ - *out++ = data->left_phase; /* left */ - *out++ = data->right_phase; /* right */ - - /* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */ - data->left_phase += 0.01f; - /* When signal reaches top, drop back down. */ - if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f; - - /* higher pitch so we can distinguish left and right. */ - data->right_phase += 0.03f; - if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f; - } - return 0; -}</pre> -</blockquote> -</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | -<a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_over.html">previous</a> | <a href="pa_tut_init.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_devs.html b/pd/portaudio/docs/pa_tut_devs.html deleted file mode 100644 index 1756992c..00000000 --- a/pd/portaudio/docs/pa_tut_devs.html +++ /dev/null @@ -1,65 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.75 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Querying for Available Devices</h2> - -<blockquote>There are often several different audio devices available in -a computer with different capabilities. They can differ in the sample rates -supported, bit widths, etc. PortAudio provides a simple way to query for -the available devices, and then pass the selected device to Pa_OpenStream(). -For an example, see the file "pa_tests/pa_devs.c". -<p>To determine the number of devices: -<blockquote> -<pre>numDevices = Pa_CountDevices();</pre> -</blockquote> -You can then query each device in turn by calling Pa_GetDeviceInfo() with -an index. -<blockquote> -<pre>for( i=0; i<numDevices; i++ ) { - pdi = Pa_GetDeviceInfo( i );</pre> -</blockquote> -It will return a pointer to a <tt>PaDeviceInfo</tt> structure which is -defined as: -<blockquote> -<pre>typedef struct{ - 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 nativeSampleFormat; -}PaDeviceInfo;</pre> -</blockquote> -If the device supports a continuous range of sample rates, then numSampleRates -will equal -1, and the sampleRates array will have two values, the minimum -and maximum rate. -<p>The device information is allocated by Pa_Initialize() and freed by -Pa_Terminate() so you do not have to free() the structure returned by Pa_GetDeviceInfo().</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | -<a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_util.html">previous</a> | <a href="pa_tut_rw.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_explore.html b/pd/portaudio/docs/pa_tut_explore.html deleted file mode 100644 index 91c08a5b..00000000 --- a/pd/portaudio/docs/pa_tut_explore.html +++ /dev/null @@ -1,42 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Exploring PortAudio</h2> - -<blockquote>Now that you have a good idea of how PortAudio works, you can -try out the test programs. -<ul> -<li> -For an example of playing a sine wave, see "pa_tests/patest_sine.c".</li> - -<li> -For an example of recording and playing back a sound, see "pa_tests/patest_record.c".</li> -</ul> -I also encourage you to examine the source for the PortAudio libraries. -If you have suggestions on ways to improve them, please let us know. if -you want to implement PortAudio on a new platform, please let us know as -well so we can coordinate people's efforts.</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_rw.html">previous</a> | next</font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_init.html b/pd/portaudio/docs/pa_tut_init.html deleted file mode 100644 index 91bfa8d9..00000000 --- a/pd/portaudio/docs/pa_tut_init.html +++ /dev/null @@ -1,43 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Initializing PortAudio</h2> - -<blockquote>Before making any other calls to PortAudio, you must call <tt>Pa_Initialize</tt>(). -This will trigger a scan of available devices which can be queried later. -Like most PA functions, it will return a result of type <tt>paError</tt>. -If the result is not <tt>paNoError</tt>, then an error has occurred. -<blockquote> -<pre>err = Pa_Initialize(); -if( err != paNoError ) goto error;</pre> -</blockquote> -You can get a text message that explains the error message by passing it -to -<blockquote> -<pre>printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) );</pre> -</blockquote> -</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_callback.html">previous</a> | <a href="pa_tut_open.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_mac.html b/pd/portaudio/docs/pa_tut_mac.html deleted file mode 100644 index bf3dafd1..00000000 --- a/pd/portaudio/docs/pa_tut_mac.html +++ /dev/null @@ -1,41 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Compiling for Macintosh</h2> - -<blockquote>To compile a Macintosh application with the PortAudio library, -add the following source files to your project: -<blockquote> -<pre>pa_mac:pa_mac.c -pa_common:pa_lib.c -pa_common:portaudio.h -pa_common:pa_host.h</pre> -</blockquote> -Also add the Apple <b>SoundLib</b> to your project. -<p>You may try compiling the "pa_tests:patest_saw.c" file first because -it is the simplest.</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | -<a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_over.html">previous</a> | <a href="pa_tut_callback.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_mac_osx.html b/pd/portaudio/docs/pa_tut_mac_osx.html deleted file mode 100644 index 3af8c140..00000000 --- a/pd/portaudio/docs/pa_tut_mac_osx.html +++ /dev/null @@ -1,46 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Compiling for Macintosh OS X</h2> - -<blockquote>To compile a Macintosh OS X CoreAudio application with the -PortAudio library: -<p>Create a new ProjectBuilder project. You can use a "Tool" project to -run the PortAudio examples. -<p>Add the following source files to your Project: -<blockquote> -<pre>pa_mac_core/pa_mac_core.c -pa_common/pa_lib.c -pa_common/portaudio.h -pa_common/pa_host.h -pa_common/pa_convert.c</pre> -</blockquote> -Add the Apple CoreAudio.framework to your project by selecting "Add FrameWorks..." -from the Project menu. -<p>Compile and run the "pa_tests:patest_saw.c" file first because it is -the simplest.</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | -<a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_over.html">previous</a> | <a href="pa_tut_callback.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_open.html b/pd/portaudio/docs/pa_tut_open.html deleted file mode 100644 index 1621ef30..00000000 --- a/pd/portaudio/docs/pa_tut_open.html +++ /dev/null @@ -1,52 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Opening a Stream using Defaults</h2> - -<blockquote>The next step is to open a stream which is similar to opening -a file. You can specify whether you want audio input and/or output, how -many channels, the data format, sample rate, etc. There are two calls for -opening streams, <tt>Pa_OpenStream</tt>() and <tt>Pa_OpenDefaultStream</tt>(). -<p><tt>Pa_OpenStream()</tt> takes extra parameters which give you -more control. You can normally just use <tt>Pa_OpenDefaultStream</tt>() -which just calls <tt>Pa_OpenStream()</tt> <tt>with</tt> some reasonable -default values. Let's open a stream for stereo output, using floating -point data, at 44100 Hz. -<blockquote> -<pre>err = Pa_OpenDefaultStream( - &stream, /* passes back stream pointer */ - 0, /* no input channels */ - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - 44100, /* sample rate */ - 256, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - patestCallback, /* specify our custom callback */ - &data ); /* pass our data through to callback */</pre> -</blockquote> -If you want to use 16 bit integer data, pass <tt>paInt16</tt> instead of -<tt>paFloat32</tt>.</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_init.html">previous</a> | <a href="pa_tut_run.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_oss.html b/pd/portaudio/docs/pa_tut_oss.html deleted file mode 100644 index 1bb76f25..00000000 --- a/pd/portaudio/docs/pa_tut_oss.html +++ /dev/null @@ -1,46 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Compiling for Unix OSS</h2> - -<blockquote>[Skip this page if you are not using Unix and OSS] -<p>We currently support the <a href="http://www.opensound.com/">OSS</a> -audio drivers for Linux, Solaris, and FreeBSD. We hope to someday support -the newer ALSA drivers. -<ol> -<li> -cd to pa_unix_oss directory</li> - -<li> -Edit the Makefile and uncomment one of the tests. You may try compiling -the "patest_sine.c" file first because it is very simple.</li> - -<li> -gmake run</li> -</ol> -</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | -<a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_pc.html">previous</a> | <a href="pa_tut_callback.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_over.html b/pd/portaudio/docs/pa_tut_over.html deleted file mode 100644 index baa99205..00000000 --- a/pd/portaudio/docs/pa_tut_over.html +++ /dev/null @@ -1,92 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Overview of PortAudio</h2> - -<blockquote>PortAudio is a library that provides streaming audio input -and output. It is a cross-platform API (Application Programming Interface) -that works on Windows, Macintosh, Unix running OSS, SGI, BeOS, and perhaps -other platforms by the time you read this. This means that you can write -a simple 'C' program to process or generate an audio signal, and that program -can run on several different types of computer just by recompiling the -source code. -<p>Here are the steps to writing a PortAudio application: -<ol> -<li> -Write a callback function that will be called by PortAudio when audio processing -is needed.</li> - -<li> -Initialize the PA library and open a stream for audio I/O.</li> - -<li> -Start the stream. Your callback function will be now be called repeatedly -by PA in the background.</li> - -<li> -In your callback you can read audio data from the inputBuffer and/or write -data to the outputBuffer.</li> - -<li> -Stop the stream by returning 1 from your callback, or by calling a stop -function.</li> - -<li> -Close the stream and terminate the library.</li> -</ol> -</blockquote> - -<blockquote>There is also <a href="pa_tut_rw.html">another interface</a> -provided that allows you to generate audio in the foreground. You then -simply write data to the stream and the tool will not return until it is -ready to accept more data. This interface is simpler to use but is usually -not preferred for large applications because it requires that you launch -a thread to perform the synthesis. Launching a thread may be difficult -on non-multi-tasking systems such as the Macintosh prior to MacOS X. -<p>Let's continue by building a simple application that will play a sawtooth -wave. -<p>Please select the page for the specific implementation you would like -to use: -<ul> -<li> -<a href="pa_tut_pc.html">Windows (WMME or DirectSound)</a></li> - -<li> -<a href="pa_tut_mac.html">Macintosh SoundManager for OS 7,8,9</a></li> - -<li> -<a href="pa_tut_mac_osx.html">Macintosh CoreAudio for OS X</a></li> - -<li> -<a href="pa_tut_asio.html">ASIO on Windows or Macintosh</a></li> - -<li> -<a href="pa_tut_oss.html">Unix OSS</a></li> -</ul> -or continue with the <a href="pa_tut_callback.html">next page of the programming -tutorial</a>.</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | -<a href="pa_tutorial.html">contents</a> -| <a href="pa_tutorial.html">previous</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_pc.html b/pd/portaudio/docs/pa_tut_pc.html deleted file mode 100644 index 87e5f9a0..00000000 --- a/pd/portaudio/docs/pa_tut_pc.html +++ /dev/null @@ -1,78 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Compiling for Windows (WMME or DirectSound)</h2> - -<blockquote>To compile PortAudio for Windows, you can choose between two -options. One implementation uses the DirectSound API. The other uses the -Windows MultiMedia Extensions API (aka WMME or WAVE). -<p>Some advantages of using DirectSound are that DirectSound may have lower -latency than WMME, and supports effects processing plugins. But one disadvantage -is that DirectSound is not installed on all PCs, and is not well supported -under Windows NT. So WMME is the best choice for most projects. -<p>For either implementation add the following source files to your project: -<blockquote> -<pre><b>pa_common\pa_lib.c -pa_common\portaudio.h -pa_common\pa_host.h</b></pre> -</blockquote> -Link with the system library "<b>winmm.lib</b>". For Visual C++: -<ol> -<li> -select "Settings..." from the "Project" menu,</li> - -<li> -select the project name in the tree on the left,</li> - -<li> -choose "All Configurations" in the popup menu above the tree,</li> - -<li> -select the "Link" tab,</li> - -<li> -enter "winmm.lib", without quotes, as the first item in the "Object/library -modules:" field.</li> -</ol> -<b>WMME</b> - To use the WMME implementation, add the following source -files to your project: -<blockquote><b><tt>pa_win_wmme/pa_win_wmme.c</tt></b></blockquote> -<b>DirectSound</b> - If you want to use the DirectSound implementation -of PortAudio then you must have a recent copy of the free -<a href="http://www.microsoft.com/directx/download.asp">DirectX</a> -SDK for Developers from Microsoft installed on your computer. To compile -an application add the following source files to your project: -<blockquote> -<pre><b>pa_win_ds\dsound_wrapper.c -pa_win_ds\pa_dsound.c</b></pre> -</blockquote> -Link with the system library "<b>dsound.lib</b>" using the procedure described -above for "winmm.lib".</blockquote> - -<blockquote>You might try compiling the "pa_tests\patest_saw.c" file first -because it is the simplest.</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | -<a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_over.html">previous</a> | <a href="pa_tut_callback.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_run.html b/pd/portaudio/docs/pa_tut_run.html deleted file mode 100644 index 5c70d089..00000000 --- a/pd/portaudio/docs/pa_tut_run.html +++ /dev/null @@ -1,56 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Starting and Stopping a Stream</h2> - -<blockquote>The stream will not start running until you call Pa_StartStream(). -Then it will start calling your callback function to perform the audio -processing. -<blockquote> -<pre>err = Pa_StartStream( stream ); -if( err != paNoError ) goto error;</pre> -</blockquote> -At this point, audio is being generated. You can communicate to your callback -routine through the data structure you passed in on the open call, or through -global variables, or using other interprocess communication techniques. -Please be aware that your callback function may be called at interrupt -time when your foreground process is least expecting it. So avoid sharing -complex data structures that are easily corrupted like double linked lists. -<p>In many of the tests we simply sleep for a few seconds so we can hear -the sound. This is easy to do with Pa_Sleep() which will sleep for some -number of milliseconds. Do not rely on this function for accurate scheduling. -it is mostly for writing examples. -<blockquote> -<pre>/* Sleep for several seconds. */ -Pa_Sleep(NUM_SECONDS*1000);</pre> -</blockquote> -When you are through, you can stop the stream from the foreground. -<blockquote> -<pre>err = Pa_StopStream( stream ); -if( err != paNoError ) goto error;</pre> -</blockquote> -You can also stop the stream by returning 1 from your custom callback function.</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_open.html">previous</a> | <a href="pa_tut_term.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_rw.html b/pd/portaudio/docs/pa_tut_rw.html deleted file mode 100644 index 93c7b8bb..00000000 --- a/pd/portaudio/docs/pa_tut_rw.html +++ /dev/null @@ -1,79 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Blocking Read/Write Functions</h2> - -<blockquote>[Note: These functions are not part of the official PortAudio -API. They are simply built on top of PortAudio as an extra utility. Also -note that they are under evaluation and their definition may change.] -<p>There are two fundamentally different ways to design an audio API. One -is to use callback functions the way we have already shown. The callback -function operates under an interrupt or background thread This leaves the -foreground application free to do other things while the audio just runs -in the background. But this can sometimes be awkward. -<p>So we have provided an alternative technique that lets a program generate -audio in the foreground and then just write it to the audio stream as if -it was a file. If there is not enough room in the audio buffer for more -data, then the write function will just block until more room is available. -This can make it very easy to write an audio example. To use this tool, -you must add the files "pablio/pablio.c" and "pablio/ringbuffer.c" to your -project. You must also: -<blockquote> -<pre>#include "pablio.h"</pre> -</blockquote> -Here is a short excerpt of a program that opens a stream for input and -output. It then reads a block of samples from input, and writes them to -output, in a loop. The complete example can be found in "pablio/test_rw.c". -<blockquote> -<pre> #define SAMPLES_PER_FRAME (2) - #define FRAMES_PER_BLOCK (1024) - SAMPLE samples[SAMPLES_PER_FRAME * FRAMES_PER_BLOCK]; - PaError err; - PABLIO_Stream *aStream; - -/* Open simplified blocking I/O layer on top of PortAudio. */ - err = OpenAudioStream( &rwbl, SAMPLE_RATE, paFloat32, - (PABLIO_READ_WRITE | PABLIO_STEREO) ); - if( err != paNoError ) goto error; - -/* Process samples in the foreground. */ - for( i=0; i<(NUM_SECONDS * SAMPLE_RATE); i++ ) - { - /* Read one block of data into sample array from audio input. */ - ReadAudioStream( aStream, samples, FRAMES_PER_BLOCK ); - /* - ** At this point you could process the data in samples array, - ** and write the result back to the same samples array. - */ - /* Write that same frame of data to output. */ - WriteAudioStream( aStream, samples, FRAMES_PER_BLOCK ); - } - - CloseAudioStream( aStream );</pre> -</blockquote> -</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | -<a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_devs.html">previous</a> | <a href="pa_tut_explore.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_term.html b/pd/portaudio/docs/pa_tut_term.html deleted file mode 100644 index 1c72209f..00000000 --- a/pd/portaudio/docs/pa_tut_term.html +++ /dev/null @@ -1,47 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Terminating PortAudio</h2> - -<blockquote>You can start and stop a stream as many times as you like. -But when you are done using it, you should close it by calling:</blockquote> - -<blockquote> -<blockquote> -<pre>err = Pa_CloseStream( stream ); -if( err != paNoError ) goto error;</pre> -</blockquote> -Then when you are done using PortAudio, you should terminate the whole -system by calling: -<blockquote> -<pre>Pa_Terminate();</pre> -</blockquote> -That's basically it. You can now write an audio program in 'C' that will -run on multiple platforms, for example PCs and Macintosh. -<p>In the rest of the tutorial we will look at some additional utility -functions, and a different way of using PortAudio that does not require -the use of a callback function.</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a> -| <a href="pa_tut_run.html">previous</a> | <a href="pa_tut_util.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tut_util.html b/pd/portaudio/docs/pa_tut_util.html deleted file mode 100644 index f4b54750..00000000 --- a/pd/portaudio/docs/pa_tut_util.html +++ /dev/null @@ -1,55 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.75 [en]C-gatewaynet (Win98; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<h2> -Utility Functions</h2> - -<blockquote>Here are several more functions that are not critical, but -may be handy when using PortAudio. -<p>Pa_StreamActive() returns one when the stream in playing audio, zero -when not playing, or a negative error number if the stream is invalid. -The stream is active between calls to Pa_StartStream() and Pa_StopStream(), -but may also become inactive if the callback returns a non-zero value. -In the latter case, the stream is considered inactive after the last buffer -has finished playing. -<blockquote> -<pre>PaError Pa_StreamActive( PortAudioStream *stream );</pre> -</blockquote> -Pa_StreamTime() returns the number of samples that have been generated. -PaTimeStamp is a double precision number which is a convenient way to pass -big numbers around even though we only need integers. -<blockquote> -<pre>PaTimestamp Pa_StreamTime( PortAudioStream *stream );</pre> -</blockquote> -The "CPU Load" is a fraction of total CPU time consumed by the stream's -audio processing. A value of 0.5 would imply that PortAudio and the sound -generating callback was consuming roughly 50% of the available CPU time. -This function may be called from the callback function or the application. -<blockquote> -<pre>double Pa_GetCPULoad( PortAudioStream* stream );</pre> -</blockquote> -</blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | -<a href="pa_tutorial.html">contents</a> | <a href="pa_tut_term.html">previous</a> -| <a href="pa_tut_devs.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/pa_tutorial.html b/pd/portaudio/docs/pa_tutorial.html deleted file mode 100644 index 1371c44f..00000000 --- a/pd/portaudio/docs/pa_tutorial.html +++ /dev/null @@ -1,46 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Tutorial</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio Tutorial</h1></center> -</td> -</tr> -</table></center> - -<p>Copyright 2000 Phil Burk and Ross Bencina -<h2> -Table of Contents</h2> - -<blockquote><a href="pa_tut_over.html">Overview of PortAudio</a> -<br><a href="pa_tut_mac.html">Compiling for Macintosh OS 7,8,9</a> -<br><a href="pa_tut_mac_osx.html">Compiling for Macintosh OS X</a> -<br><a href="pa_tut_pc.html">Compiling for Windows (DirectSound and WMME)</a> -<br><a href="pa_tut_asio.html">Compiling for ASIO on Windows or Mac OS -8,9</a> -<br><a href="pa_tut_oss.html">Compiling for Unix OSS</a> -<br><a href="pa_tut_callback.html">Writing a Callback Function</a> -<br><a href="pa_tut_init.html">Initializing PortAudio</a> -<br><a href="pa_tut_open.html">Opening a Stream using Defaults</a> -<br><a href="pa_tut_run.html">Starting and Stopping a Stream</a> -<br><a href="pa_tut_term.html">Cleaning Up</a> -<br><a href="pa_tut_util.html">Utilities</a> -<br><a href="pa_tut_devs.html">Querying for Devices</a> -<br><a href="pa_tut_rw.html">Blocking Read/Write Functions</a> -<br><a href="pa_tut_explore.html">Exploring the PortAudio Package</a></blockquote> -<font size=+2><a href="http://www.portaudio.com/">home</a> | contents | -previous | <a href="pa_tut_over.html">next</a></font> -</body> -</html> diff --git a/pd/portaudio/docs/portaudio_h.txt b/pd/portaudio/docs/portaudio_h.txt deleted file mode 100644 index 6d60086f..00000000 --- a/pd/portaudio/docs/portaudio_h.txt +++ /dev/null @@ -1,425 +0,0 @@ -#ifndef PORT_AUDIO_H -#define PORT_AUDIO_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * PortAudio Portable Real-Time Audio Library - * PortAudio API Header File - * Latest version available at: http://www.audiomulch.com/portaudio/ - * - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -typedef int PaError; -typedef enum { - paNoError = 0, - - paHostError = -10000, - paInvalidChannelCount, - paInvalidSampleRate, - paInvalidDeviceId, - paInvalidFlag, - paSampleFormatNotSupported, - paBadIODeviceCombination, - paInsufficientMemory, - paBufferTooBig, - paBufferTooSmall, - paNullCallback, - paBadStreamPtr, - paTimedOut, - paInternalError -} PaErrorNum; - -/* - Pa_Initialize() is the library initialisation function - call this before - using the library. -*/ - -PaError Pa_Initialize( void ); - -/* - Pa_Terminate() is the library termination function - call this after - using the library. -*/ - -PaError Pa_Terminate( void ); - -/* - Return host specific error. - This can be called after receiving a paHostError. -*/ -long Pa_GetHostError( void ); - -/* - Translate the error number into a human readable message. -*/ -const char *Pa_GetErrorText( PaError errnum ); - -/* - Sample formats - - These are formats used to pass sound data between the callback and the - stream. Each device has a "native" format which may be used when optimum - efficiency or control over conversion is required. - - Formats marked "always available" are supported (emulated) by all devices. - - The floating point representation uses +1.0 and -1.0 as the respective - maximum and minimum. - -*/ - -typedef unsigned long PaSampleFormat; -#define paFloat32 ((PaSampleFormat) (1<<0)) /*always available*/ -#define paInt16 ((PaSampleFormat) (1<<1)) /*always available*/ -#define paInt32 ((PaSampleFormat) (1<<2)) /*always available*/ -#define paInt24 ((PaSampleFormat) (1<<3)) -#define paPackedInt24 ((PaSampleFormat) (1<<4)) -#define paInt8 ((PaSampleFormat) (1<<5)) -#define paUInt8 ((PaSampleFormat) (1<<6)) /* unsigned 8 bit, 128 is "ground" */ -#define paCustomFormat ((PaSampleFormat) (1<<16)) - -/* - Device enumeration mechanism. - - Device ids range from 0 to Pa_CountDevices()-1. - - Devices may support input, output or both. Device 0 is always the "default" - device and should support at least stereo in and out if that is available - on the taget platform _even_ if this involves kludging an input/output - device on platforms that usually separate input from output. Other platform - specific devices are specified by positive device ids. -*/ - -typedef int PaDeviceID; -#define paNoDevice -1 - -typedef struct{ - int structVersion; - const char *name; - int maxInputChannels; - int maxOutputChannels; -/* Number of discrete rates, or -1 if range supported. */ - int numSampleRates; -/* Array of supported sample rates, or {min,max} if range supported. */ - const double *sampleRates; - PaSampleFormat nativeSampleFormats; -} PaDeviceInfo; - - -int Pa_CountDevices(); -/* - Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID() - - Return the default device ID or paNoDevice if there is no devices. - The result can be passed to Pa_OpenStream(). - - On the PC, the user can specify a default device by - setting an environment variable. For example, to use device #1. - - set PA_RECOMMENDED_OUTPUT_DEVICE=1 - - The user should first determine the available device ID by using - the supplied application "pa_devs". -*/ -PaDeviceID Pa_GetDefaultInputDeviceID( void ); -PaDeviceID Pa_GetDefaultOutputDeviceID( void ); - -/* - PaTimestamp is used to represent a continuous sample clock with arbitrary - start time useful for syncronisation. The type is used in the outTime - argument to the callback function and the result of Pa_StreamTime() -*/ - -typedef double PaTimestamp; - -/* - Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure - referring to the device specified by id. - If id is out of range the function returns NULL. - - The returned structure is owned by the PortAudio implementation and must - not be manipulated or freed. The pointer is guaranteed to be valid until - between calls to Pa_Initialize() and Pa_Terminate(). -*/ - -const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID devID ); - -/* - PortAudioCallback is implemented by clients of the portable audio api. - - inputBuffer and outputBuffer are arrays of interleaved samples, - the format, packing and number of channels used by the buffers are - determined by parameters to Pa_OpenStream() (see below). - - framesPerBuffer is the number of sample frames to be processed by the callback. - - outTime is the time in samples when the buffer(s) processed by - this callback will begin being played at the audio output. - See also Pa_StreamTime() - - userData is the value of a user supplied pointer passed to Pa_OpenStream() - intended for storing synthesis data etc. - - return value: - The callback can return a nonzero value to stop the stream. This may be - useful in applications such as soundfile players where a specific duration - of output is required. However, it is not necessary to utilise this mechanism - as StopStream() will also terminate the stream. A callback returning a - nonzero value must fill the entire outputBuffer. - - NOTE: None of the other stream functions may be called from within the - callback function except for Pa_GetCPULoad(). - -*/ - -typedef int (PortAudioCallback)( - void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ); - - -/* - Stream flags - - These flags may be supplied (ored together) in the streamFlags argument to - the Pa_OpenStream() function. - - [ suggestions? ] -*/ - -#define paNoFlag (0) -#define paClipOff (1<<0) /* disable defult clipping of out of range samples */ -#define paDitherOff (1<<1) /* disable default dithering */ -#define paPlatformSpecificFlags (0x00010000) -typedef unsigned long PaStreamFlags; - -/* - A single PortAudioStream provides multiple channels of real-time - input and output audio streaming to a client application. - Pointers to PortAudioStream objects are passed between PortAudio functions. -*/ - -typedef void PortAudioStream; -#define PaStream PortAudioStream - -/* - Pa_OpenStream() opens a stream for either input, output or both. - - stream is the address of a PortAudioStream pointer which will receive - a pointer to the newly opened stream. - - inputDevice is the id of the device used for input (see PaDeviceID above.) - inputDevice may be paNoDevice to indicate that an input device is not required. - - numInputChannels is the number of channels of sound to be delivered to the - callback. It can range from 1 to the value of maxInputChannels in the - device input record for the device specified in the inputDevice parameter. - If inputDevice is paNoDevice numInputChannels is ignored. - - inputSampleFormat is the format of inputBuffer provided to the callback - function. inputSampleFormat may be any of the formats described by the - PaSampleFormat enumeration (see above). PortAudio guarantees support for - the sound devices native formats (nativeSampleFormats in the device info - record) and additionally 16 and 32 bit integer and 32 bit floating point - formats. Support for other formats is implementation defined. - - inputDriverInfo is a pointer to an optional driver specific data structure - containing additional information for device setup or stream processing. - inputDriverInfo is never required for correct operation. If not used - inputDriverInfo should be NULL. - - outputDevice is the id of the device used for output (see PaDeviceID above.) - outputDevice may be paNoDevice to indicate that an output device is not required. - - numOutputChannels is the number of channels of sound to be supplied by the - callback. See the definition of numInputChannels above for more details. - - outputSampleFormat is the sample format of the outputBuffer filled by the - callback function. See the definition of inputSampleFormat above for more - details. - - outputDriverInfo is a pointer to an optional driver specific data structure - containing additional information for device setup or stream processing. - outputDriverInfo is never required for correct operation. If not used - outputDriverInfo should be NULL. - - sampleRate is the desired sampleRate for input and output - - framesPerBuffer is the length in sample frames of all internal sample buffers - used for communication with platform specific audio routines. Wherever - possible this corresponds to the framesPerBuffer parameter passed to the - callback function. - - numberOfBuffers is the number of buffers used for multibuffered - communication with the platform specific audio routines. This parameter is - provided only as a guide - and does not imply that an implementation must - use multibuffered i/o when reliable double buffering is available (such as - SndPlayDoubleBuffer() on the Macintosh.) - - streamFlags may contain a combination of flags ORed together. - These flags modify the behavior of the - streaming process. Some flags may only be relevant to certain buffer formats. - - callback is a pointer to a client supplied function that is responsible - for processing and filling input and output buffers (see above for details.) - - userData is a client supplied pointer which is passed to the callback - function. It could for example, contain a pointer to instance data necessary - for processing the audio buffers. - - return value: - Apon success Pa_OpenStream() returns PaNoError and places a pointer to a - valid PortAudioStream in the stream argument. The stream is inactive (stopped). - If a call to Pa_OpenStream() fails a nonzero error code is returned (see - PAError above) and the value of stream is invalid. - -*/ - -PaError Pa_OpenStream( PortAudioStream** stream, - PaDeviceID inputDevice, - int numInputChannels, - PaSampleFormat inputSampleFormat, - void *inputDriverInfo, - PaDeviceID outputDevice, - int numOutputChannels, - PaSampleFormat outputSampleFormat, - void *outputDriverInfo, - double sampleRate, - unsigned long framesPerBuffer, - unsigned long numberOfBuffers, - PaStreamFlags streamFlags, - PortAudioCallback *callback, - void *userData ); - - -/* - Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that - opens the default input and/or ouput devices. Most parameters have - identical meaning to their Pa_OpenStream() counterparts, with the following - exceptions: - - If either numInputChannels or numOutputChannels is 0 the respective device - is not opened (same as passing paNoDevice in the device arguments to Pa_OpenStream() ) - - sampleFormat applies to both the input and output buffers. -*/ - -PaError Pa_OpenDefaultStream( PortAudioStream** stream, - int numInputChannels, - int numOutputChannels, - PaSampleFormat sampleFormat, - double sampleRate, - unsigned long framesPerBuffer, - unsigned long numberOfBuffers, - PortAudioCallback *callback, - void *userData ); - -/* - Pa_CloseStream() closes an audio stream, flushing any pending buffers. -*/ - -PaError Pa_CloseStream( PortAudioStream* ); - -/* - Pa_StartStream() and Pa_StopStream() begin and terminate audio processing. - Pa_StopStream() waits until all pending audio buffers have been played. - Pa_AbortStream() stops playing immediately without waiting for pending - buffers to complete. -*/ - -PaError Pa_StartStream( PortAudioStream *stream ); - -PaError Pa_StopStream( PortAudioStream *stream ); - -PaError Pa_AbortStream( PortAudioStream *stream ); - -/* - Pa_StreamActive() returns one when the stream is playing audio, - zero when not playing, or a negative error number if the - stream is invalid. - The stream is active between calls to Pa_StartStream() and Pa_StopStream(), - but may also become inactive if the callback returns a non-zero value. - In the latter case, the stream is considered inactive after the last - buffer has finished playing. -*/ - -PaError Pa_StreamActive( PortAudioStream *stream ); - -/* - Pa_StreamTime() returns the current output time for the stream in samples. - This time may be used as a time reference (for example syncronising audio to - MIDI). -*/ - -PaTimestamp Pa_StreamTime( PortAudioStream *stream ); - -/* - The "CPU Load" is a fraction of total CPU time consumed by the - stream's audio processing. - A value of 0.5 would imply that PortAudio and the sound generating - callback was consuming roughly 50% of the available CPU time. - This function may be called from the callback function or the application. -*/ -double Pa_GetCPULoad( PortAudioStream* stream ); - -/* - Use Pa_GetMinNumBuffers() to determine minimum number of buffers required for - the current host based on minimum latency. - On the PC, for the DirectSound implementation, latency can be optionally set - by user by setting an environment variable. - For example, to set latency to 200 msec, put: - - set PA_MIN_LATENCY_MSEC=200 - - in the AUTOEXEC.BAT file and reboot. - If the environment variable is not set, then the latency will be determined - based on the OS. Windows NT has higher latency than Win95. -*/ - -int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate ); - -/* - Sleep for at least 'msec' milliseconds. - You may sleep longer than the requested time so don't rely - on this for accurate musical timing. -*/ -void Pa_Sleep( long msec ); - -/* - Return size in bytes of a single sample in a given PaSampleFormat - or paSampleFormatNotSupported. -*/ -PaError Pa_GetSampleSize( PaSampleFormat format ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PORT_AUDIO_H */ diff --git a/pd/portaudio/docs/portaudio_icmc2001.pdf b/pd/portaudio/docs/portaudio_icmc2001.pdf Binary files differdeleted file mode 100644 index dd074b7d..00000000 --- a/pd/portaudio/docs/portaudio_icmc2001.pdf +++ /dev/null diff --git a/pd/portaudio/docs/proposals.html b/pd/portaudio/docs/proposals.html deleted file mode 100644 index 0f9b8cb6..00000000 --- a/pd/portaudio/docs/proposals.html +++ /dev/null @@ -1,36 +0,0 @@ -<HTML> -<HEAD> -<TITLE>Proposed Changes to PortAudio API</TITLE> -<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252"> -<META content="Phil Burk, Ross Bencina" name=Author> -<META content="Changes being discussed by the community of PortAudio deveopers." -name=Description> -<META -content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis," -name=KeyWords> -</HEAD> -<BODY LINK="#0000ff" VLINK="#800080"> -<CENTER> -<TABLE bgColor=#fada7a cols=1 width="100%"> - <TBODY> - <TR> - <TD> - <CENTER> - <H1>Proposed Changes to PortAudio API</H1> - </CENTER> -</TD></TR></TBODY></TABLE></CENTER> -<P><A href="http://www.portaudio.com/">PortAudio Home Page</A></P> - -<P>Updated: July 27, 2002 </P> -<H2>The Proposals Have Moved</H2> - -<p> -All PortAudio Enhancement Proposal documentation has moved. On the web site, it is now located at: -<A HREF="http://www.portaudio.com/docs/proposals">http://www.portaudio.com/docs/proposals</A> - -On the CVS server it is now located in a module named "pa_proposals". -</p> - - -</BODY> -</HTML> diff --git a/pd/portaudio/docs/releases.html b/pd/portaudio/docs/releases.html deleted file mode 100644 index aec80a1c..00000000 --- a/pd/portaudio/docs/releases.html +++ /dev/null @@ -1,339 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="PortAudio is a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Release Notes</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio - Release Notes</h1></center> -</td> -</tr> -</table></center> - -<p>Link to <a href="http://www.portaudio.com">PortAudio Home Page</a> -<h2> -<b>V18 - 5/6/02</b></h2> - -<blockquote>All source code and documentation now under <a href="http://www.portaudio.com/usingcvs.html">CVS</a>. -<p>Ran most of the code through <a href="http://astyle.sourceforge.net/">AStyle</a> -to cleanup ragged indentation caused by using different editors. Used this -command: -<br><tt> astyle --style=ansi -c -o --convert-tabs --indent-preprocessor -*.c</tt></blockquote> - -<blockquote>Added "pa_common/pa_convert.c" for Mac OS X. Start of new conversion -utilities. -<p><b>ASIO</b> -<ul> -<li> -New Pa_ASIO_Adaptor_Init function to init Callback adpatation variables,</li> - -<li> -Cleanup of Pa_ASIO_Callback_Input</li> - -<li> -Break apart device loading to debug random failure in Pa_ASIO_QueryDeviceInfo</li> - -<li> -Deallocate all resources in PaHost_Term for cases where Pa_CloseStream -is not called properly</li> - -<li> -New Pa_ASIO_loadDriver that calls CoInitialize on each thread on Windows. -Allows use by multiple threads.</li> - -<li> -Correct error code management in PaHost_Term, removed various compiler -warning</li> - -<li> -Add Mac includes for <Devices.h> and <Timer.h></li> - -<li> -Pa_ASIO_QueryDeviceInfo bug correction, memory allocation checking, better -error handling</li> -</ul> -<b>Mac OS X</b> -<ul> -<li> -Major cleanup and improvements.</li> - -<li> -Fixed device queries for numChannels and sampleRates,</li> - -<li> -Audio input works if using same CoreAudio device (some HW devices make -separate CoreAudio devices).</li> - -<li> -Added paInt16, paInt8, format using new "pa_common/pa_convert.c" file.</li> - -<li> -Return error if opened in mono mode cuz not supported.</li> - -<li> -Check for getenv("PA_MIN_LATEWNCY_MSEC") to set latency externally.</li> - -<li> -Use getrusage() instead of gettimeofday() for CPU Load calculation.</li> -</ul> -<b>Windows MME</b> -<ul> -<li> -Fixed bug that caused TIMEOUT in Pa_StopStream(). Added check for past_StopSoon() -in Pa_TimeSlice(). Thanks Julien Maillard.</li> - -<li> -Detect Win XP versus NT, use lower latency.</li> - -<li> -Fix DBUG typo;</li> - -<li> -removed init of CurrentCount which was not compiling on Borland</li> - -<li> -general cleanup, factored streamData alloc and cpu usage initialization</li> - -<li> -stopped counting WAVE_MAPPER when there were no audio cards plugged in</li> -</ul> -<b>Windows DirectSound</b> -<ul> -<li> -Detect Win XP and Win 2K properly when determining latency.</li> -</ul> -<b>Unix OSS</b> -<ul> -<li> -Use high real-time priority if app is running with root priveledges. Lowers -latency.</li> - -<li> -Added watch dog thread that prevents real-time thread from hogging CPU -and hanging the computer.</li> - -<li> -Check error return from read() and write().</li> - -<li> -Check CPU endianness instead of assuming Little Endian.</li> -</ul> -</blockquote> - -<h2> -<b>V17 - 10/15/01</b></h2> - -<blockquote><b>Unix OSS</b> -<ul> -<li> -Set num channels back to two after device query for ALSA. This fixed a -bug in V16 that sometimes caused a failure when querying for the sample -rates. Thanks Stweart Greenhill.</li> -</ul> -</blockquote> - -<blockquote> -<h4> -<b>Macintosh Sound Manager</b></h4> - -<ul> -<li> -Use NewSndCallBackUPP() for CARBON compatibility.</li> -</ul> -</blockquote> - -<h2> -<b>V16 - 9/27/01</b></h2> - -<blockquote><b>Added Alpha implementations for ASIO, SGI, and BeOS!</b> -<br> -<li> -CPULoad is now calculated based on the time spent to generate a known number -of frames. This is more accurate than a simple percentage of real-time. -Implemented in pa_unix_oss, pa_win_wmme and pa_win_ds.</li> - -<li> -Fix dither and shift for recording PaUInt8 format data.</li> - -<li> -Added "patest_maxsines.c" which tests <tt>Pa_GetCPULoad().</tt></li> -</blockquote> - -<blockquote> -<h4> -Windows WMME</h4> - -<ul> -<li> -sDevicePtrs now allocated using <tt>GlobalAlloc()</tt>. This prevents a -crash in Pa_Terminate() on Win2000. Thanks Mike Berry for finding this. -Thanks Mike Berry.</li> - -<li> -Pass process instead of thread to <tt>SetPriorityClass</tt>(). This fixes -a bug that caused the priority to not be increased. Thanks to Alberto di -Bene for spotting this.</li> -</ul> - -<h4> -Windows DirectSound</h4> - -<ul> -<li> -Casts for compiling with __MWERKS__ CodeWarrior.</li> -</ul> - -<h4> -UNIX OSS</h4> - -<ul> -<li> -Derived from Linux OSS implementation.</li> - -<li> -Numerous patches from Heiko Purnhagen, Stephen Brandon, etc.</li> - -<li> -Improved query mechanism which often bailed out unnecessarily.</li> - -<li> -Removed sNumDevices and potential related bugs,</li> - -<li> -Use <tt>getenv("PA_MIN_LATENCY_MSEC")</tt> in code to set desired latency. -User can set by entering:</li> - -<br> <tt>export PA_MIN_LATENCY_MSEC=40</tt></ul> - -<h4> -Macintosh Sound Manager</h4> - -<ul> -<li> -Pass unused event to WaitNextEvent instead of NULL to prevent Mac OSX crash. -Thanks Dominic Mazzoni.</li> - -<li> -Use requested number of input channels.</li> - -<br> </ul> -</blockquote> - -<h2> -<b>V15 - 5/29/01</b></h2> - -<blockquote> -<ul> -<li> -<b>New Linux OSS Beta</b></li> -</ul> - -<h4> -Windows WMME</h4> - -<ul> -<li> - sDevicePtrs now allocated based on sizeof(pointer). Was allocating -too much space.</li> - -<li> - Check for excessive numbers of channels. Some drivers reported bogus -numbers.</li> - -<li> -Apply Mike Berry's changes for CodeWarrior on PC including condition including -of memory.h, and explicit typecasting on memory allocation.</li> -</ul> - -<h4> -Macintosh Sound Manager</h4> - -<ul> -<li> -ScanInputDevices was setting sDefaultOutputDeviceID instead of sDefaultInputDeviceID.</li> - -<li> -Device Scan was crashing for anything other than siBadSoundInDevice, but -some Macs may return other errors! Caused failure to init on some G4s under -OS9.</li> - -<li> -Fix TIMEOUT in record mode.</li> - -<li> -Change CARBON_COMPATIBLE to TARGET_API_MAC_CARBON</li> -</ul> -</blockquote> - -<h2> -<b>V14 - 2/6/01</b></h2> - -<blockquote> -<ul> -<li> -Added implementation for Windows MultiMedia Extensions (WMME) by Ross and -Phil</li> - -<li> -Changed Pa_StopStream() so that it waits for the buffers to drain.</li> - -<li> -Added Pa_AbortStream() that stops immediately without waiting.</li> - -<li> -Added new test: patest_stop.c to test above two mods.</li> - -<li> -Fixed Pa_StreamTime() so that it returns current play position instead -of the write position. Added "patest_sync.c" to demo audio/video sync.</li> - -<li> -Improved stability of Macintosh implementation. Added timeouts to prevent -hangs.</li> - -<li> -Added Pa_GetSampleSize( PaSampleFormat format );</li> - -<li> -Changes some "int"s to "long"s so that PA works properly on Macintosh which -often compiles using 16 bit ints.</li> - -<li> -Added Implementation Guide</li> -</ul> -</blockquote> - -<h2> -<b>V12 - 1/9/01</b></h2> - -<blockquote> -<ul> -<li> -Mac now scans for and queries all devices. But it does not yet support -selecting any other than the default device.</li> - -<li> -Blocking I/O calls renamed to separate them from the PortAudio API.</li> - -<li> -Cleaned up indentation problems with tabs versus spaces.</li> - -<li> -Now attempts to correct bogus sample rate info returned from DirectSound -device queries.</li> -</ul> -</blockquote> - -</body> -</html> diff --git a/pd/portaudio/fixdir.bat b/pd/portaudio/fixdir.bat deleted file mode 100755 index 92d6c747..00000000 --- a/pd/portaudio/fixdir.bat +++ /dev/null @@ -1,19 +0,0 @@ -rem Use Astyle to fix style in 'C' files -cd %1% - -fixlines -p *.c -fixlines -p *.cpp -fixlines -p *.cc - -astyle --style=ansi -c -o --convert-tabs --indent-preprocessor *.c -astyle --style=ansi -c -o --convert-tabs --indent-preprocessor *.cpp -astyle --style=ansi -c -o --convert-tabs --indent-preprocessor *.cc -del *.orig -@rem convert line terminators to Unix style LFs -fixlines -u *.c -fixlines -u *.cpp -fixlines -u *.cc -fixlines -u *.h -del *.bak - -cd ..\ diff --git a/pd/portaudio/fixfile.bat b/pd/portaudio/fixfile.bat deleted file mode 100755 index 48f6fbc2..00000000 --- a/pd/portaudio/fixfile.bat +++ /dev/null @@ -1,7 +0,0 @@ -rem Use Astyle to fix style in a file -fixlines -p %1% -astyle --style=ansi -c -o --convert-tabs --indent-preprocessor %1% -del %1%.orig -@rem convert line terminators to Unix style LFs -fixlines -u %1% -del %1%.bak diff --git a/pd/portaudio/index.html b/pd/portaudio/index.html deleted file mode 100644 index 91e5b4c3..00000000 --- a/pd/portaudio/index.html +++ /dev/null @@ -1,89 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> - <meta name="Author" content="Phil Burk"> - <meta name="Description" content="PortAudio is a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function."> - <meta name="KeyWords" content="audio, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,"> - <title>PortAudio Implementations for DirectSound</title> -</head> -<body> - -<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" > -<tr> -<td> -<center> -<h1> -PortAudio - Portable Audio Library</h1></center> -</td> -</tr> -</table></center> - -<p>Last updated 5/6/02. -<p>PortAudio is a cross platform, <a href="#License">open-source</a>, audio -I/O library proposed by <b>Ross Bencina</b> to the <a href="http://shoko.calarts.edu/~glmrboy/musicdsp/music-dsp.html">music-dsp</a> -mailing list. It lets you write simple audio programs in 'C' that will -compile and run on <b>Windows, Macintosh, Unix, BeOS</b>. PortAudio is -intended to promote the exchange of audio synthesis software between developers -on different platforms. -<p>For complete information on PortAudio and to download the latest releases, -please visit "<b><font size=+2><a href="http://www.portaudio.com">http://www.portaudio.com</a></font></b>". -<br> -<br> -<center> -<h2> -<b><a href="docs/index.html">Click here for Documentation</a></b></h2></center> - -<h2> -<b><font size=+2></font></b></h2> - -<h2> -<b><font size=+2>Contacts and E-Mail List</font></b></h2> - -<ul> -<li> -If you are using or implementing PortAudio then please join the <b><font size=+1><a href="http://techweb.rfa.org/mailman/listinfo/portaudio">PortAudio -mail list</a></font><font size=+2> </font></b>generously administered by -<b>Bill -Eldridge</b>.</li> - -<li> -If you find bugs in one of these implementations, or have suggestions, -please e-mail them to <a href="mailto:philburk@softsynth.com">Phil Burk</a>.</li> - -<li> -If you make improvements to the library, please send them to us so we can -incorporate the improvements.</li> -</ul> - -<h2> -<a NAME="License"></a>License</h2> -PortAudio Portable Real-Time Audio Library -<br>Copyright (c) 1999-2000 Ross Bencina and Phil Burk -<p>Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following conditions: -<ul> -<li> -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software.</li> - -<li> -Any person wishing to distribute modifications to the Software is requested -to send the modifications to the original developer so that they can be -incorporated into the canonical version.</li> -</ul> -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND ON INFRINGEMENT. -<br>IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT -OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -THE USE OR OTHER DEALINGS IN THE SOFTWARE. -<br> -</body> -</html> diff --git a/pd/portaudio/install-sh b/pd/portaudio/install-sh deleted file mode 100755 index e9de2384..00000000 --- a/pd/portaudio/install-sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/pd/portaudio/pa_asio/Callback_adaptation_.pdf b/pd/portaudio/pa_asio/Callback_adaptation_.pdf Binary files differdeleted file mode 100644 index 76bf6786..00000000 --- a/pd/portaudio/pa_asio/Callback_adaptation_.pdf +++ /dev/null diff --git a/pd/portaudio/pa_asio/Pa_ASIO.pdf b/pd/portaudio/pa_asio/Pa_ASIO.pdf Binary files differdeleted file mode 100644 index ac5ecadb..00000000 --- a/pd/portaudio/pa_asio/Pa_ASIO.pdf +++ /dev/null diff --git a/pd/portaudio/pa_asio/borland_asio_readme.txt b/pd/portaudio/pa_asio/borland_asio_readme.txt deleted file mode 100644 index 56e472b8..00000000 --- a/pd/portaudio/pa_asio/borland_asio_readme.txt +++ /dev/null @@ -1,6 +0,0 @@ -Steinberg's ASIO 2 SDK will compile but crash on -initialization if compiled with a Borland compiler. - -The problem is described, and a solution provided on -the following page: -http://www.audiomulch.com/~rossb/code/calliasio
\ No newline at end of file diff --git a/pd/portaudio/pa_asio/pa_asio.cpp b/pd/portaudio/pa_asio/pa_asio.cpp deleted file mode 100644 index c8ba58f4..00000000 --- a/pd/portaudio/pa_asio/pa_asio.cpp +++ /dev/null @@ -1,2107 +0,0 @@ -/* - * $Id: pa_asio.cpp,v 1.7.2.30 2002/12/03 06:30:39 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 - - @todo implement underflow/overflow streamCallback statusFlags, 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 implement IsFormatSupported - - @todo work out how to implement stream stoppage from callback and - implement IsStreamActive properly - - @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 implement the following somewhere: - - if( stream->streamRepresentation.streamFinishedCallback != 0 ) - stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); -*/ - - - -#include <stdio.h> -#include <assert.h> -#include <string.h> -//#include <values.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" - -/* -#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, 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 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 ) ) - - -/* PaAsioHostApiRepresentation - host api datastructure specific to this implementation */ - -typedef struct -{ - PaUtilHostApiRepresentation inheritedHostApiRep; - PaUtilStreamInterface callbackStreamInterface; - PaUtilStreamInterface blockingStreamInterface; - - PaUtilAllocationGroup *allocations; - - /* the ASIO C API only allows one ASIO driver to be open at a time, - so we kee track of whether we have the driver open here, and - use this information to return errors from OpenStream if the - driver is already open. - */ - int driverOpen; -} -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; - } -} - - -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; -} -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; -} - - - -typedef struct PaAsioDriverInfo -{ - ASIODriverInfo asioDriverInfo; - long numInputChannels, numOutputChannels; - long bufferMinSize, bufferMaxSize, bufferPreferredSize, bufferGranularity; - bool postOutput; -} -PaAsioDriverInfo; - -/* - 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 *info ) -{ - 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; - } - - if( (asioError = ASIOInit( &info->asioDriverInfo )) != ASE_OK ) - { - result = paUnanticipatedHostError; - PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); - goto error; - } - else - { - asioIsInitialized = 1; - } - - if( (asioError = ASIOGetChannels(&info->numInputChannels, - &info->numOutputChannels)) != ASE_OK ) - { - result = paUnanticipatedHostError; - PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); - goto error; - } - - if( (asioError = ASIOGetBufferSize(&info->bufferMinSize, - &info->bufferMaxSize, &info->bufferPreferredSize, - &info->bufferGranularity)) != ASE_OK ) - { - result = paUnanticipatedHostError; - PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); - goto error; - } - - if( ASIOOutputReady() == ASE_OK ) - info->postOutput = true; - else - info->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, 96000.0, 8000.0 }; - - -PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) -{ - PaError result = paNoError; - int i, j, driverCount; - PaAsioHostApiRepresentation *asioHostApi; - PaAsioDeviceInfo *deviceInfoArray; - char **names; - PaAsioDriverInfo paAsioDriverInfo; - ASIOError asioError; - ASIODriverInfo asioDriverInfo; - ASIOChannelInfo asioChannelInfo; - double *sampleRates; - - - asioHostApi = (PaAsioHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaAsioHostApiRepresentation) ); - if( !asioHostApi ) - { - result = paInsufficientMemory; - goto error; - } - - asioHostApi->allocations = PaUtil_CreateAllocationGroup(); - if( !asioHostApi->allocations ) - { - result = paInsufficientMemory; - goto error; - } - - asioHostApi->driverOpen = 0; - - *hostApi = &asioHostApi->inheritedHostApiRep; - (*hostApi)->info.structVersion = 1; - - (*hostApi)->info.type = paASIO; - (*hostApi)->info.name = "ASIO"; - (*hostApi)->info.deviceCount = 0; - - #ifdef WINDOWS - CoInitialize(0); - #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; - } - - - #if WINDOWS - asioDriverInfo.asioVersion = 2; /* FIXME - is this right? PLB */ - asioDriverInfo.sysRef = GetDesktopWindow(); /* FIXME - is this right? PLB */ - #elif MAC - /* REVIEW: is anything needed here?? RDB */ - #endif - - for( i=0; i < driverCount; ++i ) - { - /* Attempt to load the asio driver... */ - if( LoadAsioDriver( names[i], &paAsioDriverInfo ) == paNoError ) - { - PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; - PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo; - - deviceInfo->structVersion = 2; - deviceInfo->hostApi = hostApiIndex; - - deviceInfo->name = names[i]; - - deviceInfo->maxInputChannels = paAsioDriverInfo.numInputChannels; - deviceInfo->maxOutputChannels = paAsioDriverInfo.numOutputChannels; - - PA_DEBUG(("PaAsio_Initialize: inputChannels = %d\n", inputChannels )); - PA_DEBUG(("PaAsio_Initialize: outputChannels = %d\n", outputChannels )); - - - deviceInfo->defaultLowInputLatency = 0.; /* @todo IMPLEMENT ME */ - deviceInfo->defaultLowOutputLatency = 0.; /* @todo IMPLEMENT ME */ - deviceInfo->defaultHighInputLatency = 0.; /* @todo IMPLEMENT ME */ - deviceInfo->defaultHighOutputLatency = 0.; /* @todo IMPLEMENT ME */ - - deviceInfo->defaultSampleRate = 0.; - 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]; - break; - } - } - - asioDeviceInfo->minBufferSize = paAsioDriverInfo.bufferMinSize; - asioDeviceInfo->maxBufferSize = paAsioDriverInfo.bufferMaxSize; - asioDeviceInfo->preferredBufferSize = paAsioDriverInfo.bufferPreferredSize; - asioDeviceInfo->bufferGranularity = paAsioDriverInfo.bufferGranularity; - - - /* We assume that all channels have the same SampleType, so check the first, FIXME, probably shouldn't assume that */ - asioChannelInfo.channel = 0; - asioChannelInfo.isInput = 1; - ASIOGetChannelInfo( &asioChannelInfo ); /* FIXME, check return code */ - - - /* 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_DummyReadWrite, PaUtil_DummyReadWrite, PaUtil_DummyGetAvailable, PaUtil_DummyGetAvailable ); - - 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 ) -{ - int numInputChannels, numOutputChannels; - PaSampleFormat inputSampleFormat, outputSampleFormat; - - if( inputParameters ) - { - numInputChannels = 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 numInputChannels */ - if( numInputChannels > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) - return paInvalidChannelCount; - - /* validate inputStreamInfo */ - if( inputParameters->hostApiSpecificStreamInfo ) - return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ - } - else - { - numInputChannels = 0; - } - - if( outputParameters ) - { - numOutputChannels = 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 numInputChannels */ - if( numOutputChannels > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) - return paInvalidChannelCount; - - /* validate outputStreamInfo */ - if( outputParameters->hostApiSpecificStreamInfo ) - return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ - } - else - { - numOutputChannels = 0; - } - - /* - IMPLEMENT ME: - - 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 - */ - - return paFormatIsSupported; -} - - - -/* 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 numInputChannels, numOutputChannels; - 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 int stopProcessing; /* stop thread once existing buffers have been returned */ - volatile int abortProcessing; /* stop thread immediately */ -} -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->numOutputChannels; ++i ) - { - void *buffer = stream->asioBufferInfos[ i + stream->numInputChannels ].buffers[index]; - - int bytesPerSample = BytesPerAsioSample( stream->asioChannelInfos[ i + stream->numInputChannels ].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 *= result; - - if( result < (unsigned long)driverInfo->bufferMinSize ) - result = driverInfo->bufferMinSize; - - if( result > (unsigned long)driverInfo->bufferMaxSize ) - result = driverInfo->bufferMaxSize; - } - else if( driverInfo->bufferGranularity == 0 ) - { - result = driverInfo->bufferPreferredSize; - } - else - { - /* modulo granularity */ - - result = suggestedLatencyFrames + - (driverInfo->bufferGranularity - - (suggestedLatencyFrames % driverInfo->bufferGranularity)); - if( result > (unsigned long)driverInfo->bufferMaxSize ) - result = driverInfo->bufferMaxSize; - } - } - } - - 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; - PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi; - PaAsioStream *stream = 0; - unsigned long framesPerHostBuffer; - int numInputChannels, numOutputChannels; - PaSampleFormat inputSampleFormat, outputSampleFormat; - PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; - unsigned long suggestedInputLatencyFrames; - unsigned long suggestedOutputLatencyFrames; - const char *driverName; - ASIOError asioError; - int asioIsInitialized = 0; - int asioBuffersCreated = 0; - PaAsioDriverInfo driverInfo; - int i; - - /* unless we move to using lower level ASIO calls, we can only have - one device open at a time */ - if( asioHostApi->driverOpen ) - return paDeviceUnavailable; - - - - if( inputParameters ) - { - numInputChannels = inputParameters->channelCount; - inputSampleFormat = inputParameters->sampleFormat; - suggestedInputLatencyFrames = inputParameters->suggestedLatency * sampleRate; - - driverName = asioHostApi->inheritedHostApiRep.deviceInfos[ inputParameters->device ]->name; - - /* unless alternate device specification is supported, reject the use of - paUseHostApiSpecificDeviceSpecification */ - if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) - return paInvalidDevice; - - /* validate hostApiSpecificStreamInfo */ - if( inputParameters->hostApiSpecificStreamInfo ) - return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ - } - else - { - numInputChannels = 0; - suggestedInputLatencyFrames = 0; - } - - if( outputParameters ) - { - numOutputChannels = outputParameters->channelCount; - outputSampleFormat = outputParameters->sampleFormat; - suggestedOutputLatencyFrames = outputParameters->suggestedLatency; - - driverName = asioHostApi->inheritedHostApiRep.deviceInfos[ outputParameters->device ]->name; - - /* unless alternate device specification is supported, reject the use of - paUseHostApiSpecificDeviceSpecification */ - if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) - return paInvalidDevice; - - /* validate hostApiSpecificStreamInfo */ - if( outputParameters->hostApiSpecificStreamInfo ) - return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ - } - else - { - numOutputChannels = 0; - suggestedOutputLatencyFrames = 0; - } - - - if( inputParameters && outputParameters ) - { - /* full duplex ASIO stream must use the same device for input and output */ - - if( inputParameters->device != outputParameters->device ) - return paBadIODeviceCombination; - } - - - - /* 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( driverName, &driverInfo ); - if( result == paNoError ) - asioIsInitialized = 1; - else - goto error; - - /* check that input device can support numInputChannels */ - if( numInputChannels > 0 ) - { - if( numInputChannels > driverInfo.numInputChannels ) - { - result = paInvalidChannelCount; - goto error; - } - } - - /* check that output device can support numOutputChannels */ - if( numOutputChannels ) - { - if( numOutputChannels > driverInfo.numOutputChannels ) - { - result = paInvalidChannelCount; - goto error; - } - } - - /* Set sample rate */ - if( ASIOSetSampleRate( sampleRate ) != ASE_OK ) - { - result = paInvalidSampleRate; - goto error; - } - - framesPerHostBuffer = SelectHostBufferSize( - (( suggestedInputLatencyFrames > suggestedOutputLatencyFrames ) - ? suggestedInputLatencyFrames : suggestedOutputLatencyFrames), - &driverInfo ); - - /* - 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 ) - return paInvalidFlag; /* unexpected platform specific flag */ - - - stream = (PaAsioStream*)PaUtil_AllocateMemory( sizeof(PaAsioStream) ); - if( !stream ) - { - result = paInsufficientMemory; - goto error; - } - - 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) * (numInputChannels + numOutputChannels) ); - if( !stream->asioBufferInfos ) - { - result = paInsufficientMemory; - goto error; - } - - - for( i=0; i < numInputChannels; ++i ) - { - ASIOBufferInfo *info = &stream->asioBufferInfos[i]; - - info->isInput = ASIOTrue; - info->channelNum = i; - info->buffers[0] = info->buffers[1] = 0; - } - - for( i=0; i < numOutputChannels; ++i ){ - ASIOBufferInfo *info = &stream->asioBufferInfos[numInputChannels+i]; - - info->isInput = ASIOFalse; - info->channelNum = i; - info->buffers[0] = info->buffers[1] = 0; - } - - asioError = ASIOCreateBuffers( stream->asioBufferInfos, numInputChannels+numOutputChannels, - framesPerHostBuffer, &asioCallbacks_ ); - if( asioError != ASE_OK ) - { - result = paUnanticipatedHostError; - PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); - goto error; - } - - asioBuffersCreated = 1; - - stream->asioChannelInfos = (ASIOChannelInfo*)PaUtil_AllocateMemory( - sizeof(ASIOChannelInfo) * (numInputChannels + numOutputChannels) ); - if( !stream->asioChannelInfos ) - { - result = paInsufficientMemory; - goto error; - } - - for( i=0; i < numInputChannels + numOutputChannels; ++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 ); - goto error; - } - } - - stream->bufferPtrs = (void**)PaUtil_AllocateMemory( - 2 * sizeof(void*) * (numInputChannels + numOutputChannels) ); - if( !stream->bufferPtrs ) - { - result = paInsufficientMemory; - goto error; - } - - if( numInputChannels > 0 ) - { - stream->inputBufferPtrs[0] = stream-> bufferPtrs; - stream->inputBufferPtrs[1] = &stream->bufferPtrs[numInputChannels]; - - for( i=0; i<numInputChannels; ++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( numOutputChannels > 0 ) - { - stream->outputBufferPtrs[0] = &stream->bufferPtrs[numInputChannels*2]; - stream->outputBufferPtrs[1] = &stream->bufferPtrs[numInputChannels*2 + numOutputChannels]; - - for( i=0; i<numOutputChannels; ++i ) - { - stream->outputBufferPtrs[0][i] = stream->asioBufferInfos[numInputChannels+i].buffers[0]; - stream->outputBufferPtrs[1][i] = stream->asioBufferInfos[numInputChannels+i].buffers[1]; - } - } - else - { - stream->outputBufferPtrs[0] = 0; - stream->outputBufferPtrs[1] = 0; - } - - - ASIOGetLatencies( &stream->inputLatency, &stream->outputLatency ); - - stream->streamRepresentation.streamInfo.inputLatency = (double)stream->inputLatency / sampleRate; // seconds - stream->streamRepresentation.streamInfo.outputLatency = (double)stream->outputLatency / sampleRate; // seconds - stream->streamRepresentation.streamInfo.sampleRate = sampleRate; - - - PA_DEBUG(("PaAsio : InputLatency = %ld latency = %ld msec \n", - stream->inputLatency, - (long)((stream->inputLatency*1000)/ sampleRate))); - PA_DEBUG(("PaAsio : OuputLatency = %ld latency = %ld msec \n", - stream->outputLatency, - (long)((stream->outputLatency*1000)/ sampleRate))); - - - if( numInputChannels > 0 ) - { - /* FIXME: assume all channels use the same type for now */ - ASIOSampleType inputType = stream->asioChannelInfos[0].type; - - hostInputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( inputType ); - - SelectAsioToPaConverter( inputType, &stream->inputBufferConverter, &stream->inputShift ); - } - else - { - stream->inputBufferConverter = 0; - } - - if( numOutputChannels > 0 ) - { - /* FIXME: assume all channels use the same type for now */ - ASIOSampleType outputType = stream->asioChannelInfos[numInputChannels].type; - - hostOutputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( outputType ); - - SelectPaToAsioConverter( outputType, &stream->outputBufferConverter, &stream->outputShift ); - } - else - { - stream->outputBufferConverter = 0; - } - - result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, - numInputChannels, inputSampleFormat, hostInputSampleFormat, - numOutputChannels, outputSampleFormat, hostOutputSampleFormat, - sampleRate, streamFlags, framesPerBuffer, - framesPerHostBuffer, paUtilFixedHostBufferSize, - streamCallback, userData ); - if( result != paNoError ) - goto error; - - stream->asioHostApi = asioHostApi; - stream->framesPerHostCallback = framesPerHostBuffer; - - stream->numInputChannels = numInputChannels; - stream->numOutputChannels = numOutputChannels; - stream->postOutput = driverInfo.postOutput; - - asioHostApi->driverOpen = 1; - - *s = (PaStream*)stream; - - return result; - -error: - if( stream ) - { - 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->driverOpen = 0; - - 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 processNow) -{ -//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, processNow ); -} - - -// 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 processNow ) -{ - // the actual processing callback. - // Beware that this is normally in a seperate thread, hence be sure that - // you take care about thread synchronization. This is omitted here for simplicity. - - - (void) processNow; /* unused parameter: FIXME: the sdk implies that we shouldn't process now if this parameter is false */ - -#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 - - // Keep sample position - // FIXME: asioDriverInfo.pahsc_NumFramesDone = timeInfo->timeInfo.samplePosition.lo; - - if( theAsioStream->stopProcessing || theAsioStream->abortProcessing ) { - - ZeroOutputBuffers( theAsioStream, index ); - - // Finally if the driver supports the ASIOOutputReady() optimization, - // do it here, all data are in place - if( theAsioStream->postOutput ) - ASIOOutputReady(); - - } - else - { - 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); - paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime - theAsioStream->streamRepresentation.streamInfo.inputLatency; - paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + theAsioStream->streamRepresentation.streamInfo.outputLatency; - - - if( theAsioStream->inputBufferConverter ) - { - for( i=0; i<theAsioStream->numInputChannels; i++ ) - { - theAsioStream->inputBufferConverter( theAsioStream->inputBufferPtrs[index][i], - theAsioStream->inputShift, theAsioStream->framesPerHostCallback ); - } - } - - PaUtil_BeginBufferProcessing( &theAsioStream->bufferProcessor, &paTimeInfo ); - - PaUtil_SetInputFrameCount( &theAsioStream->bufferProcessor, 0 /* default to host buffer size */ ); - for( i=0; i<theAsioStream->numInputChannels; ++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->numOutputChannels; ++i ) - PaUtil_SetNonInterleavedOutputChannel( &theAsioStream->bufferProcessor, i, theAsioStream->outputBufferPtrs[index][i] ); - - int callbackResult; - unsigned long framesProcessed = PaUtil_EndBufferProcessing( &theAsioStream->bufferProcessor, &callbackResult ); - - if( theAsioStream->outputBufferConverter ) - { - for( i=0; i<theAsioStream->numOutputChannels; 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 ) - { - /* IMPLEMENT ME - finish playback immediately */ - } - 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 */ - } - } - - 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 */ -} - -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; - - 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->numOutputChannels > 0 ) - { - ZeroOutputBuffers( stream, 0 ); - ZeroOutputBuffers( stream, 1 ); - } - - stream->stopProcessing = 0; - stream->abortProcessing = 0; - - theAsioStream = stream; - asioError = ASIOStart(); - if( asioError != ASE_OK ) - { - 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; - - stream->stopProcessing = 1; - stream->abortProcessing = 1; - - asioError = ASIOStop(); - if( asioError != ASE_OK ) - { - result = paUnanticipatedHostError; - PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); - } - - theAsioStream = 0; - - return result; -} - - -static PaError AbortStream( PaStream *s ) -{ - /* ASIO doesn't provide Abort behavior, so just stop instead */ - return StopStream( s ); -} - - -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; - (void) s; /* unused parameter */ - return theAsioStream != 0; /* FIXME: currently there is no way to stop the stream from the callback */ -} - - -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, - 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; -} - diff --git a/pd/portaudio/pa_asio/pa_asio.h b/pd/portaudio/pa_asio/pa_asio.h deleted file mode 100644 index c2775928..00000000 --- a/pd/portaudio/pa_asio/pa_asio.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef PA_ASIO_H -#define PA_ASIO_H -/* - * - * 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. - * - */ - - -#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 minLatency 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 ); - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* PA_ASIO_H */ diff --git a/pd/portaudio/pa_asio/readme_asio_sdk_patch.txt b/pd/portaudio/pa_asio/readme_asio_sdk_patch.txt deleted file mode 100755 index c0fdca7f..00000000 --- a/pd/portaudio/pa_asio/readme_asio_sdk_patch.txt +++ /dev/null @@ -1,25 +0,0 @@ -There is a bug in the ASIO SDK that causes the Macintosh version to often fail during initialization. Here is a patch that you can apply. - -In codefragments.cpp replace getFrontProcessDirectory function with -the following one (GetFrontProcess replaced by GetCurrentProcess) - - -bool CodeFragments::getFrontProcessDirectory(void *specs) -{ - FSSpec *fss = (FSSpec *)specs; - ProcessInfoRec pif; - ProcessSerialNumber psn; - - memset(&psn,0,(long)sizeof(ProcessSerialNumber)); - // if(GetFrontProcess(&psn) == noErr) // wrong !!! - if(GetCurrentProcess(&psn) == noErr) // correct !!! - { - pif.processName = 0; - pif.processAppSpec = fss; - pif.processInfoLength = sizeof(ProcessInfoRec); - if(GetProcessInformation(&psn, &pif) == noErr) - return true; - } - return false; -} - diff --git a/pd/portaudio/pa_beos/PlaybackNode.cc b/pd/portaudio/pa_beos/PlaybackNode.cc deleted file mode 100644 index 41cbae34..00000000 --- a/pd/portaudio/pa_beos/PlaybackNode.cc +++ /dev/null @@ -1,538 +0,0 @@ -/* - * $Id: PlaybackNode.cc,v 1.1.1.1 2003-05-09 16:03:53 ggeiger Exp $ - * PortAudio Portable Real-Time Audio Library - * Latest Version at: http://www.portaudio.com - * BeOS Media Kit Implementation by Joshua Haberman - * - * Copyright (c) 2001 Joshua Haberman <joshua@haberman.com> - * - * 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. - * - * --- - * - * Significant portions of this file are based on sample code from Be. The - * Be Sample Code Licence follows: - * - * Copyright 1991-1999, Be Incorporated. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions, and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> - -#include <be/media/BufferGroup.h> -#include <be/media/Buffer.h> -#include <be/media/TimeSource.h> - -#include "PlaybackNode.h" - -#define PRINT(x) { printf x; fflush(stdout); } - -#ifdef DEBUG -#define DBUG(x) PRINT(x) -#else -#define DBUG(x) -#endif - - -PaPlaybackNode::PaPlaybackNode(uint32 channels, float frame_rate, uint32 frames_per_buffer, - PortAudioCallback* callback, void *user_data) : - BMediaNode("PortAudio input node"), - BBufferProducer(B_MEDIA_RAW_AUDIO), - BMediaEventLooper(), - mAborted(false), - mRunning(false), - mBufferGroup(NULL), - mDownstreamLatency(0), - mStartTime(0), - mCallback(callback), - mUserData(user_data), - mFramesPerBuffer(frames_per_buffer) -{ - DBUG(("Constructor called.\n")); - - mPreferredFormat.type = B_MEDIA_RAW_AUDIO; - mPreferredFormat.u.raw_audio.channel_count = channels; - mPreferredFormat.u.raw_audio.frame_rate = frame_rate; - mPreferredFormat.u.raw_audio.byte_order = - (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN; - mPreferredFormat.u.raw_audio.buffer_size = - media_raw_audio_format::wildcard.buffer_size; - - mOutput.destination = media_destination::null; - mOutput.format = mPreferredFormat; - - /* The amount of time it takes for this node to produce a buffer when - * asked. Essentially, it is how long the user's callback takes to run. - * We set this to be the length of the sound data each buffer of the - * requested size can hold. */ - //mInternalLatency = (bigtime_t)(1000000 * frames_per_buffer / frame_rate); - - /* ACK! it seems that the mixer (at least on my machine) demands that IT - * specify the buffer size, so for now I'll just make a generic guess here */ - mInternalLatency = 1000000 / 20; -} - - - -PaPlaybackNode::~PaPlaybackNode() -{ - DBUG(("Destructor called.\n")); - Quit(); /* Stop the BMediaEventLooper thread */ -} - - -/************************* - * - * Local methods - * - */ - -bool PaPlaybackNode::IsRunning() -{ - return mRunning; -} - - -PaTimestamp PaPlaybackNode::GetStreamTime() -{ - BTimeSource *timeSource = TimeSource(); - PaTimestamp time = (timeSource->Now() - mStartTime) * - mPreferredFormat.u.raw_audio.frame_rate / 1000000; - return time; -} - - -void PaPlaybackNode::SetSampleFormat(PaSampleFormat inFormat, - PaSampleFormat outFormat) -{ - uint32 beOutFormat; - - switch(outFormat) - { - case paFloat32: - beOutFormat = media_raw_audio_format::B_AUDIO_FLOAT; - mOutputSampleWidth = 4; - break; - - case paInt16: - beOutFormat = media_raw_audio_format::B_AUDIO_SHORT; - mOutputSampleWidth = 2; - break; - - case paInt32: - beOutFormat = media_raw_audio_format::B_AUDIO_INT; - mOutputSampleWidth = 4; - break; - - case paInt8: - beOutFormat = media_raw_audio_format::B_AUDIO_CHAR; - mOutputSampleWidth = 1; - break; - - case paUInt8: - beOutFormat = media_raw_audio_format::B_AUDIO_UCHAR; - mOutputSampleWidth = 1; - break; - - case paInt24: - case paPackedInt24: - case paCustomFormat: - DBUG(("Unsupported output format: %x\n", outFormat)); - break; - - default: - DBUG(("Unknown output format: %x\n", outFormat)); - } - - mPreferredFormat.u.raw_audio.format = beOutFormat; - mFramesPerBuffer * mPreferredFormat.u.raw_audio.channel_count * mOutputSampleWidth; -} - -BBuffer *PaPlaybackNode::FillNextBuffer(bigtime_t time) -{ - /* Get a buffer from the buffer group */ - BBuffer *buf = mBufferGroup->RequestBuffer( - mOutput.format.u.raw_audio.buffer_size, BufferDuration()); - unsigned long frames = mOutput.format.u.raw_audio.buffer_size / - mOutputSampleWidth / mOutput.format.u.raw_audio.channel_count; - bigtime_t start_time; - int ret; - - if( !buf ) - { - DBUG(("Unable to allocate a buffer\n")); - return NULL; - } - - start_time = mStartTime + - (bigtime_t)((double)mSamplesSent / - (double)mOutput.format.u.raw_audio.frame_rate / - (double)mOutput.format.u.raw_audio.channel_count * - 1000000.0); - - /* Now call the user callback to get the data */ - ret = mCallback(NULL, /* Input buffer */ - buf->Data(), /* Output buffer */ - frames, /* Frames per buffer */ - mSamplesSent / mOutput.format.u.raw_audio.channel_count, /* timestamp */ - mUserData); - - if( ret ) - mAborted = true; - - media_header *hdr = buf->Header(); - - hdr->type = B_MEDIA_RAW_AUDIO; - hdr->size_used = mOutput.format.u.raw_audio.buffer_size; - hdr->time_source = TimeSource()->ID(); - hdr->start_time = start_time; - - return buf; -} - - - - -/************************* - * - * BMediaNode methods - * - */ - -BMediaAddOn *PaPlaybackNode::AddOn( int32 * ) const -{ - DBUG(("AddOn() called.\n")); - return NULL; /* we don't provide service to outside applications */ -} - - -status_t PaPlaybackNode::HandleMessage( int32 message, const void *data, - size_t size ) -{ - DBUG(("HandleMessage() called.\n")); - return B_ERROR; /* we don't define any custom messages */ -} - - - - -/************************* - * - * BMediaEventLooper methods - * - */ - -void PaPlaybackNode::NodeRegistered() -{ - DBUG(("NodeRegistered() called.\n")); - - /* Start the BMediaEventLooper thread */ - SetPriority(B_REAL_TIME_PRIORITY); - Run(); - - /* set up as much information about our output as we can */ - mOutput.source.port = ControlPort(); - mOutput.source.id = 0; - mOutput.node = Node(); - ::strcpy(mOutput.name, "PortAudio Playback"); -} - - -void PaPlaybackNode::HandleEvent( const media_timed_event *event, - bigtime_t lateness, bool realTimeEvent ) -{ - // DBUG(("HandleEvent() called.\n")); - status_t err; - - switch(event->type) - { - case BTimedEventQueue::B_START: - DBUG((" Handling a B_START event\n")); - if( RunState() != B_STARTED ) - { - mStartTime = event->event_time + EventLatency(); - mSamplesSent = 0; - mAborted = false; - mRunning = true; - media_timed_event firstEvent( mStartTime, - BTimedEventQueue::B_HANDLE_BUFFER ); - EventQueue()->AddEvent( firstEvent ); - } - break; - - case BTimedEventQueue::B_STOP: - DBUG((" Handling a B_STOP event\n")); - mRunning = false; - EventQueue()->FlushEvents( 0, BTimedEventQueue::B_ALWAYS, true, - BTimedEventQueue::B_HANDLE_BUFFER ); - break; - - case BTimedEventQueue::B_HANDLE_BUFFER: - //DBUG((" Handling a B_HANDLE_BUFFER event\n")); - - /* make sure we're started and connected */ - if( RunState() != BMediaEventLooper::B_STARTED || - mOutput.destination == media_destination::null ) - break; - - BBuffer *buffer = FillNextBuffer(event->event_time); - - /* make sure we weren't aborted while this routine was running. - * this can happen in one of two ways: either the callback returned - * nonzero (in which case mAborted is set in FillNextBuffer() ) or - * the client called AbortStream */ - if( mAborted ) - { - if( buffer ) - buffer->Recycle(); - Stop(0, true); - break; - } - - if( buffer ) - { - err = SendBuffer(buffer, mOutput.destination); - if( err != B_OK ) - buffer->Recycle(); - } - - mSamplesSent += mOutput.format.u.raw_audio.buffer_size / mOutputSampleWidth; - - /* Now schedule the next buffer event, so we can send another - * buffer when this one runs out. We calculate when it should - * happen by calculating when the data we just sent will finish - * playing. - * - * NOTE, however, that the event will actually get generated - * earlier than we specify, to account for the latency it will - * take to produce the buffer. It uses the latency value we - * specified in SetEventLatency() to determine just how early - * to generate it. */ - - /* totalPerformanceTime includes the time represented by the buffer - * we just sent */ - bigtime_t totalPerformanceTime = (bigtime_t)((double)mSamplesSent / - (double)mOutput.format.u.raw_audio.channel_count / - (double)mOutput.format.u.raw_audio.frame_rate * 1000000.0); - - bigtime_t nextEventTime = mStartTime + totalPerformanceTime; - - media_timed_event nextBufferEvent(nextEventTime, - BTimedEventQueue::B_HANDLE_BUFFER); - EventQueue()->AddEvent(nextBufferEvent); - - break; - - } -} - - - - -/************************* - * - * BBufferProducer methods - * - */ - -status_t PaPlaybackNode::FormatSuggestionRequested( media_type type, - int32 /*quality*/, media_format* format ) -{ - /* the caller wants to know this node's preferred format and provides - * a suggestion, asking if we support it */ - DBUG(("FormatSuggestionRequested() called.\n")); - - if(!format) - return B_BAD_VALUE; - - *format = mPreferredFormat; - - /* we only support raw audio (a wildcard is okay too) */ - if ( type == B_MEDIA_UNKNOWN_TYPE || type == B_MEDIA_RAW_AUDIO ) - return B_OK; - else - return B_MEDIA_BAD_FORMAT; -} - - -status_t PaPlaybackNode::FormatProposal( const media_source& output, - media_format* format ) -{ - /* This is similar to FormatSuggestionRequested(), but it is actually part - * of the negotiation process. We're given the opportunity to specify any - * properties that are wildcards (ie. properties that the other node doesn't - * care one way or another about) */ - DBUG(("FormatProposal() called.\n")); - - /* Make sure this proposal really applies to our output */ - if( output != mOutput.source ) - return B_MEDIA_BAD_SOURCE; - - /* We return two things: whether we support the proposed format, and our own - * preferred format */ - *format = mPreferredFormat; - - if( format->type == B_MEDIA_UNKNOWN_TYPE || format->type == B_MEDIA_RAW_AUDIO ) - return B_OK; - else - return B_MEDIA_BAD_FORMAT; -} - - -status_t PaPlaybackNode::FormatChangeRequested( const media_source& source, - const media_destination& destination, media_format* io_format, int32* ) -{ - /* we refuse to change formats, supporting only 1 */ - DBUG(("FormatChangeRequested() called.\n")); - - return B_ERROR; -} - - -status_t PaPlaybackNode::GetNextOutput( int32* cookie, media_output* out_output ) -{ - /* this is where we allow other to enumerate our outputs -- the cookie is - * an integer we can use to keep track of where we are in enumeration. */ - DBUG(("GetNextOutput() called.\n")); - - if( *cookie == 0 ) - { - *out_output = mOutput; - *cookie = 1; - return B_OK; - } - - return B_BAD_INDEX; -} - - -status_t PaPlaybackNode::DisposeOutputCookie( int32 cookie ) -{ - DBUG(("DisposeOutputCookie() called.\n")); - return B_OK; -} - - -void PaPlaybackNode::LateNoticeReceived( const media_source& what, - bigtime_t how_much, bigtime_t performance_time ) -{ - /* This function is called as notification that a buffer we sent wasn't - * received by the time we stamped it with -- it got there late. Basically, - * it means we underestimated our own latency, so we should increase it */ - DBUG(("LateNoticeReceived() called.\n")); - - if( what != mOutput.source ) - return; - - if( RunMode() == B_INCREASE_LATENCY ) - { - mInternalLatency += how_much; - SetEventLatency( mDownstreamLatency + mInternalLatency ); - DBUG(("Increasing latency to %Ld\n", mDownstreamLatency + mInternalLatency)); - } - else - DBUG(("I don't know what to do with this notice!")); -} - - -void PaPlaybackNode::EnableOutput( const media_source& what, bool enabled, - int32* ) -{ - DBUG(("EnableOutput() called.\n")); - /* stub -- we don't support this yet */ -} - - -status_t PaPlaybackNode::PrepareToConnect( const media_source& what, - const media_destination& where, media_format* format, - media_source* out_source, char* out_name ) -{ - /* the final stage of format negotiations. here we _must_ make specific any - * remaining wildcards */ - DBUG(("PrepareToConnect() called.\n")); - - /* make sure this really refers to our source */ - if( what != mOutput.source ) - return B_MEDIA_BAD_SOURCE; - - /* make sure we're not already connected */ - if( mOutput.destination != media_destination::null ) - return B_MEDIA_ALREADY_CONNECTED; - - if( format->type != B_MEDIA_RAW_AUDIO ) - return B_MEDIA_BAD_FORMAT; - - if( format->u.raw_audio.format != mPreferredFormat.u.raw_audio.format ) - return B_MEDIA_BAD_FORMAT; - - if( format->u.raw_audio.buffer_size == - media_raw_audio_format::wildcard.buffer_size ) - { - DBUG(("We were left to decide buffer size: choosing 2048")); - format->u.raw_audio.buffer_size = 2048; - } - else - DBUG(("Using consumer specified buffer size of %lu.\n", - format->u.raw_audio.buffer_size)); - - /* Reserve the connection, return the information */ - mOutput.destination = where; - mOutput.format = *format; - *out_source = mOutput.source; - strncpy( out_name, mOutput.name, B_MEDIA_NAME_LENGTH ); - - return B_OK; -} - - -void PaPlaybackNode::Connect(status_t error, const media_source& source, - const media_destination& destination, const media_format& format, char* io_name) -{ - DBUG(("Connect() called.\n")); - diff --git a/pd/portaudio/pa_beos/PlaybackNode.h b/pd/portaudio/pa_beos/PlaybackNode.h deleted file mode 100644 index db978a59..00000000 --- a/pd/portaudio/pa_beos/PlaybackNode.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * $Id: PlaybackNode.h,v 1.1.1.1 2003-05-09 16:03:53 ggeiger Exp $ - * PortAudio Portable Real-Time Audio Library - * Latest Version at: http://www.portaudio.com - * BeOS Media Kit Implementation by Joshua Haberman - * - * Copyright (c) 2001 Joshua Haberman <joshua@haberman.com> - * - * 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 <be/media/MediaRoster.h> -#include <be/media/MediaEventLooper.h> -#include <be/media/BufferProducer.h> - -#include "portaudio.h" - -class PaPlaybackNode : - public BBufferProducer, - public BMediaEventLooper -{ - -public: - PaPlaybackNode( uint32 channels, float frame_rate, uint32 frames_per_buffer, - PortAudioCallback *callback, void *user_data ); - ~PaPlaybackNode(); - - - /* Local methods ******************************************/ - - BBuffer *FillNextBuffer(bigtime_t time); - void SetSampleFormat(PaSampleFormat inFormat, PaSampleFormat outFormat); - bool IsRunning(); - PaTimestamp GetStreamTime(); - - /* BMediaNode methods *************************************/ - - BMediaAddOn* AddOn( int32 * ) const; - status_t HandleMessage( int32 message, const void *data, size_t size ); - - /* BMediaEventLooper methods ******************************/ - - void HandleEvent( const media_timed_event *event, bigtime_t lateness, - bool realTimeEvent ); - void NodeRegistered(); - - /* BBufferProducer methods ********************************/ - - status_t FormatSuggestionRequested( media_type type, int32 quality, - media_format* format ); - status_t FormatProposal( const media_source& output, media_format* format ); - status_t FormatChangeRequested( const media_source& source, - const media_destination& destination, media_format* io_format, int32* ); - - status_t GetNextOutput( int32* cookie, media_output* out_output ); - status_t DisposeOutputCookie( int32 cookie ); - - void LateNoticeReceived( const media_source& what, bigtime_t how_much, - bigtime_t performance_time ); - void EnableOutput( const media_source& what, bool enabled, int32* _deprecated_ ); - - status_t PrepareToConnect( const media_source& what, - const media_destination& where, media_format* format, - media_source* out_source, char* out_name ); - void Connect(status_t error, const media_source& source, - const media_destination& destination, const media_format& format, - char* io_name); - void Disconnect(const media_source& what, const media_destination& where); - - status_t SetBufferGroup(const media_source& for_source, BBufferGroup* newGroup); - - bool mAborted; - -private: - media_output mOutput; - media_format mPreferredFormat; - uint32 mOutputSampleWidth, mFramesPerBuffer; - BBufferGroup *mBufferGroup; - bigtime_t mDownstreamLatency, mInternalLatency, mStartTime; - uint64 mSamplesSent; - PortAudioCallback *mCallback; - void *mUserData; - bool mRunning; - -}; - diff --git a/pd/portaudio/pa_beos/pa_beos_mk.cc b/pd/portaudio/pa_beos/pa_beos_mk.cc deleted file mode 100644 index 3307a2ff..00000000 --- a/pd/portaudio/pa_beos/pa_beos_mk.cc +++ /dev/null @@ -1,441 +0,0 @@ -/* - * $Id: pa_beos_mk.cc,v 1.1.1.1 2003-05-09 16:03:53 ggeiger Exp $ - * PortAudio Portable Real-Time Audio Library - * Latest Version at: http://www.portaudio.com - * BeOS Media Kit Implementation by Joshua Haberman - * - * Copyright (c) 2001 Joshua Haberman <joshua@haberman.com> - * - * 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 <be/app/Application.h> -#include <be/kernel/OS.h> -#include <be/media/RealtimeAlloc.h> -#include <be/media/MediaRoster.h> -#include <be/media/TimeSource.h> - -#include <stdio.h> -#include <string.h> - -#include "portaudio.h" -#include "pa_host.h" - -#include "PlaybackNode.h" - -#define PRINT(x) { printf x; fflush(stdout); } - -#ifdef DEBUG -#define DBUG(x) PRINT(x) -#else -#define DBUG(x) -#endif - -typedef struct PaHostSoundControl -{ - /* These members are common to all modes of operation */ - media_node pahsc_TimeSource; /* the sound card's DAC. */ - media_format pahsc_Format; - - /* These methods are specific to playing mode */ - media_node pahsc_OutputNode; /* output to the mixer */ - media_node pahsc_InputNode; /* reads data from user callback -- PA specific */ - - media_input pahsc_MixerInput; /* input jack on the soundcard's mixer. */ - media_output pahsc_PaOutput; /* output jack from the PA node */ - - PaPlaybackNode *pahsc_InputNodeInstance; - -} -PaHostSoundControl; - -/*************************************************************************/ -PaDeviceID Pa_GetDefaultOutputDeviceID( void ) -{ - /* stub */ - return 0; -} - -/*************************************************************************/ -PaDeviceID Pa_GetDefaultInputDeviceID( void ) -{ - /* stub */ - return 0; -} - -/*************************************************************************/ -const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id ) -{ - /* stub */ - return NULL; -} - -/*************************************************************************/ -int Pa_CountDevices() -{ - /* stub */ - return 1; -} - -/*************************************************************************/ -PaError PaHost_Init( void ) -{ - /* we have to create this in order to use BMediaRoster. I hope it doesn't - * cause problems */ - be_app = new BApplication("application/x-vnd.portaudio-app"); - - return paNoError; -} - -PaError PaHost_Term( void ) -{ - delete be_app; - return paNoError; -} - -/*************************************************************************/ -PaError PaHost_StreamActive( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *)past->past_DeviceData; - DBUG(("IsRunning returning: %s\n", - pahsc->pahsc_InputNodeInstance->IsRunning() ? "true" : "false")); - - return (PaError)pahsc->pahsc_InputNodeInstance->IsRunning(); -} - -PaError PaHost_StartOutput( internalPortAudioStream *past ) -{ - return paNoError; -} - -/*************************************************************************/ -PaError PaHost_StartInput( internalPortAudioStream *past ) -{ - return paNoError; -} - -/*************************************************************************/ -PaError PaHost_StopInput( internalPortAudioStream *past, int abort ) -{ - return paNoError; -} - -/*************************************************************************/ -PaError PaHost_StopOutput( internalPortAudioStream *past, int abort ) -{ - return paNoError; -} - - -/*************************************************************************/ -PaError PaHost_StartEngine( internalPortAudioStream *past ) -{ - bigtime_t very_soon, start_latency; - status_t err; - BMediaRoster *roster = BMediaRoster::Roster(&err); - PaHostSoundControl *pahsc = (PaHostSoundControl *)past->past_DeviceData; - - /* for some reason, err indicates an error (though nothing it wrong) - * when the DBUG macro in pa_lib.c is enabled. It's reproducably - * linked. Weird. */ - if( !roster /* || err != B_OK */ ) - { - DBUG(("No media server! err=%d, roster=%x\n", err, roster)); - return paHostError; - } - - /* tell the node when to start -- since there aren't any other nodes - * starting that we have to wait for, just tell it to start now - */ - - BTimeSource *timeSource = roster->MakeTimeSourceFor(pahsc->pahsc_TimeSource); - very_soon = timeSource->PerformanceTimeFor( BTimeSource::RealTime() ); - timeSource->Release(); - - /* Add the latency of starting the network of nodes */ - err = roster->GetStartLatencyFor( pahsc->pahsc_TimeSource, &start_latency ); - very_soon += start_latency; - - err = roster->StartNode( pahsc->pahsc_InputNode, very_soon ); - /* No need to start the mixer -- it's always running */ - - return paNoError; -} - - -/*************************************************************************/ -PaError PaHost_StopEngine( internalPortAudioStream *past, int abort ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *)past->past_DeviceData; - BMediaRoster *roster = BMediaRoster::Roster(); - - if( !roster ) - { - DBUG(("No media roster!\n")); - return paHostError; - } - - if( !pahsc ) - return paHostError; - - /* this crashes, and I don't know why yet */ - // if( abort ) - // pahsc->pahsc_InputNodeInstance->mAborted = true; - - roster->StopNode(pahsc->pahsc_InputNode, 0, /* immediate = */ true); - - return paNoError; -} - - -/*************************************************************************/ -PaError PaHost_OpenStream( internalPortAudioStream *past ) -{ - status_t err; - BMediaRoster *roster = BMediaRoster::Roster(&err); - PaHostSoundControl *pahsc; - - /* Allocate and initialize host data. */ - pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); - if( pahsc == NULL ) - { - goto error; - } - memset( pahsc, 0, sizeof(PaHostSoundControl) ); - past->past_DeviceData = (void *) pahsc; - - if( !roster /* || err != B_OK */ ) - { - /* no media server! */ - DBUG(("No media server.\n")); - goto error; - } - - if ( past->past_NumInputChannels > 0 && past->past_NumOutputChannels > 0 ) - { - /* filter -- not implemented yet */ - goto error; - } - else if ( past->past_NumInputChannels > 0 ) - { - /* recorder -- not implemented yet */ - goto error; - } - else - { - /* player ****************************************************************/ - - status_t err; - int32 num; - - /* First we need to create the three components (like components in a stereo - * system). The mixer component is our interface to the sound card, data - * we write there will get played. The BePA_InputNode component is the node - * which represents communication with the PA client (it is what calls the - * client's callbacks). The time source component is the sound card's DAC, - * which allows us to slave the other components to it instead of the system - * clock. */ - err = roster->GetAudioMixer( &pahsc->pahsc_OutputNode ); - if( err != B_OK ) - { - DBUG(("Couldn't get default mixer.\n")); - goto error; - } - - err = roster->GetTimeSource( &pahsc->pahsc_TimeSource ); - if( err != B_OK ) - { - DBUG(("Couldn't get time source.\n")); - goto error; - } - - pahsc->pahsc_InputNodeInstance = new PaPlaybackNode(2, 44100, - past->past_FramesPerUserBuffer, past->past_Callback, past->past_UserData ); - pahsc->pahsc_InputNodeInstance->SetSampleFormat(0, - past->past_OutputSampleFormat); - err = roster->RegisterNode( pahsc->pahsc_InputNodeInstance ); - if( err != B_OK ) - { - DBUG(("Unable to register node.\n")); - goto error; - } - - roster->GetNodeFor( pahsc->pahsc_InputNodeInstance->Node().node, - &pahsc->pahsc_InputNode ); - if( err != B_OK ) - { - DBUG(("Unable to get input node.\n")); - goto error; - } - - /* Now we have three components (nodes) sitting next to each other. The - * next step is to look at them and find their inputs and outputs so we can - * wire them together. */ - err = roster->GetFreeInputsFor( pahsc->pahsc_OutputNode, - &pahsc->pahsc_MixerInput, 1, &num, B_MEDIA_RAW_AUDIO ); - if( err != B_OK || num < 1 ) - { - DBUG(("Couldn't get the mixer input.\n")); - goto error; - } - - err = roster->GetFreeOutputsFor( pahsc->pahsc_InputNode, - &pahsc->pahsc_PaOutput, 1, &num, B_MEDIA_RAW_AUDIO ); - if( err != B_OK || num < 1 ) - { - DBUG(("Couldn't get PortAudio output.\n")); - goto error; - } - - - /* We've found the input and output -- the final step is to run a wire - * between them so they are connected. */ - - /* try to make the mixer input adapt to what PA sends it */ - pahsc->pahsc_Format = pahsc->pahsc_PaOutput.format; - roster->Connect( pahsc->pahsc_PaOutput.source, - pahsc->pahsc_MixerInput.destination, &pahsc->pahsc_Format, - &pahsc->pahsc_PaOutput, &pahsc->pahsc_MixerInput ); - - - /* Actually, there's one final step -- tell them all to sync to the - * sound card's DAC */ - roster->SetTimeSourceFor( pahsc->pahsc_InputNode.node, - pahsc->pahsc_TimeSource.node ); - roster->SetTimeSourceFor( pahsc->pahsc_OutputNode.node, - pahsc->pahsc_TimeSource.node ); - - } - - return paNoError; - -error: - PaHost_CloseStream( past ); - return paHostError; -} - -/*************************************************************************/ -PaError PaHost_CloseStream( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *)past->past_DeviceData; - status_t err; - BMediaRoster *roster = BMediaRoster::Roster(&err); - - if( !roster ) - { - DBUG(("Couldn't get media roster\n")); - return paHostError; - } - - if( !pahsc ) - return paHostError; - - /* Disconnect all the connections we made when opening the stream */ - - roster->Disconnect(pahsc->pahsc_InputNode.node, pahsc->pahsc_PaOutput.source, - pahsc->pahsc_OutputNode.node, pahsc->pahsc_MixerInput.destination); - - DBUG(("Calling ReleaseNode()")); - roster->ReleaseNode(pahsc->pahsc_InputNode); - - /* deleting the node shouldn't be necessary -- it is reference counted, and will - * delete itself when its references drop to zero. the call to ReleaseNode() - * above should decrease its reference count */ - pahsc->pahsc_InputNodeInstance = NULL; - - return paNoError; -} - -/*************************************************************************/ -PaTimestamp Pa_StreamTime( PortAudioStream *stream ) -{ - internalPortAudioStream *past = (internalPortAudioStream *) stream; - PaHostSoundControl *pahsc = (PaHostSoundControl *)past->past_DeviceData; - - return pahsc->pahsc_InputNodeInstance->GetStreamTime(); -} - -/*************************************************************************/ -void Pa_Sleep( long msec ) -{ - /* snooze() takes microseconds */ - snooze( msec * 1000 ); -} - -/************************************************************************* - * Allocate memory that can be accessed in real-time. - * This may need to be held in physical memory so that it is not - * paged to virtual memory. - * This call MUST be balanced with a call to PaHost_FreeFastMemory(). - * Memory will be set to zero. - */ -void *PaHost_AllocateFastMemory( long numBytes ) -{ - /* BeOS supports non-pagable memory through pools -- a pool is an area - * of physical memory that is locked. It would be best to pre-allocate - * that pool and then hand out memory from it, but we don't know in - * advance how much we'll need. So for now, we'll allocate a pool - * for every request we get, storing a pointer to the pool at the - * beginning of the allocated memory */ - rtm_pool *pool; - void *addr; - long size = numBytes + sizeof(rtm_pool *); - static int counter = 0; - char pool_name[100]; - - /* Every pool needs a unique name. */ - sprintf(pool_name, "PaPoolNumber%d", counter++); - - if( rtm_create_pool( &pool, size, pool_name ) != B_OK ) - return 0; - - addr = rtm_alloc( pool, size ); - if( addr == NULL ) - return 0; - - memset( addr, 0, numBytes ); - *((rtm_pool **)addr) = pool; // store the pointer to the pool - addr = (rtm_pool **)addr + 1; // and return the next location in memory - - return addr; -} - -/************************************************************************* - * Free memory that could be accessed in real-time. - * This call MUST be balanced with a call to PaHost_AllocateFastMemory(). - */ -void PaHost_FreeFastMemory( void *addr, long numBytes ) -{ - rtm_pool *pool; - - if( addr == NULL ) - return; - - addr = (rtm_pool **)addr - 1; - pool = *((rtm_pool **)addr); - - rtm_free( addr ); - rtm_delete_pool( pool ); -} diff --git a/pd/portaudio/pa_common/pa_allocation.c b/pd/portaudio/pa_common/pa_allocation.c deleted file mode 100644 index 5eefeabb..00000000 --- a/pd/portaudio/pa_common/pa_allocation.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Id: - * 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. - */ - -#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 = 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 ) - { - previous->next = current->next; - - current->buffer = 0; - current->next = group->spareLinks; - group->spareLinks = current; - } - 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/pd/portaudio/pa_common/pa_allocation.h b/pd/portaudio/pa_common/pa_allocation.h deleted file mode 100644 index b906c14b..00000000 --- a/pd/portaudio/pa_common/pa_allocation.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef PA_ALLOCATION_H -#define PA_ALLOCATION_H -/* - * Id: - * 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. - */ - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/** @file - 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 -*/ - - - -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/pd/portaudio/pa_common/pa_convert.c b/pd/portaudio/pa_common/pa_convert.c deleted file mode 100644 index 377a9554..00000000 --- a/pd/portaudio/pa_common/pa_convert.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * pa_conversions.c - * portaudio - * - * Created by Phil Burk on Mon Mar 18 2002. - * - */ -#include <stdio.h> - -#include "portaudio.h" -#include "pa_host.h" - -#define CLIP( val, min, max ) { val = ((val) < (min)) ? min : (((val) < (max)) ? (max) : (val)); } - -/*************************************************************************/ -static void PaConvert_Float32_Int16( - float *sourceBuffer, int sourceStride, - short *targetBuffer, int targetStride, - int numSamples ) -{ - int i; - for( i=0; i<numSamples; i++ ) - { - short samp = (short) (*sourceBuffer * (32767.0f)); - *targetBuffer = samp; - sourceBuffer += sourceStride; - targetBuffer += targetStride; - } -} - -/*************************************************************************/ -static void PaConvert_Float32_Int16_Clip( - float *sourceBuffer, int sourceStride, - short *targetBuffer, int targetStride, - int numSamples ) -{ - int i; - for( i=0; i<numSamples; i++ ) - { - long samp = (long) (*sourceBuffer * (32767.0f)); - CLIP( samp, -0x8000, 0x7FFF ); - *targetBuffer = (short) samp; - sourceBuffer += sourceStride; - targetBuffer += targetStride; - } -} - -/*************************************************************************/ -static void PaConvert_Float32_Int16_ClipDither( - float *sourceBuffer, int sourceStride, - short *targetBuffer, int targetStride, - int numSamples ) -{ - int i; - for( i=0; i<numSamples; i++ ) - { - // use smaller scaler to prevent overflow when we add the dither - float dither = PaConvert_TriangularDither() * PA_DITHER_SCALE; - float dithered = (*sourceBuffer * (32766.0f)) + dither; - long samp = (long) dithered; - CLIP( samp, -0x8000, 0x7FFF ); - *targetBuffer = (short) samp; - sourceBuffer += sourceStride; - targetBuffer += targetStride; - } -} - -/*************************************************************************/ -static void PaConvert_Float32_Int16_Dither( - float *sourceBuffer, int sourceStride, - short *targetBuffer, int targetStride, - int numSamples ) -{ - int i; - for( i=0; i<numSamples; i++ ) - { - // use smaller scaler to prevent overflow when we add the dither - float dither = PaConvert_TriangularDither() * PA_DITHER_SCALE; - float dithered = (*sourceBuffer * (32766.0f)) + dither; - *targetBuffer = (short) dithered; - sourceBuffer += sourceStride; - targetBuffer += targetStride; - } -} - - -/*************************************************************************/ -static void PaConvert_Int16_Float32( - short *sourceBuffer, int sourceStride, - float *targetBuffer, int targetStride, - int numSamples ) -{ - int i; - for( i=0; i<numSamples; i++ ) - { - float samp = *sourceBuffer * (1.0f / 32768.0f); - *targetBuffer = samp; - sourceBuffer += sourceStride; - targetBuffer += targetStride; - } -} - -/*************************************************************************/ -static void PaConvert_Float32_Int8( - float *sourceBuffer, int sourceStride, - char *targetBuffer, int targetStride, - int numSamples ) -{ - int i; - for( i=0; i<numSamples; i++ ) - { - char samp = (char) (*sourceBuffer * (127.0)); - *targetBuffer = samp; - sourceBuffer += sourceStride; - targetBuffer += targetStride; - } -} - - -/*************************************************************************/ -static void PaConvert_Float32_Int8_Clip( - float *sourceBuffer, int sourceStride, - char *targetBuffer, int targetStride, - int numSamples ) -{ - int i; - for( i=0; i<numSamples; i++ ) - { - long samp = *sourceBuffer * 127.0f; - CLIP( samp, -0x80, 0x7F ); - *targetBuffer = (char) samp; - sourceBuffer += sourceStride; - targetBuffer += targetStride; - } -} - -/*************************************************************************/ -static void PaConvert_Float32_Int8_ClipDither( - float *sourceBuffer, int sourceStride, - char *targetBuffer, int targetStride, - int numSamples ) -{ - int i; - for( i=0; i<numSamples; i++ ) - { - // use smaller scaler to prevent overflow when we add the dither - float dither = PaConvert_TriangularDither() * PA_DITHER_SCALE; - float dithered = (*sourceBuffer * (126.0f)) + dither; - long samp = (long) dithered; - CLIP( samp, -0x80, 0x7F ); - *targetBuffer = (char) samp; - sourceBuffer += sourceStride; - targetBuffer += targetStride; - } -} - -/*************************************************************************/ -static void PaConvert_Float32_Int8_Dither( - float *sourceBuffer, int sourceStride, - char *targetBuffer, int targetStride, - int numSamples ) -{ - int i; - for( i=0; i<numSamples; i++ ) - { - // use smaller scaler to prevent overflow when we add the dither - float dither = PaConvert_TriangularDither() * PA_DITHER_SCALE; //FIXME - float dithered = (*sourceBuffer * (126.0f)) + dither; - long samp = (long) dithered; - *targetBuffer = (char) samp; - sourceBuffer += sourceStride; - targetBuffer += targetStride; - } -} - -/*************************************************************************/ -static void PaConvert_Int8_Float32( - char *sourceBuffer, int sourceStride, - float *targetBuffer, int targetStride, - int numSamples ) -{ - int i; - for( i=0; i<numSamples; i++ ) - { - float samp = *sourceBuffer * (1.0f / 128.0f); - *targetBuffer = samp; - sourceBuffer += sourceStride; - targetBuffer += targetStride; - } -} - -/*************************************************************************/ -static void PaConvert_Float32_UInt8( - float *sourceBuffer, int sourceStride, - unsigned char *targetBuffer, int targetStride, - int numSamples ) -{ - int i; - for( i=0; i<numSamples; i++ ) - { - unsigned char samp = 128 + (unsigned char) (*sourceBuffer * (127.0)); - *targetBuffer = samp; - sourceBuffer += sourceStride; - targetBuffer += targetStride; - } -} - -/*************************************************************************/ -static void PaConvert_UInt8_Float32( - unsigned char *sourceBuffer, int sourceStride, - float *targetBuffer, int targetStride, - int numSamples ) -{ - int i; - for( i=0; i<numSamples; i++ ) - { - float samp = (*sourceBuffer - 128) * (1.0f / 128.0f); - *targetBuffer = samp; - sourceBuffer += sourceStride; - targetBuffer += targetStride; - } -} - -/*************************************************************************/ -static PortAudioConverter *PaConvert_SelectProc( PaSampleFormat sourceFormat, - PaSampleFormat targetFormat, int ifClip, int ifDither ) -{ - PortAudioConverter *proc = NULL; - switch( sourceFormat ) - { - case paUInt8: - switch( targetFormat ) - { - case paFloat32: - proc = (PortAudioConverter *) PaConvert_UInt8_Float32; - break; - default: - break; - } - break; - case paInt8: - switch( targetFormat ) - { - case paFloat32: - proc = (PortAudioConverter *) PaConvert_Int8_Float32; - break; - default: - break; - } - break; - case paInt16: - switch( targetFormat ) - { - case paFloat32: - proc = (PortAudioConverter *) PaConvert_Int16_Float32; - break; - default: - break; - } - break; - case paFloat32: - switch( targetFormat ) - { - case paUInt8: - proc = (PortAudioConverter *) PaConvert_Float32_UInt8; - break; - case paInt8: - if( ifClip && ifDither ) proc = (PortAudioConverter *) PaConvert_Float32_Int8_ClipDither; - else if( ifClip ) proc = (PortAudioConverter *) PaConvert_Float32_Int8_Clip; - else if( ifDither ) proc = (PortAudioConverter *) PaConvert_Float32_Int8_Dither; - else proc = (PortAudioConverter *) PaConvert_Float32_Int8; - break; - case paInt16: - if( ifClip && ifDither ) proc = (PortAudioConverter *) PaConvert_Float32_Int16_ClipDither; - else if( ifClip ) proc = (PortAudioConverter *) PaConvert_Float32_Int16_Clip; - else if( ifDither ) proc = (PortAudioConverter *) PaConvert_Float32_Int16_Dither; - else proc = (PortAudioConverter *) PaConvert_Float32_Int16; - break; - default: - break; - } - break; - default: - break; - } - return proc; - -} - -/*************************************************************************/ -PaError PaConvert_SetupInput( internalPortAudioStream *past, - PaSampleFormat nativeInputSampleFormat ) -{ - past->past_NativeInputSampleFormat = nativeInputSampleFormat; - past->past_InputConversionSourceStride = 1; - past->past_InputConversionTargetStride = 1; - - if( nativeInputSampleFormat != past->past_InputSampleFormat ) - { - int ifDither = (past->past_Flags & paDitherOff) == 0; - past->past_InputConversionProc = PaConvert_SelectProc( nativeInputSampleFormat, - past->past_InputSampleFormat, 0, ifDither ); - if( past->past_InputConversionProc == NULL ) return paSampleFormatNotSupported; - } - else - { - past->past_InputConversionProc = NULL; /* no conversion necessary */ - } - - return paNoError; -} - -/*************************************************************************/ -PaError PaConvert_SetupOutput( internalPortAudioStream *past, - PaSampleFormat nativeOutputSampleFormat ) -{ - - past->past_NativeOutputSampleFormat = nativeOutputSampleFormat; - past->past_OutputConversionSourceStride = 1; - past->past_OutputConversionTargetStride = 1; - - if( nativeOutputSampleFormat != past->past_OutputSampleFormat ) - { - int ifDither = (past->past_Flags & paDitherOff) == 0; - int ifClip = (past->past_Flags & paClipOff) == 0; - - past->past_OutputConversionProc = PaConvert_SelectProc( past->past_OutputSampleFormat, - nativeOutputSampleFormat, ifClip, ifDither ); - if( past->past_OutputConversionProc == NULL ) return paSampleFormatNotSupported; - } - else - { - past->past_OutputConversionProc = NULL; /* no conversion necessary */ - } - - return paNoError; -} - -/************************************************************************* -** Called by host code. -** Convert input from native format to user format, -** call user code, -** then convert output to native format. -** Returns result from user callback. -*/ -long PaConvert_Process( internalPortAudioStream *past, - void *nativeInputBuffer, - void *nativeOutputBuffer ) -{ - int userResult; - void *inputBuffer = NULL; - void *outputBuffer = NULL; - - /* Get native input data. */ - if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) ) - { - if( past->past_InputSampleFormat == past->past_NativeInputSampleFormat ) - { - /* Already in native format so just read directly from native buffer. */ - inputBuffer = nativeInputBuffer; - } - else - { - inputBuffer = past->past_InputBuffer; - /* Convert input data to user format. */ - (*past->past_InputConversionProc)(nativeInputBuffer, past->past_InputConversionSourceStride, - inputBuffer, past->past_InputConversionTargetStride, - past->past_FramesPerUserBuffer * past->past_NumInputChannels ); - } - } - - /* Are we doing output? */ - if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) ) - { - outputBuffer = (past->past_OutputConversionProc == NULL) ? - nativeOutputBuffer : past->past_OutputBuffer; - } - /* - AddTraceMessage("Pa_CallConvertInt16: inputBuffer = ", (int) inputBuffer ); - AddTraceMessage("Pa_CallConvertInt16: outputBuffer = ", (int) outputBuffer ); - */ - /* Call user callback routine. */ - userResult = past->past_Callback( - inputBuffer, - outputBuffer, - past->past_FramesPerUserBuffer, - past->past_FrameCount, - past->past_UserData ); - - /* Advance frame counter for timestamp. */ - past->past_FrameCount += past->past_FramesPerUserBuffer; // FIXME - should this be in here? - - /* Convert to native format if necessary. */ - if( (past->past_OutputConversionProc != NULL ) && (outputBuffer != NULL) ) - { - (*past->past_OutputConversionProc)( outputBuffer, past->past_OutputConversionSourceStride, - nativeOutputBuffer, past->past_OutputConversionTargetStride, - past->past_FramesPerUserBuffer * past->past_NumOutputChannels ); - } - - return userResult; -} diff --git a/pd/portaudio/pa_common/pa_converters.c b/pd/portaudio/pa_common/pa_converters.c deleted file mode 100644 index 39e5e47f..00000000 --- a/pd/portaudio/pa_common/pa_converters.c +++ /dev/null @@ -1,1653 +0,0 @@ -/* - * $Id: pa_converters.c,v 1.1.2.13 2003/02/28 01:49:59 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 - - @todo implement the converters marked IMPLEMENT ME: Float32_To_UInt8_Dither, - Float32_To_UInt8_Clip, Float32_To_UInt8_DitherClip, Int32_To_Int24, - Int32_To_Int24_Dither, Int32_To_Int16, Int32_To_Int16_Dither, Int32_To_Int8, - Int32_To_Int8_Dither, Int32_To_UInt8, Int32_To_UInt8_Dither, Int24_To_Int32, - Int24_To_Int16, Int24_To_Int16_Dither, Int24_To_Int8, Int24_To_Int8_Dither, - Int24_To_UInt8, Int24_To_UInt8_Dither, Int16_To_Int32, Int16_To_Int24, - Int16_To_Int8, Int16_To_Int8_Dither, Int16_To_UInt8, Int16_To_UInt8_Dither, - Int8_To_Int32, Int8_To_Int24, Int8_To_Int16, Int8_To_UInt8, UInt8_To_Int32, - UInt8_To_Int24, UInt8_To_Int16, UInt8_To_Int8 - - @todo review the converters marked REVIEW: Float32_To_Int32, - Float32_To_Int32_Dither, Float32_To_Int32_Clip, Float32_To_Int32_DitherClip -*/ - - -#include "pa_converters.h" -#include "pa_dither.h" -#include "pa_endianness.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; - 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; - } -} - -/* -------------------------------------------------------------------------- */ - -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; - 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; - *dest = (signed long) dithered; - - 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; - 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; - } -} - -/* -------------------------------------------------------------------------- */ - -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; - 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; - } -} - -/* -------------------------------------------------------------------------- */ - -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; - 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; - -#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; - signed long 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 = (signed long) 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; - 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; - -#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; - signed long 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 = (signed long) 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; - signed short *dest = (signed short*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - short samp = (short) (*src * (32767.0f)); - *dest = samp; - - 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; - signed short *dest = (signed short*)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; - *dest = (signed short) dithered; - - 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; - 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; - } -} - -/* -------------------------------------------------------------------------- */ - -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; - 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; - } -} - -/* -------------------------------------------------------------------------- */ - -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; - signed long samp = (signed long) 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-- ) - { - signed long samp = (signed long)(*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; - signed long samp = (signed long) 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 ) -{ - signed long *src = (signed long*)sourceBuffer; - float *dest = (float*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - *dest = (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 ) -{ - (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_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 ) -{ - signed long *src = (signed long*)sourceBuffer; - signed short *dest = (signed short*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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 ) -{ - signed long *src = (signed long*)sourceBuffer; - signed short *dest = (signed short*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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 ) -{ - signed long *src = (signed long*)sourceBuffer; - signed char *dest = (signed char*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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 ) -{ - signed long *src = (signed long*)sourceBuffer; - signed char *dest = (signed char*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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 ) -{ - signed long *src = (signed long*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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 ) -{ - signed long *src = (signed long*)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; - signed long 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 = (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 ) -{ - (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_Int16( - 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_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 ) -{ - (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_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 ) -{ - (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_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 ) -{ - signed short *src = (signed short*)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 ) -{ - signed short *src = (signed short*)sourceBuffer; - signed long *dest = (signed long*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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 ) -{ - (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_Int8( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - signed short *src = (signed short*)sourceBuffer; - signed char *dest = (signed char*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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 ) -{ - signed short *src = (signed short*)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 ) -{ - signed short *src = (signed short*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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 ) -{ - signed short *src = (signed short*)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; - signed long *dest = (signed long*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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-- ) - { - - /* IMPLEMENT ME */ - - 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; - signed short *dest = (signed short*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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-- ) - { - - /* IMPLEMENT ME */ - - 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; - signed long *dest = (signed long*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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 ) -{ - (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 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; - signed short *dest = (signed short*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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; - float *dest = (float*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - - /* IMPLEMENT ME */ - - 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 ) -{ - unsigned short *src = (unsigned short*)sourceBuffer; - unsigned short *dest = (unsigned short*)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 ) -{ - unsigned long *dest = (unsigned long*)destinationBuffer; - unsigned long *src = (unsigned long*)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 */ diff --git a/pd/portaudio/pa_common/pa_converters.h b/pd/portaudio/pa_common/pa_converters.h deleted file mode 100644 index 8fa0fda7..00000000 --- a/pd/portaudio/pa_common/pa_converters.h +++ /dev/null @@ -1,197 +0,0 @@ -#ifndef PA_CONVERTERS_H -#define PA_CONVERTERS_H -/* - * $Id: pa_converters.h,v 1.1.2.7 2002/10/22 08:58:17 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. - */ - -#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 PaUtil_Converter 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 ); - - -/* low level functions and data structures which may be used for - substituting additional 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; - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PA_CONVERTERS_H */ diff --git a/pd/portaudio/pa_common/pa_cpuload.c b/pd/portaudio/pa_common/pa_cpuload.c deleted file mode 100644 index bce82aff..00000000 --- a/pd/portaudio/pa_common/pa_cpuload.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * $Id: pa_cpuload.c,v 1.1.2.9 2002/10/22 08:58:17 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. - */ - -#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; -} - - -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. */ -#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/pd/portaudio/pa_common/pa_cpuload.h b/pd/portaudio/pa_common/pa_cpuload.h deleted file mode 100644 index 28c4c29a..00000000 --- a/pd/portaudio/pa_common/pa_cpuload.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef PA_CPULOAD_H -#define PA_CPULOAD_H -/* - * $Id: pa_cpuload.h,v 1.1.2.8 2002/10/22 08:58:17 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. - */ - -#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 ); -double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer ); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PA_CPULOAD_H */ diff --git a/pd/portaudio/pa_common/pa_dither.c b/pd/portaudio/pa_common/pa_dither.c deleted file mode 100644 index 10f43e69..00000000 --- a/pd/portaudio/pa_common/pa_dither.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * $Id: pa_dither.c,v 1.1.2.3 2002/06/16 13:11: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. - */ - -#include "pa_dither.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_ ((32 - 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_ ((32 - 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_; -} diff --git a/pd/portaudio/pa_common/pa_dither.h b/pd/portaudio/pa_common/pa_dither.h deleted file mode 100644 index 97116f0f..00000000 --- a/pd/portaudio/pa_common/pa_dither.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef PA_DITHER_H -#define PA_DITHER_H -/* - * $Id: pa_dither.h,v 1.1.2.2 2002/06/05 22:37:03 rossb 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. - */ - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - - -typedef struct PaUtilTriangularDitherGenerator{ - unsigned long previous; - unsigned long randSeed1; - unsigned long randSeed2; -} PaUtilTriangularDitherGenerator; -/**< State needed to generate a dither signal */ - - -void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *ditherState ); -/**< Initialize dither state */ - -signed long PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *ditherState ); -/**< - 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 -*/ - - -float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *ditherState ); -/**< - 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. -*/ - - - -/* -The following alternate dither algorithms are known... -*/ - -/*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; -} -*/ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PA_DITHER_H */ diff --git a/pd/portaudio/pa_common/pa_endianness.h b/pd/portaudio/pa_common/pa_endianness.h deleted file mode 100644 index aaccaf75..00000000 --- a/pd/portaudio/pa_common/pa_endianness.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef PA_ENDIANNESS_H -#define PA_ENDIANNESS_H -/* - * $Id: pa_endianness.h,v 1.1.2.1 2003/02/28 01:49:59 rossbencina 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. - */ - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/** @file - 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. -*/ - - -#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 */ - - #ifdef WIN32 - - #define PA_LITTLE_ENDIAN /* win32, assume intel byte order */ - - #else - -#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( "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( "compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 0 ); \ - } -#endif - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PA_ENDIANNESS_H */ diff --git a/pd/portaudio/pa_common/pa_front.c b/pd/portaudio/pa_common/pa_front.c deleted file mode 100644 index 27293b20..00000000 --- a/pd/portaudio/pa_common/pa_front.c +++ /dev/null @@ -1,1884 +0,0 @@ -/* - * $Id: pa_front.c,v 1.1.2.36 2003/02/28 01:49:59 rossbencina 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 documented in portaudio.h - -- The possibly incomplete and totally unorganised <a href="todo.html">Todo List</a> -*/ - -#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_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 as follows: - - - entry (void function): - - "FunctionName called.\n" - - - entry (non void function): - - "FunctionName called:\n" - "\tParam1Type param1: param1Value\n" - "\tParam2Type param2: param2Value\n" (etc...) - - - - exit (no return value) - - "FunctionName returned.\n" - - - 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 for more detailed 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_ = { -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_ = 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_] ) - { - - 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_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 errorNumber ) -{ - const char *result; - - switch( errorNumber ) - { - 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; - 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("\PaHostApiTypeId type: %d\n", type ); -#endif - - if( !PA_IS_INITIALISED_ ) - { - - result = -1; - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_HostApiTypeIdToHostApiIndex returned:\n" ); - PaUtil_DebugPrint("\tPaHostApiIndex: -1 [ PortAudio not initialized ]\n\n" ); -#endif - - } - else - { - result = -1; - - 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" ); - 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 = paInternalError; /* @todo should return host API not found */ - - 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_CountHostApis( void ) -{ - int result; - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_CountHostApis called.\n" ); -#endif - - if( !PA_IS_INITIALISED_ ) - { - result = paNotInitialized; - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_CountHostApis returned:\n" ); - PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) ); -#endif - - return result; - } - else - { - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_CountHostApis returned:\n" ); - PaUtil_DebugPrint("\tPaHostApiIndex %d\n\n", hostApisCount_ ); -#endif - - return hostApisCount_; - } -} - - -PaHostApiIndex Pa_GetDefaultHostApi( void ) -{ - int result; - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_GetDefaultHostApi called.\n" ); -#endif - - if( !PA_IS_INITIALISED_ ) - { - result = paNotInitialized; - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_GetDefaultHostApi returned:\n" ); - PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) ); -#endif - - return result; - } - 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" ); - PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) ); -#endif - } - else - { -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_GetDefaultHostApi returned:\n" ); - 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 = paNoDevice; - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_HostApiDeviceIndexToPaDeviceIndex returned:\n" ); - PaUtil_DebugPrint("\tPaDeviceIndex: paNoDevice [ PortAudio not initialized ]\n\n" ); -#endif - - } - else - { - if( hostApi < 0 || hostApi >= hostApisCount_ ) - { - result = paNoDevice; - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_HostApiDeviceIndexToPaDeviceIndex returned:\n" ); - PaUtil_DebugPrint("\tPaDeviceIndex: paNoDevice [ hostApi out of range ]\n\n" ); -#endif - - } - else - { - if( hostApiDeviceIndex < 0 || - hostApiDeviceIndex >= hostApis_[hostApi]->info.deviceCount ) - { - result = paNoDevice; - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_HostApiDeviceIndexToPaDeviceIndex returned:\n" ); - PaUtil_DebugPrint("\tPaDeviceIndex: paNoDevice [ hostApiDeviceIndex out of range ]\n\n" ); -#endif - - } - else - { - result = hostApis_[hostApi]->privatePaFrontInfo.baseDeviceIndex + hostApiDeviceIndex; - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_HostApiDeviceIndexToPaDeviceIndex returned:\n" ); - PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result ); -#endif - } - } - } - - return result; -} - - -PaDeviceIndex Pa_CountDevices( void ) -{ - PaDeviceIndex result; - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_CountDevices called.\n" ); -#endif - - if( !PA_IS_INITIALISED_ ) - { - result = 0; - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_CountDevices returned:\n" ); - PaUtil_DebugPrint("\tPaDeviceIndex: 0 [ PortAudio not initialized ]\n\n" ); -#endif - - } - else - { - result = deviceCount_; - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_CountDevices returned:\n" ); - 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{" ); - - 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 & 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->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_CountDevices-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 -*/ -static PaError ValidateOpenStreamParameters( - const PaStreamParameters *inputParameters, - const PaStreamParameters *outputParameters, - double sampleRate, - PaStreamFlags streamFlags, - PaUtilHostApiRepresentation **hostApi, - PaDeviceIndex *hostApiInputDevice, - PaDeviceIndex *hostApiOutputDevice ) -{ - int inputHostApiIndex=0, outputHostApiIndex=0; - - 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*)inputParameters->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; - - 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("\PaStreamParameters *inputParameters: NULL\n" ); - }else{ - PaUtil_DebugPrint("\PaStreamParameters *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("\PaStreamParameters *outputParameters: NULL\n" ); - }else{ - PaUtil_DebugPrint("\PaStreamParameters *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, paNoFlag, - &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("\PaStreamParameters *inputParameters: NULL\n" ); - }else{ - PaUtil_DebugPrint("\PaStreamParameters *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("\PaStreamParameters *outputParameters: NULL\n" ); - }else{ - PaUtil_DebugPrint("\PaStreamParameters *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. */ - - 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, streamFlags, - &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; - hostApiInputParameters.suggestedLatency = /* REVIEW: should we be using high input latency here? */ - 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; - hostApiOutputParameters.suggestedLatency = /* REVIEW: should we be using high input latency here? */ - 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; -} - - -static PaError ValidateStream( 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 = ValidateStream( 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); - if( !interface->IsStopped( stream ) ) - { - result = interface->Abort( stream ); - } - - if( result == paNoError ) /* 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 = ValidateStream( 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 ) - { - if( !PA_STREAM_INTERFACE(stream)->IsStopped( stream ) ) - { - result = paStreamIsNotStopped ; - } - else - { - PA_STREAM_REP( stream )->streamFinishedCallback = streamFinishedCallback; - } - } - -#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 = ValidateStream( stream ); - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_StartStream called:\n" ); - PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream ); -#endif - - if( result == paNoError ) - { - if( !PA_STREAM_INTERFACE(stream)->IsStopped( stream ) ) - { - result = paStreamIsNotStopped ; - } - else - { - 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 = ValidateStream( stream ); - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_StopStream called\n" ); - PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream ); -#endif - - if( result == paNoError ) - { - if( PA_STREAM_INTERFACE(stream)->IsStopped( stream ) ) - { - result = paStreamIsStopped; - } - else - { - result = PA_STREAM_INTERFACE(stream)->Stop( stream ); - } - } - -#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 = ValidateStream( stream ); - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_AbortStream called:\n" ); - PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream ); -#endif - - if( result == paNoError ) - { - if( PA_STREAM_INTERFACE(stream)->IsStopped( stream ) ) - { - result = paStreamIsStopped; - } - else - { - result = PA_STREAM_INTERFACE(stream)->Abort( stream ); - } - } - -#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 = ValidateStream( 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 = ValidateStream( 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 = ValidateStream( 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("\const 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 = ValidateStream( 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 = ValidateStream( 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 = ValidateStream( stream ); - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_ReadStream called:\n" ); - PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream ); -#endif - - /* @todo should return an error if buffer is zero or frames <= 0 */ - if( frames > 0 && buffer != 0 ) - result = PA_STREAM_INTERFACE(stream)->Read( stream, buffer, frames ); - -#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, - void *buffer, - unsigned long frames ) -{ - PaError result = ValidateStream( stream ); - -#ifdef PA_LOG_API_CALLS - PaUtil_DebugPrint("Pa_WriteStream called:\n" ); - PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream ); -#endif - - /* @todo should return an error if buffer is zero or frames <= 0 */ - if( frames > 0 && buffer != 0 ) - result = PA_STREAM_INTERFACE(stream)->Write( stream, buffer, frames ); - -#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 = ValidateStream( 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 = ValidateStream( 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/pd/portaudio/pa_common/pa_host.h b/pd/portaudio/pa_common/pa_host.h deleted file mode 100644 index d9cd71ab..00000000 --- a/pd/portaudio/pa_common/pa_host.h +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef PA_HOST_H -#define PA_HOST_H - -/* - * $Id: pa_host.h,v 1.1.1.1 2002-07-29 17:06:18 ggeiger Exp $ - * Host dependant internal API for PortAudio - * - * Author: Phil Burk <philburk@softsynth.com> - * - * PortAudio Portable Real-Time Audio Library - * Latest Version at: http://www.softsynth.com/portaudio/ - * DirectSound and Macintosh Implementation - * Copyright (c) 1999-2000 Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "portaudio.h" - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -#ifndef SUPPORT_AUDIO_CAPTURE -#define SUPPORT_AUDIO_CAPTURE (1) -#endif - -#ifndef int32 - typedef long int32; -#endif -#ifndef uint32 - typedef unsigned long uint32; -#endif -#ifndef int16 - typedef short int16; -#endif -#ifndef uint16 - typedef unsigned short uint16; -#endif - -/* Used to convert between various sample formats. */ -typedef void (PortAudioConverter)( - void *inputBuffer, int inputStride, - void *outputBuffer, int outputStride, - int numSamples ); - -#define PA_MAGIC (0x18273645) - -/************************************************************************************/ -/****************** Structures ******************************************************/ -/************************************************************************************/ - -typedef struct internalPortAudioStream -{ - uint32 past_Magic; /* ID for struct to catch bugs. */ - /* User specified information. */ - uint32 past_FramesPerUserBuffer; - uint32 past_NumUserBuffers; - double past_SampleRate; /* Closest supported sample rate. */ - int past_NumInputChannels; - int past_NumOutputChannels; - PaDeviceID past_InputDeviceID; - PaDeviceID past_OutputDeviceID; - PaSampleFormat past_NativeInputSampleFormat; - PaSampleFormat past_InputSampleFormat; - PaSampleFormat past_NativeOutputSampleFormat; - PaSampleFormat past_OutputSampleFormat; - void *past_DeviceData; - PortAudioCallback *past_Callback; - void *past_UserData; - uint32 past_Flags; - /* Flags for communicating between foreground and background. */ - volatile int past_IsActive; /* Background is still playing. */ - volatile int past_StopSoon; /* Background should keep playing when buffers empty. */ - volatile int past_StopNow; /* Background should stop playing now. */ - /* These buffers are used when the native format does not match the user format. */ - void *past_InputBuffer; - uint32 past_InputBufferSize; - void *past_OutputBuffer; - uint32 past_OutputBufferSize; - /* Measurements */ - uint32 past_NumCallbacks; - PaTimestamp past_FrameCount; /* Frames output to buffer. */ - /* For measuring CPU utilization. */ - double past_AverageInsideCount; - double past_AverageTotalCount; - double past_Usage; - int past_IfLastExitValid; - /* Format Conversion */ - /* These are setup by PaConversion_Setup() */ - PortAudioConverter *past_InputConversionProc; - int past_InputConversionSourceStride; - int past_InputConversionTargetStride; - PortAudioConverter *past_OutputConversionProc; - int past_OutputConversionSourceStride; - int past_OutputConversionTargetStride; -} -internalPortAudioStream; - -/************************************************************************************/ -/******** These functions must be provided by a platform implementation. ************/ -/************************************************************************************/ - -PaError PaHost_Init( void ); -PaError PaHost_Term( void ); - -PaError PaHost_OpenStream( internalPortAudioStream *past ); -PaError PaHost_CloseStream( internalPortAudioStream *past ); - -PaError PaHost_StartOutput( internalPortAudioStream *past ); -PaError PaHost_StopOutput( internalPortAudioStream *past, int abort ); -PaError PaHost_StartInput( internalPortAudioStream *past ); -PaError PaHost_StopInput( internalPortAudioStream *past, int abort ); -PaError PaHost_StartEngine( internalPortAudioStream *past ); -PaError PaHost_StopEngine( internalPortAudioStream *past, int abort ); -PaError PaHost_StreamActive( internalPortAudioStream *past ); - -void *PaHost_AllocateFastMemory( long numBytes ); -void PaHost_FreeFastMemory( void *addr, long numBytes ); - -/* This only called if PA_VALIDATE_RATE IS CALLED. */ -PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate, - double *closestFrameRatePtr ); - -/**********************************************************************/ -/************ Common Utility Routines provided by PA ******************/ -/**********************************************************************/ - -/* PaHost_IsInitialized() returns non-zero if PA is initialized, 0 otherwise */ -int PaHost_IsInitialized( void ); - -internalPortAudioStream* PaHost_GetStreamRepresentation( PortAudioStream *stream ); - -int PaHost_FindClosestTableEntry( double allowableError, const double *rateTable, - int numRates, double frameRate ); - -long Pa_CallConvertInt16( internalPortAudioStream *past, - short *nativeInputBuffer, - short *nativeOutputBuffer ); - -/* Calculate 2 LSB dither signal with a triangular distribution. -** Ranged properly for adding to a 32 bit 1.31 fixed point value prior to >>15. -** Range of output is +/- 65535 -** Multiply by PA_DITHER_SCALE to get a float between -2.0 and 2.0. */ -#define PA_DITHER_BITS (15) -#define PA_DITHER_SCALE (1.0f / ((1<<PA_DITHER_BITS)-1)) -long PaConvert_TriangularDither( void ); - -PaError PaConvert_SetupInput( internalPortAudioStream *past, - PaSampleFormat nativeInputSampleFormat ); - -PaError PaConvert_SetupOutput( internalPortAudioStream *past, - PaSampleFormat nativeOutputSampleFormat ); - -long PaConvert_Process( internalPortAudioStream *past, - void *nativeInputBuffer, - void *nativeOutputBuffer ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PA_HOST_H */ diff --git a/pd/portaudio/pa_common/pa_hostapi.h b/pd/portaudio/pa_common/pa_hostapi.h deleted file mode 100644 index f1f7a7ea..00000000 --- a/pd/portaudio/pa_common/pa_hostapi.h +++ /dev/null @@ -1,238 +0,0 @@ -#ifndef PA_HOSTAPI_H -#define PA_HOSTAPI_H -/* - * - * 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 - Virtualised host api mechanism used by pa_front. -*/ - -#include "portaudio.h" - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - - -typedef struct PaUtilPrivatePaFrontHostApiInfo { -/* **for the use of pa_front.c only** - don't 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 -*/ - - 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; - - - -/* - PaUtilHostApiRepresentation must be implemented by each host api implementation. - -*/ - -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 indicies within the host api's own - device index range (0 to deviceCount). These values will be converted - to global device indicies 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 - - [*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; - - -/** - every host api implementation must supply a host api initializer in the - following form. -*/ -typedef PaError PaUtilHostApiInitializer( PaUtilHostApiRepresentation**, PaHostApiIndex ); - - -/** - paHostApiInitializers is a NULL-terminated array of host api initializers - for the host apis which will be initialized when Pa_Initialize() is called. - each platform has a file which defines paHostApiInitializers for that platform. - see pa_win_init.c for example. -*/ -extern PaUtilHostApiInitializer *paHostApiInitializers[]; - - -/** index of the default host API in the paHostApiInitializers array. Each - platform has a file which defines paDefaultHostApiIndex for that platform. - see pa_win_init.c for example. -*/ -extern int paDefaultHostApiIndex; - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PA_HOSTAPI_H */ diff --git a/pd/portaudio/pa_common/pa_lib.c b/pd/portaudio/pa_common/pa_lib.c deleted file mode 100644 index ade2d82b..00000000 --- a/pd/portaudio/pa_common/pa_lib.c +++ /dev/null @@ -1,806 +0,0 @@ -/* - * $Id: pa_lib.c,v 1.1.1.1 2002-07-29 17:06:18 ggeiger Exp $ - * Portable Audio I/O Library - * Host Independant Layer - * - * Based on the Open Source API proposed by Ross Bencina - * Copyright (c) 1999-2000 Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/* Modification History: - PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC - PLB20010820 - fix dither and shift for recording PaUInt8 format -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> - -/* PLB20010422 - "memory.h" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */ -#ifdef _WIN32 -#ifndef __MWERKS__ -#include <memory.h> -#endif /* __MWERKS__ */ -#else /* !_WIN32 */ -#include <memory.h> -#endif /* _WIN32 */ - -#include "portaudio.h" -#include "pa_host.h" -#include "pa_trace.h" - -/* The reason we might NOT want to validate the rate before opening the stream - * is because many DirectSound drivers lie about the rates they actually support. - */ -#define PA_VALIDATE_RATE (0) /* If true validate sample rate against driver info. */ - -/* -O- maybe not allocate past_InputBuffer and past_OutputBuffer if not needed for conversion -*/ - -#ifndef FALSE - #define FALSE (0) - #define TRUE (!FALSE) -#endif - -#define PRINT(x) { printf x; fflush(stdout); } -#define ERR_RPT(x) PRINT(x) -#define DBUG(x) /* PRINT(x) */ -#define DBUGX(x) /* PRINT(x) */ - -static int gInitCount = 0; /* Count number of times Pa_Initialize() called to allow nesting and overlapping. */ - -static PaError Pa_KillStream( PortAudioStream *stream, int abort ); - -/***********************************************************************/ -int PaHost_FindClosestTableEntry( double allowableError, const double *rateTable, int numRates, double frameRate ) -{ - double err, minErr = allowableError; - int i, bestFit = -1; - - for( i=0; i<numRates; i++ ) - { - err = fabs( frameRate - rateTable[i] ); - if( err < minErr ) - { - minErr = err; - bestFit = i; - } - } - return bestFit; -} - -/************************************************************************** -** Make sure sample rate is legal and also convert to enumeration for driver. -*/ -PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate, - double *closestFrameRatePtr ) -{ - 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; -} - -/*************************************************************************/ -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() MUST CHECK FOR ZERO! */ - past->past_Callback = callback; - past->past_UserData = userData; - past->past_OutputSampleFormat = outputSampleFormat; - past->past_InputSampleFormat = inputSampleFormat; - past->past_OutputDeviceID = outputDeviceID; - past->past_InputDeviceID = inputDeviceID; - past->past_NumInputChannels = numInputChannels; - past->past_NumOutputChannels = numOutputChannels; - past->past_Flags = streamFlags; - - /* Check for absurd sample rates. */ - if( (sampleRate < 1000.0) || (sampleRate > 200000.0) ) - { - result = paInvalidSampleRate; - goto cleanup; - } - - /* Allocate buffers that may be used for format conversion from user to native buffers. */ - if( numInputChannels > 0 ) - { - -#if PA_VALIDATE_RATE - result = PaHost_ValidateSampleRate( inputDeviceID, sampleRate, &past->past_SampleRate ); - if( result < 0 ) - { - goto cleanup; - } -#else - past->past_SampleRate = sampleRate; -#endif - /* Allocate single Input buffer for passing formatted samples to user callback. */ - past->past_InputBufferSize = framesPerBuffer * numInputChannels * ((bitsPerInputSample+7) / 8); - past->past_InputBuffer = PaHost_AllocateFastMemory(past->past_InputBufferSize); - if( past->past_InputBuffer == NULL ) - { - result = paInsufficientMemory; - goto cleanup; - } - } - else - { - past->past_InputBuffer = NULL; - } - - /* Allocate single Output buffer. */ - if( numOutputChannels > 0 ) - { -#if PA_VALIDATE_RATE - result = PaHost_ValidateSampleRate( outputDeviceID, sampleRate, &past->past_SampleRate ); - if( result < 0 ) - { - goto cleanup; - } -#else - past->past_SampleRate = sampleRate; -#endif - past->past_OutputBufferSize = framesPerBuffer * numOutputChannels * ((bitsPerOutputSample+7) / 8); - past->past_OutputBuffer = PaHost_AllocateFastMemory(past->past_OutputBufferSize); - if( past->past_OutputBuffer == NULL ) - { - result = paInsufficientMemory; - goto cleanup; - } - } - else - { - past->past_OutputBuffer = NULL; - } - - result = PaHost_OpenStream( past ); - if( result < 0 ) goto cleanup; - - *streamPtrPtr = (void *) past; - - return result; - -cleanup: - if( past != NULL ) Pa_CloseStream( past ); - *streamPtrPtr = NULL; - return result; -} - - -/*************************************************************************/ -PaError Pa_OpenDefaultStream( PortAudioStream** stream, - int numInputChannels, - int numOutputChannels, - PaSampleFormat sampleFormat, - double sampleRate, - 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 ); -} - -/*************************************************************************/ -PaError Pa_CloseStream( PortAudioStream* stream) -{ - PaError result; - internalPortAudioStream *past; - - DBUG(("Pa_CloseStream()\n")); - if( stream == NULL ) return paBadStreamPtr; - past = (internalPortAudioStream *) stream; - - Pa_AbortStream( past ); - result = PaHost_CloseStream( past ); - - if( past->past_InputBuffer ) PaHost_FreeFastMemory( past->past_InputBuffer, past->past_InputBufferSize ); - if( past->past_OutputBuffer ) PaHost_FreeFastMemory( past->past_OutputBuffer, past->past_OutputBufferSize ); - PaHost_FreeFastMemory( past, sizeof(internalPortAudioStream) ); - - return result; -} - -/*************************************************************************/ -PaError Pa_StartStream( PortAudioStream *stream ) -{ - PaError result = paHostError; - internalPortAudioStream *past; - - if( stream == NULL ) return paBadStreamPtr; - past = (internalPortAudioStream *) stream; - - past->past_FrameCount = 0.0; - - if( past->past_NumInputChannels > 0 ) - { - result = PaHost_StartInput( past ); - DBUG(("Pa_StartStream: PaHost_StartInput returned = 0x%X.\n", result)); - if( result < 0 ) goto error; - } - - if( past->past_NumOutputChannels > 0 ) - { - result = PaHost_StartOutput( past ); - DBUG(("Pa_StartStream: PaHost_StartOutput returned = 0x%X.\n", result)); - if( result < 0 ) goto error; - } - - result = PaHost_StartEngine( past ); - DBUG(("Pa_StartStream: PaHost_StartEngine returned = 0x%X.\n", result)); - if( result < 0 ) goto error; - - return paNoError; - -error: - return result; -} - -/*************************************************************************/ -PaError Pa_StopStream( PortAudioStream *stream ) -{ - return Pa_KillStream( stream, 0 ); -} - -/*************************************************************************/ -PaError Pa_AbortStream( PortAudioStream *stream ) -{ - return Pa_KillStream( stream, 1 ); -} - -/*************************************************************************/ -static PaError Pa_KillStream( PortAudioStream *stream, int abort ) -{ - PaError result = paNoError; - internalPortAudioStream *past; - - DBUG(("Pa_StopStream().\n")); - if( stream == NULL ) return paBadStreamPtr; - past = (internalPortAudioStream *) stream; - - if( (past->past_NumInputChannels > 0) || (past->past_NumOutputChannels > 0) ) - { - result = PaHost_StopEngine( past, abort ); - DBUG(("Pa_StopStream: PaHost_StopEngine returned = 0x%X.\n", result)); - if( result < 0 ) goto error; - } - - if( past->past_NumInputChannels > 0 ) - { - result = PaHost_StopInput( past, abort ); - DBUG(("Pa_StopStream: PaHost_StopInput returned = 0x%X.\n", result)); - if( result != paNoError ) goto error; - } - - if( past->past_NumOutputChannels > 0 ) - { - result = PaHost_StopOutput( past, abort ); - DBUG(("Pa_StopStream: PaHost_StopOutput returned = 0x%X.\n", result)); - if( result != paNoError ) goto error; - } - -error: - past->past_Usage = 0; - past->past_IfLastExitValid = 0; - - return result; -} - -/*************************************************************************/ -PaError Pa_StreamActive( PortAudioStream *stream ) -{ - internalPortAudioStream *past; - if( stream == NULL ) return paBadStreamPtr; - past = (internalPortAudioStream *) stream; - return PaHost_StreamActive( past ); -} - -/*************************************************************************/ -const char *Pa_GetErrorText( PaError errnum ) -{ - const char *msg; - - switch(errnum) - { - case paNoError: msg = "Success"; break; - case paHostError: msg = "Host error."; break; - case paInvalidChannelCount: msg = "Invalid number of channels."; break; - case paInvalidSampleRate: msg = "Invalid sample rate."; break; - case paInvalidDeviceId: msg = "Invalid device ID."; break; - case paInvalidFlag: msg = "Invalid flag."; break; - case paSampleFormatNotSupported: msg = "Sample format not supported"; break; - case paBadIODeviceCombination: msg = "Illegal combination of I/O devices."; break; - case paInsufficientMemory: msg = "Insufficient memory."; break; - case paBufferTooBig: msg = "Buffer too big."; break; - case paBufferTooSmall: msg = "Buffer too small."; break; - case paNullCallback: msg = "No callback routine specified."; break; - case paBadStreamPtr: msg = "Invalid stream pointer."; break; - case paTimedOut : msg = "Wait Timed Out."; break; - case paInternalError: msg = "Internal PortAudio Error."; break; - case paDeviceUnavailable: msg = "Device Unavailable."; break; - default: msg = "Illegal error number."; break; - } - return msg; -} - -/* - Get CPU Load as a fraction of total CPU time. - A value of 0.5 would imply that PortAudio and the sound generating - callback was consuming roughly 50% of the available CPU time. - The amount may vary depending on CPU load. - This function may be called from the callback function. -*/ -double Pa_GetCPULoad( PortAudioStream* stream) -{ - internalPortAudioStream *past; - if( stream == NULL ) return (double) paBadStreamPtr; - past = (internalPortAudioStream *) stream; - return past->past_Usage; -} - -/*************************************************************************/ -internalPortAudioStream* PaHost_GetStreamRepresentation( PortAudioStream *stream ) -{ - internalPortAudioStream* result = (internalPortAudioStream*) stream; - - if( result == NULL || result->past_Magic != PA_MAGIC ) - return NULL; - else - return result; -} - -/************************************************************* -** Calculate 2 LSB dither signal with a triangular distribution. -** Ranged properly for adding to a 32 bit integer prior to >>15. -** Range of output is +/- 32767 -*/ -#define PA_DITHER_BITS (15) -#define PA_DITHER_SCALE (1.0f / ((1<<PA_DITHER_BITS)-1)) -long PaConvert_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. - * Shift before adding to prevent overflow which would skew the distribution. - * Also shift an extra bit for the high pass filter. - */ -#define DITHER_SHIFT ((32 - PA_DITHER_BITS) + 1) - current = (((long)randSeed1)>>DITHER_SHIFT) + (((long)randSeed2)>>DITHER_SHIFT); - /* High pass filter to reduce audibility. */ - highPass = current - previous; - previous = current; - return highPass; -} - -/************************************************************************* -** Called by host code. -** Convert input from Int16, call user code, then convert output -** to Int16 format for native use. -** Assumes host native format is paInt16. -** Returns result from user callback. -*/ -long Pa_CallConvertInt16( internalPortAudioStream *past, - short *nativeInputBuffer, - short *nativeOutputBuffer ) -{ - long temp; - int userResult; - unsigned int i; - void *inputBuffer = NULL; - void *outputBuffer = NULL; - -#if SUPPORT_AUDIO_CAPTURE - /* Get native data from DirectSound. */ - if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) ) - { - /* Convert from native format to PA format. */ - unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels; - switch(past->past_InputSampleFormat) - { - - case paFloat32: - { - float *inBufPtr = (float *) past->past_InputBuffer; - inputBuffer = past->past_InputBuffer; - for( i=0; i<samplesPerBuffer; i++ ) - { - inBufPtr[i] = nativeInputBuffer[i] * (1.0f / 32767.0f); - } - break; - } - - case paInt32: - { - /* Convert 16 bit data to 32 bit integers */ - int *inBufPtr = (int *) past->past_InputBuffer; - inputBuffer = past->past_InputBuffer; - for( i=0; i<samplesPerBuffer; i++ ) - { - inBufPtr[i] = nativeInputBuffer[i] << 16; - } - break; - } - - case paInt16: - { - /* Already in correct format so don't copy. */ - inputBuffer = nativeInputBuffer; - break; - } - - case paInt8: - { - /* Convert 16 bit data to 8 bit chars */ - char *inBufPtr = (char *) past->past_InputBuffer; - inputBuffer = past->past_InputBuffer; - if( past->past_Flags & paDitherOff ) - { - for( i=0; i<samplesPerBuffer; i++ ) - { - inBufPtr[i] = (char)(nativeInputBuffer[i] >> 8); - } - } - else - { - for( i=0; i<samplesPerBuffer; i++ ) - { - temp = nativeInputBuffer[i]; - temp += PaConvert_TriangularDither() >> 8; /* PLB20010820 */ - temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); - inBufPtr[i] = (char)(temp >> 8); - } - } - break; - } - - case paUInt8: - { - /* Convert 16 bit data to 8 bit unsigned chars */ - unsigned char *inBufPtr = (unsigned char *) past->past_InputBuffer; - inputBuffer = past->past_InputBuffer; - if( past->past_Flags & paDitherOff ) - { - for( i=0; i<samplesPerBuffer; i++ ) - { - inBufPtr[i] = ((unsigned char)(nativeInputBuffer[i] >> 8)) + 0x80; - } - } - else - { - /* If you dither then you have to clip because dithering could push the signal out of range! */ - for( i=0; i<samplesPerBuffer; i++ ) - { - temp = nativeInputBuffer[i]; - temp += PaConvert_TriangularDither() >> 8; /* PLB20010820 */ - temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); - inBufPtr[i] = (unsigned char)((temp>>8) + 0x80); /* PLB20010820 */ - } - } - break; - } - - default: - break; - } - } -#endif /* SUPPORT_AUDIO_CAPTURE */ - - /* Are we doing output time? */ - if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) ) - { - /* May already be in native format so just write directly to native buffer. */ - outputBuffer = (past->past_OutputSampleFormat == paInt16) ? - nativeOutputBuffer : past->past_OutputBuffer; - } - /* - AddTraceMessage("Pa_CallConvertInt16: inputBuffer = ", (int) inputBuffer ); - AddTraceMessage("Pa_CallConvertInt16: outputBuffer = ", (int) outputBuffer ); - */ - /* Call user callback routine. */ - userResult = past->past_Callback( - inputBuffer, - outputBuffer, - past->past_FramesPerUserBuffer, - past->past_FrameCount, - past->past_UserData ); - - past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer; - - /* Convert to native format if necessary. */ - if( outputBuffer != NULL ) - { - unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels; - switch(past->past_OutputSampleFormat) - { - case paFloat32: - { - float *outBufPtr = (float *) past->past_OutputBuffer; - if( past->past_Flags & paDitherOff ) - { - if( past->past_Flags & paClipOff ) /* NOTHING */ - { - for( i=0; i<samplesPerBuffer; i++ ) - { - *nativeOutputBuffer++ = (short) (outBufPtr[i] * (32767.0f)); - } - } - else /* CLIP */ - { - for( i=0; i<samplesPerBuffer; i++ ) - { - temp = (long)(outBufPtr[i] * 32767.0f); - *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); - } - } - } - else - { - /* If you dither then you have to clip because dithering could push the signal out of range! */ - for( i=0; i<samplesPerBuffer; i++ ) - { - float dither = PaConvert_TriangularDither()*PA_DITHER_SCALE; - float dithered = (outBufPtr[i] * (32767.0f)) + dither; - temp = (long) (dithered); - *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); - } - } - break; - } - - case paInt32: - { - int *outBufPtr = (int *) past->past_OutputBuffer; - if( past->past_Flags & paDitherOff ) - { - for( i=0; i<samplesPerBuffer; i++ ) - { - *nativeOutputBuffer++ = (short) (outBufPtr[i] >> 16 ); - } - } - else - { - for( i=0; i<samplesPerBuffer; i++ ) - { - /* Shift one bit down before dithering so that we have room for overflow from add. */ - temp = (outBufPtr[i] >> 1) + PaConvert_TriangularDither(); - temp = temp >> 15; - *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); - } - } - break; - } - - case paInt8: - { - char *outBufPtr = (char *) past->past_OutputBuffer; - for( i=0; i<samplesPerBuffer; i++ ) - { - *nativeOutputBuffer++ = ((short)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; -} - -/*************************************************************************/ -PaError Pa_Initialize( void ) -{ - if( gInitCount++ > 0 ) return paNoError; - ResetTraceMessages(); - return PaHost_Init(); -} - -PaError Pa_Terminate( void ) -{ - PaError result = paNoError; - - if( gInitCount == 0 ) return paNoError; - else if( --gInitCount == 0 ) - { - result = PaHost_Term(); - DumpTraceMessages(); - } - return result; -} - -int PaHost_IsInitialized() -{ - return gInitCount; -} - -/*************************************************************************/ -PaError Pa_GetSampleSize( PaSampleFormat format ) -{ - int size; - switch(format ) - { - - case paUInt8: - case paInt8: - size = 1; - break; - - case paInt16: - size = 2; - break; - - case paPackedInt24: - size = 3; - break; - - case paFloat32: - case paInt32: - case paInt24: - size = 4; - break; - - default: - size = paSampleFormatNotSupported; - break; - } - return (PaError) size; -} - - diff --git a/pd/portaudio/pa_common/pa_process.c b/pd/portaudio/pa_common/pa_process.c deleted file mode 100644 index 2fbeb277..00000000 --- a/pd/portaudio/pa_common/pa_process.c +++ /dev/null @@ -1,1355 +0,0 @@ -/* - * $Id: pa_process.c,v 1.1.2.28 2002/10/26 05:33:29 rossbencina 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. - */ - -#include <assert.h> -#include <string.h> /* memset() */ - -#include "pa_process.h" -#include "pa_util.h" - -/** @file - The code in this file is not optimised yet. 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. - - Cache tilings for intereave<->deinterleave also need to be considered. - - @todo The abort flag from the streamCallback is currently not honoured properly - in this file, see fixmes. - - @todo see FIXMEs - - @todo implement the streamFlags callback parameter, currently it is - always zero. It needs to be passed from the host layer somehow. -*/ - -#define PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_ 1024 - - -/* 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; - 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; - - /* 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] = 0; - bp->hostOutputChannels[0] = 0; - - if( framesPerUserBuffer == 0 ) /* streamCallback will accept any buffer size */ - { - bp->useNonAdaptingProcess = 1; - bp->framesInTempInputBuffer = 0; - bp->framesInTempOutputBuffer = 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->framesInTempInputBuffer = 0; - bp->framesInTempOutputBuffer = 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->framesInTempInputBuffer = frameShift; - bp->framesInTempOutputBuffer = 0; - } - else - { - bp->framesInTempInputBuffer = 0; - bp->framesInTempOutputBuffer = frameShift; - } - } - else /* variable host buffer size, add framesPerUserBuffer latency */ - { - bp->framesInTempInputBuffer = 0; - bp->framesInTempOutputBuffer = framesPerUserBuffer; - } - } - else - { - /* half duplex */ - bp->framesInTempInputBuffer = 0; - bp->framesInTempOutputBuffer = 0; - } - } - } - - - - 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->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 = - 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->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 = - 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_BeginBufferProcessing( PaUtilBufferProcessor* bp, PaStreamCallbackTimeInfo* timeInfo ) -{ - 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; - - (void)bp->timeInfo->currentTime; /* 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->hostInputFrameCount[1] = 0; - bp->hostOutputFrameCount[1] = 0; -} - - -static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp, - int *streamCallbackResult, - PaUtilChannelDescriptor *hostInputChannels, - PaUtilChannelDescriptor *hostOutputChannels, - unsigned long frameCount ); - -static unsigned long AdaptingInputOnlyProcess( PaUtilBufferProcessor *bp, - int *streamCallbackResult, - PaUtilChannelDescriptor *hostInputChannels, - unsigned long frameCount ); - -static unsigned long AdaptingOutputOnlyProcess( PaUtilBufferProcessor *bp, - int *streamCallbackResult, - PaUtilChannelDescriptor *hostOutputChannels, - unsigned long framesToProcess ); - -static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp, - int *streamCallbackResult, int processPartialUserBuffers ); - -#define PA_MIN_( a, b ) ( ((a)<(b)) ? (a) : (b) ) - -unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bp, int *streamCallbackResult ) -{ - unsigned long framesToProcess, framesToGo; - unsigned long framesProcessed = 0; - - if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 ) - { - assert( (bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) == - (bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) ); - } - - - if( bp->useNonAdaptingProcess ) - { - if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 ) - { - /* full duplex non-adapting process, splice buffers if they are - different lengths */ - - framesToGo = bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]; /* relies on assert above for input/output equivalence */ - - do{ - unsigned long *hostInputFrameCount; - PaUtilChannelDescriptor *hostInputChannels; - unsigned long *hostOutputFrameCount; - PaUtilChannelDescriptor *hostOutputChannels; - unsigned long framesProcessedThisIteration; - - if( bp->hostInputFrameCount[0] != 0 ) - { - hostInputFrameCount = &bp->hostInputFrameCount[0]; - hostInputChannels = bp->hostInputChannels[0]; - } - else - { - hostInputFrameCount = &bp->hostInputFrameCount[1]; - hostInputChannels = bp->hostInputChannels[1]; - } - - 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; -} - - -void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bp, - unsigned long frameCount ) -{ - if( frameCount == 0 ) - bp->hostInputFrameCount[0] = bp->framesPerHostBuffer; - else - bp->hostInputFrameCount[0] = frameCount; -} - - -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_SetOutputChannel( PaUtilBufferProcessor* bp, - unsigned int channel, void *data, unsigned int stride ) -{ - assert( channel < bp->outputChannelCount ); - - 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 ) - { - bp->hostOutputChannels[0][channel+i].data = p; - p += bp->bytesPerHostOutputSample; - bp->hostOutputChannels[0][channel+i].stride = channelCount; - } -} - - -void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bp, - unsigned int channel, void *data ) -{ - assert( channel < bp->outputChannelCount ); - - bp->hostOutputChannels[0][channel].data = data; - bp->hostOutputChannels[0][channel].stride = 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 ); - - 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 ) - { - bp->hostOutputChannels[1][channel+i].data = p; - p += bp->bytesPerHostOutputSample; - bp->hostOutputChannels[1][channel+i].stride = channelCount; - } -} - - -void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bp, - unsigned int channel, void *data ) -{ - assert( channel < bp->outputChannelCount ); - - bp->hostOutputChannels[1][channel].data = data; - bp->hostOutputChannels[1][channel].stride = 1; -} - - -/* - 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 srcStride, srcBytePtrStride; - unsigned int destStride, destBytePtrStride; - unsigned int i; - unsigned long frameCount; - unsigned long framesToGo = framesToProcess; - unsigned long framesProcessed = 0; - unsigned long statusFlags = 0; // FIXME: implement this - - do - { - frameCount = ( bp->framesPerTempBuffer < framesToGo ) - ? 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 = bp->tempInputBuffer; - - if( bp->userInputIsInterleaved ) - { - destStride = bp->inputChannelCount; - destBytePtrStride = bp->bytesPerUserInputSample; - userInput = bp->tempInputBuffer; - } - else /* user input is not interleaved */ - { - destStride = 1; - destBytePtrStride = 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; - } - - for( i=0; i<bp->inputChannelCount; ++i ) - { - bp->inputConverter( destBytePtr, destStride, - hostInputChannels[i].data, - hostInputChannels[i].stride, - frameCount, &bp->ditherGenerator ); - - destBytePtr += destBytePtrStride; /* 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, - statusFlags, bp->userData ); - - bp->timeInfo->inputBufferAdcTime += frameCount * bp->samplePeriod; - bp->timeInfo->outputBufferDacTime += frameCount * bp->samplePeriod; - - - // FIXME: if streamCallback result is abort, then abort! - - /* convert output data (user -> host) */ - if( bp->outputChannelCount != 0 ) - { - /* - could use more elaborate logic here and sometimes process - buffers in-place. - */ - - srcBytePtr = bp->tempOutputBuffer; - - if( bp->userOutputIsInterleaved ) - { - srcStride = bp->outputChannelCount; - srcBytePtrStride = bp->bytesPerUserOutputSample; - } - else /* user output is not interleaved */ - { - srcStride = 1; - srcBytePtrStride = frameCount * bp->bytesPerUserOutputSample; - } - - for( i=0; i<bp->outputChannelCount; ++i ) - { - bp->outputConverter( hostOutputChannels[i].data, - hostOutputChannels[i].stride, - srcBytePtr, srcStride, - frameCount, &bp->ditherGenerator ); - - srcBytePtr += srcBytePtrStride; /* 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 ); - - 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 destStride, destBytePtrStride; - unsigned int i; - unsigned long frameCount; - unsigned long framesToGo = framesToProcess; - unsigned long framesProcessed = 0; - unsigned long statusFlags = 0; // FIXME: implement this - - 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; - - destStride = bp->inputChannelCount; - destBytePtrStride = bp->bytesPerUserInputSample; - - userInput = bp->tempInputBuffer; - } - else /* user input is not interleaved */ - { - destBytePtr = ((unsigned char*)bp->tempInputBuffer) + - bp->bytesPerUserInputSample * bp->framesInTempInputBuffer; - - destStride = 1; - destBytePtrStride = 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, destStride, - hostInputChannels[i].data, - hostInputChannels[i].stride, - frameCount, &bp->ditherGenerator ); - - destBytePtr += destBytePtrStride; /* 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 ) - { - bp->timeInfo->outputBufferDacTime = 0; - - *streamCallbackResult = bp->streamCallback( userInput, userOutput, - bp->framesPerUserBuffer, bp->timeInfo, - statusFlags, bp->userData ); - - bp->timeInfo->inputBufferAdcTime += frameCount * bp->samplePeriod; - - // FIXME: if streamCallback result is abort, then abort! - - 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 srcStride, srcBytePtrStride; - unsigned int i; - unsigned long frameCount; - unsigned long framesToGo = framesToProcess; - unsigned long framesProcessed = 0; - unsigned long statusFlags = 0; // FIXME: implement this - - do - { - if( bp->framesInTempOutputBuffer == 0 ) - { - 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, - statusFlags, bp->userData ); - - bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod; - - // FIXME: if streamCallback result is abort, then abort! - - bp->framesInTempOutputBuffer = bp->framesPerUserBuffer; - } - - frameCount = ( bp->framesInTempOutputBuffer > framesToGo ) - ? framesToGo - : bp->framesInTempOutputBuffer; - - /* convert frameCount frames from user buffer to host buffer */ - - if( bp->userOutputIsInterleaved ) - { - srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + - bp->bytesPerUserOutputSample * bp->outputChannelCount * - (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); - - srcStride = bp->outputChannelCount; - srcBytePtrStride = bp->bytesPerUserOutputSample; - } - else /* user output is not interleaved */ - { - srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + - bp->bytesPerUserOutputSample * - (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); - - srcStride = 1; - srcBytePtrStride = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; - } - - for( i=0; i<bp->outputChannelCount; ++i ) - { - bp->outputConverter( hostOutputChannels[i].data, - hostOutputChannels[i].stride, - srcBytePtr, srcStride, - frameCount, &bp->ditherGenerator ); - - srcBytePtr += srcBytePtrStride; /* 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; - - framesProcessed += frameCount; - - framesToGo -= frameCount; - - }while( framesToGo > 0 ); - - return framesProcessed; -} - - -/* - 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 *srcBytePtr, *destBytePtr; - unsigned int srcStride, srcBytePtrStride, destStride, destBytePtrStride; - unsigned int i; - unsigned long statusFlags = 0; // FIXME: implement this - - framesAvailable = bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1];/* this is assumed to be the same as the output buffers frame count */ - - if( processPartialUserBuffers ) - endProcessingMinFrameCount = 0; - else - endProcessingMinFrameCount = (bp->framesPerUserBuffer - 1); - - while( framesAvailable > endProcessingMinFrameCount ) - { - /* 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 = (bp->hostOutputFrameCount[0] < maxFramesToCopy) - ? bp->hostOutputFrameCount[0] - : maxFramesToCopy; - } - else - { - hostOutputChannels = bp->hostOutputChannels[1]; - frameCount = (bp->hostOutputFrameCount[1] < maxFramesToCopy) - ? bp->hostOutputFrameCount[1] - : maxFramesToCopy; - } - - if( bp->userOutputIsInterleaved ) - { - srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + - bp->bytesPerUserOutputSample * bp->outputChannelCount * - (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); - - srcStride = bp->outputChannelCount; - srcBytePtrStride = bp->bytesPerUserOutputSample; - } - else /* user output is not interleaved */ - { - srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + - bp->bytesPerUserOutputSample * - (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); - - srcStride = 1; - srcBytePtrStride = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; - } - - for( i=0; i<bp->outputChannelCount; ++i ) - { - bp->outputConverter( hostOutputChannels[i].data, - hostOutputChannels[i].stride, - srcBytePtr, srcStride, - frameCount, &bp->ditherGenerator ); - - srcBytePtr += srcBytePtrStride; /* 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; - } - - - /* 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 = (bp->hostInputFrameCount[0] < maxFramesToCopy) - ? bp->hostInputFrameCount[0] - : maxFramesToCopy; - } - else - { - hostInputChannels = bp->hostInputChannels[1]; - frameCount = (bp->hostInputFrameCount[1] < maxFramesToCopy) - ? bp->hostInputFrameCount[1] - : maxFramesToCopy; - } - - /* configure conversion destination pointers */ - if( bp->userInputIsInterleaved ) - { - destBytePtr = ((unsigned char*)bp->tempInputBuffer) + - bp->bytesPerUserInputSample * bp->inputChannelCount * - bp->framesInTempInputBuffer; - - destStride = bp->inputChannelCount; - destBytePtrStride = bp->bytesPerUserInputSample; - } - else /* user input is not interleaved */ - { - destBytePtr = ((unsigned char*)bp->tempInputBuffer) + - bp->bytesPerUserInputSample * bp->framesInTempInputBuffer; - - destStride = 1; - destBytePtrStride = bp->framesPerUserBuffer * bp->bytesPerUserInputSample; - } - - for( i=0; i<bp->inputChannelCount; ++i ) - { - bp->inputConverter( destBytePtr, destStride, - hostInputChannels[i].data, - hostInputChannels[i].stride, - frameCount, &bp->ditherGenerator ); - - destBytePtr += destBytePtrStride; /* 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 ) - { - /* 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, - statusFlags, bp->userData ); - - bp->timeInfo->inputBufferAdcTime += bp->framesPerUserBuffer * bp->samplePeriod; - bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod; - - - // FIXME: if streamCallback result is abort, then abort! - - - bp->framesInTempInputBuffer = 0; - bp->framesInTempOutputBuffer = bp->framesPerUserBuffer; - } - } - - return framesProcessed; -} diff --git a/pd/portaudio/pa_common/pa_process.h b/pd/portaudio/pa_common/pa_process.h deleted file mode 100644 index 47bc0d70..00000000 --- a/pd/portaudio/pa_common/pa_process.h +++ /dev/null @@ -1,203 +0,0 @@ -#ifndef PA_PROCESS_H -#define PA_PROCESS_H -/* - * $Id: pa_process.h,v 1.1.2.16 2002/10/26 05:33:29 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. - */ - -#include "portaudio.h" -#include "pa_converters.h" -#include "pa_dither.h" - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/** @file - - @todo finish documentation for the buffer processor -*/ - -typedef enum { - paUtilFixedHostBufferSize, - paUtilBoundedHostBufferSize, - paUtilUnknownHostBufferSize, - paUtilVariableHostBufferSizePartialUsageAllowed, /**< the only mode where process() may not consume the whole buffer */ -}PaUtilHostBufferSizeMode; - - -typedef struct PaUtilChannelDescriptor{ - void *data; - unsigned int stride; -}PaUtilChannelDescriptor; - - -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; - - unsigned int outputChannelCount; - unsigned int bytesPerHostOutputSample; - unsigned int bytesPerUserOutputSample; - int userOutputIsInterleaved; - PaUtilConverter *outputConverter; - - 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; - - unsigned long hostInputFrameCount[2]; - PaUtilChannelDescriptor *hostInputChannels[2]; - unsigned long hostOutputFrameCount[2]; - PaUtilChannelDescriptor *hostOutputChannels[2]; - - PaUtilTriangularDitherGenerator ditherGenerator; - - double samplePeriod; - - PaStreamCallback *streamCallback; - void *userData; -} PaUtilBufferProcessor; - - -/** - @param framesPerHostBuffer Specifies the number of frames per host buffer - for fixed 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. - - @note The interleave flag is ignored for host buffer formats. Host interleave - is determined by the use of different SetInput and SetOutput functions. -*/ -PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bufferProcessor, - int numInputChannels, PaSampleFormat userInputSampleFormat, - PaSampleFormat hostInputSampleFormat, - int numOutputChannels, 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 ); - - -void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bufferProcessor ); - - -/** - @param timeInfo Timing information for the first sample of the buffer(s) - passed to the buffer processor. The buffer processor may adjust this - information as necessary. -*/ -void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bufferProcessor, - PaStreamCallbackTimeInfo* timeInfo ); - -/** returns the number of frames processed */ -unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bufferProcessor, int *callbackResult ); - - -/** a 0 frameCount indicates to use the framesPerHostBuffer value passed to init */ -void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bufferProcessor, - unsigned long frameCount ); - - -void PaUtil_SetInputChannel( PaUtilBufferProcessor* bufferProcessor, - unsigned int channel, void *data, unsigned int stride ); - -/** if channel count is zero use all channels as specified to initialize buffer processor */ -void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor, - unsigned int firstChannel, void *data, unsigned int channelCount ); - -void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor, - unsigned int channel, void *data ); - - -void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bufferProcessor, - unsigned long frameCount ); - -void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bufferProcessor, - unsigned int channel, void *data, unsigned int stride ); - -/** if channel count is zero use all channels as specified to initialize buffer processor */ -void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor, - unsigned int firstChannel, void *data, unsigned int channelCount ); - -void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor, - unsigned int channel, void *data ); - -/** a 0 frameCount indicates to use the framesPerHostBuffer value passed to init */ -void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bufferProcessor, - unsigned long frameCount ); - -void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bufferProcessor, - unsigned int channel, void *data, unsigned int stride ); - -/** if channel count is zero use all channels as specified to initialize buffer processor */ -void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor, - unsigned int firstChannel, void *data, unsigned int channelCount ); - -void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor, - unsigned int channel, void *data ); - - -void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bufferProcessor, - unsigned long frameCount ); - -void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bufferProcessor, - unsigned int channel, void *data, unsigned int stride ); - -/** if channel count is zero use all channels as specified to initialize buffer processor */ -void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor, - unsigned int firstChannel, void *data, unsigned int channelCount ); - -void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor, - unsigned int channel, void *data ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PA_PROCESS_H */ diff --git a/pd/portaudio/pa_common/pa_skeleton.c b/pd/portaudio/pa_common/pa_skeleton.c deleted file mode 100644 index d9a90f4b..00000000 --- a/pd/portaudio/pa_common/pa_skeleton.c +++ /dev/null @@ -1,724 +0,0 @@ -/* - * $Id: pa_skeleton.c,v 1.1.2.27 2002/12/03 06:30:40 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. - */ - -#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" - -/** @file - NOTE TO IMPLEMENTORS: - - 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. -*/ - - -/* prototypes for functions declared in this file */ - -PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ); -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 ); -static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); -static PaError WriteStream( PaStream* stream, 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_DummyReadWrite, PaUtil_DummyReadWrite, PaUtil_DummyGetAvailable, PaUtil_DummyGetAvailable ); - - 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 resourced 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; - - /* 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: - - 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 - */ - - 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=0, outputSampleFormat=0; - PaSampleFormat hostInputSampleFormat=0, hostOutputSampleFormat=0; - - - 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; - } - - 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; - } - - /* - 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 ); - } - - /* - IMPLEMENT ME: initialise the following fields with estimated or actual - values. - */ - stream->streamRepresentation.streamInfo.inputLatency = 0.; - stream->streamRepresentation.streamInfo.outputLatency = 0.; - stream->streamRepresentation.streamInfo.sampleRate = sampleRate; - - 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: - - 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 ); - - /* - 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 */ - - 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; - - /* IMPLEMENT ME, see portaudio.h for required behavior */ - - return result; -} - - -static PaError StopStream( PaStream *s ) -{ - PaError result = paNoError; - PaSkeletonStream *stream = (PaSkeletonStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior */ - - return result; -} - - -static PaError AbortStream( PaStream *s ) -{ - PaError result = paNoError; - PaSkeletonStream *stream = (PaSkeletonStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior */ - - return result; -} - - -static PaError IsStreamStopped( PaStream *s ) -{ - PaSkeletonStream *stream = (PaSkeletonStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior */ - - return 0; -} - - -static PaError IsStreamActive( PaStream *s ) -{ - PaSkeletonStream *stream = (PaSkeletonStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior */ - - return 0; -} - - -static PaTime GetStreamTime( PaStream *s ) -{ - PaSkeletonStream *stream = (PaSkeletonStream*)s; - - /* 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; - - /* IMPLEMENT ME, see portaudio.h for required behavior*/ - - return paNoError; -} - - -static PaError WriteStream( PaStream* s, - void *buffer, - unsigned long frames ) -{ - PaSkeletonStream *stream = (PaSkeletonStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior*/ - - return paNoError; -} - - -static signed long GetStreamReadAvailable( PaStream* s ) -{ - PaSkeletonStream *stream = (PaSkeletonStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior*/ - - return 0; -} - - -static signed long GetStreamWriteAvailable( PaStream* s ) -{ - PaSkeletonStream *stream = (PaSkeletonStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior*/ - - return 0; -} - - - diff --git a/pd/portaudio/pa_common/pa_stream.c b/pd/portaudio/pa_common/pa_stream.c deleted file mode 100644 index b2eba53d..00000000 --- a/pd/portaudio/pa_common/pa_stream.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * $Id: pa_stream.c,v 1.1.2.9 2002/12/03 06:30:40 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. - */ - -#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*, 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_DummyReadWrite( PaStream* stream, - void *buffer, - unsigned long frames ) -{ - (void)stream; /* unused parameter */ - (void)buffer; /* unused parameter */ - (void)frames; /* unused parameter */ - - return paNoError; /* @todo FIXME: need new error code paCantReadWriteToCallbackStream or something */ -} - - -signed long PaUtil_DummyGetAvailable( PaStream* stream ) -{ - (void)stream; /* unused parameter */ - - return 0; -} - - -double PaUtil_DummyGetCpuLoad( PaStream* stream ) -{ - (void)stream; /* unused parameter */ - - return 0.0; -} diff --git a/pd/portaudio/pa_common/pa_stream.h b/pd/portaudio/pa_common/pa_stream.h deleted file mode 100644 index 5e66c097..00000000 --- a/pd/portaudio/pa_common/pa_stream.h +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef PA_STREAM_H -#define PA_STREAM_H -/* - * $Id: pa_stream.h,v 1.1.2.9 2002/12/03 06:30:40 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 - Interface used by pa_front to virtualise stream calls. -*/ - -#include "portaudio.h" - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - - -#define PA_STREAM_MAGIC (0x18273645) - -typedef struct { - /* - all PaStreamInterface functions are guaranteed to be called with a - non-null, valid <stream> parameter - */ - 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, void *buffer, unsigned long frames ); - signed long (*GetReadAvailable)( PaStream* stream ); - signed long (*GetWriteAvailable)( PaStream* stream ); -} PaUtilStreamInterface; - - -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, void *buffer, unsigned long frames ), - signed long (*GetReadAvailable)( PaStream* stream ), - signed long (*GetWriteAvailable)( PaStream* stream ) ); - - -/** Use PaUtil_DummyReadWrite and PaUtil_DummyGetAvailable for - callback based streams. -*/ -PaError PaUtil_DummyReadWrite( PaStream* stream, - void *buffer, - unsigned long frames ); - - -signed long PaUtil_DummyGetAvailable( PaStream* stream ); - -/** Use PaUtil_DummyGetCpuLoad for read/write streams -*/ -double PaUtil_DummyGetCpuLoad( PaStream* stream ); - - -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; - - -void PaUtil_InitializeStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation, - PaUtilStreamInterface *streamInterface, - PaStreamCallback *streamCallback, - void *userData ); - -void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation ); - - -#define PA_STREAM_REP( streamRepPtr )\ - ((PaUtilStreamRepresentation*) streamRepPtr ) - -#define PA_STREAM_INTERFACE( streamRepPtr )\ - PA_STREAM_REP( streamRepPtr )->streamInterface - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PA_STREAM_H */ diff --git a/pd/portaudio/pa_common/pa_trace.c b/pd/portaudio/pa_common/pa_trace.c deleted file mode 100644 index 74e8bb2f..00000000 --- a/pd/portaudio/pa_common/pa_trace.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * $Id: pa_trace.c,v 1.1.1.1.2.2 2002/10/26 05:34:03 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. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "pa_trace.h" - -#if PA_TRACE_REALTIME_EVENTS - -static char *traceTextArray[MAX_TRACE_RECORDS]; -static int traceIntArray[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] ); - } - 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/pd/portaudio/pa_common/pa_trace.h b/pd/portaudio/pa_common/pa_trace.h deleted file mode 100644 index 069d006d..00000000 --- a/pd/portaudio/pa_common/pa_trace.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef PA_TRACE_H -#define PA_TRACE_H -/* - * $Id: pa_trace.h,v 1.1.1.1.2.2 2002/10/22 08:58:16 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 - 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/pd/portaudio/pa_common/pa_util.h b/pd/portaudio/pa_common/pa_util.h deleted file mode 100644 index c87d71ca..00000000 --- a/pd/portaudio/pa_common/pa_util.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef PA_UTIL_H -#define PA_UTIL_H -/* - * Id: - * 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. - */ - -#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. -*/ -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, ... ); - -#if (0) /* set to 1 to print debug messages */ -#define PA_DEBUG(x) PaUtil_DebugPrint x ; -#else -#define PA_DEBUG(x) -#endif - - -/* the following functions are implemented in a per-platform .c file */ - -void *PaUtil_AllocateMemory( long size ); -/**< Allocate size bytes, guaranteed to be aligned to a FIXME byte boundary */ - -void PaUtil_FreeMemory( void *block ); -/**< Realease block if non-NULL. block may be NULL */ - -int PaUtil_CountCurrentlyAllocatedBlocks( void ); -/**< - 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. -*/ - - -void PaUtil_InitializeClock( void ); -double PaUtil_GetTime( void ); /* system time in seconds, used to implement CPU load functions */ - -/* 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/pd/portaudio/pa_common/portaudio.h b/pd/portaudio/pa_common/portaudio.h deleted file mode 100644 index 68303e1c..00000000 --- a/pd/portaudio/pa_common/portaudio.h +++ /dev/null @@ -1,1072 +0,0 @@ -#ifndef PORTAUDIO_H -#define PORTAUDIO_H - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/* - * $Id: portaudio.h,v 1.5.2.34 2002/12/03 07:02:54 rossbencina 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. - * - */ - - -/** 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. */ - -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 -} PaErrorCode; - - -/** Translate the supplied PortAudio error number into a human readable - message. -*/ -const char *Pa_GetErrorText( PaError errorNumber ); - - -/** 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 call must be matched with - a corresponding call to Pa_Terminate(). Pairs of calls to - Pa_Initialize()/Pa_Terminate() may overlap, and are not requireed to be fully - nested. - - @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_CountHostApis()-1). - - @see Pa_CountHostApis -*/ -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. - Returns a negative PaErrorCode if PortAudio is not initialized or an error - is encountered. - - @see PaHostApiIndex -*/ -PaHostApiIndex Pa_CountHostApis( 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 indicating the default host API index. Returns a - negative PaErrorCode 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 -} 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 the default input device for this host API. The value will be a - device index ranging from 0 to (Pa_CountDevices()-1), or paNoDevice - if no default input device is available. - */ - PaDeviceIndex defaultInputDevice; - - /** The the default output device for this host API. The value will be a - device index ranging from 0 to (Pa_CountDevices()-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_CountHostApis()-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_CountHostApis()-1), or - -1 if 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_CountHostApis()-1) - - @param hostApiDeviceIndex A valid per-host device index in the range - 0 to (Pa_GetHostApiInfo(hostApi)->deviceCount-1) - - @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. - @return The number of available devices. May return 0 if PortAudio is - not initialized or an error has occured. -*/ -PaDeviceIndex Pa_CountDevices( 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 defualt 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. They indicate - the formats used to pass sound data between the stream callback and the - stream. Each device has one or more "native" formats which may be used when - optimum efficiency or control over conversion is required. - - Formats marked "always available" are supported (emulated) by all - PortAudio implementations. - - The floating point representation (paFloat32) uses +1.0 and -1.0 as the - maximum and minimum respectively. - - paUInt8 is an unsigned 8 bit format where 128 is considered "ground" - - 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_CountDevices()-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_CountDevices()-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. - FIXME: wrt below, what are we guaranteeing these days, if anything? - PortAudio guarantees support for - the device's native formats (nativeSampleFormats in the device info record) - and additionally 16 and 32 bit integer and 32 bit floating point formats. - Support for other formats is implementation defined. - */ - 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 - shouldround the suggestedLatency up to the next practial value - ie to - provide an equal or higher latency than suggestedLatency whereever 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 paNullHostApiSpecificStreamInfo (aka NULL) - FIXME: redocument this based on new changes: - If hostApiSpecificStreamInfo is supplied, it's - size and hostApi fields must be compatible with the input devices host api. - */ - 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) - -/** A full duplex stream will not discard overflowed input samples without - calling the stream callback, this flag is ignored for blocking read/write - streams. - @see PaStreamFlags -*/ -#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; - -/** Input data is all zeros because no real data is available. - @see PaStreamCallbackFlags -*/ -#define paInputUnderflow ((PaStreamCallbackFlags) 0x00000001) - -/** Input data was discarded by PortAudio - @see PaStreamCallbackFlags -*/ -#define paInputOverflow ((PaStreamCallbackFlags) 0x00000002) - -/** Output data was inserted by PortAudio because the stream callback is using - too much CPU - @see PaStreamCallbackFlags -*/ -#define paOutputUnderflow ((PaStreamCallbackFlags) 0x00000004) - -/** 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 is 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( - 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. - - @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 - (see above). - FIXME: the following may need to be rewritten - PortAudio guarantees support for - the device's native formats (nativeSampleFormats in the device info record) - and additionally 16 and 32 bit integer and 32 bit float - - @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 ); - - -/** @return Returns one (1) when the stream is stopped, zero (0) when - the stream is running, or a negative error number if the stream - is invalid. 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. -*/ -PaError Pa_IsStreamStopped( PaStream *stream ); - - -/** @return Returns one (1) when the stream is active (ie playing - or recording audio), zero (0) when not playing, or a negative error number - if the stream is invalid. - - 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. - - @see Pa_StopStream, Pa_AbortStream -*/ -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 ); - - -/** - @return The current time (in seconds) according to the same clock used to - generate buffer timestamps for stream. - This time may be used for syncronising other events to the audio stream, - for example synchronizing audio to MIDI. - - @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. -*/ -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 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 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, - void *buffer, - unsigned long frames ); - - -/** Retrieve the number of frames that can be read from the stream without - waiting. - - @return If non-negative, the return value is the maximum number of frames - that can be read from the stream without blocking or busy waiting. A - negative value is a PaErrorCode. -*/ -signed long Pa_GetStreamReadAvailable( PaStream* stream ); - - -/** Retrieve the number of frames that can be written to the stream without - waiting. - - @return If non-negative, the return value is the maximum number of frames - that can be written to the stream without blocking or busy waiting. A - negative value is a PaErrorCode. -*/ -signed long Pa_GetStreamWriteAvailable( PaStream* stream ); - - -/* Miscellaneous utilities */ - - -/** - @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 ); - - -/** Puts the caller to sleep for at least 'msec' milliseconds. - It may sleep longer than requested so don't rely on this for accurate - musical timing. - - This function is provided only as a convenience for authors of portable code - (such as the tests and examples in the PortAudio distribution.) -*/ -void Pa_Sleep( long msec ); - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PORTAUDIO_H */ diff --git a/pd/portaudio/pa_dll_switch/PaDllEntry.h b/pd/portaudio/pa_dll_switch/PaDllEntry.h deleted file mode 100644 index e070054b..00000000 --- a/pd/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/pd/portaudio/pa_dll_switch/letter_from_tim_010817.txt b/pd/portaudio/pa_dll_switch/letter_from_tim_010817.txt Binary files differdeleted file mode 100644 index a535cd1d..00000000 --- a/pd/portaudio/pa_dll_switch/letter_from_tim_010817.txt +++ /dev/null diff --git a/pd/portaudio/pa_dll_switch/loadPA_DLL.cpp b/pd/portaudio/pa_dll_switch/loadPA_DLL.cpp deleted file mode 100644 index 043eda87..00000000 --- a/pd/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/pd/portaudio/pa_dll_switch/pa_lib.c b/pd/portaudio/pa_dll_switch/pa_lib.c deleted file mode 100644 index 86601592..00000000 --- a/pd/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/pd/portaudio/pa_dll_switch/portaudio.h b/pd/portaudio/pa_dll_switch/portaudio.h deleted file mode 100644 index 9632521e..00000000 --- a/pd/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/pd/portaudio/pa_jack/pa_jack.c b/pd/portaudio/pa_jack/pa_jack.c deleted file mode 100644 index 4efeff81..00000000 --- a/pd/portaudio/pa_jack/pa_jack.c +++ /dev/null @@ -1,864 +0,0 @@ -/* - * $Id: pa_jack.c,v 1.1.2.1 2002/07/31 04:22:56 joshua Exp $ - * PortAudio Portable Real-Time Audio Library - * Latest Version at: http://www.portaudio.com - * JACK Implementation by Joshua Haberman - * - * 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 <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" - -PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, - PaHostApiIndex hostApiIndex ); - -/* - * Functions that directly map to the PortAudio stream interface - */ - -static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); -static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, - PaStream** s, - PaDeviceIndex inputDevice, - int numInputChannels, - PaSampleFormat inputSampleFormat, - unsigned long inputLatency, - PaHostApiSpecificStreamInfo *inputStreamInfo, - PaDeviceIndex outputDevice, - int numOutputChannels, - PaSampleFormat outputSampleFormat, - unsigned long outputLatency, - PaHostApiSpecificStreamInfo *outputStreamInfo, - double sampleRate, - unsigned long framesPerCallback, - PaStreamFlags streamFlags, - PortAudioCallback *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 PaTimestamp GetStreamTime( PaStream *stream ); -static double GetStreamCpuLoad( PaStream* stream ); - -/* - * Data specific to this API - */ - -typedef struct -{ - PaUtilHostApiRepresentation commonHostApiRep; - PaUtilStreamInterface callbackStreamInterface; - - PaUtilAllocationGroup *deviceInfoMemory; - - jack_client_t *jack_client; - PaHostApiIndex hostApiIndex; -} -PaJackHostApiRepresentation; - -#define MAX_CLIENTS 100 -#define TRUE 1 -#define FALSE 0 - -/* - * Functions specific to this API - */ - -static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi ); -static int JackCallback( jack_nframes_t frames, void *userData ); - - - -/* - * - * Implementation - * - */ - - -/* 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) )) - - /* ... MEMVERIFY: make sure we didn't get NULL */ -#define MEMVERIFY(ptr) \ - if( (ptr) == NULL ) return paInsufficientMemory; - - /* 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 */ - - PaUtilHostApiRepresentation *commonApi = &jackApi->commonHostApiRep; - - const char **jack_ports; - char *client_names[MAX_CLIENTS]; - int num_clients = 0; - int port_index, client_index, i; - double *globalSampleRate; - regex_t port_regex; - - /* 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) */ - jack_ports = jack_get_ports( jackApi->jack_client, "", "", 0 ); - - if( jack_ports == NULL ) - return paHostError; - - /* Parse the list of ports, using a regex to grab the client names */ - regcomp( &port_regex, "^[^:]*", REG_EXTENDED ); - - /* Build a list of clients from the list of ports */ - for( port_index = 0; jack_ports[port_index] != NULL; port_index++ ) - { - int client_seen; - regmatch_t match_info; - char tmp_client_name[100]; - - /* extract the client name from the port name, using a regex - * that parses the clientname:portname syntax */ - regexec( &port_regex, jack_ports[port_index], 1, &match_info, 0 ); - memcpy( tmp_client_name, &jack_ports[port_index][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? */ - client_seen = FALSE; - - for( i = 0; i < num_clients; i++ ) - if( strcmp( tmp_client_name, client_names[i] ) == 0 ) - client_seen = TRUE; - - if( client_seen == FALSE ) - { - client_names[num_clients] = (char*)MALLOC(strlen(tmp_client_name) + 1); - MEMVERIFY( client_names[num_clients] ); - - /* 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 && num_clients > 0 ) - { - /* alsa_pcm goes in spot 0 */ - strcpy( client_names[ num_clients ], client_names[0] ); - strcpy( client_names[0], "alsa_pcm" ); - num_clients++; - } - else - { - /* put the new client at the end of the client list */ - strcpy( client_names[ num_clients ], tmp_client_name ); - num_clients++; - } - } - } - free( jack_ports ); - - /* Now we have a list of clients, which will become the list of - * PortAudio devices. */ - - commonApi->deviceCount = num_clients; - commonApi->defaultInputDeviceIndex = 0; - commonApi->defaultOutputDeviceIndex = 0; - - /* there is one global sample rate all clients must conform to */ - - globalSampleRate = (double*)MALLOC( sizeof(double) ); - MEMVERIFY( globalSampleRate ); - *globalSampleRate = jack_get_sample_rate( jackApi->jack_client ); - - commonApi->deviceInfos = (PaDeviceInfo**)MALLOC( sizeof(PaDeviceInfo*) * - num_clients ); - MEMVERIFY(commonApi->deviceInfos); - - /* Create a PaDeviceInfo structure for every client */ - for( client_index = 0; client_index < num_clients; client_index++ ) - { - char regex_pattern[100]; - PaDeviceInfo *curDevInfo; - - curDevInfo = (PaDeviceInfo*)MALLOC( sizeof(PaDeviceInfo) ); - MEMVERIFY( curDevInfo ); - - curDevInfo->name = (char*)MALLOC( strlen(client_names[client_index]) + 1 ); - MEMVERIFY( curDevInfo->name ); - 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->numSampleRates = 1; - curDevInfo->sampleRates = globalSampleRate; - curDevInfo->nativeSampleFormats = paFloat32|paNonInterleaved; - - /* 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 to)? */ - jack_ports = jack_get_ports( jackApi->jack_client, regex_pattern, - NULL, JackPortIsOutput); - curDevInfo->maxInputChannels = 0; - for( i = 0; jack_ports[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(jack_ports); - - /* ... what are your input ports (that we could output to)? */ - jack_ports = jack_get_ports( jackApi->jack_client, regex_pattern, - NULL, JackPortIsInput); - curDevInfo->maxOutputChannels = 0; - for( i = 0; jack_ports[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(jack_ports); - - /* Add this client to the list of devices */ - commonApi->deviceInfos[client_index] = curDevInfo; - } - -#undef MALLOC -#undef MEMVERIFY - return paNoError; -} - -PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, - PaHostApiIndex hostApiIndex ) -{ - PaError result = paNoError; - PaJackHostApiRepresentation *jackHostApi; - - jackHostApi = (PaJackHostApiRepresentation*) - PaUtil_AllocateMemory( sizeof(PaJackHostApiRepresentation) ); - if( !jackHostApi ) - { - result = paInsufficientMemory; - goto error; - } - - /* Try to become a client of the JACK server. If we cannot do - * this, than this API cannot be used. */ - - jackHostApi->jack_client = jack_client_new( "PortAudio client" ); - if( jackHostApi->jack_client == 0 ) - { - /* 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; - *hostApi = NULL; - goto error; - } - - jackHostApi->deviceInfoMemory = PaUtil_CreateAllocationGroup(); - if( !jackHostApi->deviceInfoMemory ) - { - result = paInsufficientMemory; - goto error; - } - - jackHostApi->hostApiIndex = hostApiIndex; - - *hostApi = &jackHostApi->commonHostApiRep; - (*hostApi)->info.structVersion = 1; - (*hostApi)->info.type = paInDevelopment; - (*hostApi)->info.name = "JACK Audio Connection Kit"; - - /* Build a device list by querying the JACK server */ - - result = BuildDeviceList( jackHostApi ); - if( result != paNoError ) - goto error; - - /* Register functions */ - - (*hostApi)->Terminate = Terminate; - (*hostApi)->OpenStream = OpenStream; - - PaUtil_InitializeStreamInterface( &jackHostApi->callbackStreamInterface, - CloseStream, StartStream, - StopStream, AbortStream, - IsStreamStopped, IsStreamActive, - GetStreamTime, GetStreamCpuLoad, - PaUtil_DummyReadWrite, PaUtil_DummyReadWrite, - PaUtil_DummyGetAvailable, - PaUtil_DummyGetAvailable ); - - return result; - -error: - if( jackHostApi ) - { - 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; - - jack_client_close( jackHostApi->jack_client ); - - if( jackHostApi->deviceInfoMemory ) - { - PaUtil_FreeAllAllocations( jackHostApi->deviceInfoMemory ); - PaUtil_DestroyAllocationGroup( jackHostApi->deviceInfoMemory ); - } - - PaUtil_FreeMemory( jackHostApi ); -} - - -/* PaJackStream - a stream data structure specifically for this implementation */ - -typedef struct PaJackStream -{ - PaUtilStreamRepresentation streamRepresentation; - PaUtilBufferProcessor bufferProcessor; - PaUtilCpuLoadMeasurer cpuLoadMeasurer; - - /* 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. - */ - int is_running; - int is_active; - - jack_nframes_t t0; - unsigned long total_frames_sent; - - PaUtilAllocationGroup *stream_memory; -} -PaJackStream; - -static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, - PaStream** s, - PaDeviceIndex inputDevice, - int numInputChannels, - PaSampleFormat inputSampleFormat, - unsigned long inputLatency, - PaHostApiSpecificStreamInfo *inputStreamInfo, - PaDeviceIndex outputDevice, - int numOutputChannels, - PaSampleFormat outputSampleFormat, - unsigned long outputLatency, - PaHostApiSpecificStreamInfo *outputStreamInfo, - double sampleRate, - unsigned long framesPerCallback, - PaStreamFlags streamFlags, - PortAudioCallback *callback, - void *userData ) -{ - PaError result = paNoError; - PaJackHostApiRepresentation *jackHostApi = (PaJackHostApiRepresentation*)hostApi; - PaJackStream *stream = 0; - char port_string[100]; - char regex_pattern[100]; - const char **jack_ports; - int jack_max_buffer_size = jack_get_buffer_size( jackHostApi->jack_client ); - int i; - - /* the client has no say over the frames per callback */ - - (void)framesPerCallback; - - /* Preliminary checks */ - - /* ... check that input device can support numInputChannels */ - - if( inputDevice != paNoDevice && - numInputChannels > hostApi->deviceInfos[ inputDevice ]->maxInputChannels ) - return paInvalidChannelCount; - - /* ... check that output device can support numOutputChannels */ - - if( outputDevice != paNoDevice && - numOutputChannels > hostApi->deviceInfos[ outputDevice ]->maxOutputChannels) - return paInvalidChannelCount; - - /* ... check that the sample rate exactly matches the ONE acceptable rate */ - -#define ABS(x) ( (x) > 0 ? (x) : -(x) ) - if( ABS(sampleRate - hostApi->deviceInfos[0]->sampleRates[0]) > 1 ) - return paInvalidSampleRate; -#undef ABS - - /* ... this implementation doesn't use custom stream info */ - - if( inputStreamInfo ) - return paIncompatibleStreamInfo; - - /* ... this implementation doesn't use custom stream info */ - - if( outputStreamInfo ) - return paIncompatibleStreamInfo; - - /* ... this implementation doesn't use platform-specific flags */ - if( (streamFlags & paPlatformSpecificFlags) != 0 ) - return paInvalidFlag; - - /* Allocate memory for structuures */ - -#define MALLOC(size) \ - (PaUtil_GroupAllocateMemory( stream->stream_memory, (size) )) - -#define MEMVERIFY(ptr) \ - if( (ptr) == NULL ) \ - { \ - result = paInsufficientMemory; \ - goto error; \ - } - - stream = (PaJackStream*)PaUtil_AllocateMemory( sizeof(PaJackStream) ); - MEMVERIFY( stream ); - - stream->stream_memory = PaUtil_CreateAllocationGroup(); - stream->jack_client = jackHostApi->jack_client; - PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); - - stream->local_input_ports = - (jack_port_t**) MALLOC(sizeof(jack_port_t*) * numInputChannels ); - stream->local_output_ports = - (jack_port_t**) MALLOC( sizeof(jack_port_t*) * numOutputChannels ); - stream->remote_output_ports = - (jack_port_t**) MALLOC( sizeof(jack_port_t*) * numInputChannels ); - stream->remote_input_ports = - (jack_port_t**) MALLOC( sizeof(jack_port_t*) * numOutputChannels ); - - MEMVERIFY( stream->local_input_ports ); - MEMVERIFY( stream->local_output_ports ); - MEMVERIFY( stream->remote_input_ports ); - MEMVERIFY( stream->remote_output_ports ); - - stream->num_incoming_connections = numInputChannels; - stream->num_outgoing_connections = numOutputChannels; - - if( callback ) - { - PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, - &jackHostApi->callbackStreamInterface, callback, userData ); - } - else - { - /* we do not support blocking I/O */ - return paBadIODeviceCombination; - } - - /* create the JACK ports. We cannot connect them until audio - * processing begins */ - - for( i = 0; i < numInputChannels; i++ ) - { - sprintf( port_string, "in_%d", i ); - stream->local_input_ports[i] = jack_port_register( - jackHostApi->jack_client, port_string, - JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ); - } - - for( i = 0; i < numOutputChannels; i++ ) - { - sprintf( port_string, "out_%d", i ); - stream->local_output_ports[i] = jack_port_register( - jackHostApi->jack_client, port_string, - JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); - } - - /* 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( numInputChannels > 0 ) - { - /* ... remote output ports (that we input from) */ - sprintf( regex_pattern, "%s:.*", hostApi->deviceInfos[ inputDevice ]->name ); - jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern, - NULL, JackPortIsOutput); - for( i = 0; i < numInputChannels && jack_ports[i]; i++ ) - { - stream->remote_output_ports[i] = jack_port_by_name( - jackHostApi->jack_client, jack_ports[i] ); - } - if( i < numInputChannels ) - { - /* we found fewer ports than we expected */ - return paInternalError; - } - free( jack_ports ); // XXX: this doesn't happen if we exit prematurely - } - - - if( numOutputChannels > 0 ) - { - /* ... remote input ports (that we output to) */ - sprintf( regex_pattern, "%s:.*", hostApi->deviceInfos[ outputDevice ]->name ); - jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern, - NULL, JackPortIsInput); - for( i = 0; i < numOutputChannels && jack_ports[i]; i++ ) - { - stream->remote_input_ports[i] = jack_port_by_name( - jackHostApi->jack_client, jack_ports[i] ); - } - if( i < numOutputChannels ) - { - /* we found fewer ports than we expected */ - return paInternalError; - } - free( jack_ports ); // XXX: this doesn't happen if we exit prematurely - } - - result = PaUtil_InitializeBufferProcessor( - &stream->bufferProcessor, - numInputChannels, - inputSampleFormat, - paFloat32, /* hostInputSampleFormat */ - numOutputChannels, - outputSampleFormat, - paFloat32, /* hostOutputSampleFormat */ - sampleRate, - streamFlags, - framesPerCallback, - jack_max_buffer_size, - paUtilFixedHostBufferSize, - callback, - userData ); - - if( result != paNoError ) - goto error; - - stream->is_running = FALSE; - stream->t0 = -1;/* set the first time through the callback*/ - stream->total_frames_sent = 0; - - jack_set_process_callback( jackHostApi->jack_client, JackCallback, stream ); - - *s = (PaStream*)stream; - - return result; - -error: - if( stream ) - { - if( stream->stream_memory ) - { - PaUtil_FreeAllAllocations( stream->stream_memory ); - PaUtil_DestroyAllocationGroup( stream->stream_memory ); - } - - PaUtil_FreeMemory( stream ); - } - - return result; - -#undef MALLOC -#undef MEMVERIFY -} - - -static int JackCallback( jack_nframes_t frames, void *userData ) -{ - PaJackStream *stream = (PaJackStream*)userData; - PaTimestamp outTime = 0; /* IMPLEMENT ME */ - int callbackResult; - int chn; - int framesProcessed; - - if( stream->t0 == -1 ) - { - if( stream->num_outgoing_connections == 0 ) - { - /* TODO: how to handle stream time for capture-only operation? */ - } - else - { - /* the beginning time needs to be initialized */ - stream->t0 = jack_frame_time( stream->jack_client ) - - jack_frames_since_cycle_start( stream->jack_client) + - jack_port_get_total_latency( stream->jack_client, - stream->local_output_ports[0] ); - } - } - - PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); - - PaUtil_BeginBufferProcessing( &stream->bufferProcessor, outTime ); - - for( chn = 0; chn < stream->num_incoming_connections; chn++ ) - { - jack_default_audio_sample_t *channel_buf; - 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; - channel_buf = (jack_default_audio_sample_t*) - jack_port_get_buffer( stream->local_output_ports[chn], - frames ); - - PaUtil_SetNonInterleavedOutputChannel( &stream->bufferProcessor, - chn, - channel_buf ); - } - - if( stream->num_incoming_connections > 0 ) - PaUtil_SetInputFrameCount( &stream->bufferProcessor, frames ); - - if( stream->num_outgoing_connections > 0 ) - PaUtil_SetOutputFrameCount( &stream->bufferProcessor, frames ); - - framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, - &callbackResult ); - - PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); - stream->total_frames_sent += frames; - - - if( callbackResult == paContinue ) - { - /* nothing special */ - } - else if( callbackResult == paAbort ) - { - /* finish playback immediately */ - - /* TODO: memset 0 the outgoing samples to "cancel" them */ - - stream->is_active = FALSE; - - /* return nonzero so we get deactivated (and the callback won't - * get called again) */ - return 1; - } - else - { - /* User callback has asked us to stop with paComplete or other non-zero value. */ - - stream->is_active = FALSE; - - /* return nonzero so we get deactivated (and the callback won't - * get called again) */ - return 1; - } - return 0; -} - - -/* - 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; - - PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); - PaUtil_FreeMemory( stream ); - - return result; -} - - -static PaError StartStream( PaStream *s ) -{ - PaError result = paNoError; - PaJackStream *stream = (PaJackStream*)s; - int i; - - /* start the audio thread */ - - jack_activate( stream->jack_client ); - - /* 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++ ) - jack_connect( stream->jack_client, - jack_port_name(stream->remote_output_ports[i]), - jack_port_name(stream->local_input_ports[i] ) ); - } - - if( stream->num_outgoing_connections > 0 ) - { - for( i = 0; i < stream->num_outgoing_connections; i++ ) - jack_connect( stream->jack_client, - jack_port_name(stream->local_output_ports[i]), - jack_port_name(stream->remote_input_ports[i]) ); - } - - stream->is_running = TRUE; - - return result; -} - - -static PaError StopStream( PaStream *s ) -{ - PaError result = paNoError; - PaJackStream *stream = (PaJackStream*)s; - - /* note: this automatically disconnects all ports, since a deactivated - * client is not allowed to have any ports connected */ - jack_deactivate( stream->jack_client ); - - stream->is_running = FALSE; - - /* TODO: block until playback complete */ - - stream->is_active = FALSE; - - return result; -} - - -static PaError AbortStream( PaStream *s ) -{ - PaError result = paNoError; - PaJackStream *stream = (PaJackStream*)s; - - /* There's no way to cancel samples already submitted, but we can - * return immediately */ - - /* note: this automatically disconnects all ports, since a deactivated - * client is not allowed to have any ports connected */ - jack_deactivate( stream->jack_client ); - - stream->is_running = FALSE; - stream->is_active = FALSE; - - return result; -} - - -static PaError IsStreamStopped( PaStream *s ) -{ - PaJackStream *stream = (PaJackStream*)s; - - return stream->is_running == FALSE; -} - - -static PaError IsStreamActive( PaStream *s ) -{ - PaJackStream *stream = (PaJackStream*)s; - - return stream->is_active == TRUE; -} - - -static PaTimestamp GetStreamTime( PaStream *s ) -{ - PaJackStream *stream = (PaJackStream*)s; - - /* TODO: what if we're recording-only? */ - return jack_frame_time( stream->jack_client ) - stream->t0; -} - - -static double GetStreamCpuLoad( PaStream* s ) -{ - PaJackStream *stream = (PaJackStream*)s; - - return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); -} - - diff --git a/pd/portaudio/pa_linux_alsa/blocking_calls.c b/pd/portaudio/pa_linux_alsa/blocking_calls.c deleted file mode 100644 index 6304b117..00000000 --- a/pd/portaudio/pa_linux_alsa/blocking_calls.c +++ /dev/null @@ -1,61 +0,0 @@ - -#include "pa_stream.h" - -#include "pa_linux_alsa.h" - -PaError ReadStream( PaStream* s, - void *buffer, - unsigned long frames ) -{ - PaAlsaStream *stream = (PaAlsaStream*)s; - - /* TODO: handle failure, xruns */ - - if( stream->capture_interleaved ) - { - snd_pcm_mmap_readi( stream->pcm_capture, buffer, frames ); - } - else - { - snd_pcm_mmap_readn( stream->pcm_capture, (void**)buffer, frames ); - } - - return paNoError; -} - - -PaError WriteStream( PaStream* s, - void *buffer, - unsigned long frames ) -{ - PaAlsaStream *stream = (PaAlsaStream*)s; - - if( stream->playback_interleaved ) - { - snd_pcm_mmap_writei( stream->pcm_playback, buffer, frames ); - } - else - { - snd_pcm_mmap_writen( stream->pcm_playback, (void**)buffer, frames ); - } - - return paNoError; -} - - -unsigned long GetStreamReadAvailable( PaStream* s ) -{ - PaAlsaStream *stream = (PaAlsaStream*)s; - - return snd_pcm_avail_update( stream->pcm_capture ); -} - - -unsigned long GetStreamWriteAvailable( PaStream* s ) -{ - PaAlsaStream *stream = (PaAlsaStream*)s; - - return snd_pcm_avail_update( stream->pcm_playback ); -} - - diff --git a/pd/portaudio/pa_linux_alsa/callback_thread.c b/pd/portaudio/pa_linux_alsa/callback_thread.c deleted file mode 100644 index 483557b6..00000000 --- a/pd/portaudio/pa_linux_alsa/callback_thread.c +++ /dev/null @@ -1,374 +0,0 @@ - -#include <sys/poll.h> -#include <limits.h> -#include <math.h> /* abs() */ - -#include <alsa/asoundlib.h> - -#include "pa_linux_alsa.h" - -#define MIN(x,y) ( (x) < (y) ? (x) : (y) ) - -static int wait( PaAlsaStream *stream ) -{ - int need_capture; - int need_playback; - int capture_avail = INT_MAX; - int playback_avail = INT_MAX; - int common_avail; - - if( stream->pcm_capture ) - need_capture = 1; - else - need_capture = 0; - - if( stream->pcm_playback ) - need_playback = 1; - else - need_playback = 0; - - while( need_capture || need_playback ) - { - int playback_pfd_offset=0; - int total_fds = 0; - - /* if the main thread has requested that we stop, do so now */ - pthread_testcancel(); - - /*printf("still polling...\n"); - if( need_capture ) - printf("need capture.\n"); - if( need_playback ) - printf("need playback.\n"); */ - - /* get the fds, packing all applicable fds into a single array, - * so we can check them all with a single poll() call */ - - if( need_capture ) - { - snd_pcm_poll_descriptors( stream->pcm_capture, stream->pfds, - stream->capture_nfds ); - total_fds += stream->capture_nfds; - } - - if( need_playback ) - { - playback_pfd_offset = total_fds; - snd_pcm_poll_descriptors( stream->pcm_playback, - stream->pfds + playback_pfd_offset, - stream->playback_nfds ); - total_fds += stream->playback_nfds; - } - - /* now poll on the combination of playback and capture fds. - * TODO: handle interrupt and/or failure */ - poll( stream->pfds, total_fds, 1000 ); - - /* check the return status of our pfds */ - if( need_capture ) - { - short revents; - snd_pcm_poll_descriptors_revents( stream->pcm_capture, stream->pfds, - stream->capture_nfds, &revents ); - if( revents == POLLIN ) - need_capture = 0; - } - - if( need_playback ) - { - short revents; - snd_pcm_poll_descriptors_revents( stream->pcm_playback, - stream->pfds + playback_pfd_offset, - stream->playback_nfds, &revents ); - //if( revents & POLLOUT ) - //if( revents & POLLERR ) - // printf("polling error!"); - if( revents == POLLOUT ) - need_playback = 0; - } - } - - /* we have now established that there are buffers ready to be - * operated on. Now determine how many frames are available. */ - if( stream->pcm_capture ) - capture_avail = snd_pcm_avail_update( stream->pcm_capture ); - - if( stream->pcm_playback ) - playback_avail = snd_pcm_avail_update( stream->pcm_playback ); - - common_avail = MIN(capture_avail, playback_avail); - common_avail -= common_avail % stream->frames_per_period; - - return common_avail; -} - -static int setup_buffers( PaAlsaStream *stream, int frames_avail ) -{ - int i; - int capture_frames_avail = INT_MAX; - int playback_frames_avail = INT_MAX; - int common_frames_avail; - - if( stream->pcm_capture ) - { - const snd_pcm_channel_area_t *capture_areas; - const snd_pcm_channel_area_t *area; - snd_pcm_uframes_t frames = frames_avail; - - /* I do not understand this code fragment yet, it is copied out of the - * alsa-devel archives... */ - snd_pcm_mmap_begin( stream->pcm_capture, &capture_areas, - &stream->capture_offset, &frames); - - if( stream->capture_interleaved ) - { - void *interleaved_capture_buffer; - area = &capture_areas[0]; - interleaved_capture_buffer = area->addr + - (area->first + area->step * stream->capture_offset) / 8; - PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, - 0, /* starting at channel 0 */ - interleaved_capture_buffer, - 0 /* default numInputChannels */ - ); - } - else - { - /* noninterleaved */ - void *noninterleaved_capture_buffers[1000]; - for( i = 0; i < stream->capture_channels; i++ ) - { - area = &capture_areas[i]; - noninterleaved_capture_buffers[i] = area->addr + - (area->first + area->step * stream->capture_offset) / 8; - PaUtil_SetNonInterleavedInputChannel( &stream->bufferProcessor, - i, - noninterleaved_capture_buffers[i]); - } - } - - capture_frames_avail = frames; - } - - if( stream->pcm_playback ) - { - const snd_pcm_channel_area_t *playback_areas; - const snd_pcm_channel_area_t *area; - snd_pcm_uframes_t frames = frames_avail; - - /* I do not understand this code fragment yet, it is copied out of the - * alsa-devel archives... */ - snd_pcm_mmap_begin( stream->pcm_playback, &playback_areas, - &stream->playback_offset, &frames); - - if( stream->playback_interleaved ) - { - void *interleaved_playback_buffer; - area = &playback_areas[0]; - interleaved_playback_buffer = area->addr + - (area->first + area->step * stream->playback_offset) / 8; - PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, - 0, /* starting at channel 0 */ - interleaved_playback_buffer, - 0 /* default numInputChannels */ - ); - } - else - { - /* noninterleaved */ - void *noninterleaved_playback_buffers[1000]; - for( i = 0; i < stream->playback_channels; i++ ) - { - area = &playback_areas[i]; - noninterleaved_playback_buffers[i] = area->addr + - (area->first + area->step * stream->playback_offset) / 8; - PaUtil_SetNonInterleavedOutputChannel( &stream->bufferProcessor, - i, - noninterleaved_playback_buffers[i]); - } - } - - playback_frames_avail = frames; - } - - - common_frames_avail = MIN(capture_frames_avail, playback_frames_avail); - common_frames_avail -= common_frames_avail % stream->frames_per_period; - //printf( "%d capture frames available\n", capture_frames_avail ); - //printf( "%d frames playback available\n", playback_frames_avail ); - //printf( "%d frames available\n", common_frames_avail ); - - if( stream->pcm_capture ) - PaUtil_SetInputFrameCount( &stream->bufferProcessor, common_frames_avail ); - - if( stream->pcm_playback ) - PaUtil_SetOutputFrameCount( &stream->bufferProcessor, common_frames_avail ); - - return common_frames_avail; -} - -void *CallbackThread( void *userData ) -{ - PaAlsaStream *stream = (PaAlsaStream*)userData; - - if( stream->pcm_capture ) - snd_pcm_start( stream->pcm_capture ); - if( stream->pcm_playback ) - snd_pcm_start( stream->pcm_playback ); - - while(1) - { - int frames_avail; - int frames_got; - - PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* IMPLEMENT ME */ - int callbackResult; - int framesProcessed; - - pthread_testcancel(); - { - /* calculate time info */ - snd_timestamp_t capture_timestamp; - snd_timestamp_t playback_timestamp; - snd_pcm_status_t *capture_status; - snd_pcm_status_t *playback_status; - snd_pcm_status_alloca( &capture_status ); - snd_pcm_status_alloca( &playback_status ); - - if( stream->pcm_capture ) - { - snd_pcm_status( stream->pcm_capture, capture_status ); - snd_pcm_status_get_tstamp( capture_status, &capture_timestamp ); - } - if( stream->pcm_playback ) - { - snd_pcm_status( stream->pcm_playback, playback_status ); - snd_pcm_status_get_tstamp( playback_status, &playback_timestamp ); - } - - /* Hmm, we potentially have both a playback and a capture timestamp. - * Hopefully they are the same... */ - if( stream->pcm_capture && stream->pcm_playback ) - { - float capture_time = capture_timestamp.tv_sec + - ((float)capture_timestamp.tv_usec/1000000); - float playback_time= playback_timestamp.tv_sec + - ((float)playback_timestamp.tv_usec/1000000); - if( fabsf(capture_time-playback_time) > 0.01 ) - printf("Capture time and playback time differ by %f\n", fabsf(capture_time-playback_time)); - timeInfo.currentTime = capture_time; - } - else if( stream->pcm_playback ) - { - timeInfo.currentTime = playback_timestamp.tv_sec + - ((float)playback_timestamp.tv_usec/1000000); - } - else - { - timeInfo.currentTime = capture_timestamp.tv_sec + - ((float)capture_timestamp.tv_usec/1000000); - } - - if( stream->pcm_capture ) - { - snd_pcm_sframes_t capture_delay = snd_pcm_status_get_delay( capture_status ); - timeInfo.inputBufferAdcTime = timeInfo.currentTime - - (float)capture_delay / stream->streamRepresentation.streamInfo.sampleRate; - } - - if( stream->pcm_playback ) - { - snd_pcm_sframes_t playback_delay = snd_pcm_status_get_delay( playback_status ); - timeInfo.outputBufferDacTime = timeInfo.currentTime + - (float)playback_delay / stream->streamRepresentation.streamInfo.sampleRate; - } - } - - - /* - IMPLEMENT ME: - - handle buffer slips - */ - - /* - depending on whether the host buffers are interleaved, non-interleaved - or a mixture, you will want to call PaUtil_ProcessInterleavedBuffers(), - PaUtil_ProcessNonInterleavedBuffers() or PaUtil_ProcessBuffers() here. - */ - - frames_avail = wait( stream ); - //printf( "%d frames available\n", frames_avail ); - - /* Now we know the soundcard is ready to produce/receive at least - * one period. We just need to get the buffers for the client - * to read/write. */ - PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo ); - - frames_got = setup_buffers( stream, frames_avail ); - - if( frames_avail == frames_got ) - ;//printf("good, they were both %d\n", frames_avail ); - else - printf("damn, they were different: avail: %d, got: %d\n", frames_avail, frames_got ); - - /* this calls the callback */ - - PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); - - framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, - &callbackResult ); - - PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); - - /* inform ALSA how many frames we wrote */ - - if( stream->pcm_capture ) - snd_pcm_mmap_commit( stream->pcm_capture, stream->capture_offset, frames_avail ); - - if( stream->pcm_playback ) - snd_pcm_mmap_commit( stream->pcm_playback, stream->playback_offset, frames_avail ); - - - /* - If you need to byte swap outputBuffer, you can do it here using - routines in pa_byteswappers.h - */ - - if( callbackResult == paContinue ) - { - /* nothing special to do */ - } - else if( callbackResult == paAbort ) - { - stream->callback_finished = 1; - - if( stream->pcm_capture ) - { - snd_pcm_drop( stream->pcm_capture ); - } - - if( stream->pcm_playback ) - { - snd_pcm_drop( stream->pcm_playback ); - } - pthread_exit(NULL); - } - else - { - stream->callback_finished = 1; - - if( stream->pcm_capture ) - { - snd_pcm_drain( stream->pcm_capture ); - } - - if( stream->pcm_playback ) - { - snd_pcm_drain( stream->pcm_playback ); - } - pthread_exit(NULL); - } - - } -} - diff --git a/pd/portaudio/pa_linux_alsa/pa_linux_alsa.c b/pd/portaudio/pa_linux_alsa/pa_linux_alsa.c deleted file mode 100644 index 9582b5b8..00000000 --- a/pd/portaudio/pa_linux_alsa/pa_linux_alsa.c +++ /dev/null @@ -1,989 +0,0 @@ -/* - * $Id: pa_linux_alsa.c,v 1.1.2.3 2003/02/01 21:55:03 joshua Exp $ - * PortAudio Portable Real-Time Audio Library - * Latest Version at: http://www.portaudio.com - * ALSA implementation by Joshua Haberman - * - * 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 <sys/poll.h> -#include <pthread.h> - -#include <string.h> /* strlen() */ -#include <limits.h> - -#include <alsa/asoundlib.h> - -#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_linux_alsa.h" - -/* PaAlsaHostApiRepresentation - host api datastructure specific to this implementation */ - -typedef struct -{ - PaUtilHostApiRepresentation commonHostApiRep; - PaUtilStreamInterface callbackStreamInterface; - PaUtilStreamInterface blockingStreamInterface; - - PaUtilAllocationGroup *allocations; - - PaHostApiIndex hostApiIndex; -} -PaAlsaHostApiRepresentation; - - -/* prototypes for functions declared in this file */ - -PaError PaAlsa_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 *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 ); - -/* blocking calls are in blocking_calls.c */ -extern PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); -extern PaError WriteStream( PaStream* stream, void *buffer, unsigned long frames ); -extern signed long GetStreamReadAvailable( PaStream* stream ); -extern signed long GetStreamWriteAvailable( PaStream* stream ); - -/* all callback-related functions are in callback_thread.c */ -extern void *CallbackThread( void *userData ); - - -PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) -{ - PaError result = paNoError; - int i, deviceCount; - PaAlsaHostApiRepresentation *skeletonHostApi; - - skeletonHostApi = (PaAlsaHostApiRepresentation*) - PaUtil_AllocateMemory( sizeof(PaAlsaHostApiRepresentation) ); - if( !skeletonHostApi ) - { - result = paInsufficientMemory; - goto error; - } - - skeletonHostApi->allocations = PaUtil_CreateAllocationGroup(); - if( !skeletonHostApi->allocations ) - { - result = paInsufficientMemory; - goto error; - } - - skeletonHostApi->hostApiIndex = hostApiIndex; - *hostApi = (PaUtilHostApiRepresentation*)skeletonHostApi; - (*hostApi)->info.structVersion = 1; - (*hostApi)->info.type = paALSA; - (*hostApi)->info.name = "ALSA implementation"; - - BuildDeviceList( skeletonHostApi ); - - (*hostApi)->Terminate = Terminate; - (*hostApi)->OpenStream = OpenStream; - - PaUtil_InitializeStreamInterface( &skeletonHostApi->callbackStreamInterface, - CloseStream, StartStream, - StopStream, AbortStream, - IsStreamStopped, IsStreamActive, - GetStreamTime, GetStreamCpuLoad, - PaUtil_DummyReadWrite, PaUtil_DummyReadWrite, - PaUtil_DummyGetAvailable, - PaUtil_DummyGetAvailable ); - - 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 PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi ) -{ - PaUtilHostApiRepresentation *commonApi = &alsaApi->commonHostApiRep; - PaDeviceInfo *deviceInfoArray; - int deviceCount = 0; - int card_idx; - int device_idx; - snd_ctl_t *ctl; - snd_ctl_card_info_t *card_info; - - /* 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. */ - card_idx = -1; - while( snd_card_next( &card_idx ) == 0 && card_idx >= 0 ) - { - deviceCount++; - } - - /* allocate deviceInfo memory based on the number of devices */ - - commonApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( - alsaApi->allocations, sizeof(PaDeviceInfo*) * deviceCount ); - if( !commonApi->deviceInfos ) - { - return paInsufficientMemory; - } - - /* allocate all device info structs in a contiguous block */ - deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( - alsaApi->allocations, sizeof(PaDeviceInfo) * deviceCount ); - if( !deviceInfoArray ) - { - return paInsufficientMemory; - } - - /* now loop over the list of devices again, filling in the deviceInfo for each */ - card_idx = -1; - device_idx = 0; - while( snd_card_next( &card_idx ) == 0 && card_idx >= 0 ) - { - PaDeviceInfo *deviceInfo = &deviceInfoArray[device_idx]; - char *deviceName; - char alsaDeviceName[50]; - const char *cardName; - - commonApi->deviceInfos[device_idx++] = deviceInfo; - - deviceInfo->structVersion = 2; - deviceInfo->hostApi = alsaApi->hostApiIndex; - - sprintf( alsaDeviceName, "hw:%d", card_idx ); - snd_ctl_open( &ctl, alsaDeviceName, 0 ); - snd_ctl_card_info_malloc( &card_info ); - snd_ctl_card_info( ctl, card_info ); - cardName = snd_ctl_card_info_get_id( card_info ); - - deviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations, - strlen(cardName) + 1 ); - if( !deviceName ) - { - return paInsufficientMemory; - } - strcpy( deviceName, cardName ); - deviceInfo->name = deviceName; - - snd_ctl_card_info_free( card_info ); - - /* to determine max. channels, we must open the device and query the - * hardware parameter configuration space */ - { - snd_pcm_t *pcm_handle; - snd_pcm_hw_params_t *hw_params; - int dir; - - snd_pcm_hw_params_malloc( &hw_params ); - - /* get max channels for capture */ - - if( snd_pcm_open( &pcm_handle, alsaDeviceName, SND_PCM_STREAM_CAPTURE, 0 ) < 0 ) - { - deviceInfo->maxInputChannels = 0; - } - else - { - snd_pcm_hw_params_any( pcm_handle, hw_params ); - deviceInfo->maxInputChannels = snd_pcm_hw_params_get_channels_max( hw_params ); - /* TODO: I'm not really sure what to do here */ - //deviceInfo->defaultLowInputLatency = snd_pcm_hw_params_get_period_size_min( hw_params, &dir ); - //deviceInfo->defaultHighInputLatency = snd_pcm_hw_params_get_period_size_max( hw_params, &dir ); - deviceInfo->defaultLowInputLatency = 128. / 44100; - deviceInfo->defaultHighInputLatency = 16384. / 44100; - snd_pcm_close( pcm_handle ); - } - - /* get max channels for playback */ - if( snd_pcm_open( &pcm_handle, alsaDeviceName, SND_PCM_STREAM_PLAYBACK, 0 ) < 0 ) - { - deviceInfo->maxOutputChannels = 0; - } - else - { - snd_pcm_hw_params_any( pcm_handle, hw_params ); - deviceInfo->maxOutputChannels = snd_pcm_hw_params_get_channels_max( hw_params ); - /* TODO: I'm not really sure what to do here */ - //deviceInfo->defaultLowOutputLatency = snd_pcm_hw_params_get_period_size_min( hw_params, &dir ); - //deviceInfo->defaultHighOutputLatency = snd_pcm_hw_params_get_period_size_max( hw_params, &dir ); - deviceInfo->defaultLowOutputLatency = 128. / 44100; - deviceInfo->defaultHighOutputLatency = 16384. / 44100; - snd_pcm_close( pcm_handle ); - } - - snd_pcm_hw_params_free( hw_params ); - } - - deviceInfo->defaultSampleRate = 44100.; /* IMPLEMENT ME */ - } - - commonApi->info.deviceCount = deviceCount; - commonApi->info.defaultInputDevice = 0; - commonApi->info.defaultOutputDevice = 0; - - return paNoError; -} - - -static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) -{ - PaAlsaHostApiRepresentation *skeletonHostApi; - skeletonHostApi = (PaAlsaHostApiRepresentation*)hostApi; - - /* - IMPLEMENT ME: - - clean up any resourced not handled by the allocation group - */ - - if( skeletonHostApi->allocations ) - { - PaUtil_FreeAllAllocations( skeletonHostApi->allocations ); - PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations ); - } - - PaUtil_FreeMemory( skeletonHostApi ); -} - - -/* Given an open stream, what sample formats are available? */ - -static PaSampleFormat GetAvailableFormats( snd_pcm_t *stream ) -{ - PaSampleFormat available = 0; - snd_pcm_hw_params_t *hw_params; - snd_pcm_hw_params_alloca( &hw_params ); - - snd_pcm_hw_params_any( stream, hw_params ); - - if( snd_pcm_hw_params_test_format( stream, hw_params, SND_PCM_FORMAT_FLOAT ) == 0) - available |= paFloat32; - - if( snd_pcm_hw_params_test_format( stream, hw_params, SND_PCM_FORMAT_S16 ) == 0) - available |= paInt16; - - if( snd_pcm_hw_params_test_format( stream, hw_params, SND_PCM_FORMAT_S24 ) == 0) - available |= paInt24; - - if( snd_pcm_hw_params_test_format( stream, hw_params, SND_PCM_FORMAT_S32 ) == 0) - available |= paInt32; - - if( snd_pcm_hw_params_test_format( stream, hw_params, SND_PCM_FORMAT_S8 ) == 0) - available |= paInt8; - - if( snd_pcm_hw_params_test_format( stream, hw_params, SND_PCM_FORMAT_U8 ) == 0) - available |= paUInt8; - - return available; -} - -/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ - -static PaError ConfigureStream( snd_pcm_t *stream, int channels, - int interleaved, unsigned long rate, - PaSampleFormat pa_format, int framesPerBuffer ) -{ -#define ENSURE(functioncall) \ - if( (functioncall) < 0 ) { \ - printf("Error executing ALSA call, line %d\n", __LINE__); \ - return 1; \ - } \ - else { \ - printf("ALSA call at line %d succeeded\n", __LINE__ ); \ - } - - snd_pcm_access_t access_mode; - snd_pcm_format_t alsa_format; - - /* 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. */ - - snd_pcm_hw_params_t *hw_params; - snd_pcm_sw_params_t *sw_params; - - snd_pcm_hw_params_alloca( &hw_params ); - - /* ... fill up the configuration space with all possibile - * combinations of parameters this device will accept */ - ENSURE( snd_pcm_hw_params_any( stream, hw_params ) ); - - if( interleaved ) - access_mode = SND_PCM_ACCESS_MMAP_INTERLEAVED; - else - access_mode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED; - - ENSURE( snd_pcm_hw_params_set_access( stream, hw_params, access_mode ) ); - - /* set the format based on what the user selected */ - switch( pa_format ) - { - case paFloat32: - alsa_format = SND_PCM_FORMAT_FLOAT; - break; - - case paInt16: - alsa_format = SND_PCM_FORMAT_S16; - break; - - case paInt24: - alsa_format = SND_PCM_FORMAT_S24; - break; - - case paInt32: - alsa_format = SND_PCM_FORMAT_S32; - break; - - case paInt8: - alsa_format = SND_PCM_FORMAT_S8; - break; - - case paUInt8: - alsa_format = SND_PCM_FORMAT_U8; - break; - - default: - printf("Unknown PortAudio format %d\n", (int)pa_format ); - return 1; - } - //printf("PortAudio format: %d\n", pa_format); - printf("ALSA format: %d\n", alsa_format); - ENSURE( snd_pcm_hw_params_set_format( stream, hw_params, alsa_format ) ); - - /* ... set the sample rate */ - ENSURE( snd_pcm_hw_params_set_rate( stream, hw_params, rate, 0 ) ); - - /* ... set the number of channels */ - ENSURE( snd_pcm_hw_params_set_channels( stream, hw_params, channels ) ); - - /* ... set the number of periods to 2, which is essentially double buffering. - * this makes the latency the number of samples per buffer, which is the best - * it can be */ - ENSURE( snd_pcm_hw_params_set_periods ( stream, hw_params, 2, 0 ) ); - - /* ... set the period size, which is essentially the hardware buffer size */ - if( framesPerBuffer != 0 ) - { - ENSURE( snd_pcm_hw_params_set_period_size( stream, hw_params, - framesPerBuffer, 0 ) ); - } - else - { - ENSURE( snd_pcm_hw_params_set_period_size( stream, hw_params, - 2048, 0 ) ); - } - - - /* Set the parameters! */ - ENSURE( snd_pcm_hw_params( stream, hw_params ) ); - - return 0; -#undef ENSURE -} - -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 *skeletonHostApi = - (PaAlsaHostApiRepresentation*)hostApi; - PaAlsaStream *stream = 0; - PaSampleFormat hostInputSampleFormat=0, hostOutputSampleFormat=0; - int numInputChannels, numOutputChannels; - PaSampleFormat inputSampleFormat=0, outputSampleFormat=0; - unsigned long framesPerHostBuffer = framesPerBuffer; - - if( framesPerHostBuffer == paFramesPerBufferUnspecified ) - { - // TODO: have some reason - framesPerHostBuffer = 2048; - } - - if( inputParameters ) - { - numInputChannels = inputParameters->channelCount; - inputSampleFormat = inputParameters->sampleFormat; - - /* unless alternate device specification is supported, reject the use of - paUseHostApiSpecificDeviceSpecification. - [JH] this could be supported in the future, to allow ALSA device strings - like hw:0 */ - if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) - return paInvalidDevice; - - /* check that input device can support numInputChannels */ - if( numInputChannels > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) - return paInvalidChannelCount; - - /* validate inputStreamInfo */ - if( inputParameters->hostApiSpecificStreamInfo ) - return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ - } - else - { - numInputChannels = 0; - } - - if( outputParameters ) - { - numOutputChannels = outputParameters->channelCount; - outputSampleFormat = outputParameters->sampleFormat; - - /* unless alternate device specification is supported, reject the use of - paUseHostApiSpecificDeviceSpecification - [JH] this could be supported in the future, to allow ALSA device strings - like hw:0 */ - - if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) - return paInvalidDevice; - - /* check that output device can support numInputChannels */ - if( numOutputChannels > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) - return paInvalidChannelCount; - - /* validate outputStreamInfo */ - if( outputParameters->hostApiSpecificStreamInfo ) - return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ - } - else - { - numOutputChannels = 0; - } - - /* validate platform specific flags */ - if( (streamFlags & paPlatformSpecificFlags) != 0 ) - return paInvalidFlag; /* unexpected platform specific flag */ - - /* allocate and do basic initialization of the stream structure */ - - stream = (PaAlsaStream*)PaUtil_AllocateMemory( sizeof(PaAlsaStream) ); - if( !stream ) - { - printf("memory point 2\n"); - result = paInsufficientMemory; - goto error; - } - - stream->pcm_capture = NULL; - stream->pcm_playback = NULL; - stream->callback_mode = (callback != 0); - stream->callback_finished = 0; - - if( callback ) - { - PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, - &skeletonHostApi->callbackStreamInterface, - callback, userData ); - } - else - { - PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, - &skeletonHostApi->blockingStreamInterface, - callback, userData ); - } - - - stream->streamRepresentation.streamInfo.inputLatency = framesPerHostBuffer; - stream->streamRepresentation.streamInfo.outputLatency = framesPerHostBuffer; - stream->streamRepresentation.streamInfo.sampleRate = sampleRate; - - PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); - - /* open the devices now, so we can obtain info about the available formats */ - - if( numInputChannels > 0 ) - { - char inputDeviceName[50]; - - sprintf( inputDeviceName, "hw:CARD=%s", hostApi->deviceInfos[inputParameters->device]->name ); - if( snd_pcm_open( &stream->pcm_capture, inputDeviceName, SND_PCM_STREAM_CAPTURE, 0 ) < 0 ) - { - result = paBadIODeviceCombination; - goto error; - } - hostInputSampleFormat = - PaUtil_SelectClosestAvailableFormat( GetAvailableFormats(stream->pcm_capture), - inputSampleFormat ); - } - - if( numOutputChannels > 0 ) - { - char outputDeviceName[50]; - - sprintf( outputDeviceName, "hw:CARD=%s", hostApi->deviceInfos[outputParameters->device]->name ); - if( snd_pcm_open( &stream->pcm_playback, outputDeviceName, SND_PCM_STREAM_PLAYBACK, 0 ) < 0 ) - { - result = paBadIODeviceCombination; - goto error; - } - hostOutputSampleFormat = - PaUtil_SelectClosestAvailableFormat( GetAvailableFormats(stream->pcm_playback), - outputSampleFormat ); - stream->playback_hostsampleformat = hostOutputSampleFormat; - } - - - - result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, - numInputChannels, inputSampleFormat, hostInputSampleFormat, - numOutputChannels, outputSampleFormat, hostOutputSampleFormat, - sampleRate, streamFlags, framesPerBuffer, framesPerHostBuffer, - paUtilFixedHostBufferSize, callback, userData ); - if( result != paNoError ) - goto error; - - /* configure the streams */ - - if( numInputChannels > 0 ) - { - int interleaved; - PaSampleFormat plain_format = hostInputSampleFormat & ~paNonInterleaved; - - if( inputSampleFormat & paNonInterleaved ) - interleaved = 0; - else - interleaved = 1; - - if( ConfigureStream( stream->pcm_capture, numInputChannels, interleaved, - sampleRate, plain_format, framesPerHostBuffer ) != 0 ) - { - result = paBadIODeviceCombination; - goto error; - } - - stream->capture_interleaved = interleaved; - } - - if( numOutputChannels > 0 ) - { - int interleaved; - PaSampleFormat plain_format = hostOutputSampleFormat & ~paNonInterleaved; - - if( outputSampleFormat & paNonInterleaved ) - interleaved = 0; - else - interleaved = 1; - - if( ConfigureStream( stream->pcm_playback, numOutputChannels, interleaved, - sampleRate, plain_format, framesPerHostBuffer ) != 0 ) - { - result = paBadIODeviceCombination; - goto error; - } - - stream->playback_interleaved = interleaved; - } - - stream->capture_nfds = 0; - stream->playback_nfds = 0; - - if( stream->pcm_capture ) - stream->capture_nfds = snd_pcm_poll_descriptors_count( stream->pcm_capture ); - - if( stream->pcm_playback ) - stream->playback_nfds = snd_pcm_poll_descriptors_count( stream->pcm_playback ); - - /* TODO: free this properly */ - printf("trying to allocate %d bytes of memory\n", (stream->capture_nfds + stream->playback_nfds + 1) * sizeof(struct pollfd) ); - stream->pfds = (struct pollfd*)PaUtil_AllocateMemory( (stream->capture_nfds + - stream->playback_nfds + 1) * - sizeof(struct pollfd) ); - if( !stream->pfds ) - { - printf("bad memory point 1\n"); - result = paInsufficientMemory; - goto error; - } - - stream->frames_per_period = framesPerHostBuffer; - stream->capture_channels = numInputChannels; - stream->playback_channels = numOutputChannels; - - *s = (PaStream*)stream; - - return result; - -error: - if( stream ) - PaUtil_FreeMemory( stream ); - - 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; - PaAlsaStream *stream = (PaAlsaStream*)s; - - if( stream->pcm_capture ) - { - snd_pcm_close( stream->pcm_capture ); - } - - if( stream->pcm_playback ) - { - snd_pcm_close( stream->pcm_playback ); - } - - PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); - PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); - PaUtil_FreeMemory( stream ); - - return result; -} - - -static PaError StartStream( PaStream *s ) -{ - PaError result = paNoError; - PaAlsaStream *stream = (PaAlsaStream*)s; - - /* TODO: support errorText */ -#define ENSURE(x) \ - { \ - int error_ret; \ - error_ret = (x); \ - if( error_ret != 0 ) { \ - PaHostErrorInfo err; \ - err.errorCode = error_ret; \ - err.hostApiType = paALSA; \ - printf("call at %d failed\n", __LINE__); \ - return paUnanticipatedHostError; \ - } \ - else \ - printf("call at line %d succeeded\n", __LINE__); \ - } - - if( stream->pcm_capture ) - { - ENSURE( snd_pcm_prepare( stream->pcm_capture ) ); - } - - if( stream->pcm_playback ) - { - const snd_pcm_channel_area_t *playback_areas, *area; - snd_pcm_uframes_t offset, frames; - int sample_size = Pa_GetSampleSize( stream->playback_hostsampleformat ); - printf("Sample size: %d\n", sample_size ); - ENSURE( snd_pcm_prepare( stream->pcm_playback ) ); - frames = snd_pcm_avail_update( stream->pcm_playback ); - printf("frames: %d\n", (int)frames ); - printf("channels: %d\n", stream->playback_channels ); - - snd_pcm_mmap_begin( stream->pcm_playback, &playback_areas, &offset, &frames ); - - /* Insert silence */ - if( stream->playback_interleaved ) - { - void *playback_buffer; - area = &playback_areas[0]; - playback_buffer = area->addr + (area->first + area->step * offset) / 8; - memset( playback_buffer, 0, - frames * stream->playback_channels * sample_size ); - } - else - { - int i; - for( i = 0; i < stream->playback_channels; i++ ) - { - void *channel_buffer; - area = &playback_areas[i]; - channel_buffer = area->addr + (area->first + area->step * offset) / 8; - memset( channel_buffer, 0, frames * sample_size ); - } - } - - snd_pcm_mmap_commit( stream->pcm_playback, offset, frames ); - } - - if( stream->callback_mode ) - { - ENSURE( pthread_create( &stream->callback_thread, NULL, &CallbackThread, stream ) ); - - /* we'll do the snd_pcm_start() in the callback thread */ - } - else - { - if( stream->pcm_capture ) - snd_pcm_start( stream->pcm_capture ); - if( stream->pcm_playback ) - snd_pcm_start( stream->pcm_playback ); - } - - /* On my machine, the pcm stream will not transition to the RUNNING - * state for a while after snd_pcm_start is called. The PortAudio - * client needs to be able to depend on Pa_IsStreamActive() returning - * true the second after this function returns. So I sleep briefly here. - * - * I don't like this one bit. - */ - Pa_Sleep( 100 ); - - stream->callback_finished = 0; - - return result; -} - - -static PaError StopStream( PaStream *s ) -{ - PaError result = paNoError; - PaAlsaStream *stream = (PaAlsaStream*)s; - - /* First deal with the callback thread, cancelling and/or joining - * it if necessary - */ - - if( stream->callback_mode && stream->callback_finished ) - { - /* We are running in callback mode but the callback thread has - * already been cancelled by the return value from the user's - * callback function. Therefore we don't need to cancel the - * thread, but we do want to wait for it. */ - pthread_join( stream->callback_thread, NULL ); - } - else if( stream->callback_mode ) - { - /* We are running in callback mode, and the callback thread - * is still running. Cancel it and wait for it to be done. */ - pthread_cancel( stream->callback_thread ); - pthread_join( stream->callback_thread, NULL ); - } - - /* Stop the ALSA streams if necessary */ - - if( stream->callback_mode && stream->callback_finished ) - { - /* If we are in the callback_finished state the callback thread - * already stopped the streams. So there is nothing to do here. - */ - } - else - { - if( stream->pcm_capture ) - { - snd_pcm_drain( stream->pcm_capture ); - } - - if( stream->pcm_playback ) - { - snd_pcm_drain( stream->pcm_playback ); - } - } - - stream->callback_finished = 0; - - return result; -} - - -static PaError AbortStream( PaStream *s ) -{ - PaError result = paNoError; - PaAlsaStream *stream = (PaAlsaStream*)s; - - /* First deal with the callback thread, cancelling and/or joining - * it if necessary - */ - - if( stream->callback_mode && stream->callback_finished ) - { - /* We are running in callback mode but the callback thread has - * already been cancelled by the return value from the user's - * callback function. Therefore we don't need to cancel the - * thread, but we do want to wait for it. */ - pthread_join( stream->callback_thread, NULL ); - } - else if( stream->callback_mode ) - { - /* We are running in callback mode, and the callback thread - * is still running. Cancel it and wait for it to be done. */ - pthread_cancel( stream->callback_thread ); - pthread_join( stream->callback_thread, NULL ); - } - - /* Stop the ALSA streams if necessary */ - - if( stream->callback_mode && stream->callback_finished ) - { - /* If we are in the callback_finished state the callback thread - * already stopped the streams. So there is nothing to do here. - */ - } - else - { - if( stream->pcm_capture ) - { - snd_pcm_drop( stream->pcm_capture ); - } - - if( stream->pcm_playback ) - { - snd_pcm_drop( stream->pcm_playback ); - } - } - - stream->callback_finished = 0; - - return result; -} - - -static PaError IsStreamStopped( PaStream *s ) -{ - PaAlsaStream *stream = (PaAlsaStream*)s; - - if( IsStreamActive(s) || stream->callback_finished ) - return 0; - else - return 1; -} - - -static PaError IsStreamActive( PaStream *s ) -{ - PaAlsaStream *stream = (PaAlsaStream*)s; - - if( stream->pcm_capture ) - { - snd_pcm_state_t capture_state = snd_pcm_state( stream->pcm_capture ); - - if( capture_state == SND_PCM_STATE_RUNNING /*|| - capture_state == SND_PCM_STATE_PREPARED*/ ) - return 1; - } - - if( stream->pcm_playback ) - { - snd_pcm_state_t playback_state = snd_pcm_state( stream->pcm_playback ); - - if( playback_state == SND_PCM_STATE_RUNNING /*|| - playback_state == SND_PCM_STATE_PREPARED*/ ) - return 1; - } - - return 0; -} - - -static PaTime GetStreamTime( PaStream *s ) -{ - PaAlsaStream *stream = (PaAlsaStream*)s; - - snd_output_t *output; - 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 form multiple threads. - * need to verify that libasound is thread-safe. */ - - if( stream->pcm_capture ) - { - snd_pcm_status( stream->pcm_capture, status ); - } - else if( stream->pcm_playback ) - { - snd_pcm_status( stream->pcm_playback, status ); - } - - snd_pcm_status_get_tstamp( status, ×tamp ); - - return timestamp.tv_sec + ((float)timestamp.tv_usec/1000000); -} - - -static double GetStreamCpuLoad( PaStream* s ) -{ - PaAlsaStream *stream = (PaAlsaStream*)s; - - return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); -} - diff --git a/pd/portaudio/pa_linux_alsa/pa_linux_alsa.h b/pd/portaudio/pa_linux_alsa/pa_linux_alsa.h deleted file mode 100644 index 62c9512c..00000000 --- a/pd/portaudio/pa_linux_alsa/pa_linux_alsa.h +++ /dev/null @@ -1,45 +0,0 @@ - -#include <alsa/asoundlib.h> - -#include <pthread.h> - -#include "pa_util.h" -#include "pa_process.h" -#include "pa_cpuload.h" -#include "pa_stream.h" - -typedef struct PaAlsaStream -{ - PaUtilStreamRepresentation streamRepresentation; - PaUtilCpuLoadMeasurer cpuLoadMeasurer; - PaUtilBufferProcessor bufferProcessor; - - snd_pcm_t *pcm_capture; - snd_pcm_t *pcm_playback; - - int callback_finished; /* bool: are we in the "callback finished" state? */ - - int frames_per_period; - int playback_hostsampleformat; - - int capture_channels; - int playback_channels; - - int capture_interleaved; /* bool: is capture interleaved? */ - int playback_interleaved; /* bool: is playback interleaved? */ - - int callback_mode; /* bool: are we running in callback mode? */ - pthread_t callback_thread; - - /* the callback thread uses these to poll the sound device, waiting - * for data to be ready/available */ - unsigned int capture_nfds; - unsigned int playback_nfds; - struct pollfd *pfds; - - /* these aren't really stream state, the callback uses them */ - snd_pcm_uframes_t capture_offset; - snd_pcm_uframes_t playback_offset; -} -PaAlsaStream; - diff --git a/pd/portaudio/pa_mac_core/notes.txt b/pd/portaudio/pa_mac_core/notes.txt deleted file mode 100644 index c79b90e6..00000000 --- a/pd/portaudio/pa_mac_core/notes.txt +++ /dev/null @@ -1,34 +0,0 @@ -Notes on Core Audio Implementation of PortAudio - -by Phil Burk and Darren Gibbs - -Document last updated March 20, 2002 - -WHAT WORKS - -Output with very low latency, <10 msec. -Half duplex input or output. -Full duplex on the same CoreAudio device. -The paFLoat32, paInt16, paInt8, paUInt8 sample formats. -Pa_GetCPULoad() -Pa_StreamTime() - -KNOWN BUGS OR LIMITATIONS - -We do not yet support simultaneous input and output on different -devices. Note that some CoreAudio devices like the Roland UH30 look -like one device but are actually two different CoreAudio devices. The -BuiltIn audio is typically one CoreAudio device. - -Mono doesn't work. - -DEVICE MAPPING - -CoreAudio devices can support both input and output. But the sample -rates supported may be different. So we have map one or two PortAudio -device to each CoreAudio device depending on whether it supports -input, output or both. - -When we query devices, we first get a list of CoreAudio devices. Then -we scan the list and add a PortAudio device for each CoreAudio device -that supports input. Then we make a scan for output devices. diff --git a/pd/portaudio/pa_mac_core/pa_mac_core.c b/pd/portaudio/pa_mac_core/pa_mac_core.c deleted file mode 100644 index 9a4b1488..00000000 --- a/pd/portaudio/pa_mac_core/pa_mac_core.c +++ /dev/null @@ -1,1261 +0,0 @@ -/* - * $Id: pa_mac_core.c,v 1.8 2002/04/12 18:07:20 philburk Exp $ - * pa_mac_core.c - * Implementation of PortAudio for Mac OS X Core Audio - * - * PortAudio Portable Real-Time Audio Library - * Latest Version at: http://www.portaudio.com - * - * Authors: Ross Bencina and Phil Burk - * Copyright (c) 1999-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. - * - * CHANGE HISTORY: - - 3.29.2001 - Phil Burk - First pass... converted from Window MME code with help from Darren. - 3.30.2001 - Darren Gibbs - Added more support for dynamically querying device info. - 12.7.2001 - Gord Peters - Tweaks to compile on PA V17 and OS X 10.1 - 2.7.2002 - Darren and Phil - fixed isInput so GetProperty works better, - fixed device queries for numChannels and sampleRates, - one CoreAudio device now maps to separate input and output PaDevices, - audio input works if using same CoreAudio device (some HW devices make separate CoreAudio devices). - 2.22.2002 - Stephane Letz - Explicit cast needed for compilation with Code Warrior 7 - 3.19.2002 - Phil Burk - Added paInt16, paInt8, format using new "pa_common/pa_convert.c" file. - Return error if opened in mono mode cuz not supported. - Add support for Pa_GetCPULoad(); - Fixed timestamp in callback and Pa_StreamTime() (Thanks n++k for the advice!) - Check for invalid sample rates and return an error. - Check for getenv("PA_MIN_LATEWNCY_MSEC") to set latency externally. - Better error checking for invalid channel counts and invalid devices. - 3.29.2002 - Phil Burk - Fixed Pa_GetCPULoad() for small buffers. - 3.31.2002 - Phil Burk - Use getrusage() instead of gettimeofday() for CPU Load calculation. - -TODO: -O- how do mono output? -O- FIFO between input and output callbacks if different devices, like in pa_mac.c -*/ - -#include <CoreServices/CoreServices.h> -#include <CoreAudio/CoreAudio.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <unistd.h> - -#include "portaudio.h" -#include "pa_host.h" -#include "pa_trace.h" - -/************************************************* Constants ********/ - -/* To trace program, enable TRACE_REALTIME_EVENTS in pa_trace.h */ -#define PA_TRACE_RUN (0) -#define PA_TRACE_START_STOP (1) - -#define PA_MIN_LATENCY_MSEC (8) -#define MIN_TIMEOUT_MSEC (1000) - -#define PRINT(x) { printf x; fflush(stdout); } -#define ERR_RPT(x) PRINT(x) -#define DBUG(x) /* PRINT(x) /**/ -#define DBUGX(x) /* PRINT(x) /**/ - -// define value of isInput passed to CoreAudio routines -#define IS_INPUT (true) -#define IS_OUTPUT (false) - -/************************************************************** - * Structure for internal host specific stream data. - * This is allocated on a per stream basis. - */ -typedef struct PaHostSoundControl -{ - AudioDeviceID pahsc_AudioDeviceID; // Must be the same for input and output for now. - /* Input -------------- */ - int pahsc_BytesPerUserNativeInputBuffer; /* native buffer size in bytes per user chunk */ - /* Output -------------- */ - int pahsc_BytesPerUserNativeOutputBuffer; /* native buffer size in bytes per user chunk */ - /* Init Time -------------- */ - int pahsc_FramesPerHostBuffer; - int pahsc_UserBuffersPerHostBuffer; - /* For measuring CPU utilization. */ - struct rusage pahsc_EntryRusage; - double pahsc_InverseMicrosPerHostBuffer; /* 1/Microseconds of real-time audio per user buffer. */ -} -PaHostSoundControl; - -/************************************************************** - * Structure for internal extended device info. - * There will be one or two PortAudio devices for each Core Audio device: - * one input and or one output. - */ -typedef struct PaHostDeviceInfo -{ - PaDeviceInfo paInfo; - AudioDeviceID audioDeviceID; -} -PaHostDeviceInfo; - -/************************************************* Shared Data ********/ -/* FIXME - put Mutex around this shared data. */ -static int sNumPaDevices = 0; /* Total number of PaDeviceInfos */ -static int sNumInputDevices = 0; /* Total number of input PaDeviceInfos */ -static int sNumOutputDevices = 0; -static PaHostDeviceInfo *sDeviceInfos = NULL; -static int sDefaultInputDeviceID = paNoDevice; -static int sDefaultOutputDeviceID = paNoDevice; -static int sPaHostError = 0; - -static int sNumCoreDevices = 0; -static AudioDeviceID *sCoreDeviceIDs; // Array of Core AudioDeviceIDs - -static const char sMapperSuffixInput[] = " - Input"; -static const char sMapperSuffixOutput[] = " - Output"; - -/* We index the input devices first, then the output devices. */ -#define LOWEST_INPUT_DEVID (0) -#define HIGHEST_INPUT_DEVID (sNumInputDevices - 1) -#define LOWEST_OUTPUT_DEVID (sNumInputDevices) -#define HIGHEST_OUTPUT_DEVID (sNumPaDevices - 1) - -/************************************************* Macros ********/ - -/************************************************* Prototypes **********/ - -static PaError Pa_QueryDevices( void ); -PaError PaHost_GetTotalBufferFrames( internalPortAudioStream *past ); - -static int PaHost_ScanDevices( Boolean isInput ); -static int PaHost_QueryDeviceInfo( PaHostDeviceInfo *hostDeviceInfo, int coreDeviceIndex, Boolean isInput ); - -static PaDeviceID Pa_QueryDefaultInputDevice( void ); -static PaDeviceID Pa_QueryDefaultOutputDevice( void ); -static void PaHost_CalcHostBufferSize( internalPortAudioStream *past ); - -/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/ -static void Pa_StartUsageCalculation( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return; - /* Query user CPU timer for usage analysis and to prevent overuse of CPU. */ - getrusage( RUSAGE_SELF, &pahsc->pahsc_EntryRusage ); -} - -static long SubtractTime_AminusB( struct timeval *timeA, struct timeval *timeB ) -{ - long secs = timeA->tv_sec - timeB->tv_sec; - long usecs = secs * 1000000; - usecs += (timeA->tv_usec - timeB->tv_usec); - return usecs; -} - -/****************************************************************************** -** Measure fractional CPU load based on real-time it took to calculate -** buffers worth of output. -*/ -static void Pa_EndUsageCalculation( internalPortAudioStream *past ) -{ - struct rusage currentRusage; - long usecsElapsed; - double newUsage; - -#define LOWPASS_COEFFICIENT_0 (0.95) -#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0) - - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return; - - if( getrusage( RUSAGE_SELF, ¤tRusage ) == 0 ) - { - usecsElapsed = SubtractTime_AminusB( ¤tRusage.ru_utime, &pahsc->pahsc_EntryRusage.ru_utime ); - - /* Use inverse because it is faster than the divide. */ - newUsage = usecsElapsed * pahsc->pahsc_InverseMicrosPerHostBuffer; - - past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) + - (LOWPASS_COEFFICIENT_1 * newUsage); - } -} -/****************************************** END CPU UTILIZATION *******/ - -/************************************************************************/ -static PaDeviceID Pa_QueryDefaultInputDevice( void ) -{ - OSStatus err = noErr; - UInt32 count; - int i; - AudioDeviceID tempDeviceID = kAudioDeviceUnknown; - PaDeviceID defaultDeviceID = paNoDevice; - - // get the default output device for the HAL - // it is required to pass the size of the data to be returned - count = sizeof(tempDeviceID); - err = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultInputDevice, &count, (void *) &tempDeviceID); - if (err != noErr) goto Bail; - - // scan input devices to see which one matches this device - defaultDeviceID = paNoDevice; - for( i=LOWEST_INPUT_DEVID; i<=HIGHEST_INPUT_DEVID; i++ ) - { - DBUG(("Pa_QueryDefaultInputDevice: i = %d, aDevId = %d\n", i, sDeviceInfos[i].audioDeviceID )); - if( sDeviceInfos[i].audioDeviceID == tempDeviceID ) - { - defaultDeviceID = i; - break; - } - } -Bail: - return defaultDeviceID; -} - -/************************************************************************/ -static PaDeviceID Pa_QueryDefaultOutputDevice( void ) -{ - OSStatus err = noErr; - UInt32 count; - int i; - AudioDeviceID tempDeviceID = kAudioDeviceUnknown; - PaDeviceID defaultDeviceID = paNoDevice; - - // get the default output device for the HAL - // it is required to pass the size of the data to be returned - count = sizeof(tempDeviceID); - err = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultOutputDevice, &count, (void *) &tempDeviceID); - if (err != noErr) goto Bail; - - // scan output devices to see which one matches this device - defaultDeviceID = paNoDevice; - for( i=LOWEST_OUTPUT_DEVID; i<=HIGHEST_OUTPUT_DEVID; i++ ) - { - DBUG(("Pa_QueryDefaultOutputDevice: i = %d, aDevId = %d\n", i, sDeviceInfos[i].audioDeviceID )); - if( sDeviceInfos[i].audioDeviceID == tempDeviceID ) - { - defaultDeviceID = i; - break; - } - } -Bail: - return defaultDeviceID; -} - -/******************************************************************/ -static PaError Pa_QueryDevices( void ) -{ - OSStatus err = noErr; - UInt32 outSize; - Boolean outWritable; - int numBytes; - - // find out how many Core Audio devices there are, if any - err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &outSize, &outWritable); - if (err != noErr) - ERR_RPT(("Couldn't get info about list of audio devices\n")); - - // calculate the number of device available - sNumCoreDevices = outSize / sizeof(AudioDeviceID); - - // Bail if there aren't any devices - if (sNumCoreDevices < 1) - ERR_RPT(("No Devices Available\n")); - - // make space for the devices we are about to get - sCoreDeviceIDs = (AudioDeviceID *)malloc(outSize); - - // get an array of AudioDeviceIDs - err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &outSize, (void *)sCoreDeviceIDs); - if (err != noErr) - ERR_RPT(("Couldn't get list of audio device IDs\n")); - - // Allocate structures to hold device info pointers. - // There will be a maximum of two Pa devices per Core Audio device, input and/or output. - numBytes = sNumCoreDevices * 2 * sizeof(PaHostDeviceInfo); - sDeviceInfos = (PaHostDeviceInfo *) PaHost_AllocateFastMemory( numBytes ); - if( sDeviceInfos == NULL ) return paInsufficientMemory; - - // Scan all the Core Audio devices to see which support input and allocate a - // PaHostDeviceInfo structure for each one. - PaHost_ScanDevices( IS_INPUT ); - sNumInputDevices = sNumPaDevices; - // Now scan all the output devices. - PaHost_ScanDevices( IS_OUTPUT ); - sNumOutputDevices = sNumPaDevices - sNumInputDevices; - - // Figure out which of the devices that we scanned is the default device. - sDefaultInputDeviceID = Pa_QueryDefaultInputDevice(); - sDefaultOutputDeviceID = Pa_QueryDefaultOutputDevice(); - - return paNoError; -} - -/************************************************************************************/ -long Pa_GetHostError() -{ - return sPaHostError; -} - -/*************************************************************************/ -int Pa_CountDevices() -{ - if( sNumPaDevices <= 0 ) Pa_Initialize(); - return sNumPaDevices; -} - -/*************************************************************************/ -/* Allocate a string containing the device name. */ -static char *PaHost_DeviceNameFromID(AudioDeviceID deviceID, Boolean isInput ) -{ - OSStatus err = noErr; - UInt32 outSize; - Boolean outWritable; - char *deviceName = nil; - - // query size of name - err = AudioDeviceGetPropertyInfo(deviceID, 0, isInput, kAudioDevicePropertyDeviceName, &outSize, &outWritable); - if (err == noErr) - { - deviceName = (char*)malloc( outSize + 1); - if( deviceName ) - { - err = AudioDeviceGetProperty(deviceID, 0, isInput, kAudioDevicePropertyDeviceName, &outSize, deviceName); - if (err != noErr) - ERR_RPT(("Couldn't get audio device name.\n")); - } - } - - return deviceName; -} - -/*************************************************************************/ -// An AudioStreamBasicDescription is passed in to query whether or not -// the format is supported. A kAudioDeviceUnsupportedFormatError will -// be returned if the format is not supported and kAudioHardwareNoError -// will be returned if it is supported. AudioStreamBasicDescription -// fields set to 0 will be ignored in the query, but otherwise values -// must match exactly. - -Boolean deviceDoesSupportFormat(AudioDeviceID deviceID, AudioStreamBasicDescription *desc, Boolean isInput ) -{ - OSStatus err = noErr; - UInt32 outSize; - - outSize = sizeof(*desc); - err = AudioDeviceGetProperty(deviceID, 0, isInput, kAudioDevicePropertyStreamFormatSupported, &outSize, desc); - - if (err == kAudioHardwareNoError) - return true; - else - return false; -} - -/*************************************************************************/ -// return an error string -char* coreAudioErrorString (int errCode ) -{ - char *str; - - switch (errCode) - { - case kAudioHardwareUnspecifiedError: - str = "kAudioHardwareUnspecifiedError"; - break; - case kAudioHardwareNotRunningError: - str = "kAudioHardwareNotRunningError"; - break; - case kAudioHardwareUnknownPropertyError: - str = "kAudioHardwareUnknownPropertyError"; - break; - case kAudioDeviceUnsupportedFormatError: - str = "kAudioDeviceUnsupportedFormatError"; - break; - case kAudioHardwareBadPropertySizeError: - str = "kAudioHardwareBadPropertySizeError"; - break; - case kAudioHardwareIllegalOperationError: - str = "kAudioHardwareIllegalOperationError"; - break; - default: - str = "Unknown CoreAudio Error!"; - break; - } - - return str; -} - -/************************************************************************* -** PaDeviceInfo structures have already been created -** so just return the pointer. -** -*/ -const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id ) -{ - if( id < 0 || id >= sNumPaDevices ) - return NULL; - - return &sDeviceInfos[id].paInfo; -} - -/************************************************************************* -** Scan all of the Core Audio devices to see which support input or output. -** Changes sNumDevices, and fills in sDeviceInfos. -*/ -static int PaHost_ScanDevices( Boolean isInput ) -{ - int coreDeviceIndex; - int result; - PaHostDeviceInfo *hostDeviceInfo; - int numAdded = 0; - - for( coreDeviceIndex=0; coreDeviceIndex<sNumCoreDevices; coreDeviceIndex++ ) - { - // try to fill in next PaHostDeviceInfo - hostDeviceInfo = &sDeviceInfos[sNumPaDevices]; - result = PaHost_QueryDeviceInfo( hostDeviceInfo, coreDeviceIndex, isInput ); - DBUG(("PaHost_ScanDevices: paDevId = %d, coreDevId = %d\n", sNumPaDevices, hostDeviceInfo->audioDeviceID )); - if( result > 0 ) - { - sNumPaDevices += 1; // bump global counter if we got one - numAdded += 1; - } - else if( result < 0 ) return result; - } - return numAdded; -} - -/************************************************************************* -** Try to fill in the device info for this device. -** Return 1 if a good device that PA can use. -** Return 0 if not appropriate -** or return negative error. -** -*/ -static int PaHost_QueryDeviceInfo( PaHostDeviceInfo *hostDeviceInfo, int coreDeviceIndex, Boolean isInput ) -{ - OSErr err; - int index; - UInt32 outSize; - AudioStreamBasicDescription formatDesc; - Boolean result; - AudioDeviceID devID; - double *sampleRates = NULL; /* non-const ptr */ - - PaDeviceInfo *deviceInfo = &hostDeviceInfo->paInfo; - double possibleSampleRates[] = {8000.0, 11025.0, 22050.0, 44100.0, 48000.0, 88200.0, 96000.0}; - int maxNumSampleRates = sizeof( possibleSampleRates ) / sizeof( double ); - - deviceInfo->structVersion = 1; - deviceInfo->maxInputChannels = 0; - deviceInfo->maxOutputChannels = 0; - deviceInfo->numSampleRates = -1; - - devID = sCoreDeviceIDs[ coreDeviceIndex ]; - hostDeviceInfo->audioDeviceID = devID; - - // Figure out supported sample rates - // Make room in case device supports all rates. - sampleRates = (double*)PaHost_AllocateFastMemory( maxNumSampleRates * sizeof(double) ); - if( sampleRates == NULL ) return paInsufficientMemory; - - deviceInfo->sampleRates = sampleRates; - deviceInfo->numSampleRates = 0; - - // Loop through the possible sampling rates and check each to see if the device supports it. - for (index = 0; index < maxNumSampleRates; index ++) - { - memset( &formatDesc, 0, sizeof(AudioStreamBasicDescription) ); - formatDesc.mSampleRate = possibleSampleRates[index]; - result = deviceDoesSupportFormat( devID, &formatDesc, isInput ); - - if (result == true) - { - deviceInfo->numSampleRates += 1; - *sampleRates = possibleSampleRates[index]; - sampleRates++; - } - } - // If no sample rates supported, then not a very good device. - if( deviceInfo->numSampleRates == 0 ) goto error; - - // Get data format info from the device. - outSize = sizeof(formatDesc); - err = AudioDeviceGetProperty(devID, 0, isInput, kAudioDevicePropertyStreamFormat, &outSize, &formatDesc); - - // If no channels supported, then not a very good device. - if( (err != noErr) || (formatDesc.mChannelsPerFrame == 0) ) goto error; - - if( isInput ) - { - deviceInfo->maxInputChannels = formatDesc.mChannelsPerFrame; - } - else - { - deviceInfo->maxOutputChannels = formatDesc.mChannelsPerFrame; - } - - // FIXME - where to put current sample rate?: formatDesc.mSampleRate - - // Right now the Core Audio headers only define one formatID: LinearPCM - // Apparently LinearPCM must be Float32 for now. - switch (formatDesc.mFormatID) - { - case kAudioFormatLinearPCM: - deviceInfo->nativeSampleFormats = paFloat32; - - // FIXME - details about the format are in these flags. - // formatDesc.mFormatFlags - - // here are the possibilities - // kLinearPCMFormatFlagIsFloat // set for floating point, clear for integer - // kLinearPCMFormatFlagIsBigEndian // set for big endian, clear for little - // kLinearPCMFormatFlagIsSignedInteger // set for signed integer, clear for unsigned integer, - // only valid if kLinearPCMFormatFlagIsFloat is clear - // kLinearPCMFormatFlagIsPacked // set if the sample bits are packed as closely together as possible, - // clear if they are high or low aligned within the channel - // kLinearPCMFormatFlagIsAlignedHigh // set if the sample bits are placed - break; - - default: - deviceInfo->nativeSampleFormats = paFloat32; // FIXME - break; - } - - // Get the device name - deviceInfo->name = PaHost_DeviceNameFromID( devID, isInput ); - return 1; - -error: - if( sampleRates != NULL ) free( sampleRates ); - return 0; -} - -/************************************************************************* -** 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 PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName ) -{ -#if 0 - UInt32 hresult; - char envbuf[PA_ENV_BUF_SIZE]; - PaDeviceID recommendedID = paNoDevice; - - /* Let user determine default device by setting environment variable. */ - hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE ); - if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) ) - { - recommendedID = atoi( envbuf ); - } - - return recommendedID; -#endif - return paNoDevice; -} - -static PaError Pa_MaybeQueryDevices( void ) -{ - if( sNumPaDevices == 0 ) - { - return Pa_QueryDevices(); - } - return 0; -} - -/********************************************************************** -** Check for environment variable, else query devices and use result. -*/ -PaDeviceID Pa_GetDefaultInputDeviceID( void ) -{ - PaError result; - result = PaHost_GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME ); - if( result < 0 ) - { - result = Pa_MaybeQueryDevices(); - if( result < 0 ) return result; - result = sDefaultInputDeviceID; - } - return result; -} - -PaDeviceID Pa_GetDefaultOutputDeviceID( void ) -{ - PaError result; - result = PaHost_GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME ); - if( result < 0 ) - { - result = Pa_MaybeQueryDevices(); - if( result < 0 ) return result; - result = sDefaultOutputDeviceID; - } - return result; -} - -/********************************************************************** -** Initialize Host dependant part of API. -*/ - -PaError PaHost_Init( void ) -{ - return Pa_MaybeQueryDevices(); -} - -/********************************************************************** -** Fill any available output buffers and use any available -** input buffers by calling user callback. -*/ -static PaError Pa_TimeSlice( internalPortAudioStream *past, const AudioBufferList* inInputData, - AudioBufferList* outOutputData ) -{ - PaError result = 0; - char *inputNativeBufferfPtr = NULL; - char *outputNativeBufferfPtr = NULL; - int i; - int buffersProcessed = 0; - int done = 0; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paInternalError; - - past->past_NumCallbacks += 1; - -#if PA_TRACE_RUN - AddTraceMessage("Pa_TimeSlice: past_NumCallbacks ", past->past_NumCallbacks ); -#endif - - Pa_StartUsageCalculation( past ); - - /* If we are using output, then we need an empty output buffer. */ - if( past->past_NumOutputChannels > 0 ) - { - outputNativeBufferfPtr = (char*)outOutputData->mBuffers[0].mData; - } - - /* If we are using input, then we need a full input buffer. */ - if( past->past_NumInputChannels > 0 ) - { - inputNativeBufferfPtr = (char*)inInputData->mBuffers[0].mData; - } - - buffersProcessed += 1; - - /* Each host buffer contains multiple user buffers so do them all now. */ - for( i=0; i<pahsc->pahsc_UserBuffersPerHostBuffer; i++ ) - { - if( done ) - { - if( outputNativeBufferfPtr ) - { - /* Clear remainder of wave buffer if we are waiting for stop. */ - AddTraceMessage("Pa_TimeSlice: zero rest of wave buffer ", i ); - memset( outputNativeBufferfPtr, 0, pahsc->pahsc_BytesPerUserNativeOutputBuffer ); - } - } - else - { - /* Convert 32 bit native data to user data and call user routine. */ - result = PaConvert_Process( past, inputNativeBufferfPtr, outputNativeBufferfPtr ); - if( result != 0) done = 1; - } - if( inputNativeBufferfPtr ) inputNativeBufferfPtr += pahsc->pahsc_BytesPerUserNativeInputBuffer; - if( outputNativeBufferfPtr) outputNativeBufferfPtr += pahsc->pahsc_BytesPerUserNativeOutputBuffer; - } - - Pa_EndUsageCalculation( past ); - -#if PA_TRACE_RUN - AddTraceMessage("Pa_TimeSlice: buffersProcessed ", buffersProcessed ); -#endif - - return (result != 0) ? result : done; -} - -OSStatus appIOProc (AudioDeviceID inDevice, const AudioTimeStamp* inNow, - const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, - AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, - void* contextPtr) -{ - - PaError result = 0; - internalPortAudioStream *past; - PaHostSoundControl *pahsc; - past = (internalPortAudioStream *) contextPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - -// printf("Num input Buffers: %d; Num output Buffers: %d.\n", inInputData->mNumberBuffers, outOutputData->mNumberBuffers); - - /* Has someone asked us to abort by calling Pa_AbortStream()? */ - if( past->past_StopNow ) - { - past->past_IsActive = 0; /* Will cause thread to return. */ - } - /* Has someone asked us to stop by calling Pa_StopStream() - * OR has a user callback returned '1' to indicate finished. - */ - else if( past->past_StopSoon ) - { - // FIXME - pretend all done - past->past_IsActive = 0; /* Will cause thread to return. */ - } - else - { - /* use time stamp from CoreAudio if valid */ - if( inOutputTime->mFlags & kAudioTimeStampSampleTimeValid) - { - past->past_FrameCount = inOutputTime->mSampleTime; - } - - /* Process full input buffer and fill up empty output buffers. */ - if( (result = Pa_TimeSlice( past, inInputData, outOutputData )) != 0) - { - /* User callback has asked us to stop. */ -#if PA_TRACE_START_STOP - AddTraceMessage( "Pa_OutputThreadProc: TimeSlice() returned ", result ); -#endif - past->past_StopSoon = 1; /* Request that audio play out then stop. */ - result = paNoError; - } - } - - // FIXME PaHost_UpdateStreamTime( pahsc ); - - return result; -} - -#if 0 -static int PaHost_CalcTimeOut( internalPortAudioStream *past ) -{ - /* Calculate timeOut longer than longest time it could take to play all buffers. */ - int timeOut = (UInt32) (1500.0 * PaHost_GetTotalBufferFrames( past ) / past->past_SampleRate); - if( timeOut < MIN_TIMEOUT_MSEC ) timeOut = MIN_TIMEOUT_MSEC; - return timeOut; -} -#endif - - -/*******************************************************************/ -/* Attempt to set device sample rate. */ -static PaError PaHost_SetSampleRate( AudioDeviceID devID, Boolean isInput, double sampleRate ) -{ - AudioStreamBasicDescription formatDesc; - OSStatus err; - memset( &formatDesc, 0, sizeof(AudioStreamBasicDescription) ); - formatDesc.mSampleRate = sampleRate; - err = AudioDeviceSetProperty( devID, 0, 0, - isInput, kAudioDevicePropertyStreamFormat, sizeof(formatDesc), &formatDesc); - - if (err != kAudioHardwareNoError) return paInvalidSampleRate; - else return paNoError; -} - -/*******************************************************************/ -PaError PaHost_OpenInputStream( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc; - const PaHostDeviceInfo *hostDeviceInfo; - PaError result = paNoError; - UInt32 bytesPerHostBuffer; - UInt32 dataSize; - OSStatus err = noErr; - int bytesPerInputFrame; - - pahsc = (PaHostSoundControl *) past->past_DeviceData; - - DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", past->past_InputDeviceID)); - if( (past->past_InputDeviceID < LOWEST_INPUT_DEVID) || - (past->past_InputDeviceID > HIGHEST_INPUT_DEVID) ) - { - return paInvalidDeviceId; - } - hostDeviceInfo = &sDeviceInfos[past->past_InputDeviceID]; - - /* Try to set sample rate. */ - result = PaHost_SetSampleRate( hostDeviceInfo->audioDeviceID, IS_INPUT, past->past_SampleRate ); - if( result != paNoError ) return result; - - if( past->past_NumInputChannels != hostDeviceInfo->paInfo.maxInputChannels ) - { -#if 1 - return paInvalidChannelCount; // FIXME - how support mono? -#else -FIXME - should this be set on a stream basis? Is it possible to change? - /* Attempt to set number of channels. */ - AudioStreamBasicDescription formatDesc; - OSStatus err; - memset( &formatDesc, 0, sizeof(AudioStreamBasicDescription) ); - formatDesc.mChannelsPerFrame = past->past_NumInputChannels; - - err = AudioDeviceSetProperty( hostDeviceInfo->audioDeviceID, 0, 0, - IS_INPUT, kAudioDevicePropertyStreamFormat, sizeof(formatDesc), &formatDesc); - if (err != kAudioHardwareNoError) - { - result = paInvalidChannelCount; - goto error; - } -#endif - } - - // calculate native buffer sizes in bytes - bytesPerInputFrame = Pa_GetSampleSize(paFloat32) * past->past_NumInputChannels; - pahsc->pahsc_BytesPerUserNativeInputBuffer = past->past_FramesPerUserBuffer * bytesPerInputFrame; - bytesPerHostBuffer = pahsc->pahsc_FramesPerHostBuffer * bytesPerInputFrame; - - // Change the bufferSize of the device! Is this per device or just for our stream? - dataSize = sizeof(UInt32); - err = AudioDeviceSetProperty( hostDeviceInfo->audioDeviceID, 0, 0, IS_INPUT, - kAudioDevicePropertyBufferSize, dataSize, &bytesPerHostBuffer); - if( err != noErr ) - { - ERR_RPT(("Could not force buffer size!")); - result = paHostError; - goto error; - } - - // setup conversion procedure - result = PaConvert_SetupInput( past, paFloat32 ); - - return result; - -error: - return result; -} - -/*******************************************************************/ -PaError PaHost_OpenOutputStream( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc; - const PaHostDeviceInfo *hostDeviceInfo; - PaError result = paNoError; - UInt32 bytesPerHostBuffer; - UInt32 dataSize; - OSStatus err = noErr; - int bytesPerOutputFrame; - - pahsc = (PaHostSoundControl *) past->past_DeviceData; - - DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", past->past_OutputDeviceID)); - if( (past->past_OutputDeviceID < LOWEST_OUTPUT_DEVID) || - (past->past_OutputDeviceID > HIGHEST_OUTPUT_DEVID) ) - { - return paInvalidDeviceId; - } - hostDeviceInfo = &sDeviceInfos[past->past_OutputDeviceID]; - - /* Try to set sample rate. */ - result = PaHost_SetSampleRate( hostDeviceInfo->audioDeviceID, IS_OUTPUT, past->past_SampleRate ); - if( result != paNoError ) return result; - - if( past->past_NumOutputChannels != hostDeviceInfo->paInfo.maxOutputChannels ) - { -#if 1 - return paInvalidChannelCount; // FIXME - how support mono? -#else - /* Attempt to set number of channels. */ - AudioStreamBasicDescription formatDesc; - OSStatus err; - memset( &formatDesc, 0, sizeof(AudioStreamBasicDescription) ); - formatDesc.mChannelsPerFrame = past->past_NumOutputChannels; - err = AudioDeviceSetProperty( hostDeviceInfo->audioDeviceID, 0, 0, - IS_OUTPUT, kAudioDevicePropertyStreamFormat, sizeof(formatDesc), &formatDesc); - - if (err != kAudioHardwareNoError) - { - result = paInvalidChannelCount; - goto error; - } -#endif - } - - // calculate buffer sizes in bytes - bytesPerOutputFrame = Pa_GetSampleSize(paFloat32) * past->past_NumOutputChannels; - pahsc->pahsc_BytesPerUserNativeOutputBuffer = past->past_FramesPerUserBuffer * bytesPerOutputFrame; - bytesPerHostBuffer = pahsc->pahsc_FramesPerHostBuffer * bytesPerOutputFrame; - - // Change the bufferSize of the device! Is this per device or just for our stream? - dataSize = sizeof(bytesPerHostBuffer); - err = AudioDeviceSetProperty( hostDeviceInfo->audioDeviceID, 0, 0, IS_OUTPUT, - kAudioDevicePropertyBufferSize, dataSize, &bytesPerHostBuffer); - if( err != noErr ) - { - ERR_RPT(("Could not force buffer size!")); - result = paHostError; - goto error; - } - - // setup conversion procedure - result = PaConvert_SetupOutput( past, paFloat32 ); - - return result; - -error: - return result; -} - -/*******************************************************************/ -PaError PaHost_GetTotalBufferFrames( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - return pahsc->pahsc_FramesPerHostBuffer; -} - - -/******************************************************************* -* Determine how many User Buffers we can put into our CoreAudio stream buffer. -* Uses: -* past->past_FramesPerUserBuffer, etc. -* Sets: -* past->past_NumUserBuffers -* pahsc->pahsc_UserBuffersPerHostBuffer -* pahsc->pahsc_FramesPerHostBuffer -*/ -static void PaHost_CalcHostBufferSize( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = ( PaHostSoundControl *)past->past_DeviceData; - unsigned int minNumUserBuffers; - - // Determine number of user buffers based on minimum latency. - minNumUserBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate ); - // Compare to user requested number in user wants more than the minimum. - past->past_NumUserBuffers = ( minNumUserBuffers > past->past_NumUserBuffers ) ? - minNumUserBuffers : past->past_NumUserBuffers; - DBUG(("PaHost_CalcNumHostBuffers: min past_NumUserBuffers = %d\n", past->past_NumUserBuffers )); - - // For CoreAudio, we only have one Host buffer, so... - pahsc->pahsc_UserBuffersPerHostBuffer = past->past_NumUserBuffers; - // Calculate size of CoreAudio buffer. - pahsc->pahsc_FramesPerHostBuffer = past->past_FramesPerUserBuffer * past->past_NumUserBuffers; - - DBUG(("PaHost_CalcNumHostBuffers: pahsc_UserBuffersPerHostBuffer = %d\n", pahsc->pahsc_UserBuffersPerHostBuffer )); - DBUG(("PaHost_CalcNumHostBuffers: pahsc_FramesPerHostBuffer = %d\n", pahsc->pahsc_FramesPerHostBuffer )); -} - -/*******************************************************************/ -PaError PaHost_OpenStream( internalPortAudioStream *past ) -{ - PaError result = paNoError; - PaHostSoundControl *pahsc; - - /* Allocate and initialize host data. */ - pahsc = (PaHostSoundControl *) malloc(sizeof(PaHostSoundControl)); - if( pahsc == NULL ) - { - result = paInsufficientMemory; - goto error; - } - memset( pahsc, 0, sizeof(PaHostSoundControl) ); - past->past_DeviceData = (void *) pahsc; - - // If we are using both input and out, then they must be on the same CoreAudio device, - // until we implement a FIFO between two devices. - if( (past->past_OutputDeviceID != paNoDevice) && (past->past_InputDeviceID != paNoDevice) ) - { - AudioDeviceID inputID = sDeviceInfos[past->past_InputDeviceID].audioDeviceID; - AudioDeviceID outputID = sDeviceInfos[past->past_OutputDeviceID].audioDeviceID; - if( inputID != outputID ) - { - ERR_RPT(("PortAudio: input and output must use same CoreAudio device!\n")); - return paInvalidDeviceId; - } - } - - PaHost_CalcHostBufferSize( past ); - - { - int msecLatency = (int) ((PaHost_GetTotalBufferFrames(past) * 1000) / past->past_SampleRate); - PRINT(("PortAudio on OS X - Latency = %d frames, %d msec\n", PaHost_GetTotalBufferFrames(past), msecLatency )); - } - - /* Setup constants for CPU load measurement. */ - pahsc->pahsc_InverseMicrosPerHostBuffer = past->past_SampleRate / (1000000.0 * pahsc->pahsc_FramesPerHostBuffer); - - /* ------------------ OUTPUT */ - if( (past->past_OutputDeviceID != paNoDevice) && (past->past_NumOutputChannels > 0) ) - { - pahsc->pahsc_AudioDeviceID = sDeviceInfos[past->past_OutputDeviceID].audioDeviceID; - result = PaHost_OpenOutputStream( past ); - if( result < 0 ) goto error; - } - - /* ------------------ INPUT */ - if( (past->past_InputDeviceID != paNoDevice) && (past->past_NumInputChannels > 0) ) - { - pahsc->pahsc_AudioDeviceID = sDeviceInfos[past->past_InputDeviceID].audioDeviceID; - result = PaHost_OpenInputStream( past ); - if( result < 0 ) goto error; - } - - return result; - -error: - PaHost_CloseStream( past ); - return result; -} - -/*************************************************************************/ -PaError PaHost_StartOutput( internalPortAudioStream *past ) -{ - return 0; -} - -/*************************************************************************/ -PaError PaHost_StartInput( internalPortAudioStream *past ) -{ - return 0; -} - -/*************************************************************************/ -PaError PaHost_StartEngine( internalPortAudioStream *past ) -{ - OSStatus err = noErr; - PaError result = paNoError; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - - past->past_StopSoon = 0; - past->past_StopNow = 0; - past->past_IsActive = 1; - - // Associate an IO proc with the device and pass a pointer to the audio data context - err = AudioDeviceAddIOProc(pahsc->pahsc_AudioDeviceID, (AudioDeviceIOProc)appIOProc, past); - if (err != noErr) goto error; - - // start playing sound through the device - err = AudioDeviceStart(pahsc->pahsc_AudioDeviceID, (AudioDeviceIOProc)appIOProc); - if (err != noErr) goto error; - return result; - -#if PA_TRACE_START_STOP - AddTraceMessage( "PaHost_StartEngine: TimeSlice() returned ", result ); -#endif - -error: - return paHostError; // FIXME - save host error -} - -/*************************************************************************/ -PaError PaHost_StopEngine( internalPortAudioStream *past, int abort ) -{ - OSStatus err = noErr; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paNoError; - (void) abort; - - /* Tell background thread to stop generating more data and to let current data play out. */ - past->past_StopSoon = 1; - /* If aborting, tell background thread to stop NOW! */ - if( abort ) past->past_StopNow = 1; - past->past_IsActive = 0; - -#if PA_TRACE_START_STOP - AddTraceMessage( "PaHost_StopOutput: pahsc_HWaveOut ", (int) pahsc->pahsc_HWaveOut ); -#endif - - // FIXME - we should ask proc to stop instead of stopping abruptly - err = AudioDeviceStop(pahsc->pahsc_AudioDeviceID, (AudioDeviceIOProc)appIOProc); - if (err != noErr) goto Bail; - - err = AudioDeviceRemoveIOProc(pahsc->pahsc_AudioDeviceID, (AudioDeviceIOProc)appIOProc); - if (err != noErr) goto Bail; - - return paNoError; - -Bail: - return paHostError; // FIXME - save err -} - -/*************************************************************************/ -PaError PaHost_StopInput( internalPortAudioStream *past, int abort ) -{ - return paNoError; -} - -/*************************************************************************/ -PaError PaHost_StopOutput( internalPortAudioStream *past, int abort ) -{ - return paNoError; -} - -/*******************************************************************/ -PaError PaHost_CloseStream( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc; - - if( past == NULL ) return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paNoError; - -#if PA_TRACE_START_STOP - AddTraceMessage( "PaHost_CloseStream: pahsc_HWaveOut ", (int) pahsc->pahsc_HWaveOut ); -#endif - - free( pahsc ); - past->past_DeviceData = NULL; - - return paNoError; -} - -/************************************************************************* -** Determine minimum number of buffers required for this host based -** on minimum latency. Latency can be optionally set by user by setting -** an environment variable. For example, to set latency to 200 msec, put: -** -** set PA_MIN_LATENCY_MSEC=200 -** -** in the cshrc file. -*/ -#define PA_LATENCY_ENV_NAME ("PA_MIN_LATENCY_MSEC") - -#if 1 -int Pa_GetMinNumBuffers( int framesPerBuffer, double framesPerSecond ) -{ - int minBuffers; - int denominator; - int minLatencyMsec = PA_MIN_LATENCY_MSEC; - char *minLatencyText = getenv(PA_LATENCY_ENV_NAME); - if( minLatencyText != NULL ) - { - PRINT(("PA_MIN_LATENCY_MSEC = %s\n", minLatencyText )); - minLatencyMsec = atoi( minLatencyText ); - if( minLatencyMsec < 1 ) minLatencyMsec = 1; - else if( minLatencyMsec > 5000 ) minLatencyMsec = 5000; - } - - denominator = 1000.0 * framesPerBuffer; - minBuffers = (int) (((minLatencyMsec * framesPerSecond) + denominator - 1) / denominator ); - if( minBuffers < 1 ) minBuffers = 1; - return minBuffers; -} -#else -/************************************************************************* -** Determine minimum number of buffers required for this host based -** on minimum latency. -*/ -int Pa_GetMinNumBuffers( int framesPerUserBuffer, double sampleRate ) -{ - int minUserBuffers; - int minFramesPerHostBuffer; - - // Calculate minimum and maximum sizes based on timing and sample rate. - minFramesPerHostBuffer = (int) (PA_MIN_LATENCY_MSEC * sampleRate / 1000.0); - // round up to nearest multiple of 8 - minFramesPerHostBuffer = (minFramesPerHostBuffer + 7) & ~7; - DBUG(("Pa_GetMinNumBuffers: minFramesPerHostBuffer = %d\n", minFramesPerHostBuffer )); - - minUserBuffers = (minFramesPerHostBuffer + framesPerUserBuffer - 1) / framesPerUserBuffer; - if( minUserBuffers < 1 ) minUserBuffers = 1; - - return minUserBuffers; -} -#endif - -/************************************************************************* -** Cleanup device info. -*/ -PaError PaHost_Term( void ) -{ - int i; - - if( sDeviceInfos != NULL ) - { - for( i=0; i<sNumPaDevices; i++ ) - { - if( sDeviceInfos[i].paInfo.name != NULL ) free( (char*)sDeviceInfos[i].paInfo.name ); - if( sDeviceInfos[i].paInfo.sampleRates != NULL ) free( (void*)sDeviceInfos[i].paInfo.sampleRates ); - } - free( sDeviceInfos ); - sDeviceInfos = NULL; - } - - sNumPaDevices = 0; - return paNoError; -} - -/*************************************************************************/ -void Pa_Sleep( long msec ) -{ -#if 0 - struct timeval timeout; - timeout.tv_sec = msec / 1000; - timeout.tv_usec = (msec % 1000) * 1000; - select( 0, NULL, NULL, NULL, &timeout ); -#else - usleep( msec * 1000 ); -#endif -} - -/************************************************************************* - * Allocate memory that can be accessed in real-time. - * This may need to be held in physical memory so that it is not - * paged to virtual memory. - * This call MUST be balanced with a call to PaHost_FreeFastMemory(). - */ -void *PaHost_AllocateFastMemory( long numBytes ) -{ - void *addr = malloc( numBytes ); /* FIXME - do we need physical memory? */ - if( addr != NULL ) memset( addr, 0, numBytes ); - return addr; -} - -/************************************************************************* - * Free memory that could be accessed in real-time. - * This call MUST be balanced with a call to PaHost_AllocateFastMemory(). - */ -void PaHost_FreeFastMemory( void *addr, long numBytes ) -{ - if( addr != NULL ) free( addr ); -} - - -/***********************************************************************/ -PaError PaHost_StreamActive( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc; - if( past == NULL ) return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paInternalError; - return (PaError) past->past_IsActive; -} - -/*************************************************************************/ -PaTimestamp Pa_StreamTime( PortAudioStream *stream ) -{ - AudioTimeStamp timeStamp; - PaTimestamp streamTime; - PaHostSoundControl *pahsc; - internalPortAudioStream *past = (internalPortAudioStream *) stream; - if( past == NULL ) return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - - AudioDeviceGetCurrentTime(pahsc->pahsc_AudioDeviceID, &timeStamp); - - streamTime = ( timeStamp.mFlags & kAudioTimeStampSampleTimeValid) ? - timeStamp.mSampleTime : past->past_FrameCount; - - return streamTime; -} diff --git a/pd/portaudio/pa_mac_sm/pa_mac_sm.c b/pd/portaudio/pa_mac_sm/pa_mac_sm.c deleted file mode 100644 index 59457ded..00000000 --- a/pd/portaudio/pa_mac_sm/pa_mac_sm.c +++ /dev/null @@ -1,1656 +0,0 @@ -/* - * $Id: pa_mac_sm.c,v 1.1.2.1 2002/06/07 21:20:48 rossb Exp $ - * Portable Audio I/O Library for Macintosh - * - * Based on the Open Source API proposed by Ross Bencina - * Copyright (c) 1999-2000 Phil Burk - * - * Special thanks to Chris Rolfe for his many helpful suggestions, bug fixes, - * and code contributions. - * Thanks also to Tue Haste Andersen, Alberto Ricci, Nico Wald, - * Roelf Toxopeus and Tom Erbe for testing the code and making - * numerous suggestions. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -/* Modification History - PLB20010415 - ScanInputDevices was setting sDefaultOutputDeviceID instead of sDefaultInputDeviceID - PLB20010415 - Device Scan was crashing for anything other than siBadSoundInDevice, but some Macs may return other errors! - PLB20010420 - Fix TIMEOUT in record mode. - PLB20010420 - Change CARBON_COMPATIBLE to TARGET_API_MAC_CARBON - PLB20010907 - Pass unused event to WaitNextEvent to prevent Mac OSX crash. Thanks Dominic Mazzoni. - PLB20010908 - Use requested number of input channels. Thanks Dominic Mazzoni. - PLB20011009 - Use NewSndCallBackUPP() for CARBON - PLB20020417 - I used to call Pa_GetMinNumBuffers() which doesn't take into account the - variable minFramesPerHostBuffer. Now I call PaMac_GetMinNumBuffers() which will - give lower latency when virtual memory is turned off. - Thanks Kristoffer Jensen and Georgios Marentakis for spotting this bug. - PLB20020423 - Use new method to calculate CPU load similar to other ports. Based on num frames calculated. - Fixed Pa_StreamTime(). Now estimates how many frames have played based on MicroSecond timer. - Added PA_MAX_USAGE_ALLOWED to prevent Mac form hanging when CPU load approaches 100%. - PLB20020424 - Fixed return value in Pa_StreamTime -*/ - -/* -COMPATIBILITY -This Macintosh implementation is designed for use with Mac OS 7, 8 and -9 on PowerMacs, and OS X if compiled with CARBON - -OUTPUT -A circular array of CmpSoundHeaders is used as a queue. For low latency situations -there will only be two small buffers used. For higher latency, more and larger buffers -may be used. -To play the sound we use SndDoCommand() with bufferCmd. Each buffer is followed -by a callbackCmd which informs us when the buffer has been processsed. - -INPUT -The SndInput Manager SPBRecord call is used for sound input. If only -input is used, then the PA user callback is called from the Input completion proc. -For full-duplex, or output only operation, the PA callback is called from the -HostBuffer output completion proc. In that case, input sound is passed to the -callback by a simple FIFO. - -TODO: -O- Add support for native sample data formats other than int16. -O- Review buffer sizing. Should it be based on result of siDeviceBufferInfo query? -O- Determine default devices somehow. -*/ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <memory.h> -#include <math.h> - -/* Mac specific includes */ -#include "OSUtils.h" -#include <MacTypes.h> -#include <Math64.h> -#include <Errors.h> -#include <Sound.h> -#include <SoundInput.h> -#include <SoundComponents.h> -#include <Devices.h> -#include <DateTimeUtils.h> -#include <Timer.h> -#include <Gestalt.h> - -#include "portaudio.h" -#include "pa_host.h" -#include "pa_trace.h" - -#ifndef FALSE - #define FALSE (0) - #define TRUE (!FALSE) -#endif - -/* #define TARGET_API_MAC_CARBON (1) */ - -/* - * Define maximum CPU load that will be allowed. User callback will - * be skipped if load exceeds this limit. This is to prevent the Mac - * from hanging when the CPU is hogged by the sound thread. - * On my PowerBook G3, the mac hung when I used 94% of CPU ( usage = 0.94 ). - */ -#define PA_MAX_USAGE_ALLOWED (0.92) - -/* Debugging output macros. */ -#define PRINT(x) { printf x; fflush(stdout); } -#define ERR_RPT(x) PRINT(x) -#define DBUG(x) /* PRINT(x) /**/ -#define DBUGX(x) /* PRINT(x) /**/ - -#define MAC_PHYSICAL_FRAMES_PER_BUFFER (512) /* Minimum number of stereo frames per SoundManager double buffer. */ -#define MAC_VIRTUAL_FRAMES_PER_BUFFER (4096) /* Need this many when using Virtual Memory for recording. */ -#define PA_MIN_NUM_HOST_BUFFERS (2) -#define PA_MAX_NUM_HOST_BUFFERS (16) /* Do not exceed!! */ -#define PA_MAX_DEVICE_INFO (32) - -/* Conversions for 16.16 fixed point code. */ -#define DoubleToUnsignedFixed(x) ((UnsignedFixed) ((x) * 65536.0)) -#define UnsignedFixedToDouble(fx) (((double)(fx)) * (1.0/(1<<16))) - -/************************************************************************************/ -/****************** Structures ******************************************************/ -/************************************************************************************/ -/* Use for passing buffers from input callback to output callback for processing. */ -typedef struct MultiBuffer -{ - char *buffers[PA_MAX_NUM_HOST_BUFFERS]; - int numBuffers; - int nextWrite; - int nextRead; -} -MultiBuffer; - -/* Define structure to contain all Macintosh specific data. */ -typedef struct PaHostSoundControl -{ - UInt64 pahsc_EntryCount; - double pahsc_InverseMicrosPerHostBuffer; /* 1/Microseconds of real-time audio per user buffer. */ - - /* Use char instead of Boolean for atomic operation. */ - volatile char pahsc_IsRecording; /* Recording in progress. Set by foreground. Cleared by background. */ - volatile char pahsc_StopRecording; /* Signal sent to background. */ - volatile char pahsc_IfInsideCallback; - /* Input */ - SPB pahsc_InputParams; - SICompletionUPP pahsc_InputCompletionProc; - MultiBuffer pahsc_InputMultiBuffer; - int32 pahsc_BytesPerInputHostBuffer; - int32 pahsc_InputRefNum; - /* Output */ - CmpSoundHeader pahsc_SoundHeaders[PA_MAX_NUM_HOST_BUFFERS]; - int32 pahsc_BytesPerOutputHostBuffer; - SndChannelPtr pahsc_Channel; - SndCallBackUPP pahsc_OutputCompletionProc; - int32 pahsc_NumOutsQueued; - int32 pahsc_NumOutsPlayed; - PaTimestamp pahsc_NumFramesDone; - UInt64 pahsc_WhenFramesDoneIncremented; - /* Init Time -------------- */ - int32 pahsc_NumHostBuffers; - int32 pahsc_FramesPerHostBuffer; - int32 pahsc_UserBuffersPerHostBuffer; - int32 pahsc_MinFramesPerHostBuffer; /* Can vary depending on virtual memory usage. */ -} -PaHostSoundControl; - -/* Mac specific device information. */ -typedef struct internalPortAudioDevice -{ - long pad_DeviceRefNum; - long pad_DeviceBufferSize; - Component pad_Identifier; - PaDeviceInfo pad_Info; -} -internalPortAudioDevice; - -/************************************************************************************/ -/****************** Data ************************************************************/ -/************************************************************************************/ -static int sNumDevices = 0; -static internalPortAudioDevice sDevices[PA_MAX_DEVICE_INFO] = { 0 }; -static int32 sPaHostError = 0; -static int sDefaultOutputDeviceID; -static int sDefaultInputDeviceID; - -/************************************************************************************/ -/****************** Prototypes ******************************************************/ -/************************************************************************************/ -static PaError PaMac_TimeSlice( internalPortAudioStream *past, int16 *macOutputBufPtr ); -static PaError PaMac_CallUserLoop( internalPortAudioStream *past, int16 *outPtr ); -static PaError PaMac_RecordNext( internalPortAudioStream *past ); -static void PaMac_StartLoadCalculation( internalPortAudioStream *past ); -static int PaMac_GetMinNumBuffers( int minFramesPerHostBuffer, int framesPerBuffer, double sampleRate ); -static double *PaMac_GetSampleRatesFromHandle ( int numRates, Handle h ); -static PaError PaMac_ScanInputDevices( void ); -static PaError PaMac_ScanOutputDevices( void ); -static PaError PaMac_QueryOutputDeviceInfo( Component identifier, internalPortAudioDevice *ipad ); -static PaError PaMac_QueryInputDeviceInfo( Str255 deviceName, internalPortAudioDevice *ipad ); -static void PaMac_InitSoundHeader( internalPortAudioStream *past, CmpSoundHeader *sndHeader ); -static void PaMac_EndLoadCalculation( internalPortAudioStream *past ); -static void PaMac_PlayNext ( internalPortAudioStream *past, int index ); -static long PaMac_FillNextOutputBuffer( internalPortAudioStream *past, int index ); -static pascal void PaMac_InputCompletionProc(SPBPtr recParams); -static pascal void PaMac_OutputCompletionProc (SndChannelPtr theChannel, SndCommand * theCmd); -static PaError PaMac_BackgroundManager( internalPortAudioStream *past, int index ); -long PaHost_GetTotalBufferFrames( internalPortAudioStream *past ); -static int Mac_IsVirtualMemoryOn( void ); -static void PToCString(unsigned char* inString, char* outString); -char *MultiBuffer_GetNextWriteBuffer( MultiBuffer *mbuf ); -char *MultiBuffer_GetNextReadBuffer( MultiBuffer *mbuf ); -int MultiBuffer_GetNextReadIndex( MultiBuffer *mbuf ); -int MultiBuffer_GetNextWriteIndex( MultiBuffer *mbuf ); -int MultiBuffer_IsWriteable( MultiBuffer *mbuf ); -int MultiBuffer_IsReadable( MultiBuffer *mbuf ); -void MultiBuffer_AdvanceReadIndex( MultiBuffer *mbuf ); -void MultiBuffer_AdvanceWriteIndex( MultiBuffer *mbuf ); - -/************************************************************************* -** Simple FIFO index control for multiple buffers. -** Read and Write indices range from 0 to 2N-1. -** This allows us to distinguish between full and empty. -*/ -char *MultiBuffer_GetNextWriteBuffer( MultiBuffer *mbuf ) -{ - return mbuf->buffers[mbuf->nextWrite % mbuf->numBuffers]; -} -char *MultiBuffer_GetNextReadBuffer( MultiBuffer *mbuf ) -{ - return mbuf->buffers[mbuf->nextRead % mbuf->numBuffers]; -} -int MultiBuffer_GetNextReadIndex( MultiBuffer *mbuf ) -{ - return mbuf->nextRead % mbuf->numBuffers; -} -int MultiBuffer_GetNextWriteIndex( MultiBuffer *mbuf ) -{ - return mbuf->nextWrite % mbuf->numBuffers; -} - -int MultiBuffer_IsWriteable( MultiBuffer *mbuf ) -{ - int bufsFull = mbuf->nextWrite - mbuf->nextRead; - if( bufsFull < 0 ) bufsFull += (2 * mbuf->numBuffers); - return (bufsFull < mbuf->numBuffers); -} -int MultiBuffer_IsReadable( MultiBuffer *mbuf ) -{ - int bufsFull = mbuf->nextWrite - mbuf->nextRead; - if( bufsFull < 0 ) bufsFull += (2 * mbuf->numBuffers); - return (bufsFull > 0); -} -void MultiBuffer_AdvanceReadIndex( MultiBuffer *mbuf ) -{ - int temp = mbuf->nextRead + 1; - mbuf->nextRead = (temp >= (2 * mbuf->numBuffers)) ? 0 : temp; -} -void MultiBuffer_AdvanceWriteIndex( MultiBuffer *mbuf ) -{ - int temp = mbuf->nextWrite + 1; - mbuf->nextWrite = (temp >= (2 * mbuf->numBuffers)) ? 0 : temp; -} - -/************************************************************************* -** String Utility by Chris Rolfe -*/ -static void PToCString(unsigned char* inString, char* outString) -{ - long i; - for(i=0; i<inString[0]; i++) /* convert Pascal to C string */ - outString[i] = inString[i+1]; - outString[i]=0; -} - -/*************************************************************************/ -PaError PaHost_Term( void ) -{ - int i; - PaDeviceInfo *dev; - double *rates; - /* Free any allocated sample rate arrays. */ - for( i=0; i<sNumDevices; i++ ) - { - dev = &sDevices[i].pad_Info; - rates = (double *) dev->sampleRates; - if( (rates != NULL) ) free( rates ); /* MEM_011 */ - dev->sampleRates = NULL; - if( dev->name != NULL ) free( (void *) dev->name ); /* MEM_010 */ - dev->name = NULL; - } - sNumDevices = 0; - return paNoError; -} - -/************************************************************************* - PaHost_Init() is the library initialization function - call this before - using the library. -*/ -PaError PaHost_Init( void ) -{ - PaError err; - NumVersionVariant version; - - version.parts = SndSoundManagerVersion(); - DBUG(("SndSoundManagerVersion = 0x%x\n", version.whole)); - - /* Have we already initialized the device info? */ - err = (PaError) Pa_CountDevices(); - if( err < 0 ) return err; - else return paNoError; -} - -/************************************************************************* - PaMac_ScanOutputDevices() queries the properties of all output devices. -*/ -static PaError PaMac_ScanOutputDevices( void ) -{ - PaError err; - Component identifier=0; - ComponentDescription criteria = { kSoundOutputDeviceType, 0, 0, 0, 0 }; - long numComponents, i; - - /* Search the system linked list for output components */ - numComponents = CountComponents (&criteria); - identifier = 0; - sDefaultOutputDeviceID = sNumDevices; /* FIXME - query somehow */ - for (i = 0; i < numComponents; i++) - { - /* passing nil returns first matching component. */ - identifier = FindNextComponent( identifier, &criteria); - sDevices[sNumDevices].pad_Identifier = identifier; - - /* Set up for default OUTPUT devices. */ - err = PaMac_QueryOutputDeviceInfo( identifier, &sDevices[sNumDevices] ); - if( err < 0 ) return err; - else sNumDevices++; - - } - - return paNoError; -} - -/************************************************************************* - PaMac_ScanInputDevices() queries the properties of all input devices. -*/ -static PaError PaMac_ScanInputDevices( void ) -{ - Str255 deviceName; - int count; - Handle iconHandle; - PaError err; - OSErr oserr; - count = 1; - sDefaultInputDeviceID = sNumDevices; /* FIXME - query somehow */ /* PLB20010415 - was setting sDefaultOutputDeviceID */ - while(true) - { - /* Thanks Chris Rolfe and Alberto Ricci for this trick. */ - oserr = SPBGetIndexedDevice(count++, deviceName, &iconHandle); - DBUG(("PaMac_ScanInputDevices: SPBGetIndexedDevice returned %d\n", oserr )); -#if 1 - /* PLB20010415 - was giving error for anything other than siBadSoundInDevice, but some Macs may return other errors! */ - if(oserr != noErr) break; /* Some type of error is expected when count > devices */ -#else - if(oserr == siBadSoundInDevice) - { /* it's expected when count > devices */ - oserr = noErr; - break; - } - if(oserr != noErr) - { - ERR_RPT(("ERROR: SPBGetIndexedDevice(%d,,) returned %d\n", count-1, oserr )); - sPaHostError = oserr; - return paHostError; - } -#endif - DisposeHandle(iconHandle); /* Don't need the icon */ - - err = PaMac_QueryInputDeviceInfo( deviceName, &sDevices[sNumDevices] ); - DBUG(("PaMac_ScanInputDevices: PaMac_QueryInputDeviceInfo returned %d\n", err )); - if( err < 0 ) return err; - else if( err == 1 ) sNumDevices++; - } - - return paNoError; -} - -/* Sample rate info returned by using siSampleRateAvailable selector in SPBGetDeviceInfo() */ -/* Thanks to Chris Rolfe for help with this query. */ -#pragma options align=mac68k -typedef struct -{ - int16 numRates; - UnsignedFixed (**rates)[]; /* Handle created by SPBGetDeviceInfo */ -} -SRateInfo; -#pragma options align=reset - -/************************************************************************* -** PaMac_QueryOutputDeviceInfo() -** Query information about a named output device. -** Clears contents of ipad and writes info based on queries. -** Return one if OK, -** zero if device cannot be used, -** or negative error. -*/ -static PaError PaMac_QueryOutputDeviceInfo( Component identifier, internalPortAudioDevice *ipad ) -{ - int len; - OSErr err; - PaDeviceInfo *dev = &ipad->pad_Info; - SRateInfo srinfo = {0}; - int numRates; - ComponentDescription tempD; - Handle nameH=nil, infoH=nil, iconH=nil; - - memset( ipad, 0, sizeof(internalPortAudioDevice) ); - - dev->structVersion = 1; - dev->maxInputChannels = 0; - dev->maxOutputChannels = 2; - dev->nativeSampleFormats = paInt16; /* FIXME - query to see if 24 or 32 bit data can be handled. */ - - /* Get sample rates supported. */ - err = GetSoundOutputInfo(identifier, siSampleRateAvailable, (Ptr) &srinfo); - if(err != noErr) - { - ERR_RPT(("Error in PaMac_QueryOutputDeviceInfo: GetSoundOutputInfo siSampleRateAvailable returned %d\n", err )); - goto error; - } - numRates = srinfo.numRates; - DBUG(("PaMac_QueryOutputDeviceInfo: srinfo.numRates = 0x%x\n", srinfo.numRates )); - if( numRates == 0 ) - { - dev->numSampleRates = -1; - numRates = 2; - } - else - { - dev->numSampleRates = numRates; - } - dev->sampleRates = PaMac_GetSampleRatesFromHandle( numRates, (Handle) srinfo.rates ); - /* SPBGetDeviceInfo created the handle, but it's OUR job to release it. */ - DisposeHandle((Handle) srinfo.rates); - - /* Device name */ - /* we pass an existing handle for the component name; - we don't care about the info (type, subtype, etc.) or icon, so set them to nil */ - infoH = nil; - iconH = nil; - nameH = NewHandle(0); - if(nameH == nil) return paInsufficientMemory; - err = GetComponentInfo(identifier, &tempD, nameH, infoH, iconH); - if (err) - { - ERR_RPT(("Error in PaMac_QueryOutputDeviceInfo: GetComponentInfo returned %d\n", err )); - goto error; - } - len = (*nameH)[0] + 1; - dev->name = (char *) malloc(len); /* MEM_010 */ - if( dev->name == NULL ) - { - DisposeHandle(nameH); - return paInsufficientMemory; - } - else - { - PToCString((unsigned char *)(*nameH), (char *) dev->name); - DisposeHandle(nameH); - } - - DBUG(("PaMac_QueryOutputDeviceInfo: dev->name = %s\n", dev->name )); - return paNoError; - -error: - sPaHostError = err; - return paHostError; - -} - -/************************************************************************* -** PaMac_QueryInputDeviceInfo() -** Query information about a named input device. -** Clears contents of ipad and writes info based on queries. -** Return one if OK, -** zero if device cannot be used, -** or negative error. -*/ -static PaError PaMac_QueryInputDeviceInfo( Str255 deviceName, internalPortAudioDevice *ipad ) -{ - PaError result = paNoError; - int len; - OSErr err; - long mRefNum = 0; - long tempL; - int16 tempS; - Fixed tempF; - PaDeviceInfo *dev = &ipad->pad_Info; - SRateInfo srinfo = {0}; - int numRates; - - memset( ipad, 0, sizeof(internalPortAudioDevice) ); - dev->maxOutputChannels = 0; - - /* Open device based on name. If device is in use, it may not be able to open in write mode. */ - err = SPBOpenDevice( deviceName, siWritePermission, &mRefNum); - if (err) - { - /* If device is in use, it may not be able to open in write mode so try read mode. */ - err = SPBOpenDevice( deviceName, siReadPermission, &mRefNum); - if (err) - { - ERR_RPT(("Error in PaMac_QueryInputDeviceInfo: SPBOpenDevice returned %d\n", err )); - sPaHostError = err; - return paHostError; - } - } - - /* Define macros for printing out device info. */ -#define PrintDeviceInfo(selector,var) \ - err = SPBGetDeviceInfo(mRefNum, selector, (Ptr) &var); \ - if (err) { \ - DBUG(("query %s failed\n", #selector )); \ - }\ - else { \ - DBUG(("query %s = 0x%x\n", #selector, var )); \ - } - - PrintDeviceInfo( siContinuous, tempS ); - PrintDeviceInfo( siAsync, tempS ); - PrintDeviceInfo( siNumberChannels, tempS ); - PrintDeviceInfo( siSampleSize, tempS ); - PrintDeviceInfo( siSampleRate, tempF ); - PrintDeviceInfo( siChannelAvailable, tempS ); - PrintDeviceInfo( siActiveChannels, tempL ); - PrintDeviceInfo( siDeviceBufferInfo, tempL ); - - err = SPBGetDeviceInfo(mRefNum, siActiveChannels, (Ptr) &tempL); - if (err == 0) DBUG(("%s = 0x%x\n", "siActiveChannels", tempL )); - /* Can we use this device? */ - err = SPBGetDeviceInfo(mRefNum, siAsync, (Ptr) &tempS); - if (err) - { - ERR_RPT(("Error in PaMac_QueryInputDeviceInfo: SPBGetDeviceInfo siAsync returned %d\n", err )); - goto error; - } - if( tempS == 0 ) goto useless; /* Does not support async recording so forget about it. */ - - err = SPBGetDeviceInfo(mRefNum, siChannelAvailable, (Ptr) &tempS); - if (err) - { - ERR_RPT(("Error in PaMac_QueryInputDeviceInfo: SPBGetDeviceInfo siChannelAvailable returned %d\n", err )); - goto error; - } - dev->maxInputChannels = tempS; - - /* Get sample rates supported. */ - err = SPBGetDeviceInfo(mRefNum, siSampleRateAvailable, (Ptr) &srinfo); - if (err) - { - ERR_RPT(("Error in PaMac_QueryInputDeviceInfo: SPBGetDeviceInfo siSampleRateAvailable returned %d\n", err )); - goto error; - } - - numRates = srinfo.numRates; - DBUG(("numRates = 0x%x\n", numRates )); - if( numRates == 0 ) - { - dev->numSampleRates = -1; - numRates = 2; - } - else - { - dev->numSampleRates = numRates; - } - dev->sampleRates = PaMac_GetSampleRatesFromHandle( numRates, (Handle) srinfo.rates ); - /* SPBGetDeviceInfo created the handle, but it's OUR job to release it. */ - DisposeHandle((Handle) srinfo.rates); - - /* Get size of device buffer. */ - err = SPBGetDeviceInfo(mRefNum, siDeviceBufferInfo, (Ptr) &tempL); - if (err) - { - ERR_RPT(("Error in PaMac_QueryInputDeviceInfo: SPBGetDeviceInfo siDeviceBufferInfo returned %d\n", err )); - goto error; - } - ipad->pad_DeviceBufferSize = tempL; - DBUG(("siDeviceBufferInfo = %d\n", tempL )); - - /* Set format based on sample size. */ - err = SPBGetDeviceInfo(mRefNum, siSampleSize, (Ptr) &tempS); - if (err) - { - ERR_RPT(("Error in PaMac_QueryInputDeviceInfo: SPBGetDeviceInfo siSampleSize returned %d\n", err )); - goto error; - } - switch( tempS ) - { - case 0x0020: - dev->nativeSampleFormats = paInt32; /* FIXME - warning, code probably won't support this! */ - break; - case 0x0010: - default: /* FIXME - What about other formats? */ - dev->nativeSampleFormats = paInt16; - break; - } - DBUG(("nativeSampleFormats = %d\n", dev->nativeSampleFormats )); - - /* Device name */ - len = deviceName[0] + 1; /* Get length of Pascal string */ - dev->name = (char *) malloc(len); /* MEM_010 */ - if( dev->name == NULL ) - { - result = paInsufficientMemory; - goto cleanup; - } - PToCString(deviceName, (char *) dev->name); - DBUG(("deviceName = %s\n", dev->name )); - result = (PaError) 1; - /* All done so close up device. */ -cleanup: - if( mRefNum ) SPBCloseDevice(mRefNum); - return result; - -error: - if( mRefNum ) SPBCloseDevice(mRefNum); - sPaHostError = err; - return paHostError; - -useless: - if( mRefNum ) SPBCloseDevice(mRefNum); - return (PaError) 0; -} - -/************************************************************************* -** Allocate a double array and fill it with listed sample rates. -*/ -static double * PaMac_GetSampleRatesFromHandle ( int numRates, Handle h ) -{ - OSErr err = noErr; - SInt8 hState; - int i; - UnsignedFixed *fixedRates; - double *rates = (double *) malloc( numRates * sizeof(double) ); /* MEM_011 */ - if( rates == NULL ) return NULL; - /* Save and restore handle state as suggested by TechNote at: - http://developer.apple.com/technotes/tn/tn1122.html - */ - hState = HGetState (h); - if (!(err = MemError ())) - { - HLock (h); - if (!(err = MemError ( ))) - { - fixedRates = (UInt32 *) *h; - for( i=0; i<numRates; i++ ) - { - rates[i] = UnsignedFixedToDouble(fixedRates[i]); - } - - HSetState (h,hState); - err = MemError ( ); - } - } - if( err ) - { - free( rates ); - ERR_RPT(("Error in PaMac_GetSampleRatesFromHandle = %d\n", err )); - } - return rates; -} - -/*************************************************************************/ -int Pa_CountDevices() -{ - PaError err; - DBUG(("Pa_CountDevices()\n")); - /* If no devices, go find some. */ - if( sNumDevices <= 0 ) - { - err = PaMac_ScanOutputDevices(); - if( err != paNoError ) goto error; - err = PaMac_ScanInputDevices(); - if( err != paNoError ) goto error; - } - return sNumDevices; - -error: - PaHost_Term(); - DBUG(("Pa_CountDevices: returns %d\n", err )); - return err; - -} - -/*************************************************************************/ -const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id ) -{ - if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL; - return &sDevices[id].pad_Info; -} -/*************************************************************************/ -PaDeviceID Pa_GetDefaultInputDeviceID( void ) -{ - return sDefaultInputDeviceID; -} - -/*************************************************************************/ -PaDeviceID Pa_GetDefaultOutputDeviceID( void ) -{ - return sDefaultOutputDeviceID; -} - -/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/ -static void PaMac_StartLoadCalculation( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - UnsignedWide widePad; - if( pahsc == NULL ) return; - /* Query system timer for usage analysis and to prevent overuse of CPU. */ - Microseconds( &widePad ); - pahsc->pahsc_EntryCount = UnsignedWideToUInt64( widePad ); -} - -/****************************************************************************** -** Measure fractional CPU load based on real-time it took to calculate -** buffers worth of output. -*/ -/**************************************************************************/ -static void PaMac_EndLoadCalculation( internalPortAudioStream *past ) -{ - UnsignedWide widePad; - UInt64 currentCount; - long usecsElapsed; - double newUsage; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return; - - /* Measure CPU utilization during this callback. Note that this calculation - ** assumes that we had the processor the whole time. - */ -#define LOWPASS_COEFFICIENT_0 (0.95) -#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0) - Microseconds( &widePad ); - currentCount = UnsignedWideToUInt64( widePad ); - - usecsElapsed = (long) U64Subtract(currentCount, pahsc->pahsc_EntryCount); - - /* Use inverse because it is faster than the divide. */ - newUsage = usecsElapsed * pahsc->pahsc_InverseMicrosPerHostBuffer; - - past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) + - (LOWPASS_COEFFICIENT_1 * newUsage); - -} - -/*********************************************************************** -** Called by Pa_StartStream() -*/ -PaError PaHost_StartInput( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - pahsc->pahsc_IsRecording = 0; - pahsc->pahsc_StopRecording = 0; - pahsc->pahsc_InputMultiBuffer.nextWrite = 0; - pahsc->pahsc_InputMultiBuffer.nextRead = 0; - return PaMac_RecordNext( past ); -} - -/*********************************************************************** -** Called by Pa_StopStream(). -** May be called during error recovery or cleanup code -** so protect against NULL pointers. -*/ -PaError PaHost_StopInput( internalPortAudioStream *past, int abort ) -{ - int32 timeOutMsec; - PaError result = paNoError; - OSErr err = 0; - long mRefNum; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paNoError; - - (void) abort; - - mRefNum = pahsc->pahsc_InputRefNum; - - DBUG(("PaHost_StopInput: mRefNum = %d\n", mRefNum )); - if( mRefNum ) - { - DBUG(("PaHost_StopInput: pahsc_IsRecording = %d\n", pahsc->pahsc_IsRecording )); - if( pahsc->pahsc_IsRecording ) - { - /* PLB20010420 - Fix TIMEOUT in record mode. */ - pahsc->pahsc_StopRecording = 1; /* Request that we stop recording. */ - err = SPBStopRecording(mRefNum); - DBUG(("PaHost_StopInput: then pahsc_IsRecording = %d\n", pahsc->pahsc_IsRecording )); - - /* Calculate timeOut longer than longest time it could take to play one buffer. */ - timeOutMsec = (int32) ((1500.0 * pahsc->pahsc_FramesPerHostBuffer) / past->past_SampleRate); - /* Keep querying sound channel until it is no longer busy playing. */ - while( !err && pahsc->pahsc_IsRecording && (timeOutMsec > 0)) - { - Pa_Sleep(20); - timeOutMsec -= 20; - } - if( timeOutMsec <= 0 ) - { - ERR_RPT(("PaHost_StopInput: timed out!\n")); - return paTimedOut; - } - } - } - if( err ) - { - sPaHostError = err; - result = paHostError; - } - - DBUG(("PaHost_StopInput: finished.\n", mRefNum )); - return result; -} - -/***********************************************************************/ -static void PaMac_InitSoundHeader( internalPortAudioStream *past, CmpSoundHeader *sndHeader ) -{ - sndHeader->numChannels = past->past_NumOutputChannels; - sndHeader->sampleRate = DoubleToUnsignedFixed(past->past_SampleRate); - sndHeader->loopStart = 0; - sndHeader->loopEnd = 0; - sndHeader->encode = cmpSH; - sndHeader->baseFrequency = kMiddleC; - sndHeader->markerChunk = nil; - sndHeader->futureUse2 = nil; - sndHeader->stateVars = nil; - sndHeader->leftOverSamples = nil; - sndHeader->compressionID = 0; - sndHeader->packetSize = 0; - sndHeader->snthID = 0; - sndHeader->sampleSize = 8 * sizeof(int16); // FIXME - might be 24 or 32 bits some day; - sndHeader->sampleArea[0] = 0; - sndHeader->format = kSoundNotCompressed; -} - -static void SetFramesDone( PaHostSoundControl *pahsc, PaTimestamp framesDone ) -{ - UnsignedWide now; - Microseconds( &now ); - pahsc->pahsc_NumFramesDone = framesDone; - pahsc->pahsc_WhenFramesDoneIncremented = UnsignedWideToUInt64( now ); -} - -/***********************************************************************/ -PaError PaHost_StartOutput( internalPortAudioStream *past ) -{ - SndCommand pauseCommand; - SndCommand resumeCommand; - int i; - OSErr error; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paInternalError; - if( pahsc->pahsc_Channel == NULL ) return paInternalError; - - past->past_StopSoon = 0; - past->past_IsActive = 1; - pahsc->pahsc_NumOutsQueued = 0; - pahsc->pahsc_NumOutsPlayed = 0; - - SetFramesDone( pahsc, 0.0 ); - - /* Pause channel so it does not do back ground processing while we are still filling the queue. */ - pauseCommand.cmd = pauseCmd; - pauseCommand.param1 = pauseCommand.param2 = 0; - error = SndDoCommand (pahsc->pahsc_Channel, &pauseCommand, true); - if (noErr != error) goto exit; - - /* Queue all of the buffers so we start off full. */ - for (i = 0; i<pahsc->pahsc_NumHostBuffers; i++) - { - PaMac_PlayNext( past, i ); - } - - /* Resume channel now that the queue is full. */ - resumeCommand.cmd = resumeCmd; - resumeCommand.param1 = resumeCommand.param2 = 0; - error = SndDoImmediate( pahsc->pahsc_Channel, &resumeCommand ); - if (noErr != error) goto exit; - - return paNoError; -exit: - past->past_IsActive = 0; - sPaHostError = error; - ERR_RPT(("Error in PaHost_StartOutput: SndDoCommand returned %d\n", error )); - return paHostError; -} - -/*******************************************************************/ -long PaHost_GetTotalBufferFrames( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - return (long) (pahsc->pahsc_NumHostBuffers * pahsc->pahsc_FramesPerHostBuffer); -} - -/*********************************************************************** -** Called by Pa_StopStream(). -** May be called during error recovery or cleanup code -** so protect against NULL pointers. -*/ -PaError PaHost_StopOutput( internalPortAudioStream *past, int abort ) -{ - int32 timeOutMsec; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paNoError; - if( pahsc->pahsc_Channel == NULL ) return paNoError; - - DBUG(("PaHost_StopOutput()\n")); - if( past->past_IsActive == 0 ) return paNoError; - - /* Set flags for callback function to see. */ - if( abort ) past->past_StopNow = 1; - past->past_StopSoon = 1; - /* Calculate timeOut longer than longest time it could take to play all buffers. */ - timeOutMsec = (int32) ((1500.0 * PaHost_GetTotalBufferFrames( past )) / past->past_SampleRate); - /* Keep querying sound channel until it is no longer busy playing. */ - while( past->past_IsActive && (timeOutMsec > 0)) - { - Pa_Sleep(20); - timeOutMsec -= 20; - } - if( timeOutMsec <= 0 ) - { - ERR_RPT(("PaHost_StopOutput: timed out!\n")); - return paTimedOut; - } - else return paNoError; -} - -/***********************************************************************/ -PaError PaHost_StartEngine( internalPortAudioStream *past ) -{ - (void) past; /* Prevent unused variable warnings. */ - return paNoError; -} - -/***********************************************************************/ -PaError PaHost_StopEngine( internalPortAudioStream *past, int abort ) -{ - (void) past; /* Prevent unused variable warnings. */ - (void) abort; /* Prevent unused variable warnings. */ - return paNoError; -} -/***********************************************************************/ -PaError PaHost_StreamActive( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - return (PaError) ( past->past_IsActive + pahsc->pahsc_IsRecording ); -} -int Mac_IsVirtualMemoryOn( void ) -{ - long attr; - OSErr result = Gestalt( gestaltVMAttr, &attr ); - DBUG(("gestaltVMAttr : 0x%x\n", attr )); - return ((attr >> gestaltVMHasPagingControl ) & 1); -} - -/******************************************************************* -* Determine number of host Buffers -* and how many User Buffers we can put into each host buffer. -*/ -static void PaHost_CalcNumHostBuffers( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - int32 minNumBuffers; - int32 minFramesPerHostBuffer; - int32 minTotalFrames; - int32 userBuffersPerHostBuffer; - int32 framesPerHostBuffer; - int32 numHostBuffers; - - minFramesPerHostBuffer = pahsc->pahsc_MinFramesPerHostBuffer; - minFramesPerHostBuffer = (minFramesPerHostBuffer + 7) & ~7; - DBUG(("PaHost_CalcNumHostBuffers: minFramesPerHostBuffer = %d\n", minFramesPerHostBuffer )); - - /* Determine number of user buffers based on minimum latency. */ - /* PLB20020417 I used to call Pa_GetMinNumBuffers() which doesn't take into account the - ** variable minFramesPerHostBuffer. Now I call PaMac_GetMinNumBuffers() which will - ** gove lower latency when virtual memory is turned off. */ - /* minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate ); WRONG */ - minNumBuffers = PaMac_GetMinNumBuffers( minFramesPerHostBuffer, past->past_FramesPerUserBuffer, past->past_SampleRate ); - - past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers; - DBUG(("PaHost_CalcNumHostBuffers: min past_NumUserBuffers = %d\n", past->past_NumUserBuffers )); - minTotalFrames = past->past_NumUserBuffers * past->past_FramesPerUserBuffer; - - /* We cannot make the buffers too small because they may not get serviced quickly enough. */ - if( (int32) past->past_FramesPerUserBuffer < minFramesPerHostBuffer ) - { - userBuffersPerHostBuffer = - (minFramesPerHostBuffer + past->past_FramesPerUserBuffer - 1) / - past->past_FramesPerUserBuffer; - } - else - { - userBuffersPerHostBuffer = 1; - } - framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer; - - /* Calculate number of host buffers needed. Round up to cover minTotalFrames. */ - numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer; - /* Make sure we have enough host buffers. */ - if( numHostBuffers < PA_MIN_NUM_HOST_BUFFERS) - { - numHostBuffers = PA_MIN_NUM_HOST_BUFFERS; - } - else - { - /* If we have too many host buffers, try to put more user buffers in a host buffer. */ - while(numHostBuffers > PA_MAX_NUM_HOST_BUFFERS) - { - userBuffersPerHostBuffer += 1; - framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer; - numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer; - } - } - - pahsc->pahsc_UserBuffersPerHostBuffer = userBuffersPerHostBuffer; - pahsc->pahsc_FramesPerHostBuffer = framesPerHostBuffer; - pahsc->pahsc_NumHostBuffers = numHostBuffers; - DBUG(("PaHost_CalcNumHostBuffers: pahsc_UserBuffersPerHostBuffer = %d\n", pahsc->pahsc_UserBuffersPerHostBuffer )); - DBUG(("PaHost_CalcNumHostBuffers: pahsc_NumHostBuffers = %d\n", pahsc->pahsc_NumHostBuffers )); - DBUG(("PaHost_CalcNumHostBuffers: pahsc_FramesPerHostBuffer = %d\n", pahsc->pahsc_FramesPerHostBuffer )); - DBUG(("PaHost_CalcNumHostBuffers: past_NumUserBuffers = %d\n", past->past_NumUserBuffers )); -} - -/*******************************************************************/ -PaError PaHost_OpenStream( internalPortAudioStream *past ) -{ - OSErr err; - PaError result = paHostError; - PaHostSoundControl *pahsc; - int i; - /* Allocate and initialize host data. */ - pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); - if( pahsc == NULL ) - { - return paInsufficientMemory; - } - past->past_DeviceData = (void *) pahsc; - - /* If recording, and virtual memory is turned on, then use bigger buffers to prevent glitches. */ - if( (past->past_NumInputChannels > 0) && Mac_IsVirtualMemoryOn() ) - { - pahsc->pahsc_MinFramesPerHostBuffer = MAC_VIRTUAL_FRAMES_PER_BUFFER; - } - else - { - pahsc->pahsc_MinFramesPerHostBuffer = MAC_PHYSICAL_FRAMES_PER_BUFFER; - } - - PaHost_CalcNumHostBuffers( past ); - - /* Setup constants for CPU load measurement. */ - pahsc->pahsc_InverseMicrosPerHostBuffer = past->past_SampleRate / (1000000.0 * pahsc->pahsc_FramesPerHostBuffer); - - /* ------------------ OUTPUT */ - if( past->past_NumOutputChannels > 0 ) - { - /* Create sound channel to which we can send commands. */ - pahsc->pahsc_Channel = 0L; - err = SndNewChannel(&pahsc->pahsc_Channel, sampledSynth, 0, nil); /* FIXME - use kUseOptionalOutputDevice if not default. */ - if(err != 0) - { - ERR_RPT(("Error in PaHost_OpenStream: SndNewChannel returned 0x%x\n", err )); - goto error; - } - - /* Install our callback function pointer straight into the sound channel structure */ - /* Use new CARBON name for callback procedure. */ -#if TARGET_API_MAC_CARBON - pahsc->pahsc_OutputCompletionProc = NewSndCallBackUPP(PaMac_OutputCompletionProc); -#else - pahsc->pahsc_OutputCompletionProc = NewSndCallBackProc(PaMac_OutputCompletionProc); -#endif - - pahsc->pahsc_Channel->callBack = pahsc->pahsc_OutputCompletionProc; - - pahsc->pahsc_BytesPerOutputHostBuffer = pahsc->pahsc_FramesPerHostBuffer * past->past_NumOutputChannels * sizeof(int16); - for (i = 0; i<pahsc->pahsc_NumHostBuffers; i++) - { - char *buf = (char *)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerOutputHostBuffer); - if (buf == NULL) - { - ERR_RPT(("Error in PaHost_OpenStream: could not allocate output buffer. Size = \n", pahsc->pahsc_BytesPerOutputHostBuffer )); - goto memerror; - } - - PaMac_InitSoundHeader( past, &pahsc->pahsc_SoundHeaders[i] ); - pahsc->pahsc_SoundHeaders[i].samplePtr = buf; - pahsc->pahsc_SoundHeaders[i].numFrames = (unsigned long) pahsc->pahsc_FramesPerHostBuffer; - - } - } -#ifdef SUPPORT_AUDIO_CAPTURE - /* ------------------ INPUT */ - /* Use double buffer scheme that matches output. */ - if( past->past_NumInputChannels > 0 ) - { - int16 tempS; - long tempL; - Fixed tempF; - long mRefNum; - unsigned char noname = 0; /* FIXME - use real device names. */ -#if TARGET_API_MAC_CARBON - pahsc->pahsc_InputCompletionProc = NewSICompletionUPP((SICompletionProcPtr)PaMac_InputCompletionProc); -#else - pahsc->pahsc_InputCompletionProc = NewSICompletionProc((ProcPtr)PaMac_InputCompletionProc); -#endif - pahsc->pahsc_BytesPerInputHostBuffer = pahsc->pahsc_FramesPerHostBuffer * past->past_NumInputChannels * sizeof(int16); - for (i = 0; i<pahsc->pahsc_NumHostBuffers; i++) - { - char *buf = (char *) PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerInputHostBuffer); - if ( buf == NULL ) - { - ERR_RPT(("PaHost_OpenStream: could not allocate input buffer. Size = \n", pahsc->pahsc_BytesPerInputHostBuffer )); - goto memerror; - } - pahsc->pahsc_InputMultiBuffer.buffers[i] = buf; - } - pahsc->pahsc_InputMultiBuffer.numBuffers = pahsc->pahsc_NumHostBuffers; - - err = SPBOpenDevice( (const unsigned char *) &noname, siWritePermission, &mRefNum); /* FIXME - use name so we get selected device */ - // FIXME err = SPBOpenDevice( (const unsigned char *) sDevices[past->past_InputDeviceID].pad_Info.name, siWritePermission, &mRefNum); - if (err) goto error; - pahsc->pahsc_InputRefNum = mRefNum; - DBUG(("PaHost_OpenStream: mRefNum = %d\n", mRefNum )); - - /* Set input device characteristics. */ - tempS = 1; - err = SPBSetDeviceInfo(mRefNum, siContinuous, (Ptr) &tempS); - if (err) - { - ERR_RPT(("Error in PaHost_OpenStream: SPBSetDeviceInfo siContinuous returned %d\n", err )); - goto error; - } - - tempL = 0x03; - err = SPBSetDeviceInfo(mRefNum, siActiveChannels, (Ptr) &tempL); - if (err) - { - DBUG(("PaHost_OpenStream: setting siActiveChannels returned 0x%x. Error ignored.\n", err )); - } - - /* PLB20010908 - Use requested number of input channels. Thanks Dominic Mazzoni. */ - tempS = past->past_NumInputChannels; - err = SPBSetDeviceInfo(mRefNum, siNumberChannels, (Ptr) &tempS); - if (err) - { - ERR_RPT(("Error in PaHost_OpenStream: SPBSetDeviceInfo siNumberChannels returned %d\n", err )); - goto error; - } - - tempF = ((unsigned long)past->past_SampleRate) << 16; - err = SPBSetDeviceInfo(mRefNum, siSampleRate, (Ptr) &tempF); - if (err) - { - ERR_RPT(("Error in PaHost_OpenStream: SPBSetDeviceInfo siSampleRate returned %d\n", err )); - goto error; - } - - /* Setup record-parameter block */ - pahsc->pahsc_InputParams.inRefNum = mRefNum; - pahsc->pahsc_InputParams.milliseconds = 0; // not used - pahsc->pahsc_InputParams.completionRoutine = pahsc->pahsc_InputCompletionProc; - pahsc->pahsc_InputParams.interruptRoutine = 0; - pahsc->pahsc_InputParams.userLong = (long) past; - pahsc->pahsc_InputParams.unused1 = 0; - } -#endif /* SUPPORT_AUDIO_CAPTURE */ - DBUG(("PaHost_OpenStream: complete.\n")); - return paNoError; - -error: - PaHost_CloseStream( past ); - ERR_RPT(("PaHost_OpenStream: sPaHostError = 0x%x.\n", err )); - sPaHostError = err; - return paHostError; - -memerror: - PaHost_CloseStream( past ); - return paInsufficientMemory; -} - -/*********************************************************************** -** Called by Pa_CloseStream(). -** May be called during error recovery or cleanup code -** so protect against NULL pointers. -*/ -PaError PaHost_CloseStream( internalPortAudioStream *past ) -{ - PaError result = paNoError; - OSErr err = 0; - int i; - PaHostSoundControl *pahsc; - - DBUG(("PaHost_CloseStream( 0x%x )\n", past )); - - if( past == NULL ) return paBadStreamPtr; - - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paNoError; - - if( past->past_NumOutputChannels > 0 ) - { - /* TRUE means flush now instead of waiting for quietCmd to be processed. */ - if( pahsc->pahsc_Channel != NULL ) SndDisposeChannel(pahsc->pahsc_Channel, TRUE); - { - for (i = 0; i<pahsc->pahsc_NumHostBuffers; i++) - { - Ptr p = (Ptr) pahsc->pahsc_SoundHeaders[i].samplePtr; - if( p != NULL ) PaHost_FreeFastMemory( p, pahsc->pahsc_BytesPerOutputHostBuffer ); - } - } - } - - if( past->past_NumInputChannels > 0 ) - { - if( pahsc->pahsc_InputRefNum ) - { - err = SPBCloseDevice(pahsc->pahsc_InputRefNum); - pahsc->pahsc_InputRefNum = 0; - if( err ) - { - sPaHostError = err; - result = paHostError; - } - } - { - for (i = 0; i<pahsc->pahsc_InputMultiBuffer.numBuffers; i++) - { - Ptr p = (Ptr) pahsc->pahsc_InputMultiBuffer.buffers[i]; - if( p != NULL ) PaHost_FreeFastMemory( p, pahsc->pahsc_BytesPerInputHostBuffer ); - } - } - } - - past->past_DeviceData = NULL; - PaHost_FreeFastMemory( pahsc, sizeof(PaHostSoundControl) ); - - DBUG(("PaHost_CloseStream: complete.\n", past )); - return result; -} -/*************************************************************************/ -int Pa_GetMinNumBuffers( int framesPerUserBuffer, double sampleRate ) -{ -/* We use the MAC_VIRTUAL_FRAMES_PER_BUFFER because we might be recording. -** This routine doesn't have enough information to determine the best value -** and is being depracated. */ - return PaMac_GetMinNumBuffers( MAC_VIRTUAL_FRAMES_PER_BUFFER, framesPerUserBuffer, sampleRate ); -} -/*************************************************************************/ -static int PaMac_GetMinNumBuffers( int minFramesPerHostBuffer, int framesPerUserBuffer, double sampleRate ) -{ - int minUserPerHost = ( minFramesPerHostBuffer + framesPerUserBuffer - 1) / framesPerUserBuffer; - int numBufs = PA_MIN_NUM_HOST_BUFFERS * minUserPerHost; - if( numBufs < PA_MIN_NUM_HOST_BUFFERS ) numBufs = PA_MIN_NUM_HOST_BUFFERS; - (void) sampleRate; - return numBufs; -} - -/*************************************************************************/ -void Pa_Sleep( int32 msec ) -{ - EventRecord event; - int32 sleepTime, endTime; - /* Convert to ticks. Round up so we sleep a MINIMUM of msec time. */ - sleepTime = ((msec * 60) + 999) / 1000; - if( sleepTime < 1 ) sleepTime = 1; - endTime = TickCount() + sleepTime; - do - { - DBUGX(("Sleep for %d ticks.\n", sleepTime )); - /* Use WaitNextEvent() to sleep without getting events. */ - /* PLB20010907 - Pass unused event to WaitNextEvent instead of NULL to prevent - * Mac OSX crash. Thanks Dominic Mazzoni. */ - WaitNextEvent( 0, &event, sleepTime, NULL ); - sleepTime = endTime - TickCount(); - } - while( sleepTime > 0 ); -} -/*************************************************************************/ -int32 Pa_GetHostError( void ) -{ - int32 err = sPaHostError; - sPaHostError = 0; - return err; -} - -/************************************************************************* - * Allocate memory that can be accessed in real-time. - * This may need to be held in physical memory so that it is not - * paged to virtual memory. - * This call MUST be balanced with a call to PaHost_FreeFastMemory(). - */ -void *PaHost_AllocateFastMemory( long numBytes ) -{ - void *addr = NewPtrClear( numBytes ); - if( (addr == NULL) || (MemError () != 0) ) return NULL; - -#if (TARGET_API_MAC_CARBON == 0) - if( HoldMemory( addr, numBytes ) != noErr ) - { - DisposePtr( (Ptr) addr ); - return NULL; - } -#endif - return addr; -} - -/************************************************************************* - * Free memory that could be accessed in real-time. - * This call MUST be balanced with a call to PaHost_AllocateFastMemory(). - */ -void PaHost_FreeFastMemory( void *addr, long numBytes ) -{ - if( addr == NULL ) return; -#if TARGET_API_MAC_CARBON - (void) numBytes; -#else - UnholdMemory( addr, numBytes ); -#endif - DisposePtr( (Ptr) addr ); -} - -/*************************************************************************/ -PaTimestamp Pa_StreamTime( PortAudioStream *stream ) -{ - PaTimestamp framesDone1; - PaTimestamp framesDone2; - UInt64 whenIncremented; - UnsignedWide now; - UInt64 now64; - long microsElapsed; - long framesElapsed; - - PaHostSoundControl *pahsc; - internalPortAudioStream *past = (internalPortAudioStream *) stream; - if( past == NULL ) return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - -/* Capture information from audio thread. - * We have to be careful that we don't get interrupted in the middle. - * So we grab the pahsc_NumFramesDone twice and make sure it didn't change. - */ - do - { - framesDone1 = pahsc->pahsc_NumFramesDone; - whenIncremented = pahsc->pahsc_WhenFramesDoneIncremented; - framesDone2 = pahsc->pahsc_NumFramesDone; - } while( framesDone1 != framesDone2 ); - - /* Calculate how many microseconds have elapsed and convert to frames. */ - Microseconds( &now ); - now64 = UnsignedWideToUInt64( now ); - microsElapsed = U64Subtract( now64, whenIncremented ); - framesElapsed = microsElapsed * past->past_SampleRate * 0.000001; - - return framesDone1 + framesElapsed; -} - -/************************************************************************** -** Callback for Input, SPBRecord() -*/ -int gRecordCounter = 0; -int gPlayCounter = 0; -pascal void PaMac_InputCompletionProc(SPBPtr recParams) -{ - PaError result = paNoError; - int finished = 1; - internalPortAudioStream *past; - PaHostSoundControl *pahsc; - - gRecordCounter += 1; /* debug hack to see if engine running */ - - /* Get our PA data from Mac structure. */ - past = (internalPortAudioStream *) recParams->userLong; - if( past == NULL ) return; - - if( past->past_Magic != PA_MAGIC ) - { - AddTraceMessage("PaMac_InputCompletionProc: bad MAGIC, past", (long) past ); - AddTraceMessage("PaMac_InputCompletionProc: bad MAGIC, magic", (long) past->past_Magic ); - goto error; - } - pahsc = (PaHostSoundControl *) past->past_DeviceData; - past->past_NumCallbacks += 1; - - /* Have we been asked to stop recording? */ - if( (recParams->error == abortErr) || pahsc->pahsc_StopRecording ) goto error; - - /* If there are no output channels, then we need to call the user callback function from here. - * Otherwise we will call the user code during the output completion routine. - */ - if(past->past_NumOutputChannels == 0) - { - SetFramesDone( pahsc, - pahsc->pahsc_NumFramesDone + pahsc->pahsc_FramesPerHostBuffer ); - result = PaMac_CallUserLoop( past, NULL ); - } - - /* Did user code ask us to stop? If not, issue another recording request. */ - if( (result == paNoError) && (pahsc->pahsc_StopRecording == 0) ) - { - result = PaMac_RecordNext( past ); - if( result != paNoError ) pahsc->pahsc_IsRecording = 0; - } - else goto error; - - return; - -error: - pahsc->pahsc_IsRecording = 0; - pahsc->pahsc_StopRecording = 0; - return; -} - -/*********************************************************************** -** Called by either input or output completion proc. -** Grabs input data if any present, and calls PA conversion code, -** that in turn calls user code. -*/ -static PaError PaMac_CallUserLoop( internalPortAudioStream *past, int16 *outPtr ) -{ - PaError result = paNoError; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - int16 *inPtr = NULL; - int i; - - - /* Advance read index for sound input FIFO here, independantly of record/write process. */ - if(past->past_NumInputChannels > 0) - { - if( MultiBuffer_IsReadable( &pahsc->pahsc_InputMultiBuffer ) ) - { - inPtr = (int16 *) MultiBuffer_GetNextReadBuffer( &pahsc->pahsc_InputMultiBuffer ); - MultiBuffer_AdvanceReadIndex( &pahsc->pahsc_InputMultiBuffer ); - } - } - - /* Call user code enough times to fill buffer. */ - if( (inPtr != NULL) || (outPtr != NULL) ) - { - PaMac_StartLoadCalculation( past ); /* CPU usage */ - -#ifdef PA_MAX_USAGE_ALLOWED - /* If CPU usage exceeds limit, skip user callback to prevent hanging CPU. */ - if( past->past_Usage > PA_MAX_USAGE_ALLOWED ) - { - past->past_FrameCount += (PaTimestamp) pahsc->pahsc_FramesPerHostBuffer; - } - else -#endif - { - - for( i=0; i<pahsc->pahsc_UserBuffersPerHostBuffer; i++ ) - { - result = (PaError) Pa_CallConvertInt16( past, inPtr, outPtr ); - if( result != 0) - { - /* Recording might be in another process, so tell it to stop with a flag. */ - pahsc->pahsc_StopRecording = pahsc->pahsc_IsRecording; - break; - } - /* Advance sample pointers. */ - if(inPtr != NULL) inPtr += past->past_FramesPerUserBuffer * past->past_NumInputChannels; - if(outPtr != NULL) outPtr += past->past_FramesPerUserBuffer * past->past_NumOutputChannels; - } - } - - PaMac_EndLoadCalculation( past ); - } - return result; -} - -/*********************************************************************** -** Setup next recording buffer in FIFO and issue recording request to Snd Input Manager. -*/ -static PaError PaMac_RecordNext( internalPortAudioStream *past ) -{ - PaError result = paNoError; - OSErr err; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - /* Get pointer to next buffer to record into. */ - pahsc->pahsc_InputParams.bufferPtr = MultiBuffer_GetNextWriteBuffer( &pahsc->pahsc_InputMultiBuffer ); - - /* Advance write index if there is room. Otherwise keep writing same buffer. */ - if( MultiBuffer_IsWriteable( &pahsc->pahsc_InputMultiBuffer ) ) - { - MultiBuffer_AdvanceWriteIndex( &pahsc->pahsc_InputMultiBuffer ); - } - - AddTraceMessage("PaMac_RecordNext: bufferPtr", (long) pahsc->pahsc_InputParams.bufferPtr ); - AddTraceMessage("PaMac_RecordNext: nextWrite", pahsc->pahsc_InputMultiBuffer.nextWrite ); - - /* Setup parameters and issue an asynchronous recording request. */ - pahsc->pahsc_InputParams.bufferLength = pahsc->pahsc_BytesPerInputHostBuffer; - pahsc->pahsc_InputParams.count = pahsc->pahsc_BytesPerInputHostBuffer; - err = SPBRecord(&pahsc->pahsc_InputParams, true); - if( err ) - { - AddTraceMessage("PaMac_RecordNext: SPBRecord error ", err ); - sPaHostError = err; - result = paHostError; - } - else - { - pahsc->pahsc_IsRecording = 1; - } - return result; -} - -/************************************************************************** -** Callback for Output Playback() -** Return negative error, 0 to continue, 1 to stop. -*/ -long PaMac_FillNextOutputBuffer( internalPortAudioStream *past, int index ) -{ - PaHostSoundControl *pahsc; - long result = 0; - int finished = 1; - char *outPtr; - - gPlayCounter += 1; /* debug hack */ - - past->past_NumCallbacks += 1; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return -1; - /* Are we nested?! */ - if( pahsc->pahsc_IfInsideCallback ) return 0; - pahsc->pahsc_IfInsideCallback = 1; - /* Get pointer to buffer to fill. */ - outPtr = pahsc->pahsc_SoundHeaders[index].samplePtr; - /* Combine with any sound input, and call user callback. */ - result = PaMac_CallUserLoop( past, (int16 *) outPtr ); - - pahsc->pahsc_IfInsideCallback = 0; - return result; -} - -/************************************************************************************* -** Called by SoundManager when ready for another buffer. -*/ -static pascal void PaMac_OutputCompletionProc (SndChannelPtr theChannel, SndCommand * theCallBackCmd) -{ - internalPortAudioStream *past; - PaHostSoundControl *pahsc; - (void) theChannel; - (void) theCallBackCmd; - - /* Get our data from Mac structure. */ - past = (internalPortAudioStream *) theCallBackCmd->param2; - if( past == NULL ) return; - - pahsc = (PaHostSoundControl *) past->past_DeviceData; - pahsc->pahsc_NumOutsPlayed += 1; - - SetFramesDone( pahsc, - pahsc->pahsc_NumFramesDone + pahsc->pahsc_FramesPerHostBuffer ); - - PaMac_BackgroundManager( past, theCallBackCmd->param1 ); -} - -/*******************************************************************/ -static PaError PaMac_BackgroundManager( internalPortAudioStream *past, int index ) -{ - PaError result = paNoError; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - /* Has someone asked us to abort by calling Pa_AbortStream()? */ - if( past->past_StopNow ) - { - SndCommand command; - /* Clear the queue of any pending commands. */ - command.cmd = flushCmd; - command.param1 = command.param2 = 0; - SndDoImmediate( pahsc->pahsc_Channel, &command ); - /* Then stop currently playing buffer, if any. */ - command.cmd = quietCmd; - SndDoImmediate( pahsc->pahsc_Channel, &command ); - past->past_IsActive = 0; - } - /* Has someone asked us to stop by calling Pa_StopStream() - * OR has a user callback returned '1' to indicate finished. - */ - else if( past->past_StopSoon ) - { - if( (pahsc->pahsc_NumOutsQueued - pahsc->pahsc_NumOutsPlayed) <= 0 ) - { - past->past_IsActive = 0; /* We're finally done. */ - } - } - else - { - PaMac_PlayNext( past, index ); - } - return result; -} - -/************************************************************************************* -** Fill next buffer with sound and queue it for playback. -*/ -static void PaMac_PlayNext ( internalPortAudioStream *past, int index ) -{ - OSErr error; - long result; - SndCommand playCmd; - SndCommand callbackCmd; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - - /* If this was the last buffer, or abort requested, then just be done. */ - if ( past->past_StopSoon ) goto done; - - /* Load buffer with sound. */ - result = PaMac_FillNextOutputBuffer ( past, index ); - if( result > 0 ) past->past_StopSoon = 1; /* Stop generating audio but wait until buffers play. */ - else if( result < 0 ) goto done; - - /* Play the next buffer. */ - playCmd.cmd = bufferCmd; - playCmd.param1 = 0; - playCmd.param2 = (long) &pahsc->pahsc_SoundHeaders[ index ]; - error = SndDoCommand (pahsc->pahsc_Channel, &playCmd, true ); - if( error != noErr ) goto gotError; - - /* Ask for a callback when it is done. */ - callbackCmd.cmd = callBackCmd; - callbackCmd.param1 = index; - callbackCmd.param2 = (long)past; - error = SndDoCommand (pahsc->pahsc_Channel, &callbackCmd, true ); - if( error != noErr ) goto gotError; - pahsc->pahsc_NumOutsQueued += 1; - - return; - -gotError: - sPaHostError = error; -done: - return; -} diff --git a/pd/portaudio/pa_sgi/Makefile b/pd/portaudio/pa_sgi/Makefile deleted file mode 100644 index 6548c6c5..00000000 --- a/pd/portaudio/pa_sgi/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# Make PortAudio for Silicon Graphics IRIX (6.2) -# Pieter suurmond, september 23, 2001. (pa_sgi sub-version #0.21 for PA v15.) -# Based on SGI-specific sproc()-method to spawn children, not on POSIX-threads. - -# Instead of "-lpthread", as with linux, -# just the audio- and math-library for SGI: -LIBS = -laudio -lm - -CDEFINES = -I../pa_common - -# Possible CFLAGS with MIPSpro compiler are: -32, -o32, -n32, -64, -# -mips1, -mips2, -mips3, -mips4, etc. Use -g, -g2, -g3 for debugging. -# And use for example -O2 or -O3 for better optimization: -CFLAGS = -O2 -PASRC = ../pa_common/pa_lib.c pa_sgi.c -PAINC = ../pa_common/portaudio.h - -# Tests that work (SGI Indy with R5000 @ 180MHz running IRIX 6.2). -TESTC = $(PASRC) ../pa_tests/patest_record.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_many.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_latency.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_longsine.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_saw.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_wire.c # OK -#TESTC = $(PASRC) ../pa_tests/pa_devs.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_sine.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_sine_time.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_sine8.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_leftright.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_pink.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_clip.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_stop.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_dither.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_sync.c # BEEPS and delta's, no crashes anymore. - -# Tests that were not yet performed. -#TESTC = $(PASRC) ../pa_tests/paqa_devs.c # test?? -#TESTC = $(PASRC) ../pa_tests/paqa_errs.c # test?? -#TESTC = $(PASRC) ../pa_tests/pa_fuzz.c # test?? - -TESTH = $(PAINC) - -all: patest - -# "cc" for the MIPSpro compiler, may be changed to "gcc": -patest: $(TESTC) $(TESTH) Makefile - cc $(CFLAGS) $(TESTC) $(CDEFINES) $(LIBS) -o patest - -run: patest - ./patest - diff --git a/pd/portaudio/pa_sgi/pa_sgi.c b/pd/portaudio/pa_sgi/pa_sgi.c deleted file mode 100644 index 4b91f02c..00000000 --- a/pd/portaudio/pa_sgi/pa_sgi.c +++ /dev/null @@ -1,999 +0,0 @@ -/* - * $Id: pa_sgi.c,v 1.2 2002/05/04 20:38:42 philburk Exp $ - * PortAudio Portable Real-Time Audio Library. Copyright (c) 1999-2001 Phil Burk. - * Latest Version at: http://www.portaudio.com - * - * Silicon Graphics IRIX implementation by Pieter Suurmond, september 23, 2001. - * pa_sgi-sub-version number 0.21, for PortAudio v15. - * This implementation uses the sproc()-method, not the POSIX method. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * -Modfication History: - 8/12/2001 - Pieter Suurmond - took the v15 pa_linux_oss.c file and started to adapt for IRIX 6.2. - 8/17/2001 - v15 pa_sgi sub-version #0.04 (unstable alpha release) Sent to Phil & Ross. - 9/23/2001 - #0.21 Many fixes and changes: POLLIN for input, not POLLOUT. - Open and close ALports in the audio-process-thread. - Proper semaphore communication now. - Hopefully stable enough now (for beta release?). -TODO: - - Test under IRIX 6.5. - - Dynamically switch to 32 bit float as native format when appropriate (let SGI do the conversion), - and maybe also the other natively supported formats? (might increase performance) - - The minimal number of buffers setting... I do not yet fully understand it.. I now just take *4. -REFERENCES: - - IRIX 6.2 man pages regarding SGI AL library. - - IRIS Digital MediaProgramming Guide (online books and man-pages come - with IRIX 6.2 and may not be publically available on the internet). -*/ - -#include <stdio.h> /* Standard libraries. */ -#include <stdlib.h> - -#include "../pa_common/portaudio.h" /* BETTER PATH !!!???? Portaudio headers. */ -#include "../pa_common/pa_host.h" -#include "../pa_common/pa_trace.h" - -#include <sys/time.h> -#include <sys/types.h> -#include <sys/prctl.h> -#include <sys/schedctl.h> /* For schedctl(NDPRI, NDPHIMIN). */ -#include <fcntl.h> /* fcntl.h needed. */ -#include <unistd.h> /* For streams, ioctl(), etc. */ -#include <ulocks.h> -#include <poll.h> -#include <dmedia/audio.h> /* System specific (IRIX 6.2). */ - -/*--------------------------------------------*/ -#define PRINT(x) { printf x; fflush(stdout); } -#define ERR_RPT(x) PRINT(x) -#define DBUG(x) /* PRINT(x) */ -#define DBUGX(x) /* PRINT(x) */ - -#define MAX_CHARS_DEVNAME (16) /* Was 32 in OSS (20 for AL but "in"/"out" is concat. */ -#define MAX_SAMPLE_RATES (8) /* Known from SGI AL there are 7 (was 10 in OSS v15). */ - -typedef struct internalPortAudioDevice /* IRIX specific device info: */ -{ - PaDeviceID /* NEW: */ pad_DeviceID; /* THIS "ID" IS NEW HERE (Pieter)! */ - long pad_ALdevice; /* SGI-number! */ - double pad_SampleRates[MAX_SAMPLE_RATES]; /* for pointing to from pad_Info */ - char pad_DeviceName[MAX_CHARS_DEVNAME+1]; /* +1 for \0, one more than OSS. */ - PaDeviceInfo pad_Info; /* pad_Info (v15) contains: */ - /* int structVersion; */ - /* const char* name; */ - /* int maxInputChannels, maxOutputChannels; */ - /* int numSampleRates; Num rates, or -1 if range supprtd. */ - /* const double* sampleRates; Array of supported sample rates, */ - /* PaSampleFormat nativeSampleFormats; or {min,max} if range supported. */ - struct internalPortAudioDevice* pad_Next; /* Singly linked list, (NULL=end). */ -} internalPortAudioDevice; - -typedef struct PaHostSoundControl /* Structure to contain all SGI IRIX specific data. */ -{ - ALconfig pahsc_ALconfigIN, /* IRIX-audio-library-datatype. Configuration */ - pahsc_ALconfigOUT; /* stucts separate for input and output ports. */ - ALport pahsc_ALportIN, /* IRIX-audio-library-datatype. ALports can only be */ - pahsc_ALportOUT; /* unidirectional, so we sometimes need 2 of them. */ - int pahsc_threadPID; /* Sproc()-result, written by PaHost_StartEngine(). */ - short *pahsc_NativeInputBuffer, /* Allocated here, in this file, if necessary. */ - *pahsc_NativeOutputBuffer; - unsigned int pahsc_BytesPerInputBuffer, /* Native buffer sizes in bytes, really needed here */ - pahsc_BytesPerOutputBuffer; /* to free FAST memory, if buffs were alloctd FAST. */ - unsigned int pahsc_SamplesPerInputBuffer, /* These amounts are needed again and again in the */ - pahsc_SamplesPerOutputBuffer; /* audio-thread (don't need to be kept globally). */ - struct itimerval pahsc_EntryTime, /* For measuring CPU utilization (same as linux). */ - pahsc_LastExitTime; - long pahsc_InsideCountSum, - pahsc_TotalCountSum; -} PaHostSoundControl; - -/*-------------------------------------------------------- Shared Data -------------------------------*/ -static internalPortAudioDevice* sDeviceList = NULL; /* FIXME - put Mutex around this shared data. */ -static int sPaHostError = 0; /* Maybe more than one process writing errs!? */ -usema_t *SendSema, /* These variables are shared between the */ - *RcvSema; /* audio handling process and main process. */ -/*--------------------------*/ -long Pa_GetHostError(void) -{ - return (long)sPaHostError; -} - -/*----------------------------- BEGIN CPU UTILIZATION MEASUREMENT -----------------*/ -/* (copied from source pa_linux_oss/pa_linux_oss.c) */ -static void Pa_StartUsageCalculation( internalPortAudioStream *past ) -{ - struct itimerval itimer; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return; -/* Query system timer for usage analysis and to prevent overuse of CPU. */ - getitimer( ITIMER_REAL, &pahsc->pahsc_EntryTime ); -} - -static long SubtractTime_AminusB( struct itimerval *timeA, struct itimerval *timeB ) -{ - long secs = timeA->it_value.tv_sec - timeB->it_value.tv_sec; - long usecs = secs * 1000000; - usecs += (timeA->it_value.tv_usec - timeB->it_value.tv_usec); - return usecs; -} - -static void Pa_EndUsageCalculation( internalPortAudioStream *past ) -{ - struct itimerval currentTime; - long insideCount; - long totalCount; /* Measure CPU utilization during this callback. */ - -#define LOWPASS_COEFFICIENT_0 (0.95) -#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0) - - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if (pahsc == NULL) - return; - if (getitimer( ITIMER_REAL, ¤tTime ) == 0 ) - { - if (past->past_IfLastExitValid) - { - insideCount = SubtractTime_AminusB( &pahsc->pahsc_EntryTime, ¤tTime ); - pahsc->pahsc_InsideCountSum += insideCount; - totalCount = SubtractTime_AminusB( &pahsc->pahsc_LastExitTime, ¤tTime ); - pahsc->pahsc_TotalCountSum += totalCount; - /* DBUG(("insideCount = %d, totalCount = %d\n", insideCount, totalCount )); */ - /* Low pass filter the result because sometimes we get called several times in a row. */ - /* That can cause the TotalCount to be very low which can cause the usage to appear */ - /* unnaturally high. So we must filter numerator and denominator separately!!! */ - if (pahsc->pahsc_InsideCountSum > 0) - { - past->past_AverageInsideCount = ((LOWPASS_COEFFICIENT_0 * past->past_AverageInsideCount) + - (LOWPASS_COEFFICIENT_1 * pahsc->pahsc_InsideCountSum)); - past->past_AverageTotalCount = ((LOWPASS_COEFFICIENT_0 * past->past_AverageTotalCount) + - (LOWPASS_COEFFICIENT_1 * pahsc->pahsc_TotalCountSum)); - past->past_Usage = past->past_AverageInsideCount / past->past_AverageTotalCount; - pahsc->pahsc_InsideCountSum = 0; - pahsc->pahsc_TotalCountSum = 0; - } - } - past->past_IfLastExitValid = 1; - } - pahsc->pahsc_LastExitTime.it_value.tv_sec = 100; - pahsc->pahsc_LastExitTime.it_value.tv_usec = 0; - setitimer( ITIMER_REAL, &pahsc->pahsc_LastExitTime, NULL ); - past->past_IfLastExitValid = 1; -} /*----------- END OF CPU UTILIZATION CODE (from pa_linux_oss/pa_linux_oss.c v15)--------------------*/ - - -/*--------------------------------------------------------------------------------------*/ -PaError translateSGIerror(void) /* Calls oserror(), may be used after an SGI AL-library */ -{ /* call to report via ERR_RPT(), yields a PaError-num. */ - const char* a = "SGI AL "; /* (Not absolutely sure errno came from THIS thread! */ - switch(oserror()) /* Read IRIX man-pages about the _SGI_MP_SOURCE macro.) */ - { - case AL_BAD_OUT_OF_MEM: - ERR_RPT(("%sout of memory.\n", a)); - return paInsufficientMemory; /* Known PaError. */ - case AL_BAD_CONFIG: - ERR_RPT(("%sconfiguration invalid or NULL.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_CHANNELS: - ERR_RPT(("%schannels not 1,2 or 4.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_NO_PORTS: - ERR_RPT(("%sout of audio ports.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_DEVICE: - ERR_RPT(("%swrong device number.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_DEVICE_ACCESS: - ERR_RPT(("%swrong device access.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_DIRECTION: - ERR_RPT(("%sinvalid direction.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_SAMPFMT: - ERR_RPT(("%sdoesn't accept sampleformat.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_FLOATMAX: - ERR_RPT(("%smax float value is zero.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_WIDTH: - ERR_RPT(("%sunsupported samplewidth.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_QSIZE: - ERR_RPT(("%sinvalid queue size.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_PVBUFFER: - ERR_RPT(("%sPVbuffer null.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_BUFFERLENGTH_NEG: - ERR_RPT(("%snegative bufferlength.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_BUFFERLENGTH_ODD: - ERR_RPT(("%sodd bufferlength.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_PARAM: - ERR_RPT(("%sparameter not valid for device.\n", a)); - return paHostError; /* Generic PaError. */ - default: - ERR_RPT(("%sunknown error.\n", a)); - return paHostError; /* Generic PaError. */ - } -} - -/*------------------------------------------------------------------------------------------*/ -/* Tries to set various rates and formats and fill in the device info structure. */ -static PaError Pa_sgiQueryDevice(long ALdev, /* (AL_DEFAULT_DEVICE) */ - PaDeviceID id, /* (DefaultI|ODeviceID()) */ - char* name, /* (for example "SGI AL") */ - internalPortAudioDevice* pad) /* Result written to pad. */ -{ - int format; - long min, max; /* To catch hardware characteristics. */ - ALseterrorhandler(0); /* 0 = turn off the default error handler. */ - /*--------------------------------------------------------------------------------------*/ - pad->pad_ALdevice = ALdev; /* Set the AL device number. */ - pad->pad_DeviceID = id; /* Set the PA device number. */ - if (strlen(name) > MAX_CHARS_DEVNAME) /* MAX_CHARS defined above. */ - { - ERR_RPT(("Pa_QueryDevice(): name too long (%s).\n", name)); - return paHostError; - } - strcpy(pad->pad_DeviceName, name); /* Write name-string. */ - pad->pad_Info.name = pad->pad_DeviceName; /* Set pointer,..hmmm. */ - /*--------------------------------- natively supported sample formats: -----------------*/ - pad->pad_Info.nativeSampleFormats = paInt16; /* Later also include paFloat32 | ..| etc. */ - /* Then also choose other CallConvertXX()! */ - /*--------------------------------- number of available i/o channels: ------------------*/ - if (ALgetminmax(ALdev, AL_INPUT_COUNT, &min, &max)) - return translateSGIerror(); - pad->pad_Info.maxInputChannels = max; - DBUG(("Pa_QueryDevice: maxInputChannels = %d\n", pad->pad_Info.maxInputChannels)) - if (ALgetminmax(ALdev, AL_OUTPUT_COUNT, &min, &max)) - return translateSGIerror(); - pad->pad_Info.maxOutputChannels = max; - DBUG(("Pa_QueryDevice: maxOutputChannels = %d\n", pad->pad_Info.maxOutputChannels)) - /*--------------------------------- supported samplerates: ----------------------*/ - pad->pad_Info.numSampleRates = 7; - pad->pad_Info.sampleRates = pad->pad_SampleRates; - pad->pad_SampleRates[0] = (double)AL_RATE_8000; /* long -> double. */ - pad->pad_SampleRates[1] = (double)AL_RATE_11025; - pad->pad_SampleRates[2] = (double)AL_RATE_16000; - pad->pad_SampleRates[3] = (double)AL_RATE_22050; - pad->pad_SampleRates[4] = (double)AL_RATE_32000; - pad->pad_SampleRates[5] = (double)AL_RATE_44100; - pad->pad_SampleRates[6] = (double)AL_RATE_48000; - if (ALgetminmax(ALdev, AL_INPUT_RATE, &min, &max)) /* Ask INPUT rate-max. */ - return translateSGIerror(); /* double -> long. */ - if (max != (long)(0.5 + pad->pad_SampleRates[6])) /* FP-compare not recommndd. */ - goto weird; - if (ALgetminmax(ALdev, AL_OUTPUT_RATE, &min, &max)) /* Ask OUTPUT rate-max. */ - return translateSGIerror(); - if (max != (long)(0.5 + pad->pad_SampleRates[6])) - { -weird: ERR_RPT(("Pa_sgiQueryDevice() did not confirm max samplerate (%ld)\n",max)); - return paHostError; /* Or make it a warning and just carry on... */ - } - /*-------------------------------------------------------------------------------*/ - return paNoError; -} - - -/*--------------------------------------------------------------------------------*/ -int Pa_CountDevices() /* Name of this function suggests it only counts and */ -{ /* is NOT destructive, it however resets whole PA ! */ - int numDevices = 0; /* Let 's not do that here. */ - internalPortAudioDevice* currentDevice = sDeviceList; /* COPY GLOBAL VAR. */ -#if 0 /* Remains from linux_oss v15: Pa_Initialize(), on */ - if (!currentDevice) /* its turn, calls PaHost_Init() via file pa_lib.c. */ - Pa_Initialize(); /* Isn't that a bit too 'rude'? Don't be too */ -#endif /* friendly to clients that forgot to initialize PA. */ - while (currentDevice) /* Slower but more elegant than the sNumDevices-way: */ - { - numDevices++; - currentDevice = currentDevice->pad_Next; - } - return numDevices; -} - -/*-------------------------------------------------------------------------------*/ -static internalPortAudioDevice *Pa_GetInternalDevice(PaDeviceID id) -{ - int numDevices = 0; - internalPortAudioDevice *res = (internalPortAudioDevice*)NULL; - internalPortAudioDevice *pad = sDeviceList; /* COPY GLOBAL VAR. */ - while (pad) /* pad may be NULL, that's ok, return 0. */ - { /* (Added ->pad_DeviceID field to the pad-struct, Pieter, 2001.) */ - if (pad->pad_DeviceID == id) /* This the device we were looking for? */ - res = pad; /* But keep on(!) counting so we don't */ - numDevices++; /* have to call Pa_CountDevices() later. */ - pad = pad->pad_Next; /* Advance to the next device or NULL. */ - } /* No assumptions about order of ID's in */ - if (!res) /* the list. */ - ERR_RPT(("Pa_GetInternalDevice() could not find specified ID (%d).\n",id)); - if ((id < 0) || (id >= numDevices)) - { - ERR_RPT(("Pa_GetInternalDevice() supplied with an illegal ID (%d).\n",id)); -#if 1 /* Be strict, even when found, */ - res = (internalPortAudioDevice*)NULL; /* do not accept illegal ID's. */ -#endif - } - return res; -} - -/*----------------------------------------------------------------------*/ -const PaDeviceInfo* Pa_GetDeviceInfo(PaDeviceID id) -{ - PaDeviceInfo* res = (PaDeviceInfo*)NULL; - internalPortAudioDevice* pad = Pa_GetInternalDevice(id); /* Call. */ - if (pad) - res = &pad->pad_Info; /* Not finding the specified ID is not */ - if (!res) /* the same as &pad->pad_Info == NULL. */ - ERR_RPT(("Pa_GetDeviceInfo() could not find it (ID=%d).\n", id)); - return res; /* So (maybe) a second/third ERR_RPT(). */ -} - -/*------------------------------------------------*/ -PaDeviceID Pa_GetDefaultInputDeviceID(void) -{ - return 0; /* 0 is the default device ID. */ -} -/*------------------------------------------------*/ -PaDeviceID Pa_GetDefaultOutputDeviceID(void) -{ - return 0; -} - -/*-------------------------------------------------------------------------------------------------*/ -/* Build linked a list with all the available audio devices on this SGI machine (only 1 for now). */ -PaError PaHost_Init(void) /* Called by Pa_Initialize() from pa_lib.c. */ -{ - internalPortAudioDevice* pad; - PaError r = paNoError; - int audioLibFileID; /* To test for the presence of audio. */ - - if (sDeviceList) /* Allow re-init, only warn, no error. */ - { - ERR_RPT(("Warning: PaHost_Init() did not really re-init PA.\n")); - return r; - } - /*------------- ADD THE SGI DEFAULT DEVICE TO THE LIST: ---------------------------------------*/ - audioLibFileID = open("/dev/hdsp/hdsp0master", O_RDONLY); /* Try to open Indigo style audio */ - if (audioLibFileID < 0) /* IO port. On failure, machine */ - { /* has no audio ability. */ - ERR_RPT(("PaHost_Init(): This machine has no (Indigo-style) audio abilities.\n")); - return paHostError; - } - close(audioLibFileID); /* Allocate fast mem to hold device info. */ - pad = PaHost_AllocateFastMemory(sizeof(internalPortAudioDevice)); - if (pad == NULL) - return paInsufficientMemory; - memset(pad, 0, sizeof(internalPortAudioDevice)); /* "pad->pad_Next = NULL" is more elegant. */ - r = Pa_sgiQueryDevice(AL_DEFAULT_DEVICE, /* Set AL device num (AL_DEFAULT_DEVICE). */ - Pa_GetDefaultOutputDeviceID(),/* Set PA device num (or InputDeviceID()). */ - "AL default", /* A suitable name. */ - pad); /* Write args and queried info into pad. */ - if (r != paNoError) - { - ERR_RPT(("Pa_QueryDevice for '%s' returned: %d\n", pad->pad_DeviceName, r)); - PaHost_FreeFastMemory(pad, sizeof(internalPortAudioDevice)); /* sDeviceList still NULL ! */ - } - else - sDeviceList = pad; /* First element in linked list. pad->pad_Next already NULL. */ - /*------------- QUERY AND ADD MORE POSSIBLE SGI DEVICES TO THE LINKED LIST: -------------------*/ - /*---------------------------------------------------------------------------------------------*/ - return r; -} - -/*--------------------------------------------------------------------------------------------*/ -#define MIN(a,b) ((a)<(b)?(a):(b)) /* MIN()-function is used below. */ -#define kPollSEMA 0 /* To index the pollfd-array, reads nicer than just */ -#define kPollOUT 1 /* numbers. */ -#define kPollIN 2 -void Pa_SgiAudioProcess(void *v) /* This function is sproc-ed by PaHost_StartEngine() */ -{ /* as a separate thread. (Argument must be void*). */ - short evtLoop; /* Reset by parent indirectly, or at local errors. */ - PaError result; - struct pollfd PollFD[3]; /* To catch kPollSEMA-, kPollOUT- and kPollIN-events. */ - internalPortAudioStream *past = (internalPortAudioStream*)v; /* Copy void-ptr-argument.*/ - PaHostSoundControl *pahsc; - short inputEvent, outputEvent, /* .revents members are of type short. */ - semaEvent = 0; - DBUG(("Entering sproc-thread.\n")); - if (!past) - { - sPaHostError = paInternalError; /* Or paBadStreamPtr ? */ - ERR_RPT(("argument NULL!\n")); - goto skip; - } - pahsc = (PaHostSoundControl*)past->past_DeviceData; - if (!pahsc) - { - sPaHostError = paInternalError; /* The only way is to signal error to shared area?! */ - ERR_RPT(("past_DeviceData NULL!\n")); - goto skip; /* Sproc-ed threads MAY NOT RETURN paInternalError. */ - } - /*----------------------------- open AL-ports here, after sproc(): -----------------------*/ - if (past->past_NumInputChannels > 0) /* Open input port. */ - { - pahsc->pahsc_ALportIN = ALopenport("PA sgi in", "r", pahsc->pahsc_ALconfigIN); - if (!pahsc->pahsc_ALportIN) - { - ERR_RPT(("Failed to open AL input port.\n")); - sPaHostError = paInternalError; - goto skip; - } - DBUG(("Opened %d input channel(s).\n", past->past_NumInputChannels)); - } - if (past->past_NumOutputChannels > 0) /* Open output port. */ - { - pahsc->pahsc_ALportOUT = ALopenport("PA sgi out", "w", pahsc->pahsc_ALconfigOUT); - if (!pahsc->pahsc_ALportOUT) - { - ERR_RPT(("Failed to open AL output port.\n")); - sPaHostError = paInternalError; /* Assume pahsc_ALconfigs are the */ - goto skip; /* same for IN and OUT in case */ - } /* both ports are opened (bidir). */ - DBUG(("Opened %d output channel(s).\n", past->past_NumOutputChannels)); - } - /*-----------------------------------------------------------------------*/ - past->past_IsActive = 1; /* Wasn't this already done by the calling parent?! */ - PollFD[kPollIN].fd = ALgetfd(pahsc->pahsc_ALportIN); /* ALgetfd returns -1 on failures */ - PollFD[kPollIN].events = POLLIN; /* such as ALport not there. */ - PollFD[kPollOUT].fd = ALgetfd(pahsc->pahsc_ALportOUT); - PollFD[kPollOUT].events = POLLOUT; /* .events = POLLOUT is OK. */ - schedctl(NDPRI, NDPHIMIN); /* Sets non-degrading priority for this process. */ - PollFD[kPollSEMA].fd = usopenpollsema(SendSema, 0777); /* To communicate with parent. */ - PollFD[kPollSEMA].events = POLLIN; /* .events = POLLIN is OK. */ - uspsema(SendSema); /* Blocks until ... MUST be here, this uspsema(). */ - evtLoop = ((past->past_StopNow | past->past_StopSoon) == 0); - while (evtLoop) - { - /*---------------------------- SET FILLPOINTS AND WAIT UNTIL SOMETHING HAPPENS: ----------*/ - if (pahsc->pahsc_NativeInputBuffer) /* Then pahsc_ALportIN should also be there! */ - /* For input port, fill point is number of locations in the sample queue that must be */ - /* filled in order to trigger a return from select(). (or poll()) */ - /* Notice IRIX docs mention number of samples as argument, not number of sampleframes.*/ - if (ALsetfillpoint(pahsc->pahsc_ALportIN, pahsc->pahsc_SamplesPerInputBuffer)) - { /* Same amount as transferred per time. */ - ERR_RPT(("ALsetfillpoint() for ALportIN failed.\n")); - sPaHostError = paInternalError; /* (Using exit(-1) would be a bit rude.) */ - goto skip; - } - if (pahsc->pahsc_NativeOutputBuffer) /* Then pahsc_ALportOUT should also be there! */ - /* For output port, fill point is number of locations that must be free in order to */ - /* wake up from select(). (or poll()) */ - if (ALsetfillpoint(pahsc->pahsc_ALportOUT, pahsc->pahsc_SamplesPerOutputBuffer)) - { - ERR_RPT(("ALsetfillpoint() for ALportOUT failed.\n")); - sPaHostError = paInternalError; /* (Using exit(-1) would be a bit rude.) */ - goto skip; - } /* poll() with timeout=-1 makes it block until a requested */ - poll(PollFD, 3, -1); /* event occurs or until call is interrupted. If fd-value in */ - /* array <0, events is ignored and revents is set to 0. */ - /*---------------------------- MESSAGE-EVENT FROM PARENT THREAD: -------------------------*/ - semaEvent = PollFD[kPollSEMA].revents & POLLIN; - if (semaEvent) - { - if (past->past_StopSoon) - evtLoop = 0; - if (past->past_StopNow) - goto skip; - } - /*------------------------------------- FILLED-EVENT FROM INPUT BUFFER: --------------------------*/ - inputEvent = PollFD[kPollIN].revents & POLLIN; - if (inputEvent) /* Don't need to check (pahsc->pahsc_NativeInputBuffer): */ - { /* if buffer was not there, ALport not there, no events! */ - if (ALreadsamps(pahsc->pahsc_ALportIN, (void*)pahsc->pahsc_NativeInputBuffer, - pahsc->pahsc_SamplesPerInputBuffer)) - { /* Here again: number of samples instead of number of frames. */ - ERR_RPT(("ALreadsamps() failed.\n")); - sPaHostError = paInternalError; - goto skip; - } - } - outputEvent = PollFD[kPollOUT].revents & POLLOUT; - /*------------------------------------- USER-CALLBACK-ROUTINE: -----------------------------------*/ - if (inputEvent | outputEvent) /* (Bitwise is ok.) */ - { /* To be sure we that really DID input-transfer or gonna DO output-transfer, and that it is */ - /* not just "sema"- (i.e. user)-event, or some other system-event that awakened the poll(). */ - Pa_StartUsageCalculation(past); /* Convert 16 bit native data to */ - result = Pa_CallConvertInt16(past, /* user data and call user routine. */ - pahsc->pahsc_NativeInputBuffer, - pahsc->pahsc_NativeOutputBuffer); - Pa_EndUsageCalculation(past); - if (result) - { - DBUG(("Pa_CallConvertInt16() returned %d, stopping...\n", result)); - goto skip; /* This is apparently NOT an error! */ - } /* Just letting the userCallBack stop us. */ - } - /*------------------------------------- FREE-EVENT FROM OUTPUT BUFFER: ---------------------------*/ - if (outputEvent) /* Don't need to check (pahsc->pahsc_NativeOutputBuffer) */ - { /* because if filedescriptor not there, no event for it. */ - if (ALwritesamps(pahsc->pahsc_ALportOUT, (void*)pahsc->pahsc_NativeOutputBuffer, - pahsc->pahsc_SamplesPerOutputBuffer)) - { - ERR_RPT(("ALwritesamps() failed.\n")); /* Better use SEMAS for messaging back to parent! */ - sPaHostError = paInternalError; - goto skip; - } - } - } -skip: - /*------------------------------- close AL-ports ----------------------------*/ - if (pahsc->pahsc_ALportIN) - { - if (ALcloseport(pahsc->pahsc_ALportIN)) - translateSGIerror(); /* Translates SGI AL-code to PA-code and ERR_RPTs string. */ - else /* But go on anyway... to release other stuff... */ - pahsc->pahsc_ALportIN = (ALport)0; - } - if (pahsc->pahsc_ALportOUT) - { - if (ALcloseport(pahsc->pahsc_ALportOUT)) - translateSGIerror(); - else - pahsc->pahsc_ALportOUT = (ALport)0; - } - past->past_IsActive = 0; - if (semaEvent) - { - uspsema(SendSema); /* StopEngine() was still waiting for this acknowledgement. */ - usvsema(RcvSema); /* (semaEvent initialized with 0.) */ - } - DBUG(("Leaving sproc-thread.\n")); -} - - -#define kALinternalQueuesizeFact 4L /* Internal queue 4 times as large as transferSize. */ - /* Used below, twice: for input and for output. */ -/*--------------------------------------------------------------------------------------*/ -PaError PaHost_OpenStream(internalPortAudioStream *past) -{ - PaError result = paNoError; - PaHostSoundControl *pahsc; - unsigned int minNumBuffers; - internalPortAudioDevice *padIN, *padOUT; /* For looking up native AL-numbers. */ - long pvbuf[8]; /* To get/set hardware configs. */ - long sr; - DBUG(("PaHost_OpenStream() called.\n")); /* Alloc FASTMEM and init host data. */ - if (!past) - { - ERR_RPT(("Streampointer NULL!\n")); - result = paBadStreamPtr; goto done; - } - pahsc = (PaHostSoundControl*)PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); - if (pahsc == NULL) - { - ERR_RPT(("FAST Memory allocation failed.\n")); /* Pass trough some ERR_RPT-exit- */ - result = paInsufficientMemory; goto done; /* code (nothing will be freed). */ - } - memset(pahsc, 0, sizeof(PaHostSoundControl)); - pahsc->pahsc_threadPID = -1; /* Should pahsc_threadPID be inited to */ - past->past_DeviceData = (void*)pahsc; /* -1 instead of 0 ?? */ - /*------------------------------------------ Manipulate hardware if necessary and allowed: --*/ - ALseterrorhandler(0); /* 0 = turn off the default error handler. */ - pvbuf[0] = AL_INPUT_RATE; - pvbuf[2] = AL_INPUT_COUNT; - pvbuf[4] = AL_OUTPUT_RATE; /* TO FIX: rates may be logically, not always in Hz! */ - pvbuf[6] = AL_OUTPUT_COUNT; - sr = (long)(past->past_SampleRate + 0.5); /* Common for input and output :-) */ - /*---------------------------------------------------- SET INPUT CONFIGURATION: ------------------------*/ - if (past->past_NumInputChannels > 0) /* We need to lookup the corre- */ - { /* sponding native AL-number(s). */ - /*--------------------------------------------------- Allocate native buffers: --------*/ - pahsc->pahsc_SamplesPerInputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */ - past->past_NumInputChannels; /* audio-thread. */ - pahsc->pahsc_BytesPerInputBuffer = pahsc->pahsc_SamplesPerInputBuffer * sizeof(short); - pahsc->pahsc_NativeInputBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerInputBuffer); - if (!pahsc->pahsc_NativeInputBuffer) - { - ERR_RPT(("Fast memory allocation failed (in).\n")); - result = paInsufficientMemory; - goto done; - } - padIN = Pa_GetInternalDevice(past->past_InputDeviceID); - if (!padIN) - { - ERR_RPT(("Pa_GetInternalDevice() for input failed.\n")); - result = paHostError; - goto done; - } - if (ALgetparams(padIN->pad_ALdevice, &pvbuf[0], 4)) /* Although input and output will both be on */ - goto sgiError; /* the same AL-device, the AL-library might */ - if (pvbuf[1] != sr) /* contain more than AL_DEFAULT_DEVICE in */ - { /* Rate different from current harware-rate? the future. Therefore 2 seperate queries. */ - if (pvbuf[3] > 0) /* Means, there's other clients using AL-input-ports */ - { - ERR_RPT(("Sorry, not allowed to switch input-hardware to %ld Hz because \ -another process is currently using input at %ld kHz.\n", sr, pvbuf[1])); - result = paHostError; - goto done; - } - pvbuf[1] = sr; /* Then set input-rate. */ - if (ALsetparams(padIN->pad_ALdevice, &pvbuf[0], 2)) - goto sgiError; /* WHETHER THIS SAMPLERATE WAS REALLY PRESENT IN OUR ARRAY OF RATES, */ - } /* IS NOT CHECKED, AT LEAST NOT BY ME, WITHIN THIS FILE! Does PA do? */ - pahsc->pahsc_ALconfigIN = ALnewconfig(); /* Released at PaHost_CloseStream(). */ - if (pahsc->pahsc_ALconfigIN == (ALconfig)0) - goto sgiError; - if (ALsetsampfmt(pahsc->pahsc_ALconfigIN, AL_SAMPFMT_TWOSCOMP))/* Choose paInt16 as native i/o-format. */ - goto sgiError; - if (ALsetwidth (pahsc->pahsc_ALconfigIN, AL_SAMPLE_16)) /* Only meaningful when sample format for */ - goto sgiError; /* config is set to two's complement format. */ - /************************ Future versions might (dynamically) switch to 32-bit floats? ******* - if (ALsetsampfmt(pahsc_ALconfigIN, AL_SAMPFMT_FLOAT)) (Then also call another CallConvert-func.) - goto sgiError; - if (ALsetfloatmax (pahsc_ALconfigIN, 1.0)) Only meaningful when sample format for config - goto sgiError; is set to AL_SAMPFMT_FLOAT or AL_SAMPFMT_DOUBLE. */ - /*--------- Set internal AL queuesize (in samples) -------------------------------*/ - if (ALsetqueuesize(pahsc->pahsc_ALconfigIN, (long)pahsc->pahsc_SamplesPerInputBuffer * - (long)kALinternalQueuesizeFact)) - goto sgiError; /* Or should we use past_NumUserBuffers here? */ - /* Do 4 timea, using 2 times may give glitches. */ - if (ALsetchannels (pahsc->pahsc_ALconfigIN, (long)(past->past_NumInputChannels))) - goto sgiError; /* Returns 0 on success, -1 on failure. */ - } - /*---------------------------------------------------- SET OUTPUT CONFIGURATION: ------------------------*/ - if (past->past_NumOutputChannels > 0) /* CARE: padOUT/IN may NOT be NULL if Channels <= 0! */ - { /* We use padOUT/IN later on, or at least 1 of both. */ - pahsc->pahsc_SamplesPerOutputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */ - past->past_NumOutputChannels; /* audio-thread. */ - pahsc->pahsc_BytesPerOutputBuffer = pahsc->pahsc_SamplesPerOutputBuffer * sizeof(short); - - pahsc->pahsc_NativeOutputBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerOutputBuffer); - if (!pahsc->pahsc_NativeOutputBuffer) - { - ERR_RPT(("Fast memory allocation failed (out).\n")); - result = paInsufficientMemory; - goto done; - } - padOUT = Pa_GetInternalDevice(past->past_OutputDeviceID); - if (!padOUT) - { - ERR_RPT(("Pa_GetInternalDevice() for output failed.\n")); - result = paHostError; - goto done; - } - if (ALgetparams(padOUT->pad_ALdevice,&pvbuf[4], 4)) - goto sgiError; - if (pvbuf[5] != sr) - { /* Output needed and rate different from current harware-rate. */ - if (pvbuf[7] > 0) /* Means, there's other clients using AL-output-ports */ - { - ERR_RPT(("Sorry, not allowed to switch output-hardware to %ld Hz because \ -another process is currently using output at %ld kHz.\n", sr, pvbuf[5])); - result = paHostError; - goto done; /* Will free again the inputbuffer */ - } /* that was just created above. */ - pvbuf[5] = sr; /* Then set output-rate. */ - if (ALsetparams(padOUT->pad_ALdevice, &pvbuf[4], 2)) - goto sgiError; - } - pahsc->pahsc_ALconfigOUT = ALnewconfig(); /* Released at PaHost_CloseStream(). */ - if (pahsc->pahsc_ALconfigOUT == (ALconfig)0) - goto sgiError; - if (ALsetsampfmt(pahsc->pahsc_ALconfigOUT, AL_SAMPFMT_TWOSCOMP)) /* Choose paInt16 as native i/o-format. */ - goto sgiError; - if (ALsetwidth (pahsc->pahsc_ALconfigOUT, AL_SAMPLE_16)) /* Only meaningful when sample format for */ - goto sgiError; /* config is set to two's complement format. */ - /************************************ Future versions might (dynamically) switch to 32-bit floats? *******/ - if (ALsetqueuesize(pahsc->pahsc_ALconfigOUT, (long)pahsc->pahsc_SamplesPerOutputBuffer * - (long)kALinternalQueuesizeFact)) - goto sgiError; /* Or should we use past_NumUserBuffers here?*/ - if (ALsetchannels (pahsc->pahsc_ALconfigOUT, (long)(past->past_NumOutputChannels))) - goto sgiError; - } - /*---------- ?? --------------------*/ - /* DBUG(("PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\n", pahsc->pahsc_MinFramesPerHostBuffer )); */ - minNumBuffers = Pa_GetMinNumBuffers(past->past_FramesPerUserBuffer, past->past_SampleRate); - past->past_NumUserBuffers = (minNumBuffers > past->past_NumUserBuffers) ? - minNumBuffers : past->past_NumUserBuffers; /* I don't yet use past_NumUserBuffers */ - /*----------------------------------------------- TEST DEVICE ID's: --------------------*/ - if ((past->past_OutputDeviceID != past->past_InputDeviceID) && /* Who SETS these devive-numbers? */ - (past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0)) - { - ERR_RPT(("Cannot setup bidirectional stream between different devices.\n")); - result = paHostError; - goto done; - } - goto done; /* (no errors occured) */ -sgiError: - result = translateSGIerror(); /* Translates SGI AL-code to PA-code and ERR_RPTs string. */ -done: - if (result != paNoError) - PaHost_CloseStream(past); /* Frees memory (only if really allocated!). */ - return result; -} - -/*-----------------------------------------------------*/ -PaError PaHost_StartOutput(internalPortAudioStream *past) -{ - return paNoError; /* Hmm, not implemented yet? */ -} -PaError PaHost_StartInput(internalPortAudioStream *past) -{ - return paNoError; -} - -/*------------------------------------------------------------------------------*/ -PaError PaHost_StartEngine(internalPortAudioStream *past) -{ - PaHostSoundControl *pahsc; - usptr_t *arena; - if (!past) /* Test argument. */ - { - ERR_RPT(("PaHost_StartEngine(NULL)!\n")); - return paBadStreamPtr; - } - pahsc = (PaHostSoundControl*)past->past_DeviceData; - if (!pahsc) - { - ERR_RPT(("PaHost_StartEngine(arg): arg->past_DeviceData = NULL!\n")); - return paHostError; - } - past->past_StopSoon = 0; /* Assume SGI ALport is already opened! */ - past->past_StopNow = 0; /* Why don't we check pahsc for NULL? */ - past->past_IsActive = 1; - - /* Although the pthread_create() function, as well as <pthread.h>, may be */ - /* available in IRIX, use sproc() on SGI to create audio-background-thread. */ - /* (Linux/oss uses pthread_create() instead of __clone() because: */ - /* - pthread_create also works for other UNIX systems like Solaris, */ - /* - Java HotSpot VM crashes in pthread_setcanceltype() using __clone().) */ - - usconfig(CONF_ARENATYPE, US_SHAREDONLY); /* (From SGI-AL-examples, file */ - arena = usinit(tmpnam(0)); /* motifexample.c, function */ - SendSema = usnewpollsema(arena, 0); /* InitializeAudioProcess().) */ - RcvSema = usnewsema(arena, 1); /* 1= common mutual exclusion semaphore, where 1 and only 1 process - will be permitted through a semaphore at a time. Values > 1 - imply that up to val resources may be simultaneously used, but requests - for more than val resources cause the calling process to block until a - resource comes free (by a process holding a resource performing a - usvsema(). IS THIS usnewsema() TOO PLATFORM SPECIFIC? */ - prctl(PR_SETEXITSIG, 0); /* No not (void*)9, but 0, which doesn't kill the parent! */ - /* PR_SETEXITSIG controls whether all members of a share group will be - signaled if any one of them leaves the share group (either via exit() - or exec()). If 2nd arg, interpreted as an int is 0, then normal IRIX - process termination rules apply, namely that the parent is sent a - SIGCLD upon death of child, but no indication of death of parent is - given. If the second argument is a valid signal number then if any - member of a share group leaves the share group, a signal is - sent to ALL surviving members of the share group. */ - /* SPAWN AUDIO-CHILD: */ - pahsc->pahsc_threadPID = sproc(Pa_SgiAudioProcess, /* Returns process ID of */ - PR_SALL, /* new process, or -1. */ - (void*)past); /* Pass past as optional */ /* IS THIS SAFE, will past never */ - if (pahsc->pahsc_threadPID == -1) /* third void-ptr-arg. */ /* be moved around in memory???? */ - { - ERR_RPT(("PaHost_StartEngine() failed to spawn audio-thread.\n")); - sPaHostError = oserror(); /* Pass native error-number to shared area. */ - return paHostError; /* But return the generic error-number. */ - } - return paNoError; /* Hmmm, errno may come from other threads in same group! */ -} /* ("man sproc" in IRIX6.2 to read about _SGI_MP_SOURCE.) */ - -/*------------------------------------------------------------------------------*/ -PaError PaHost_StopEngine(internalPortAudioStream *past, int abort) -{ - int hres; - long timeOut; - PaError result = paNoError; - PaHostSoundControl *pahsc; - - DBUG(("PaHost_StopEngine() called.\n")); - if (!past) - return paBadStreamPtr; - pahsc = (PaHostSoundControl*)past->past_DeviceData; - /* Prevent from doing this twice!! */ - if ((!pahsc) || /* Some tests call this CLOSE twice!! */ - (!past->past_IsActive) || - past->past_StopSoon || past->past_StopNow) - return result; /* paNoError (already stopped, no err?). */ - past->past_StopSoon = 1; /* Tell background thread to stop generating */ - if (abort) /* more and to let current data play out. If */ - past->past_StopNow = 1; /* aborting, tell backgrnd thread to stop NOW! */ - /*---- USE SEMAPHORE LOCK TO COMMUNICATE: -----*/ - usvsema(SendSema); /* Increments count associated with SendSema. */ - /* Wait for the response. */ - uspsema(RcvSema); /* Decrements count of previously allocated */ - /* semaphore specified by RcvSema. */ - while (past->past_IsActive) /* REALLY WAIT. */ - { - /* DBUG(("wait 1 ms for audio-thread to stop.\n")); */ - Pa_Sleep(1); - } - -#if 0 /* We don't need to KILL(), just COMMUNICATE and be patient... */ - if (pahsc->pahsc_threadPID != -1) /* Did we really init it to -1 somewhere? */ - { - DBUG(("PaHost_StopEngine() is about to kill(SIGKILL) audio-thread.\n")); - if (kill(pahsc->pahsc_threadPID, SIGKILL)) /* Or SIGTERM or SIGQUIT(core) */ - { /* Returns -1 in case of error. */ - result = paHostError; - sPaHostError = oserror(); /* Hmmm, other threads may also write here! */ - ERR_RPT(("PaHost_StopEngine() failed to kill audio-thread.\n")); - } - else - pahsc->pahsc_threadPID = -1; /* Notify that we've killed this thread. */ - } -#endif - past->past_IsActive = 0; /* Even when kill() failed and pahsc_threadPID still there??? */ - return result; -} - -/*---------------------------------------------------------------*/ -PaError PaHost_StopOutput(internalPortAudioStream *past, int abort) -{ - return paNoError; /* Not implemented yet? */ -} -PaError PaHost_StopInput(internalPortAudioStream *past, int abort ) -{ - return paNoError; -} - -/*******************************************************************/ -PaError PaHost_CloseStream(internalPortAudioStream *past) -{ - PaHostSoundControl *pahsc; - PaError result = paNoError; - - DBUG(("PaHost_CloseStream() called.\n")); - if (!past) - return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if (!pahsc) /* If pahsc not NULL, past_DeviceData will be freed, and set to NULL. */ - return result; /* This test prevents from freeing NULL-pointers. */ - - if (pahsc->pahsc_ALconfigIN) - { /* Release configuration structs, only if allocated. */ - ALfreeconfig(pahsc->pahsc_ALconfigIN); - pahsc->pahsc_ALconfigIN = NULL; - } - if (pahsc->pahsc_ALconfigOUT) - { - ALfreeconfig(pahsc->pahsc_ALconfigOUT); /* (Al-ports were already closed by audioProcess). */ - pahsc->pahsc_ALconfigOUT = NULL; - } - if (pahsc->pahsc_NativeInputBuffer) - { - PaHost_FreeFastMemory(pahsc->pahsc_NativeInputBuffer, pahsc->pahsc_BytesPerInputBuffer); - pahsc->pahsc_NativeInputBuffer = NULL; - } - if (pahsc->pahsc_NativeOutputBuffer) - { - PaHost_FreeFastMemory(pahsc->pahsc_NativeOutputBuffer, pahsc->pahsc_BytesPerOutputBuffer); - pahsc->pahsc_NativeOutputBuffer = NULL; - } - PaHost_FreeFastMemory(pahsc, sizeof(PaHostSoundControl)); - past->past_DeviceData = NULL; /* PaHost_OpenStream() allocated FAST MEM. */ - return result; -} - -/************************************************************************* -** Determine minimum number of buffers required for this host based -** on minimum latency. Latency can be optionally set by user by setting -** an environment variable. For example, to set latency to 200 msec, put: -** set PA_MIN_LATENCY_MSEC=200 -** in the AUTOEXEC.BAT file and reboot. -** If the environment variable is not set, then the latency will be -** determined based on the OS. Windows NT has higher latency than Win95. -*/ -#define PA_LATENCY_ENV_NAME ("PA_MIN_LATENCY_MSEC") - -int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate ) -{ - return 2; -} -/* Hmmm, the note above isn't appropriate for SGI I'm afraid... */ -/* Do we HAVE to do it this way under IRIX???.... */ -/*--------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------*/ -PaError PaHost_Term(void) /* Frees all of the linked audio-devices. */ -{ /* Called by Pa_Terminate() from pa_lib.c. */ - internalPortAudioDevice *pad = sDeviceList, - *nxt; - while (pad) - { - DBUG(("PaHost_Term: freeing %s\n", pad->pad_DeviceName)); - nxt = pad->pad_Next; - PaHost_FreeFastMemory(pad, sizeof(internalPortAudioDevice)); - pad = nxt; /* PaHost_Init allocated this FAST MEM.*/ - } - sDeviceList = (internalPortAudioDevice*)NULL; - return 0; /* Got rid of sNumDevices=0; */ -} - -/***********************************************************************/ -void Pa_Sleep( long msec ) /* Sleep requested number of milliseconds. */ -{ -#if 0 - struct timeval timeout; - timeout.tv_sec = msec / 1000; - timeout.tv_usec = (msec % 1000) * 1000; - select(0, NULL, NULL, NULL, &timeout); -#else - long usecs = msec * 1000; - usleep( usecs ); -#endif -} - -/*---------------------------------------------------------------------------------------*/ -/* Allocate memory that can be accessed in real-time. This may need to be held in physi- */ -/* cal memory so that it is not paged to virtual memory. This call MUST be balanced with */ -/* a call to PaHost_FreeFastMemory(). */ -void *PaHost_AllocateFastMemory(long numBytes) -{ - void *addr = malloc(numBytes); /* mpin() reads into memory all pages over the given */ - if (addr) /* range and locks the pages into memory. A counter */ - { /* is incremented each time the page is locked. The */ - if (mpin(addr, numBytes)) /* superuser can lock as many pages as it wishes, */ - { /* others are limited to the configurable PLOCK_MA. */ - ERR_RPT(("PaHost_AllocateFastMemory() failed to mpin() memory.\n")); -#if 1 - free(addr); /* You MAY cut out these 2 lines to be less strict, */ - addr = NULL; /* you then only get the warning but PA goes on... */ -#endif /* Only problem then may be corresponding munpin() */ - } /* call at PaHost_FreeFastMemory(), below. */ - memset(addr, 0, numBytes); /* Locks established with mlock are not inherited by */ - } /* a child process after a fork. Furthermore, IRIX- */ - return addr; /* man-pages warn against mixing both mpin and mlock */ -} /* in 1 piece of code, so stick to mpin()/munpin() ! */ - - -/*---------------------------------------------------------------------------------------*/ -/* Free memory that could be accessed in real-time. This call MUST be balanced with a */ -/* call to PaHost_AllocateFastMemory(). */ -void PaHost_FreeFastMemory(void *addr, long numBytes) -{ - if (addr) - { - if (munpin(addr, numBytes)) /* Will munpin() fail when it was never mpinned? */ - ERR_RPT(("WARNING: PaHost_FreeFastMemory() failed to munpin() memory.\n")); - free(addr); /* But go on, try to release it, just warn... */ - } -} - -/*----------------------------------------------------------*/ -PaError PaHost_StreamActive( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc; - if (past == NULL) - return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if (pahsc == NULL) - return paInternalError; - return (PaError)(past->past_IsActive != 0); -} - -/*-------------------------------------------------------------------*/ -PaTimestamp Pa_StreamTime( PortAudioStream *stream ) -{ - internalPortAudioStream *past = (internalPortAudioStream *) stream; -/* FIXME - return actual frames played, not frames generated. -** Need to query the output device somehow. -*/ - return past->past_FrameCount; -} diff --git a/pd/portaudio/pa_sgi/pthread-Makefile b/pd/portaudio/pa_sgi/pthread-Makefile deleted file mode 100644 index 527677a8..00000000 --- a/pd/portaudio/pa_sgi/pthread-Makefile +++ /dev/null @@ -1,52 +0,0 @@ -# Make PortAudio for Silicon Graphics IRIX (6.2) -# Pieter suurmond, september 22, 2001. (v15 pa_sgi sub-version #0.18) - -# pthread, math (as with linux) and SGI audio library: -# SGI-books say -lpthread should be the last on the line. -LIBS = -lm -laudio -lpthread - -CDEFINES = -I../pa_common - -# Possible CFLAGS with MIPSpro compiler are: -32, -o32, -n32, -64, -# -mips1, -mips2, -mips3, -mips4, etc. Use -g, -g2, -g3 for debugging. -# And use for example -O2 or -O3 for better optimization: -CFLAGS = -O2 -PASRC = ../pa_common/pa_lib.c pa_sgi.c -PAINC = ../pa_common/portaudio.h - -# Tests that work (SGI Indy with R5000 @ 180MHz running IRIX 6.2). -#TESTC = $(PASRC) ../pa_tests/patest_record.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_many.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_latency.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_longsine.c # OK but needs more than 4 buffers to do without glitches. -TESTC = $(PASRC) ../pa_tests/patest_saw.c # Seems OK (does it gracefully exit?). -#TESTC = $(PASRC) ../pa_tests/patest_wire.c # OK -#TESTC = $(PASRC) ../pa_tests/pa_devs.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_sine.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_sine_time.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_sine8.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_leftright.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_pink.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_clip.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_stop.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_dither.c # OK -#TESTC = $(PASRC) ../pa_tests/patest_sync.c # BEEPS and delta's, no crashes anymore. - -# Tests that do not yet work. -#TESTC = $(PASRC) ../pa_tests/paqa_devs.c # Heavy crash with core-dump after PaHost_OpenStream: opening 1 output channel(s) on AL default -#TESTC = $(PASRC) ../pa_tests/paqa_errs.c # Heavy crash with core-dump after PaHost_OpenStream: opening 2 output channel(s) on AL default -#TESTC = $(PASRC) ../pa_tests/pa_fuzz.c # THIS FUZZ CRASHED MY WHOLE IRIX SYSTEM after "ENTER"! :-( - # PROCESS IN ITSELF RUNS OK, WITH LARGER BUFFSIZES THOUGH. - # OH MAYBE IT WAS BECAUSE DEBUGGING WAS ON??? - # ANYWAY, I'M NOT GONNA RUN THAT AGAIN... WAY TOO DANGEROUS! -TESTH = $(PAINC) - -all: patest - -# "cc" for the MIPSpro compiler, may be changed to "gcc": -patest: $(TESTC) $(TESTH) Makefile - cc $(CFLAGS) $(TESTC) $(CDEFINES) $(LIBS) -o patest - -run: patest - ./patest - diff --git a/pd/portaudio/pa_sgi/pthread-pa_sgi.c b/pd/portaudio/pa_sgi/pthread-pa_sgi.c deleted file mode 100644 index e9ab273c..00000000 --- a/pd/portaudio/pa_sgi/pthread-pa_sgi.c +++ /dev/null @@ -1,908 +0,0 @@ -/* - * PortAudio Portable Real-Time Audio Library - * Latest Version at: http://www.portaudio.com - * SGI IRIX implementation by Pieter Suurmond, september 22, 2001 (#0.18). - * - * Copyright (c) 1999-2001 Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -/* -Modfication History: - 8/12/2001 - Pieter Suurmond - took the v15 pa_linux_oss.c file and started to adapt for IRIX 6.2. - 8/17/2001 - alpha release with IRIX sproc()-method, may sometimes let IRIX6.2 crash at closing audiostream. - 9/22/2001 - #0.18 pthread starts to work a bit: - BUT UNDER IRIX6.2, I DON'T GET IT TO WORK REALLY CORRECTLY, - this POSIX-attempt, - DON'T USE THIS FILE FOR RELIABLE OPERATION, IT IS HERE JUST - FOR DOCUMENTATION/ARCHIVE... OR FOR ANYONE WHO WANTS TO FIX...... -TODO: - - Test under IRIX 6.5. - - Dynamically switch to 32 bit float as native format when appropriate (let SGI do the conversion), - and maybe also the other natively supported formats? (might increase performance) - - Not sure whether CPU UTILIZATION MEASUREMENT (from OSS/linux) really works. Changed nothing yet, - seems ok, but I've not yet tested it thoroughly. (maybe utilization-code may be made _unix_common_ then?) - - The minimal number of buffers setting... I do not yet fully understand it.. I now just take *4. -REFERENCES: - - IRIX 6.2 man pages regarding SGI AL library. - - IRIS Digital MediaProgramming Guide (online books as well as man-pages come with IRIX 6.2 and - may not be publically available on the internet). -*/ - -#include <stdio.h> /* Standard libraries. */ -#include <stdlib.h> - -#include "../pa_common/portaudio.h" /* Portaudio headers. */ -#include "../pa_common/pa_host.h" -#include "../pa_common/pa_trace.h" - -/* -#include <malloc.h> -#include <memory.h> -#include <sys/prctl.h> Not needed -#include <sys/types.h> -#include <sys/schedctl.h> -#include <signal.h> -#include <sys/ioctl.h> Needed? -#include <sys/time.h> -#include <sched.h> sched_param struct and related functions - used in setting thread priorities. -#include <limits.h> Some POSIX constants such as _POSIX_THREAD_THREADS_MAX -*/ - -#include <pthread.h> /* Pthreads are supported by IRIX 6.2 after */ - /* patches 1361, 1367, and 1429 are applied. */ - -#include <fcntl.h> /* fcntl.h needed for "O_RDONLY". */ -#include <unistd.h> /* For usleep() and constants used when calling sysconf() */ - /* to query POSIX limits (see the sysconf(3) ref. page. */ - -#include <dmedia/audio.h> /* SGI-specific audio library. */ - - -/*--------------------------------------------*/ -#define PRINT(x) { printf x; fflush(stdout); } -#define ERR_RPT(x) PRINT(x) -#define DBUG(x) PRINT(x) -#define DBUGX(x) /* PRINT(x) */ - -#define MAX_CHARS_DEVNAME (16) /* Was 32 in OSS (20 for AL but "in"/"out" is concat. */ -#define MAX_SAMPLE_RATES (8) /* Known from SGI AL there are 7 (was 10 in OSS v15). */ - -typedef struct internalPortAudioDevice /* IRIX specific device info: */ -{ - PaDeviceID /* NEW: */ pad_DeviceID; /* THIS "ID" IS NEW HERE (Pieter)! */ - long pad_ALdevice; /* SGI-number! */ - double pad_SampleRates[MAX_SAMPLE_RATES]; /* for pointing to from pad_Info */ - char pad_DeviceName[MAX_CHARS_DEVNAME+1]; /* +1 for \0, one more than OSS. */ - PaDeviceInfo pad_Info; /* pad_Info (v15) contains: */ - /* int structVersion; */ - /* const char* name; */ - /* int maxInputChannels, maxOutputChannels; */ - /* int numSampleRates; Num rates, or -1 if range supprtd. */ - /* const double* sampleRates; Array of supported sample rates, */ - /* PaSampleFormat nativeSampleFormats; or {min,max} if range supported. */ - struct internalPortAudioDevice* pad_Next; /* Singly linked list, (NULL=end). */ -} internalPortAudioDevice; - -typedef struct PaHostSoundControl /* Structure to contain all SGI IRIX specific data. */ -{ - ALport pahsc_ALportIN, /* IRIX-audio-library-datatype. ALports can only be */ - pahsc_ALportOUT; /* unidirectional, so we sometimes need 2 of them. */ - pthread_t pahsc_ThreadPID; - short *pahsc_NativeInputBuffer, /* Allocated here, in this file, if necessary. */ - *pahsc_NativeOutputBuffer; - unsigned int pahsc_BytesPerInputBuffer, /* Native buffer sizes in bytes, really needed here */ - pahsc_BytesPerOutputBuffer; /* to free FAST memory, if buffs were alloctd FAST. */ - unsigned int pahsc_SamplesPerInputBuffer, /* These amounts are needed again and again in the */ - pahsc_SamplesPerOutputBuffer; /* audio-thread (don't need to be kept globally). */ - struct itimerval pahsc_EntryTime, /* For measuring CPU utilization (same as linux). */ - pahsc_LastExitTime; - long pahsc_InsideCountSum, - pahsc_TotalCountSum; -} PaHostSoundControl; - -/*----------------------------- Shared Data ------------------------------------------------------*/ -static internalPortAudioDevice* sDeviceList = NULL; /* FIXME - put Mutex around this shared data. */ -static int sPaHostError = 0; /* Maybe more than one process writing errs!? */ - -long Pa_GetHostError(void) -{ - return (long)sPaHostError; -} - -/*----------------------------- BEGIN CPU UTILIZATION MEASUREMENT -----------------*/ -/* (copied from source pa_linux_oss/pa_linux_oss.c) */ -static void Pa_StartUsageCalculation( internalPortAudioStream *past ) -{ - struct itimerval itimer; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return; -/* Query system timer for usage analysis and to prevent overuse of CPU. */ - getitimer( ITIMER_REAL, &pahsc->pahsc_EntryTime ); -} - -static long SubtractTime_AminusB( struct itimerval *timeA, struct itimerval *timeB ) -{ - long secs = timeA->it_value.tv_sec - timeB->it_value.tv_sec; - long usecs = secs * 1000000; - usecs += (timeA->it_value.tv_usec - timeB->it_value.tv_usec); - return usecs; -} - -static void Pa_EndUsageCalculation( internalPortAudioStream *past ) -{ - struct itimerval currentTime; - long insideCount; - long totalCount; /* Measure CPU utilization during this callback. */ - -#define LOWPASS_COEFFICIENT_0 (0.95) -#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0) - - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if (pahsc == NULL) - return; - if (getitimer( ITIMER_REAL, ¤tTime ) == 0 ) - { - if (past->past_IfLastExitValid) - { - insideCount = SubtractTime_AminusB( &pahsc->pahsc_EntryTime, ¤tTime ); - pahsc->pahsc_InsideCountSum += insideCount; - totalCount = SubtractTime_AminusB( &pahsc->pahsc_LastExitTime, ¤tTime ); - pahsc->pahsc_TotalCountSum += totalCount; - /* DBUG(("insideCount = %d, totalCount = %d\n", insideCount, totalCount )); */ - /* Low pass filter the result because sometimes we get called several times in a row. */ - /* That can cause the TotalCount to be very low which can cause the usage to appear */ - /* unnaturally high. So we must filter numerator and denominator separately!!! */ - if (pahsc->pahsc_InsideCountSum > 0) - { - past->past_AverageInsideCount = ((LOWPASS_COEFFICIENT_0 * past->past_AverageInsideCount) + - (LOWPASS_COEFFICIENT_1 * pahsc->pahsc_InsideCountSum)); - past->past_AverageTotalCount = ((LOWPASS_COEFFICIENT_0 * past->past_AverageTotalCount) + - (LOWPASS_COEFFICIENT_1 * pahsc->pahsc_TotalCountSum)); - past->past_Usage = past->past_AverageInsideCount / past->past_AverageTotalCount; - pahsc->pahsc_InsideCountSum = 0; - pahsc->pahsc_TotalCountSum = 0; - } - } - past->past_IfLastExitValid = 1; - } - pahsc->pahsc_LastExitTime.it_value.tv_sec = 100; - pahsc->pahsc_LastExitTime.it_value.tv_usec = 0; - setitimer( ITIMER_REAL, &pahsc->pahsc_LastExitTime, NULL ); - past->past_IfLastExitValid = 1; -} /*----------- END OF CPU UTILIZATION CODE (from pa_linux_oss/pa_linux_oss.c v15)--------------------*/ - - -/*--------------------------------------------------------------------------------------*/ -PaError translateSGIerror(void) /* Calls oserror(), may be used after an SGI AL-library */ -{ /* call to report via ERR_RPT(), yields a PaError-num. */ - const char* a = "SGI AL "; /* (Not absolutely sure errno came from THIS thread! */ - switch(oserror()) /* Read IRIX man-pages about the _SGI_MP_SOURCE macro.) */ - { - case AL_BAD_OUT_OF_MEM: - ERR_RPT(("%sout of memory.\n", a)); - return paInsufficientMemory; /* Known PaError. */ - case AL_BAD_CONFIG: - ERR_RPT(("%sconfiguration invalid or NULL.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_CHANNELS: - ERR_RPT(("%schannels not 1,2 or 4.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_NO_PORTS: - ERR_RPT(("%sout of audio ports.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_DEVICE: - ERR_RPT(("%swrong device number.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_DEVICE_ACCESS: - ERR_RPT(("%swrong device access.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_DIRECTION: - ERR_RPT(("%sinvalid direction.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_SAMPFMT: - ERR_RPT(("%sdoesn't accept sampleformat.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_FLOATMAX: - ERR_RPT(("%smax float value is zero.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_WIDTH: - ERR_RPT(("%sunsupported samplewidth.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_QSIZE: - ERR_RPT(("%sinvalid queue size.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_PVBUFFER: - ERR_RPT(("%sPVbuffer null.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_BUFFERLENGTH_NEG: - ERR_RPT(("%snegative bufferlength.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_BUFFERLENGTH_ODD: - ERR_RPT(("%sodd bufferlength.\n", a)); - return paHostError; /* Generic PaError. */ - case AL_BAD_PARAM: - ERR_RPT(("%sparameter not valid for device.\n", a)); - return paHostError; /* Generic PaError. */ - default: - ERR_RPT(("%sunknown error.\n", a)); - return paHostError; /* Generic PaError. */ - } -} - -/*------------------------------------------------------------------------------------------*/ -/* Tries to set various rates and formats and fill in the device info structure. */ -static PaError Pa_sgiQueryDevice(long ALdev, /* (AL_DEFAULT_DEVICE) */ - PaDeviceID id, /* (DefaultI|ODeviceID()) */ - char* name, /* (for example "SGI AL") */ - internalPortAudioDevice* pad) /* Result written to pad. */ -{ - int format; - long min, max; /* To catch hardware characteristics. */ - ALseterrorhandler(0); /* 0 = turn off the default error handler. */ - /*--------------------------------------------------------------------------------------*/ - pad->pad_ALdevice = ALdev; /* Set the AL device number. */ - pad->pad_DeviceID = id; /* Set the PA device number. */ - if (strlen(name) > MAX_CHARS_DEVNAME) /* MAX_CHARS defined above. */ - { - ERR_RPT(("Pa_QueryDevice(): name too long (%s).\n", name)); - return paHostError; - } - strcpy(pad->pad_DeviceName, name); /* Write name-string. */ - pad->pad_Info.name = pad->pad_DeviceName; /* Set pointer,..hmmm. */ - /*--------------------------------- natively supported sample formats: -----------------*/ - pad->pad_Info.nativeSampleFormats = paInt16; /* Later also include paFloat32 | ..| etc. */ - /* Then also choose other CallConvertXX()! */ - /*--------------------------------- number of available i/o channels: ------------------*/ - if (ALgetminmax(ALdev, AL_INPUT_COUNT, &min, &max)) - return translateSGIerror(); - pad->pad_Info.maxInputChannels = max; - DBUG(("Pa_QueryDevice: maxInputChannels = %d\n", pad->pad_Info.maxInputChannels)) - if (ALgetminmax(ALdev, AL_OUTPUT_COUNT, &min, &max)) - return translateSGIerror(); - pad->pad_Info.maxOutputChannels = max; - DBUG(("Pa_QueryDevice: maxOutputChannels = %d\n", pad->pad_Info.maxOutputChannels)) - /*--------------------------------- supported samplerates: ----------------------*/ - pad->pad_Info.numSampleRates = 7; - pad->pad_Info.sampleRates = pad->pad_SampleRates; - pad->pad_SampleRates[0] = (double)AL_RATE_8000; /* long -> double. */ - pad->pad_SampleRates[1] = (double)AL_RATE_11025; - pad->pad_SampleRates[2] = (double)AL_RATE_16000; - pad->pad_SampleRates[3] = (double)AL_RATE_22050; - pad->pad_SampleRates[4] = (double)AL_RATE_32000; - pad->pad_SampleRates[5] = (double)AL_RATE_44100; - pad->pad_SampleRates[6] = (double)AL_RATE_48000; - if (ALgetminmax(ALdev, AL_INPUT_RATE, &min, &max)) /* Ask INPUT rate-max. */ - return translateSGIerror(); /* double -> long. */ - if (max != (long)(0.5 + pad->pad_SampleRates[6])) /* FP-compare not recommndd. */ - goto weird; - if (ALgetminmax(ALdev, AL_OUTPUT_RATE, &min, &max)) /* Ask OUTPUT rate-max. */ - return translateSGIerror(); - if (max != (long)(0.5 + pad->pad_SampleRates[6])) - { -weird: ERR_RPT(("Pa_sgiQueryDevice() did not confirm max samplerate (%ld)\n",max)); - return paHostError; /* Or make it a warning and just carry on... */ - } - /*-------------------------------------------------------------------------------*/ - return paNoError; -} - - -/*--------------------------------------------------------------------------------*/ -int Pa_CountDevices() /* Name of this function suggests it only counts and */ -{ /* is NOT destructive, it however resets whole PA ! */ - int numDevices = 0; /* Let 's not do that here. */ - internalPortAudioDevice* currentDevice = sDeviceList; /* COPY GLOBAL VAR. */ -#if 0 /* Remains from linux_oss v15: Pa_Initialize(), on */ - if (!currentDevice) /* its turn, calls PaHost_Init() via file pa_lib.c. */ - Pa_Initialize(); /* Isn't that a bit too 'rude'? Don't be too */ -#endif /* friendly to clients that forgot to initialize PA. */ - while (currentDevice) /* Slower but more elegant than the sNumDevices-way: */ - { - numDevices++; - currentDevice = currentDevice->pad_Next; - } - return numDevices; -} - -/*-------------------------------------------------------------------------------*/ -static internalPortAudioDevice *Pa_GetInternalDevice(PaDeviceID id) -{ - int numDevices = 0; - internalPortAudioDevice *res = (internalPortAudioDevice*)NULL; - internalPortAudioDevice *pad = sDeviceList; /* COPY GLOBAL VAR. */ - while (pad) /* pad may be NULL, that's ok, return 0. */ - { /* (Added ->pad_DeviceID field to the pad-struct, Pieter, 2001.) */ - if (pad->pad_DeviceID == id) /* This the device we were looking for? */ - res = pad; /* But keep on(!) counting so we don't */ - numDevices++; /* have to call Pa_CountDevices() later. */ - pad = pad->pad_Next; /* Advance to the next device or NULL. */ - } /* No assumptions about order of ID's in */ - if (!res) /* the list. */ - ERR_RPT(("Pa_GetInternalDevice() could not find specified ID (%d).\n",id)); - if ((id < 0) || (id >= numDevices)) - { - ERR_RPT(("Pa_GetInternalDevice() supplied with an illegal ID (%d).\n",id)); -#if 1 /* Be strict, even when found, */ - res = (internalPortAudioDevice*)NULL; /* do not accept illegal ID's. */ -#endif - } - return res; -} - -/*----------------------------------------------------------------------*/ -const PaDeviceInfo* Pa_GetDeviceInfo(PaDeviceID id) -{ - PaDeviceInfo* res = (PaDeviceInfo*)NULL; - internalPortAudioDevice* pad = Pa_GetInternalDevice(id); /* Call. */ - if (pad) - res = &pad->pad_Info; /* Not finding the specified ID is not */ - if (!res) /* the same as &pad->pad_Info == NULL. */ - ERR_RPT(("Pa_GetDeviceInfo() could not find it (ID=%d).\n", id)); - return res; /* So (maybe) a second/third ERR_RPT(). */ -} - -/*------------------------------------------------*/ -PaDeviceID Pa_GetDefaultInputDeviceID(void) -{ - return 0; /* 0 is the default device ID. */ -} -/*------------------------------------------------*/ -PaDeviceID Pa_GetDefaultOutputDeviceID(void) -{ - return 0; -} - -/*-------------------------------------------------------------------------------------------------*/ -/* Build linked a list with all the available audio devices on this SGI machine (only 1 for now). */ -PaError PaHost_Init(void) /* Called by Pa_Initialize() from pa_lib.c. */ -{ - internalPortAudioDevice* pad; - PaError r = paNoError; - int audioLibFileID; /* To test for the presence of audio. */ - - if (sDeviceList) /* Allow re-init, only warn, no error. */ - { - ERR_RPT(("Warning: PaHost_Init() did not really re-init PA.\n")); - return r; - } - /*------------- ADD THE SGI DEFAULT DEVICE TO THE LIST: ---------------------------------------*/ - audioLibFileID = open("/dev/hdsp/hdsp0master", O_RDONLY); /* Try to open Indigo style audio */ - if (audioLibFileID < 0) /* IO port. On failure, machine */ - { /* has no audio ability. */ - ERR_RPT(("PaHost_Init(): This machine has no (Indigo-style) audio abilities.\n")); - return paHostError; - } - close(audioLibFileID); /* Allocate fast mem to hold device info. */ - pad = PaHost_AllocateFastMemory(sizeof(internalPortAudioDevice)); - if (pad == NULL) - return paInsufficientMemory; - memset(pad, 0, sizeof(internalPortAudioDevice)); /* "pad->pad_Next = NULL" is more elegant. */ - r = Pa_sgiQueryDevice(AL_DEFAULT_DEVICE, /* Set AL device num (AL_DEFAULT_DEVICE). */ - Pa_GetDefaultOutputDeviceID(),/* Set PA device num (or InputDeviceID()). */ - "AL default", /* A suitable name. */ - pad); /* Write args and queried info into pad. */ - if (r != paNoError) - { - ERR_RPT(("Pa_QueryDevice for '%s' returned: %d\n", pad->pad_DeviceName, r)); - PaHost_FreeFastMemory(pad, sizeof(internalPortAudioDevice)); /* sDeviceList still NULL ! */ - } - else - sDeviceList = pad; /* First element in linked list. pad->pad_Next already NULL. */ - /*------------- QUERY AND ADD MORE POSSIBLE SGI DEVICES TO THE LINKED LIST: -------------------*/ - /*---------------------------------------------------------------------------------------------*/ - return r; -} - -/*---------------------------------------------------------------------------------------------------*/ -static PaError Pa_SgiAudioProcess(internalPortAudioStream *past) /* Spawned by PaHost_StartEngine(). */ -{ - PaError result = paNoError; - PaHostSoundControl *pahsc; - - if (!past) - return paBadStreamPtr; - pahsc = (PaHostSoundControl*)past->past_DeviceData; - if (!pahsc) - return paInternalError; - past->past_IsActive = 1; /* Wasn't this already done by the calling parent?! */ - DBUG(("entering thread.\n")); - - while (!past->past_StopSoon) /* OR-ing StopSoon and StopNow here gives problems! */ - { - /*---------------------------------------- INPUT: ------------------------------------*/ - if (pahsc->pahsc_NativeInputBuffer) /* Then pahsc_ALportIN should also be there! */ - { - while (ALgetfilled(pahsc->pahsc_ALportIN) < pahsc->pahsc_SamplesPerInputBuffer) - { - /* Trying sginap(1); and usleep(); here... things get blocked under IRIX6.2. */ - if (past->past_StopNow) /* Don't let ALreadsamps() block */ - goto done; - } - if (ALreadsamps(pahsc->pahsc_ALportIN, (void*)pahsc->pahsc_NativeInputBuffer, - pahsc->pahsc_SamplesPerInputBuffer)) /* Number of samples instead */ - { /* of number of frames. */ - ERR_RPT(("ALreadsamps() failed.\n")); - result = paInternalError; - goto done; - } - } - /*---------------------------------------------------- USER CALLBACK ROUTINE: ----------*/ - /* DBUG(("Calling Pa_CallConvertInt16()...\n")); */ - Pa_StartUsageCalculation(past); /* Convert 16 bit native data to */ - result = Pa_CallConvertInt16(past, /* user data and call user routine. */ - pahsc->pahsc_NativeInputBuffer, pahsc->pahsc_NativeOutputBuffer); - Pa_EndUsageCalculation(past); - if (result) - { - DBUG(("Pa_CallConvertInt16() returned %d, stopping...\n", result)); - goto done; /* This is apparently NOT an error! */ - } /* Just letting the userCallBack stop us. */ - /*---------------------------------------- OUTPUT: ------------------------------------*/ - if (pahsc->pahsc_NativeOutputBuffer) /* Then pahsc_ALportOUT should also be there! */ - { - while (ALgetfillable(pahsc->pahsc_ALportOUT) < pahsc->pahsc_SamplesPerOutputBuffer) - { - /* Trying sginap(1); and usleep(); here... things get blocked under IRIX6.2. */ - if (past->past_StopNow) /* Don't let ALwritesamps() block */ - goto done; - } - if (ALwritesamps(pahsc->pahsc_ALportOUT, (void*)pahsc->pahsc_NativeOutputBuffer, - pahsc->pahsc_SamplesPerOutputBuffer)) - { - ERR_RPT(("ALwritesamps() failed.\n")); - result = paInternalError; - goto done; - } - } - /*-------------------------------------------------------------------------------------*/ - } -done: - /* pahsc->pahsc_ThreadPID = -1; Hu? doesn't help!! (added by Pieter) */ - past->past_IsActive = 0; - DBUG(("leaving thread.\n")); - return result; -} - - -/*--------------------------------------------------------------------------------------*/ -PaError PaHost_OpenStream(internalPortAudioStream *past) -{ - PaError result = paNoError; - PaHostSoundControl *pahsc; - unsigned int minNumBuffers; - internalPortAudioDevice *padIN, *padOUT; /* For looking up native AL-numbers. */ - ALconfig sgiALconfig = NULL; /* IRIX-datatype. */ - long pvbuf[8]; /* To get/set hardware configs. */ - long sr, ALqsize; - DBUG(("PaHost_OpenStream() called.\n")); /* Alloc FASTMEM and init host data. */ - if (!past) - { - ERR_RPT(("Streampointer NULL!\n")); - result = paBadStreamPtr; goto done; - } - pahsc = (PaHostSoundControl*)PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); - if (pahsc == NULL) - { - ERR_RPT(("FAST Memory allocation failed.\n")); /* Pass trough some ERR_RPT-exit- */ - result = paInsufficientMemory; goto done; /* code (nothing will be freed). */ - } - memset(pahsc, 0, sizeof(PaHostSoundControl)); -/* pahsc->pahsc_threadPID = -1; Should pahsc_threadPID be inited to */ - past->past_DeviceData = (void*)pahsc; /* -1 instead of 0 ?? */ - /*--------------------------------------------------- Allocate native buffers: --------*/ - pahsc->pahsc_SamplesPerInputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */ - past->past_NumInputChannels; /* audio-thread. */ - pahsc->pahsc_BytesPerInputBuffer = pahsc->pahsc_SamplesPerInputBuffer * sizeof(short); - if (past->past_NumInputChannels > 0) /* Assumes short = 16 bits! */ - { - pahsc->pahsc_NativeInputBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerInputBuffer); - if( pahsc->pahsc_NativeInputBuffer == NULL ) - { - ERR_RPT(("Fast memory allocation for input-buffer failed.\n")); - result = paInsufficientMemory; goto done; - } - } - pahsc->pahsc_SamplesPerOutputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */ - past->past_NumOutputChannels; /* audio-thread. */ - pahsc->pahsc_BytesPerOutputBuffer = pahsc->pahsc_SamplesPerOutputBuffer * sizeof(short); - if (past->past_NumOutputChannels > 0) /* Assumes short = 16 bits! */ - { - pahsc->pahsc_NativeOutputBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerOutputBuffer); - if (pahsc->pahsc_NativeOutputBuffer == NULL) - { - ERR_RPT(("Fast memory allocation for output-buffer failed.\n")); - result = paInsufficientMemory; goto done; - } - } - /*------------------------------------------ Manipulate hardware if necessary and allowed: --*/ - ALseterrorhandler(0); /* 0 = turn off the default error handler. */ - pvbuf[0] = AL_INPUT_RATE; - pvbuf[2] = AL_INPUT_COUNT; - pvbuf[4] = AL_OUTPUT_RATE; /* TO FIX: rates may be logically, not always in Hz! */ - pvbuf[6] = AL_OUTPUT_COUNT; - sr = (long)(past->past_SampleRate + 0.5); /* Common for input and output :-) */ - if (past->past_NumInputChannels > 0) /* We need to lookup the corre- */ - { /* sponding native AL-number(s). */ - padIN = Pa_GetInternalDevice(past->past_InputDeviceID); - if (!padIN) - { - ERR_RPT(("Pa_GetInternalDevice() for input failed.\n")); - result = paHostError; goto done; - } - if (ALgetparams(padIN->pad_ALdevice, &pvbuf[0], 4)) /* Although input and output will both be on */ - goto sgiError; /* the same AL-device, the AL-library might */ - if (pvbuf[1] != sr) /* contain more than AL_DEFAULT_DEVICE in */ - { /* Rate different from current harware-rate? the future. Therefore 2 seperate queries. */ - if (pvbuf[3] > 0) /* Means, there's other clients using AL-input-ports */ - { - ERR_RPT(("Sorry, not allowed to switch input-hardware to %ld Hz because \ -another process is currently using input at %ld kHz.\n", sr, pvbuf[1])); - result = paHostError; goto done; - } - pvbuf[1] = sr; /* Then set input-rate. */ - if (ALsetparams(padIN->pad_ALdevice, &pvbuf[0], 2)) - goto sgiError; /* WHETHER THIS SAMPLERATE WAS REALLY PRESENT IN OUR ARRAY OF RATES, */ - } /* IS NOT CHECKED, AT LEAST NOT BY ME, WITHIN THIS FILE! Does PA do? */ - } - if (past->past_NumOutputChannels > 0) /* CARE: padOUT/IN may NOT be NULL if Channels <= 0! */ - { /* We use padOUT/IN later on, or at least 1 of both. */ - padOUT = Pa_GetInternalDevice(past->past_OutputDeviceID); - if (!padOUT) - { - ERR_RPT(("Pa_GetInternalDevice() for output failed.\n")); - result = paHostError; goto done; - } - if (ALgetparams(padOUT->pad_ALdevice,&pvbuf[4], 4)) - goto sgiError; - if ((past->past_NumOutputChannels > 0) && (pvbuf[5] != sr)) - { /* Output needed and rate different from current harware-rate. */ - if (pvbuf[7] > 0) /* Means, there's other clients using AL-output-ports */ - { - ERR_RPT(("Sorry, not allowed to switch output-hardware to %ld Hz because \ -another process is currently using output at %ld kHz.\n", sr, pvbuf[5])); - result = paHostError; goto done; /* Will free again the inputbuffer */ - } /* that was just created above. */ - pvbuf[5] = sr; /* Then set output-rate. */ - if (ALsetparams(padOUT->pad_ALdevice, &pvbuf[4], 2)) - goto sgiError; - } - } - /*------------------------------------------ Construct an audio-port-configuration ----------*/ - sgiALconfig = ALnewconfig(); /* Change the SGI-AL-default-settings. */ - if (sgiALconfig == (ALconfig)0) /* sgiALconfig is released here after use! */ - goto sgiError; /* See that sgiALconfig is NOT released! */ - if (ALsetsampfmt(sgiALconfig, AL_SAMPFMT_TWOSCOMP)) /* Choose paInt16 as native i/o-format. */ - goto sgiError; - if (ALsetwidth (sgiALconfig, AL_SAMPLE_16)) /* Only meaningful when sample format for */ - goto sgiError; /* config is set to two's complement format. */ - /************************ Future versions might (dynamically) switch to 32-bit floats? ******* - if (ALsetsampfmt(sgiALconfig, AL_SAMPFMT_FLOAT)) (Then also call another CallConvert-func.) - goto sgiError; - if (ALsetfloatmax (sgiALconfig, 1.0)) Only meaningful when sample format for config - goto sgiError; is set to AL_SAMPFMT_FLOAT or AL_SAMPFMT_DOUBLE. */ - /*---------- ?? --------------------*/ - /* DBUG(("PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\n", pahsc->pahsc_MinFramesPerHostBuffer )); */ - minNumBuffers = Pa_GetMinNumBuffers(past->past_FramesPerUserBuffer, past->past_SampleRate); - past->past_NumUserBuffers = (minNumBuffers > past->past_NumUserBuffers) ? - minNumBuffers : past->past_NumUserBuffers; - /*------------------------------------------------ Set internal AL queuesize (in samples) ----*/ - if (pahsc->pahsc_SamplesPerInputBuffer >= pahsc->pahsc_SamplesPerOutputBuffer) - ALqsize = (long)pahsc->pahsc_SamplesPerInputBuffer; - else /* Take the largest of the two amounts. */ - ALqsize = (long)pahsc->pahsc_SamplesPerOutputBuffer; - ALqsize *= 4; /* 4 times as large as amount per transfer! */ - if (ALsetqueuesize(sgiALconfig, ALqsize)) /* Or should we use past_NumUserBuffers here? */ - goto sgiError; /* Using 2 times may give glitches... */ - /* Have to work on ALsetqueuesize() above. */ - - /* Do ALsetchannels() later, apart per input and/or output. */ - /*----------------------------------------------- OPEN 1 OR 2 AL-DEVICES: --------------------*/ - if (past->past_OutputDeviceID == past->past_InputDeviceID) /* Who SETS these devive-numbers? */ - { - if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0)) - { - DBUG(("PaHost_OpenStream: opening both input and output channels.\n")); - /*------------------------- open output port: ----------------------------------*/ - if (ALsetchannels (sgiALconfig, (long)(past->past_NumOutputChannels))) - goto sgiError; /* Returns 0 on success, -1 on failure. */ - pahsc->pahsc_ALportOUT = ALopenport("PA sgi out", "w", sgiALconfig); - if (pahsc->pahsc_ALportOUT == (ALport)0) - goto sgiError; - /*------------------------- open input port: -----------------------------------*/ - if (ALsetchannels (sgiALconfig, (long)(past->past_NumInputChannels))) - goto sgiError; /* Returns 0 on success, -1 on failure. */ - pahsc->pahsc_ALportIN = ALopenport("PA sgi in", "r", sgiALconfig); - if (pahsc->pahsc_ALportIN == (ALport)0) - goto sgiError; /* For some reason the "patest_wire.c"-test crashes! */ - } /* Probably due to too small buffersizes?.... */ - else - { - ERR_RPT(("Cannot setup bidirectional stream between different devices.\n")); - result = paHostError; - goto done; - } - } - else /* (OutputDeviceID != InputDeviceID) */ - { - if (past->past_NumOutputChannels > 0) /* WRITE-ONLY: */ - { - /*------------------------- open output port: ----------------------------------*/ - DBUG(("PaHost_OpenStream: opening %d output channel(s) on %s.\n", - past->past_NumOutputChannels, padOUT->pad_DeviceName)); - if (ALsetchannels (sgiALconfig, (long)(past->past_NumOutputChannels))) - goto sgiError; /* Returns 0 on success, -1 on failure. */ - pahsc->pahsc_ALportOUT = ALopenport("PA sgi out", "w", sgiALconfig); - if (pahsc->pahsc_ALportOUT == (ALport)0) - goto sgiError; - } - if (past->past_NumInputChannels > 0) /* READ-ONLY: */ - { - /*------------------------- open input port: -----------------------------------*/ - DBUG(("PaHost_OpenStream: opening %d input channel(s) on %s.\n", - past->past_NumInputChannels, padIN->pad_DeviceName)); - if (ALsetchannels (sgiALconfig, (long)(past->past_NumInputChannels))) - goto sgiError; /* Returns 0 on success, -1 on failure. */ - pahsc->pahsc_ALportIN = ALopenport("PA sgi in", "r", sgiALconfig); - if (pahsc->pahsc_ALportIN == (ALport)0) - goto sgiError; - } - } - DBUG(("PaHost_OpenStream() succeeded.\n")); - goto done; /* (no errors occured) */ -sgiError: - result = translateSGIerror(); /* Translates SGI AL-code to PA-code and ERR_RPTs string. */ -done: - if (sgiALconfig) - ALfreeconfig(sgiALconfig); /* We don't need that struct anymore. */ - if (result != paNoError) - PaHost_CloseStream(past); /* Frees memory (only if really allocated!). */ - return result; -} - -/*-----------------------------------------------------*/ -PaError PaHost_StartOutput(internalPortAudioStream *past) -{ - return paNoError; /* Hmm, not implemented yet? */ -} -PaError PaHost_StartInput(internalPortAudioStream *past) -{ - return paNoError; -} - -/*------------------------------------------------------------------------------*/ -PaError PaHost_StartEngine(internalPortAudioStream *past) -{ - PaHostSoundControl *pahsc; - int hres; - PaError result = paNoError; - - if (!past) /* Test argument. */ - { - ERR_RPT(("PaHost_StartEngine(NULL)!\n")); - return paBadStreamPtr; - } - pahsc = (PaHostSoundControl*)past->past_DeviceData; - if (!pahsc) - { - ERR_RPT(("PaHost_StartEngine(arg): arg->past_DeviceData == NULL!\n")); - return paHostError; - } - past->past_StopSoon = 0; /* Assume SGI ALport is already opened! */ - past->past_StopNow = 0; - past->past_IsActive = 1; - DBUG(("PaHost_StartEngine() called.\n")); - /* Use pthread_create() instead of __clone() because: */ - /* - pthread_create also works for other UNIX systems like Solaris, */ - /* - Java HotSpot VM crashes in pthread_setcanceltype() when using __clone(). */ - hres = pthread_create(&(pahsc->pahsc_ThreadPID), /* SPAWN AUDIO-CHILD. */ - NULL, /* pthread_attr_t * attr */ - (void*)Pa_SgiAudioProcess, - past); - if (hres) - { - result = paHostError; - sPaHostError = hres; - ERR_RPT(("PaHost_StartEngine() failed to spawn audio-thread.\n")); - } - return result; -} - -/*------------------------------------------------------------------------------*/ -PaError PaHost_StopEngine(internalPortAudioStream *past, int abort) -{ - int hres; - PaError result = paNoError; - PaHostSoundControl *pahsc; - - DBUG(("PaHost_StopEngine() called.\n")); - if (!past) - return paBadStreamPtr; - pahsc = (PaHostSoundControl*)past->past_DeviceData; - if (pahsc == NULL) - return result; /* paNoError (already stopped, no err?). */ - past->past_StopSoon = 1; /* Tell background thread to stop generating */ - if (abort) /* more and to let current data play out. If */ - past->past_StopNow = 1; /* aborting, tell backgrnd thread to stop NOW! */ - if (pahsc->pahsc_ThreadPID != -1) /* Join thread to recover memory resources. */ - { - DBUG(("pthread_join() called.\n")); - hres = pthread_join(pahsc->pahsc_ThreadPID, NULL); - if (hres) - { - result = paHostError; - sPaHostError = hres; - ERR_RPT(("PaHost_StopEngine() failed pthread_join().\n")); - } - pahsc->pahsc_ThreadPID = -1; - } - past->past_IsActive = 0; - return result; -} - -/*---------------------------------------------------------------*/ -PaError PaHost_StopOutput(internalPortAudioStream *past, int abort) -{ - return paNoError; /* Not implemented yet? */ -} -PaError PaHost_StopInput(internalPortAudioStream *past, int abort ) -{ - return paNoError; -} - -/*******************************************************************/ -PaError PaHost_CloseStream(internalPortAudioStream *past) -{ - PaHostSoundControl *pahsc; - PaError result = paNoError; - - DBUG(("PaHost_CloseStream() called.\n")); - if (past == NULL) - return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if (pahsc == NULL) /* If pahsc not NULL, past_DeviceData will be freed, and set to NULL. */ - return result; /* This test prevents from freeing NULL-pointers. */ - - if (pahsc->pahsc_ALportIN) - { - if (ALcloseport(pahsc->pahsc_ALportIN)) - result = translateSGIerror(); /* Translates SGI AL-code to PA-code and ERR_RPTs string. */ - else /* But go on anyway... to release other stuff... */ - pahsc->pahsc_ALportIN = (ALport)0; - } - if (pahsc->pahsc_ALportOUT) - { - if (ALcloseport(pahsc->pahsc_ALportOUT)) - result = translateSGIerror(); - else - pahsc->pahsc_ALportOUT = (ALport)0; - } - if (pahsc->pahsc_NativeInputBuffer) - { - PaHost_FreeFastMemory(pahsc->pahsc_NativeInputBuffer, pahsc->pahsc_BytesPerInputBuffer); - pahsc->pahsc_NativeInputBuffer = NULL; - } - if (pahsc->pahsc_NativeOutputBuffer) - { - PaHost_FreeFastMemory(pahsc->pahsc_NativeOutputBuffer, pahsc->pahsc_BytesPerOutputBuffer); - pahsc->pahsc_NativeOutputBuffer = NULL; - } - PaHost_FreeFastMemory(pahsc, sizeof(PaHostSoundControl)); - past->past_DeviceData = NULL; /* PaHost_OpenStream() allocated FAST. */ - return result; -} - -/************************************************************************* -** Determine minimum number of buffers required for this host based -** on minimum latency. Latency can be optionally set by user by setting -** an environment variable. For example, to set latency to 200 msec, put: -** set PA_MIN_LATENCY_MSEC=200 -** in the AUTOEXEC.BAT file and reboot. -** If the environment variable is not set, then the latency will be -** determined based on the OS. Windows NT has higher latency than Win95. -*/ -#define PA_LATENCY_ENV_NAME ("PA_MIN_LATENCY_MSEC") - -int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate ) -{ - return 2; -} -/* Hmmm, the note above isn't appropriate for SGI I'm afraid... */ -/* Do we HAVE to do it this way under IRIX???.... */ -/*--------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------*/ -PaError PaHost_Term(void) /* Frees all of the linked audio-devices. */ -{ /* Called by Pa_Terminate() from pa_lib.c. */ - internalPortAudioDevice *pad = sDeviceList, - *nxt; - while (pad) - { - DBUG(("PaHost_Term: freeing %s\n", pad->pad_DeviceName)); - nxt = pad->pad_Next; - PaHost_FreeFastMemory(pad, sizeof(internalPortAudioDevice)); - pad = nxt; /* PaHost_Init allocated this FAST MEM.*/ - } - sDeviceList = (internalPortAudioDevice*)NULL; - return 0; /* Got rid of sNumDevices=0; */ -} - -/***********************************************************************/ -void Pa_Sleep( long msec ) /* Sleep requested number of milliseconds. */ -{ -#if 0 - struct timeval timeout; - timeout.tv_sec = msec / 1000; - timeout.tv_usec = (msec % 1000) * 1000; - select(0, NULL, NULL, NULL, &timeout); -#else - long usecs = msec * 1000; - usleep( usecs ); -#endif -} - -/*---------------------------------------------------------------------------------------*/ -/* Allocate memory that can be accessed in real-time. This may need to be held in physi- */ -/* cal memory so that it is not paged to virtual memory. This call MUST be balanced with */ -/* a call to PaHost_FreeFastMemory(). */ -void *PaHost_AllocateFastMemory(long numBytes) -{ - void *addr = malloc(numBytes); - if (addr) - memset(addr, 0, numBytes); - return addr; -} - -/*---------------------------------------------------------------------------------------*/ -/* Free memory that could be accessed in real-time. This call MUST be balanced with a */ -/* call to PaHost_AllocateFastMemory(). */ -void PaHost_FreeFastMemory(void *addr, long numBytes) -{ - if (addr) - free(addr); -} - -/*----------------------------------------------------------*/ -PaError PaHost_StreamActive (internalPortAudioStream *past) -{ - PaHostSoundControl *pahsc; - if (past == NULL) - return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if (pahsc == NULL) - return paInternalError; - return (PaError)(past->past_IsActive != 0); -} - -/*-------------------------------------------------------------------*/ -PaTimestamp Pa_StreamTime( PortAudioStream *stream ) -{ - internalPortAudioStream *past = (internalPortAudioStream *) stream; -/* FIXME - return actual frames played, not frames generated. -** Need to query the output device somehow. -*/ - return past->past_FrameCount; -} diff --git a/pd/portaudio/pa_tests/debug_convert.c b/pd/portaudio/pa_tests/debug_convert.c deleted file mode 100644 index 8e9dc6d1..00000000 --- a/pd/portaudio/pa_tests/debug_convert.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * $Id: debug_convert.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * Convert tagged values. - * - * Author: Phil Burk <philburk@softsynth.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) -//#define OUTPUT_DEVICE (11) -#define NUM_SECONDS (8) -#define SLEEP_DUR (800) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) - -#define NUM_BUFFERS (0) - -typedef struct -{ - unsigned int framesToGo; -} -paTestData; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - short *out = (short*)outputBuffer; - int i; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - if( data->framesToGo < framesPerBuffer ) finished = 1; - - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = 0x0000 + i; /* left */ - *out++ = 0x1000 + i; /* right */ - } - return finished; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int i; - int totalSamps; - printf("PortAudio Test: output debug values\n" ); - data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */ - printf("totalSamps = %d\n", totalSamps ); - err = Pa_Initialize(); - if( err != paNoError ) goto error; - printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE ); - - err = Pa_OpenStream( - &stream, - paNoDevice, - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - OUTPUT_DEVICE, - 2, /* stereo output */ - paInt16, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - NUM_BUFFERS, /* number of buffers, if zero then use default minimum */ - paClipOff|paDitherOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - printf("Is callback being called?\n"); - for( i=0; i<((NUM_SECONDS+1)*1000); i+=SLEEP_DUR ) - { - printf("data.framesToGo = %d\n", data.framesToGo ); fflush(stdout); - Pa_Sleep( SLEEP_DUR ); - } - /* Stop sound until ENTER hit. */ - printf("Call Pa_StopStream()\n"); - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/debug_dither_calc.c b/pd/portaudio/pa_tests/debug_dither_calc.c deleted file mode 100644 index d751ca39..00000000 --- a/pd/portaudio/pa_tests/debug_dither_calc.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * $Id: debug_dither_calc.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * Test Dither calculations. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#include "pa_host.h" - -/*******************************************************************/ -int main(void); -int main(void) -{ - long max,min; - int i; - - for( i=0; i<10000; i++ ) - { - long dither = PaConvert_TriangularDither(); - // printf("dither = 0x%08X\n", dither ); - if( dither < min ) min = dither; - else if( dither > max ) max = dither; - } - printf("min = 0x%08X = %d, max = 0x%08X = %d\n", min, min, max, max ); -} diff --git a/pd/portaudio/pa_tests/debug_dual.c b/pd/portaudio/pa_tests/debug_dual.c deleted file mode 100644 index b90ef290..00000000 --- a/pd/portaudio/pa_tests/debug_dual.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * $Id: debug_dual.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * debug_dual.c - * Try to open TWO streams on separate cards. - * Play a sine sweep using the Portable Audio api for several seconds. - * Hacked test for debugging PA. - * - * Author: Phil Burk <philburk@softsynth.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#define DEV_ID_1 (13) -#define DEV_ID_2 (15) -#define NUM_SECONDS (8) -#define SLEEP_DUR (800) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) -#if 0 -#define MIN_LATENCY_MSEC (200) -#define NUM_BUFFERS ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000)) -#else -#define NUM_BUFFERS (0) -#endif -#define MIN_FREQ (100.0f) -#define MAX_FREQ (4000.0f) -#define FREQ_SCALAR (1.00002f) -#define CalcPhaseIncrement(freq) (freq/SAMPLE_RATE) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TABLE_SIZE (400) -typedef struct -{ - float sine[TABLE_SIZE + 1]; // add one for guard point for interpolation - float phase_increment; - float left_phase; - float right_phase; -} -paTestData; -/* Convert phase between and 1.0 to sine value - * using linear interpolation. - */ -float LookupSine( paTestData *data, float phase ); -float LookupSine( paTestData *data, float phase ) -{ - float fIndex = phase*TABLE_SIZE; - int index = (int) fIndex; - float fract = fIndex - index; - float lo = data->sine[index]; - float hi = data->sine[index+1]; - float val = lo + fract*(hi-lo); - return val; -} -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned long i; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = LookupSine(data, data->left_phase); /* left */ - *out++ = LookupSine(data, data->right_phase); /* right */ - data->left_phase += data->phase_increment; - if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f; - data->right_phase += (data->phase_increment * 1.5f); /* fifth above */ - if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f; - /* sweep frequency then start over. */ - data->phase_increment *= FREQ_SCALAR; - if( data->phase_increment > CalcPhaseIncrement(MAX_FREQ) ) data->phase_increment = CalcPhaseIncrement(MIN_FREQ); - } - return 0; -} - -PaError TestStart( PortAudioStream **streamPtr, PaDeviceID devID, - paTestData *data ); -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream1, *stream2; - PaError err; - paTestData DATA1, DATA2; - printf("PortAudio Test: DUAL sine sweep. ask for %d buffers\n", NUM_BUFFERS ); - err = Pa_Initialize(); - if( err != paNoError ) goto error; - err = TestStart( &stream1, DEV_ID_1, &DATA1 ); - if( err != paNoError ) goto error; - err = TestStart( &stream2, DEV_ID_2, &DATA2 ); - if( err != paNoError ) goto error; - printf("Hit ENTER\n"); - getchar(); - err = Pa_StopStream( stream1 ); - if( err != paNoError ) goto error; - err = Pa_StopStream( stream2 ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} -PaError TestStart( PortAudioStream **streamPtr, PaDeviceID devID, paTestData *data ) -{ - PortAudioStream *stream; - PaError err; - int i; - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - data->sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - data->sine[TABLE_SIZE] = data->sine[0]; // set guard point - data->left_phase = data->right_phase = 0.0; - data->phase_increment = CalcPhaseIncrement(MIN_FREQ); - printf("PortAudio Test: output device = %d\n", devID ); - err = Pa_OpenStream( - &stream, - paNoDevice, - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - devID, - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - NUM_BUFFERS, /* number of buffers, if zero then use default minimum */ - paClipOff|paDitherOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - data ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - *streamPtr = stream; - return 0; -error: - return err; -} diff --git a/pd/portaudio/pa_tests/debug_multi_in.c b/pd/portaudio/pa_tests/debug_multi_in.c deleted file mode 100644 index ef1d4a19..00000000 --- a/pd/portaudio/pa_tests/debug_multi_in.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * $Id: debug_multi_in.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * debug_multi_in.c - * Pass output from each of multiple channels - * to a stereo output using the Portable Audio api. - * Hacked test for debugging PA. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include <string.h> -#include "portaudio.h" -//#define INPUT_DEVICE_NAME ("EWS88 MT Interleaved Rec") -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) -//#define OUTPUT_DEVICE (18) -#define SAMPLE_RATE (22050) -#define FRAMES_PER_BUFFER (256) -#define MIN_LATENCY_MSEC (400) -#define NUM_BUFFERS ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000)) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -typedef struct -{ - int liveChannel; - int numChannels; -} -paTestData; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - float *in = (float*)inputBuffer; - int i; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - if( in == NULL ) return 0; - for( i=0; i<(int)framesPerBuffer; i++ ) - { - /* Copy one channel of input to output. */ - *out++ = in[data->liveChannel]; - *out++ = in[data->liveChannel]; - in += data->numChannels; - } - return 0; -} -/*******************************************************************/ -int PaFindDeviceByName( const char *name ) -{ - int i; - int numDevices; - const PaDeviceInfo *pdi; - int len = strlen( name ); - PaDeviceID result = paNoDevice; - numDevices = Pa_CountDevices(); - for( i=0; i<numDevices; i++ ) - { - pdi = Pa_GetDeviceInfo( i ); - if( strncmp( name, pdi->name, len ) == 0 ) - { - result = i; - break; - } - } - return result; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int i; - PaDeviceID inputDevice; - const PaDeviceInfo *pdi; - printf("PortAudio Test: input signal from each channel. %d buffers\n", NUM_BUFFERS ); - data.liveChannel = 0; - err = Pa_Initialize(); - if( err != paNoError ) goto error; -#ifdef INPUT_DEVICE_NAME - printf("Try to use device: %s\n", INPUT_DEVICE_NAME ); - inputDevice = PaFindDeviceByName(INPUT_DEVICE_NAME); - if( inputDevice == paNoDevice ) - { - printf("Could not find %s. Using default instead.\n", INPUT_DEVICE_NAME ); - inputDevice = Pa_GetDefaultInputDeviceID(); - } -#else - printf("Using default input device.\n"); - inputDevice = Pa_GetDefaultInputDeviceID(); -#endif - pdi = Pa_GetDeviceInfo( inputDevice ); - if( pdi == NULL ) - { - printf("Could not get device info!\n"); - goto error; - } - data.numChannels = pdi->maxInputChannels; - printf("Input Device name is %s\n", pdi->name ); - printf("Input Device has %d channels.\n", pdi->maxInputChannels); - err = Pa_OpenStream( - &stream, - inputDevice, - pdi->maxInputChannels, - paFloat32, /* 32 bit floating point input */ - NULL, - OUTPUT_DEVICE, - 2, - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - NUM_BUFFERS, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - data.liveChannel = 0; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - for( i=0; i<data.numChannels; i++ ) - { - data.liveChannel = i; - printf("Channel %d being sent to output. Hit ENTER for next channel.", i ); - fflush(stdout); - getchar(); - } - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - - err = Pa_CloseStream( stream ); - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/debug_multi_out.c b/pd/portaudio/pa_tests/debug_multi_out.c deleted file mode 100644 index 6ff64ac6..00000000 --- a/pd/portaudio/pa_tests/debug_multi_out.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * $Id: debug_multi_out.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * debug_multi_out.c - * Play a different sine wave on each channels, - * using the Portable Audio api. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) -#define FREQ_INCR (300.0 / SAMPLE_RATE) -#define MAX_CHANNELS (64) - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - -typedef struct -{ - int numChannels; - double phases[MAX_CHANNELS]; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - int frameIndex, channelIndex; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ ) - { - for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ ) - { - /* Output sine wave on every channel. */ - *out++ = (float) sin(data->phases[channelIndex]); - - /* Play each channel at a higher frequency. */ - data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex); - if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI); - } - } - - return 0; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - const PaDeviceInfo *pdi; - paTestData data = {0}; - printf("PortAudio Test: output sine wave on each channel.\n" ); - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE ); - data.numChannels = pdi->maxOutputChannels; - if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS; - printf("Number of Channels = %d\n", data.numChannels ); - - err = Pa_OpenStream( - &stream, - paNoDevice, /* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - OUTPUT_DEVICE, - data.numChannels, - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Hit ENTER to stop sound.\n"); - fflush(stdout); - getchar(); - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - - Pa_CloseStream( stream ); - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/debug_record.c b/pd/portaudio/pa_tests/debug_record.c deleted file mode 100644 index f82ea58c..00000000 --- a/pd/portaudio/pa_tests/debug_record.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * $Id: debug_record.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * debug_record.c - * Record input into an array. - * Save array to a file. - * Based on patest_record.c but with various ugly debug hacks thrown in. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <stdlib.h> -#include <memory.h> -#include "portaudio.h" -#define SAMPLE_RATE (22050) -#define NUM_SECONDS (10) -#define SLEEP_DUR_MSEC (200) -#define FRAMES_PER_BUFFER (1<<10) -#define NUM_REC_BUFS (0) - -#if 1 -#define PA_SAMPLE_TYPE paFloat32 -typedef float SAMPLE; -#else -#define PA_SAMPLE_TYPE paInt16 -typedef short SAMPLE; -#endif - -typedef struct -{ - long frameIndex; /* Index into sample array. */ - long maxFrameIndex; - long samplesPerFrame; - long numSamples; - SAMPLE *recordedSamples; -} -paTestData; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may be called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int recordCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - SAMPLE *rptr = (SAMPLE*)inputBuffer; - SAMPLE *wptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame]; - long framesToCalc; - unsigned long i; - int finished; - unsigned long framesLeft = data->maxFrameIndex - data->frameIndex; - - (void) outputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( framesLeft < framesPerBuffer ) - { - framesToCalc = framesLeft; - finished = 1; - } - else - { - framesToCalc = framesPerBuffer; - finished = 0; - } - if( inputBuffer == NULL ) - { - for( i=0; i<framesToCalc; i++ ) - { - *wptr++ = 0; /* left */ - *wptr++ = 0; /* right */ - } - } - else - { - for( i=0; i<framesToCalc; i++ ) - { - *wptr++ = *rptr++; /* left */ - *wptr++ = *rptr++; /* right */ - } - } - data->frameIndex += framesToCalc; - return finished; -} -/* This routine will be called by the PortAudio engine when audio is needed. -** It may be called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int playCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - SAMPLE *rptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame]; - SAMPLE *wptr = (SAMPLE*)outputBuffer; - unsigned long i; - int finished; - unsigned int framesLeft = data->maxFrameIndex - data->frameIndex; - if( outputBuffer == NULL ) return 0; - (void) inputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( framesLeft < framesPerBuffer ) - { - /* final buffer... */ - for( i=0; i<framesLeft; i++ ) - { - *wptr++ = *rptr++; /* left */ - *wptr++ = *rptr++; /* right */ - } - for( ; i<framesPerBuffer; i++ ) - { - *wptr++ = 0; /* left */ - *wptr++ = 0; /* right */ - } - data->frameIndex += framesLeft; - finished = 1; - } - else - { - for( i=0; i<framesPerBuffer; i++ ) - { - *wptr++ = *rptr++; /* left */ - *wptr++ = *rptr++; /* right */ - } - data->frameIndex += framesPerBuffer; - finished = 0; - } - return finished; -} - -/****************************************************************/ -PaError TestRecording( paTestData *dataPtr ) -{ - PortAudioStream *stream; - PaError err; - int i; - - /* Record some audio. */ - err = Pa_OpenStream( - &stream, - Pa_GetDefaultInputDeviceID(), - dataPtr->samplesPerFrame, /* stereo input */ - PA_SAMPLE_TYPE, - NULL, - paNoDevice, - 0, - PA_SAMPLE_TYPE, - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - NUM_REC_BUFS, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - recordCallback, - dataPtr ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Now recording!\n"); fflush(stdout); - for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) - { - if( Pa_StreamActive( stream ) <= 0) - { - printf("Stream inactive!\n"); - break; - } - if( dataPtr->maxFrameIndex <= dataPtr->frameIndex ) - { - printf("Buffer recording complete.\n"); - break; - } - Pa_Sleep(100); - printf("index = %d\n", dataPtr->frameIndex ); fflush(stdout); - } - - printf("Finished loop. Close stream.\n"); fflush(stdout); - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - - printf("Done.\n"); fflush(stdout); - { - SAMPLE max = 0; - SAMPLE posVal; - int i; - for( i=0; i<dataPtr->numSamples; i++ ) - { - posVal = dataPtr->recordedSamples[i]; - if( posVal < 0 ) posVal = -posVal; - if( posVal > max ) max = posVal; - } - printf("Largest recorded sample = %d\n", max ); - } - /* Write recorded data to a file. */ -#if 0 - { - FILE *fid; - fid = fopen("recorded.raw", "wb"); - if( fid == NULL ) - { - printf("Could not open file."); - } - else - { - fwrite( dataPtr->recordedSamples, dataPtr->samplesPerFrame * sizeof(SAMPLE), totalFrames, fid ); - fclose( fid ); - printf("Wrote data to 'recorded.raw'\n"); - } - } -#endif - -error: - return err; -} - -/****************************************************************/ -PaError TestPlayback( paTestData *dataPtr ) -{ - PortAudioStream *stream; - PaError err; - int i; - - /* Playback recorded data. */ - dataPtr->frameIndex = 0; - printf("Begin playback.\n"); fflush(stdout); - err = Pa_OpenStream( - &stream, - paNoDevice, - 0, /* NO input */ - PA_SAMPLE_TYPE, - NULL, - Pa_GetDefaultOutputDeviceID(), - dataPtr->samplesPerFrame, /* stereo output */ - PA_SAMPLE_TYPE, - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - playCallback, - dataPtr ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - printf("Waiting for playback to finish.\n"); fflush(stdout); - for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) - { - Pa_Sleep(100); - printf("index = %d\n", dataPtr->frameIndex ); - } - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - -error: - return err; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PaError err; - paTestData data; - long totalFrames; - long numBytes; - long i; - printf("patest_record.c\n"); fflush(stdout); - - data.frameIndex = 0; - data.samplesPerFrame = 2; - data.maxFrameIndex = totalFrames = NUM_SECONDS*SAMPLE_RATE; - - printf("totalFrames = %d\n", totalFrames ); fflush(stdout); - data.numSamples = totalFrames * data.samplesPerFrame; - - numBytes = data.numSamples * sizeof(SAMPLE); - data.recordedSamples = (SAMPLE *) malloc( numBytes ); - if( data.recordedSamples == NULL ) - { - printf("Could not allocate record array.\n"); - exit(1); - } - for( i=0; i<data.numSamples; i++ ) data.recordedSamples[i] = 0; - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - for( i=0; i<2; i++ ) - { - err = TestRecording( &data ); - if( err != paNoError ) goto error; - - err = TestPlayback( &data ); - if( err != paNoError ) goto error; - } - - free( data.recordedSamples ); - Pa_Terminate(); - return 0; - -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - if( err == paHostError ) - { - fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() ); - } - return -1; -} diff --git a/pd/portaudio/pa_tests/debug_record_reuse.c b/pd/portaudio/pa_tests/debug_record_reuse.c deleted file mode 100644 index 4f4fb53d..00000000 --- a/pd/portaudio/pa_tests/debug_record_reuse.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * $Id: debug_record_reuse.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * debug_record_reuse.c - * Record input into an array. - * Save array to a file. - * Based on patest_record.c but with various ugly debug hacks thrown in. - * Loop twice and reuse same streams. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <stdlib.h> -#include <memory.h> -#include "portaudio.h" -#define SAMPLE_RATE (22050) -#define NUM_SECONDS (4) -#define SLEEP_DUR_MSEC (200) -#define FRAMES_PER_BUFFER (256) -#define NUM_REC_BUFS (0) - -#if 1 -#define PA_SAMPLE_TYPE paFloat32 -typedef float SAMPLE; -#else -#define PA_SAMPLE_TYPE paInt16 -typedef short SAMPLE; -#endif - -typedef struct -{ - long frameIndex; /* Index into sample array. */ - long maxFrameIndex; - long samplesPerFrame; - long numSamples; - PortAudioStream *outputStream; - PortAudioStream *inputStream; - SAMPLE *recordedSamples; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may be called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int recordCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - SAMPLE *rptr = (SAMPLE*)inputBuffer; - SAMPLE *wptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame]; - long framesToCalc; - unsigned long i; - int finished; - unsigned long framesLeft = data->maxFrameIndex - data->frameIndex; - - (void) outputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( framesLeft < framesPerBuffer ) - { - framesToCalc = framesLeft; - finished = 1; - } - else - { - framesToCalc = framesPerBuffer; - finished = 0; - } - if( inputBuffer == NULL ) - { - for( i=0; i<framesToCalc; i++ ) - { - *wptr++ = 0; /* left */ - *wptr++ = 0; /* right */ - } - } - else - { - for( i=0; i<framesToCalc; i++ ) - { - *wptr++ = *rptr++; /* left */ - *wptr++ = *rptr++; /* right */ - } - } - data->frameIndex += framesToCalc; - return finished; -} - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may be called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int playCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - SAMPLE *rptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame]; - SAMPLE *wptr = (SAMPLE*)outputBuffer; - unsigned long i; - int finished; - unsigned int framesLeft = data->maxFrameIndex - data->frameIndex; - if( outputBuffer == NULL ) return 0; - (void) inputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( framesLeft < framesPerBuffer ) - { - /* final buffer... */ - for( i=0; i<framesLeft; i++ ) - { - *wptr++ = *rptr++; /* left */ - *wptr++ = *rptr++; /* right */ - } - for( ; i<framesPerBuffer; i++ ) - { - *wptr++ = 0; /* left */ - *wptr++ = 0; /* right */ - } - data->frameIndex += framesLeft; - finished = 1; - } - else - { - for( i=0; i<framesPerBuffer; i++ ) - { - *wptr++ = *rptr++; /* left */ - *wptr++ = *rptr++; /* right */ - } - data->frameIndex += framesPerBuffer; - finished = 0; - } - return finished; -} - -/****************************************************************/ -PaError TestRecording( paTestData *dataPtr ) -{ - PaError err; - int i; - int lastIndex = 0; - -/* Open input stream if not already open. */ - if( dataPtr->inputStream == NULL ) - { - /* Record some audio. */ - err = Pa_OpenStream( - &dataPtr->inputStream, - Pa_GetDefaultInputDeviceID(), - dataPtr->samplesPerFrame, /* stereo input */ - PA_SAMPLE_TYPE, - NULL, - paNoDevice, - 0, - PA_SAMPLE_TYPE, - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - NUM_REC_BUFS, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - recordCallback, - dataPtr ); - if( err != paNoError ) goto error; - } - - dataPtr->frameIndex = 0; - - err = Pa_StartStream( dataPtr->inputStream ); - if( err != paNoError ) goto error; - - printf("Now recording!\n"); fflush(stdout); - for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) - { - int frameIndex, delta; - Pa_Sleep(SLEEP_DUR_MSEC); - - frameIndex = dataPtr->frameIndex; - if( Pa_StreamActive( dataPtr->inputStream ) <= 0) - { - printf("Stream inactive!\n"); - break; - } - if( dataPtr->maxFrameIndex <= frameIndex ) - { - printf("Buffer recording complete.\n"); - break; - } - - delta = frameIndex - lastIndex; - lastIndex = frameIndex; - printf("index = %d, delta = %d\n", frameIndex, delta ); fflush(stdout); - } - - err = Pa_StopStream( dataPtr->inputStream ); - if( err != paNoError ) goto error; - - printf("Done.\n"); fflush(stdout); - -error: - return err; -} - -/****************************************************************/ -PaError TestPlayback( paTestData *dataPtr ) -{ - PaError err; - int i; - int lastIndex = 0; - - /* Playback recorded data. */ - dataPtr->frameIndex = 0; - printf("Begin playback.\n"); fflush(stdout); - -/* Open output stream if not already open. */ - if( dataPtr->outputStream == NULL ) - { - err = Pa_OpenStream( - &dataPtr->outputStream, - paNoDevice, - 0, /* NO input */ - PA_SAMPLE_TYPE, - NULL, - Pa_GetDefaultOutputDeviceID(), - dataPtr->samplesPerFrame, /* stereo output */ - PA_SAMPLE_TYPE, - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - playCallback, - dataPtr ); - if( err != paNoError ) goto error; - } - - err = Pa_StartStream( dataPtr->outputStream ); - if( err != paNoError ) goto error; - - printf("Waiting for playback to finish.\n"); fflush(stdout); - for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) - { - int frameIndex, delta; - Pa_Sleep(SLEEP_DUR_MSEC); - frameIndex = dataPtr->frameIndex; - delta = frameIndex - lastIndex; - lastIndex = frameIndex; - printf("index = %d, delta = %d\n", frameIndex, delta ); fflush(stdout); - } - - err = Pa_StopStream( dataPtr->outputStream ); - if( err != paNoError ) goto error; - -error: - return err; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PaError err; - paTestData data = { 0 }; - long totalFrames; - long numBytes; - long i; - printf("patest_record.c\n"); fflush(stdout); - -/* Set up test data structure and sample array. */ - data.frameIndex = 0; - data.samplesPerFrame = 2; - data.maxFrameIndex = totalFrames = NUM_SECONDS*SAMPLE_RATE; - - printf("totalFrames = %d\n", totalFrames ); fflush(stdout); - data.numSamples = totalFrames * data.samplesPerFrame; - - numBytes = data.numSamples * sizeof(SAMPLE); - data.recordedSamples = (SAMPLE *) malloc( numBytes ); - if( data.recordedSamples == NULL ) - { - printf("Could not allocate record array.\n"); - exit(1); - } - for( i=0; i<data.numSamples; i++ ) data.recordedSamples[i] = 0; - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - -/* Record and playback multiple times. */ - for( i=0; i<2; i++ ) - { - err = TestRecording( &data ); - if( err != paNoError ) goto error; - - err = TestPlayback( &data ); - if( err != paNoError ) goto error; - } - -/* Clean up. */ - err = Pa_CloseStream( data.inputStream ); - if( err != paNoError ) goto error; - - err = Pa_CloseStream( data.outputStream ); - if( err != paNoError ) goto error; - - if( err != paNoError ) goto error; - - free( data.recordedSamples ); - Pa_Terminate(); - - printf("Test complete.\n"); fflush(stdout); - return 0; - -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - if( err == paHostError ) - { - fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() ); - } - return -1; -} diff --git a/pd/portaudio/pa_tests/debug_sine.c b/pd/portaudio/pa_tests/debug_sine.c deleted file mode 100644 index 93d74160..00000000 --- a/pd/portaudio/pa_tests/debug_sine.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * $Id: debug_sine.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * debug_sine.c - * Play a sine sweep using the Portable Audio api for several seconds. - * Hacked test for debugging PA. - * - * Author: Phil Burk <philburk@softsynth.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) -//#define OUTPUT_DEVICE (11) -#define NUM_SECONDS (8) -#define SLEEP_DUR (800) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) -#if 0 -#define MIN_LATENCY_MSEC (200) -#define NUM_BUFFERS ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000)) -#else -#define NUM_BUFFERS (0) -#endif -#define MIN_FREQ (100.0f) -#define MAX_FREQ (4000.0f) -#define FREQ_SCALAR (1.00002f) -#define CalcPhaseIncrement(freq) (freq/SAMPLE_RATE) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TABLE_SIZE (400) -typedef struct -{ - float sine[TABLE_SIZE + 1]; // add one for guard point for interpolation - float phase_increment; - float left_phase; - float right_phase; - unsigned int framesToGo; -} -paTestData; -/* Convert phase between and 1.0 to sine value - * using linear interpolation. - */ -float LookupSine( paTestData *data, float phase ); -float LookupSine( paTestData *data, float phase ) -{ - float fIndex = phase*TABLE_SIZE; - int index = (int) fIndex; - float fract = fIndex - index; - float lo = data->sine[index]; - float hi = data->sine[index+1]; - float val = lo + fract*(hi-lo); - return val; -} -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - int framesToCalc; - int i; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - if( data->framesToGo < framesPerBuffer ) - { - framesToCalc = data->framesToGo; - data->framesToGo = 0; - finished = 1; - } - else - { - framesToCalc = framesPerBuffer; - data->framesToGo -= framesPerBuffer; - } - - for( i=0; i<framesToCalc; i++ ) - { - *out++ = LookupSine(data, data->left_phase); /* left */ - *out++ = LookupSine(data, data->right_phase); /* right */ - data->left_phase += data->phase_increment; - if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f; - data->right_phase += (data->phase_increment * 1.5f); /* fifth above */ - if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f; - /* sweep frequency then start over. */ - data->phase_increment *= FREQ_SCALAR; - if( data->phase_increment > CalcPhaseIncrement(MAX_FREQ) ) data->phase_increment = CalcPhaseIncrement(MIN_FREQ); - } - /* zero remainder of final buffer */ - for( ; i<(int)framesPerBuffer; i++ ) - { - *out++ = 0; /* left */ - *out++ = 0; /* right */ - } - return finished; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int i; - int totalSamps; - printf("PortAudio Test: output sine sweep. ask for %d buffers\n", NUM_BUFFERS ); - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - data.sine[TABLE_SIZE] = data.sine[0]; // set guard point - data.left_phase = data.right_phase = 0.0; - data.phase_increment = CalcPhaseIncrement(MIN_FREQ); - data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */ - printf("totalSamps = %d\n", totalSamps ); - err = Pa_Initialize(); - if( err != paNoError ) goto error; - printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE ); - err = Pa_OpenStream( - &stream, - paNoDevice, - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - OUTPUT_DEVICE, - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - NUM_BUFFERS, /* number of buffers, if zero then use default minimum */ - paClipOff|paDitherOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - printf("Is callback being called?\n"); - for( i=0; i<((NUM_SECONDS+1)*1000); i+=SLEEP_DUR ) - { - printf("data.framesToGo = %d\n", data.framesToGo ); fflush(stdout); - Pa_Sleep( SLEEP_DUR ); - } - /* Stop sound until ENTER hit. */ - printf("Call Pa_StopStream()\n"); - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/debug_sine_amp.c b/pd/portaudio/pa_tests/debug_sine_amp.c deleted file mode 100644 index b6b21865..00000000 --- a/pd/portaudio/pa_tests/debug_sine_amp.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * $Id: debug_sine_amp.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * Play a different sine wave on each channels, - * using the Portable Audio api. - * Allos amplitude to be set interactively. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) -#define FREQ_INCR (300.0 / SAMPLE_RATE) -#define MAX_CHANNELS (64) - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - -typedef struct -{ - int numChannels; - double phases[MAX_CHANNELS]; - float amplitude; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - int frameIndex, channelIndex; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ ) - { - for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ ) - { - /* Output sine wave on every channel. */ - *out++ = (float) ( data->amplitude * sin(data->phases[channelIndex]) ); - - /* Play each channel at a higher frequency. */ - data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex); - if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI); - } - } - - return 0; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - char pad[256]; - PortAudioStream *stream; - PaError err; - const PaDeviceInfo *pdi; - paTestData data = {0}; - printf("PortAudio Test: output sine wave on each channel.\n" ); - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE ); - data.numChannels = pdi->maxOutputChannels; - if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS; - printf("Number of Channels = %d\n", data.numChannels ); - data.amplitude = 1.0; - - err = Pa_OpenStream( - &stream, - paNoDevice, /* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - OUTPUT_DEVICE, - data.numChannels, - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - do - { - printf("Current amplitude = %f\n", data.amplitude ); - printf("Enter new amplitude or 'q' to quit.\n"); - fflush(stdout); - gets( pad ); - if( pad[0] != 'q' ) - { - // I tried to use atof but it seems to be broken on Mac OS X 10.1 - float amp; - sscanf( pad, "%f", & ); - data.amplitude = amp; - } - } while( pad[0] != 'q' ); - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - - Pa_CloseStream( stream ); - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/debug_sine_formats.c b/pd/portaudio/pa_tests/debug_sine_formats.c deleted file mode 100644 index 3f75fa2e..00000000 --- a/pd/portaudio/pa_tests/debug_sine_formats.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * $Id: debug_sine_formats.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_sine_formats.c - * Play a sine wave using the Portable Audio api for several seconds. - * Test various data formats. - * - * Author: Phil Burk - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define NUM_SECONDS (10) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) - -#define LEFT_FREQ (SAMPLE_RATE/512.0) /* So we hit 1.0 */ -#define RIGHT_FREQ (500.0) - -#define AMPLITUDE (1.0) - -/* Select ONE format for testing. */ -#define TEST_UINT8 (1) -#define TEST_INT8 (0) -#define TEST_INT16 (0) -#define TEST_FLOAT32 (0) - -#if TEST_UINT8 -#define TEST_FORMAT paUInt8 -typedef unsigned char SAMPLE_t; -#define SAMPLE_ZERO (0x80) -#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x))) -#define FORMAT_NAME "Unsigned 8 Bit" - -#elif TEST_INT8 -#define TEST_FORMAT paInt8 -typedef char SAMPLE_t; -#define SAMPLE_ZERO (0) -#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x))) -#define FORMAT_NAME "Signed 8 Bit" - -#elif TEST_INT16 -#define TEST_FORMAT paInt16 -typedef short SAMPLE_t; -#define SAMPLE_ZERO (0) -#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(32767 * (x))) -#define FORMAT_NAME "Signed 16 Bit" - -#elif TEST_FLOAT32 -#define TEST_FORMAT paFloat32 -typedef float SAMPLE_t; -#define SAMPLE_ZERO (0.0) -#define DOUBLE_TO_SAMPLE(x) ((SAMPLE_t)(x)) -#define FORMAT_NAME "Float 32 Bit" -#endif - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - - -typedef struct -{ - double left_phase; - double right_phase; - unsigned int framesToGo; -} -paTestData; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - SAMPLE_t *out = (SAMPLE_t *)outputBuffer; - SAMPLE_t sample; - int i; - int framesToCalc; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - if( data->framesToGo < framesPerBuffer ) - { - framesToCalc = data->framesToGo; - data->framesToGo = 0; - finished = 1; - } - else - { - framesToCalc = framesPerBuffer; - data->framesToGo -= framesPerBuffer; - } - - for( i=0; i<framesToCalc; i++ ) - { - data->left_phase += (LEFT_FREQ / SAMPLE_RATE); - if( data->left_phase > 1.0) data->left_phase -= 1.0; - sample = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->left_phase * M_PI * 2. ))); /**/ - *out++ = sample; -/* *out++ = sample; /**/ -/* *out++ = 0; /**/ - - data->right_phase += (RIGHT_FREQ / SAMPLE_RATE); - if( data->right_phase > 1.0) data->right_phase -= 1.0; - *out++ = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->right_phase * M_PI * 2. ))); /**/ -/* *out++ = 0; /* */ - } - /* zero remainder of final buffer */ - for( ; i<(int)framesPerBuffer; i++ ) - { - *out++ = SAMPLE_ZERO; /* left */ - *out++ = SAMPLE_ZERO; /* right */ - } - return finished; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int totalSamps; - - printf("PortAudio Test: output " FORMAT_NAME "\n"); - - - data.left_phase = data.right_phase = 0.0; - data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */ - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - TEST_FORMAT, - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 2, /* stereo output */ - TEST_FORMAT, - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Waiting %d seconds for sound to finish.\n", NUM_SECONDS ); - while( Pa_StreamActive( stream ) ) Pa_Sleep(10); - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - - printf("PortAudio Test Finished: " FORMAT_NAME "\n"); - - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/debug_srate.c b/pd/portaudio/pa_tests/debug_srate.c deleted file mode 100644 index b3e3b70f..00000000 --- a/pd/portaudio/pa_tests/debug_srate.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * $Id: debug_srate.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * debug_record_reuse.c - * Record input into an array. - * Save array to a file. - * Based on patest_record.c but with various ugly debug hacks thrown in. - * Loop twice and reuse same streams. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <stdlib.h> -#include <memory.h> -#include "portaudio.h" - -#define EWS88MT_12_REC (1) -#define EWS88MT_12_PLAY (10) -#define SBLIVE_REC (2) -#define SBLIVE_PLAY (11) - -#if 0 -#define INPUT_DEVICE_ID Pa_GetDefaultInputDeviceID() -#define OUTPUT_DEVICE_ID Pa_GetDefaultOutputDeviceID() -#else -#define INPUT_DEVICE_ID (EWS88MT_12_REC) -#define OUTPUT_DEVICE_ID (SBLIVE_PLAY) -#endif - -#define INPUT_SAMPLE_RATE (22050.0) -#define OUTPUT_SAMPLE_RATE (22050.0) -#define NUM_SECONDS (4) -#define SLEEP_DUR_MSEC (1000) -#define FRAMES_PER_BUFFER (64) -#define NUM_REC_BUFS (0) -#define SAMPLES_PER_FRAME (2) - -#define PA_SAMPLE_TYPE paInt16 -typedef short SAMPLE; - -typedef struct -{ - long frameIndex; /* Index into sample array. */ -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may be called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int recordCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData *) userData; - (void) outputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( inputBuffer != NULL ) - { - data->frameIndex += framesPerBuffer; - } - return 0; -} - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may be called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int playCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData *) userData; - (void) inputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( outputBuffer != NULL ) - { - data->frameIndex += framesPerBuffer; - } - return 0; -} - -/****************************************************************/ -PaError MeasureStreamRate( PortAudioStream *stream, paTestData *dataPtr, double *ratePtr ) -{ - PaError err; - int i; - int totalFrames = 0; - int totalMSec = 0; - - dataPtr->frameIndex = 0; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) - { - int delta, endIndex; - - int startIndex = dataPtr->frameIndex; - Pa_Sleep(SLEEP_DUR_MSEC); - endIndex = dataPtr->frameIndex; - - delta = endIndex - startIndex; - totalFrames += delta; - totalMSec += SLEEP_DUR_MSEC; - - printf("index = %d, delta = %d\n", endIndex, delta ); fflush(stdout); - } - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - - *ratePtr = (totalFrames * 1000.0) / totalMSec; - -error: - return err; -} - -void ReportRate( double measuredRate, double expectedRate ) -{ - double error; - - error = (measuredRate - expectedRate) / expectedRate; - error = (error < 0 ) ? -error : error; - - printf("Measured rate = %6.1f, expected rate = %6.1f\n", - measuredRate, expectedRate ); - if( error > 0.1 ) - { - printf("ERROR: unexpected rate! --------------------- ERROR!\n"); - } - else - { - printf("SUCCESS: rate within tolerance!\n"); - } -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PaError err; - paTestData data = { 0 }; - long i; - double rate; - const PaDeviceInfo *pdi; - - PortAudioStream *outputStream; - PortAudioStream *inputStream; - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - - pdi = Pa_GetDeviceInfo( INPUT_DEVICE_ID ); - printf("Input device = %s\n", pdi->name ); - pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE_ID ); - printf("Output device = %s\n", pdi->name ); - -/* Open input stream. */ - err = Pa_OpenStream( - &inputStream, - INPUT_DEVICE_ID, - SAMPLES_PER_FRAME, /* stereo input */ - PA_SAMPLE_TYPE, - NULL, - paNoDevice, - 0, - PA_SAMPLE_TYPE, - NULL, - INPUT_SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - NUM_REC_BUFS, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - recordCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_OpenStream( - &outputStream, - paNoDevice, - 0, /* NO input */ - PA_SAMPLE_TYPE, - NULL, - OUTPUT_DEVICE_ID, - SAMPLES_PER_FRAME, /* stereo output */ - PA_SAMPLE_TYPE, - NULL, - OUTPUT_SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - playCallback, - &data ); - if( err != paNoError ) goto error; - -/* Record and playback multiple times. */ - for( i=0; i<2; i++ ) - { - printf("Measuring INPUT ------------------------- \n"); - err = MeasureStreamRate( inputStream, &data, &rate ); - if( err != paNoError ) goto error; - ReportRate( rate, INPUT_SAMPLE_RATE ); - - printf("Measuring OUTPUT ------------------------- \n"); - err = MeasureStreamRate( outputStream, &data, &rate ); - if( err != paNoError ) goto error; - ReportRate( rate, OUTPUT_SAMPLE_RATE ); - } - -/* Clean up. */ - err = Pa_CloseStream( inputStream ); - if( err != paNoError ) goto error; - - err = Pa_CloseStream( outputStream ); - if( err != paNoError ) goto error; - - if( err != paNoError ) goto error; - - Pa_Terminate(); - - printf("Test complete.\n"); fflush(stdout); - return 0; - -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - if( err == paHostError ) - { - fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() ); - } - return -1; -} diff --git a/pd/portaudio/pa_tests/debug_test1.c b/pd/portaudio/pa_tests/debug_test1.c deleted file mode 100644 index 05370b00..00000000 --- a/pd/portaudio/pa_tests/debug_test1.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * $Id: debug_test1.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - patest1.c - Ring modulate the audio input with a 441hz sine wave for 20 seconds - using the Portable Audio api - Author: Ross Bencina <rossb@audiomulch.com> - Modifications: - April 5th, 2001 - PLB - Check for NULL inputBuffer. -*/ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#ifndef M_PI -#define M_PI (3.14159265) -#endif -typedef struct -{ - float sine[100]; - int phase; - int sampsToGo; -} -patest1data; -static int patest1Callback( void *inputBuffer, void *outputBuffer, - unsigned long bufferFrames, - PaTimestamp outTime, void *userData ) -{ - patest1data *data = (patest1data*)userData; - float *in = (float*)inputBuffer; - float *out = (float*)outputBuffer; - int framesToCalc = bufferFrames; - unsigned long i; - int finished = 0; - if(inputBuffer == NULL) return 0; - if( data->sampsToGo < bufferFrames ) - { - finished = 1; - } - for( i=0; i<bufferFrames; i++ ) - { - *out++ = *in++; - *out++ = *in++; - if( data->phase >= 100 ) - data->phase = 0; - } - data->sampsToGo -= bufferFrames; - /* zero remainder of final buffer if not already done */ - for( ; i<bufferFrames; i++ ) - { - *out++ = 0; /* left */ - *out++ = 0; /* right */ - } - return finished; -} -int main(int argc, char* argv[]); -int main(int argc, char* argv[]) -{ - PaStream *stream; - PaError err; - patest1data data; - int i; - int inputDevice = Pa_GetDefaultInputDeviceID(); - int outputDevice = Pa_GetDefaultOutputDeviceID(); - /* initialise sinusoidal wavetable */ - for( i=0; i<100; i++ ) - data.sine[i] = sin( ((double)i/100.) * M_PI * 2. ); - data.phase = 0; - data.sampsToGo = 44100 * 4; // 20 seconds - /* initialise portaudio subsytem */ - Pa_Initialize(); - err = Pa_OpenStream( - &stream, - inputDevice, - 2, /* stereo input */ - paFloat32, /* 32 bit floating point input */ - NULL, - outputDevice, - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - NULL, - 44100., - // 22050, /* half second buffers */ - // 4, /* four buffers */ - 512, /* half second buffers */ - 0, /* four buffers */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patest1Callback, - &data ); - if( err == paNoError ) - { - err = Pa_StartStream( stream ); - // printf( "Press any key to end.\n" ); - // getc( stdin ); //wait for input before exiting - // Pa_AbortStream( stream ); - - printf( "Waiting for stream to complete...\n" ); - - while( Pa_StreamActive( stream ) ) - Pa_Sleep(1000); /* sleep until playback has finished */ - - err = Pa_CloseStream( stream ); - } - else - { - fprintf( stderr, "An error occured while opening the portaudio stream\n" ); - if( err == paHostError ) - fprintf( stderr, "Host error number: %d\n", Pa_GetHostError() ); - else - fprintf( stderr, "Error number: %d\n", err ); - } - Pa_Terminate(); - printf( "bye\n" ); - - return 0; -} diff --git a/pd/portaudio/pa_tests/pa_devs.c b/pd/portaudio/pa_tests/pa_devs.c deleted file mode 100644 index 983699d1..00000000 --- a/pd/portaudio/pa_tests/pa_devs.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * $Id: pa_devs.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * pa_devs.c - * List available devices. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -/*******************************************************************/ -static void PrintSupportedStandardSampleRates( - const PaStreamParameters *inputParameters, - const PaStreamParameters *outputParameters ) -{ - static double standardSampleRates[] = { - 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0, - 44100.0, 48000.0, 88200.0, 96000.0, -1 /* negative terminated list */ - }; - int i, printCount; - PaError err; - - printCount = 0; - for( i=0; standardSampleRates[i] > 0; i++ ) - { - err = Pa_IsFormatSupported( inputParameters, outputParameters, standardSampleRates[i] ); - if( err == paFormatIsSupported ) - { - if( printCount == 0 ) - { - printf( "\t%8.2f", standardSampleRates[i] ); - printCount = 1; - } - else if( printCount == 4 ) - { - printf( ",\n\t%8.2f", standardSampleRates[i] ); - printCount = 1; - } - else - { - printf( ", %8.2f", standardSampleRates[i] ); - ++printCount; - } - } - } - if( !printCount ) - printf( "None\n" ); - else - printf( "\n" ); -} -/*******************************************************************/ -int main(void); -int main(void) -{ - int i, numDevices, defaultDisplayed; - const PaDeviceInfo *deviceInfo; - PaStreamParameters inputParameters, outputParameters; - PaError err; - - - Pa_Initialize(); - - printf( "PortAudio version number = %d\nPortAudio version text = '%s'\n", - Pa_GetVersion(), Pa_GetVersionText() ); - - - numDevices = Pa_CountDevices(); - if( numDevices < 0 ) - { - printf( "ERROR: Pa_CountDevices returned 0x%x\n", numDevices ); - err = numDevices; - goto error; - } - - printf( "Number of devices = %d\n", numDevices ); - for( i=0; i<numDevices; i++ ) - { - deviceInfo = Pa_GetDeviceInfo( i ); - printf( "--------------------------------------- device #%d\n", i ); - - /* Mark global and API specific default devices */ - defaultDisplayed = 0; - if( i == Pa_GetDefaultInputDevice() ) - { - printf( "[ Default Input" ); - defaultDisplayed = 1; - } - else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultInputDevice ) - { - const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi ); - printf( "[ Default %s Input", hostInfo->name ); - defaultDisplayed = 1; - } - - if( i == Pa_GetDefaultOutputDevice() ) - { - printf( (defaultDisplayed ? "," : "[") ); - printf( " Default Output" ); - defaultDisplayed = 1; - } - else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultOutputDevice ) - { - const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi ); - printf( (defaultDisplayed ? "," : "[") ); - printf( " Default %s Output", hostInfo->name ); - defaultDisplayed = 1; - } - - if( defaultDisplayed ) - printf( " ]\n" ); - - /* print device info fields */ - printf( "Name = %s\n", deviceInfo->name ); - printf( "Host API = %s\n", Pa_GetHostApiInfo( deviceInfo->hostApi )->name ); - printf( "Max inputs = %d", deviceInfo->maxInputChannels ); - printf( ", Max outputs = %d\n", deviceInfo->maxOutputChannels ); - - printf( "Default low input latency = %8.3f\n", deviceInfo->defaultLowInputLatency ); - printf( "Default low output latency = %8.3f\n", deviceInfo->defaultLowOutputLatency ); - printf( "Default high input latency = %8.3f\n", deviceInfo->defaultHighInputLatency ); - printf( "Default high output latency = %8.3f\n", deviceInfo->defaultHighOutputLatency ); - - printf( "Default sample rate = %8.2f\n", deviceInfo->defaultSampleRate ); - - /* poll for standard sample rates */ - inputParameters.device = i; - inputParameters.channelCount = deviceInfo->maxInputChannels; - inputParameters.sampleFormat = paInt16; - inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */ - inputParameters.hostApiSpecificStreamInfo = NULL; - - outputParameters.device = i; - outputParameters.channelCount = deviceInfo->maxOutputChannels; - outputParameters.sampleFormat = paInt16; - outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */ - outputParameters.hostApiSpecificStreamInfo = NULL; - - if( inputParameters.channelCount > 0 ) - { - printf("Supported standard sample rates\n for half-duplex 16 bit %d channel input = \n", - inputParameters.channelCount ); - PrintSupportedStandardSampleRates( &inputParameters, NULL ); - } - - if( outputParameters.channelCount > 0 ) - { - printf("Supported standard sample rates\n for half-duplex 16 bit %d channel output = \n", - outputParameters.channelCount ); - PrintSupportedStandardSampleRates( NULL, &outputParameters ); - } - - if( inputParameters.channelCount > 0 && outputParameters.channelCount > 0 ) - { - printf("Supported standard sample rates\n for full-duplex 16 bit %d channel input, %d channel output = \n", - inputParameters.channelCount, outputParameters.channelCount ); - PrintSupportedStandardSampleRates( &inputParameters, &outputParameters ); - } - } - - Pa_Terminate(); - - printf("----------------------------------------------\n"); - 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 err; -} diff --git a/pd/portaudio/pa_tests/pa_fuzz.c b/pd/portaudio/pa_tests/pa_fuzz.c deleted file mode 100644 index 1ec88785..00000000 --- a/pd/portaudio/pa_tests/pa_fuzz.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * $Id: pa_fuzz.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * pa_fuzz.c - * Distort input like a fuzz boz. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -/* -** 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 PA_SAMPLE_TYPE paFloat32 -#define FRAMES_PER_BUFFER (64) - -typedef float SAMPLE; - -float CubicAmplifier( float input ); -static int fuzzCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void *userData ); - -/* Non-linear amplifier with soft distortion curve. */ -float CubicAmplifier( float input ) -{ - float output, temp; - if( input < 0.0 ) - { - temp = input + 1.0f; - output = (temp * temp * temp) - 1.0f; - } - else - { - temp = input - 1.0f; - output = (temp * temp * temp) + 1.0f; - } - - return output; -} -#define FUZZ(x) CubicAmplifier(CubicAmplifier(CubicAmplifier(CubicAmplifier(x)))) - -static int gNumNoInputs = 0; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may be called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int fuzzCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void *userData ) -{ - SAMPLE *out = (SAMPLE*)outputBuffer; - SAMPLE *in = (SAMPLE*)inputBuffer; - unsigned int i; - (void) timeInfo; /* Prevent unused variable warnings. */ - (void) statusFlags; - (void) userData; - - if( inputBuffer == NULL ) - { - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = 0; /* left - silent */ - *out++ = 0; /* right - silent */ - } - gNumNoInputs += 1; - } - else - { - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = FUZZ(*in++); /* left - distorted */ - *out++ = *in++; /* right - clean */ - } - } - - return paContinue; -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PaStreamParameters inputParameters, outputParameters; - PaStream *stream; - PaError err; - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - - inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */ - inputParameters.channelCount = 2; /* stereo input */ - inputParameters.sampleFormat = PA_SAMPLE_TYPE; - inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; - inputParameters.hostApiSpecificStreamInfo = NULL; - - outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ - outputParameters.channelCount = 2; /* stereo output */ - outputParameters.sampleFormat = PA_SAMPLE_TYPE; - outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; - outputParameters.hostApiSpecificStreamInfo = NULL; - - err = Pa_OpenStream( - &stream, - &inputParameters, - &outputParameters, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - 0, // paClipOff, /* we won't output out of range samples so don't bother clipping them */ - fuzzCallback, - NULL ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Hit ENTER to stop program.\n"); - getchar(); - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - - printf("Finished. gNumNoInputs = %d\n", gNumNoInputs ); - Pa_Terminate(); - 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/pd/portaudio/pa_tests/pa_minlat.c b/pd/portaudio/pa_tests/pa_minlat.c deleted file mode 100644 index 736445a7..00000000 --- a/pd/portaudio/pa_tests/pa_minlat.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * $Id: pa_minlat.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * paminlat.c - * Experiment with different numbers of buffers to determine the - * minimum latency for a computer. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include "portaudio.h" - -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TWOPI (M_PI * 2.0) - -#define DEFAULT_BUFFER_SIZE (32) - -typedef struct -{ - double left_phase; - double right_phase; -} -paTestData; - -/* Very simple synthesis routine to generate two sine waves. */ -static int paminlatCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned int i; - double left_phaseInc = 0.02; - double right_phaseInc = 0.06; - - double left_phase = data->left_phase; - double right_phase = data->right_phase; - - for( i=0; i<framesPerBuffer; i++ ) - { - left_phase += left_phaseInc; - if( left_phase > TWOPI ) left_phase -= TWOPI; - *out++ = (float) sin( left_phase ); - - right_phase += right_phaseInc; - if( right_phase > TWOPI ) right_phase -= TWOPI; - *out++ = (float) sin( right_phase ); - } - - data->left_phase = left_phase; - data->right_phase = right_phase; - return 0; -} -void main( int argc, char **argv ); -void main( int argc, char **argv ) -{ - PaStream *stream; - PaError err; - paTestData data; - int go; - int outLatency = 0; - int minLatency = DEFAULT_BUFFER_SIZE * 2; - int framesPerBuffer; - double sampleRate = 44100.0; - char str[256]; - printf("pa_minlat - Determine minimum latency for your computer.\n"); - printf(" usage: pa_minlat {userBufferSize}\n"); - printf(" for example: pa_minlat 64\n"); - printf("Adjust your stereo until you hear a smooth tone in each speaker.\n"); - printf("Then try to find the smallest number of frames that still sounds smooth.\n"); - printf("Note that the sound will stop momentarily when you change the number of buffers.\n"); - - /* Get bufferSize from command line. */ - framesPerBuffer = ( argc > 1 ) ? atol( argv[1] ) : DEFAULT_BUFFER_SIZE; - printf("Frames per buffer = %d\n", framesPerBuffer ); - - data.left_phase = data.right_phase = 0.0; - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - outLatency = sampleRate * 200.0 / 1000.0; // 200 msec - - /* Try different numBuffers in a loop. */ - go = 1; - while( go ) - { - - printf("Latency = %d frames = %6.1f msec.\n", outLatency, - (outLatency * 1000.0 / sampleRate) ); - err = Pa_OpenStream( - &stream, - paNoDevice, - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - 0, - NULL, - Pa_GetDefaultOutputDevice(), /* default output device */ - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - outLatency, - NULL, - sampleRate, - framesPerBuffer, - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - paminlatCallback, - &data ); - if( err != paNoError ) goto error; - if( stream == NULL ) goto error; - - /* Start audio. */ - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - /* Ask user for a new nlatency. */ - printf("\nMove windows around to see if the sound glitches.\n"); - printf("Latency currently %d, enter new number, or 'q' to quit: ", outLatency ); - gets( str ); - if( str[0] == 'q' ) go = 0; - else - { - outLatency = atol( str ); - if( outLatency < minLatency ) - { - printf( "Latency below minimum of %d! Set to minimum!!!\n", minLatency ); - outLatency = minLatency; - } - } - /* Stop sound until ENTER hit. */ - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - } - printf("A good setting for latency would be somewhat higher than\n"); - printf("the minimum latency that worked.\n"); - printf("PortAudio: Test finished.\n"); - Pa_Terminate(); - return; -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 ) ); -} diff --git a/pd/portaudio/pa_tests/paqa_devs.c b/pd/portaudio/pa_tests/paqa_devs.c deleted file mode 100644 index 904a6082..00000000 --- a/pd/portaudio/pa_tests/paqa_devs.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * $Id: paqa_devs.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * paqa_devs.c - * Self Testing Quality Assurance app for PortAudio - * Try to open each device and run through all the - * possible configurations. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#include "pa_trace.h" -/****************************************** Definitions ***********/ -#define MODE_INPUT (0) -#define MODE_OUTPUT (1) -typedef struct PaQaData -{ - unsigned long framesLeft; - int numChannels; - int bytesPerSample; - int mode; - short sawPhase; - PaSampleFormat format; -} -PaQaData; -/****************************************** Prototypes ***********/ -static void TestDevices( int mode ); -static void TestFormats( int mode, PaDeviceID deviceID, double sampleRate, - int numChannels ); -static int TestAdvance( int mode, PaDeviceID deviceID, double sampleRate, - int numChannels, PaSampleFormat format ); -static int QaCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ); -/****************************************** Globals ***********/ -static int gNumPassed = 0; -static int gNumFailed = 0; -/****************************************** Macros ***********/ -/* Print ERROR if it fails. Tally success or failure. */ -/* Odd do-while wrapper seems to be needed for some compilers. */ -#define EXPECT(_exp) \ - do \ - { \ - if ((_exp)) {\ - /* printf("SUCCESS for %s\n", #_exp ); */ \ - gNumPassed++; \ - } \ - else { \ - printf("ERROR - 0x%x - %s for %s\n", result, \ - ((result == 0) ? "-" : Pa_GetErrorText(result)), \ - #_exp ); \ - gNumFailed++; \ - goto error; \ - } \ - } while(0) -/*******************************************************************/ -/* This routine will be called by the PortAudio engine when audio is needed. -** It may be called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int QaCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - unsigned long i; - short phase; - PaQaData *data = (PaQaData *) userData; - (void) inputBuffer; - (void) outTime; - - /* Play simle sawtooth wave. */ - if( data->mode == MODE_OUTPUT ) - { - phase = data->sawPhase; - switch( data->format ) - { - case paFloat32: - { - float *out = (float *) outputBuffer; - for( i=0; i<framesPerBuffer; i++ ) - { - phase += 0x123; - *out++ = (float) (phase * (1.0 / 32768.0)); - if( data->numChannels == 2 ) - { - *out++ = (float) (phase * (1.0 / 32768.0)); - } - } - } - break; - - case paInt32: - { - int *out = (int *) outputBuffer; - for( i=0; i<framesPerBuffer; i++ ) - { - phase += 0x123; - *out++ = ((int) phase ) << 16; - if( data->numChannels == 2 ) - { - *out++ = ((int) phase ) << 16; - } - } - } - break; - case paInt16: - { - short *out = (short *) outputBuffer; - for( i=0; i<framesPerBuffer; i++ ) - { - phase += 0x123; - *out++ = phase; - if( data->numChannels == 2 ) - { - *out++ = phase; - } - } - } - break; - - default: - { - unsigned char *out = (unsigned char *) outputBuffer; - unsigned long numBytes = framesPerBuffer * data->numChannels * data->bytesPerSample; - for( i=0; i<numBytes; i++ ) - { - *out++ = 0; - } - } - break; - } - data->sawPhase = phase; - } - /* Are we through yet? */ - if( data->framesLeft > framesPerBuffer ) - { - AddTraceMessage("QaCallback: running. framesLeft", data->framesLeft ); - data->framesLeft -= framesPerBuffer; - return 0; - } - else - { - AddTraceMessage("QaCallback: DONE! framesLeft", data->framesLeft ); - data->framesLeft = 0; - return 1; - } -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PaError result; - EXPECT( ((result=Pa_Initialize()) == 0) ); - printf("Test OUTPUT ---------------\n"); - TestDevices( MODE_OUTPUT ); - printf("Test INPUT ---------------\n"); - TestDevices( MODE_INPUT ); -error: - Pa_Terminate(); - printf("QA Report: %d passed, %d failed.\n", gNumPassed, gNumFailed ); -} -/******************************************************************* -* Try each output device, through its full range of capabilities. */ -static void TestDevices( int mode ) -{ - int id,jc,kr; - int maxChannels; - const PaDeviceInfo *pdi; - int numDevices = Pa_CountDevices(); - /* Iterate through all devices. */ - for( id=0; id<numDevices; id++ ) - { - pdi = Pa_GetDeviceInfo( id ); - /* Try 1 to maxChannels on each device. */ - maxChannels = ( mode == MODE_INPUT ) ? pdi->maxInputChannels : pdi->maxOutputChannels; - for( jc=1; jc<=maxChannels; jc++ ) - { - printf("Name = %s\n", pdi->name ); - /* Try each legal sample rate. */ - if( pdi->numSampleRates == -1 ) - { - double low, high; - low = pdi->sampleRates[0]; - high = pdi->sampleRates[1]; - if( low < 8000.0 ) low = 8000.0; - TestFormats( mode, id, low, jc ); -#define TESTSR(sr) {if(((sr)>=low) && ((sr)<=high)) TestFormats( mode, id, (sr), jc ); } - - TESTSR(11025.0); - TESTSR(22050.0); - TESTSR(44100.0); - TestFormats( mode, id, high, jc ); - } - else - { - for( kr=0; kr<pdi->numSampleRates; kr++ ) - { - TestFormats( mode, id, pdi->sampleRates[kr], jc ); - } - } - } - } -} -/*******************************************************************/ -static void TestFormats( int mode, PaDeviceID deviceID, double sampleRate, - int numChannels ) -{ - TestAdvance( mode, deviceID, sampleRate, numChannels, paFloat32 ); /* */ - TestAdvance( mode, deviceID, sampleRate, numChannels, paInt16 ); /* */ - TestAdvance( mode, deviceID, sampleRate, numChannels, paInt32 ); /* */ - /* TestAdvance( mode, deviceID, sampleRate, numChannels, paInt24 ); */ -} -/*******************************************************************/ -static int TestAdvance( int mode, PaDeviceID deviceID, double sampleRate, - int numChannels, PaSampleFormat format ) -{ - PortAudioStream *stream = NULL; - PaError result; - PaQaData myData; -#define FRAMES_PER_BUFFER (64) - printf("------ TestAdvance: %s, device = %d, rate = %g, numChannels = %d, format = %d -------\n", - ( mode == MODE_INPUT ) ? "INPUT" : "OUTPUT", - deviceID, sampleRate, numChannels, format); - /* Setup data for synthesis thread. */ - myData.framesLeft = (unsigned long) (sampleRate * 100); /* 100 seconds */ - myData.numChannels = numChannels; - myData.mode = mode; - myData.format = format; - switch( format ) - { - case paFloat32: - case paInt32: - case paInt24: - myData.bytesPerSample = 4; - break; - case paPackedInt24: - myData.bytesPerSample = 3; - break; - default: - myData.bytesPerSample = 2; - break; - } - EXPECT( ((result = Pa_OpenStream( - &stream, - ( mode == MODE_INPUT ) ? deviceID : paNoDevice, - ( mode == MODE_INPUT ) ? numChannels : 0, - format, - NULL, - ( mode == MODE_OUTPUT ) ? deviceID : paNoDevice, - ( mode == MODE_OUTPUT ) ? numChannels : 0, - format, - NULL, - sampleRate, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - QaCallback, - &myData ) - ) == 0) ); - if( stream ) - { - PaTimestamp oldStamp, newStamp; - unsigned long oldFrames; - int minDelay = ( mode == MODE_INPUT ) ? 1000 : 400; - int minNumBuffers = Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, sampleRate ); - int msec = (int) ((minNumBuffers * 3 * 1000.0 * FRAMES_PER_BUFFER) / sampleRate); - if( msec < minDelay ) msec = minDelay; - printf("msec = %d\n", msec); /**/ - EXPECT( ((result=Pa_StartStream( stream )) == 0) ); - /* Check to make sure PortAudio is advancing timeStamp. */ - result = paNoError; - oldStamp = Pa_StreamTime(stream); - Pa_Sleep(msec); - newStamp = Pa_StreamTime(stream); - printf("oldStamp = %g,newStamp = %g\n", oldStamp, newStamp ); /**/ - EXPECT( (oldStamp < newStamp) ); - /* Check to make sure callback is decrementing framesLeft. */ - oldFrames = myData.framesLeft; - Pa_Sleep(msec); - printf("oldFrames = %d, myData.framesLeft = %d\n", oldFrames, myData.framesLeft ); /**/ - EXPECT( (oldFrames > myData.framesLeft) ); - EXPECT( ((result=Pa_CloseStream( stream )) == 0) ); - stream = NULL; - } -error: - if( stream != NULL ) Pa_CloseStream( stream ); - return result; -} diff --git a/pd/portaudio/pa_tests/paqa_errs.c b/pd/portaudio/pa_tests/paqa_errs.c deleted file mode 100644 index d0738602..00000000 --- a/pd/portaudio/pa_tests/paqa_errs.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * $Id: paqa_errs.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * paqa_devs.c - * Self Testing Quality Assurance app for PortAudio - * Do lots of bad things to test error reporting. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -/****************************************** Definitions ***********/ -#define MODE_INPUT (0) -#define MODE_OUTPUT (1) -#define FRAMES_PER_BUFFER (64) -#define SAMPLE_RATE (44100.0) -#define NUM_BUFFERS (0) -typedef struct PaQaData -{ - unsigned long framesLeft; - int numChannels; - int bytesPerSample; - int mode; -} -PaQaData; -/****************************************** Prototypes ***********/ -static void TestDevices( int mode ); -static void TestFormats( int mode, PaDeviceID deviceID, double sampleRate, - int numChannels ); -static int TestBadOpens( void ); -static int TestBadActions( void ); -static int QaCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ); -/****************************************** Globals ***********/ -static int gNumPassed = 0; -static int gNumFailed = 0; -/****************************************** Macros ***********/ -/* Print ERROR if it fails. Tally success or failure. */ -/* Odd do-while wrapper seems to be needed for some compilers. */ -#define EXPECT(_exp) \ - do \ - { \ - if ((_exp)) {\ - gNumPassed++; \ - } \ - else { \ - printf("\nERROR - 0x%x - %s for %s\n", result, Pa_GetErrorText(result), #_exp ); \ - gNumFailed++; \ - goto error; \ - } \ - } while(0) -#define HOPEFOR(_exp) \ - do \ - { \ - if ((_exp)) {\ - gNumPassed++; \ - } \ - else { \ - printf("\nERROR - 0x%x - %s for %s\n", result, Pa_GetErrorText(result), #_exp ); \ - gNumFailed++; \ - } \ - } while(0) -/*******************************************************************/ -/* This routine will be called by the PortAudio engine when audio is needed. -** It may be called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int QaCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - unsigned long i; - unsigned char *out = (unsigned char *) outputBuffer; - PaQaData *data = (PaQaData *) userData; - (void) inputBuffer; /* Prevent "unused variable" warnings. */ - (void) outTime; - - /* Zero out buffer so we don't hear terrible noise. */ - if( data->mode == MODE_OUTPUT ) - { - unsigned long numBytes = framesPerBuffer * data->numChannels * data->bytesPerSample; - for( i=0; i<numBytes; i++ ) - { - *out++ = 0; - } - } - /* Are we through yet? */ - if( data->framesLeft > framesPerBuffer ) - { - data->framesLeft -= framesPerBuffer; - return 0; - } - else - { - data->framesLeft = 0; - return 1; - } -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PaError result; - EXPECT( ((result=Pa_Initialize()) == 0) ); - TestBadOpens(); - TestBadActions(); -error: - Pa_Terminate(); - printf("QA Report: %d passed, %d failed.\n", gNumPassed, gNumFailed ); - return 0; -} -/*******************************************************************/ -static int TestBadOpens( void ) -{ - PortAudioStream *stream = NULL; - PaError result; - PaQaData myData; - /* Setup data for synthesis thread. */ - myData.framesLeft = (unsigned long) (SAMPLE_RATE * 100); /* 100 seconds */ - myData.numChannels = 1; - myData.mode = MODE_OUTPUT; - HOPEFOR( (/* No devices specified. */ - (result = Pa_OpenStream( - &stream, - paNoDevice, 0, paFloat32, NULL, - paNoDevice, 0, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == paInvalidDeviceId) ); - HOPEFOR( ( /* Out of range input device specified. */ - (result = Pa_OpenStream( - &stream, - Pa_CountDevices(), 0, paFloat32, NULL, - paNoDevice, 0, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == paInvalidDeviceId) ); - - HOPEFOR( ( /* Out of range output device specified. */ - (result = Pa_OpenStream( - &stream, - paNoDevice, 0, paFloat32, NULL, - Pa_CountDevices(), 0, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == paInvalidDeviceId) ); - HOPEFOR( ( /* Zero input channels. */ - (result = Pa_OpenStream( - &stream, - Pa_GetDefaultInputDeviceID(), 0, paFloat32, NULL, - paNoDevice, 0, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == paInvalidChannelCount) ); - HOPEFOR( ( /* Zero output channels. */ - (result = Pa_OpenStream( - &stream, - paNoDevice, 0, paFloat32, NULL, - Pa_GetDefaultOutputDeviceID(), 0, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == paInvalidChannelCount) ); - HOPEFOR( ( /* Nonzero input channels but no device. */ - (result = Pa_OpenStream( - &stream, - Pa_GetDefaultInputDeviceID(), 2, paFloat32, NULL, - paNoDevice, 2, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == paInvalidChannelCount) ); - - HOPEFOR( ( /* Nonzero output channels but no device. */ - (result = Pa_OpenStream( - &stream, - paNoDevice, 2, paFloat32, NULL, - Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == paInvalidChannelCount) ); - HOPEFOR( ( /* NULL stream pointer. */ - (result = Pa_OpenStream( - NULL, - paNoDevice, 0, paFloat32, NULL, - Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == paBadStreamPtr) ); - HOPEFOR( ( /* Low sample rate. */ - (result = Pa_OpenStream( - &stream, - paNoDevice, 0, paFloat32, NULL, - Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, - 1.0, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == paInvalidSampleRate) ); - HOPEFOR( ( /* High sample rate. */ - (result = Pa_OpenStream( - &stream, - paNoDevice, 0, paFloat32, NULL, - Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, - 10000000.0, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == paInvalidSampleRate) ); - HOPEFOR( ( /* NULL callback. */ - (result = Pa_OpenStream( - &stream, - paNoDevice, 0, paFloat32, NULL, - Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - NULL, - &myData ) - ) == paNullCallback) ); - HOPEFOR( ( /* Bad flag. */ - (result = Pa_OpenStream( - &stream, - paNoDevice, 0, paFloat32, NULL, - Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - (1<<3), - QaCallback, - &myData ) - ) == paInvalidFlag) ); - -#if 0 /* FIXME - this is legal for some implementations. */ - HOPEFOR( ( /* Use input device as output device. */ - (result = Pa_OpenStream( - &stream, - paNoDevice, 0, paFloat32, NULL, - Pa_GetDefaultInputDeviceID(), 2, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == paInvalidDeviceId) ); - - HOPEFOR( ( /* Use output device as input device. */ - (result = Pa_OpenStream( - &stream, - Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, - paNoDevice, 0, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == paInvalidDeviceId) ); -#endif - - if( stream != NULL ) Pa_CloseStream( stream ); - return result; -} -/*******************************************************************/ -static int TestBadActions( void ) -{ - PortAudioStream *stream = NULL; - PaError result; - PaQaData myData; - /* Setup data for synthesis thread. */ - myData.framesLeft = (unsigned long) (SAMPLE_RATE * 100); /* 100 seconds */ - myData.numChannels = 1; - myData.mode = MODE_OUTPUT; - /* Default output. */ - EXPECT( ((result = Pa_OpenStream( - &stream, - paNoDevice, 0, paFloat32, NULL, - Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, - SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, - paClipOff, - QaCallback, - &myData ) - ) == 0) ); - HOPEFOR( ((result = Pa_StartStream( NULL )) == paBadStreamPtr) ); - HOPEFOR( ((result = Pa_StopStream( NULL )) == paBadStreamPtr) ); - HOPEFOR( ((result = Pa_StreamActive( NULL )) == paBadStreamPtr) ); - HOPEFOR( ((result = Pa_CloseStream( NULL )) == paBadStreamPtr) ); - HOPEFOR( ((result = (PaError)Pa_StreamTime( NULL )) != 0) ); - HOPEFOR( ((result = (PaError)Pa_GetCPULoad( NULL )) != 0) ); -error: - if( stream != NULL ) Pa_CloseStream( stream ); - return result; -} diff --git a/pd/portaudio/pa_tests/patest1.c b/pd/portaudio/pa_tests/patest1.c deleted file mode 100644 index 1f969436..00000000 --- a/pd/portaudio/pa_tests/patest1.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - $Id: patest1.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - patest1.c - Ring modulate the audio input with a sine wave for 20 seconds - using the Portable Audio api - Author: Ross Bencina <rossb@audiomulch.com> - Modifications: - April 5th, 2001 - PLB - Check for NULL inputBuffer. -*/ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#ifndef M_PI -#define M_PI (3.14159265) -#endif -typedef struct -{ - float sine[100]; - int phase; - int sampsToGo; -} -patest1data; -static int patest1Callback( void *inputBuffer, void *outputBuffer, - unsigned long bufferFrames, - PaTime outTime, void *userData ) -{ - patest1data *data = (patest1data*)userData; - float *in = (float*)inputBuffer; - float *out = (float*)outputBuffer; - int framesToCalc = bufferFrames; - unsigned long i; - int finished = 0; - /* Check to see if any input data is available. */ - if(inputBuffer == NULL) return 0; - if( data->sampsToGo < bufferFrames ) - { - framesToCalc = data->sampsToGo; - finished = 1; - } - for( i=0; i<framesToCalc; i++ ) - { - *out++ = *in++ * data->sine[data->phase]; /* left */ - *out++ = *in++ * data->sine[data->phase++]; /* right */ - if( data->phase >= 100 ) - data->phase = 0; - } - data->sampsToGo -= framesToCalc; - /* zero remainder of final buffer if not already done */ - for( ; i<bufferFrames; i++ ) - { - *out++ = 0; /* left */ - *out++ = 0; /* right */ - } - return finished; -} -int main(int argc, char* argv[]); -int main(int argc, char* argv[]) -{ - PaStream *stream; - PaError err; - patest1data data; - int i; - int inputDevice = Pa_GetDefaultInputDevice(); - int outputDevice = Pa_GetDefaultOutputDevice(); - /* initialise sinusoidal wavetable */ - for( i=0; i<100; i++ ) - data.sine[i] = sin( ((double)i/100.) * M_PI * 2. ); - data.phase = 0; - data.sampsToGo = 44100 * 20; // 20 seconds - /* initialise portaudio subsytem */ - Pa_Initialize(); - err = Pa_OpenStream( - &stream, - inputDevice, - 2, /* stereo input */ - paFloat32, /* 32 bit floating point input */ - NULL, - outputDevice, - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - NULL, - 44100., - 512, /* small buffers */ - 0, /* let PA determine number of buffers */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patest1Callback, - &data ); - if( err == paNoError ) - { - err = Pa_StartStream( stream ); - printf( "Press any key to end.\n" ); - getc( stdin ); //wait for input before exiting - Pa_AbortStream( stream ); - - printf( "Waiting for stream to complete...\n" ); - - while( Pa_IsStreamActive( stream ) ) - Pa_Sleep(1000); /* sleep until playback has finished */ - - err = Pa_CloseStream( stream ); - } - else - { - fprintf( stderr, "An error occured while opening the portaudio stream\n" ); - if( err == paHostError ) - { - fprintf( stderr, "Host error number: %d\n", Pa_GetHostError() ); - } - else - { - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error text: %s\n", Pa_GetErrorText( err ) ); - } - } - Pa_Terminate(); - printf( "bye\n" ); - - return 0; -} diff --git a/pd/portaudio/pa_tests/patest_buffer.c b/pd/portaudio/pa_tests/patest_buffer.c deleted file mode 100644 index dbc55913..00000000 --- a/pd/portaudio/pa_tests/patest_buffer.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * $Id: patest_buffer.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_buffer.c - * Test opening streams with different buffer sizes. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include "portaudio.h" -#define NUM_SECONDS (1) -#define SAMPLE_RATE (44100) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TABLE_SIZE (200) - -#define BUFFER_TABLE 9 -long buffer_table[] = {200,256,500,512,600, 723, 1000, 1024, 2345}; - -typedef struct -{ - short sine[TABLE_SIZE]; - int left_phase; - int right_phase; - unsigned int sampsToGo; -} -paTestData; -PaError TestOnce( int buffersize ); - -static int patest1Callback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ); -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patest1Callback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - short *out = (short*)outputBuffer; - unsigned int i; - int finished = 0; - (void) inputBuffer; /* Prevent "unused variable" warnings. */ - (void) outTime; - - if( data->sampsToGo < framesPerBuffer ) - { - /* final buffer... */ - - for( i=0; i<data->sampsToGo; i++ ) - { - *out++ = data->sine[data->left_phase]; /* left */ - *out++ = data->sine[data->right_phase]; /* right */ - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - /* zero remainder of final buffer */ - for( ; i<framesPerBuffer; i++ ) - { - *out++ = 0; /* left */ - *out++ = 0; /* right */ - } - - finished = 1; - } - else - { - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = data->sine[data->left_phase]; /* left */ - *out++ = data->sine[data->right_phase]; /* right */ - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - data->sampsToGo -= framesPerBuffer; - } - return finished; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - int i; - PaError err; - printf("Test opening streams with different buffer sizes\n\n"); - - for (i = 0 ; i < BUFFER_TABLE; i++) - { - printf("Buffer size %d\n", buffer_table[i]); - err = TestOnce(buffer_table[i]); - if( err < 0 ) return 0; - - } -} - - -PaError TestOnce( int buffersize ) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int i; - int totalSamps; - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - data.sine[i] = (short) (32767.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. )); - } - data.left_phase = data.right_phase = 0; - data.sampsToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */ - err = Pa_Initialize(); - if( err != paNoError ) goto error; - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - paInt16, /* sample format */ - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 2, /* stereo output */ - paInt16, /* sample format */ - NULL, - SAMPLE_RATE, - buffersize, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patest1Callback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - printf("Waiting for sound to finish.\n"); - Pa_Sleep(1000); - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - return paNoError; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_clip.c b/pd/portaudio/pa_tests/patest_clip.c deleted file mode 100644 index c19bf3fe..00000000 --- a/pd/portaudio/pa_tests/patest_clip.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * $Id: patest_clip.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_clip.c - * Play a sine wave using the Portable Audio api for several seconds - * at an amplitude that would require clipping. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#define NUM_SECONDS (4) -#define SAMPLE_RATE (44100) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TABLE_SIZE (200) -typedef struct paTestData -{ - float sine[TABLE_SIZE]; - float amplitude; - int left_phase; - int right_phase; -} -paTestData; -PaError PlaySine( paTestData *data, unsigned long flags, float amplitude ); -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int sineCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - float amplitude = data->amplitude; - unsigned int i; - (void) inputBuffer; /* Prevent "unused variable" warnings. */ - (void) outTime; - - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = amplitude * data->sine[data->left_phase]; /* left */ - *out++ = amplitude * data->sine[data->right_phase]; /* right */ - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - return 0; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PaError err; - paTestData DATA; - int i; - printf("PortAudio Test: output sine wave with and without clipping.\n"); - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - DATA.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - printf("\nHalf amplitude. Should sound like sine wave.\n"); fflush(stdout); - err = PlaySine( &DATA, paClipOff | paDitherOff, 0.5f ); - if( err < 0 ) goto error; - printf("\nFull amplitude. Should sound like sine wave.\n"); fflush(stdout); - err = PlaySine( &DATA, paClipOff | paDitherOff, 0.999f ); - if( err < 0 ) goto error; - printf("\nOver range with clipping and dithering turned OFF. Should sound very nasty.\n"); - fflush(stdout); - err = PlaySine( &DATA, paClipOff | paDitherOff, 1.1f ); - if( err < 0 ) goto error; - printf("\nOver range with clipping and dithering turned ON. Should sound smoother than previous.\n"); - fflush(stdout); - err = PlaySine( &DATA, paNoFlag, 1.1f ); - if( err < 0 ) goto error; - printf("\nOver range with paClipOff but dithering ON.\n" - "That forces clipping ON so it should sound the same as previous.\n"); - fflush(stdout); - err = PlaySine( &DATA, paClipOff, 1.1f ); - if( err < 0 ) goto error; - return 0; -error: - 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; -} -/*****************************************************************************/ -PaError PlaySine( paTestData *data, unsigned long flags, float amplitude ) -{ - PortAudioStream *stream; - PaError err; - data->left_phase = data->right_phase = 0; - data->amplitude = amplitude; - err = Pa_Initialize(); - if( err != paNoError ) goto error; - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - 1024, - 0, /* number of buffers, if zero then use default minimum */ - flags, /* we won't output out of range samples so don't bother clipping them */ - sineCallback, - data ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - Pa_Sleep( NUM_SECONDS * 1000 ); - printf("CPULoad = %8.6f\n", Pa_GetCPULoad( stream ) ); - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - return paNoError; -error: - return err; -} diff --git a/pd/portaudio/pa_tests/patest_dither.c b/pd/portaudio/pa_tests/patest_dither.c deleted file mode 100644 index 2ab11e7b..00000000 --- a/pd/portaudio/pa_tests/patest_dither.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * $Id: patest_dither.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_dither.c - * Attempt to hear difference between dithered and non-dithered signal. - * This only has an effect if the native format is 16 bit. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#define NUM_SECONDS (4) -#define SAMPLE_RATE (44100) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TABLE_SIZE (200) -typedef struct paTestData -{ - float sine[TABLE_SIZE]; - float amplitude; - int left_phase; - int right_phase; -} -paTestData; -PaError PlaySine( paTestData *data, PaStreamFlags flags, float amplitude ); -static int sineCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ); -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int sineCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - float amplitude = data->amplitude; - unsigned int i; - (void) outTime; - (void) inputBuffer; - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = amplitude * data->sine[data->left_phase]; /* left */ - *out++ = amplitude * data->sine[data->right_phase]; /* right */ - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - return 0; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PaError err; - paTestData DATA; - int i; - float amplitude = 32.0 / (1<<15); - printf("PortAudio Test: output EXTREMELY QUIET sine wave with and without dithering.\n"); - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - DATA.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - printf("\nNo treatment..\n"); fflush(stdout); - err = PlaySine( &DATA, paClipOff | paDitherOff, amplitude ); - if( err < 0 ) goto error; - printf("\nClip.\n"); - fflush(stdout); - err = PlaySine( &DATA, paDitherOff, amplitude ); - if( err < 0 ) goto error; - printf("\nClip and Dither.\n"); - fflush(stdout); - err = PlaySine( &DATA, paNoFlag, amplitude ); - if( err < 0 ) goto error; - return 0; -error: - 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; -} -/*****************************************************************************/ -PaError PlaySine( paTestData *data, PaStreamFlags flags, float amplitude ) -{ - PortAudioStream *stream; - PaError err; - data->left_phase = data->right_phase = 0; - data->amplitude = amplitude; - err = Pa_Initialize(); - if( err != paNoError ) goto error; - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - 1024, - 0, /* number of buffers, if zero then use default minimum */ - flags, /* we won't output out of range samples so don't bother clipping them */ - sineCallback, - (void *)data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - Pa_Sleep( NUM_SECONDS * 1000 ); - printf("CPULoad = %8.6f\n", Pa_GetCPULoad( stream ) ); - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - return paNoError; -error: - return err; -} diff --git a/pd/portaudio/pa_tests/patest_hang.c b/pd/portaudio/pa_tests/patest_hang.c deleted file mode 100644 index b97727ba..00000000 --- a/pd/portaudio/pa_tests/patest_hang.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * $Id: patest_hang.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * Play a sine then hang audio callback to test watchdog. - * - * Authors: - * Ross Bencina <rossb@audiomulch.com> - * Phil Burk <philburk@softsynth.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - - -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (1024) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TWOPI (M_PI * 2.0) - -typedef struct paTestData -{ - int sleepFor; - double phase; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned long i; - int finished = 0; - double phaseInc = 0.02; - double phase = data->phase; - - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - for( i=0; i<framesPerBuffer; i++ ) - { - phase += phaseInc; - if( phase > TWOPI ) phase -= TWOPI; - /* This is not a very efficient way to calc sines. */ - *out++ = (float) sin( phase ); /* mono */ - } - - if( data->sleepFor > 0 ) - { - Pa_Sleep( data->sleepFor ); - } - - data->phase = phase; - return finished; -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - int i; - paTestData data = {0}; - - printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", - SAMPLE_RATE, FRAMES_PER_BUFFER ); - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 1, /* mono output */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - -/* Gradually increase sleep time. */ - for( i=0; i<10000; i+= 1000 ) - { - printf("Sleep for %d milliseconds in audio callback.\n", i ); - data.sleepFor = i; - Pa_Sleep( ((i<1000) ? 1000 : i) ); - } - - printf("Suffer for 10 seconds.\n"); - Pa_Sleep( 10000 ); - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_latency.c b/pd/portaudio/pa_tests/patest_latency.c deleted file mode 100644 index 261a005c..00000000 --- a/pd/portaudio/pa_tests/patest_latency.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * $Id: patest_latency.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * Hear the latency caused by big buffers. - * Play a sine wave and change frequency based on letter input. - * - * Author: Phil Burk <philburk@softsynth.com>, and Darren Gibbs - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (64) - -#if 0 -#define MIN_LATENCY_MSEC (2000) -#define NUM_BUFFERS ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000)) -#else -#define NUM_BUFFERS (0) -#endif - -#define MIN_FREQ (100.0f) -#define CalcPhaseIncrement(freq) ((freq)/SAMPLE_RATE) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TABLE_SIZE (400) -typedef struct -{ - float sine[TABLE_SIZE + 1]; // add one for guard point for interpolation - float phase_increment; - float left_phase; - float right_phase; -} -paTestData; -float LookupSine( paTestData *data, float phase ); -/* Convert phase between and 1.0 to sine value - * using linear interpolation. - */ -float LookupSine( paTestData *data, float phase ) -{ - float fIndex = phase*TABLE_SIZE; - int index = (int) fIndex; - float fract = fIndex - index; - float lo = data->sine[index]; - float hi = data->sine[index+1]; - float val = lo + fract*(hi-lo); - return val; -} -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - int i; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = LookupSine(data, data->left_phase); /* left */ - *out++ = LookupSine(data, data->right_phase); /* right */ - data->left_phase += data->phase_increment; - if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f; - data->right_phase += (data->phase_increment * 1.5f); /* fifth above */ - if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f; - } - return 0; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int i; - int done = 0; - printf("PortAudio Test: enter letter then hit ENTER. numBuffers = %d\n", NUM_BUFFERS ); - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - data.sine[i] = 0.90f * (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - data.sine[TABLE_SIZE] = data.sine[0]; // set guard point - data.left_phase = data.right_phase = 0.0; - data.phase_increment = CalcPhaseIncrement(MIN_FREQ); - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE ); - err = Pa_OpenStream( - &stream, - paNoDevice, - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - OUTPUT_DEVICE, - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - NUM_BUFFERS, /* number of buffers, if zero then use default minimum */ - paClipOff|paDitherOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - printf("Play ASCII keyboard. Hit 'q' to stop. (Use RETURN key on Mac)\n"); - fflush(stdout); - while ( !done ) - { - float freq; - int index; - char c; - do - { - c = getchar(); - } - while( c < ' '); /* Strip white space and control chars. */ - - if( c == 'q' ) done = 1; - index = c % 26; - freq = MIN_FREQ + (index * 40.0); - data.phase_increment = CalcPhaseIncrement(freq); - } - printf("Call Pa_StopStream()\n"); - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_leftright.c b/pd/portaudio/pa_tests/patest_leftright.c deleted file mode 100644 index d23c8b2c..00000000 --- a/pd/portaudio/pa_tests/patest_leftright.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * $Id: patest_leftright.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_leftright.c - * Play different tone sine waves that alternate between left and right channel. - * The low tone should be on the left channel. - * - * Authors: - * Ross Bencina <rossb@audiomulch.com> - * Phil Burk <philburk@softsynth.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#define NUM_SECONDS (8) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (512) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TABLE_SIZE (200) -typedef struct -{ - float sine[TABLE_SIZE]; - int left_phase; - int right_phase; - int toggle; - int countDown; -} -paTestData; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned long i; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - for( i=0; i<framesPerBuffer; i++ ) - { - if( data->toggle ) - { - *out++ = data->sine[data->left_phase]; /* left */ - *out++ = 0; /* right */ - } - else - { - *out++ = 0; /* left */ - *out++ = data->sine[data->right_phase]; /* right */ - } - - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - - if( data->countDown < 0 ) - { - data->countDown = SAMPLE_RATE; - data->toggle = !data->toggle; - } - data->countDown -= framesPerBuffer; - - return finished; -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int i; - int timeout; - - printf("Play different tone sine waves that alternate between left and right channel.\n"); - printf("The low tone should be on the left channel.\n"); - - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - data.left_phase = data.right_phase = data.toggle = 0; - data.countDown = SAMPLE_RATE; - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Play for several seconds.\n"); - timeout = NUM_SECONDS * 4; - while( timeout > 0 ) - { - Pa_Sleep( 300 ); - timeout -= 1; - } - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_longsine.c b/pd/portaudio/pa_tests/patest_longsine.c deleted file mode 100644 index cc48c44a..00000000 --- a/pd/portaudio/pa_tests/patest_longsine.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * $Id: patest_longsine.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_longsine.c - * Play a sine wave using the Portable Audio api until ENTER hit. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define SAMPLE_RATE (44100) - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - -#define TABLE_SIZE (200) -typedef struct -{ - float sine[TABLE_SIZE]; - int left_phase; - int right_phase; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned int i; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = data->sine[data->left_phase]; /* left */ - *out++ = data->sine[data->right_phase]; /* right */ - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - return 0; -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int i; - printf("PortAudio Test: output sine wave.\n"); - - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - data.left_phase = data.right_phase = 0; - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - 256, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Hit ENTER to stop program.\n"); - getchar(); - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - - printf("Test finished.\n"); - return err; - -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_many.c b/pd/portaudio/pa_tests/patest_many.c deleted file mode 100644 index f42efb52..00000000 --- a/pd/portaudio/pa_tests/patest_many.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * $Id: patest_many.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_many.c - * Start and stop the PortAudio Driver multiple times. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include "portaudio.h" -#define NUM_SECONDS (1) -#define SAMPLE_RATE (44100) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TABLE_SIZE (200) -typedef struct -{ - short sine[TABLE_SIZE]; - int left_phase; - int right_phase; - unsigned int sampsToGo; -} -paTestData; -PaError TestOnce( void ); -static int patest1Callback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ); -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patest1Callback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - short *out = (short*)outputBuffer; - unsigned int i; - int finished = 0; - (void) inputBuffer; /* Prevent "unused variable" warnings. */ - (void) outTime; - - if( data->sampsToGo < framesPerBuffer ) - { - /* final buffer... */ - - for( i=0; i<data->sampsToGo; i++ ) - { - *out++ = data->sine[data->left_phase]; /* left */ - *out++ = data->sine[data->right_phase]; /* right */ - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - /* zero remainder of final buffer */ - for( ; i<framesPerBuffer; i++ ) - { - *out++ = 0; /* left */ - *out++ = 0; /* right */ - } - - finished = 1; - } - else - { - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = data->sine[data->left_phase]; /* left */ - *out++ = data->sine[data->right_phase]; /* right */ - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - data->sampsToGo -= framesPerBuffer; - } - return finished; -} -/*******************************************************************/ -#ifdef MACINTOSH -int main(void); -int main(void) -{ - int i; - PaError err; - int numLoops = 10; - printf("Loop %d times.\n", numLoops ); - for( i=0; i<numLoops; i++ ) - { - printf("Loop %d out of %d.\n", i+1, numLoops ); - err = TestOnce(); - if( err < 0 ) return 0; - } -} -#else -int main(int argc, char **argv); -int main(int argc, char **argv) -{ - PaError err; - int i, numLoops = 10; - if( argc > 1 ) - { - numLoops = atoi(argv[1]); - } - for( i=0; i<numLoops; i++ ) - { - printf("Loop %d out of %d.\n", i+1, numLoops ); - err = TestOnce(); - if( err < 0 ) return 1; - } - printf("Test complete.\n"); - return 0; -} -#endif -PaError TestOnce( void ) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int i; - int totalSamps; - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - data.sine[i] = (short) (32767.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. )); - } - data.left_phase = data.right_phase = 0; - data.sampsToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */ - err = Pa_Initialize(); - if( err != paNoError ) goto error; - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - paInt16, /* sample format */ - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 2, /* stereo output */ - paInt16, /* sample format */ - NULL, - SAMPLE_RATE, - 1024, /* frames per buffer */ - 8, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patest1Callback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - printf("Waiting for sound to finish.\n"); - Pa_Sleep(1000); - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - return paNoError; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_maxsines.c b/pd/portaudio/pa_tests/patest_maxsines.c deleted file mode 100644 index 9fcd7ba8..00000000 --- a/pd/portaudio/pa_tests/patest_maxsines.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * $Id: patest_maxsines.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_maxsines.c - * How many sine waves can we calculate and play in less than 80% CPU Load. - * - * Authors: - * Ross Bencina <rossb@audiomulch.com> - * Phil Burk <philburk@softsynth.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define MAX_SINES (500) -#define MAX_USAGE (0.8) -#define SAMPLE_RATE (44100) -#define FREQ_TO_PHASE_INC(freq) (freq/(float)SAMPLE_RATE) - -#define MIN_PHASE_INC FREQ_TO_PHASE_INC(200.0f) -#define MAX_PHASE_INC (MIN_PHASE_INC * (1 << 5)) - -#define FRAMES_PER_BUFFER (512) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TWOPI (M_PI * 2.0) - -#define TABLE_SIZE (512) - -typedef struct paTestData -{ - int numSines; - float sine[TABLE_SIZE + 1]; /* add one for guard point for interpolation */ - float phases[MAX_SINES]; -} -paTestData; - -/* Convert phase between and 1.0 to sine value - * using linear interpolation. - */ -float LookupSine( paTestData *data, float phase ); -float LookupSine( paTestData *data, float phase ) -{ - float fIndex = phase*TABLE_SIZE; - int index = (int) fIndex; - float fract = fIndex - index; - float lo = data->sine[index]; - float hi = data->sine[index+1]; - float val = lo + fract*(hi-lo); - return val; -} - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - float outSample; - float scaler; - int numForScale; - unsigned long i; - int j; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - -/* Detemine amplitude scaling factor */ - numForScale = data->numSines; - if( numForScale < 8 ) numForScale = 8; /* prevent pops at beginning */ - scaler = 1.0f / numForScale; - - for( i=0; i<framesPerBuffer; i++ ) - { - float output = 0.0; - float phaseInc = MIN_PHASE_INC; - float phase; - for( j=0; j<data->numSines; j++ ) - { - /* Advance phase of next oscillator. */ - phase = data->phases[j]; - phase += phaseInc; - if( phase >= 1.0 ) phase -= 1.0; - - output += LookupSine(data, phase); - data->phases[j] = phase; - - phaseInc *= 1.02f; - if( phaseInc > MAX_PHASE_INC ) phaseInc = MIN_PHASE_INC; - } - - outSample = (float) (output * scaler); - *out++ = outSample; /* Left */ - *out++ = outSample; /* Right */ - } - return finished; -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - int i; - PaStream *stream; - PaError err; - paTestData data = {0}; - double load; - printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); - - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - data.sine[TABLE_SIZE] = data.sine[0]; /* set guard point */ - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - err = Pa_OpenStream( - &stream, - paNoDevice, - 0, /* no input */ - paFloat32, - 0, /* default latency */ - NULL, - Pa_GetDefaultOutputDevice(), /* default output device */ - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - 0, /* default latency */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - -/* Play an increasing number of sine waves until we hit MAX_USAGE */ - do - { - data.numSines++; - Pa_Sleep( 200 ); - - load = Pa_GetStreamCpuLoad( stream ); - printf("numSines = %d, CPU load = %f\n", data.numSines, load ); - fflush( stdout ); - } - while( (load < MAX_USAGE) && (data.numSines < MAX_SINES) ); - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_multi_sine.c b/pd/portaudio/pa_tests/patest_multi_sine.c deleted file mode 100644 index 2b78e932..00000000 --- a/pd/portaudio/pa_tests/patest_multi_sine.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * $Id: patest_multi_sine.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_multi_out.c - * Play a different sine wave on each channels, - * using the Portable Audio api. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDevice()) -//#define NON_INTERLEAVED -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (0) // take what we get(256) -#define FREQ_INCR (300.0 / SAMPLE_RATE) -#define MAX_CHANNELS (64) - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - -typedef struct -{ - int numChannels; - double phases[MAX_CHANNELS]; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - float **outputs = (float**)outputBuffer; - -#ifdef NON_INTERLEAVED - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - int frameIndex, channelIndex; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ ) - { - for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ ) - { - /* Output sine wave on every channel. */ - outputs[channelIndex][frameIndex] = (float) sin(data->phases[channelIndex]); - - /* Play each channel at a higher frequency. */ - data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex); - if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI); - } - } - -#else /* interleaved version */ - - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - int frameIndex, channelIndex; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ ) - { - for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ ) - { - /* Output sine wave on every channel. */ - *out++ = (float) sin(data->phases[channelIndex]); - - /* Play each channel at a higher frequency. */ - data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex); - if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI); - } - } -#endif /* NON_INTERLEAVED */ - return 0; -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PaStream *stream; - PaError err; - const PaDeviceInfo *pdi; - paTestData data = {0}; - printf("PortAudio Test: output sine wave on each channel.\n" ); - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE ); - data.numChannels = pdi->maxOutputChannels; - if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS; - printf("Number of Channels = %d\n", data.numChannels ); - - err = Pa_OpenStream( - &stream, - paNoDevice, /* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - 0, /* default input latency */ - NULL, - OUTPUT_DEVICE, - data.numChannels, -#ifdef NON_INTERLEAVED - paFloat32 | paNonInterleaved, /* 32 bit floating point output */ -#else - paFloat32, -#endif - 0, /* default output latency */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Hit ENTER to stop sound.\n"); - getchar(); - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - - Pa_CloseStream( stream ); - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_pink.c b/pd/portaudio/pa_tests/patest_pink.c deleted file mode 100644 index 7a3e29cd..00000000 --- a/pd/portaudio/pa_tests/patest_pink.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * $Id: patest_pink.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - patest_pink.c - Generate Pink Noise using Gardner method. - Optimization suggested by James McCartney uses a tree - to select which random value to replace. - x x x x x x x x x x x x x x x x - x x x x x x x x - x x x x - x x - x - Tree is generated by counting trailing zeros in an increasing index. - When the index is zero, no random number is selected. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#define PINK_MAX_RANDOM_ROWS (30) -#define PINK_RANDOM_BITS (24) -#define PINK_RANDOM_SHIFT ((sizeof(long)*8)-PINK_RANDOM_BITS) -typedef struct -{ - long pink_Rows[PINK_MAX_RANDOM_ROWS]; - long pink_RunningSum; /* Used to optimize summing of generators. */ - int pink_Index; /* Incremented each sample. */ - int pink_IndexMask; /* Index wrapped by ANDing with this mask. */ - float pink_Scalar; /* Used to scale within range of -1.0 to +1.0 */ -} -PinkNoise; -/* Prototypes */ -static unsigned long GenerateRandomNumber( void ); -void InitializePinkNoise( PinkNoise *pink, int numRows ); -float GeneratePinkNoise( PinkNoise *pink ); -/************************************************************/ -/* Calculate pseudo-random 32 bit number based on linear congruential method. */ -static unsigned long GenerateRandomNumber( void ) -{ - /* Change this seed for different random sequences. */ - static unsigned long randSeed = 22222; - randSeed = (randSeed * 196314165) + 907633515; - return randSeed; -} -/************************************************************/ -/* Setup PinkNoise structure for N rows of generators. */ -void InitializePinkNoise( PinkNoise *pink, int numRows ) -{ - int i; - long pmax; - pink->pink_Index = 0; - pink->pink_IndexMask = (1<<numRows) - 1; - /* Calculate maximum possible signed random value. Extra 1 for white noise always added. */ - pmax = (numRows + 1) * (1<<(PINK_RANDOM_BITS-1)); - pink->pink_Scalar = 1.0f / pmax; - /* Initialize rows. */ - for( i=0; i<numRows; i++ ) pink->pink_Rows[i] = 0; - pink->pink_RunningSum = 0; -} -#define PINK_MEASURE -#ifdef PINK_MEASURE -float pinkMax = -999.0; -float pinkMin = 999.0; -#endif -/* Generate Pink noise values between -1.0 and +1.0 */ -float GeneratePinkNoise( PinkNoise *pink ) -{ - long newRandom; - long sum; - float output; - /* Increment and mask index. */ - pink->pink_Index = (pink->pink_Index + 1) & pink->pink_IndexMask; - /* If index is zero, don't update any random values. */ - if( pink->pink_Index != 0 ) - { - /* Determine how many trailing zeros in PinkIndex. */ - /* This algorithm will hang if n==0 so test first. */ - int numZeros = 0; - int n = pink->pink_Index; - while( (n & 1) == 0 ) - { - n = n >> 1; - numZeros++; - } - /* Replace the indexed ROWS random value. - * Subtract and add back to RunningSum instead of adding all the random - * values together. Only one changes each time. - */ - pink->pink_RunningSum -= pink->pink_Rows[numZeros]; - newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT; - pink->pink_RunningSum += newRandom; - pink->pink_Rows[numZeros] = newRandom; - } - - /* Add extra white noise value. */ - newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT; - sum = pink->pink_RunningSum + newRandom; - /* Scale to range of -1.0 to 0.9999. */ - output = pink->pink_Scalar * sum; -#ifdef PINK_MEASURE - /* Check Min/Max */ - if( output > pinkMax ) pinkMax = output; - else if( output < pinkMin ) pinkMin = output; -#endif - return output; -} -/*******************************************************************/ -#define PINK_TEST -#ifdef PINK_TEST -/* Context for callback routine. */ -typedef struct -{ - PinkNoise leftPink; - PinkNoise rightPink; - unsigned int sampsToGo; -} -paTestData; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - int finished; - int i; - int numFrames; - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - (void) inputBuffer; /* Prevent "unused variable" warnings. */ - (void) outTime; - - /* Are we almost at end. */ - if( data->sampsToGo < framesPerBuffer ) - { - numFrames = data->sampsToGo; - finished = 1; - } - else - { - numFrames = framesPerBuffer; - finished = 0; - } - for( i=0; i<numFrames; i++ ) - { - *out++ = GeneratePinkNoise( &data->leftPink ); - *out++ = GeneratePinkNoise( &data->rightPink ); - } - data->sampsToGo -= numFrames; - return finished; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int totalSamps; - /* Initialize two pink noise signals with different numbers of rows. */ - InitializePinkNoise( &data.leftPink, 12 ); - InitializePinkNoise( &data.rightPink, 16 ); - /* Look at a few values. */ - { - int i; - float pink; - for( i=0; i<20; i++ ) - { - pink = GeneratePinkNoise( &data.leftPink ); - printf("Pink = %f\n", pink ); - } - } - data.sampsToGo = totalSamps = 8*44100; /* Play for a few seconds. */ - err = Pa_Initialize(); - if( err != paNoError ) goto error; - /* Open a stereo PortAudio stream so we can hear the result. */ - err = Pa_OpenStream( - &stream, - paNoDevice, - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - NULL, - 44100., - 2048, /* 46 msec buffers */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - printf("Waiting for sound to finish.\n"); - while( Pa_StreamActive( stream ) ) - { - Pa_Sleep(100); /* SPIN! */ - } - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; -#ifdef PINK_MEASURE - printf("Pink min = %f, max = %f\n", pinkMin, pinkMax ); -#endif - Pa_Terminate(); - 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 0; -} -#endif /* PINK_TEST */ diff --git a/pd/portaudio/pa_tests/patest_record.c b/pd/portaudio/pa_tests/patest_record.c deleted file mode 100644 index 59471aaf..00000000 --- a/pd/portaudio/pa_tests/patest_record.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * $Id: patest_record.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_record.c - * Record input into an array. - * Save array to a file. - * Playback recorded data. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include "portaudio.h" - -/* #define SAMPLE_RATE (17932) /* Test failure to open with this value. */ -#define SAMPLE_RATE (44100) -#define NUM_SECONDS (5) -#define NUM_CHANNELS (2) -/* #define DITHER_FLAG (paDitherOff) /**/ -#define DITHER_FLAG (0) /**/ - -/* Select sample format. */ -#if 1 -#define PA_SAMPLE_TYPE paFloat32 -typedef float SAMPLE; -#define SAMPLE_SILENCE (0.0f) -#elif 1 -#define PA_SAMPLE_TYPE paInt16 -typedef short SAMPLE; -#define SAMPLE_SILENCE (0) -#elif 0 -#define PA_SAMPLE_TYPE paInt8 -typedef char SAMPLE; -#define SAMPLE_SILENCE (0) -#else -#define PA_SAMPLE_TYPE paUInt8 -typedef unsigned char SAMPLE; -#define SAMPLE_SILENCE (128) - -#endif - -typedef struct -{ - int frameIndex; /* Index into sample array. */ - int maxFrameIndex; - SAMPLE *recordedSamples; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may be called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int recordCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - SAMPLE *rptr = (SAMPLE*)inputBuffer; - SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS]; - long framesToCalc; - long i; - int finished; - unsigned long framesLeft = data->maxFrameIndex - data->frameIndex; - - (void) outputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( framesLeft < framesPerBuffer ) - { - framesToCalc = framesLeft; - finished = paComplete; - } - else - { - framesToCalc = framesPerBuffer; - finished = paContinue; - } - - if( inputBuffer == NULL ) - { - for( i=0; i<framesToCalc; i++ ) - { - *wptr++ = SAMPLE_SILENCE; /* left */ - if( NUM_CHANNELS == 2 ) *wptr++ = SAMPLE_SILENCE; /* right */ - } - } - else - { - for( i=0; i<framesToCalc; i++ ) - { - *wptr++ = *rptr++; /* left */ - if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */ - } - } - data->frameIndex += framesToCalc; - return finished; -} - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may be called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int playCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - SAMPLE *rptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS]; - SAMPLE *wptr = (SAMPLE*)outputBuffer; - unsigned int i; - int finished; - unsigned int framesLeft = data->maxFrameIndex - data->frameIndex; - (void) inputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( framesLeft < framesPerBuffer ) - { - /* final buffer... */ - for( i=0; i<framesLeft; i++ ) - { - *wptr++ = *rptr++; /* left */ - if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */ - } - for( ; i<framesPerBuffer; i++ ) - { - *wptr++ = 0; /* left */ - if( NUM_CHANNELS == 2 ) *wptr++ = 0; /* right */ - } - data->frameIndex += framesLeft; - finished = paComplete; - } - else - { - for( i=0; i<framesPerBuffer; i++ ) - { - *wptr++ = *rptr++; /* left */ - if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */ - } - data->frameIndex += framesPerBuffer; - finished = paContinue; - } - return finished; -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PaStream *stream; - PaError err; - paTestData data; - int i; - int totalFrames; - int numSamples; - int numBytes; - SAMPLE max, average, val; - printf("patest_record.c\n"); fflush(stdout); - - data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */ - data.frameIndex = 0; - numSamples = totalFrames * NUM_CHANNELS; - - numBytes = numSamples * sizeof(SAMPLE); - data.recordedSamples = (SAMPLE *) malloc( numBytes ); - if( data.recordedSamples == NULL ) - { - printf("Could not allocate record array.\n"); - exit(1); - } - for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0; - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - /* Record some audio. -------------------------------------------- */ - err = Pa_OpenStream( - &stream, - Pa_GetDefaultInputDevice(), - NUM_CHANNELS, /* stereo input */ - PA_SAMPLE_TYPE, - 0, /* default latency */ - NULL, - paNoDevice, - 0, - PA_SAMPLE_TYPE, - 0, /* default latency */ - NULL, - SAMPLE_RATE, - 1024, /* frames per buffer */ - 0, //paDitherOff, /* flags */ - recordCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - printf("Now recording!!\n"); fflush(stdout); - - while( Pa_IsStreamActive( stream ) ) - { - Pa_Sleep(1000); - printf("index = %d\n", data.frameIndex ); fflush(stdout); - } - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - - /* Measure maximum peak amplitude. */ - max = 0; - average = 0; - for( i=0; i<numSamples; i++ ) - { - val = data.recordedSamples[i]; - if( val < 0 ) val = -val; /* ABS */ - if( val > max ) - { - max = val; - } - average += val; - } - - average = average / numSamples; - - if( PA_SAMPLE_TYPE == paFloat32 ) - { - printf("sample max amplitude = %f\n", max ); - printf("sample average = %f\n", average ); - } - else - { - printf("sample max amplitude = %d\n", max ); - printf("sample average = %d\n", average ); - } - - /* Write recorded data to a file. */ -#if 0 - { - FILE *fid; - fid = fopen("recorded.raw", "wb"); - if( fid == NULL ) - { - printf("Could not open file."); - } - else - { - fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid ); - fclose( fid ); - printf("Wrote data to 'recorded.raw'\n"); - } - } -#endif - - /* Playback recorded data. -------------------------------------------- */ - data.frameIndex = 0; - printf("Begin playback.\n"); fflush(stdout); - err = Pa_OpenStream( - &stream, - paNoDevice, - 0, /* NO input */ - PA_SAMPLE_TYPE, - 0, /* default latency */ - NULL, - Pa_GetDefaultOutputDevice(), - NUM_CHANNELS, /* stereo output */ - PA_SAMPLE_TYPE, - 0, /* default latency */ - NULL, - SAMPLE_RATE, - 1024, /* frames per buffer */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - playCallback, - &data ); - if( err != paNoError ) goto error; - - if( stream ) - { - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - printf("Waiting for playback to finish.\n"); fflush(stdout); - - while( Pa_IsStreamActive( stream ) ) Pa_Sleep(100); - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - printf("Done.\n"); fflush(stdout); - } - free( data.recordedSamples ); - - Pa_Terminate(); - 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/pd/portaudio/pa_tests/patest_ringmix.c b/pd/portaudio/pa_tests/patest_ringmix.c deleted file mode 100644 index 34c66381..00000000 --- a/pd/portaudio/pa_tests/patest_ringmix.c +++ /dev/null @@ -1,41 +0,0 @@ -/* $Id: patest_ringmix.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ */ - -#include "stdio.h" -#include "portaudio.h" -/* This will be called asynchronously by the PortAudio engine. */ -static int myCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, PaTimestamp outTime, void *userData ) -{ - float *out = (float *) outputBuffer; - float *in = (float *) inputBuffer; - float leftInput, rightInput; - unsigned int i; - if( inputBuffer == NULL ) return 0; - /* Read input buffer, process data, and fill output buffer. */ - for( i=0; i<framesPerBuffer; i++ ) - { - leftInput = *in++; /* Get interleaved samples from input buffer. */ - rightInput = *in++; - *out++ = leftInput * rightInput; /* ring modulation */ - *out++ = 0.5f * (leftInput + rightInput); /* mix */ - } - return 0; -} -/* Open a PortAudioStream to input and output audio data. */ -int main(void) -{ - PortAudioStream *stream; - Pa_Initialize(); - Pa_OpenDefaultStream( - &stream, - 2, 2, /* stereo input and output */ - paFloat32, 44100.0, - 64, 0, /* 64 frames per buffer, let PA determine numBuffers */ - myCallback, NULL ); - Pa_StartStream( stream ); - Pa_Sleep( 10000 ); /* Sleep for 10 seconds while processing. */ - Pa_StopStream( stream ); - Pa_CloseStream( stream ); - Pa_Terminate(); - return 0; -} diff --git a/pd/portaudio/pa_tests/patest_saw.c b/pd/portaudio/pa_tests/patest_saw.c deleted file mode 100644 index da1851ed..00000000 --- a/pd/portaudio/pa_tests/patest_saw.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * $Id: patest_saw.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_saw.c - * Play a simple sawtooth wave. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#define NUM_SECONDS (4) -#define SAMPLE_RATE (44100) -typedef struct -{ - float left_phase; - float right_phase; -} -paTestData; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - /* Cast data passed through stream to our structure. */ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned int i; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = data->left_phase; /* left */ - *out++ = data->right_phase; /* right */ - /* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */ - data->left_phase += 0.01f; - /* When signal reaches top, drop back down. */ - if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f; - /* higher pitch so we can distinguish left and right. */ - data->right_phase += 0.03f; - if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f; - } - return 0; -} -/*******************************************************************/ -static paTestData data; -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - printf("PortAudio Test: output sawtooth wave.\n"); - /* Initialize our data for use by callback. */ - data.left_phase = data.right_phase = 0.0; - /* Initialize library before making any other calls. */ - err = Pa_Initialize(); - if( err != paNoError ) goto error; - /* Open an audio I/O stream. */ - err = Pa_OpenDefaultStream( - &stream, - 0, /* no input channels */ - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - SAMPLE_RATE, - 256, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - /* Sleep for several seconds. */ - Pa_Sleep(NUM_SECONDS*1000); - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_sine.c b/pd/portaudio/pa_tests/patest_sine.c deleted file mode 100644 index 1bebb90e..00000000 --- a/pd/portaudio/pa_tests/patest_sine.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * $Id: patest_sine.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_sine.c - * Play a sine wave using the Portable Audio api for several seconds. - * - * Authors: - * Ross Bencina <rossb@audiomulch.com> - * Phil Burk <philburk@softsynth.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define NUM_SECONDS (5) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (64) - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - -#define TABLE_SIZE (200) -typedef struct -{ - float sine[TABLE_SIZE]; - int left_phase; - int right_phase; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned long i; - - (void) timeInfo; /* Prevent unused variable warnings. */ - (void) statusFlags; - (void) inputBuffer; - - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = data->sine[data->left_phase]; /* left */ - *out++ = data->sine[data->right_phase]; /* right */ - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - - return paContinue; -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PaStreamParameters outputParameters; - PaStream *stream; - PaError err; - paTestData data; - int i; - - - printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); - - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - data.left_phase = data.right_phase = 0; - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ - outputParameters.channelCount = 2; /* stereo output */ - outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */ - outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; - outputParameters.hostApiSpecificStreamInfo = NULL; - - err = Pa_OpenStream( - &stream, - NULL, /* no input */ - &outputParameters, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Play for %d seconds.\n", NUM_SECONDS ); - Pa_Sleep( NUM_SECONDS * 1000 ); - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - - Pa_Terminate(); - printf("Test finished.\n"); - - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_sine8.c b/pd/portaudio/pa_tests/patest_sine8.c deleted file mode 100644 index f3ef9ebb..00000000 --- a/pd/portaudio/pa_tests/patest_sine8.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * $Id: patest_sine8.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_sine8.c - * Play a sine wave using the Portable Audio api for several seconds. - * Test 8 bit data. - * - * Author: Ross Bencina <rossb@audiomulch.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#define NUM_SECONDS (8) -#define SAMPLE_RATE (44100) -#define TEST_UNSIGNED (1) -#if TEST_UNSIGNED -#define TEST_FORMAT paUInt8 -#else -#define TEST_FORMAT paInt8 -#endif -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TABLE_SIZE (200) -typedef struct -{ -#if TEST_UNSIGNED - unsigned char sine[TABLE_SIZE]; -#else - char sine[TABLE_SIZE]; -#endif - int left_phase; - int right_phase; - unsigned int framesToGo; -} -paTestData; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - char *out = (char*)outputBuffer; - int i; - int framesToCalc; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - if( data->framesToGo < framesPerBuffer ) - { - framesToCalc = data->framesToGo; - data->framesToGo = 0; - finished = 1; - } - else - { - framesToCalc = framesPerBuffer; - data->framesToGo -= framesPerBuffer; - } - - for( i=0; i<framesToCalc; i++ ) - { - *out++ = data->sine[data->left_phase]; /* left */ - *out++ = data->sine[data->right_phase]; /* right */ - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - /* zero remainder of final buffer */ - for( ; i<(int)framesPerBuffer; i++ ) - { -#if TEST_UNSIGNED - *out++ = (unsigned char) 0x80; /* left */ - *out++ = (unsigned char) 0x80; /* right */ -#else - *out++ = 0; /* left */ - *out++ = 0; /* right */ -#endif - - } - return finished; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int i; - int totalSamps; -#if TEST_UNSIGNED - printf("PortAudio Test: output UNsigned 8 bit sine wave.\n"); -#else - printf("PortAudio Test: output signed 8 bit sine wave.\n"); -#endif - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - data.sine[i] = (char) (127.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. )); -#if TEST_UNSIGNED - data.sine[i] += (unsigned char) 0x80; -#endif - - } - data.left_phase = data.right_phase = 0; - data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */ - err = Pa_Initialize(); - if( err != paNoError ) goto error; - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - TEST_FORMAT, - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 2, /* stereo output */ - TEST_FORMAT, - NULL, - SAMPLE_RATE, - 256, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - /* Watch until sound is halfway finished. */ - while( Pa_StreamTime( stream ) < (totalSamps/2) ) Pa_Sleep(10); - /* Stop sound until ENTER hit. */ - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - printf("Pause for 2 seconds.\n"); - Pa_Sleep( 2000 ); - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - printf("Waiting for sound to finish.\n"); - while( Pa_StreamActive( stream ) ) Pa_Sleep(10); - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_sine_formats.c b/pd/portaudio/pa_tests/patest_sine_formats.c deleted file mode 100644 index 74e12022..00000000 --- a/pd/portaudio/pa_tests/patest_sine_formats.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * $Id: patest_sine_formats.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_sine_formats.c - * Play a sine wave using the Portable Audio api for several seconds. - * Test various data formats. - * - * Author: Phil Burk - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define NUM_SECONDS (10) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (512) -#define LEFT_FREQ (SAMPLE_RATE/256.0) /* So we hit 1.0 */ -#define RIGHT_FREQ (500.0) -#define AMPLITUDE (1.0) - -/* Select ONE format for testing. */ -#define TEST_UINT8 (0) -#define TEST_INT8 (0) -#define TEST_INT16 (1) -#define TEST_FLOAT32 (0) - -#if TEST_UINT8 -#define TEST_FORMAT paUInt8 -typedef unsigned char SAMPLE_t; -#define SAMPLE_ZERO (0x80) -#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x))) -#define FORMAT_NAME "Unsigned 8 Bit" - -#elif TEST_INT8 -#define TEST_FORMAT paInt8 -typedef char SAMPLE_t; -#define SAMPLE_ZERO (0) -#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x))) -#define FORMAT_NAME "Signed 8 Bit" - -#elif TEST_INT16 -#define TEST_FORMAT paInt16 -typedef short SAMPLE_t; -#define SAMPLE_ZERO (0) -#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(32767 * (x))) -#define FORMAT_NAME "Signed 16 Bit" - -#elif TEST_FLOAT32 -#define TEST_FORMAT paFloat32 -typedef float SAMPLE_t; -#define SAMPLE_ZERO (0.0) -#define DOUBLE_TO_SAMPLE(x) ((SAMPLE_t)(x)) -#define FORMAT_NAME "Float 32 Bit" -#endif - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - - -typedef struct -{ - double left_phase; - double right_phase; - unsigned int framesToGo; -} -paTestData; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - SAMPLE_t *out = (SAMPLE_t *)outputBuffer; - int i; - int framesToCalc; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - if( data->framesToGo < framesPerBuffer ) - { - framesToCalc = data->framesToGo; - data->framesToGo = 0; - finished = 1; - } - else - { - framesToCalc = framesPerBuffer; - data->framesToGo -= framesPerBuffer; - } - - for( i=0; i<framesToCalc; i++ ) - { - data->left_phase += (LEFT_FREQ / SAMPLE_RATE); - if( data->left_phase > 1.0) data->left_phase -= 1.0; - *out++ = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->left_phase * M_PI * 2. ))); - - data->right_phase += (RIGHT_FREQ / SAMPLE_RATE); - if( data->right_phase > 1.0) data->right_phase -= 1.0; - *out++ = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->right_phase * M_PI * 2. ))); - } - /* zero remainder of final buffer */ - for( ; i<(int)framesPerBuffer; i++ ) - { - *out++ = SAMPLE_ZERO; /* left */ - *out++ = SAMPLE_ZERO; /* right */ - } - return finished; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PaStream *stream; - PaError err; - paTestData data; - int totalSamps; - - printf("PortAudio Test: output " FORMAT_NAME "\n"); - - - data.left_phase = data.right_phase = 0.0; - data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */ - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - TEST_FORMAT, - 0, /* default latency */ - NULL, - Pa_GetDefaultOutputDevice(), /* default output device */ - 2, /* stereo output */ - TEST_FORMAT, - 0, /* default latency */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Waiting %d seconds for sound to finish.\n", NUM_SECONDS ); - while( Pa_IsStreamActive( stream ) ) Pa_Sleep(10); - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - - printf("PortAudio Test Finished: " FORMAT_NAME "\n"); - - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_sine_time.c b/pd/portaudio/pa_tests/patest_sine_time.c deleted file mode 100644 index c849af0a..00000000 --- a/pd/portaudio/pa_tests/patest_sine_time.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * $Id: patest_sine_time.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_sine_time.c - * Play a sine wave using the Portable Audio api for several seconds. - * Pausing in the middle. - * use the Pa_GetStreamTime() and Pa_IsStreamActive() calls. - * - * Authors: - * Ross Bencina <rossb@audiomulch.com> - * Phil Burk <philburk@softsynth.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#include "pa_util.h" -#define NUM_SECONDS (8) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (64) -#define NUM_BUFFERS (0) - -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TWOPI (M_PI * 2.0) - -#define TABLE_SIZE (200) -typedef struct -{ - double left_phase; - double right_phase; - volatile PaTimestamp outTime; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned int i; - - double left_phaseInc = 0.02; - double right_phaseInc = 0.06; - - double left_phase = data->left_phase; - double right_phase = data->right_phase; - - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - data->outTime = outTime;\ - - for( i=0; i<framesPerBuffer; i++ ) - { - left_phase += left_phaseInc; - if( left_phase > TWOPI ) left_phase -= TWOPI; - *out++ = (float) sin( left_phase ); - - right_phase += right_phaseInc; - if( right_phase > TWOPI ) right_phase -= TWOPI; - *out++ = (float) sin( right_phase ); - } - - data->left_phase = left_phase; - data->right_phase = right_phase; - - return paContinue; -} -/*******************************************************************/ -static void ReportStreamTime( PaStream *stream, paTestData *data ); -static void ReportStreamTime( PaStream *stream, paTestData *data ) -{ - PaTimestamp streamTime, latency, outTime; - - streamTime = Pa_GetStreamTime( stream ); - outTime = data->outTime; - if( outTime < 0.0 ) - { - printf("Stream time = %8.1f\n", streamTime ); - } - else - { - latency = outTime - streamTime; - printf("Stream time = %8.1f, outTime = %8.1f, latency = %8.1f\n", - streamTime, outTime, latency ); - } - fflush(stdout); -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PaStream *stream; - PaError err; - paTestData DATA; - int totalSamps; - printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); - DATA.left_phase = DATA.right_phase = 0; - totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */ - err = Pa_Initialize(); - if( err != paNoError ) goto error; - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - 0, /* default latency */ - NULL, - Pa_GetDefaultOutputDevice(), /* default output device */ - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - 0, /* default latency */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &DATA ); - if( err != paNoError ) goto error; - - /* Watch until sound is halfway finished. */ - printf("Play for %d seconds.\n", NUM_SECONDS/2 ); fflush(stdout); - - DATA.outTime = -1.0; // mark time for callback as undefined - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - do - { - ReportStreamTime( stream, &DATA ); - Pa_Sleep(100); - } while( Pa_GetStreamTime( stream ) < (totalSamps/2) ); - - /* Stop sound until ENTER hit. */ - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - printf("Pause for 2 seconds.\n"); fflush(stdout); - Pa_Sleep( 2000 ); - - DATA.outTime = -1.0; // mark time for callback as undefined - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Play until sound is finished.\n"); fflush(stdout); - do - { - ReportStreamTime( stream, &DATA ); - Pa_Sleep(100); - } while( Pa_GetStreamTime( stream ) < (totalSamps/2) ); - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_start_stop.c b/pd/portaudio/pa_tests/patest_start_stop.c deleted file mode 100644 index 0e183708..00000000 --- a/pd/portaudio/pa_tests/patest_start_stop.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * $Id: patest_start_stop.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_start_stop.c - * Play a sine wave using the Portable Audio api for several seconds. - * Start and stop the stream multiple times. - * - * Authors: - * Ross Bencina <rossb@audiomulch.com> - * Phil Burk <philburk@softsynth.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define NUM_SECONDS (3) -#define NUM_LOOPS (4) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (400) - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - -#define TABLE_SIZE (200) -typedef struct -{ - float sine[TABLE_SIZE]; - int left_phase; - int right_phase; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned long i; - - (void) timeInfo; /* Prevent unused variable warnings. */ - (void) statusFlags; - (void) inputBuffer; - - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = data->sine[data->left_phase]; /* left */ - *out++ = data->sine[data->right_phase]; /* right */ - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - - return paContinue; -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PaStreamParameters outputParameters; - PaStream *stream; - PaError err; - paTestData data; - int i; - - - printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); - - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - data.left_phase = data.right_phase = 0; - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ - outputParameters.channelCount = 2; /* stereo output */ - outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */ - outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; - outputParameters.hostApiSpecificStreamInfo = NULL; - - err = Pa_OpenStream( - &stream, - NULL, /* no input */ - &outputParameters, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - for( i=0; i<NUM_LOOPS; i++ ) - { - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Play for %d seconds.\n", NUM_SECONDS ); - Pa_Sleep( NUM_SECONDS * 1000 ); - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - - printf("Stopped.\n" ); - Pa_Sleep( 1000 ); - } - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - - Pa_Terminate(); - printf("Test finished.\n"); - - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_stop.c b/pd/portaudio/pa_tests/patest_stop.c deleted file mode 100644 index 54e72ff7..00000000 --- a/pd/portaudio/pa_tests/patest_stop.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * $Id: patest_stop.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_stop.c - * - * Test the three ways of stopping audio: - * calling Pa_StopStream(), - * calling Pa_AbortStream(), - * and returning a 1 from the callback function. - * - * A long latency is set up so that you can hear the difference. - * Then a simple 8 note sequence is repeated twice. - * The program will print what you should hear. - * - * Author: Phil Burk <philburk@softsynth.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDevice()) -#define SLEEP_DUR (200) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) -#define LATENCY_MSEC (3000) -#define FRAMES_PER_NOTE (SAMPLE_RATE/2) -#define MAX_REPEATS (2) -#define FUNDAMENTAL (400.0f / SAMPLE_RATE) -#define NOTE_0 (FUNDAMENTAL * 1.0f / 1.0f) -#define NOTE_1 (FUNDAMENTAL * 5.0f / 4.0f) -#define NOTE_2 (FUNDAMENTAL * 4.0f / 3.0f) -#define NOTE_3 (FUNDAMENTAL * 3.0f / 2.0f) -#define NOTE_4 (FUNDAMENTAL * 2.0f / 1.0f) -#define MODE_FINISH (0) -#define MODE_STOP (1) -#define MODE_ABORT (2) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TABLE_SIZE (400) -typedef struct -{ - float waveform[TABLE_SIZE + 1]; // add one for guard point for interpolation - float phase_increment; - float phase; - float *tune; - int notesPerTune; - int frameCounter; - int noteCounter; - int repeatCounter; - PaTimestamp outTime; - int stopMode; - int done; -} -paTestData; -/************* Prototypes *****************************/ -int TestStopMode( paTestData *data ); -float LookupWaveform( paTestData *data, float phase ); -/****************************************************** - * Convert phase between 0.0 and 1.0 to waveform value - * using linear interpolation. - */ -float LookupWaveform( paTestData *data, float phase ) -{ - float fIndex = phase*TABLE_SIZE; - int index = (int) fIndex; - float fract = fIndex - index; - float lo = data->waveform[index]; - float hi = data->waveform[index+1]; - float val = lo + fract*(hi-lo); - return val; -} -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - float value; - unsigned int i = 0; - int finished = paContinue; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - data->outTime = outTime; - if( !data->done ) - { - for( i=0; i<framesPerBuffer; i++ ) - { - /* Are we done with this note? */ - if( data->frameCounter >= FRAMES_PER_NOTE ) - { - data->noteCounter += 1; - data->frameCounter = 0; - /* Are we done with this tune? */ - if( data->noteCounter >= data->notesPerTune ) - { - data->noteCounter = 0; - data->repeatCounter += 1; - /* Are we totally done? */ - if( data->repeatCounter >= MAX_REPEATS ) - { - data->done = 1; - if( data->stopMode == MODE_FINISH ) - { - finished = paComplete; - break; - } - } - } - data->phase_increment = data->tune[data->noteCounter]; - } - value = LookupWaveform(data, data->phase); - *out++ = value; /* left */ - *out++ = value; /* right */ - data->phase += data->phase_increment; - if( data->phase >= 1.0f ) data->phase -= 1.0f; - - data->frameCounter += 1; - } - } - /* zero remainder of final buffer */ - for( ; i<framesPerBuffer; i++ ) - { - *out++ = 0; /* left */ - *out++ = 0; /* right */ - } - return finished; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - paTestData DATA; - int i; - float simpleTune[] = { NOTE_0, NOTE_1, NOTE_2, NOTE_3, NOTE_4, NOTE_3, NOTE_2, NOTE_1 }; - printf("PortAudio Test: play song and test stopping. ask for %d latency\n", LATENCY_MSEC ); - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - DATA.waveform[i] = (float) ( - (0.2 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. )) + - (0.2 * sin( ((double)(3*i)/(double)TABLE_SIZE) * M_PI * 2. )) + - (0.1 * sin( ((double)(5*i)/(double)TABLE_SIZE) * M_PI * 2. )) - ); - } - DATA.waveform[TABLE_SIZE] = DATA.waveform[0]; // set guard point - DATA.tune = &simpleTune[0]; - DATA.notesPerTune = sizeof(simpleTune) / sizeof(float); - printf("Test MODE_FINISH - callback returns 1.\n"); - printf("Should hear entire %d note tune repeated twice.\n", DATA.notesPerTune); - DATA.stopMode = MODE_FINISH; - if( TestStopMode( &DATA ) != paNoError ) - { - printf("Test of MODE_FINISH failed!\n"); - goto error; - } - printf("Test MODE_STOP - stop when song is done.\n"); - printf("Should hear entire %d note tune repeated twice.\n", DATA.notesPerTune); - DATA.stopMode = MODE_STOP; - if( TestStopMode( &DATA ) != paNoError ) - { - printf("Test of MODE_STOP failed!\n"); - goto error; - } - - printf("Test MODE_ABORT - abort immediately.\n"); - printf("Should hear last repetition cut short by %d msec.\n", LATENCY_MSEC); - DATA.stopMode = MODE_ABORT; - if( TestStopMode( &DATA ) != paNoError ) - { - printf("Test of MODE_ABORT failed!\n"); - goto error; - } - return 0; -error: - return 1; -} - -int TestStopMode( paTestData *data ) -{ - PaStream *stream; - PaError err; - data->done = 0; - data->phase = 0.0; - data->frameCounter = 0; - data->noteCounter = 0; - data->repeatCounter = 0; - data->phase_increment = data->tune[data->noteCounter]; - err = Pa_Initialize(); - if( err != paNoError ) goto error; - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - 0, - NULL, - OUTPUT_DEVICE, - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - LATENCY_MSEC, - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - data ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - if( data->stopMode == MODE_FINISH ) - { - while( Pa_IsStreamActive( stream ) ) - { - /*printf("outTime = %g, note# = %d, repeat# = %d\n", data->outTime, - data->noteCounter, data->repeatCounter ); - fflush(stdout); /**/ - Pa_Sleep( SLEEP_DUR ); - } - } - else - { - while( data->repeatCounter < MAX_REPEATS ) - { - /*printf("outTime = %g, note# = %d, repeat# = %d\n", data->outTime, - data->noteCounter, data->repeatCounter ); - fflush(stdout); /**/ - Pa_Sleep( SLEEP_DUR ); - } - } - - if( data->stopMode == MODE_ABORT ) - { - printf("Call Pa_AbortStream()\n"); - err = Pa_AbortStream( stream ); - } - else - { - printf("Call Pa_StopStream()\n"); - err = Pa_StopStream( stream ); - } - if( err != paNoError ) goto error; - - printf("Call Pa_CloseStream()\n"); fflush(stdout); - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_sync.c b/pd/portaudio/pa_tests/patest_sync.c deleted file mode 100644 index 46854eb6..00000000 --- a/pd/portaudio/pa_tests/patest_sync.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * $Id: patest_sync.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * patest_sync.c - * Test time stamping and synchronization of audio and video. - * A high latency is used so we can hear the difference in time. - * Random durations are used so we know we are hearing the right beep - * and not the one before or after. - * - * Sequence of events: - * Foreground requests a beep. - * Background randomly schedules a beep. - * Foreground waits for the beep to be heard based on PaUtil_GetTime(). - * Foreground outputs video (printf) in sync with audio. - * Repeat. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" -#include "pa_util.h" -#define NUM_BEEPS (6) -#define SAMPLE_RATE (44100) -#define SAMPLE_PERIOD (1.0/44100.0) -#define FRAMES_PER_BUFFER (256) -#define BEEP_DURATION (400) -#define LATENCY_MSEC (2000) -#define SLEEP_MSEC (10) -#define TIMEOUT_MSEC (15000) - -#define STATE_BKG_IDLE (0) -#define STATE_BKG_PENDING (1) -#define STATE_BKG_BEEPING (2) -typedef struct -{ - float left_phase; - float right_phase; - int state; - int requestBeep; /* Set by foreground, cleared by background. */ - PaTime beepTime; - int beepCount; - double latency; /* For debugging. */ -} -paTestData; - -static unsigned long GenerateRandomNumber( void ); -/************************************************************/ -/* Calculate pseudo-random 32 bit number based on linear congruential method. */ -static unsigned long GenerateRandomNumber( void ) -{ - static unsigned long randSeed = 99887766; /* Change this for different random sequences. */ - randSeed = (randSeed * 196314165) + 907633515; - return randSeed; -} - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo *timeInfo, - PaStreamCallbackFlags statusFlags, void *userData ) -{ - /* Cast data passed through stream to our structure. */ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned int i; - (void) inputBuffer; - - data->latency = timeInfo->outputBufferDacTime - timeInfo->currentTime; - - for( i=0; i<framesPerBuffer; i++ ) - { - switch( data->state ) - { - case STATE_BKG_IDLE: - /* Schedule beep at some random time in the future. */ - if( data->requestBeep ) - { - int random = GenerateRandomNumber() >> 14; - data->beepTime = timeInfo->outputBufferDacTime + (( (double)(random + SAMPLE_RATE)) * SAMPLE_PERIOD ); - data->state = STATE_BKG_PENDING; - } - *out++ = 0.0; /* left */ - *out++ = 0.0; /* right */ - break; - - case STATE_BKG_PENDING: - if( (timeInfo->outputBufferDacTime + (i*SAMPLE_PERIOD)) >= data->beepTime ) - { - data->state = STATE_BKG_BEEPING; - data->beepCount = BEEP_DURATION; - data->left_phase = data->right_phase = 0.0; - } - *out++ = 0.0; /* left */ - *out++ = 0.0; /* right */ - break; - - case STATE_BKG_BEEPING: - if( data->beepCount <= 0 ) - { - data->state = STATE_BKG_IDLE; - data->requestBeep = 0; - *out++ = 0.0; /* left */ - *out++ = 0.0; /* right */ - } - else - { - /* Play sawtooth wave. */ - *out++ = data->left_phase; /* left */ - *out++ = data->right_phase; /* right */ - /* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */ - data->left_phase += 0.01f; - /* When signal reaches top, drop back down. */ - if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f; - /* higher pitch so we can distinguish left and right. */ - data->right_phase += 0.03f; - if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f; - } - data->beepCount -= 1; - break; - - default: - data->state = STATE_BKG_IDLE; - break; - } - } - return 0; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PaStream *stream; - PaError err; - paTestData DATA; - int i, timeout; - PaTime previousTime; - PaStreamParameters outputParameters; - printf("PortAudio Test: you should see BEEP at the same time you hear it.\n"); - printf("Wait for a few seconds random delay between BEEPs.\n"); - printf("BEEP %d times.\n", NUM_BEEPS ); - /* Initialize our DATA for use by callback. */ - DATA.left_phase = DATA.right_phase = 0.0; - DATA.state = STATE_BKG_IDLE; - DATA.requestBeep = 0; - /* Initialize library before making any other calls. */ - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - outputParameters.device = Pa_GetDefaultOutputDevice(); - outputParameters.channelCount = 2; - outputParameters.hostApiSpecificStreamInfo = NULL; - outputParameters.sampleFormat = paFloat32; - outputParameters.suggestedLatency = (double)LATENCY_MSEC / 1000; - - /* Open an audio I/O stream. */ - err = Pa_OpenStream( - &stream, - NULL, /* no input */ - &outputParameters, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &DATA ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("started\n"); - fflush(stdout); - - previousTime = Pa_GetStreamTime( stream ); - for( i=0; i<NUM_BEEPS; i++ ) - { - /* Request a beep from background. */ - DATA.requestBeep = 1; - - /* Wait for background to acknowledge request. */ - timeout = TIMEOUT_MSEC; - while( (DATA.requestBeep == 1) && (timeout-- > 0 ) ) Pa_Sleep(SLEEP_MSEC); - if( timeout <= 0 ) - { - fprintf( stderr, "Timed out waiting for background to acknowledge request.\n" ); - goto error; - } - printf("calc beep for %9.3f, latency = %6.3f\n", DATA.beepTime, DATA.latency ); - fflush(stdout); - - /* Wait for scheduled beep time. */ - timeout = TIMEOUT_MSEC + (10000/SLEEP_MSEC); - while( (Pa_GetStreamTime( stream ) < DATA.beepTime) && (timeout-- > 0 ) ) - { - Pa_Sleep(SLEEP_MSEC); - } - if( timeout <= 0 ) - { - fprintf( stderr, "Timed out waiting for time. Now = %9.3f, Beep for %9.3f.\n", - PaUtil_GetTime(), DATA.beepTime ); - goto error; - } - - /* Beep should be sounding now so print synchronized BEEP. */ - printf("hear \"BEEP\" at %9.3f, delta = %9.3f\n", - Pa_GetStreamTime( stream ), (DATA.beepTime - previousTime) ); - fflush(stdout); - - previousTime = DATA.beepTime; - } - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_toomanysines.c b/pd/portaudio/pa_tests/patest_toomanysines.c deleted file mode 100644 index 2fbb8433..00000000 --- a/pd/portaudio/pa_tests/patest_toomanysines.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * $Id: patest_toomanysines.c,v 1.1.1.1 2003-05-09 16:03:56 ggeiger Exp $ - * Play more sine waves than we can handle in real time as a stress test, - * - * Authors: - * Ross Bencina <rossb@audiomulch.com> - * Phil Burk <philburk@softsynth.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define MAX_SINES (500) -#define MAX_LOAD (1.2) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (512) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TWOPI (M_PI * 2.0) - -typedef struct paTestData -{ - int numSines; - double phases[MAX_SINES]; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned long i; - int j; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - for( i=0; i<framesPerBuffer; i++ ) - { - float output = 0.0; - double phaseInc = 0.02; - double phase; - for( j=0; j<data->numSines; j++ ) - { - /* Advance phase of next oscillator. */ - phase = data->phases[j]; - phase += phaseInc; - if( phase > TWOPI ) phase -= TWOPI; - - phaseInc *= 1.02; - if( phaseInc > 0.5 ) phaseInc *= 0.5; - - /* This is not a very efficient way to calc sines. */ - output += (float) sin( phase ); - data->phases[j] = phase; - } - - - *out++ = (float) (output / data->numSines); - } - return finished; -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - int numStress; - paTestData data = {0}; - double load; - printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d. MAX_LOAD = %f\n", - SAMPLE_RATE, FRAMES_PER_BUFFER, MAX_LOAD ); - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 1, /* mono output */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - /* Determine number of sines required to get to 50% */ - do - { - data.numSines++; - Pa_Sleep( 100 ); - - load = Pa_GetCPULoad( stream ); - printf("numSines = %d, CPU load = %f\n", data.numSines, load ); - } - while( load < 0.5 ); - - /* Calculate target stress value then ramp up to that level*/ - numStress = (int) (2.0 * data.numSines * MAX_LOAD ); - for( ; data.numSines < numStress; data.numSines++ ) - { - Pa_Sleep( 200 ); - load = Pa_GetCPULoad( stream ); - printf("STRESSING: numSines = %d, CPU load = %f\n", data.numSines, load ); - } - - printf("Suffer for 5 seconds.\n"); - Pa_Sleep( 5000 ); - - printf("Stop stream.\n"); - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_underflow.c b/pd/portaudio/pa_tests/patest_underflow.c deleted file mode 100644 index 3f02c5a4..00000000 --- a/pd/portaudio/pa_tests/patest_underflow.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * $Id: patest_underflow.c,v 1.1.1.1 2003-05-09 16:03:57 ggeiger Exp $ - * patest_underflow.c - * Simulate an output buffer underflow condition. - * Tests whether the stream can be stopped when underflowing buffers. - * - * Authors: - * Ross Bencina <rossb@audiomulch.com> - * Phil Burk <philburk@softsynth.com> - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define NUM_SECONDS (20) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (2048) -#define MSEC_PER_BUFFER ( (FRAMES_PER_BUFFER * 1000) / SAMPLE_RATE ) - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - -#define TABLE_SIZE (200) -typedef struct -{ - float sine[TABLE_SIZE]; - int left_phase; - int right_phase; - int sleepTime; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned long i; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - for( i=0; i<framesPerBuffer; i++ ) - { - *out++ = data->sine[data->left_phase]; /* left */ - *out++ = data->sine[data->right_phase]; /* right */ - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - - /* Cause underflow to occur. */ - if( data->sleepTime > 0 ) Pa_Sleep( data->sleepTime ); - data->sleepTime += 1; - - return finished; -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int i; - printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); - /* initialise sinusoidal wavetable */ - for( i=0; i<TABLE_SIZE; i++ ) - { - data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - data.left_phase = data.right_phase = data.sleepTime = 0; - err = Pa_Initialize(); - if( err != paNoError ) goto error; - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - while( data.sleepTime < (2 * MSEC_PER_BUFFER) ) - { - printf("SleepTime = %d\n", data.sleepTime ); - Pa_Sleep( data.sleepTime ); - } - - printf("Try to stop stream.\n"); - err = Pa_StopStream( stream ); /* */ - err = Pa_AbortStream( stream ); /* */ - if( err != paNoError ) goto error; - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} diff --git a/pd/portaudio/pa_tests/patest_wire.c b/pd/portaudio/pa_tests/patest_wire.c deleted file mode 100644 index 51531395..00000000 --- a/pd/portaudio/pa_tests/patest_wire.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * $Id: patest_wire.c,v 1.1.1.1 2003-05-09 16:03:57 ggeiger Exp $ - * patest_wire.c - * - * Pass input directly to output. - * Note that some HW devices, for example many ISA audio cards - * on PCs, do NOT support full duplex! For a PC, you normally need - * a PCI based audio card such as the SBLive. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <math.h> -#include "portaudio.h" - -#define SAMPLE_RATE (44100) - -typedef struct WireConfig_s -{ - int isInputInterleaved; - int isOutputInterleaved; - int numInputChannels; - int numOutputChannels; - int framesPerCallback; -} WireConfig_t; - -#define USE_FLOAT_INPUT (1) -#define USE_FLOAT_OUTPUT (1) - -#define INPUT_LATENCY_MSEC (0) -#define INPUT_LATENCY_FRAMES ((INPUT_LATENCY_MSEC * SAMPLE_RATE) / 1000) -#define OUTPUT_LATENCY_MSEC (0) -#define OUTPUT_LATENCY_FRAMES ((OUTPUT_LATENCY_MSEC * SAMPLE_RATE) / 1000) - - -#if USE_FLOAT_INPUT - #define INPUT_FORMAT paFloat32 - typedef float INPUT_SAMPLE; -#else - #define INPUT_FORMAT paInt16 - typedef short INPUT_SAMPLE; -#endif - -#if USE_FLOAT_OUTPUT - #define OUTPUT_FORMAT paFloat32 - typedef float OUTPUT_SAMPLE; -#else - #define OUTPUT_FORMAT paInt16 - typedef short OUTPUT_SAMPLE; -#endif - -double gInOutScaler = 1.0; -#define CONVERT_IN_TO_OUT(in) ((OUTPUT_SAMPLE) ((in) * gInOutScaler)) - -#define INPUT_DEVICE (Pa_GetDefaultInputDevice()) -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDevice()) - -static PaError TestConfiguration( WireConfig_t *config ); - -static int wireCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ); - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may be called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ - -static int wireCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - INPUT_SAMPLE *in; - OUTPUT_SAMPLE *out; - int inStride; - int outStride; - - int inDone = 0; - int outDone = 0; - WireConfig_t *config = (WireConfig_t *) userData; - unsigned int i; - int inChannel, outChannel; - (void) outTime; - - /* This may get called with NULL inputBuffer during initial setup. */ - if( inputBuffer == NULL) return 0; - - inChannel=0, outChannel=0; - while( !(inDone && outDone) ) - { - if( config->isInputInterleaved ) - { - in = ((INPUT_SAMPLE*)inputBuffer) + inChannel; - inStride = config->numInputChannels; - } - else - { - in = ((INPUT_SAMPLE**)inputBuffer)[inChannel]; - inStride = 1; - } - - if( config->isOutputInterleaved ) - { - out = ((OUTPUT_SAMPLE*)outputBuffer) + outChannel; - outStride = config->numOutputChannels; - } - else - { - out = ((OUTPUT_SAMPLE**)outputBuffer)[outChannel]; - outStride = 1; - } - - for( i=0; i<framesPerBuffer; i++ ) - { - *out = CONVERT_IN_TO_OUT( *in ); - out += outStride; - in += inStride; - } - - if(inChannel < (config->numInputChannels - 1)) inChannel++; - else inDone = 1; - if(outChannel < (config->numOutputChannels - 1)) outChannel++; - else outDone = 1; - } - return 0; -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PaError err; - WireConfig_t CONFIG; - WireConfig_t *config = &CONFIG; - int configIndex = 0;; - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - printf("Please connect audio signal to input and listen for it on output!\n"); - printf("input format = %d\n", INPUT_FORMAT ); - printf("output format = %d\n", OUTPUT_FORMAT ); - printf("input device ID = %d\n", INPUT_DEVICE ); - printf("output device ID = %d\n", OUTPUT_DEVICE ); - - if( INPUT_FORMAT == OUTPUT_FORMAT ) - { - gInOutScaler = 1.0; - } - else if( (INPUT_FORMAT == paInt16) && (OUTPUT_FORMAT == paFloat32) ) - { - gInOutScaler = 1.0/32768.0; - } - else if( (INPUT_FORMAT == paFloat32) && (OUTPUT_FORMAT == paInt16) ) - { - gInOutScaler = 32768.0; - } - - for( config->isInputInterleaved = 0; config->isInputInterleaved < 2; config->isInputInterleaved++ ) - { - for( config->isOutputInterleaved = 0; config->isOutputInterleaved < 2; config->isOutputInterleaved++ ) - { - for( config->numInputChannels = 1; config->numInputChannels < 3; config->numInputChannels++ ) - { - for( config->numOutputChannels = 1; config->numOutputChannels < 3; config->numOutputChannels++ ) - { - for( config->framesPerCallback = 0; config->framesPerCallback < 65; config->framesPerCallback += 64 ) - { - printf("-----------------------------------------------\n" ); - printf("Configuration #%d\n", configIndex++ ); - err = TestConfiguration( config ); - // give user a chance to bail out - if( err == 1 ) - { - err = paNoError; - goto done; - } - else if( err != paNoError ) goto error; - } - } - } - } - } - -done: - Pa_Terminate(); - - printf("Full duplex sound test complete.\n"); fflush(stdout); - - printf("Hit ENTER to quit.\n"); fflush(stdout); - getchar(); - - 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 ) ); - printf("Hit ENTER to quit.\n"); fflush(stdout); - getchar(); - return -1; -} - -static PaError TestConfiguration( WireConfig_t *config ) -{ - int c; - PaError err; - PaStream *stream; - printf("input %sinterleaved!\n", (config->isInputInterleaved ? " " : "NOT ") ); - printf("output %sinterleaved!\n", (config->isOutputInterleaved ? " " : "NOT ") ); - printf("input channels = %d\n", config->numInputChannels ); - printf("output channels = %d\n", config->numOutputChannels ); - printf("framesPerCallback = %d\n", config->framesPerCallback ); - - err = Pa_OpenStream( - &stream, - INPUT_DEVICE, - config->numInputChannels, - INPUT_FORMAT | (config->isInputInterleaved ? 0 : paNonInterleaved), - INPUT_LATENCY_FRAMES, /* input latency */ - NULL, - OUTPUT_DEVICE, - config->numOutputChannels, - OUTPUT_FORMAT | (config->isOutputInterleaved ? 0 : paNonInterleaved), - OUTPUT_LATENCY_FRAMES, /* output latency */ - NULL, - SAMPLE_RATE, - config->framesPerCallback, /* frames per buffer */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - wireCallback, - config ); /* user data */ - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Hit ENTER for next configuration, or 'q' to quit.\n"); fflush(stdout); - c = getchar(); - - printf("Closing stream.\n"); - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - - if( c == 'q' ) return 1; - -error: - return err; -} diff --git a/pd/portaudio/pa_unix/pa_unix_hostapis.c b/pd/portaudio/pa_unix/pa_unix_hostapis.c deleted file mode 100644 index 4d10ef93..00000000 --- a/pd/portaudio/pa_unix/pa_unix_hostapis.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * $Id: pa_unix_hostapis.c,v 1.1.2.4 2003/02/10 01:06:09 dmazzoni 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 ); - - -PaUtilHostApiInitializer *paHostApiInitializers[] = - { -#ifdef PA_USE_OSS - PaOSS_Initialize, -#endif - -#ifdef PA_USE_ALSA - PaAlsa_Initialize, -#endif - -#ifdef PA_USE_JACK - PaJack_Initialize, -#endif - - - 0 /* NULL terminated array */ - }; - -int paDefaultHostApiIndex = 0; - - diff --git a/pd/portaudio/pa_unix/pa_unix_util.c b/pd/portaudio/pa_unix/pa_unix_util.c deleted file mode 100644 index 826d4e7c..00000000 --- a/pd/portaudio/pa_unix/pa_unix_util.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * $Id: pa_unix_util.c,v 1.1.2.1 2002/07/31 04:22:56 joshua 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 <unistd.h> -#include <stdlib.h> - -#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 = 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 ) -{ - usleep( msec * 1000 ); -} - - -static int usePerformanceCounter_; -static double microsecondsPerTick_; - -void PaUtil_InitializeClock( void ) -{ - /* TODO */ -} - - -double PaUtil_GetTime( void ) -{ - /* TODO */ - return (0); -} diff --git a/pd/portaudio/pa_unix_oss/Makefile b/pd/portaudio/pa_unix_oss/Makefile deleted file mode 100644 index f5015631..00000000 --- a/pd/portaudio/pa_unix_oss/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# Make PortAudio for Linux - -LIBS = -lm -lpthread - -CDEFINES = -I../pa_common -CFLAGS = -g -Wall -PASRC = ../pa_common/pa_lib.c pa_unix_oss.c -PAINC = ../pa_common/portaudio.h - -# Tests that work. -TESTC = $(PASRC) ../pa_tests/patest_sine.c -#TESTC = $(PASRC) ../pa_tests/patest_longsine.c -#TESTC = $(PASRC) ../pa_tests/patest_sine_time.c -#TESTC = $(PASRC) ../pa_tests/patest_maxsines.c -#TESTC = $(PASRC) ../pa_tests/patest_toomanysines.c -#TESTC = $(PASRC) ../pa_tests/patest_underflow.c -#TESTC = $(PASRC) ../pa_tests/patest_hang.c -#TESTC = $(PASRC) ../pa_tests/patest_sync.c -#TESTC = $(PASRC) ../pa_tests/patest_pink.c -#TESTC = $(PASRC) ../pa_tests/patest_leftright.c -#TESTC = $(PASRC) ../pa_tests/patest_clip.c -#TESTC = $(PASRC) ../pa_tests/patest_dither.c -#TESTC = $(PASRC) ../pa_tests/pa_devs.c -#TESTC = $(PASRC) ../pa_tests/patest_many.c -#TESTC = $(PASRC) ../pa_tests/patest_record.c -#TESTC = $(PASRC) ../pa_tests/pa_fuzz.c -#TESTC = $(PASRC) ../pa_tests/patest_wire.c -#TESTC = $(PASRC) ../pa_tests/paqa_devs.c - -# Tests that do not yet work. -# OSS doesn't let us make obscenely huge buffers so the test will seem to fail. But its OK. -#TESTC = $(PASRC) ../pa_tests/patest_stop.c - -TESTH = $(PAINC) - -all: patest - -patest: $(TESTC) $(TESTH) Makefile - gcc $(CFLAGS) $(TESTC) $(CDEFINES) $(LIBS) -o patest - -run: patest - ./patest - diff --git a/pd/portaudio/pa_unix_oss/Makefile_freebsd b/pd/portaudio/pa_unix_oss/Makefile_freebsd deleted file mode 100644 index fc8b14db..00000000 --- a/pd/portaudio/pa_unix_oss/Makefile_freebsd +++ /dev/null @@ -1,36 +0,0 @@ -# Make PortAudio for FreeBSD - -LIBS = -lm -pthread - -CDEFINES = -I../pa_common -CFLAGS = -g -PASRC = ../pa_common/pa_lib.c pa_freebsd.c -PAINC = ../pa_common/portaudio.h - -# Tests that work. -#TESTC = $(PASRC) ../pa_tests/patest_sine.c -TESTC = $(PASRC) ../pa_tests/patest_sine_time.c -#TESTC = $(PASRC) ../pa_tests/patest_stop.c -#TESTC = $(PASRC) ../pa_tests/patest_sync.c -#TESTC = $(PASRC) ../pa_tests/patest_pink.c -#TESTC = $(PASRC) ../pa_tests/patest_leftright.c -#TESTC = $(PASRC) ../pa_tests/patest_clip.c -#TESTC = $(PASRC) ../pa_tests/patest_dither.c -#TESTC = $(PASRC) ../pa_tests/pa_devs.c -#TESTC = $(PASRC) ../pa_tests/patest_many.c -#TESTC = $(PASRC) ../pa_tests/patest_record.c -#TESTC = $(PASRC) ../pa_tests/patest_wire.c -#TESTC = $(PASRC) ../pa_tests/paqa_devs.c - -# Tests that do not yet work. - -TESTH = $(PAINC) - -all: patest - -patest: $(TESTC) $(TESTH) Makefile - gcc $(CFLAGS) $(TESTC) $(CDEFINES) $(LIBS) -o patest - -run: patest - ./patest - diff --git a/pd/portaudio/pa_unix_oss/low_latency_tip.txt b/pd/portaudio/pa_unix_oss/low_latency_tip.txt Binary files differdeleted file mode 100644 index 2d982b79..00000000 --- a/pd/portaudio/pa_unix_oss/low_latency_tip.txt +++ /dev/null diff --git a/pd/portaudio/pa_unix_oss/pa_unix_oss.c b/pd/portaudio/pa_unix_oss/pa_unix_oss.c deleted file mode 100644 index 2e51b245..00000000 --- a/pd/portaudio/pa_unix_oss/pa_unix_oss.c +++ /dev/null @@ -1,1187 +0,0 @@ -/* - * $Id - * PortAudio Portable Real-Time Audio Library - * Latest Version at: http://www.portaudio.com - * OSS implementation by: - * Douglas Repetto - * Phil Burk - * Dominic Mazzoni - * - * 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 <sys/ioctl.h> -#include <fcntl.h> -#include <unistd.h> -#include <pthread.h> - -#ifdef __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" - -/* TODO: add error text handling -#define PA_UNIX_OSS_ERROR( errorCode, errorText ) \ - PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText ) -*/ - -#define PRINT(x) { printf x; fflush(stdout); } -#define DBUG(x) /* PRINT(x) */ - -/* PaOSSHostApiRepresentation - host api datastructure specific to this implementation */ - -typedef struct -{ - PaUtilHostApiRepresentation inheritedHostApiRep; - PaUtilStreamInterface callbackStreamInterface; - PaUtilStreamInterface blockingStreamInterface; - - PaUtilAllocationGroup *allocations; - - PaHostApiIndex hostApiIndex; -} -PaOSSHostApiRepresentation; - -typedef struct PaOSS_DeviceList { - PaDeviceInfo *deviceInfo; - struct PaOSS_DeviceList *next; -} -PaOSS_DeviceList; - -/* prototypes for functions declared in this file */ - -PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ); -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, void *buffer, unsigned long frames ); -static signed long GetStreamReadAvailable( PaStream* stream ); -static signed long GetStreamWriteAvailable( PaStream* stream ); -static PaError BuildDeviceList( PaOSSHostApiRepresentation *hostApi ); - - -PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) -{ - PaError result = paNoError; - PaOSSHostApiRepresentation *ossHostApi; - - DBUG(("PaOSS_Initialize\n")); - - ossHostApi = (PaOSSHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaOSSHostApiRepresentation) ); - if( !ossHostApi ) - { - result = paInsufficientMemory; - goto error; - } - - ossHostApi->allocations = PaUtil_CreateAllocationGroup(); - if( !ossHostApi->allocations ) - { - result = paInsufficientMemory; - goto error; - } - - *hostApi = &ossHostApi->inheritedHostApiRep; - (*hostApi)->info.structVersion = 1; - (*hostApi)->info.type = paOSS; - (*hostApi)->info.name = "OSS"; - ossHostApi->hostApiIndex = hostApiIndex; - - BuildDeviceList( ossHostApi ); - - (*hostApi)->Terminate = Terminate; - (*hostApi)->OpenStream = OpenStream; - (*hostApi)->IsFormatSupported = IsFormatSupported; - - PaUtil_InitializeStreamInterface( &ossHostApi->callbackStreamInterface, CloseStream, StartStream, - StopStream, AbortStream, IsStreamStopped, IsStreamActive, - GetStreamTime, GetStreamCpuLoad, - PaUtil_DummyReadWrite, PaUtil_DummyReadWrite, - PaUtil_DummyGetAvailable, PaUtil_DummyGetAvailable ); - - PaUtil_InitializeStreamInterface( &ossHostApi->blockingStreamInterface, CloseStream, StartStream, - StopStream, AbortStream, IsStreamStopped, IsStreamActive, - GetStreamTime, PaUtil_DummyGetCpuLoad, - ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); - - return result; - -error: - if( ossHostApi ) - { - if( ossHostApi->allocations ) - { - PaUtil_FreeAllAllocations( ossHostApi->allocations ); - PaUtil_DestroyAllocationGroup( ossHostApi->allocations ); - } - - PaUtil_FreeMemory( ossHostApi ); - } - return result; -} - -#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 - -PaError PaOSS_SetFormat(const char *callingFunctionName, int deviceHandle, - char *deviceName, int inputChannelCount, int outputChannelCount, - double *sampleRate) -{ - int format; - int rate; - int temp; - - /* Attempt to set format to 16-bit */ - - format = AFMT_S16_NE; - if (ioctl(deviceHandle, SNDCTL_DSP_SETFMT, &format) == -1) { - DBUG(("%s: could not set format: %s\n", callingFunctionName, deviceName )); - return paSampleFormatNotSupported; - } - if (format != AFMT_S16_NE) { - DBUG(("%s: device does not support AFMT_S16_NE: %s\n", callingFunctionName, deviceName )); - return paSampleFormatNotSupported; - } - - /* try to set the number of channels */ - - if (inputChannelCount > 0) { - temp = inputChannelCount; - - if( ioctl(deviceHandle, SNDCTL_DSP_CHANNELS, &temp) < 0 ) { - DBUG(("%s: Couldn't set device %s to %d channels\n", callingFunctionName, deviceName, inputChannelCount )); - return paSampleFormatNotSupported; - } - } - - if (outputChannelCount > 0) { - temp = outputChannelCount; - - if( ioctl(deviceHandle, SNDCTL_DSP_CHANNELS, &temp) < 0 ) { - DBUG(("%s: Couldn't set device %s to %d channels\n", callingFunctionName, deviceName, outputChannelCount )); - return paSampleFormatNotSupported; - } - } - - /* try to set the sample rate */ - - rate = (int)(*sampleRate); - if (ioctl(deviceHandle, SNDCTL_DSP_SPEED, &rate) == -1) - { - DBUG(("%s: Device %s, couldn't set sample rate to %d\n", - callingFunctionName, deviceName, (int)*sampleRate )); - return paInvalidSampleRate; - } - - /* reject if there's no sample rate within 1% of the one requested */ - if ((fabs(*sampleRate - rate) / *sampleRate) > 0.01) - { - DBUG(("%s: Device %s, wanted %d, closest sample rate was %d\n", - callingFunctionName, deviceName, (int)*sampleRate, rate )); - return paInvalidSampleRate; - } - - *sampleRate = rate; - - return paNoError; -} - -static PaError PaOSS_QueryDevice(char *deviceName, PaDeviceInfo *deviceInfo) -{ - PaError result = paNoError; - int tempDevHandle; - int numChannels, maxNumChannels; - int sampleRate; - int format; - - /* 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 - */ - - if ( (tempDevHandle = open(deviceName,O_WRONLY|O_NONBLOCK)) == -1 ) - { - DBUG(("PaOSS_QueryDevice: could not open %s\n", deviceName )); - return paDeviceUnavailable; - } - - /* Attempt to set format to 16-bit */ - format = AFMT_S16_NE; - if (ioctl(tempDevHandle, SNDCTL_DSP_SETFMT, &format) == -1) { - DBUG(("PaOSS_QueryDevice: could not set format: %s\n", deviceName )); - result = paSampleFormatNotSupported; - goto error; - } - if (format != AFMT_S16_NE) { - DBUG(("PaOSS_QueryDevice: device does not support AFMT_S16_NE: %s\n", deviceName )); - result = paSampleFormatNotSupported; - goto error; - } - - /* 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; - DBUG(("PaOSS_QueryDevice: use SNDCTL_DSP_CHANNELS, numChannels = %d\n", numChannels )) - if(ioctl(tempDevHandle, SNDCTL_DSP_CHANNELS, &temp) < 0 ) - { - /* ioctl() failed so bail out if we already have stereo */ - if( numChannels > 2 ) break; - } - else - { - /* ioctl() worked but bail out if it does not support numChannels. - * We don't want to leave gaps in the numChannels supported. - */ - if( (numChannels > 2) && (temp != numChannels) ) break; - DBUG(("PaOSS_QueryDevice: temp = %d\n", temp )) - if( temp > maxNumChannels ) maxNumChannels = temp; /* Save maximum. */ - } - } - - /* The above negotiation may fail for an old driver so try this older technique. */ - if( maxNumChannels < 1 ) - { - int stereo = 1; - if(ioctl(tempDevHandle, SNDCTL_DSP_STEREO, &stereo) < 0) - { - maxNumChannels = 1; - } - else - { - maxNumChannels = (stereo) ? 2 : 1; - } - DBUG(("PaOSS_QueryDevice: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", maxNumChannels )) - } - - DBUG(("PaOSS_QueryDevice: maxNumChannels = %d\n", maxNumChannels)) - - deviceInfo->maxOutputChannels = maxNumChannels; - /* FIXME - for now, assume maxInputChannels = maxOutputChannels. - * Eventually do separate queries for O_WRONLY and O_RDONLY - */ - deviceInfo->maxInputChannels = deviceInfo->maxOutputChannels; - - /* During channel negotiation, the last ioctl() may have failed. This can - * also cause sample rate negotiation to fail. Hence the following, to return - * to a supported number of channels. SG20011005 */ - { - int temp = maxNumChannels; - if( temp > 2 ) temp = 2; /* use most reasonable default value */ - ioctl(tempDevHandle, SNDCTL_DSP_CHANNELS, &temp); - } - - /* Get supported sample rate closest to 44100 Hz */ - sampleRate = 44100; - if (ioctl(tempDevHandle, SNDCTL_DSP_SPEED, &sampleRate) == -1) - { - result = paUnanticipatedHostError; - goto error; - } - - deviceInfo->defaultSampleRate = sampleRate; - - deviceInfo->structVersion = 2; - - /* TODO */ - deviceInfo->defaultLowInputLatency = 128.0 / sampleRate; - deviceInfo->defaultLowOutputLatency = 128.0 / sampleRate; - deviceInfo->defaultHighInputLatency = 16384.0 / sampleRate; - deviceInfo->defaultHighOutputLatency = 16384.0 / sampleRate; - - result = paNoError; - -error: - /* We MUST close the handle here or we won't be able to reopen it later!!! */ - close(tempDevHandle); - - return result; -} - -static PaError BuildDeviceList( PaOSSHostApiRepresentation *ossApi ) -{ - PaUtilHostApiRepresentation *commonApi = &ossApi->inheritedHostApiRep; - PaOSS_DeviceList *head = NULL, *tail = NULL, *entry; - int i; - int numDevices; - - /* Find devices by calling PaOSS_QueryDevice on each - potential device names. When we find a valid one, - add it to a linked list. */ - - for(i=0; i<10; i++) { - char deviceName[32]; - PaDeviceInfo deviceInfo; - int testResult; - - if (i==0) - sprintf(deviceName, "%s", DEVICE_NAME_BASE); - else - sprintf(deviceName, "%s%d", DEVICE_NAME_BASE, i); - - DBUG(("PaOSS BuildDeviceList: trying device %s\n", deviceName )); - testResult = PaOSS_QueryDevice(deviceName, &deviceInfo); - DBUG(("PaOSS BuildDeviceList: PaOSS_QueryDevice returned %d\n", testResult )); - - if (testResult == paNoError) { - DBUG(("PaOSS BuildDeviceList: Adding device %s to list\n", deviceName)); - deviceInfo.hostApi = ossApi->hostApiIndex; - deviceInfo.name = PaUtil_GroupAllocateMemory( - ossApi->allocations, strlen(deviceName)+1); - strcpy((char *)deviceInfo.name, deviceName); - entry = (PaOSS_DeviceList *)PaUtil_AllocateMemory(sizeof(PaOSS_DeviceList)); - entry->deviceInfo = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( - ossApi->allocations, sizeof(PaDeviceInfo) ); - entry->next = NULL; - memcpy(entry->deviceInfo, &deviceInfo, sizeof(PaDeviceInfo)); - if (tail) - tail->next = entry; - else { - head = entry; - tail = entry; - } - } - } - - /* Make an array of PaDeviceInfo pointers out of the linked list */ - - numDevices = 0; - entry = head; - while(entry) { - numDevices++; - entry = entry->next; - } - - DBUG(("PaOSS BuildDeviceList: Total number of devices found: %d\n", numDevices)); - - commonApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( - ossApi->allocations, sizeof(PaDeviceInfo*) *numDevices ); - - entry = head; - i = 0; - while(entry) { - commonApi->deviceInfos[i] = entry->deviceInfo; - i++; - entry = entry->next; - } - - commonApi->info.deviceCount = numDevices; - commonApi->info.defaultInputDevice = 0; - commonApi->info.defaultOutputDevice = 0; - - return paNoError; -} - -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 ) -{ - PaDeviceIndex device; - PaDeviceInfo *deviceInfo; - PaError result = paNoError; - char *deviceName; - int inputChannelCount, outputChannelCount; - int tempDevHandle = 0; - 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; - - if ( (tempDevHandle = open(deviceInfo->name, flags)) == -1 ) - { - DBUG(("PaOSS IsFormatSupported: could not open %s\n", deviceName )); - return paDeviceUnavailable; - } - - /* PaOSS_SetFormat will do the rest of the checking for us */ - - if ((result = PaOSS_SetFormat("PaOSS IsFormatSupported", tempDevHandle, - deviceName, inputChannelCount, outputChannelCount, - &sampleRate)) != paNoError) - { - goto error; - } - - /* everything succeeded! */ - - close(tempDevHandle); - - return paFormatIsSupported; - - error: - if (tempDevHandle) - close(tempDevHandle); - - return paSampleFormatNotSupported; -} - -/* PaOSSStream - a stream data structure specifically for this implementation */ - -typedef struct PaOSSStream -{ - PaUtilStreamRepresentation streamRepresentation; - PaUtilCpuLoadMeasurer cpuLoadMeasurer; - PaUtilBufferProcessor bufferProcessor; - - int deviceHandle; - - int stopSoon; - int stopNow; - int isActive; - - int inputChannelCount; - int outputChannelCount; - - pthread_t thread; - - void *inputBuffer; - void *outputBuffer; - - int lastPosPtr; - double lastStreamBytes; - - int framesProcessed; - - double sampleRate; - - unsigned long framesPerHostCallback; -} -PaOSSStream; - -/* 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; - PaOSSHostApiRepresentation *ossHostApi = (PaOSSHostApiRepresentation*)hostApi; - PaOSSStream *stream = 0; - PaDeviceIndex device; - PaDeviceInfo *deviceInfo; - audio_buf_info bufinfo; - int bytesPerHostBuffer; - int flags; - int deviceHandle = 0; - char *deviceName; - unsigned long framesPerHostBuffer; - int inputChannelCount, outputChannelCount; - PaSampleFormat inputSampleFormat = paInt16, outputSampleFormat = paInt16; - PaSampleFormat hostInputSampleFormat = paInt16, hostOutputSampleFormat = paInt16; - - 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 */ - - hostInputSampleFormat = - PaUtil_SelectClosestAvailableFormat( paInt16, inputSampleFormat ); - } - 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 */ - - hostOutputSampleFormat = - PaUtil_SelectClosestAvailableFormat( paInt16, outputSampleFormat ); - } - else - { - outputChannelCount = 0; - } - - if( inputChannelCount == 0 && outputChannelCount == 0 ) - { - DBUG(("Both inputChannelCount and outputChannelCount are zero!\n")); - return paUnanticipatedHostError; - } - - /* validate platform specific flags */ - if( (streamFlags & paPlatformSpecificFlags) != 0 ) - return paInvalidFlag; /* unexpected platform specific flag */ - - /* - * open the device and set parameters here - */ - - 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; - - 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; - - /* open first in nonblocking mode, in case it's busy... */ - if ( (deviceHandle = open(deviceInfo->name, flags)) == -1 ) - { - DBUG(("PaOSS OpenStream: could not open %s\n", deviceName )); - return paDeviceUnavailable; - } - - /* if that succeeded, immediately open it again in blocking mode */ - close(deviceHandle); - flags -= O_NONBLOCK; - if ( (deviceHandle = open(deviceInfo->name, flags)) == -1 ) - { - DBUG(("PaOSS OpenStream: could not open %s in blocking mode\n", deviceName )); - return paDeviceUnavailable; - } - - if ((result = PaOSS_SetFormat("PaOSS OpenStream", deviceHandle, - deviceName, inputChannelCount, outputChannelCount, - &sampleRate)) != paNoError) - { - goto error; - } - - /* Compute number of frames per host buffer - if we can't retrieve the - * value, use the user's value instead - */ - - if ( ioctl(deviceHandle, SNDCTL_DSP_GETBLKSIZE, &bytesPerHostBuffer) == 0) - { - framesPerHostBuffer = bytesPerHostBuffer / 2 / (inputChannelCount>0? inputChannelCount: outputChannelCount); - } - else - framesPerHostBuffer = framesPerBuffer; - - /* Allocate stream and fill in structure */ - - stream = (PaOSSStream*)PaUtil_AllocateMemory( sizeof(PaOSSStream) ); - if( !stream ) - { - result = paInsufficientMemory; - goto error; - } - - if( streamCallback ) - { - PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, - &ossHostApi->callbackStreamInterface, streamCallback, userData ); - } - else - { - PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, - &ossHostApi->blockingStreamInterface, streamCallback, userData ); - } - - stream->streamRepresentation.streamInfo.inputLatency = 0.; - stream->streamRepresentation.streamInfo.outputLatency = 0.; - - if (inputChannelCount > 0) { - if (ioctl( deviceHandle, SNDCTL_DSP_GETISPACE, &bufinfo) == 0) - stream->streamRepresentation.streamInfo.inputLatency = - (bufinfo.fragsize * bufinfo.fragstotal) / sampleRate; - } - - if (outputChannelCount > 0) { - if (ioctl( deviceHandle, SNDCTL_DSP_GETOSPACE, &bufinfo) == 0) - stream->streamRepresentation.streamInfo.outputLatency = - (bufinfo.fragsize * bufinfo.fragstotal) / sampleRate; - } - - stream->streamRepresentation.streamInfo.sampleRate = sampleRate; - - 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; - - stream->framesPerHostCallback = framesPerHostBuffer; - - stream->stopSoon = 0; - stream->stopNow = 0; - stream->isActive = 0; - stream->thread = 0; - stream->lastPosPtr = 0; - stream->lastStreamBytes = 0; - stream->sampleRate = sampleRate; - stream->framesProcessed = 0; - stream->deviceHandle = deviceHandle; - - if (inputChannelCount > 0) - stream->inputBuffer = PaUtil_AllocateMemory( 2 * framesPerHostBuffer * inputChannelCount ); - else - stream->inputBuffer = NULL; - - if (outputChannelCount > 0) - stream->outputBuffer = PaUtil_AllocateMemory( 2 * framesPerHostBuffer * outputChannelCount ); - else - stream->outputBuffer = NULL; - - stream->inputChannelCount = inputChannelCount; - stream->outputChannelCount = outputChannelCount; - - *s = (PaStream*)stream; - - result = paNoError; - - return result; - -error: - if( stream ) - PaUtil_FreeMemory( stream ); - - if( deviceHandle ) - close( deviceHandle ); - - return result; -} - -static void *PaOSS_AudioThreadProc(void *userData) -{ - PaOSSStream *stream = (PaOSSStream*)userData; - - DBUG(("PaOSS AudioThread: %d in, %d out\n", stream->inputChannelCount, stream->outputChannelCount)); - - while( (stream->stopNow == 0) && (stream->stopSoon == 0) ) { - PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* TODO: IMPLEMENT ME */ - int callbackResult; - unsigned long framesProcessed; - int bytesRequested; - int bytesRead, bytesWritten; - int delta; - int result; - count_info info; - - PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); - - PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo ); - - /* - 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. - */ - - if ( stream->inputChannelCount > 0 ) - { - bytesRequested = stream->framesPerHostCallback * 2 * stream->inputChannelCount; - bytesRead = read( stream->deviceHandle, stream->inputBuffer, bytesRequested ); - - PaUtil_SetInputFrameCount( &stream->bufferProcessor, bytesRead/(2*stream->inputChannelCount)); - PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, - 0, /* first channel of inputBuffer is channel 0 */ - stream->inputBuffer, - 0 ); /* 0 - use inputChannelCount passed to init buffer processor */ - } - - if ( stream->outputChannelCount > 0 ) - { - PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); - PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, - 0, /* first channel of outputBuffer is channel 0 */ - stream->outputBuffer, - 0 ); /* 0 - use outputChannelCount passed to init buffer processor */ - } - - framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); - - PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); - - if( callbackResult == paContinue ) - { - /* nothing special to do */ - } - else if( callbackResult == paAbort ) - { - /* once finished, call the finished callback */ - if( stream->streamRepresentation.streamFinishedCallback != 0 ) - stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); - - return NULL; /* return from the loop */ - } - else if ( callbackResult == paComplete ) - { - /* User callback has asked us to stop with paComplete or other non-zero value */ - - /* once finished, call the finished callback */ - if( stream->streamRepresentation.streamFinishedCallback != 0 ) - stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); - - stream->stopSoon = 1; - } - - if ( stream->outputChannelCount > 0 ) { - /* write output samples AFTER we've checked the callback result code */ - - bytesRequested = stream->framesPerHostCallback * 2 * stream->outputChannelCount; - bytesWritten = write( stream->deviceHandle, stream->outputBuffer, bytesRequested ); - - /* TODO: handle bytesWritten != bytesRequested (slippage?) */ - } - - /* Update current stream time (using a double so that - we don't wrap around like info.bytes does) */ - if( stream->outputChannelCount > 0 ) - result = ioctl( stream->deviceHandle, SNDCTL_DSP_GETOPTR, &info); - else - result = ioctl( stream->deviceHandle, SNDCTL_DSP_GETIPTR, &info); - - if (result == 0) { - delta = ( info.bytes - stream->lastPosPtr ) & 0x000FFFFF; - stream->lastStreamBytes += delta; - stream->lastPosPtr = info.bytes; - } - - stream->framesProcessed += stream->framesPerHostCallback; - } - - return NULL; -} - -/* - 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; - PaOSSStream *stream = (PaOSSStream*)s; - - close(stream->deviceHandle); - - if ( stream->inputBuffer ) - PaUtil_FreeMemory( stream->inputBuffer ); - if ( stream->outputBuffer ) - PaUtil_FreeMemory( stream->outputBuffer ); - - PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); - PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); - PaUtil_FreeMemory( stream ); - - return result; -} - - -static PaError StartStream( PaStream *s ) -{ - PaError result = paNoError; - PaOSSStream *stream = (PaOSSStream*)s; - int presult; - - stream->isActive = 1; - stream->lastPosPtr = 0; - stream->lastStreamBytes = 0; - stream->framesProcessed = 0; - - DBUG(("PaOSS StartStream\n")); - - presult = pthread_create(&stream->thread, - NULL /*pthread_attr_t * attr*/, - (void*)PaOSS_AudioThreadProc, (void *)stream); - - return result; -} - - -static PaError StopStream( PaStream *s ) -{ - PaError result = paNoError; - PaOSSStream *stream = (PaOSSStream*)s; - - stream->stopSoon = 1; - pthread_join( stream->thread, NULL ); - stream->stopSoon = 0; - stream->stopNow = 0; - stream->isActive = 0; - - DBUG(("PaOSS StopStream: Stopped stream\n")); - - return result; -} - - -static PaError AbortStream( PaStream *s ) -{ - PaError result = paNoError; - PaOSSStream *stream = (PaOSSStream*)s; - - stream->stopNow = 1; - pthread_join( stream->thread, NULL ); - stream->stopSoon = 0; - stream->stopNow = 0; - stream->isActive = 0; - - DBUG(("PaOSS AbortStream: Stopped stream\n")); - - return result; -} - - -static PaError IsStreamStopped( PaStream *s ) -{ - PaOSSStream *stream = (PaOSSStream*)s; - - return (!stream->isActive); -} - - -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->outputChannelCount > 0 ) { - if (ioctl( stream->deviceHandle, SNDCTL_DSP_GETOPTR, &info) == 0) { - delta = ( info.bytes - stream->lastPosPtr ) & 0x000FFFFF; - return ( stream->lastStreamBytes + delta) / ( stream->outputChannelCount * 2 ) / stream->sampleRate; - } - } - else { - if (ioctl( stream->deviceHandle, SNDCTL_DSP_GETIPTR, &info) == 0) { - delta = (info.bytes - stream->lastPosPtr) & 0x000FFFFF; - return ( stream->lastStreamBytes + delta) / ( stream->inputChannelCount * 2 ) / 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; - - bytesRequested = frames * 2 * stream->inputChannelCount; - bytesRead = read( stream->deviceHandle, stream->inputBuffer, bytesRequested ); - - if ( bytesRequested != bytesRead ) - return paUnanticipatedHostError; - else - return paNoError; -} - - -static PaError WriteStream( PaStream* s, - void *buffer, - unsigned long frames ) -{ - PaOSSStream *stream = (PaOSSStream*)s; - int bytesRequested, bytesWritten; - - bytesRequested = frames * 2 * stream->outputChannelCount; - bytesWritten = write( stream->deviceHandle, buffer, bytesRequested ); - - if ( bytesRequested != bytesWritten ) - return paUnanticipatedHostError; - else - return paNoError; -} - - -static signed long GetStreamReadAvailable( PaStream* s ) -{ - PaOSSStream *stream = (PaOSSStream*)s; - audio_buf_info info; - - if ( ioctl(stream->deviceHandle, SNDCTL_DSP_GETISPACE, &info) == 0) - { - int bytesAvailable = info.fragments * info.fragsize; - return ( bytesAvailable / 2 / stream->inputChannelCount ); - } - else - return 0; /* TODO: is this right for "don't know"? */ -} - - -static signed long GetStreamWriteAvailable( PaStream* s ) -{ - PaOSSStream *stream = (PaOSSStream*)s; - - audio_buf_info info; - - if ( ioctl(stream->deviceHandle, SNDCTL_DSP_GETOSPACE, &info) == 0) - { - int bytesAvailable = info.fragments * info.fragsize; - return ( bytesAvailable / 2 / stream->outputChannelCount ); - } - else - return 0; /* TODO: is this right for "don't know"? */ -} - diff --git a/pd/portaudio/pa_unix_oss/recplay.c b/pd/portaudio/pa_unix_oss/recplay.c deleted file mode 100644 index 9d4c78cf..00000000 --- a/pd/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/pd/portaudio/pa_win/pa_win_hostapis.c b/pd/portaudio/pa_win/pa_win_hostapis.c deleted file mode 100644 index 2b518512..00000000 --- a/pd/portaudio/pa_win/pa_win_hostapis.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * $Id: pa_win_hostapis.c,v 1.1.2.6 2002/10/26 05:32:35 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. - */ - - -#include "pa_hostapi.h" - -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 ); - - -PaUtilHostApiInitializer *paHostApiInitializers[] = - { - -#ifndef PA_NO_WMME - PaWinMme_Initialize, -#endif - -#ifndef PA_NO_DS - PaWinDs_Initialize, -#endif - -#ifndef PA_NO_ASIO - PaAsio_Initialize, -#endif - - PaSkeleton_Initialize, /* just for testing */ - - 0 /* NULL terminated array */ - }; - - -int paDefaultHostApiIndex = 0; - diff --git a/pd/portaudio/pa_win/pa_win_util.c b/pd/portaudio/pa_win/pa_win_util.c deleted file mode 100644 index f92d1e35..00000000 --- a/pd/portaudio/pa_win/pa_win_util.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * $Id: pa_win_util.c,v 1.1.2.5 2002/10/18 18:36:57 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. - */ - - -#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/pd/portaudio/pa_win/pa_x86_plain_converters.c b/pd/portaudio/pa_win/pa_x86_plain_converters.c deleted file mode 100644 index 98442a8c..00000000 --- a/pd/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/pd/portaudio/pa_win/pa_x86_plain_converters.h b/pd/portaudio/pa_win/pa_x86_plain_converters.h deleted file mode 100644 index b93a291c..00000000 --- a/pd/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 */ - - -/** - 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/pd/portaudio/pa_win_ds/dsound_wrapper.c b/pd/portaudio/pa_win_ds/dsound_wrapper.c deleted file mode 100644 index ac8c927d..00000000 --- a/pd/portaudio/pa_win_ds/dsound_wrapper.c +++ /dev/null @@ -1,604 +0,0 @@ -/* - * $Id: dsound_wrapper.c,v 1.1.1.1.2.5 2002/07/01 00:49:41 philburk 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> -#define INITGUID // Needed to build IID_IDirectSoundNotify. See objbase.h for info. -#include <objbase.h> -#include <unknwn.h> -#include "dsound_wrapper.h" -#include "pa_trace.h" - -/************************************************************************************/ -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, int 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(); - 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 = 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( ¤tTime ); - 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, int 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 = 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/pd/portaudio/pa_win_ds/dsound_wrapper.h b/pd/portaudio/pa_win_ds/dsound_wrapper.h deleted file mode 100644 index e9ce4c6b..00000000 --- a/pd/portaudio/pa_win_ds/dsound_wrapper.h +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef __DSOUND_WRAPPER_H -#define __DSOUND_WRAPPER_H -/* - * $Id: dsound_wrapper.h,v 1.1.1.1.2.5 2002/07/03 01:43:56 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 - -#include <DSound.h> -#if !defined(BOOL) -#define BOOL short -#endif - - -#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, - int 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, - int 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/pd/portaudio/pa_win_ds/pa_dsound.c b/pd/portaudio/pa_win_ds/pa_dsound.c deleted file mode 100644 index 8fa343cf..00000000 --- a/pd/portaudio/pa_win_ds/pa_dsound.c +++ /dev/null @@ -1,1021 +0,0 @@ -/* - * $Id: pa_dsound.c,v 1.1.1.1 2003-05-09 16:03:58 ggeiger Exp $ - * PortAudio Portable Real-Time Audio Library - * Latest Version at: http://www.softsynth.com/portaudio/ - * DirectSound Implementation - * - * Copyright (c) 1999-2000 Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -/* Modifications - * 7/19/01 Mike Berry - casts for compiling with __MWERKS__ CodeWarrior - * 9/27/01 Phil Burk - use number of frames instead of real-time for CPULoad calculation. - * 4/19/02 Phil Burk - Check for Win XP for system latency calculation. - */ -/* Compiler flags: - SUPPORT_AUDIO_CAPTURE - define this flag if you want to SUPPORT_AUDIO_CAPTURE - */ - -#include <stdio.h> -#include <stdlib.h> -#ifndef __MWERKS__ -#include <malloc.h> -#include <memory.h> -#endif //__MWERKS__ -#include <math.h> -#include "portaudio.h" -#include "pa_host.h" -#include "pa_trace.h" -#include "dsound_wrapper.h" - -#define PRINT(x) { printf x; fflush(stdout); } -#define ERR_RPT(x) PRINT(x) -#define DBUG(x) /* PRINT(x) */ -#define DBUGX(x) /* PRINT(x) */ - -#define PA_USE_HIGH_LATENCY (0) -#if PA_USE_HIGH_LATENCY -#define PA_WIN_9X_LATENCY (500) -#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) - -/* Trigger an underflow for testing purposes. Should normally be (0). */ -#define PA_SIMULATE_UNDERFLOW (0) -#if PA_SIMULATE_UNDERFLOW -static gUnderCallbackCounter = 0; -#define UNDER_START_GAP (10) -#define UNDER_STOP_GAP (UNDER_START_GAP + 4) -#endif - -/************************************************* Definitions ********/ -typedef struct internalPortAudioStream internalPortAudioStream; -typedef struct internalPortAudioDevice -{ - GUID pad_GUID; - GUID *pad_lpGUID; - double pad_SampleRates[10]; /* for pointing to from pad_Info FIXME?!*/ - PaDeviceInfo pad_Info; -} -internalPortAudioDevice; - -/* Define structure to contain all DirectSound and Windows specific data. */ -typedef struct PaHostSoundControl -{ - DSoundWrapper pahsc_DSoundWrapper; - MMRESULT pahsc_TimerID; - BOOL pahsc_IfInsideCallback; /* Test for reentrancy. */ - short *pahsc_NativeBuffer; - unsigned int pahsc_BytesPerBuffer; /* native buffer size in bytes */ - double pahsc_ValidFramesWritten; - int pahsc_FramesPerDSBuffer; - /* For measuring CPU utilization. */ - LARGE_INTEGER pahsc_EntryCount; - double pahsc_InverseTicksPerUserBuffer; -} -PaHostSoundControl; - -/************************************************* Shared Data ********/ -/* FIXME - put Mutex around this shared data. */ -static int sNumDevices = 0; -static int sDeviceIndex = 0; -static internalPortAudioDevice *sDevices = NULL; -static int sDefaultInputDeviceID = paNoDevice; -static int sDefaultOutputDeviceID = paNoDevice; -static int sEnumerationError; -static int sPaHostError = 0; -/************************************************* Prototypes **********/ -static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id ); -static BOOL CALLBACK Pa_EnumProc(LPGUID lpGUID, - LPCTSTR lpszDesc, - LPCTSTR lpszDrvName, - LPVOID lpContext ); -static BOOL CALLBACK Pa_CountDevProc(LPGUID lpGUID, - LPCTSTR lpszDesc, - LPCTSTR lpszDrvName, - LPVOID lpContext ); -static Pa_QueryDevices( void ); -static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, - DWORD dwUser, DWORD dw1, DWORD dw2); - -/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/ -static void Pa_StartUsageCalculation( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return; - /* Query system timer for usage analysis and to prevent overuse of CPU. */ - QueryPerformanceCounter( &pahsc->pahsc_EntryCount ); -} - -static void Pa_EndUsageCalculation( internalPortAudioStream *past ) -{ - LARGE_INTEGER CurrentCount = { 0, 0 }; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return; - /* - ** Measure CPU utilization during this callback. Note that this calculation - ** assumes that we had the processor the whole time. - */ -#define LOWPASS_COEFFICIENT_0 (0.9) -#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0) - if( QueryPerformanceCounter( &CurrentCount ) ) - { - LONGLONG InsideCount = CurrentCount.QuadPart - pahsc->pahsc_EntryCount.QuadPart; - double newUsage = InsideCount * pahsc->pahsc_InverseTicksPerUserBuffer; - past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) + - (LOWPASS_COEFFICIENT_1 * newUsage); - } -} - -/****************************************** END CPU UTILIZATION *******/ -static PaError Pa_QueryDevices( void ) -{ - int numBytes; - sDefaultInputDeviceID = paNoDevice; - sDefaultOutputDeviceID = paNoDevice; - /* Enumerate once just to count devices. */ - sNumDevices = 0; // for default device - DirectSoundEnumerate( (LPDSENUMCALLBACK)Pa_CountDevProc, NULL ); -#if SUPPORT_AUDIO_CAPTURE - DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)Pa_CountDevProc, NULL ); -#endif /* SUPPORT_AUDIO_CAPTURE */ - /* Allocate structures to hold device info. */ - numBytes = sNumDevices * sizeof(internalPortAudioDevice); - sDevices = (internalPortAudioDevice *)PaHost_AllocateFastMemory( numBytes ); /* MEM */ - if( sDevices == NULL ) return paInsufficientMemory; - /* Enumerate again to fill in structures. */ - sDeviceIndex = 0; - sEnumerationError = 0; - DirectSoundEnumerate( (LPDSENUMCALLBACK)Pa_EnumProc, (void *)0 ); -#if SUPPORT_AUDIO_CAPTURE - if( sEnumerationError != paNoError ) return sEnumerationError; - sEnumerationError = 0; - DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)Pa_EnumProc, (void *)1 ); -#endif /* SUPPORT_AUDIO_CAPTURE */ - return sEnumerationError; -} -/************************************************************************************/ -long Pa_GetHostError() -{ - return sPaHostError; -} -/************************************************************************************ -** Just count devices so we know how much memory to allocate. -*/ -static BOOL CALLBACK Pa_CountDevProc(LPGUID lpGUID, - LPCTSTR lpszDesc, - LPCTSTR lpszDrvName, - LPVOID lpContext ) -{ - sNumDevices++; - return TRUE; -} -/************************************************************************************ -** Extract capabilities info from each device. -*/ -static BOOL CALLBACK Pa_EnumProc(LPGUID lpGUID, - LPCTSTR lpszDesc, - LPCTSTR lpszDrvName, - LPVOID lpContext ) -{ - HRESULT hr; - LPDIRECTSOUND lpDirectSound; -#if SUPPORT_AUDIO_CAPTURE - LPDIRECTSOUNDCAPTURE lpDirectSoundCapture; -#endif /* SUPPORT_AUDIO_CAPTURE */ - int isInput = (int) lpContext; /* Passed from Pa_CountDevices() */ - internalPortAudioDevice *pad; - - if( sDeviceIndex >= sNumDevices ) - { - sEnumerationError = paInternalError; - return FALSE; - } - pad = &sDevices[sDeviceIndex]; - /* Copy GUID to static array. Set pointer. */ - if( lpGUID == NULL ) - { - pad->pad_lpGUID = NULL; - } - else - { - memcpy( &pad->pad_GUID, lpGUID, sizeof(GUID) ); - pad->pad_lpGUID = &pad->pad_GUID; - } - pad->pad_Info.sampleRates = pad->pad_SampleRates; /* Point to array. */ - /* Allocate room for descriptive name. */ - if( lpszDesc != NULL ) - { - int len = strlen(lpszDesc); - pad->pad_Info.name = (char *)malloc( len+1 ); - if( pad->pad_Info.name == NULL ) - { - sEnumerationError = paInsufficientMemory; - return FALSE; - } - memcpy( (void *) pad->pad_Info.name, lpszDesc, len+1 ); - } -#if SUPPORT_AUDIO_CAPTURE - if( isInput ) - { - /********** Input ******************************/ - DSCCAPS caps; - if( lpGUID == NULL ) sDefaultInputDeviceID = sDeviceIndex; - hr = DirectSoundCaptureCreate( lpGUID, &lpDirectSoundCapture, NULL ); - if( hr != DS_OK ) - { - pad->pad_Info.maxInputChannels = 0; - DBUG(("Cannot create Capture for %s. Result = 0x%x\n", lpszDesc, hr )); - } - else - { - /* Query device characteristics. */ - caps.dwSize = sizeof(caps); - IDirectSoundCapture_GetCaps( lpDirectSoundCapture, &caps ); - /* printf("caps.dwFormats = 0x%x\n", caps.dwFormats ); */ - pad->pad_Info.maxInputChannels = caps.dwChannels; - /* Determine sample rates from flags. */ - if( caps.dwChannels == 2 ) - { - int index = 0; - if( caps.dwFormats & WAVE_FORMAT_1S16) pad->pad_SampleRates[index++] = 11025.0; - if( caps.dwFormats & WAVE_FORMAT_2S16) pad->pad_SampleRates[index++] = 22050.0; - if( caps.dwFormats & WAVE_FORMAT_4S16) pad->pad_SampleRates[index++] = 44100.0; - pad->pad_Info.numSampleRates = index; - } - else if( caps.dwChannels == 1 ) - { - int index = 0; - if( caps.dwFormats & WAVE_FORMAT_1M16) pad->pad_SampleRates[index++] = 11025.0; - if( caps.dwFormats & WAVE_FORMAT_2M16) pad->pad_SampleRates[index++] = 22050.0; - if( caps.dwFormats & WAVE_FORMAT_4M16) pad->pad_SampleRates[index++] = 44100.0; - pad->pad_Info.numSampleRates = index; - } - else pad->pad_Info.numSampleRates = 0; - IDirectSoundCapture_Release( lpDirectSoundCapture ); - } - } - else -#endif /* SUPPORT_AUDIO_CAPTURE */ - - { - /********** Output ******************************/ - DSCAPS caps; - if( lpGUID == NULL ) sDefaultOutputDeviceID = sDeviceIndex; - /* Create interfaces for each object. */ - hr = DirectSoundCreate( lpGUID, &lpDirectSound, NULL ); - if( hr != DS_OK ) - { - pad->pad_Info.maxOutputChannels = 0; - DBUG(("Cannot create dsound for %s. Result = 0x%x\n", lpszDesc, hr )); - } - else - { - /* Query device characteristics. */ - caps.dwSize = sizeof(caps); - IDirectSound_GetCaps( lpDirectSound, &caps ); - pad->pad_Info.maxOutputChannels = ( caps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1; - /* Get sample rates. */ - pad->pad_SampleRates[0] = (double) caps.dwMinSecondarySampleRate; - pad->pad_SampleRates[1] = (double) caps.dwMaxSecondarySampleRate; - if( caps.dwFlags & DSCAPS_CONTINUOUSRATE ) pad->pad_Info.numSampleRates = -1; - 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. - */ - pad->pad_SampleRates[0] = 11025.0f; - pad->pad_SampleRates[1] = 48000.0f; - pad->pad_Info.numSampleRates = -1; /* continuous range */ - - DBUG(("PA - Reported rates both zero. Setting to fake values for device #%d\n", sDeviceIndex )); - } - else - { - pad->pad_Info.numSampleRates = 1; - } - } - 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. - */ - pad->pad_Info.numSampleRates = -1; - DBUG(("PA - Sample rate range used instead of two odd values for device #%d\n", sDeviceIndex )); - } - else pad->pad_Info.numSampleRates = 2; - IDirectSound_Release( lpDirectSound ); - } - } - pad->pad_Info.nativeSampleFormats = paInt16; - sDeviceIndex++; - return( TRUE ); -} -/*************************************************************************/ -int Pa_CountDevices() -{ - if( sNumDevices <= 0 ) Pa_Initialize(); - return sNumDevices; -} -static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id ) -{ - if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL; - return &sDevices[id]; -} -/*************************************************************************/ -const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id ) -{ - internalPortAudioDevice *pad; - if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL; - pad = Pa_GetInternalDevice( id ); - return &pad->pad_Info ; -} -static PaError Pa_MaybeQueryDevices( void ) -{ - if( sNumDevices == 0 ) - { - return Pa_QueryDevices(); - } - return 0; -} -/************************************************************************* -** 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 PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName ) -{ - DWORD hresult; - char envbuf[PA_ENV_BUF_SIZE]; - PaDeviceID recommendedID = paNoDevice; - /* Let user determine default device by setting environment variable. */ - hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE ); - if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) ) - { - recommendedID = atoi( envbuf ); - } - return recommendedID; -} -PaDeviceID Pa_GetDefaultInputDeviceID( void ) -{ - PaError result; - result = PaHost_GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME ); - if( result < 0 ) - { - result = Pa_MaybeQueryDevices(); - if( result < 0 ) return result; - result = sDefaultInputDeviceID; - } - return result; -} -PaDeviceID Pa_GetDefaultOutputDeviceID( void ) -{ - PaError result; - result = PaHost_GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME ); - if( result < 0 ) - { - result = Pa_MaybeQueryDevices(); - if( result < 0 ) return result; - result = sDefaultOutputDeviceID; - } - return result; -} -/********************************************************************** -** Make sure that we have queried the device capabilities. -*/ -PaError PaHost_Init( void ) -{ -#if PA_SIMULATE_UNDERFLOW - PRINT(("WARNING - Underflow Simulation Enabled - Expect a Big Glitch!!!\n")); -#endif - return Pa_MaybeQueryDevices(); -} -static PaError Pa_TimeSlice( internalPortAudioStream *past ) -{ - PaError result = 0; - long bytesEmpty = 0; - long bytesFilled = 0; - long bytesToXfer = 0; - long numChunks; - HRESULT hresult; - PaHostSoundControl *pahsc; - short *nativeBufPtr; - past->past_NumCallbacks += 1; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paInternalError; - /* How much input data is available? */ -#if SUPPORT_AUDIO_CAPTURE - if( past->past_NumInputChannels > 0 ) - { - DSW_QueryInputFilled( &pahsc->pahsc_DSoundWrapper, &bytesFilled ); - bytesToXfer = bytesFilled; - } -#endif /* SUPPORT_AUDIO_CAPTURE */ - /* How much output room is available? */ - if( past->past_NumOutputChannels > 0 ) - { - DSW_QueryOutputSpace( &pahsc->pahsc_DSoundWrapper, &bytesEmpty ); - bytesToXfer = bytesEmpty; - } - AddTraceMessage( "bytesEmpty ", bytesEmpty ); - /* Choose smallest value if both are active. */ - if( (past->past_NumInputChannels > 0) && (past->past_NumOutputChannels > 0) ) - { - bytesToXfer = ( bytesFilled < bytesEmpty ) ? bytesFilled : bytesEmpty; - } - /* printf("bytesFilled = %d, bytesEmpty = %d, bytesToXfer = %d\n", - bytesFilled, bytesEmpty, bytesToXfer); - */ - /* Quantize to multiples of a buffer. */ - numChunks = bytesToXfer / pahsc->pahsc_BytesPerBuffer; - if( numChunks > (long)(past->past_NumUserBuffers/2) ) - { - numChunks = (long)past->past_NumUserBuffers/2; - } - else if( numChunks < 0 ) - { - numChunks = 0; - } - AddTraceMessage( "numChunks ", numChunks ); - nativeBufPtr = pahsc->pahsc_NativeBuffer; - if( numChunks > 0 ) - { - while( numChunks-- > 0 ) - { - /* Measure usage based on time to process one user buffer. */ - Pa_StartUsageCalculation( past ); -#if SUPPORT_AUDIO_CAPTURE - /* Get native data from DirectSound. */ - if( past->past_NumInputChannels > 0 ) - { - hresult = DSW_ReadBlock( &pahsc->pahsc_DSoundWrapper, (char *) nativeBufPtr, pahsc->pahsc_BytesPerBuffer ); - if( hresult < 0 ) - { - ERR_RPT(("DirectSound ReadBlock failed, hresult = 0x%x\n",hresult)); - sPaHostError = hresult; - break; - } - } -#endif /* SUPPORT_AUDIO_CAPTURE */ - /* Convert 16 bit native data to user data and call user routine. */ - result = Pa_CallConvertInt16( past, nativeBufPtr, nativeBufPtr ); - if( result != 0) break; - /* Pass native data to DirectSound. */ - if( past->past_NumOutputChannels > 0 ) - { - /* static short DEBUGHACK = 0; - DEBUGHACK += 0x0049; - nativeBufPtr[0] = DEBUGHACK; /* Make buzz to see if DirectSound still running. */ - hresult = DSW_WriteBlock( &pahsc->pahsc_DSoundWrapper, (char *) nativeBufPtr, pahsc->pahsc_BytesPerBuffer ); - if( hresult < 0 ) - { - ERR_RPT(("DirectSound WriteBlock failed, result = 0x%x\n",hresult)); - sPaHostError = hresult; - break; - } - } - Pa_EndUsageCalculation( past ); - } - } - return result; -} -/*******************************************************************/ -static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) -{ - internalPortAudioStream *past; - PaHostSoundControl *pahsc; -#if PA_SIMULATE_UNDERFLOW - gUnderCallbackCounter++; - if( (gUnderCallbackCounter >= UNDER_START_GAP) && - (gUnderCallbackCounter <= UNDER_STOP_GAP) ) - { - if( gUnderCallbackCounter == UNDER_START_GAP) - { - AddTraceMessage("Begin stall: gUnderCallbackCounter =======", gUnderCallbackCounter ); - } - if( gUnderCallbackCounter == UNDER_STOP_GAP) - { - AddTraceMessage("End stall: gUnderCallbackCounter =======", gUnderCallbackCounter ); - } - return; - } -#endif - past = (internalPortAudioStream *) dwUser; - if( past == NULL ) return; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return; - if( !pahsc->pahsc_IfInsideCallback && past->past_IsActive ) - { - if( past->past_StopNow ) - { - past->past_IsActive = 0; - } - else if( past->past_StopSoon ) - { - DSoundWrapper *dsw = &pahsc->pahsc_DSoundWrapper; - if( past->past_NumOutputChannels > 0 ) - { - DSW_ZeroEmptySpace( dsw ); - AddTraceMessage("Pa_TimerCallback: waiting - written ", (int) dsw->dsw_FramesWritten ); - AddTraceMessage("Pa_TimerCallback: waiting - played ", (int) dsw->dsw_FramesPlayed ); - /* clear past_IsActive when all sound played */ - if( dsw->dsw_FramesPlayed >= past->past_FrameCount ) - { - past->past_IsActive = 0; - } - } - else - { - past->past_IsActive = 0; - } - } - else - { - pahsc->pahsc_IfInsideCallback = 1; - if( Pa_TimeSlice( past ) != 0) /* Call time slice independant of timing method. */ - { - past->past_StopSoon = 1; - } - pahsc->pahsc_IfInsideCallback = 0; - } - } -} -/*******************************************************************/ -PaError PaHost_OpenStream( internalPortAudioStream *past ) -{ - HRESULT hr; - PaError result = paNoError; - PaHostSoundControl *pahsc; - int numBytes, maxChannels; - unsigned int minNumBuffers; - internalPortAudioDevice *pad; - DSoundWrapper *dsw; - /* Allocate and initialize host data. */ - pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); /* MEM */ - if( pahsc == NULL ) - { - result = paInsufficientMemory; - goto error; - } - memset( pahsc, 0, sizeof(PaHostSoundControl) ); - past->past_DeviceData = (void *) pahsc; - pahsc->pahsc_TimerID = 0; - dsw = &pahsc->pahsc_DSoundWrapper; - DSW_Init( dsw ); - /* Allocate native buffer. */ - maxChannels = ( past->past_NumOutputChannels > past->past_NumInputChannels ) ? - past->past_NumOutputChannels : past->past_NumInputChannels; - pahsc->pahsc_BytesPerBuffer = past->past_FramesPerUserBuffer * maxChannels * sizeof(short); - if( maxChannels > 0 ) - { - pahsc->pahsc_NativeBuffer = (short *) PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerBuffer); /* MEM */ - if( pahsc->pahsc_NativeBuffer == NULL ) - { - result = paInsufficientMemory; - goto error; - } - } - else - { - result = paInvalidChannelCount; - goto error; - } - - DBUG(("PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\n", pahsc->pahsc_MinFramesPerHostBuffer )); - minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate ); - past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers; - numBytes = pahsc->pahsc_BytesPerBuffer * past->past_NumUserBuffers; - if( numBytes < DSBSIZE_MIN ) - { - result = paBufferTooSmall; - goto error; - } - if( numBytes > DSBSIZE_MAX ) - { - result = paBufferTooBig; - goto error; - } - pahsc->pahsc_FramesPerDSBuffer = past->past_FramesPerUserBuffer * past->past_NumUserBuffers; - { - int msecLatency = (int) ((pahsc->pahsc_FramesPerDSBuffer * 1000) / past->past_SampleRate); - PRINT(("PortAudio on DirectSound - Latency = %d frames, %d msec\n", pahsc->pahsc_FramesPerDSBuffer, msecLatency )); - } - /* ------------------ OUTPUT */ - if( (past->past_OutputDeviceID >= 0) && (past->past_NumOutputChannels > 0) ) - { - DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", past->past_OutputDeviceID)); - pad = Pa_GetInternalDevice( past->past_OutputDeviceID ); - hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound, NULL ); - /* If this fails, then try each output device until we find one that works. */ - if( hr != DS_OK ) - { - int i; - ERR_RPT(("Creation of requested Audio Output device '%s' failed.\n", - ((pad->pad_lpGUID == NULL) ? "Default" : pad->pad_Info.name) )); - for( i=0; i<Pa_CountDevices(); i++ ) - { - pad = Pa_GetInternalDevice( i ); - if( pad->pad_Info.maxOutputChannels >= past->past_NumOutputChannels ) - { - DBUG(("Try device '%s' instead.\n", pad->pad_Info.name )); - hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound, NULL ); - if( hr == DS_OK ) - { - ERR_RPT(("Using device '%s' instead.\n", pad->pad_Info.name )); - break; - } - } - } - } - if( hr != DS_OK ) - { - ERR_RPT(("PortAudio: DirectSoundCreate() failed!\n")); - result = paHostError; - sPaHostError = hr; - goto error; - } - hr = DSW_InitOutputBuffer( dsw, - (unsigned long) (past->past_SampleRate + 0.5), - past->past_NumOutputChannels, numBytes ); - DBUG(("DSW_InitOutputBuffer() returns %x\n", hr)); - if( hr != DS_OK ) - { - result = paHostError; - sPaHostError = hr; - goto error; - } - past->past_FrameCount = pahsc->pahsc_DSoundWrapper.dsw_FramesWritten; - } -#if SUPPORT_AUDIO_CAPTURE - /* ------------------ INPUT */ - if( (past->past_InputDeviceID >= 0) && (past->past_NumInputChannels > 0) ) - { - pad = Pa_GetInternalDevice( past->past_InputDeviceID ); - hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture, NULL ); - /* If this fails, then try each input device until we find one that works. */ - if( hr != DS_OK ) - { - int i; - ERR_RPT(("Creation of requested Audio Capture device '%s' failed.\n", - ((pad->pad_lpGUID == NULL) ? "Default" : pad->pad_Info.name) )); - for( i=0; i<Pa_CountDevices(); i++ ) - { - pad = Pa_GetInternalDevice( i ); - if( pad->pad_Info.maxInputChannels >= past->past_NumInputChannels ) - { - PRINT(("Try device '%s' instead.\n", pad->pad_Info.name )); - hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture, NULL ); - if( hr == DS_OK ) break; - } - } - } - if( hr != DS_OK ) - { - ERR_RPT(("PortAudio: DirectSoundCaptureCreate() failed!\n")); - result = paHostError; - sPaHostError = hr; - goto error; - } - hr = DSW_InitInputBuffer( dsw, - (unsigned long) (past->past_SampleRate + 0.5), - past->past_NumInputChannels, numBytes ); - DBUG(("DSW_InitInputBuffer() returns %x\n", hr)); - if( hr != DS_OK ) - { - ERR_RPT(("PortAudio: DSW_InitInputBuffer() returns %x\n", hr)); - result = paHostError; - sPaHostError = hr; - goto error; - } - } -#endif /* SUPPORT_AUDIO_CAPTURE */ - /* Calculate scalar used in CPULoad calculation. */ - { - LARGE_INTEGER frequency; - if( QueryPerformanceFrequency( &frequency ) == 0 ) - { - pahsc->pahsc_InverseTicksPerUserBuffer = 0.0; - } - else - { - pahsc->pahsc_InverseTicksPerUserBuffer = past->past_SampleRate / - ( (double)frequency.QuadPart * past->past_FramesPerUserBuffer ); - DBUG(("pahsc_InverseTicksPerUserBuffer = %g\n", pahsc->pahsc_InverseTicksPerUserBuffer )); - } - } - return result; -error: - PaHost_CloseStream( past ); - return result; -} -/*************************************************************************/ -PaError PaHost_StartOutput( internalPortAudioStream *past ) -{ - HRESULT hr; - PaHostSoundControl *pahsc; - PaError result = paNoError; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - /* Give user callback a chance to pre-fill buffer. */ - result = Pa_TimeSlice( past ); - if( result != paNoError ) return result; // FIXME - what if finished? - hr = DSW_StartOutput( &pahsc->pahsc_DSoundWrapper ); - DBUG(("PaHost_StartOutput: DSW_StartOutput returned = 0x%X.\n", hr)); - if( hr != DS_OK ) - { - result = paHostError; - sPaHostError = hr; - goto error; - } -error: - return result; -} -/*************************************************************************/ -PaError PaHost_StartInput( internalPortAudioStream *past ) -{ - PaError result = paNoError; -#if SUPPORT_AUDIO_CAPTURE - HRESULT hr; - PaHostSoundControl *pahsc; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - hr = DSW_StartInput( &pahsc->pahsc_DSoundWrapper ); - DBUG(("Pa_StartStream: DSW_StartInput returned = 0x%X.\n", hr)); - if( hr != DS_OK ) - { - result = paHostError; - sPaHostError = hr; - goto error; - } -error: -#endif /* SUPPORT_AUDIO_CAPTURE */ - return result; -} -/*************************************************************************/ -PaError PaHost_StartEngine( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc; - PaError result = paNoError; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - past->past_StopNow = 0; - past->past_StopSoon = 0; - past->past_IsActive = 1; - /* Create timer that will wake us up so we can fill the DSound buffer. */ - { - int msecPerBuffer; - int resolution; - int bufsPerInterrupt = past->past_NumUserBuffers/4; - if( bufsPerInterrupt < 1 ) bufsPerInterrupt = 1; - msecPerBuffer = 1000 * (bufsPerInterrupt * past->past_FramesPerUserBuffer) / (int) past->past_SampleRate; - if( msecPerBuffer < 10 ) msecPerBuffer = 10; - else if( msecPerBuffer > 100 ) msecPerBuffer = 100; - resolution = msecPerBuffer/4; - pahsc->pahsc_TimerID = timeSetEvent( msecPerBuffer, resolution, (LPTIMECALLBACK) Pa_TimerCallback, - (DWORD) past, TIME_PERIODIC ); - } - if( pahsc->pahsc_TimerID == 0 ) - { - past->past_IsActive = 0; - result = paHostError; - sPaHostError = 0; - goto error; - } -error: - return result; -} -/*************************************************************************/ -PaError PaHost_StopEngine( internalPortAudioStream *past, int abort ) -{ - int timeoutMsec; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paNoError; - if( abort ) past->past_StopNow = 1; - past->past_StopSoon = 1; - /* Set timeout at 20% beyond maximum time we might wait. */ - timeoutMsec = (int) (1200.0 * pahsc->pahsc_FramesPerDSBuffer / past->past_SampleRate); - while( past->past_IsActive && (timeoutMsec > 0) ) - { - Sleep(10); - timeoutMsec -= 10; - } - if( pahsc->pahsc_TimerID != 0 ) - { - timeKillEvent(pahsc->pahsc_TimerID); /* Stop callback timer. */ - pahsc->pahsc_TimerID = 0; - } - return paNoError; -} -/*************************************************************************/ -PaError PaHost_StopInput( internalPortAudioStream *past, int abort ) -{ -#if SUPPORT_AUDIO_CAPTURE - HRESULT hr; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paNoError; - (void) abort; - hr = DSW_StopInput( &pahsc->pahsc_DSoundWrapper ); - DBUG(("DSW_StopInput() result is %x\n", hr)); -#endif /* SUPPORT_AUDIO_CAPTURE */ - return paNoError; -} -/*************************************************************************/ -PaError PaHost_StopOutput( internalPortAudioStream *past, int abort ) -{ - HRESULT hr; - PaHostSoundControl *pahsc; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paNoError; - (void) abort; - hr = DSW_StopOutput( &pahsc->pahsc_DSoundWrapper ); - DBUG(("DSW_StopOutput() result is %x\n", hr)); - return paNoError; -} -/*******************************************************************/ -PaError PaHost_CloseStream( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc; - if( past == NULL ) return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paNoError; - DSW_Term( &pahsc->pahsc_DSoundWrapper ); - if( pahsc->pahsc_NativeBuffer ) - { - PaHost_FreeFastMemory( pahsc->pahsc_NativeBuffer, pahsc->pahsc_BytesPerBuffer ); /* MEM */ - pahsc->pahsc_NativeBuffer = NULL; - } - PaHost_FreeFastMemory( pahsc, sizeof(PaHostSoundControl) ); /* MEM */ - past->past_DeviceData = NULL; - return paNoError; -} - -/* Set minimal latency based on whether NT or Win95. - * NT has higher latency. - */ -static int PaHost_GetMinSystemLatency( void ) -{ - int minLatencyMsec; - /* Set minimal latency based on whether NT or other OS. - * NT has higher latency. - */ - OSVERSIONINFO osvi; - osvi.dwOSVersionInfoSize = sizeof( osvi ); - GetVersionEx( &osvi ); - DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId )); - DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion )); - DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion )); - /* Check for NT */ - if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) ) - { - minLatencyMsec = PA_WIN_NT_LATENCY; - } - else if(osvi.dwMajorVersion >= 5) - { - minLatencyMsec = PA_WIN_WDM_LATENCY; - } - else - { - minLatencyMsec = PA_WIN_9X_LATENCY; - } - return minLatencyMsec; -} - -/************************************************************************* -** Determine minimum number of buffers required for this host based -** on minimum latency. Latency can be optionally set by user by setting -** an environment variable. For example, to set latency to 200 msec, put: -** -** set PA_MIN_LATENCY_MSEC=200 -** -** in the AUTOEXEC.BAT file and reboot. -** If the environment variable is not set, then the latency will be determined -** based on the OS. Windows NT has higher latency than Win95. -*/ -#define PA_LATENCY_ENV_NAME ("PA_MIN_LATENCY_MSEC") -int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate ) -{ - char envbuf[PA_ENV_BUF_SIZE]; - DWORD hresult; - int minLatencyMsec = 0; - double msecPerBuffer = (1000.0 * framesPerBuffer) / sampleRate; - int minBuffers; - /* Let user determine minimal latency by setting environment variable. */ - hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE ); - if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) ) - { - minLatencyMsec = atoi( envbuf ); - } - else - { - minLatencyMsec = PaHost_GetMinSystemLatency(); -#if PA_USE_HIGH_LATENCY - PRINT(("PA - Minimum Latency set to %d msec!\n", minLatencyMsec )); -#endif - - } - minBuffers = (int) (1.0 + ((double)minLatencyMsec / msecPerBuffer)); - if( minBuffers < 2 ) minBuffers = 2; - return minBuffers; -} -/*************************************************************************/ -PaError PaHost_Term( void ) -{ - int i; - /* Free names allocated during enumeration. */ - for( i=0; i<sNumDevices; i++ ) - { - if( sDevices[i].pad_Info.name != NULL ) - { - free( (void *) sDevices[i].pad_Info.name ); - sDevices[i].pad_Info.name = NULL; - } - } - if( sDevices != NULL ) - { - PaHost_FreeFastMemory( sDevices, sNumDevices * sizeof(internalPortAudioDevice) ); /* MEM */ - sDevices = NULL; - sNumDevices = 0; - } - return 0; -} -void Pa_Sleep( long msec ) -{ - Sleep( msec ); -} -/************************************************************************* - * Allocate memory that can be accessed in real-time. - * This may need to be held in physical memory so that it is not - * paged to virtual memory. - * This call MUST be balanced with a call to PaHost_FreeFastMemory(). - * Memory will be set to zero. - */ -void *PaHost_AllocateFastMemory( long numBytes ) -{ - void *addr = GlobalAlloc( GPTR, numBytes ); /* FIXME - do we need physical memory? Use VirtualLock() */ /* MEM */ - return addr; -} -/************************************************************************* - * Free memory that could be accessed in real-time. - * This call MUST be balanced with a call to PaHost_AllocateFastMemory(). - */ -void PaHost_FreeFastMemory( void *addr, long numBytes ) -{ - if( addr != NULL ) GlobalFree( addr ); /* MEM */ -} -/***********************************************************************/ -PaError PaHost_StreamActive( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc; - if( past == NULL ) return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paInternalError; - return (PaError) (past->past_IsActive); -} -/*************************************************************************/ -PaTimestamp Pa_StreamTime( PortAudioStream *stream ) -{ - DSoundWrapper *dsw; - internalPortAudioStream *past = (internalPortAudioStream *) stream; - PaHostSoundControl *pahsc; - if( past == NULL ) return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - dsw = &pahsc->pahsc_DSoundWrapper; - return dsw->dsw_FramesPlayed; -} diff --git a/pd/portaudio/pa_win_ds/pa_win_ds.c b/pd/portaudio/pa_win_ds/pa_win_ds.c deleted file mode 100644 index b23a407e..00000000 --- a/pd/portaudio/pa_win_ds/pa_win_ds.c +++ /dev/null @@ -1,1441 +0,0 @@ -/* - * $Id: pa_win_ds.c,v 1.1.2.29 2002/12/03 06:30:40 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 underflow/overflow streamCallback statusFlags, 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 implement PaDeviceInfo.defaultSampleRate; -*/ - -#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" - -/* TODO -O- fix "patest_stop.c" -O- Handle buffer underflow, overflow, etc. -*/ - -#define PRINT(x) { printf x; fflush(stdout); } -#define ERR_RPT(x) PRINT(x) -#define DBUG(x) /* PRINT(x) */ -#define DBUGX(x) /* PRINT(x) */ - -#define PA_USE_HIGH_LATENCY (0) -#if PA_USE_HIGH_LATENCY -#define PA_WIN_9X_LATENCY (500) -#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 */ - -PaError PaWinDs_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, 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 Pa_EnumOutputProc(LPGUID lpGUID, - LPCTSTR lpszDesc, - LPCTSTR lpszDrvName, - LPVOID lpContext ); -static BOOL CALLBACK Pa_CountDevProc(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; - PaError enumerationError; - -} 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 */ - -/* 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; - - -/************************************************************************************ -** Just count devices so we know how much memory to allocate. -*/ -static BOOL CALLBACK Pa_CountDevProc(LPGUID lpGUID, - LPCTSTR lpszDesc, - LPCTSTR lpszDrvName, - LPVOID lpContext ) -{ - int *counterPtr = (int *)lpContext; - *counterPtr += 1; - return TRUE; -} - -/************************************************************************************ -** Extract capabilities info from each device. -*/ -static BOOL CALLBACK Pa_EnumOutputProc(LPGUID lpGUID, - LPCTSTR lpszDesc, - LPCTSTR lpszDrvName, - LPVOID lpContext ) -{ - HRESULT hr; - DSCAPS caps; - LPDIRECTSOUND lpDirectSound; - PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation *) lpContext; - PaUtilHostApiRepresentation *hostApi = &winDsHostApi->inheritedHostApiRep; - int index = hostApi->info.deviceCount; - PaDeviceInfo *deviceInfo = hostApi->deviceInfos[index]; - PaWinDsDeviceInfo *winDsDeviceInfo = &winDsHostApi->winDsDeviceInfos[index]; - int deviceOK = TRUE; - - /* Copy GUID to static array. Set pointer. */ - if( lpGUID == NULL ) - { - winDsDeviceInfo->lpGUID = NULL; - } - else - { - winDsDeviceInfo->lpGUID = &winDsDeviceInfo->GUID; - memcpy( &winDsDeviceInfo->GUID, lpGUID, sizeof(GUID) ); - } - - - /********** Output ******************************/ - - /* Create interfaces for each object. */ - hr = dswDSoundEntryPoints.DirectSoundCreate( lpGUID, &lpDirectSound, NULL ); - if( hr != DS_OK ) - { - deviceInfo->maxOutputChannels = 0; - DBUG(("Cannot create dsound for %s. Result = 0x%x\n", lpszDesc, hr )); - deviceOK = FALSE; - } - else - { - /* Query device characteristics. */ - caps.dwSize = sizeof(caps); - IDirectSound_GetCaps( lpDirectSound, &caps ); - -#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 ) - { - /* Mono or stereo device? */ - deviceInfo->maxOutputChannels = ( caps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1; - - deviceInfo->defaultSampleRate = 0.; /* @todo IMPLEMENT ME */ - - /* Get sample rates. */ - /* - winDsDeviceInfo->sampleRates[0] = (double) caps.dwMinSecondarySampleRate; - winDsDeviceInfo->sampleRates[1] = (double) caps.dwMaxSecondarySampleRate; - if( caps.dwFlags & DSCAPS_CONTINUOUSRATE ) deviceInfo->numSampleRates = -1; - 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. - // - winDsDeviceInfo->sampleRates[0] = 11025.0f; - winDsDeviceInfo->sampleRates[1] = 48000.0f; - deviceInfo->numSampleRates = -1; // continuous range - - DBUG(("PA - Reported rates both zero. Setting to fake values for device #%d\n", sDeviceIndex )); - } - else - { - deviceInfo->numSampleRates = 1; - } - } - 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->numSampleRates = -1; - DBUG(("PA - Sample rate range used instead of two odd values for device #%d\n", sDeviceIndex )); - } - else deviceInfo->numSampleRates = 2; - */ - } - - IDirectSound_Release( lpDirectSound ); - } - - if( deviceOK ) - { - if( lpGUID == NULL ) hostApi->info.defaultOutputDevice = index; - - /* Allocate room for descriptive name. */ - if( lpszDesc != NULL ) - { - char *deviceName; - int len = strlen(lpszDesc); - deviceName = (char*)PaUtil_GroupAllocateMemory( winDsHostApi->allocations, len + 1 ); - if( !deviceName ) - { - winDsHostApi->enumerationError = paInsufficientMemory; - return FALSE; - } - memcpy( (void *) deviceName, lpszDesc, len+1 ); - deviceInfo->name = deviceName; - } - - hostApi->info.deviceCount++; - } - - return( TRUE ); -} - - -/************************************************************************************ -** Extract capabilities info from each device. -*/ -static BOOL CALLBACK Pa_EnumInputProc(LPGUID lpGUID, - LPCTSTR lpszDesc, - LPCTSTR lpszDrvName, - LPVOID lpContext ) -{ - HRESULT hr; - DSCCAPS caps; - LPDIRECTSOUNDCAPTURE lpDirectSoundCapture; - PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation *) lpContext; - PaUtilHostApiRepresentation *hostApi = &winDsHostApi->inheritedHostApiRep; - int index = hostApi->info.deviceCount; - PaDeviceInfo *deviceInfo = hostApi->deviceInfos[index]; - PaWinDsDeviceInfo *winDsDeviceInfo = &winDsHostApi->winDsDeviceInfos[index]; - int deviceOK = TRUE; - - /* Copy GUID to static array. Set pointer. */ - if( lpGUID == NULL ) - { - winDsDeviceInfo->lpGUID = NULL; - } - else - { - winDsDeviceInfo->lpGUID = &winDsDeviceInfo->GUID; - memcpy( &winDsDeviceInfo->GUID, lpGUID, sizeof(GUID) ); - } - - /********** Input ******************************/ - - hr = dswDSoundEntryPoints.DirectSoundCaptureCreate( lpGUID, &lpDirectSoundCapture, NULL ); - if( hr != DS_OK ) - { - deviceInfo->maxInputChannels = 0; - DBUG(("Cannot create Capture for %s. Result = 0x%x\n", lpszDesc, hr )); - deviceOK = FALSE; - } - else - { - /* Query device characteristics. */ - caps.dwSize = sizeof(caps); - IDirectSoundCapture_GetCaps( lpDirectSoundCapture, &caps ); - - /* printf("caps.dwFormats = 0x%x\n", caps.dwFormats ); */ - deviceInfo->maxInputChannels = caps.dwChannels; - /* Determine sample rates from flags. */ - /* - if( caps.dwChannels == 2 ) - { - int index = 0; - if( caps.dwFormats & WAVE_FORMAT_1S16) winDsDeviceInfo->sampleRates[index++] = 11025.0; - if( caps.dwFormats & WAVE_FORMAT_2S16) winDsDeviceInfo->sampleRates[index++] = 22050.0; - if( caps.dwFormats & WAVE_FORMAT_4S16) winDsDeviceInfo->sampleRates[index++] = 44100.0; - deviceInfo->numSampleRates = index; - } - else if( caps.dwChannels == 1 ) - { - int index = 0; - if( caps.dwFormats & WAVE_FORMAT_1M16) winDsDeviceInfo->sampleRates[index++] = 11025.0; - if( caps.dwFormats & WAVE_FORMAT_2M16) winDsDeviceInfo->sampleRates[index++] = 22050.0; - if( caps.dwFormats & WAVE_FORMAT_4M16) winDsDeviceInfo->sampleRates[index++] = 44100.0; - deviceInfo->numSampleRates = index; - } - else - { - deviceInfo->numSampleRates = 0; - deviceOK = FALSE; - } - */ - IDirectSoundCapture_Release( lpDirectSoundCapture ); - } - - if( deviceOK ) - { - /* Allocate room for descriptive name. */ - if( lpszDesc != NULL ) - { - char *deviceName; - int len = strlen(lpszDesc); - deviceName = (char*)PaUtil_GroupAllocateMemory( winDsHostApi->allocations, len + 1 ); - if( !deviceName ) - { - winDsHostApi->enumerationError = paInsufficientMemory; - return FALSE; - } - memcpy( (void *) deviceName, lpszDesc, len+1 ); - deviceInfo->name = deviceName; - } - - if( lpGUID == NULL ) hostApi->info.defaultInputDevice = index; - - hostApi->info.deviceCount++; - } - - return TRUE; -} - - -/***********************************************************************************/ -PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) -{ - PaError result = paNoError; - int i, deviceCount; - PaWinDsHostApiRepresentation *winDsHostApi; - PaDeviceInfo *deviceInfoArray; - - 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; - - deviceCount = 0; -/* DSound - enumerate devices to count them. */ - dswDSoundEntryPoints.DirectSoundEnumerate( (LPDSENUMCALLBACK)Pa_CountDevProc, &deviceCount ); - dswDSoundEntryPoints.DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)Pa_CountDevProc, &deviceCount ); - - 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; - - deviceInfo->defaultLowInputLatency = 0.; /* @todo IMPLEMENT ME */ - deviceInfo->defaultLowOutputLatency = 0.; /* @todo IMPLEMENT ME */ - deviceInfo->defaultHighInputLatency = 0.; /* @todo IMPLEMENT ME */ - deviceInfo->defaultHighOutputLatency = 0.; /* @todo IMPLEMENT ME */ - - (*hostApi)->deviceInfos[i] = deviceInfo; - } - - /* DSound - Enumerate again to fill in structures. */ - winDsHostApi->enumerationError = 0; - dswDSoundEntryPoints.DirectSoundEnumerate( (LPDSENUMCALLBACK)Pa_EnumOutputProc, (void *)winDsHostApi ); - if( winDsHostApi->enumerationError != paNoError ) return winDsHostApi->enumerationError; - - winDsHostApi->enumerationError = 0; - dswDSoundEntryPoints.DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)Pa_EnumInputProc, (void *)winDsHostApi ); - if( winDsHostApi->enumerationError != paNoError ) return winDsHostApi->enumerationError; - } - - (*hostApi)->Terminate = Terminate; - (*hostApi)->OpenStream = OpenStream; - (*hostApi)->IsFormatSupported = IsFormatSupported; - - PaUtil_InitializeStreamInterface( &winDsHostApi->callbackStreamInterface, CloseStream, StartStream, - StopStream, AbortStream, IsStreamStopped, IsStreamActive, - GetStreamTime, GetStreamCpuLoad, - PaUtil_DummyReadWrite, PaUtil_DummyReadWrite, PaUtil_DummyGetAvailable, PaUtil_DummyGetAvailable ); - - 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 ); - } - return result; -} - - -/***********************************************************************************/ -static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) -{ - PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation*)hostApi; - - /* - IMPLEMENT ME: - - clean up any resourced not handled by the allocation group - */ - - if( winDsHostApi->allocations ) - { - PaUtil_FreeAllAllocations( winDsHostApi->allocations ); - PaUtil_DestroyAllocationGroup( winDsHostApi->allocations ); - } - - PaUtil_FreeMemory( winDsHostApi ); - - DSW_TerminateDSoundEntryPoints(); -} - - -/* 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: - - 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 - */ - - 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 = 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 = 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 ); - } - - stream->streamRepresentation.streamInfo.inputLatency = 0.; /* FIXME: not initialised anywhere else */ - stream->streamRepresentation.streamInfo.outputLatency = 0.; - stream->streamRepresentation.streamInfo.sampleRate = sampleRate; - - - 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; - -/* 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", outputDevice)); - - 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), - 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 ]; - - 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), - 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; - } - - /* How much output room is available? */ - if( stream->bufferProcessor.outputChannelCount > 0 ) - { - DSW_QueryOutputSpace( dsw, &bytesEmpty ); - framesToXfer = numOutFramesReady = bytesEmpty / dsw->dsw_BytesPerOutputFrame; - } - - 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 ); - - /* 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 ); - } - } - - numFrames = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &result ); - stream->framesWritten += numFrames; - - if( stream->bufferProcessor.outputChannelCount > 0 ) - { - /* 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 ) - { - /* 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 dwUser, DWORD dw1, DWORD dw2) -{ - PaWinDsStream *stream; - - 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; - - 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->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) 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 ) -{ - PaError result = paNoError; - 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 ) -{ -/* - 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; - - /* IMPLEMENT ME, see portaudio.h for required behavior*/ - - return paNoError; -} - - -/***********************************************************************************/ -static PaError WriteStream( PaStream* s, - void *buffer, - unsigned long frames ) -{ - PaWinDsStream *stream = (PaWinDsStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior*/ - - return paNoError; -} - - -/***********************************************************************************/ -static signed long GetStreamReadAvailable( PaStream* s ) -{ - PaWinDsStream *stream = (PaWinDsStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior*/ - - return 0; -} - - -/***********************************************************************************/ -static signed long GetStreamWriteAvailable( PaStream* s ) -{ - PaWinDsStream *stream = (PaWinDsStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior*/ - - return 0; -} - - - diff --git a/pd/portaudio/pa_win_ds/portaudio.def b/pd/portaudio/pa_win_ds/portaudio.def deleted file mode 100644 index 8012b99e..00000000 --- a/pd/portaudio/pa_win_ds/portaudio.def +++ /dev/null @@ -1,28 +0,0 @@ -LIBRARY PortAudio -DESCRIPTION 'PortAudio Portable interface to audio HW' - -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 - - ;123456789012345678901234567890123456 - ;000000000111111111122222222223333333 - - diff --git a/pd/portaudio/pa_win_wmme/Makefile.cygwin b/pd/portaudio/pa_win_wmme/Makefile.cygwin deleted file mode 100644 index 5cb4acef..00000000 --- a/pd/portaudio/pa_win_wmme/Makefile.cygwin +++ /dev/null @@ -1,34 +0,0 @@ - -# Makefile for PortAudio on cygwin -# Contributed by Bill Eldridge on 6/13/2001 - -ARCH= pa_win_wmme - -TESTS:= $(wildcard pa_tests/pa*.c pa_tests/debug*.c) - -.c.o: - -gcc -c -I./pa_common $< -o $*.o - -gcc $*.o -o $*.exe -L/usr/local/lib -L$(ARCH) -lportaudio.dll -lwinmm - -all: sharedlib tests - -sharedlib: ./pa_common/pa_lib.c - gcc -c -I./pa_common pa_common/pa_lib.c -o pa_common/pa_lib.o - gcc -c -I./pa_common pa_win_wmme/pa_win_wmme.c -o pa_win_wmme/pa_win_wmme.o - dlltool --export-all --output-def pa_win_wmme/pa_lib.def pa_common/pa_lib.o pa_win_wmme/pa_win_wmme.o - gcc -shared -Wl,--enable-auto-image-base -o pa_win_wmme/portaudio.dll -Wl,--out-implib=pa_win_wmme/libportaudio.dll.a pa_win_wmme/pa_lib.def pa_common/pa_lib.o pa_win_wmme/pa_win_wmme.o -L/usr/lib/w32api -lwinmm - cp pa_win_wmme/portaudio.dll /usr/local/bin - -tests: $(TESTS:.c=.o) - -sine: - gcc -c -I./pa_common pa_tests/patest_sine.c -o pa_tests/patest_sine.o - gcc pa_tests/patest_sine.o -o pa_tests/patest_sine.exe -L/usr/local/lib -lportaudio.dll -lwinmm - -clean: - -rm ./pa_tests/*.exe - -nothing: - gcc pa_tests/patest_sine.o -L/usr/lib/w32api -L./pa_win_wmme -lportaudio.dll -lwinmm - - diff --git a/pd/portaudio/pa_win_wmme/pa_win_wmme.c b/pd/portaudio/pa_win_wmme/pa_win_wmme.c deleted file mode 100644 index 2b1cc57d..00000000 --- a/pd/portaudio/pa_win_wmme/pa_win_wmme.c +++ /dev/null @@ -1,2672 +0,0 @@ -/* - * $Id: pa_win_wmme.c,v 1.6.2.44 2003/03/18 14:27:58 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 Handle case where user supplied full duplex buffer sizes are not compatible - (must be common multiples) - - @todo Fix buffer catch up code, can sometimes get stuck - - @todo Implement "close sample rate matching" if needed - is this really needed - in mme? - - @todo Investigate supporting host buffer formats > 16 bits - - @todo Implement buffer size and number of buffers code, - this code should generate defaults the way the old code did - - @todo implement underflow/overflow streamCallback statusFlags, paNeverDropInput. - - @todo Fix fixmes - - @todo implement initialisation of PaDeviceInfo default*Latency fields (currently set to 0.) - - @todo implement ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable - - @todo implement IsFormatSupported - - @todo implement PaDeviceInfo.defaultSampleRate; - - @todo define UNICODE and _UNICODE in the project settings and see what breaks -*/ - -#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" - -/************************************************* Constants ********/ - -/* Switches for debugging. */ -#define PA_SIMULATE_UNDERFLOW_ (0) /* Set to one to force an underflow of the output buffer. */ - -#define PA_USE_HIGH_LATENCY_ (0) /* For debugging glitches. */ - -#if PA_USE_HIGH_LATENCY_ - #define PA_MIN_MSEC_PER_HOST_BUFFER_ (100) - #define PA_MAX_MSEC_PER_HOST_BUFFER_ (300) /* Do not exceed unless user buffer exceeds */ - #define PA_MIN_NUM_HOST_BUFFERS_ (4) - #define PA_MAX_NUM_HOST_BUFFERS_ (16) /* OK to exceed if necessary */ - #define PA_WIN_9X_LATENCY_ (400) -#else - #define PA_MIN_MSEC_PER_HOST_BUFFER_ (10) - #define PA_MAX_MSEC_PER_HOST_BUFFER_ (100) /* Do not exceed unless user buffer exceeds */ - #define PA_MIN_NUM_HOST_BUFFERS_ (3) - #define PA_MAX_NUM_HOST_BUFFERS_ (16) /* OK to exceed if necessary */ - #define PA_WIN_9X_LATENCY_ (200) -#endif - -#define PA_MIN_TIMEOUT_MSEC_ (1000) - -/* -** Use higher latency for NT because it is even worse at real-time -** operation than Win9x. -*/ -#define PA_WIN_NT_LATENCY_ (PA_WIN_9X_LATENCY_ * 2) -#define PA_WIN_WDM_LATENCY_ (PA_WIN_9X_LATENCY_) - - -static const char constInputMapperSuffix_[] = " - Input"; -static const char constOutputMapperSuffix_[] = " - Output"; - - -typedef struct PaWinMmeStream PaWinMmeStream; /* forward reference */ - -/* prototypes for functions declared in this file */ - -PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ); -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, void *buffer, unsigned long frames ); -static signed long GetStreamReadAvailable( PaStream* stream ); -static signed long GetStreamWriteAvailable( PaStream* stream ); - -static PaError UpdateStreamTime( PaWinMmeStream *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 ) -{ - LPVOID 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 ) - - -/* PaWinMmeHostApiRepresentation - host api datastructure specific to this implementation */ - -typedef struct -{ - PaUtilHostApiRepresentation inheritedHostApiRep; - PaUtilStreamInterface callbackStreamInterface; - PaUtilStreamInterface blockingStreamInterface; - - PaUtilAllocationGroup *allocations; - - int numInputDevices, numOutputDevices; - - /** winMmeDeviceIds is an array of WinMme device ids. - fields in the range [0, numInputDevices) are input device ids, - and [numInputDevices, numInputDevices + numOutputDevices) are output - device ids. - */ - int *winMmeDeviceIds; -} -PaWinMmeHostApiRepresentation; - - -/************************************************************************* - * 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 int LocalDeviceIndexToWinMmeDeviceId( PaWinMmeHostApiRepresentation *hostApi, PaDeviceIndex device ) -{ - assert( device >= 0 && device < hostApi->numInputDevices + hostApi->numOutputDevices ); - - return hostApi->winMmeDeviceIds[ device ]; -} - - -static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi, - PaDeviceInfo *deviceInfo, int winMmeInputDeviceId, int *success ) -{ - PaError result = paNoError; - char *deviceName; /* non-const ptr */ - MMRESULT mmresult; - WAVEINCAPS wic; - - *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; - } - - deviceInfo->defaultSampleRate = 0.; /* @todo IMPLEMENT ME */ - - *success = 1; - -error: - return result; -} - - -static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi, - PaDeviceInfo *deviceInfo, int winMmeOutputDeviceId, int *success ) -{ - PaError result = paNoError; - char *deviceName; /* non-const ptr */ - MMRESULT mmresult; - WAVEOUTCAPS woc; - - *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; - } - - deviceInfo->defaultSampleRate = 0.; /* @todo IMPLEMENT ME */ - - *success = 1; - -error: - return result; -} - - -PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) -{ - PaError result = paNoError; - int i; - PaWinMmeHostApiRepresentation *winMmeHostApi; - int numInputDevices, numOutputDevices, maximumPossibleNumDevices; - PaDeviceInfo *deviceInfoArray; - int deviceInfoInitializationSucceeded; - - 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->numInputDevices = 0; - winMmeHostApi->numOutputDevices = 0; - - - maximumPossibleNumDevices = 0; - - numInputDevices = waveInGetNumDevs(); - if( numInputDevices > 0 ) - maximumPossibleNumDevices += numInputDevices + 1; /* assume there is a WAVE_MAPPER */ - - numOutputDevices = waveOutGetNumDevs(); - if( numOutputDevices > 0 ) - maximumPossibleNumDevices += numOutputDevices + 1; /* assume there is a WAVE_MAPPER */ - - - if( maximumPossibleNumDevices > 0 ){ - - (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( - winMmeHostApi->allocations, sizeof(PaDeviceInfo*) * maximumPossibleNumDevices ); - if( !(*hostApi)->deviceInfos ) - { - result = paInsufficientMemory; - goto error; - } - - /* allocate all device info structs in a contiguous block */ - deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( - winMmeHostApi->allocations, sizeof(PaDeviceInfo) * maximumPossibleNumDevices ); - if( !deviceInfoArray ) - { - result = paInsufficientMemory; - goto error; - } - - winMmeHostApi->winMmeDeviceIds = (int*)PaUtil_GroupAllocateMemory( - winMmeHostApi->allocations, sizeof(int) * maximumPossibleNumDevices ); - if( !winMmeHostApi->winMmeDeviceIds ) - { - result = paInsufficientMemory; - goto error; - } - - if( numInputDevices > 0 ){ - // -1 is the WAVE_MAPPER - for( i = -1; i < numInputDevices; ++i ){ - PaDeviceInfo *deviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; - deviceInfo->structVersion = 2; - deviceInfo->hostApi = hostApiIndex; - - deviceInfo->maxInputChannels = 0; - 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 */ - - result = InitializeInputDeviceInfo( winMmeHostApi, deviceInfo, i, &deviceInfoInitializationSucceeded ); - if( result != paNoError ) - goto error; - - if( deviceInfoInitializationSucceeded ){ - if( (*hostApi)->info.defaultInputDevice == paNoDevice ) - (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount; - - winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = i; - (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo; - - winMmeHostApi->numInputDevices++; - (*hostApi)->info.deviceCount++; - } - } - } - - if( numOutputDevices > 0 ){ - // -1 is the WAVE_MAPPER - for( i = -1; i < numOutputDevices; ++i ){ - PaDeviceInfo *deviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; - deviceInfo->structVersion = 2; - deviceInfo->hostApi = hostApiIndex; - - deviceInfo->maxInputChannels = 0; - 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 */ - - result = InitializeOutputDeviceInfo( winMmeHostApi, deviceInfo, i, &deviceInfoInitializationSucceeded ); - if( result != paNoError ) - goto error; - - if( deviceInfoInitializationSucceeded ){ - if( (*hostApi)->info.defaultOutputDevice == paNoDevice ) - (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount; - - winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = i; - (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo; - - winMmeHostApi->numOutputDevices++; - (*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_DummyReadWrite, PaUtil_DummyReadWrite, PaUtil_DummyGetAvailable, PaUtil_DummyGetAvailable ); - - 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 ) -{ - 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: - - 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 - */ - - return paFormatIsSupported; -} - - -/* CalculateBufferSettings() fills the framesPerHostInputBuffer, numHostInputBuffers, - framesPerHostOutputBuffer and numHostOutputBuffers parameters based on the values - of the other parameters. - -*/ - -static PaError CalculateBufferSettings( - unsigned long *framesPerHostInputBuffer, unsigned long *numHostInputBuffers, - unsigned long *framesPerHostOutputBuffer, unsigned long *numHostOutputBuffers, - int inputChannelCount, PaSampleFormat hostInputSampleFormat, - PaTime suggestedInputLatency, PaWinMmeStreamInfo *inputStreamInfo, - int outputChannelCount, PaSampleFormat hostOutputSampleFormat, - PaTime suggestedOutputLatency, PaWinMmeStreamInfo *outputStreamInfo, - double sampleRate, unsigned long framesPerBuffer ) -{ - PaError result = paNoError; - - if( inputChannelCount > 0 ) - { - if( inputStreamInfo ) - { - if( inputStreamInfo->flags & PaWinMmeUseLowLevelLatencyParameters ) - { - if( inputStreamInfo->numBuffers <= 0 - || inputStreamInfo->framesPerBuffer <= 0 ) - { - result = paIncompatibleHostApiSpecificStreamInfo; - goto error; - } - - *framesPerHostInputBuffer = inputStreamInfo->framesPerBuffer; - *numHostInputBuffers = inputStreamInfo->numBuffers; - } - } - else - { - /* hardwire for now, FIXME */ - /* don't forget that there will be one more buffer than the number required to achieve the requested latency */ - *framesPerHostInputBuffer = 4096; - *numHostInputBuffers = 4; - - /* - Need to determine the right heuristic for mapping latency in - seconds to buffer sizes and number of buffers. - - - for output don't allocate less than 1+1 buffers - - - for input don't allocate less than 2+1 buffers - (less than 1+1 if input only) - - - don't allocate buffers smaller than framesPerBuffer - - - if the client doesn't care about the buffer size use a power - of two buffer size. otherwise use a multiple of the user - buffer size. if the user buffer size is a power of 2, it - might be wise to make the host buffer size a power of 2 too. - - - there probably shouldn't be too many buffers ( 3 to 10 seems - reasonable). - - - aside from a limit on what constitutes a "reasonable" number - of buffers, there should be as many buffers as possible, - because this will place a less bursty load on CPU resources - - - the host buffers should be as big as practical (ie multiple - user buffers per host buffer). - - - . One way to achieve the above is to say: Try to have 8 - host buffers, and host buffers cannot be larger than 32k - unless the user buffer size requires it" - I say 32k because buffers larger than this are known to - crash some drivers (Turtle Beach for example.) - - just some idle rambling: - - if( framesPerBuffer == 0 ){ - // use a power of two buffer size - - }else{ - latencySamples = ceil(requestedLatency * sampleRate) - - numBuffers = ceil(latencySamples / framesPerBuffer); - - bufferSize = framesPerBuffer; - - minBuffers = ( inputChannelCount > 0 && outputChannelCount > 0 ) ? 2 : 1; - - if( numBuffers <= minBuffers ){ - numBuffers = minBuffers; - }else{ - make buffer size a multiple of framesPerBuffer until numBuffers is - greater than 4 and less than 10. - } - } - */ - } - } - else - { - *framesPerHostInputBuffer = 0; - *numHostInputBuffers = 0; - } - - if( outputChannelCount > 0 ) - { - if( outputStreamInfo ) - { - if( outputStreamInfo->flags & PaWinMmeUseLowLevelLatencyParameters ) - { - if( outputStreamInfo->numBuffers <= 0 - || outputStreamInfo->framesPerBuffer <= 0 ) - { - result = paIncompatibleHostApiSpecificStreamInfo; - goto error; - } - - *framesPerHostOutputBuffer = outputStreamInfo->framesPerBuffer; - *numHostOutputBuffers = outputStreamInfo->numBuffers; - } - } - else - { - /* hardwire for now, FIXME */ - /* don't forget that there will be one more buffer than the number required to achieve the requested latency */ - *framesPerHostOutputBuffer = 4096; - *numHostOutputBuffers = 4; - } - } - else - { - *framesPerHostOutputBuffer = 0; - *numHostOutputBuffers = 0; - } - -error: - return result; -} - - - -typedef HWAVEIN MmeHandle; - -static PaError InitializeBufferSet( WAVEHDR **bufferSet, int numBuffers, int bufferBytes, - int isInput, /* if 0, then output */ - MmeHandle mmeWaveHandle, int numDeviceChannels ) -{ - PaError result = paNoError; - MMRESULT mmresult; - int i; - - *bufferSet = 0; - - /* Allocate an array to hold the buffer pointers. */ - *bufferSet = (WAVEHDR *) PaUtil_AllocateMemory( sizeof(WAVEHDR)*numBuffers ); - if( !*bufferSet ) - { - result = paInsufficientMemory; - goto error; - } - - for( i=0; i<numBuffers; ++i ) - { - (*bufferSet)[i].lpData = 0; - } - - /* Allocate each buffer. */ - for( i=0; i<numBuffers; ++i ) - { - (*bufferSet)[i].lpData = (char *)PaUtil_AllocateMemory( bufferBytes ); - if( !(*bufferSet)[i].lpData ) - { - result = paInsufficientMemory; - goto error; - } - (*bufferSet)[i].dwBufferLength = bufferBytes; - (*bufferSet)[i].dwUser = 0xFFFFFFFF; /* indicates unprepared to error clean up code */ - - if( isInput ) - { - mmresult = waveInPrepareHeader( mmeWaveHandle, &(*bufferSet)[i], sizeof(WAVEHDR) ); - if( mmresult != MMSYSERR_NOERROR ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); - goto error; - } - } - else /* output */ - { - mmresult = waveOutPrepareHeader( (HWAVEOUT)mmeWaveHandle, &(*bufferSet)[i], sizeof(WAVEHDR) ); - if( mmresult != MMSYSERR_NOERROR ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); - goto error; - } - } - - (*bufferSet)[i].dwUser = numDeviceChannels; - } - - return result; - -error: - if( *bufferSet ) - { - for( i=0; i<numBuffers; ++i ) - { - if( (*bufferSet)[i].lpData ) - { - - if( (*bufferSet)[i].dwUser != 0xFFFFFFFF ) - { - if( isInput ) - waveInUnprepareHeader( mmeWaveHandle, &(*bufferSet)[i], sizeof(WAVEHDR) ); - else - waveOutUnprepareHeader( (HWAVEOUT)mmeWaveHandle, &(*bufferSet)[i], sizeof(WAVEHDR) ); - } - PaUtil_FreeMemory( (*bufferSet)[i].lpData ); - } - } - - PaUtil_FreeMemory( *bufferSet ); - } - - return result; -} - - -static void TerminateBufferSet( WAVEHDR * *bufferSet, unsigned int numBuffers, int isInput, MmeHandle mmeWaveHandle ) -{ - unsigned int i; - - for( i=0; i<numBuffers; ++i ) - { - if( (*bufferSet)[i].lpData ) - { - if( isInput ) - waveInUnprepareHeader( mmeWaveHandle, &(*bufferSet)[i], sizeof(WAVEHDR) ); - else - waveOutUnprepareHeader( (HWAVEOUT)mmeWaveHandle, &(*bufferSet)[i], sizeof(WAVEHDR) ); - - PaUtil_FreeMemory( (*bufferSet)[i].lpData ); - } - } - - if( *bufferSet ) - PaUtil_FreeMemory( *bufferSet ); -} - - -/* PaWinMmeStream - a stream data structure specifically for this implementation */ - -typedef struct PaWinMmeStream -{ - PaUtilStreamRepresentation streamRepresentation; - PaUtilCpuLoadMeasurer cpuLoadMeasurer; - PaUtilBufferProcessor bufferProcessor; - - CRITICAL_SECTION lock; - - /* Input -------------- */ - HWAVEIN *hWaveIns; - unsigned int numInputDevices; - /* unsigned int inputChannelCount; */ - WAVEHDR **inputBuffers; - unsigned int numInputBuffers; - unsigned int currentInputBufferIndex; - unsigned int framesPerInputBuffer; - unsigned int framesUsedInCurrentInputBuffer; - - /* Output -------------- */ - HWAVEOUT *hWaveOuts; - unsigned int numOutputDevices; - /* unsigned int outputChannelCount; */ - WAVEHDR **outputBuffers; - unsigned int numOutputBuffers; - unsigned int currentOutputBufferIndex; - unsigned int framesPerOutputBuffer; - unsigned int framesUsedInCurrentOutputBuffer; - - /* Processing thread management -------------- */ - HANDLE abortEvent; - HANDLE bufferEvent; - HANDLE processingThread; - DWORD processingThreadId; - - char noHighPriorityProcessClass; - char useTimeCriticalProcessingThreadPriority; - char throttleProcessingThreadOnOverload; /* 0 -> don't throtte, non-0 -> throttle */ - int processingThreadPriority; - int highThreadPriority; - int throttledThreadPriority; - - 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 */ - - /* @todo FIXME: we no longer need the following for GetStreamTime support */ - /* GetStreamTime() support ------------- */ - - PaTime streamPosition; - long previousStreamPosition; /* used to track frames played. */ -} -PaWinMmeStream; - - -/* the following macros are intended to improve the readability of the following code */ -#define PA_IS_INPUT_STREAM_( stream ) ( stream ->hWaveIns ) -#define PA_IS_OUTPUT_STREAM_( stream ) ( stream ->hWaveOuts ) -#define PA_IS_FULL_DUPLEX_STREAM_( stream ) ( stream ->hWaveIns && stream ->hWaveOuts ) - - -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; - PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; - PaWinMmeStream *stream = 0; - PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; - int inputChannelCount, outputChannelCount; - PaSampleFormat inputSampleFormat, outputSampleFormat; - double suggestedInputLatency, suggestedOutputLatency; - PaWinMmeStreamInfo *inputStreamInfo, *outputStreamInfo; - unsigned long bytesPerInputFrame, bytesPerOutputFrame; - unsigned long framesPerHostInputBuffer; - unsigned long numHostInputBuffers; - unsigned long framesPerHostOutputBuffer; - unsigned long numHostOutputBuffers; - unsigned long framesPerBufferProcessorCall; - int lockInited = 0; - int bufferEventInited = 0; - int abortEventInited = 0; - WAVEFORMATEX wfx; - MMRESULT mmresult; - unsigned int i; - int channelCount; - PaWinMmeDeviceAndChannelCount *inputDevices = 0; - unsigned long numInputDevices = (inputParameters) ? 1 : 0; - PaWinMmeDeviceAndChannelCount *outputDevices = 0; - unsigned long numOutputDevices = (outputParameters) ? 1 : 0; - char noHighPriorityProcessClass = 0; - char useTimeCriticalProcessingThreadPriority = 0; - char throttleProcessingThreadOnOverload = 1; - - - if( inputParameters ) - { - inputChannelCount = inputParameters->channelCount; - inputSampleFormat = inputParameters->sampleFormat; - suggestedInputLatency = inputParameters->suggestedLatency; - - /* check that input device can support inputChannelCount */ - if( (inputParameters->device != paUseHostApiSpecificDeviceSpecification) && - (inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels) ) - return paInvalidChannelCount; - - - /* validate input hostApiSpecificStreamInfo */ - inputStreamInfo = (PaWinMmeStreamInfo*)inputParameters->hostApiSpecificStreamInfo; - if( inputStreamInfo ) - { - if( inputStreamInfo->size != sizeof( PaWinMmeStreamInfo ) - || inputStreamInfo->version != 1 ) - { - return paIncompatibleHostApiSpecificStreamInfo; - } - - if( inputStreamInfo->flags & PaWinMmeNoHighPriorityProcessClass ) - noHighPriorityProcessClass = 1; - if( inputStreamInfo->flags & PaWinMmeDontThrottleOverloadedProcessingThread ) - throttleProcessingThreadOnOverload = 0; - if( inputStreamInfo->flags & PaWinMmeUseTimeCriticalThreadPriority ) - useTimeCriticalProcessingThreadPriority = 1; - - /* validate multidevice fields */ - - if( inputStreamInfo->flags & PaWinMmeUseMultipleDevices ) - { - int totalChannels = 0; - for( i=0; i< inputStreamInfo->deviceCount; ++i ) - { - /* validate that the device number is within range, and that - the number of channels is legal */ - PaDeviceIndex hostApiDevice; - - if( inputParameters->device != paUseHostApiSpecificDeviceSpecification ) - return paInvalidDevice; - - channelCount = inputStreamInfo->devices[i].channelCount; - - result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, - inputStreamInfo->devices[i].device, hostApi ); - if( result != paNoError ) - return result; - - if( channelCount < 1 || channelCount > hostApi->deviceInfos[ hostApiDevice ]->maxInputChannels ) - return paInvalidChannelCount; - - /* FIXME this validation might be easier and better if there was a pautil - function which performed the validation in pa_front:ValidateOpenStreamParameters() */ - - totalChannels += channelCount; - } - - if( totalChannels != inputChannelCount ) - { - /* inputChannelCount must match total channels specified by multiple devices */ - return paInvalidChannelCount; /* REVIEW use of this error code */ - } - - inputDevices = inputStreamInfo->devices; - numInputDevices = inputStreamInfo->deviceCount; - } - } - - /* FIXME: establish which host formats are available */ - hostInputSampleFormat = - PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat ); - - } - else - { - inputChannelCount = 0; - inputSampleFormat = -1; - suggestedInputLatency = 0.; - inputStreamInfo = 0; - hostInputSampleFormat = -1; - } - - - if( outputParameters ) - { - outputChannelCount = outputParameters->channelCount; - outputSampleFormat = outputParameters->sampleFormat; - suggestedOutputLatency = outputParameters->suggestedLatency; - - /* check that input device can support inputChannelCount */ - if( (outputParameters->device != paUseHostApiSpecificDeviceSpecification) && - (inputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels) ) - return paInvalidChannelCount; - - - /* validate input hostApiSpecificStreamInfo */ - outputStreamInfo = (PaWinMmeStreamInfo*)outputParameters->hostApiSpecificStreamInfo; - if( outputStreamInfo ) - { - if( outputStreamInfo->size != sizeof( PaWinMmeStreamInfo ) - || outputStreamInfo->version != 1 ) - { - return paIncompatibleHostApiSpecificStreamInfo; - } - - if( outputStreamInfo->flags & PaWinMmeNoHighPriorityProcessClass ) - noHighPriorityProcessClass = 1; - if( outputStreamInfo->flags & PaWinMmeDontThrottleOverloadedProcessingThread ) - throttleProcessingThreadOnOverload = 0; - if( outputStreamInfo->flags & PaWinMmeUseTimeCriticalThreadPriority ) - useTimeCriticalProcessingThreadPriority = 1; - - /* validate multidevice fields */ - - if( outputStreamInfo->flags & PaWinMmeUseMultipleDevices ) - { - int totalChannels = 0; - for( i=0; i< outputStreamInfo->deviceCount; ++i ) - { - /* validate that the device number is within range, and that - the number of channels is legal */ - PaDeviceIndex hostApiDevice; - - if( outputParameters->device != paUseHostApiSpecificDeviceSpecification ) - return paInvalidDevice; - - channelCount = outputStreamInfo->devices[i].channelCount; - - result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, - outputStreamInfo->devices[i].device, - hostApi ); - if( result != paNoError ) - return result; - - if( channelCount < 1 || channelCount > hostApi->deviceInfos[ hostApiDevice ]->maxOutputChannels ) - return paInvalidChannelCount; - - /* FIXME this validation might be easier and better if there was a pautil - function which performed the validation in pa_front:ValidateOpenStreamParameters() */ - - totalChannels += channelCount; - } - - if( totalChannels != outputChannelCount ) - { - /* outputChannelCount must match total channels specified by multiple devices */ - return paInvalidChannelCount; /* REVIEW use of this error code */ - } - - outputDevices = outputStreamInfo->devices; - numOutputDevices = outputStreamInfo->deviceCount; - } - } - - /* FIXME: establish which host formats are available */ - hostOutputSampleFormat = - PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat ); - } - else - { - outputChannelCount = 0; - outputSampleFormat = -1; - outputStreamInfo = 0; - hostOutputSampleFormat = -1; - 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, &numHostInputBuffers, - &framesPerHostOutputBuffer, &numHostOutputBuffers, - 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; - } - - stream->hWaveIns = 0; - stream->inputBuffers = 0; - stream->hWaveOuts = 0; - stream->outputBuffers = 0; - stream->processingThread = 0; - - stream->noHighPriorityProcessClass = noHighPriorityProcessClass; - stream->useTimeCriticalProcessingThreadPriority = useTimeCriticalProcessingThreadPriority; - stream->throttleProcessingThreadOnOverload = throttleProcessingThreadOnOverload; - - PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, - &winMmeHostApi->callbackStreamInterface, streamCallback, userData ); - - stream->streamRepresentation.streamInfo.inputLatency = (double)(framesPerHostInputBuffer * (numHostInputBuffers-1)) / sampleRate; - stream->streamRepresentation.streamInfo.outputLatency = (double)(framesPerHostOutputBuffer * (numHostOutputBuffers-1)) / sampleRate; - stream->streamRepresentation.streamInfo.sampleRate = sampleRate; - - PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); - - - if( inputParameters && outputParameters ) /* full duplex */ - { - /* - either host input and output buffers must be the same size, or the - larger one must be an integer multiple of the smaller one. - FIXME: should this return an error if the host specific latency - settings don't fulfill these constraints? rb: probably - */ - - if( framesPerHostInputBuffer < framesPerHostOutputBuffer ) - { - assert( (framesPerHostOutputBuffer % framesPerHostInputBuffer) == 0 ); - - framesPerBufferProcessorCall = framesPerHostInputBuffer; - } - else - { - assert( (framesPerHostInputBuffer % framesPerHostOutputBuffer) == 0 ); - - framesPerBufferProcessorCall = framesPerHostOutputBuffer; - } - } - else if( inputParameters ) - { - framesPerBufferProcessorCall = framesPerHostInputBuffer; - } - else if( outputParameters ) - { - framesPerBufferProcessorCall = framesPerHostOutputBuffer; - } - - stream->framesPerInputBuffer = framesPerHostInputBuffer; - stream->framesPerOutputBuffer = framesPerHostOutputBuffer; - - result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, - inputChannelCount, inputSampleFormat, hostInputSampleFormat, - outputChannelCount, outputSampleFormat, hostOutputSampleFormat, - sampleRate, streamFlags, framesPerBuffer, - framesPerBufferProcessorCall, paUtilFixedHostBufferSize, - streamCallback, userData ); - if( result != paNoError ) - goto error; - - stream->isActive = 0; - - stream->streamPosition = 0.; - stream->previousStreamPosition = 0; - - - stream->bufferEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); - if( stream->bufferEvent == NULL ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); - goto error; - } - bufferEventInited = 1; - - if( inputParameters ) - { - wfx.wFormatTag = WAVE_FORMAT_PCM; - wfx.nSamplesPerSec = (DWORD) sampleRate; - wfx.cbSize = 0; - - stream->numInputDevices = numInputDevices; - stream->hWaveIns = (HWAVEIN*)PaUtil_AllocateMemory( sizeof(HWAVEIN) * stream->numInputDevices ); - if( !stream->hWaveIns ) - { - result = paInsufficientMemory; - goto error; - } - - for( i = 0; i < stream->numInputDevices; ++i ) - stream->hWaveIns[i] = 0; - - for( i = 0; i < stream->numInputDevices; ++i ) - { - int inputWinMmeId; - - if( inputDevices ) - { - PaDeviceIndex hostApiDevice; - - result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, - inputDevices[i].device, hostApi ); - if( result != paNoError ) - return result; - - inputWinMmeId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, hostApiDevice ); - wfx.nChannels = (WORD) inputDevices[i].channelCount; - } - else - { - inputWinMmeId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, inputParameters->device ); - wfx.nChannels = (WORD) inputChannelCount; - } - - bytesPerInputFrame = wfx.nChannels * stream->bufferProcessor.bytesPerHostInputSample; - - wfx.nAvgBytesPerSec = (DWORD)(bytesPerInputFrame * sampleRate); - wfx.nBlockAlign = (WORD)bytesPerInputFrame; - wfx.wBitsPerSample = (WORD)((bytesPerInputFrame/wfx.nChannels) * 8); - - /* REVIEW: consider not firing an event for input when a full duplex stream is being used */ - - mmresult = waveInOpen( &stream->hWaveIns[i], inputWinMmeId, &wfx, - (DWORD)stream->bufferEvent, (DWORD) stream, CALLBACK_EVENT ); - if( mmresult != MMSYSERR_NOERROR ) - { - switch( mmresult ) - { - case MMSYSERR_ALLOCATED: /* Specified resource is already allocated. */ - result = paDeviceUnavailable; - break; - case MMSYSERR_BADDEVICEID: /* Specified device identifier is out of range. */ - result = paInternalError; /* portaudio should ensure that only good device ids are used */ - 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 WAVERR_BADFORMAT: /* Attempted to open with an unsupported waveform-audio format. */ - result = paInternalError; /* REVIEW: port audio shouldn't get this far without using compatible format info */ - break; - default: - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); - } - goto error; - } - } - } - - if( outputParameters ) - { - wfx.wFormatTag = WAVE_FORMAT_PCM; - wfx.nSamplesPerSec = (DWORD) sampleRate; - wfx.cbSize = 0; - - stream->numOutputDevices = numOutputDevices; - stream->hWaveOuts = (HWAVEOUT*)PaUtil_AllocateMemory( sizeof(HWAVEOUT) * stream->numOutputDevices ); - if( !stream->hWaveOuts ) - { - result = paInsufficientMemory; - goto error; - } - - for( i = 0; i < stream->numOutputDevices; ++i ) - stream->hWaveOuts[i] = 0; - - for( i = 0; i < stream->numOutputDevices; ++i ) - { - int outputWinMmeId; - - if( outputDevices ) - { - PaDeviceIndex hostApiDevice; - - result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, - outputDevices[i].device, hostApi ); - if( result != paNoError ) - return result; - - outputWinMmeId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, hostApiDevice ); - wfx.nChannels = (WORD) outputDevices[i].channelCount; - } - else - { - outputWinMmeId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputParameters->device ); - wfx.nChannels = (WORD) outputChannelCount; - } - - bytesPerOutputFrame = wfx.nChannels * stream->bufferProcessor.bytesPerHostOutputSample; - - wfx.nAvgBytesPerSec = (DWORD)(bytesPerOutputFrame * sampleRate); - wfx.nBlockAlign = (WORD)bytesPerOutputFrame; - wfx.wBitsPerSample = (WORD)((bytesPerOutputFrame/wfx.nChannels) * 8); - - mmresult = waveOutOpen( &stream->hWaveOuts[i], outputWinMmeId, &wfx, - (DWORD)stream->bufferEvent, (DWORD) stream, CALLBACK_EVENT ); - if( mmresult != MMSYSERR_NOERROR ) - { - switch( mmresult ) - { - case MMSYSERR_ALLOCATED: /* Specified resource is already allocated. */ - result = paDeviceUnavailable; - break; - case MMSYSERR_BADDEVICEID: /* Specified device identifier is out of range. */ - result = paInternalError; /* portaudio should ensure that only good device ids are used */ - 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 WAVERR_BADFORMAT: /* Attempted to open with an unsupported waveform-audio format. */ - result = paInternalError; /* REVIEW: port audio shouldn't get this far without using compatible format info */ - break; - default: - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); - } - goto error; - } - } - } - - if( PA_IS_INPUT_STREAM_(stream) ) - { - stream->inputBuffers = (WAVEHDR**)PaUtil_AllocateMemory( sizeof(WAVEHDR*) * stream->numInputDevices ); - if( stream->inputBuffers == 0 ) - { - result = paInsufficientMemory; - goto error; - } - - for( i =0; i < stream->numInputDevices; ++i ) - stream->inputBuffers[i] = 0; - - stream->numInputBuffers = numHostInputBuffers; - - for( i =0; i < stream->numInputDevices; ++i ) - { - int hostInputBufferBytes = Pa_GetSampleSize( hostInputSampleFormat ) * - framesPerHostInputBuffer * - ((inputDevices) ? inputDevices[i].channelCount : inputChannelCount); - if( hostInputBufferBytes < 0 ) - { - result = paInternalError; - goto error; - } - - result = InitializeBufferSet( &stream->inputBuffers[i], numHostInputBuffers, hostInputBufferBytes, - 1 /* isInput */, - (MmeHandle)stream->hWaveIns[i], - ((inputDevices) ? inputDevices[i].channelCount : inputChannelCount) ); - - if( result != paNoError ) - goto error; - } - } - - if( PA_IS_OUTPUT_STREAM_(stream) ) - { - stream->outputBuffers = (WAVEHDR**)PaUtil_AllocateMemory( sizeof(WAVEHDR*) * stream->numOutputDevices ); - if( stream->outputBuffers == 0 ) - { - result = paInsufficientMemory; - goto error; - } - - for( i =0; i < stream->numOutputDevices; ++i ) - stream->outputBuffers[i] = 0; - - stream->numOutputBuffers = numHostOutputBuffers; - - for( i=0; i < stream->numOutputDevices; ++i ) - { - int hostOutputBufferBytes = Pa_GetSampleSize( hostOutputSampleFormat ) * - framesPerHostOutputBuffer * - ((outputDevices) ? outputDevices[i].channelCount : outputChannelCount); - if( hostOutputBufferBytes < 0 ) - { - result = paInternalError; - goto error; - } - - result = InitializeBufferSet( &stream->outputBuffers[i], numHostOutputBuffers, hostOutputBufferBytes, - 0 /* not isInput */, - (MmeHandle)stream->hWaveOuts[i], - ((outputDevices) ? outputDevices[i].channelCount : outputChannelCount) ); - - if( result != paNoError ) - goto error; - } - } - - stream->abortEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); - if( stream->abortEvent == NULL ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); - goto error; - } - abortEventInited = 1; - - InitializeCriticalSection( &stream->lock ); - lockInited = 1; - - if( PA_IS_OUTPUT_STREAM_(stream) ) - stream->allBuffersDurationMs = (DWORD) (1000.0 * (framesPerHostOutputBuffer * stream->numOutputBuffers) / sampleRate); - else - stream->allBuffersDurationMs = (DWORD) (1000.0 * (framesPerHostInputBuffer * stream->numInputBuffers) / sampleRate); - - - *s = (PaStream*)stream; - - return result; - -error: - if( lockInited ) - DeleteCriticalSection( &stream->lock ); - - if( abortEventInited ) - CloseHandle( stream->abortEvent ); - - - if( stream->inputBuffers ) - { - for( i =0 ; i< stream->numInputDevices; ++i ) - { - if( stream->inputBuffers[i] ) - { - TerminateBufferSet( &stream->inputBuffers[i], stream->numInputBuffers, - 1 /* isInput */, (MmeHandle)stream->hWaveIns[i] ); - } - } - - PaUtil_FreeMemory( stream->inputBuffers ); - } - - if( stream->outputBuffers ) - { - for( i =0 ; i< stream->numOutputDevices; ++i ) - { - if( stream->outputBuffers[i] ) - { - TerminateBufferSet( &stream->outputBuffers[i], stream->numOutputBuffers, - 0 /* not isInput */, (MmeHandle)stream->hWaveOuts[i] ); - } - } - - PaUtil_FreeMemory( stream->outputBuffers ); - } - - if( stream->hWaveIns ) - { - for( i =0 ; i< stream->numInputDevices; ++i ) - { - if( stream->hWaveIns[i] ) - waveInClose( stream->hWaveIns[i] ); - } - - PaUtil_FreeMemory( stream->hWaveIns ); - } - - if( stream->hWaveOuts ) - { - for( i =0 ; i< stream->numOutputDevices; ++i ) - { - if( stream->hWaveOuts[i] ) - waveOutClose( stream->hWaveOuts[i] ); - } - - PaUtil_FreeMemory( stream->hWaveOuts ); - } - - if( bufferEventInited ) - CloseHandle( stream->bufferEvent ); - - if( stream ) - PaUtil_FreeMemory( stream ); - - return result; -} - - -/* return non-zero if any output buffers are queued */ -static int OutputBuffersAreQueued( PaWinMmeStream *stream ) -{ - int result = 0; - unsigned int i, j; - - if( PA_IS_OUTPUT_STREAM_( stream ) ) - { - for( i=0; i<stream->numOutputBuffers; ++i ) - { - for( j=0; j < stream->numOutputDevices; ++j ) - { - if( !( stream->outputBuffers[ j ][ i ].dwFlags & WHDR_DONE) ) - { - result++; - } - } - } - } - - return result; -} - - -static PaError AdvanceToNextInputBuffer( PaWinMmeStream *stream ) -{ - PaError result = paNoError; - MMRESULT mmresult; - unsigned int i; - - for( i=0; i< stream->numInputDevices; ++i ) - { - mmresult = waveInAddBuffer( stream->hWaveIns[i], - &stream->inputBuffers[i][ stream->currentInputBufferIndex ], - sizeof(WAVEHDR) ); - if( mmresult != MMSYSERR_NOERROR ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); - } - } - stream->currentInputBufferIndex = (stream->currentInputBufferIndex+1 >= stream->numInputBuffers) ? - 0 : stream->currentInputBufferIndex+1; - - stream->framesUsedInCurrentInputBuffer = 0; - - return result; -} - - -static PaError AdvanceToNextOutputBuffer( PaWinMmeStream *stream ) -{ - PaError result = paNoError; - MMRESULT mmresult; - unsigned int i; - - for( i=0; i< stream->numOutputDevices; ++i ) - { - mmresult = waveOutWrite( stream->hWaveOuts[i], - &stream->outputBuffers[i][ stream->currentOutputBufferIndex ], - sizeof(WAVEHDR) ); - if( mmresult != MMSYSERR_NOERROR ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); - } - } - - stream->currentOutputBufferIndex = (stream->currentOutputBufferIndex+1 >= stream->numOutputBuffers) ? - 0 : stream->currentOutputBufferIndex+1; - - stream->framesUsedInCurrentOutputBuffer = 0; - - return result; -} - - -static DWORD WINAPI ProcessingThreadProc( void *pArg ) -{ - PaWinMmeStream *stream = (PaWinMmeStream *)pArg; - HANDLE events[2]; - int numEvents = 0; - DWORD result = paNoError; - DWORD waitResult; -/** @todo: -Gordon Gidluck: -> function: ProcessingThreadProc() -> line #1665 DWORD timeout = stream->allBuffersDurationMs * 0.5; -> conversion from 'double ' to 'unsigned long ', possible loss of data -*/ - DWORD timeout = stream->allBuffersDurationMs * 0.5; - DWORD numTimeouts = 0; - int hostBuffersAvailable; - signed int hostInputBufferIndex, hostOutputBufferIndex; - int callbackResult; - int done = 0; - unsigned int channel, i, j; - unsigned long framesProcessed; - - /* prepare event array for call to WaitForMultipleObjects() */ - events[numEvents++] = stream->bufferEvent; - events[numEvents++] = stream->abortEvent; - - /* loop until something causes us to stop */ - while( !done ) - { - /* wait for MME to signal that a buffer is available, or for - the PA abort event to be signaled */ - waitResult = WaitForMultipleObjects( numEvents, events, FALSE, timeout ); - if( waitResult == WAIT_FAILED ) - { - result = paUnanticipatedHostError; - /* 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 */ - numTimeouts += 1; - } - - 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( !OutputBuffersAreQueued( 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)) - { - hostInputBufferIndex = stream->currentInputBufferIndex; - for( i=0; i<stream->numInputDevices; ++i ) - { - if( !(stream->inputBuffers[i][ stream->currentInputBufferIndex ].dwFlags & WHDR_DONE) ) - { - hostInputBufferIndex = -1; - break; - } - } - - if( hostInputBufferIndex != -1 ) - { - /* if all of the other buffers are also ready then we dicard all but the - most recent. */ - int inputCatchUp = 1; - - for( i=0; i < stream->numInputBuffers && inputCatchUp == 1; ++i ) - { - for( j=0; j<stream->numInputDevices; ++j ) - { - if( !(stream->inputBuffers[ j ][ i ].dwFlags & WHDR_DONE) ) - { - inputCatchUp = 0; - break; - } - } - } - - if( inputCatchUp ) - { - for( i=0; i < stream->numInputBuffers - 1; ++i ) - { - result = AdvanceToNextInputBuffer( stream ); - if( result != paNoError ) - done = 1; - } - } - } - } - - if( PA_IS_OUTPUT_STREAM_(stream) ) - { - hostOutputBufferIndex = stream->currentOutputBufferIndex; - for( i=0; i<stream->numOutputDevices; ++i ) - { - if( !(stream->outputBuffers[i][ stream->currentOutputBufferIndex ].dwFlags & WHDR_DONE) ) - { - hostOutputBufferIndex = -1; - break; - } - } - - if( hostOutputBufferIndex != - 1 ) - { - /* 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 */ - int outputCatchUp = 1; - - for( i=0; i < stream->numOutputBuffers && outputCatchUp == 1; ++i ) - { - for( j=0; j<stream->numOutputDevices; ++j ) - { - if( !(stream->outputBuffers[ j ][ i ].dwFlags & WHDR_DONE) ) - { - outputCatchUp = 0; - break; - } - } - } - - if( outputCatchUp ) - { - /* FIXME: this is an output underflow buffer slip and should be flagged as such */ - unsigned int previousBufferIndex = (stream->currentOutputBufferIndex==0) - ? stream->numOutputBuffers - 1 - : stream->currentOutputBufferIndex - 1; - - for( i=0; i < stream->numOutputBuffers - 1; ++i ) - { - for( j=0; j<stream->numOutputDevices; ++j ) - { - if( stream->outputBuffers[j][ stream->currentOutputBufferIndex ].lpData - != stream->outputBuffers[j][ previousBufferIndex ].lpData ) - { - CopyMemory( stream->outputBuffers[j][ stream->currentOutputBufferIndex ].lpData, - stream->outputBuffers[j][ previousBufferIndex ].lpData, - stream->outputBuffers[j][ stream->currentOutputBufferIndex ].dwBufferLength ); - } - } - - result = AdvanceToNextOutputBuffer( stream ); - if( result != paNoError ) - done = 1; - } - } - } - } - - - if( (PA_IS_FULL_DUPLEX_STREAM_(stream) && hostInputBufferIndex != -1 && hostOutputBufferIndex != -1) || - (!PA_IS_FULL_DUPLEX_STREAM_(stream) && ( hostInputBufferIndex != -1 || hostOutputBufferIndex != -1 ) ) ) - { - PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* @todo implement inputBufferAdcTime and currentTime */ - - - if( hostOutputBufferIndex != -1 ){ - MMTIME time; - double now; - long totalRingFrames; - long ringPosition; - long playbackPosition; - - time.wType = TIME_SAMPLES; - waveOutGetPosition( stream->hWaveOuts[0], &time, sizeof(MMTIME) ); - now = PaUtil_GetTime(); - - totalRingFrames = stream->numOutputBuffers * stream->bufferProcessor.framesPerHostBuffer; - - ringPosition = stream->currentOutputBufferIndex * stream->bufferProcessor.framesPerHostBuffer; - - playbackPosition = time.u.sample % totalRingFrames; - - if( playbackPosition >= ringPosition ){ - timeInfo.outputBufferDacTime = - now + ((double)( ringPosition + (totalRingFrames - playbackPosition) ) * stream->bufferProcessor.samplePeriod ); - }else{ - timeInfo.outputBufferDacTime = - now + ((double)( ringPosition - playbackPosition ) * stream->bufferProcessor.samplePeriod ); - } - } - - - PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); - - PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo ); - - if( hostInputBufferIndex != -1 ) - { - PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); - - channel = 0; - for( i=0; i<stream->numInputDevices; ++i ) - { - /* we have stored the number of channels in the buffer in dwUser */ - int channelCount = stream->inputBuffers[i][ hostInputBufferIndex ].dwUser; - - PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, channel, - stream->inputBuffers[i][ hostInputBufferIndex ].lpData + - stream->framesUsedInCurrentInputBuffer * channelCount * - stream->bufferProcessor.bytesPerHostInputSample, - channelCount ); - - - channel += channelCount; - } - } - - if( hostOutputBufferIndex != -1 ) - { - PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); - - channel = 0; - for( i=0; i<stream->numOutputDevices; ++i ) - { - /* we have stored the number of channels in the buffer in dwUser */ - int channelCount = stream->outputBuffers[i][ hostOutputBufferIndex ].dwUser; - - PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, - stream->outputBuffers[i][ hostOutputBufferIndex ].lpData + - stream->framesUsedInCurrentOutputBuffer * channelCount * - stream->bufferProcessor.bytesPerHostOutputSample, - channelCount ); - - /* we have stored the number of channels in the buffer in dwUser */ - channel += channelCount; - } - } - - framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); - - stream->framesUsedInCurrentInputBuffer += framesProcessed; - stream->framesUsedInCurrentOutputBuffer += framesProcessed; - - PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); - - if( callbackResult == paContinue ) - { - /* nothing special to do */ - } - else if( callbackResult == paAbort ) - { - stream->abortProcessing = 1; - done = 1; - /* FIXME: should probably do a reset here */ - result = paNoError; - } - else - { - /* User cllback has asked us to stop with paComplete or other non-zero value */ - stream->stopProcessing = 1; /* stop once currently queued audio has finished */ - result = paNoError; - } - - /* - FIXME: the following code is incorrect, because stopProcessing should - still queue the current buffer. - */ - if( stream->stopProcessing == 0 && stream->abortProcessing == 0 ) - { - if( stream->throttleProcessingThreadOnOverload != 0 ) - { - if( PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ) > 1. ) - { - if( stream->processingThreadPriority != stream->throttledThreadPriority ) - { - SetThreadPriority( stream->processingThread, stream->throttledThreadPriority ); - stream->processingThreadPriority = stream->throttledThreadPriority; - } - -/** @todo: -Gordon Gidluck: -> function: ProcessingThreadProc() -> line #1947/1948 Sleep( stream->bufferProcessor.framesPerHostBuffer * -> stream->bufferProcessor.samplePeriod * .25 ); -> conversion from 'double ' to 'unsigned long ', possible loss of data -> integral size mismatch in argument; conversion supplied -*/ - /* sleep for a quater of a buffer's duration to give other processes a go */ - Sleep( stream->bufferProcessor.framesPerHostBuffer * - stream->bufferProcessor.samplePeriod * .25 ); - } - else - { - if( stream->processingThreadPriority != stream->highThreadPriority ) - { - SetThreadPriority( stream->processingThread, stream->highThreadPriority ); - stream->processingThreadPriority = stream->highThreadPriority; - } - } - } - - if( PA_IS_INPUT_STREAM_(stream) && - stream->framesUsedInCurrentInputBuffer == stream->framesPerInputBuffer ) - { - result = AdvanceToNextInputBuffer( stream ); - if( result != paNoError ) - done = 1; - } - - if( PA_IS_OUTPUT_STREAM_(stream) && - stream->framesUsedInCurrentOutputBuffer == stream->framesPerOutputBuffer ) - { - result = AdvanceToNextOutputBuffer( stream ); - if( result != paNoError ) - done = 1; - } - } - } - else - { - hostBuffersAvailable = 0; - } - } - while( hostBuffersAvailable && - stream->stopProcessing == 0 && - stream->abortProcessing == 0 && - !done ); - } - - result = UpdateStreamTime( stream ); - if( result != paNoError ) - done = 1; - } - - stream->isActive = 0; - - if( stream->streamRepresentation.streamFinishedCallback != 0 ) - stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); - - 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; - PaWinMmeStream *stream = (PaWinMmeStream*)s; - MMRESULT mmresult; - unsigned int i; - - if( PA_IS_INPUT_STREAM_(stream) ) - { - for( i=0; i<stream->numInputDevices; ++i ) - { - TerminateBufferSet( &stream->inputBuffers[i], stream->numInputBuffers, - 1 /* isInput */, (MmeHandle)stream->hWaveIns[i] ); - } - - PaUtil_FreeMemory( stream->inputBuffers ); - } - - if( PA_IS_OUTPUT_STREAM_(stream) ) - { - for( i=0; i<stream->numOutputDevices; ++i ) - { - TerminateBufferSet( &stream->outputBuffers[i], stream->numOutputBuffers, - 0 /* not isInput */, (MmeHandle)stream->hWaveOuts[i] ); - } - - PaUtil_FreeMemory( stream->outputBuffers ); - } - - - if( PA_IS_INPUT_STREAM_(stream) ) - { - for( i=0; i<stream->numInputDevices; ++i ) - { - mmresult = waveInClose( stream->hWaveIns[i] ); - if( mmresult != MMSYSERR_NOERROR ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); - goto error; - } - } - - PaUtil_FreeMemory( stream->hWaveIns ); - } - - if( PA_IS_OUTPUT_STREAM_(stream) ) - { - for( i=0; i<stream->numOutputDevices; ++i ) - { - mmresult = waveOutClose( stream->hWaveOuts[i] ); - if( mmresult != MMSYSERR_NOERROR ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); - goto error; - } - } - - PaUtil_FreeMemory( stream->hWaveOuts ); - } - - if( CloseHandle( stream->bufferEvent ) == 0 ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); - goto error; - } - - if( CloseHandle( stream->abortEvent ) == 0 ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); - goto error; - } - - DeleteCriticalSection( &stream->lock ); - - PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); - PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); - PaUtil_FreeMemory( stream ); - -error: - /* FIXME: consider how to best clean up on failure */ - return result; -} - - -static PaError StartStream( PaStream *s ) -{ - PaError result = paNoError; - PaWinMmeStream *stream = (PaWinMmeStream*)s; - MMRESULT mmresult; - unsigned int i, j; - - if( PA_IS_INPUT_STREAM_(stream) ) - { - for( i=0; i<stream->numInputBuffers; ++i ) - { - for( j=0; j<stream->numInputDevices; ++j ) - { - mmresult = waveInAddBuffer( stream->hWaveIns[j], &stream->inputBuffers[j][i], sizeof(WAVEHDR) ); - if( mmresult != MMSYSERR_NOERROR ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); - goto error; - } - } - } - stream->currentInputBufferIndex = 0; - stream->framesUsedInCurrentInputBuffer = 0; - } - - if( PA_IS_OUTPUT_STREAM_(stream) ) - { - for( i=0; i<stream->numOutputDevices; ++i ) - { - if( (mmresult = waveOutPause( stream->hWaveOuts[i] )) != MMSYSERR_NOERROR ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); - goto error; - } - } - - for( i=0; i<stream->numOutputBuffers; ++i ) - { - for( j=0; j<stream->numOutputDevices; ++j ) - { - ZeroMemory( stream->outputBuffers[j][i].lpData, stream->outputBuffers[j][i].dwBufferLength ); - mmresult = waveOutWrite( stream->hWaveOuts[j], &stream->outputBuffers[j][i], sizeof(WAVEHDR) ); - if( mmresult != MMSYSERR_NOERROR ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); - goto error; - } - } - } - stream->currentOutputBufferIndex = 0; - stream->framesUsedInCurrentOutputBuffer = 0; - } - - stream->streamPosition = 0.; - stream->previousStreamPosition = 0; - - stream->isActive = 1; - stream->stopProcessing = 0; - stream->abortProcessing = 0; - - if( ResetEvent( stream->bufferEvent ) == 0 ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); - goto error; - } - - if( ResetEvent( stream->abortEvent ) == 0 ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); - 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; - } - - /* I used to pass the thread which was failing. I now pass GetCurrentProcess(). - * This fix could improve latency for some applications. It could also result in CPU - * starvation if the callback did too much processing. - * I also added result checks, so we might see more failures at initialization. - * Thanks to Alberto di Bene for spotting this. - */ - /* REVIEW: should we reset the priority class when the stream has stopped? - - would be best to refcount priority boosts incase more than one - stream is open - */ - - if( !stream->noHighPriorityProcessClass ) - { -#ifndef WIN32_PLATFORM_PSPC /* no SetPriorityClass or HIGH_PRIORITY_CLASS on PocketPC */ - - if( !SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) ) /* PLB20010816 */ - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); - goto error; - } -#endif - } - - if( stream->useTimeCriticalProcessingThreadPriority ) - stream->highThreadPriority = THREAD_PRIORITY_TIME_CRITICAL; - else - stream->highThreadPriority = THREAD_PRIORITY_HIGHEST; - - 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; - - - if( PA_IS_INPUT_STREAM_(stream) ) - { - for( i=0; i < stream->numInputDevices; ++i ) - { - mmresult = waveInStart( stream->hWaveIns[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->numOutputDevices; ++i ) - { - if( (mmresult = waveOutRestart( stream->hWaveOuts[i] )) != MMSYSERR_NOERROR ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); - goto error; - } - } - } - - return result; - -error: - /* 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; - unsigned int i; - - /* - FIXME: 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. - */ - - - /* 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 = stream->allBuffersDurationMs * 1.5; - if( timeout < PA_MIN_TIMEOUT_MSEC_ ) - timeout = PA_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; - - if( PA_IS_OUTPUT_STREAM_(stream) ) - { - for( i =0; i < stream->numOutputDevices; ++i ) - { - mmresult = waveOutReset( stream->hWaveOuts[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->numInputDevices; ++i ) - { - mmresult = waveInReset( stream->hWaveIns[i] ); - if( mmresult != MMSYSERR_NOERROR ) - { - result = paUnanticipatedHostError; - PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); - } - } - } - - 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; - - /* - FIXME: 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. - */ - - /* Tell processing thread to abort immediately */ - stream->abortProcessing = 1; - SetEvent( stream->abortEvent ); - - /* Calculate timeOut longer than longest time it could take to return all buffers. */ - timeout = stream->allBuffersDurationMs * 1.5; - if( timeout < PA_MIN_TIMEOUT_MSEC_ ) - timeout = PA_MIN_TIMEOUT_MSEC_; - - if( PA_IS_OUTPUT_STREAM_(stream) ) - { - for( i =0; i < stream->numOutputDevices; ++i ) - { - mmresult = waveOutReset( stream->hWaveOuts[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->numInputDevices; ++i ) - { - mmresult = waveInReset( stream->hWaveIns[i] ); - if( mmresult != MMSYSERR_NOERROR ) - { - PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); - return paUnanticipatedHostError; - } - } - } - - - PA_DEBUG(("WinMME AbortStream: waiting for background thread.\n")); - - 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->isActive = 0; - - return result; -} - - -static PaError IsStreamStopped( PaStream *s ) -{ - PaWinMmeStream *stream = (PaWinMmeStream*)s; - - return ( stream->processingThread == NULL ); -} - - -static PaError IsStreamActive( PaStream *s ) -{ - PaWinMmeStream *stream = (PaWinMmeStream*)s; - - return stream->isActive; -} - - -/* UpdateStreamTime() must be called periodically because mmtime.u.sample - is a DWORD and can wrap and lose sync after a few hours. - */ -static PaError UpdateStreamTime( PaWinMmeStream *stream ) -{ - MMRESULT mmresult; - MMTIME mmtime; - mmtime.wType = TIME_SAMPLES; - - if( stream->hWaveOuts ) - { - /* assume that all devices have the same position */ - mmresult = waveOutGetPosition( stream->hWaveOuts[0], &mmtime, sizeof(mmtime) ); - - if( mmresult != MMSYSERR_NOERROR ) - { - PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); - return paUnanticipatedHostError; - } - } - else - { - /* assume that all devices have the same position */ - mmresult = waveInGetPosition( stream->hWaveIns[0], &mmtime, sizeof(mmtime) ); - - if( mmresult != MMSYSERR_NOERROR ) - { - PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); - return paUnanticipatedHostError; - } - } - - - /* This data has two variables and is shared by foreground and background. - * So we need to make it thread safe. */ - EnterCriticalSection( &stream->lock ); - stream->streamPosition += ((long)mmtime.u.sample) - stream->previousStreamPosition; - stream->previousStreamPosition = (long)mmtime.u.sample; - LeaveCriticalSection( &stream->lock ); - - return paNoError; -} - - -static PaTime GetStreamTime( PaStream *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. - - PaWinMmeStream *stream = (PaWinMmeStream*)s; - PaError error = UpdateStreamTime( stream ); - - if( error == paNoError ) - return stream->streamPosition; - else - return 0; -*/ - (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 ) -{ - PaWinMmeStream *stream = (PaWinMmeStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior*/ - (void) stream; /* unused parameters */ - (void) buffer; - (void) frames; - - return paNoError; -} - - -static PaError WriteStream( PaStream* s, - void *buffer, - unsigned long frames ) -{ - PaWinMmeStream *stream = (PaWinMmeStream*)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 ) -{ - PaWinMmeStream *stream = (PaWinMmeStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior*/ - (void) stream; /* unused parameter */ - - return 0; -} - - -static signed long GetStreamWriteAvailable( PaStream* s ) -{ - PaWinMmeStream *stream = (PaWinMmeStream*)s; - - /* IMPLEMENT ME, see portaudio.h for required behavior*/ - (void) stream; /* unused parameter */ - - return 0; -} - - - - diff --git a/pd/portaudio/pa_win_wmme/pa_win_wmme.h b/pd/portaudio/pa_win_wmme/pa_win_wmme.h deleted file mode 100644 index d5c18a28..00000000 --- a/pd/portaudio/pa_win_wmme/pa_win_wmme.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef PA_WIN_WMME_H -#define PA_WIN_WMME_H - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/* - * - * 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. - * - */ - - -#include "portaudio.h" - -#define PaWinMmeUseLowLevelLatencyParameters (0x01) -#define PaWinMmeUseMultipleDevices (0x02) /* use mme specific multiple device feature */ - -/* by default, the mme implementation boosts the process priority class to - HIGH_PRIORITY_CLASS. This flag disables that priority boost */ -#define PaWinMmeNoHighPriorityProcessClass (0x03) - -/* 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% */ -#define PaWinMmeDontThrottleOverloadedProcessingThread (0x04) - -/* by default, the mme implementation sets the processing thread's priority to - THREAD_PRIORITY_HIGHEST. This flag sets the priority to - THREAD_PRIORITY_TIME_CRITICAL instead. Note that this has the potential - to freeze the machine, especially when used in combination with - PaWinMmeDontThrottleOverloadedProcessingThread */ -#define PaWinMmeUseTimeCriticalThreadPriority (0x05) - -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. - */ - unsigned long framesPerBuffer; - unsigned long 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; - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* PA_WIN_WMME_H */ diff --git a/pd/portaudio/pablio/README.txt b/pd/portaudio/pablio/README.txt deleted file mode 100644 index 99c7d146..00000000 --- a/pd/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/pd/portaudio/pablio/pablio.c b/pd/portaudio/pablio/pablio.c deleted file mode 100644 index 53dec058..00000000 --- a/pd/portaudio/pablio/pablio.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * $Id: pablio.c,v 1.1.1.1 2002-07-29 17:06:16 ggeiger 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/pd/portaudio/pablio/pablio.def b/pd/portaudio/pablio/pablio.def deleted file mode 100644 index a10f9529..00000000 --- a/pd/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/pd/portaudio/pablio/pablio.h b/pd/portaudio/pablio/pablio.h deleted file mode 100644 index 85843ae9..00000000 --- a/pd/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.2 2003-05-09 16:03:59 ggeiger 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/pd/portaudio/pablio/pablio_pd.c b/pd/portaudio/pablio/pablio_pd.c deleted file mode 100644 index 49323ef1..00000000 --- a/pd/portaudio/pablio/pablio_pd.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * $Id: pablio_pd.c,v 1.1.1.2 2003-05-09 16:03:59 ggeiger 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. - * - */ - - /* changes by Miller Puckette to support Pd: device selection, - settable audio buffer size, and settable number of channels. - LATER also fix it to poll for input and output fifo fill points. */ - -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include "portaudio.h" -#include "ringbuffer.h" -#include "pablio_pd.h" /* MSP */ -#include <string.h> - - /* MSP -- FRAMES_PER_BUFFER constant removed */ - -/************************************************************************/ -/******** Prototypes ****************************************************/ -/************************************************************************/ - -static int blockingIOCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo *outTime, - PaStreamCallbackFlags myflags, - 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, - const PaStreamCallbackTimeInfo *outTime, - PaStreamCallbackFlags myflags, - 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 - */ -PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate, - PaSampleFormat format, long flags, int nchannels, - int framesperbuf, int nbuffers, - int indeviceno, int outdeviceno) /* MSP */ -{ - long bytesPerSample; - long doRead = 0; - long doWrite = 0; - PaError err; - PABLIO_Stream *aStream; - PaStreamParameters instreamparams, outstreamparams; /* MSP */ - long minNumBuffers; - long numFrames; - - /* fprintf(stderr, - "open %lf fmt %d flags %d ch: %d fperbuf: %d nbuf: %d devs: %d %d\n", - sampleRate, format, flags, nchannels, - framesperbuf, nbuffers, indeviceno, outdeviceno); */ - - if (indeviceno < 0) /* MSP... */ - { - indeviceno = Pa_GetDefaultInputDevice(); - fprintf(stderr, "using default input device number: %d\n", indeviceno); - } - if (outdeviceno < 0) - { - outdeviceno = Pa_GetDefaultOutputDevice(); - fprintf(stderr, "using default output device number: %d\n", outdeviceno); - } - nbuffers = RoundUpToNextPowerOf2(nbuffers); - fprintf(stderr, "nchan %d, flags %ld, bufs %d, framesperbuf %d\n", - nchannels, flags, nbuffers, framesperbuf); - /* ...MSP */ - - /* 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 = nchannels; /* MSP */ - aStream->bytesPerFrame = bytesPerSample * aStream->samplesPerFrame; - - - numFrames = nbuffers * framesperbuf; - - instreamparams.device = indeviceno; /* MSP */ - instreamparams.channelCount = nchannels; - instreamparams.sampleFormat = format; - instreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate; - instreamparams.hostApiSpecificStreamInfo = 0; - - outstreamparams.device = outdeviceno; - outstreamparams.channelCount = nchannels; - outstreamparams.sampleFormat = format; - outstreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate; - outstreamparams.hostApiSpecificStreamInfo = 0; - - - /* 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 ? &instreamparams : 0), /* MSP */ - (doWrite ? &outstreamparams : 0), /* MSP */ - sampleRate, - framesperbuf, /* MSP */ - paNoFlag, /* MSP -- portaudio will clip for us */ - blockingIOCallback, - aStream ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( aStream->stream ); - if( err != paNoError ) /* MSP */ - { - fprintf(stderr, "Pa_StartStream failed; closing audio stream...\n"); - CloseAudioStream( aStream ); - goto error; - } - - *rwblPtr = aStream; - return paNoError; - -error: - *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/pd/portaudio/pablio/pablio_pd.h b/pd/portaudio/pablio/pablio_pd.h deleted file mode 100644 index 8f8a688a..00000000 --- a/pd/portaudio/pablio/pablio_pd.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef _PABLIO_H -#define _PABLIO_H - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/* - * $Id: pablio_pd.h,v 1.1.1.2 2003-05-09 16:03:59 ggeiger 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; - PaStream *stream; /* MSP -- was PortAudioStream; probably an error */ - 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, - */ -PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate, - PaSampleFormat format, long flags, int nchannels, - int framesperbuf, int nbuffers, - int indeviceno, int outdeviceno); /* MSP */ - -PaError CloseAudioStream( PABLIO_Stream *aStream ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _PABLIO_H */ diff --git a/pd/portaudio/pablio/ringbuffer.c b/pd/portaudio/pablio/ringbuffer.c deleted file mode 100644 index b8cc691f..00000000 --- a/pd/portaudio/pablio/ringbuffer.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * $Id: ringbuffer.c,v 1.1.1.1 2002-07-29 17:06:17 ggeiger 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/pd/portaudio/pablio/ringbuffer.h b/pd/portaudio/pablio/ringbuffer.h deleted file mode 100644 index 1bf78e3a..00000000 --- a/pd/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-07-29 17:06:17 ggeiger 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/pd/portaudio/pablio/ringbuffer_pd.c b/pd/portaudio/pablio/ringbuffer_pd.c deleted file mode 100644 index 16890d65..00000000 --- a/pd/portaudio/pablio/ringbuffer_pd.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * $Id: ringbuffer_pd.c,v 1.1.1.1 2002-07-29 17:06:17 ggeiger 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. - * - */ -/* - * modified 2002/07/13 by olaf.matthes@gmx.de to allow any number if channels - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include "ringbuffer.h" -#include <string.h> - -/*************************************************************************** - * Initialize FIFO. - */ -long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr ) -{ - rbuf->bufferSize = numBytes; - rbuf->buffer = (char *)dataPtr; - RingBuffer_Flush( rbuf ); - return 0; -} -/*************************************************************************** -** Return number of bytes available for reading. */ -long RingBuffer_GetReadAvailable( RingBuffer *rbuf ) -{ - long ret = (rbuf->writeIndex - rbuf->readIndex) + rbuf->bufferSize; - if (ret >= 2 * rbuf->bufferSize) - ret -= 2 * rbuf->bufferSize; - return ( ret ); -} -/*************************************************************************** -** 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; - while (index >= rbuf->bufferSize) - index -= rbuf->bufferSize; - 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 ) -{ - long ret = (rbuf->writeIndex + numBytes); - if ( ret > 2 * rbuf->bufferSize) - ret -= 2 * rbuf->bufferSize; /* check for end of buffer */ - return rbuf->writeIndex = ret; -} - -/*************************************************************************** -** 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; - while (index > rbuf->bufferSize) - index -= rbuf->bufferSize; - - 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 ) -{ - long ret = (rbuf->readIndex + numBytes); - if( ret > 2 * rbuf->bufferSize) - ret -= 2 * rbuf->bufferSize; - return rbuf->readIndex = ret; -} - -/*************************************************************************** -** 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/pd/portaudio/pablio/test_rw.c b/pd/portaudio/pablio/test_rw.c deleted file mode 100644 index cf54427d..00000000 --- a/pd/portaudio/pablio/test_rw.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * $Id: test_rw.c,v 1.1.1.1 2002-07-29 17:06:17 ggeiger 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/pd/portaudio/pablio/test_rw_echo.c b/pd/portaudio/pablio/test_rw_echo.c deleted file mode 100644 index 9b27e3c2..00000000 --- a/pd/portaudio/pablio/test_rw_echo.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * $Id: test_rw_echo.c,v 1.1.1.1 2002-07-29 17:06:17 ggeiger 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/pd/portaudio/pablio/test_w_saw.c b/pd/portaudio/pablio/test_w_saw.c deleted file mode 100644 index b8e3e71a..00000000 --- a/pd/portaudio/pablio/test_w_saw.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * $Id: test_w_saw.c,v 1.1.1.1 2002-07-29 17:06:17 ggeiger 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/pd/portaudio/pablio/test_w_saw8.c b/pd/portaudio/pablio/test_w_saw8.c deleted file mode 100644 index b876bd9f..00000000 --- a/pd/portaudio/pablio/test_w_saw8.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * $Id: test_w_saw8.c,v 1.1.1.1 2002-07-29 17:06:17 ggeiger 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/pd/portaudio/pablio/test_w_saw_pd.c b/pd/portaudio/pablio/test_w_saw_pd.c deleted file mode 100644 index be95d245..00000000 --- a/pd/portaudio/pablio/test_w_saw_pd.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * $Id: test_w_saw_pd.c,v 1.1.1.1 2002-07-29 17:06:17 ggeiger 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_pd.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, 2, 512, 8, -1, -1 ); - 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/pd/portaudio/portmidi-macosx/Makefile b/pd/portaudio/portmidi-macosx/Makefile deleted file mode 100644 index d8667355..00000000 --- a/pd/portaudio/portmidi-macosx/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -CC = cc -CFLAGS = -Wmost -LDFLAGS = -framework Carbon -framework CoreMIDI -OBJS = ptdarwin.o pmutil.o pmmacosx.o pmdarwin.o portmidi.o -LIBS = - -all: libportmidi.a pmtest - -libportmidi.a: portmidi.h porttime.h pminternal.h $(OBJS) - rm -f libportmidi.a - ar rv libportmidi.a $(OBJS) - ranlib libportmidi.a - -pmtest: pmtest.c libportmidi.a - $(CC) $(CFLAGS) pmtest.c $(OBJS) -o pmtest $(LDFLAGS) $(LIBS) - -pmmacosx.o: pmmacosx.c portmidi.h pminternal.h pmmacosx.h porttime.h -pmdarwin.o: pmdarwin.c portmidi.h pmmacosx.h -pmutil.o: pmutil.c portmidi.h pmutil.h pminternal.h -portmidi.o: portmidi.c portmidi.h pminternal.h -ptdarwin.o: ptdarwin.c porttime.h portmidi.h - -clean: - rm -f pmtest *.o diff --git a/pd/portaudio/portmidi-macosx/README b/pd/portaudio/portmidi-macosx/README deleted file mode 100644 index 89c0e6fa..00000000 --- a/pd/portaudio/portmidi-macosx/README +++ /dev/null @@ -1,12 +0,0 @@ -PortMidi for MacOS X / Darwin -Jon Parise <jparise@cmu.edu> -$Date: 2002-07-29 17:06:16 $ - -This is the MacOS X / Darwin port of the PortMidi library from the Carnegie -Mellon Computer Music Group. It is based on the Apple CoreAudio MIDI -interface. - -This port was finished in early 2002. At this point, I consider the code -base complete. - -- Jon diff --git a/pd/portaudio/portmidi-macosx/pmdarwin.c b/pd/portaudio/portmidi-macosx/pmdarwin.c deleted file mode 100644 index 510339c3..00000000 --- a/pd/portaudio/portmidi-macosx/pmdarwin.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * PortMidi OS-dependent interface for Darwin (MacOS X) - * Jon Parise <jparise@cmu.edu> - * - * $Id: pmdarwin.c,v 1.1.1.1 2002-07-29 17:06:16 ggeiger Exp $ - */ - -/* - * 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, say, pmwinmm.c, because it - * might need to register devices for winmm, directx, and others. - */ - -#include <stdlib.h> -#include "portmidi.h" -#include "pmmacosx.h" - -PmError pm_init() -{ - return pm_macosx_init(); -} - -PmError pm_term() -{ - return pm_macosx_term(); -} - -PmDeviceID Pm_GetDefaultInputDeviceID() { return 0; }; -PmDeviceID Pm_GetDefaultOutputDeviceID() { return 0; }; - -void *pm_alloc(size_t s) { return malloc(s); } - -void pm_free(void *ptr) { free(ptr); } - diff --git a/pd/portaudio/portmidi-macosx/pminternal.h b/pd/portaudio/portmidi-macosx/pminternal.h deleted file mode 100644 index 2a92e16d..00000000 --- a/pd/portaudio/portmidi-macosx/pminternal.h +++ /dev/null @@ -1,100 +0,0 @@ -/* pminternal.h -- header for interface implementations */ - -/* this file is included by files that implement library internals */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> - -/* these are defined in system-specific file */ -void *pm_alloc(size_t s); -void pm_free(void *ptr); - -struct pm_internal_struct; - -/* these do not use PmInternal because it is not defined yet... */ -typedef PmError (*pm_write_fn)(struct pm_internal_struct *midi, - PmEvent *buffer, long length); -typedef PmError (*pm_open_fn)(struct pm_internal_struct *midi, - void *driverInfo); -typedef PmError (*pm_abort_fn)(struct pm_internal_struct *midi); -typedef PmError (*pm_close_fn)(struct pm_internal_struct *midi); - -typedef struct { - pm_write_fn write; - pm_open_fn open; - pm_abort_fn abort; - pm_close_fn close; -} 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; - void *descriptor; /* system-specific data to open device */ - pm_fns_type dictionary; -} descriptor_node, *descriptor_type; - - -#define pm_descriptor_max 32 -extern descriptor_node descriptors[pm_descriptor_max]; -extern int descriptor_index; - - -typedef unsigned long (*time_get_proc_type)(void *time_info); - -typedef struct pm_internal_struct { - short write_flag; /* MIDI_IN, or MIDI_OUT */ - int device_id; /* which device is open (index to descriptors) */ - PmTimeProcPtr time_proc; /* where to get the time */ - void *time_info; /* pass this to get_time() */ - PmEvent *buffer; /* input or output buffer */ - long buffer_len; /* how big is the buffer */ - 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 */ - 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 */ - struct pm_internal_struct *thru; - PmTimestamp last_msg_time; /* timestamp of last message */ - long head; - long tail; - 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; - - -PmError pm_init(void); /* defined in a system-specific file */ -PmError pm_term(void); /* defined in a system-specific file */ -int pm_in_device(int n, char *interf, char *device); -int pm_out_device(int n, char *interf, char *device); -PmError none_write(PmInternal *midi, PmEvent *buffer, long length); -PmError pm_success_fn(PmInternal *midi); -PmError pm_fail_fn(PmInternal *midi); -long pm_in_poll(PmInternal *midi); -long pm_out_poll(PmInternal *midi); - -PmError pm_add_device(char *interf, char *name, int input, void *descriptor, - pm_fns_type dictionary); - -void pm_enqueue(PmInternal *midi, PmEvent *event); - - -#ifdef __cplusplus -} -#endif - diff --git a/pd/portaudio/portmidi-macosx/pmmacosx.c b/pd/portaudio/portmidi-macosx/pmmacosx.c deleted file mode 100644 index 0aafcf7f..00000000 --- a/pd/portaudio/portmidi-macosx/pmmacosx.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Platform interface to the MacOS X CoreMIDI framework - * - * Jon Parise <jparise@cmu.edu> - * - * $Id: pmmacosx.c,v 1.1.1.1 2002-07-29 17:06:16 ggeiger Exp $ - */ - -#include "portmidi.h" -#include "pminternal.h" -#include "porttime.h" -#include "pmmacosx.h" - -#include <stdio.h> -#include <string.h> - -#include <CoreServices/CoreServices.h> -#include <CoreMIDI/MIDIServices.h> - -#define PACKET_BUFFER_SIZE 1024 - -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; - -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 -get_timestamp(PmInternal *midi) -{ - PmTimeProcPtr time_proc; - - /* Set the time procedure accordingly */ - time_proc = midi->time_proc; - if (time_proc == NULL) { - time_proc = Pt_Time; - } - - return (*time_proc)(midi->time_info); -} - -/* called when MIDI packets are received */ -static void -readProc(const MIDIPacketList *newPackets, void *refCon, void *connRefCon) -{ - PmInternal *midi; - PmEvent event; - MIDIPacket *packet; - unsigned int packetIndex; - - /* Retrieve the context for this connection */ - midi = (PmInternal *) connRefCon; - - packet = (MIDIPacket *) &newPackets->packet[0]; - for (packetIndex = 0; packetIndex < newPackets->numPackets; packetIndex++) { - - /* 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 */ - continue; - } - - /* Set the timestamp and dispatch this message */ - event.timestamp = get_timestamp(midi); - pm_enqueue(midi, &event); - - /* Advance to the next packet in the packet list */ - packet = MIDIPacketNext(packet); - } -} - -static PmError -midi_in_open(PmInternal *midi, void *driverInfo) -{ - MIDIEndpointRef endpoint; - - endpoint = (MIDIEndpointRef) descriptors[midi->device_id].descriptor; - if (endpoint == NULL) { - return pmInvalidDeviceId; - } - - if (MIDIPortConnectSource(portIn, endpoint, midi) != noErr) { - return pmHostError; - } - - return pmNoError; -} - -static PmError -midi_in_close(PmInternal *midi) -{ - MIDIEndpointRef endpoint; - - endpoint = (MIDIEndpointRef) descriptors[midi->device_id].descriptor; - if (endpoint == NULL) { - return pmInvalidDeviceId; - } - - if (MIDIPortDisconnectSource(portIn, endpoint) != noErr) { - return pmHostError; - } - - return pmNoError; -} - -static PmError -midi_out_open(PmInternal *midi, void *driverInfo) -{ - /* - * MIDISent() only requires an output port (portOut) and a valid MIDI - * endpoint (which we've already created and stored in the PmInternal - * structure). Therefore, no additional work needs to be done here to - * open the device for output. - */ - - return pmNoError; -} - -static PmError -midi_out_close(PmInternal *midi) -{ - return pmNoError; -} - -static PmError -midi_abort(PmInternal *midi) -{ - return pmNoError; -} - -static PmError -midi_write(PmInternal *midi, PmEvent *events, long length) -{ - Byte packetBuffer[PACKET_BUFFER_SIZE]; - MIDIEndpointRef endpoint; - MIDIPacketList *packetList; - MIDIPacket *packet; - MIDITimeStamp timestamp; - PmTimeProcPtr time_proc; - PmEvent event; - unsigned int pm_time; - unsigned int eventIndex; - unsigned int messageLength; - Byte message[3]; - - endpoint = (MIDIEndpointRef) descriptors[midi->device_id].descriptor; - if (endpoint == NULL) { - return pmInvalidDeviceId; - } - - /* Make sure the packetBuffer is large enough */ - if (length > PACKET_BUFFER_SIZE) { - return pmHostError; - } - - /* - * Initialize the packet list. Each packet contains bytes that are to - * be played at the same time. - */ - packetList = (MIDIPacketList *) packetBuffer; - if ((packet = MIDIPacketListInit(packetList)) == NULL) { - return pmHostError; - } - - /* Set the time procedure accordingly */ - time_proc = midi->time_proc; - if (time_proc == NULL) { - time_proc = Pt_Time; - } - - /* Extract the event data and pack it into the message buffer */ - for (eventIndex = 0; eventIndex < length; eventIndex++) { - event = events[eventIndex]; - - /* Compute the timestamp */ - pm_time = (*time_proc)(midi->time_info); - timestamp = pm_time + midi->latency; - - messageLength = midi_length(event.message); - message[0] = Pm_MessageStatus(event.message); - message[1] = Pm_MessageData1(event.message); - message[2] = Pm_MessageData2(event.message); - - /* Add this message to the packet list */ - packet = MIDIPacketListAdd(packetList, sizeof(packetBuffer), packet, - timestamp, messageLength, message); - if (packet == NULL) { - return pmHostError; - } - } - - if (MIDISend(portOut, endpoint, packetList) != noErr) { - return pmHostError; - } - - return pmNoError; -} - -pm_fns_node pm_macosx_in_dictionary = { - none_write, - midi_in_open, - midi_abort, - midi_in_close -}; - -pm_fns_node pm_macosx_out_dictionary = { - midi_write, - midi_out_open, - midi_abort, - midi_out_close -}; - -PmError -pm_macosx_init(void) -{ - OSStatus status; - ItemCount numDevices, numInputs, numOutputs; - MIDIEndpointRef endpoint; - CFStringEncoding defaultEncoding; - CFStringRef deviceName; - char nameBuf[256]; - int i; - - /* Determine the number of MIDI devices on the system */ - numDevices = MIDIGetNumberOfDevices(); - numInputs = MIDIGetNumberOfSources(); - numOutputs = MIDIGetNumberOfDestinations(); - - /* Return prematurely if no devices exist on the system */ - if (numDevices <= 0) { - return pmHostError; - } - - /* Determine the default system character encording */ - defaultEncoding = CFStringGetSystemEncoding(); - - /* Iterate over the MIDI input devices */ - for (i = 0; i < numInputs; i++) { - endpoint = MIDIGetSource(i); - if (endpoint == NULL) { - continue; - } - - /* Get the name of this device */ - MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &deviceName); - CFStringGetCString(deviceName, nameBuf, 256, defaultEncoding); - CFRelease(deviceName); - - /* Register this device with PortMidi */ - pm_add_device("CoreMIDI", nameBuf, 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; - } - - /* Get the name of this device */ - MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &deviceName); - CFStringGetCString(deviceName, nameBuf, 256, defaultEncoding); - CFRelease(deviceName); - - /* Register this device with PortMidi */ - pm_add_device("CoreMIDI", nameBuf, FALSE, (void *)endpoint, - &pm_macosx_out_dictionary); - } - - /* Initialize the client handle */ - status = MIDIClientCreate(CFSTR("PortMidi"), NULL, NULL, &client); - if (status != noErr) { - fprintf(stderr, "Could not initialize client: %d\n", (int)status); - return pmHostError; - } - - /* Create the input port */ - status = MIDIInputPortCreate(client, CFSTR("Input port"), readProc, NULL, - &portIn); - if (status != noErr) { - fprintf(stderr, "Could not create input port: %d\n", (int)status); - return pmHostError; - } - - /* Create the output port */ - status = MIDIOutputPortCreate(client, CFSTR("Output port"), &portOut); - if (status != noErr) { - fprintf(stderr, "Could not create output port: %d\n", (int)status); - return pmHostError; - } - - return pmNoError; -} - -PmError -pm_macosx_term(void) -{ - if (client != NULL) MIDIClientDispose(client); - if (portIn != NULL) MIDIPortDispose(portIn); - if (portOut != NULL) MIDIPortDispose(portOut); - - return pmNoError; -} diff --git a/pd/portaudio/portmidi-macosx/pmmacosx.h b/pd/portaudio/portmidi-macosx/pmmacosx.h deleted file mode 100644 index 15e9551d..00000000 --- a/pd/portaudio/portmidi-macosx/pmmacosx.h +++ /dev/null @@ -1,4 +0,0 @@ -/* system-specific definitions */ - -PmError pm_macosx_init(void); -PmError pm_macosx_term(void); diff --git a/pd/portaudio/portmidi-macosx/pmtest b/pd/portaudio/portmidi-macosx/pmtest Binary files differdeleted file mode 100644 index 8adc5334..00000000 --- a/pd/portaudio/portmidi-macosx/pmtest +++ /dev/null diff --git a/pd/portaudio/portmidi-macosx/pmtest.c b/pd/portaudio/portmidi-macosx/pmtest.c deleted file mode 100644 index 5628d25e..00000000 --- a/pd/portaudio/portmidi-macosx/pmtest.c +++ /dev/null @@ -1,136 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include "portmidi.h" -#include "porttime.h" -#include "pminternal.h" - -#define LATENCY 0 -#define NUM_ECHOES 10 - -int -main() -{ - int i = 0; - int n = 0; - PmStream *midi_in; - PmStream *midi_out; - PmError err; - char line[80]; - PmEvent buffer[NUM_ECHOES]; - int transpose; - int delay; - int status, data1, data2; - int statusprefix; - - - - /* always start the timer before you start midi */ - Pt_Start(1, 0, 0); /* start a timer with millisecond accuracy */ - - - 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"); - } - - /* OPEN INPUT DEVICE */ - - printf("Type input number: "); - while (n != 1) { - n = scanf("%d", &i); - gets(line); - } - - err = Pm_OpenInput(&midi_in, i, NULL, 100, NULL, NULL, NULL); - if (err) { - printf("could not open midi device: %s\n", Pm_GetErrorText(err)); - exit(1); - } - printf("Midi Input opened.\n"); - - /* OPEN OUTPUT DEVICE */ - - printf("Type output number: "); - n = 0; - while (n != 1) { - n = scanf("%d", &i); - gets(line); - } - - err = Pm_OpenOutput(&midi_out, i, NULL, 0, NULL, NULL, LATENCY); - if (err) { - printf("could not open midi device: %s\n", Pm_GetErrorText(err)); - exit(1); - } - printf("Midi Output opened with %d ms latency.\n", LATENCY); - - - - /* Get input from user for parameters */ - printf("Type number of milliseconds for echoes: "); - n = 0; - while (n != 1) { - n = scanf("%d", &delay); - gets(line); - } - - printf("Type number of semitones to transpose up: "); - n = 0; - while (n != 1) { - n = scanf("%d", &transpose); - gets(line); - } - - - - /* loop, echoing input back transposed with multiple taps */ - - printf("Press C2 on the keyboard (2 octaves below middle C) to quit.\nWaiting for MIDI input...\n"); - - do { - err = Pm_Read(midi_in, buffer, 1); - if (err == 0) continue; /* no bytes read. */ - - /* print a hash mark for each event read. */ - printf("#"); - fflush(stdout); - - status = Pm_MessageStatus(buffer[0].message); - data1 = Pm_MessageData1(buffer[0].message); - data2 = Pm_MessageData2(buffer[0].message); - statusprefix = status >> 4; - - /* ignore messages other than key-down and key-up */ - if ((statusprefix != 0x9) && (statusprefix != 0x8)) continue; - - printf("\nReceived key message = %X %X %X, at time %ld\n", status, data1, data2, buffer[0].timestamp); - fflush(stdout); - - /* immediately send the echoes to PortMIDI */ - for (i = 1; i < NUM_ECHOES; i++) { - buffer[i].message = Pm_Message(status, data1 + transpose, data2 >> i); - buffer[i].timestamp = buffer[0].timestamp + (i * delay); - } - Pm_Write(midi_out, buffer, NUM_ECHOES); - } while (data1 != 36); /* quit when C2 is pressed */ - - printf("Key C2 pressed. Exiting...\n"); - fflush(stdout); - - /* Give the echoes time to finish before quitting. */ - sleep(((NUM_ECHOES * delay) / 1000) + 1); - - Pm_Close(midi_in); - Pm_Close(midi_out); - - printf("Done.\n"); - return 0; -} - - - diff --git a/pd/portaudio/portmidi-macosx/pmutil.c b/pd/portaudio/portmidi-macosx/pmutil.c deleted file mode 100644 index f3582a42..00000000 --- a/pd/portaudio/portmidi-macosx/pmutil.c +++ /dev/null @@ -1,86 +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 *) malloc(sizeof(PmQueueRep)); - if (!queue) return NULL; - queue->len = num_msgs * bytes_per_msg; - queue->buffer = malloc(queue->len); - if (!queue->buffer) { - 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; - if (!queue || !queue->buffer) return pmBadPtr; - free(queue->buffer); - free(queue); - return pmNoError; -} - - -PmError Pm_Dequeue(PmQueue *q, void *msg) -{ - long head; - PmQueueRep *queue = (PmQueueRep *) q; - 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 = 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_QueueFull(PmQueue *q) -{ - PmQueueRep *queue = (PmQueueRep *) q; - long tail = queue->tail; - tail += queue->msg_size; - if (tail == queue->len) { - tail = 0; - } - return (tail == queue->head); -} - diff --git a/pd/portaudio/portmidi-macosx/pmutil.h b/pd/portaudio/portmidi-macosx/pmutil.h deleted file mode 100644 index b6268ed3..00000000 --- a/pd/portaudio/portmidi-macosx/pmutil.h +++ /dev/null @@ -1,44 +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 and clears the overflow flag if - the flag is set. - */ -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); -#define Pm_QueueEmpty(m) (m->head == m->tail) diff --git a/pd/portaudio/portmidi-macosx/portmidi.c b/pd/portaudio/portmidi-macosx/portmidi.c deleted file mode 100644 index c2a32ae7..00000000 --- a/pd/portaudio/portmidi-macosx/portmidi.c +++ /dev/null @@ -1,358 +0,0 @@ -#include "stdlib.h" -#include "portmidi.h" -#include "pminternal.h" - -#define is_empty(midi) ((midi)->tail == (midi)->head) - -static int pm_initialized = FALSE; - -int descriptor_index = 0; -descriptor_node descriptors[pm_descriptor_max]; - - -/* 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 (descriptor_index >= pm_descriptor_max) { - return pmInvalidDeviceId; - } - descriptors[descriptor_index].pub.interf = interf; - descriptors[descriptor_index].pub.name = name; - descriptors[descriptor_index].pub.input = input; - descriptors[descriptor_index].pub.output = !input; - descriptors[descriptor_index].descriptor = descriptor; - descriptors[descriptor_index].dictionary = dictionary; - descriptor_index++; - return pmNoError; -} - - -PmError Pm_Initialize( void ) -{ - if (!pm_initialized) { - PmError err = pm_init(); /* defined by implementation specific file */ - if (err) return err; - pm_initialized = TRUE; - } - return pmNoError; -} - - -PmError Pm_Terminate( void ) -{ - PmError err = pmNoError; - if (pm_initialized) { - err = pm_term(); /* defined by implementation specific file */ - /* note that even when pm_term() fails, we mark portmidi as - not initialized */ - pm_initialized = FALSE; - } - return err; -} - - -int Pm_CountDevices( void ) -{ - PmError err = Pm_Initialize(); - if (err) return err; - - return descriptor_index; -} - - -const PmDeviceInfo* Pm_GetDeviceInfo( PmDeviceID id ) -{ - PmError err = Pm_Initialize(); - if (err) return NULL; - - if (id >= 0 && id < descriptor_index) { - return &descriptors[id].pub; - } - return NULL; -} - - -/* failure_fn -- "noop" function pointer */ -/**/ -PmError failure_fn(PmInternal *midi) -{ - return pmBadPtr; -} - - -/* pm_success_fn -- "noop" function pointer */ -/**/ -PmError pm_success_fn(PmInternal *midi) -{ - return pmNoError; -} - - -PmError none_write(PmInternal *midi, PmEvent *buffer, long length) -{ - return length; /* if we return 0, caller might get into a loop */ -} - -PmError pm_fail_fn(PmInternal *midi) -{ - return pmBadPtr; -} - -static PmError none_open(PmInternal *midi, void *driverInfo) -{ - return pmBadPtr; -} - -#define none_abort pm_fail_fn - -#define none_close pm_fail_fn - - -pm_fns_node pm_none_dictionary = { - none_write, none_open, - none_abort, none_close }; - - -/* 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 = midi->head; - while (head != midi->tail && n < length) { - *buffer++ = midi->buffer[head++]; - if (head == midi->buffer_len) head = 0; - n++; - } - midi->head = head; - if (midi->overflow) { - midi->head = midi->tail; - midi->overflow = FALSE; - return pmBufferOverflow; - } - return n; -} - - -PmError Pm_Poll( PortMidiStream *stream ) -{ - PmInternal *midi = (PmInternal *) stream; - return midi->head != midi->tail; -} - - -PmError Pm_Write( PortMidiStream *stream, PmEvent *buffer, long length) -{ - PmInternal *midi = (PmInternal *) stream; - return (*midi->dictionary->write)(midi, buffer, length); -} - - -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_OpenInput( PortMidiStream** stream, - PmDeviceID inputDevice, - void *inputDriverInfo, - long bufferSize, - PmTimeProcPtr time_proc, - void *time_info, - PmStream *thru) -{ - PmInternal *midi; - - PmError err = Pm_Initialize(); - if (err) return err; - - if (inputDevice < 0 || inputDevice >= descriptor_index) { - return pmInvalidDeviceId; - } - - if (!descriptors[inputDevice].pub.input) { - return pmInvalidDeviceId; - } - - midi = (PmInternal *) malloc(sizeof(PmInternal)); - *stream = midi; - if (!midi) return pmInsufficientMemory; - - midi->head = 0; - midi->tail = 0; - midi->dictionary = &pm_none_dictionary; - midi->overflow = FALSE; - midi->flush = FALSE; - midi->sysex_in_progress = FALSE; - midi->buffer_len = bufferSize; - midi->buffer = (PmEvent *) pm_alloc(sizeof(PmEvent) * midi->buffer_len); - if (!midi->buffer) return pmInsufficientMemory; - midi->latency = 0; - midi->thru = thru; - midi->time_proc = time_proc; - midi->time_info = time_info; - midi->device_id = inputDevice; - midi->dictionary = descriptors[inputDevice].dictionary; - midi->write_flag = FALSE; - err = (*midi->dictionary->open)(midi, inputDriverInfo); - if (err) { - pm_free(midi->buffer); - *stream = NULL; - } - return err; -} - - -PmError Pm_OpenOutput( PortMidiStream** stream, - PmDeviceID outputDevice, - void *outputDriverInfo, - long bufferSize, - PmTimeProcPtr time_proc, - void *time_info, - long latency ) -{ - PmInternal *midi; - - PmError err = Pm_Initialize(); - if (err) return err; - - if (outputDevice < 0 || outputDevice >= descriptor_index) { - return pmInvalidDeviceId; - } - - if (!descriptors[outputDevice].pub.output) { - return pmInvalidDeviceId; - } - - midi = (PmInternal *) pm_alloc(sizeof(PmInternal)); - *stream = midi; - if (!midi) return pmInsufficientMemory; - - midi->head = 0; - midi->tail = 0; - midi->buffer_len = bufferSize; - midi->buffer = NULL; - midi->device_id = outputDevice; - midi->dictionary = descriptors[outputDevice].dictionary; - midi->time_proc = time_proc; - midi->time_info = time_info; - midi->latency = latency; - midi->write_flag = TRUE; - err = (*midi->dictionary->open)(midi, outputDriverInfo); - if (err) { - *stream = NULL; - pm_free(midi); // Fixed by Ning Hu, Sep.2001 - } - return err; -} - - -PmError Pm_Abort( PortMidiStream* stream ) -{ - PmInternal *midi = (PmInternal *) stream; - return (*midi->dictionary->abort)(midi); -} - - -PmError Pm_Close( PortMidiStream *stream ) -{ - PmInternal *midi = (PmInternal *) stream; - return (*midi->dictionary->close)(midi); -} - - -const char *Pm_GetErrorText( PmError errnum ) -{ - const char *msg; - - switch(errnum) - { - case pmNoError: msg = "Success"; break; - case pmHostError: msg = "Host error."; break; - case pmInvalidDeviceId: msg = "Invalid device ID."; break; - case pmInsufficientMemory: msg = "Insufficient memory."; break; - case pmBufferTooSmall: msg = "Buffer too small."; break; - case pmBadPtr: msg = "Bad pointer."; break; - case pmInternalError: msg = "Internal PortMidi Error."; break; - default: msg = "Illegal error number."; break; - } - return msg; -} - - -long pm_next_time(PmInternal *midi) -{ - return midi->buffer[midi->head].timestamp; -} - - -/* source should not enqueue data if overflow is set */ -/* - When producer has data to enqueue: - if buffer is full: - set overflow_flag and flush_flag - return - else if overflow_flag: - return - else if flush_flag: - if sysex message is in progress: - return - else: - clear flush_flag - // fall through to enqueue data - enqueue the data - - */ -void pm_enqueue(PmInternal *midi, PmEvent *event) -{ - long tail = midi->tail; - midi->buffer[tail++] = *event; - if (tail == midi->buffer_len) tail = 0; - if (tail == midi->head || midi->overflow) { - midi->overflow = TRUE; - midi->flush = TRUE; - return; - } - if (midi->flush) { - if (midi->sysex_in_progress) return; - else midi->flush = FALSE; - } - midi->tail = tail; -} - - -int pm_queue_full(PmInternal *midi) -{ - long tail = midi->tail + 1; - if (tail == midi->buffer_len) tail = 0; - return tail == midi->head; -} - - - diff --git a/pd/portaudio/portmidi-macosx/portmidi.h b/pd/portaudio/portmidi-macosx/portmidi.h deleted file mode 100644 index 3e648c90..00000000 --- a/pd/portaudio/portmidi-macosx/portmidi.h +++ /dev/null @@ -1,338 +0,0 @@ -#ifndef PORT_MIDI_H -#define PORT_MIDI_H -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * PortMidi Portable Real-Time Audio 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 -- THIS VERSION IS 1.0 - * - * 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(). - */ - -#ifndef FALSE - #define FALSE 0 -#endif -#ifndef TRUE - #define TRUE 1 -#endif - - -typedef enum { - pmNoError = 0, - - pmHostError = -10000, - pmInvalidDeviceId, /* out of range or - output device when input is requested or - input device when output is requested */ - //pmInvalidFlag, - pmInsufficientMemory, - pmBufferTooSmall, - pmBufferOverflow, - pmBadPtr, - pmInternalError -} 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 ); - -/* - Return host specific error number. All host-specific errors are translated - to the single error class pmHostError. To find out the original error - number, call Pm_GetHostError(). - This can be called after a function returns a PmError equal to pmHostError. -*/ -int Pm_GetHostError(); - -/* - Translate the error number into a human readable message. -*/ -const char *Pm_GetErrorText( PmError errnum ); - - -/* - Device enumeration mechanism. - - Device ids range from 0 to Pm_CountDevices()-1. - - Devices may support input, output or both. Device 0 is always the "default" - device. Other platform specific devices are specified by positive device - ids. -*/ - -typedef int PmDeviceID; -#define pmNoDevice -1 - -typedef struct { - int structVersion; - const char *interf; - const char *name; - int input; /* true iff input is available */ - int output; /* true iff output is available */ -} PmDeviceInfo; - - -int Pm_CountDevices( void ); -/* - Pm_GetDefaultInputDeviceID(), Pm_GetDefaultOutputDeviceID() - - Return the default device ID or pmNoDevice if there is 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 "pm_devs". -*/ -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; - -/* 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 ); - - -/* - A single PortMidiStream is a descriptor for an open MIDI device. -*/ - -typedef void PortMidiStream; -#define PmStream PortMidiStream - -typedef PmTimestamp (*PmTimeProcPtr)(void *time_info); - - -/* - Pm_Open() opens a device; for either input or output. - - Port 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. - - latency is the delay in milliseconds applied to timestamps to determine - when the output should actually occur. - - time_proc is a pointer to a procedure that returns time in milliseconds. It - may be NULL, in which case a default millisecond timebase is used. - - time_info is a pointer passed to time_proc. - - thru points to a PmMidi descriptor opened for output; Midi input will be - copied to this output. To disable Midi thru, use NULL. - - 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. - -*/ - -PmError Pm_OpenInput( PortMidiStream** stream, - PmDeviceID inputDevice, - void *inputDriverInfo, - long bufferSize, - PmTimeProcPtr time_proc, - void *time_info, - PmStream* thru ); - - -PmError Pm_OpenOutput( PortMidiStream** stream, - PmDeviceID outputDevice, - void *outputDriverInfo, - long bufferSize, - PmTimeProcPtr time_proc, - void *time_info, - long latency ); - - -/* - Pm_Abort() terminates outgoing messages immediately - */ -PmError Pm_Abort( PortMidiStream* stream ); - -/* - Pm_Close() closes a midi stream, flushing any pending buffers. -*/ - -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. The port parameter is the - index of the Midi port if the device supports more than one. - - Pm_MessagePort(), 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. - - When receiving sysex messages, the sysex message is terminated - by either an EOX status byte (anywhere in the 4 byte message) or - by a non-real-time status byte in the low order byte of message. - If you get a non-real-time status byte, it means the sysex message - was somehow truncated. It is permissible to interleave real-time - messages within sysex messages. - */ - -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. Use Pm_WriteSysEx() to write a sysex message stored as a - contiguous array of bytes. -*/ - -PmError Pm_Write( PortMidiStream *stream, PmEvent *buffer, long length ); - -/* - Pm_WriteShort() writes a timestamped non-system-exclusive midi message. -*/ - -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, char *msg); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PORT_MIDI_H */ diff --git a/pd/portaudio/portmidi-macosx/porttime.h b/pd/portaudio/portmidi-macosx/porttime.h deleted file mode 100644 index 8592106d..00000000 --- a/pd/portaudio/portmidi-macosx/porttime.h +++ /dev/null @@ -1,30 +0,0 @@ -/* porttime.h -- portable interface to millisecond timer */ - -/* 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 -} PtError; - - -typedef long PtTimestamp; - -typedef int (PtCallback)( PtTimestamp timestamp, void *userData ); - - -PtError Pt_Start(int resolution, PtCallback *callback, void *userData); -PtError Pt_Stop(); -int Pt_Started(); -PtTimestamp Pt_Time(); - -#ifdef __cplusplus -} -#endif diff --git a/pd/portaudio/portmidi-macosx/ptdarwin.c b/pd/portaudio/portmidi-macosx/ptdarwin.c deleted file mode 100644 index 51cf5fde..00000000 --- a/pd/portaudio/portmidi-macosx/ptdarwin.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Portable timer implementation for Darwin / MacOS X - * - * Jon Parise <jparise@cmu.edu> - * - * $Id: ptdarwin.c,v 1.1.1.1 2002-07-29 17:06:16 ggeiger Exp $ - */ - -#include <stdio.h> -#include <sys/time.h> -#include "porttime.h" - -#define TRUE 1 -#define FALSE 0 - -static int time_started_flag = FALSE; -static struct timeval time_offset; - -PtError Pt_Start(int resolution, PtCallback *callback, void *userData) -{ - struct timezone tz; - - if (callback) printf("error in porttime: callbacks not implemented\n"); - time_started_flag = TRUE; - gettimeofday(&time_offset, &tz); - - return ptNoError; -} - - -PtError Pt_Stop() -{ - time_started_flag = FALSE; - return ptNoError; -} - - -int Pt_Started() -{ - return time_started_flag; -} - - -PtTimestamp Pt_Time() -{ - long seconds, milliseconds; - struct timeval now; - struct timezone tz; - - gettimeofday(&now, &tz); - seconds = now.tv_sec - time_offset.tv_sec; - milliseconds = (now.tv_usec - time_offset.tv_usec) / 1000; - - return (seconds * 1000 + milliseconds); -} - - - diff --git a/pd/portaudio/testcvs/changeme.txt b/pd/portaudio/testcvs/changeme.txt deleted file mode 100644 index 2866c3b7..00000000 --- a/pd/portaudio/testcvs/changeme.txt +++ /dev/null @@ -1,8 +0,0 @@ -This is just a dopy little file used to test the CVS repository. -Feel free to trash this file. -Minor change. -Another tweak. -philburk tweak -stephane test -Phil changed this again on 2/21/02. Yawn... - |