Init
This commit is contained in:
10
DependentExtensions/portaudio_v18_1/CMakeLists.txt
Normal file
10
DependentExtensions/portaudio_v18_1/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
#
|
||||
# This file was taken from RakNet 4.082 without any modifications.
|
||||
# Please see licenses/RakNet license.txt for the underlying license and related copyright.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
project(portaudio)
|
||||
|
||||
|
||||
|
||||
65
DependentExtensions/portaudio_v18_1/LICENSE.txt
Normal file
65
DependentExtensions/portaudio_v18_1/LICENSE.txt
Normal file
@ -0,0 +1,65 @@
|
||||
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.
|
||||
*
|
||||
*/
|
||||
96
DependentExtensions/portaudio_v18_1/Makefile.in
Normal file
96
DependentExtensions/portaudio_v18_1/Makefile.in
Normal file
@ -0,0 +1,96 @@
|
||||
#
|
||||
# PortAudio Makefile.in
|
||||
#
|
||||
# Dominic Mazzoni
|
||||
#
|
||||
|
||||
PREFIX = @prefix@
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@ -Ipa_common
|
||||
LIBS = @LIBS@
|
||||
AR = @AR@
|
||||
RANLIB = @RANLIB@
|
||||
INSTALL = @INSTALL@
|
||||
SHARED_FLAGS = @SHARED_FLAGS@
|
||||
DLL_LIBS = @DLL_LIBS@
|
||||
|
||||
OTHER_OBJS = @OTHER_OBJS@
|
||||
|
||||
PALIB = libportaudio.a
|
||||
PADLL = @PADLL@
|
||||
PADLLV = $(PADLL).0.0.18
|
||||
PAINC = pa_common/portaudio.h
|
||||
|
||||
COMMON_OBJS = \
|
||||
pa_common/pa_convert.o \
|
||||
pa_common/pa_lib.o
|
||||
|
||||
TESTS = \
|
||||
bin/patest_buffer \
|
||||
bin/patest_clip \
|
||||
bin/patest_dither \
|
||||
bin/patest_hang \
|
||||
bin/patest_latency \
|
||||
bin/patest_leftright \
|
||||
bin/patest_longsine \
|
||||
bin/patest_many \
|
||||
bin/patest_maxsines \
|
||||
bin/patest_multi_sine \
|
||||
bin/patest_pink \
|
||||
bin/patest_record \
|
||||
bin/patest_ringmix \
|
||||
bin/patest_saw \
|
||||
bin/patest_sine8 \
|
||||
bin/patest_sine \
|
||||
bin/patest_sine_formats \
|
||||
bin/patest_sine_time \
|
||||
bin/patest_stop \
|
||||
bin/patest_sync \
|
||||
bin/patest_toomanysines \
|
||||
bin/patest_underflow \
|
||||
bin/patest_wire
|
||||
|
||||
OBJS = $(COMMON_OBJS) $(OTHER_OBJS)
|
||||
|
||||
all: lib/$(PALIB) lib/$(PADLLV) tests
|
||||
|
||||
tests: bin/ $(TESTS)
|
||||
|
||||
lib/$(PALIB): lib/ $(OBJS) Makefile $(PAINC)
|
||||
$(AR) ruv lib/$(PALIB) $(OBJS)
|
||||
$(RANLIB) lib/$(PALIB)
|
||||
|
||||
lib/$(PADLLV): lib/ $(OBJS) Makefile $(PAINC)
|
||||
$(CC) $(SHARED_FLAGS) -o lib/$(PADLLV) $(OBJS) $(DLL_LIBS)
|
||||
|
||||
$(TESTS): bin/%: lib/$(PALIB) Makefile $(PAINC) pa_tests/%.c
|
||||
$(CC) -o $@ $(CFLAGS) pa_tests/$*.c lib/$(PALIB) $(LIBS)
|
||||
|
||||
install: lib/$(PALIB) lib/$(PADLLV)
|
||||
$(INSTALL) -m 644 lib/$(PADLLV) $(PREFIX)/lib/$(PADLLV)
|
||||
$(INSTALL) -m 644 lib/$(PALIB) $(PREFIX)/lib/$(PALIB)
|
||||
cd $(PREFIX)/lib && rm -f $(PADLL) && ln -s $(PADLLV) $(PADLL)
|
||||
$(INSTALL) -m 644 pa_common/portaudio.h $(PREFIX)/include/portaudio.h
|
||||
@echo ""
|
||||
@echo "------------------------------------------------------------"
|
||||
@echo "PortAudio was successfully installed."
|
||||
@echo ""
|
||||
@echo "On some systems (e.g. Linux) you should run 'ldconfig' now"
|
||||
@echo "to make the shared object available. You may also need to"
|
||||
@echo "modify your LD_LIBRARY_PATH environment variable to include"
|
||||
@echo "the directory $(PREFIX)/lib"
|
||||
@echo "------------------------------------------------------------"
|
||||
@echo ""
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(TESTS) lib/$(PALIB)
|
||||
rm -f config.log config.status
|
||||
|
||||
%.o: %.c Makefile $(PAINC)
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
bin:
|
||||
mkdir bin
|
||||
|
||||
lib:
|
||||
mkdir lib
|
||||
59
DependentExtensions/portaudio_v18_1/Makefile.linux
Normal file
59
DependentExtensions/portaudio_v18_1/Makefile.linux
Normal file
@ -0,0 +1,59 @@
|
||||
# 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 ./pa_unix_oss/pa_unix.c
|
||||
|
||||
#all: sharedlib libinstall tests
|
||||
all: sharedlib libinstall testo testq
|
||||
|
||||
.c.o:
|
||||
-gcc $(CFLAGS) -c -I./pa_common $< -o $*.o
|
||||
|
||||
.o:
|
||||
-gcc $*.o -o $* -Lpa_unix_oss -lportaudio $(LIBS)
|
||||
|
||||
#.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 ./pa_unix_oss/pa_unix.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
|
||||
|
||||
|
||||
57
DependentExtensions/portaudio_v18_1/Makefile.mingw
Normal file
57
DependentExtensions/portaudio_v18_1/Makefile.mingw
Normal file
@ -0,0 +1,57 @@
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
59
DependentExtensions/portaudio_v18_1/Makefile.solaris
Normal file
59
DependentExtensions/portaudio_v18_1/Makefile.solaris
Normal file
@ -0,0 +1,59 @@
|
||||
# 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 -lrt
|
||||
|
||||
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_solaris.c ./pa_unix_oss/pa_unix.c
|
||||
|
||||
#all: sharedlib libinstall tests
|
||||
all: sharedlib libinstall testo testq
|
||||
|
||||
.c.o:
|
||||
-gcc $(CFLAGS) -c -I./pa_common $< -o $*.o
|
||||
|
||||
.o:
|
||||
-gcc $*.o -o $* -Lpa_unix_oss -lportaudio $(LIBS)
|
||||
|
||||
#.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_solaris.o ./pa_unix_oss/pa_unix.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
|
||||
|
||||
|
||||
81
DependentExtensions/portaudio_v18_1/README.txt
Normal file
81
DependentExtensions/portaudio_v18_1/README.txt
Normal file
@ -0,0 +1,81 @@
|
||||
README for PortAudio
|
||||
Implementations for PC DirectSound and Mac SoundManager
|
||||
|
||||
/*
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* Latest Version at: http://www.portaudio.com//
|
||||
*
|
||||
* Copyright (c) 1999-2000 Phil Burk and Ross Bencina
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
PortAudio is a portable audio I/O library designed for cross-platform
|
||||
support of audio. It uses a callback mechanism to request audio processing.
|
||||
Audio can be generated in various formats, including 32 bit floating point,
|
||||
and will be converted to the native format internally.
|
||||
|
||||
Documentation:
|
||||
See "pa_common/portaudio.h" for API spec.
|
||||
See docs folder for a tutorial.
|
||||
Also see http://www.portaudio.com/docs/
|
||||
And see "pa_tests/patest_saw.c" for an example.
|
||||
|
||||
For information on compiling programs with PortAudio, please see the
|
||||
tutorial at:
|
||||
|
||||
http://www.portaudio.com/docs/pa_tutorial.html
|
||||
|
||||
Important Files and Folders:
|
||||
pa_common/ = platform independant code
|
||||
pa_common/portaudio.h = header file for PortAudio API. Specifies API.
|
||||
pa_common/pa_lib.c = host independant code for all implementations.
|
||||
|
||||
pablio = simple blocking read/write interface
|
||||
|
||||
Platform Implementations
|
||||
pa_asio = ASIO for Windows and Macintosh
|
||||
pa_beos = BeOS
|
||||
pa_mac = Macintosh Sound Manager for OS 8,9 and Carbon
|
||||
pa_mac_core = Macintosh Core Audio for OS X
|
||||
pa_sgi = Silicon Graphics AL
|
||||
pa_unix_oss = OSS implementation for various Unixes
|
||||
pa_win_ds = Windows Direct Sound
|
||||
pa_win_wmme = Windows MME (most widely supported)
|
||||
|
||||
Test Programs
|
||||
pa_tests/pa_fuzz.c = guitar fuzz box
|
||||
pa_tests/pa_devs.c = print a list of available devices
|
||||
pa_tests/pa_minlat.c = determine minimum latency for your machine
|
||||
pa_tests/paqa_devs.c = self test that opens all devices
|
||||
pa_tests/paqa_errs.c = test error detection and reporting
|
||||
pa_tests/patest_clip.c = hear a sine wave clipped and unclipped
|
||||
pa_tests/patest_dither.c = hear effects of dithering (extremely subtle)
|
||||
pa_tests/patest_pink.c = fun with pink noise
|
||||
pa_tests/patest_record.c = record and playback some audio
|
||||
pa_tests/patest_maxsines.c = how many sine waves can we play? Tests Pa_GetCPULoad().
|
||||
pa_tests/patest_sine.c = output a sine wave in a simple PA app
|
||||
pa_tests/patest_sync.c = test syncronization of audio and video
|
||||
pa_tests/patest_wire.c = pass input to output, wire simulator
|
||||
1308
DependentExtensions/portaudio_v18_1/config.guess
vendored
Normal file
1308
DependentExtensions/portaudio_v18_1/config.guess
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1413
DependentExtensions/portaudio_v18_1/config.sub
vendored
Normal file
1413
DependentExtensions/portaudio_v18_1/config.sub
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2622
DependentExtensions/portaudio_v18_1/configure
vendored
Normal file
2622
DependentExtensions/portaudio_v18_1/configure
vendored
Normal file
File diff suppressed because it is too large
Load Diff
81
DependentExtensions/portaudio_v18_1/configure.in
Normal file
81
DependentExtensions/portaudio_v18_1/configure.in
Normal file
@ -0,0 +1,81 @@
|
||||
dnl
|
||||
dnl PortAudio configure.in script
|
||||
dnl
|
||||
dnl Dominic Mazzoni
|
||||
dnl
|
||||
|
||||
dnl Require autoconf >= 2.13
|
||||
AC_PREREQ(2.13)
|
||||
|
||||
dnl Init autoconf and make sure configure is being called
|
||||
dnl from the right directory
|
||||
AC_INIT([pa_common/portaudio.h])
|
||||
|
||||
dnl Checks for programs
|
||||
AC_PROG_CC
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_INSTALL
|
||||
AC_PATH_PROG(AR, ar, no)
|
||||
if [[ $AR = "no" ]] ; then
|
||||
AC_MSG_ERROR("Could not find ar - needed to create a library");
|
||||
fi
|
||||
|
||||
dnl Extra variables we want to substitute
|
||||
AC_SUBST(OTHER_OBJS)
|
||||
AC_SUBST(PADLL)
|
||||
AC_SUBST(SHARED_FLAGS)
|
||||
AC_SUBST(DLL_LIBS)
|
||||
|
||||
dnl Determine the host operating system / platform
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
case "${host_os}" in
|
||||
darwin* )
|
||||
dnl Mac OS X configuration
|
||||
|
||||
OTHER_OBJS="pa_mac_core/pa_mac_core.o";
|
||||
LIBS="-framework CoreAudio -lm";
|
||||
PADLL="libportaudio.dylib";
|
||||
SHARED_FLAGS="-framework CoreAudio -dynamiclib";
|
||||
;;
|
||||
|
||||
mingw* )
|
||||
dnl MingW configuration
|
||||
|
||||
OTHER_OBJS="pa_win_wmme/pa_win_wmme.o";
|
||||
LIBS="-lwinmm -lm";
|
||||
PADLL="portaudio.dll";
|
||||
SHARED_FLAGS="-shared -mthreads";
|
||||
DLL_LIBS="-lwinmm";
|
||||
;;
|
||||
|
||||
cygwin* )
|
||||
dnl Cygwin configuration
|
||||
|
||||
OTHER_OBJS="pa_win_wmme/pa_win_wmme.o";
|
||||
LIBS="-lwinmm -lm";
|
||||
PADLL="portaudio.dll";
|
||||
SHARED_FLAGS="-shared -mthreads";
|
||||
DLL_LIBS="-lwinmm";
|
||||
;;
|
||||
|
||||
*)
|
||||
dnl Unix OSS configuration
|
||||
|
||||
AC_CHECK_LIB(pthread, pthread_create,
|
||||
,
|
||||
AC_MSG_ERROR([libpthread not found!]))
|
||||
|
||||
OTHER_OBJS="pa_unix_oss/pa_unix_oss.o pa_unix_oss/pa_unix.o";
|
||||
LIBS="-lm -lpthread";
|
||||
PADLL="libportaudio.so";
|
||||
SHARED_FLAGS="-shared";
|
||||
esac
|
||||
|
||||
AC_OUTPUT([Makefile])
|
||||
|
||||
echo ""
|
||||
echo "Finished configure."
|
||||
|
||||
echo ""
|
||||
echo "Type 'make' to build PortAudio and examples."
|
||||
78
DependentExtensions/portaudio_v18_1/docs/index.html
Normal file
78
DependentExtensions/portaudio_v18_1/docs/index.html
Normal file
@ -0,0 +1,78 @@
|
||||
<!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>
|
||||
<hr WIDTH="100%">
|
||||
<h2>
|
||||
V18</h2>
|
||||
|
||||
<h3>
|
||||
<a href="portaudio_h.txt">API Reference for V18</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>
|
||||
|
||||
<hr WIDTH="100%">
|
||||
<h2>
|
||||
V19 - improved API</h2>
|
||||
|
||||
<h3>
|
||||
<a href="proposals/index.html">Proposed V19 Changes</a></h3>
|
||||
|
||||
<blockquote>Describes API changes being considered by the developer community.
|
||||
Feedback welcome.</blockquote>
|
||||
|
||||
<h3>
|
||||
<a href="v19-doxydocs/">API Reference for V19</a></h3>
|
||||
|
||||
<blockquote>Reference documents for the Application Programmer Interface
|
||||
for V19 generated by doxygen.</blockquote>
|
||||
|
||||
<hr WIDTH="100%">
|
||||
<h2>
|
||||
Miscellaneous</h2>
|
||||
|
||||
<h3>
|
||||
<a href="latency.html">Improving Latency</a></h3>
|
||||
|
||||
<blockquote>How to tune your computer to achieve the lowest possible audio
|
||||
delay.</blockquote>
|
||||
<a href="http://www.portaudio.com/">Return to PortAudio Home Page</a>
|
||||
</body>
|
||||
</html>
|
||||
192
DependentExtensions/portaudio_v18_1/docs/latency.html
Normal file
192
DependentExtensions/portaudio_v18_1/docs/latency.html
Normal file
@ -0,0 +1,192 @@
|
||||
<!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>
|
||||
488
DependentExtensions/portaudio_v18_1/docs/pa_drivermodel.c.txt
Normal file
488
DependentExtensions/portaudio_v18_1/docs/pa_drivermodel.c.txt
Normal file
@ -0,0 +1,488 @@
|
||||
/*
|
||||
This file contains the host-neutral code for implementing multiple driver model
|
||||
support in PortAudio.
|
||||
|
||||
It has not been compiled, but it is supplied only for example purposes at this stage.
|
||||
|
||||
TODO: use of CHECK_DRIVER_MODEL is bogus in some instances since some
|
||||
of those functions don't return a PaError
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "pa_drivermodel.h.txt"
|
||||
|
||||
|
||||
#ifndef PA_MULTIDRIVER
|
||||
/* single driver support, most functions will stay in the implementation files */
|
||||
|
||||
PaDriverModelID Pa_CountDriverModels()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Perhaps all drivers should define this with this signature
|
||||
const PaDriverModelInfo* Pa_GetDriverModelInfo( PaDriverModelID driverModelID )
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
PaDeviceID Pa_DriverModelDefaultInputDeviceID( PaDriverModelID driverModelID )
|
||||
{
|
||||
return Pa_GetDefaultInputDeviceID();
|
||||
}
|
||||
|
||||
|
||||
PaDeviceID Pa_DriverModelDefaultOutputDeviceID( PaDriverModelID driverModelID )
|
||||
{
|
||||
return Pa_GetDefaultInputDeviceID();
|
||||
}
|
||||
|
||||
/*
|
||||
Perhaps all drivers should define with this signature
|
||||
int Pa_DriverModelMinNumBuffers( PaDriverModelID driverModelID, int framesPerBuffer, double sampleRate )
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
int Pa_DriverModelCountDevices( PaDriverModelID driverModelID )
|
||||
{
|
||||
return Pa_CountDevices();
|
||||
}
|
||||
|
||||
PaDeviceID Pa_DriverModelGetDeviceID(PaDriverModelID driverModelID, int perDriverModelIndex )
|
||||
{
|
||||
return perDriverModelIndex;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
/* multidriver support */
|
||||
|
||||
|
||||
typedef PaError (*PaInitializeFunPtr)( PaDriverModelImplementation** );
|
||||
|
||||
/*
|
||||
the initializers array is a static table of function pointers
|
||||
to all the available driverModels on the current platform.
|
||||
|
||||
the order of pointers in the array is important. the first
|
||||
pointer is always considered to be the "default" driver model.
|
||||
*/
|
||||
|
||||
static PaInitializeFunPtr driverModelInitializers[] = {
|
||||
#ifdef WINDOWS
|
||||
PaWin32WMME_MultiDriverInitialize,
|
||||
PaWin32DS_MultiDriverInitialize,
|
||||
PaASIO_MultiDriverInitialize
|
||||
#endif
|
||||
#ifdef MAC
|
||||
PaMacSM_MultiDriverInitialize,
|
||||
PaMacCA_MultiDriverInitialize,
|
||||
PaASIO_MultiDriverInitialize
|
||||
#endif
|
||||
/* other platforms here */
|
||||
(PaInitializeFunPtr*)0 /* NULL terminate the list */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
the driverModels array is a dynamically created table of
|
||||
currently available driverModels.
|
||||
*/
|
||||
static PaDriverModelImplementation* driverModels = 0;
|
||||
static int numDriverModels = 0;
|
||||
|
||||
|
||||
#define PA_CHECK_INITIALIZED\
|
||||
if( driverModels == 0 )
|
||||
return paLibraryNotInitialised
|
||||
|
||||
#define PA_CHECK_DRIVER_MODEL_ID( id )
|
||||
if( id < 0 || id >= numDriverModels )
|
||||
return paBadDriverModelID;
|
||||
|
||||
|
||||
/*
|
||||
ConvertPublicDeviceIdToImplementationDeviceId converts deviceId
|
||||
from a public device id, to a device id for a particular
|
||||
PortAudio implementation. On return impl will either point
|
||||
to a valid implementation or will be NULL.
|
||||
*/
|
||||
static void ConvertPublicDeviceIDToImplementationDeviceID(
|
||||
PaDriverModelImplementation *impl, PaDeviceID deviceID )
|
||||
{
|
||||
int i, count;
|
||||
|
||||
impl = NULL;
|
||||
|
||||
for( i=0; i < numDriverModels; ++i ){
|
||||
count = driverModels[i]->countDevices();
|
||||
if( deviceID < count ){
|
||||
impl = driverModels[i];
|
||||
return NULL;
|
||||
}else{
|
||||
deviceID -= count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PaDeviceID ConvertImplementationDeviceIDToPublicDeviceID(
|
||||
PaDriverModelID driverModelID, PaDeviceID deviceID )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0; i < driverModelID; ++i )
|
||||
deviceID += driverModels[i]->countDevices();
|
||||
}
|
||||
|
||||
|
||||
PaError Pa_Initialize( void )
|
||||
{
|
||||
PaError result = paNoError;
|
||||
int i, initializerCount;
|
||||
PaDriverModelImplementation *impl;
|
||||
|
||||
if( driverModels != 0 )
|
||||
return paAlreadyInitialized;
|
||||
|
||||
/* count the number of driverModels */
|
||||
initializerCount=0;
|
||||
while( driverModelInitializers[initializerCount] != 0 ){
|
||||
++initializerCount;
|
||||
}
|
||||
|
||||
driverModels = malloc( sizeof(PaDriverModelImplementation*) * initializerCount );
|
||||
if( driverModels == NULL )
|
||||
return paInsufficientMemory;
|
||||
|
||||
numDriverModels = 0;
|
||||
for( i=0; i<initializerCount; ++i ){
|
||||
result = (*driverModelInitializers[i])( &impl );
|
||||
if( result == paNoError ){
|
||||
driverModels[numDriverModels] = impl;
|
||||
++numDriverModels;
|
||||
}else{
|
||||
// TODO: terminate the drivers which have already been initialized.
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PaError Pa_Terminate( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
/*
|
||||
rather than require each implementation to do it separately we could
|
||||
keep track of all open streams and close them here
|
||||
*/
|
||||
|
||||
for( i=0; i<numDriverModels; ++i )
|
||||
driverModels[i]->terminate( driverModels[i] );
|
||||
}
|
||||
|
||||
|
||||
long Pa_GetHostError( void )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
under construction. depends on error text proposal.
|
||||
}
|
||||
|
||||
|
||||
const char *Pa_GetErrorText( PaError errnum )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
under construction. may need to call driver model specific code
|
||||
depending on how the error text proposal pans out.
|
||||
}
|
||||
|
||||
|
||||
|
||||
int Pa_CountDevices()
|
||||
{
|
||||
int i, result;
|
||||
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
result = 0;
|
||||
for( i=0; i < numDriverModels; ++i )
|
||||
result += driverModels[i]->countDevices();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PaDeviceID Pa_GetDefaultInputDeviceID( void )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
return driverModels[0]->getDefaultInputDeviceID();
|
||||
}
|
||||
|
||||
PaDeviceID Pa_GetDefaultOutputDeviceID( void )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
return driverModels[0]->getDefaultInputDeviceID();
|
||||
}
|
||||
|
||||
|
||||
const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID deviceID )
|
||||
{
|
||||
PaDriverModelImplementation *impl;
|
||||
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
ConvertPublicDeviceIDToImplementationDeviceID( impl, deviceID );
|
||||
if( impl == NULL )
|
||||
return paInvalidDeviceID;
|
||||
|
||||
return impl->getDeviceInfo( deviceID );
|
||||
}
|
||||
|
||||
/* NEW MULTIPLE DRIVER MODEL FUNCTIONS ---------------------------------- */
|
||||
|
||||
PaDriverModelID Pa_CountDriverModels()
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
return numDriverModels;
|
||||
}
|
||||
|
||||
|
||||
const PaDriverModelInfo* Pa_GetDriverModelInfo( PaDriverModelID driverModelID )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
PA_CHECK_DRIVER_MODEL_ID( driverModelID );
|
||||
|
||||
return driverModels[ driverModelID ]->getDriverModelInfo();
|
||||
}
|
||||
|
||||
|
||||
PaDeviceID Pa_DriverModelDefaultInputDeviceID( PaDriverModelID driverModelID )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
PA_CHECK_DRIVER_MODEL_ID( driverModelID );
|
||||
|
||||
return ConvertImplementationDeviceIDToPublicDeviceID( driverModelID,
|
||||
driverModels[ driverModelID ]->getDefaultInputDeviceID();
|
||||
}
|
||||
|
||||
|
||||
PaDeviceID Pa_DriverModelDefaultOutputDeviceID( PaDriverModelID driverModelID )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
PA_CHECK_DRIVER_MODEL_ID( driverModelID );
|
||||
|
||||
return ConvertImplementationDeviceIDToPublicDeviceID( driverModelID,
|
||||
driverModels[ driverModelID ]->getDefaultOutputDeviceID();
|
||||
}
|
||||
|
||||
|
||||
int Pa_DriverModelMinNumBuffers( PaDriverModelID driverModelID, int framesPerBuffer, double sampleRate )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
PA_CHECK_DRIVER_MODEL_ID( driverModelID );
|
||||
|
||||
return driverModels[ driverModelID ]->getMinNumBuffers( int framesPerBuffer, double sampleRate );
|
||||
}
|
||||
|
||||
|
||||
int Pa_DriverModelCountDevices( PaDriverModelID driverModelID )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
PA_CHECK_DRIVER_MODEL_ID( driverModelID );
|
||||
|
||||
return driverModels[ driverModelID ]->coundDevices();
|
||||
}
|
||||
|
||||
PaDeviceID Pa_DriverModelGetDeviceID(PaDriverModelID driverModelID, int perDriverModelIndex )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
PA_CHECK_DRIVER_MODEL_ID( driverModelID );
|
||||
|
||||
return ConvertImplementationDeviceIDToPublicDeviceID( driverModelID, perDriverModelIndex );
|
||||
}
|
||||
|
||||
/* END NEW MULTIPLE DRIVER MODEL FUNCTIONS ------------------------------ */
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
PaError result;
|
||||
PaDriverModelImplementation *inputImpl, *outputImpl, impl;
|
||||
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
if( inputDevice != paNoDevice ){
|
||||
ConvertPublicDeviceIDToImplementationDeviceID( inputImpl, inputDevice );
|
||||
if( inputImpl == NULL )
|
||||
return paInvalidDeviceID;
|
||||
else
|
||||
impl = inputImpl;
|
||||
}
|
||||
|
||||
if( outputDevice != paNoDevice ){
|
||||
ConvertPublicDeviceIDToImplementationDeviceID( outputImpl, outputDevice );
|
||||
if( outputImpl == NULL )
|
||||
return paInvalidDeviceID;
|
||||
else
|
||||
impl = outputImpl;
|
||||
}
|
||||
|
||||
if( inputDevice != paNoDevice && outputDevice != paNoDevice ){
|
||||
if( inputImpl != outputImpl )
|
||||
return paDevicesMustBelongToTheSameDriverModel;
|
||||
}
|
||||
|
||||
|
||||
result = impl->openStream( stream, inputDevice, numInputChannels, inputSampleFormat, inputDriverInfo,
|
||||
outputDevice, numOutputChannels, outputSampleFormat, outputDriverInfo,
|
||||
sampleRate, framesPerBuffer, numberOfBuffers, streamFlags, callback, userData );
|
||||
|
||||
|
||||
if( result == paNoError )
|
||||
((PaStreamImplementation*)stream)->magic = PA_STREAM_MAGIC;
|
||||
|
||||
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 )
|
||||
{
|
||||
PaError result;
|
||||
int inputDevice = driverModels[0]->getDefaultInputDeviceID;
|
||||
int outputDevice = driverModels[0]->getDefaultOutputDeviceID;
|
||||
|
||||
result = driverModels[0]->openStream( stream, inputDevice, numInputChannels, sampleFormat, 0,
|
||||
outputDevice, numOutputChannels, sampleFormat, 0,
|
||||
sampleRate, framesPerBuffer, numberOfBuffers,
|
||||
streamFlags, callback, userData );
|
||||
|
||||
if( result == paNoError )
|
||||
((PaStreamImplementation*)stream)->magic = PA_STREAM_MAGIC;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PaError Pa_CloseStream( PortAudioStream* stream )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
PaError result = ((PaStreamImplementation*)stream)->close();
|
||||
|
||||
if( result == PaNoError )
|
||||
((PaStreamImplementation*)stream)->magic = 0; /* clear magic number */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PaError Pa_StartStream( PortAudioStream *stream );
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
return ((PaStreamImplementation*)stream)->start();
|
||||
}
|
||||
|
||||
|
||||
PaError Pa_StopStream( PortAudioStream *stream );
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
return ((PaStreamImplementation*)stream)->stop();
|
||||
}
|
||||
|
||||
|
||||
PaError Pa_AbortStream( PortAudioStream *stream );
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
return ((PaStreamImplementation*)stream)->abort();
|
||||
}
|
||||
|
||||
|
||||
PaError Pa_StreamActive( PortAudioStream *stream )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
return ((PaStreamImplementation*)stream)->active();
|
||||
}
|
||||
|
||||
PaTimestamp Pa_StreamTime( PortAudioStream *stream )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
return ((PaStreamImplementation*)stream)->time();
|
||||
}
|
||||
|
||||
|
||||
double Pa_StreamCPULoad( PortAudioStream* stream )
|
||||
{
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
return ((PaStreamImplementation*)stream)->cpuLoad();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int Pa_GetMinNumBuffers( PaDeviceID deviceID, int framesPerBuffer, double sampleRate )
|
||||
{
|
||||
PaDriverModelImplementation *impl;
|
||||
PA_CHECK_INITIALIZED;
|
||||
|
||||
ConvertPublicDeviceIDToImplementationDeviceID( impl, deviceID );
|
||||
if( impl == NULL )
|
||||
return paInvalidDeviceID;
|
||||
|
||||
return impl->getMinNumBuffers( framesPerBuffer, sampleRate );
|
||||
}
|
||||
|
||||
|
||||
void Pa_Sleep( long msec )
|
||||
{
|
||||
same as existing implementaion
|
||||
}
|
||||
|
||||
|
||||
PaError Pa_GetSampleSize( PaSampleFormat format )
|
||||
{
|
||||
same as existing implementation
|
||||
}
|
||||
|
||||
#endif /* PA_MULTIDRIVER */
|
||||
|
||||
|
||||
143
DependentExtensions/portaudio_v18_1/docs/pa_drivermodel.h.txt
Normal file
143
DependentExtensions/portaudio_v18_1/docs/pa_drivermodel.h.txt
Normal file
@ -0,0 +1,143 @@
|
||||
#ifndef PA_MULTIDRIVERMODEL_H
|
||||
#define PA_MULTIDRIVERMODEL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/*
|
||||
This file contains the host-neutral code for implementing multiple driver model
|
||||
support in PortAudio.
|
||||
|
||||
It has not been compiled, but it is supplied only for example purposes at this stage.
|
||||
*/
|
||||
|
||||
|
||||
#include "portaudio.h"
|
||||
|
||||
|
||||
#define PA_MULTIDRIVER // for multidriver support
|
||||
|
||||
|
||||
|
||||
TODO: declare function pointer types for the following function pointers
|
||||
|
||||
/*
|
||||
Each driver model implementation needs to implement an initialize function
|
||||
which is added to the driverModelInitializers array in pa_multidrivermodel.c
|
||||
|
||||
the initializer function needs to return a pointer to a
|
||||
PaDriverModelImplementation structure, or NULL if initiliazation failed. TODO: need error code instead
|
||||
|
||||
the function pointer members of this structure point to funtions
|
||||
which operate in exactly the same way as the corresponding functions
|
||||
in the PortAudio API.
|
||||
*/
|
||||
|
||||
struct{
|
||||
fptr terminate; /* takes the PaDriverModelImplementation* returned by initialize */
|
||||
fptr getDriverModelInfo;
|
||||
fptr getHostError;
|
||||
fptr getHostErrorText;
|
||||
fptr countDevices;
|
||||
fptr getDefaultInputDeviceID;
|
||||
fptr getDefaultOutputDeviceID;
|
||||
fptr getDeviceInfo;
|
||||
fptr openStream;
|
||||
fptr getMinNumBuffers;
|
||||
} PaDriverModelImplementation;
|
||||
|
||||
/*
|
||||
whenever an implementaion's openstream method is called it should return a
|
||||
PortAudioStream* whose first segment is actually the following structure.
|
||||
|
||||
the functions pointer members of this structure point to funcitons
|
||||
which operate in exactly the same way as the corresponding functions
|
||||
in the PortAudio API.
|
||||
*/
|
||||
struct{
|
||||
unsigned long magic;
|
||||
fptr close;
|
||||
fptr start;
|
||||
fptr stop;
|
||||
fptr abort;
|
||||
fptr active;
|
||||
fptr time;
|
||||
fptr cpuLoad;
|
||||
} PaStreamImplementation;
|
||||
|
||||
/*
|
||||
Implementations should set magic to PA_STREAM_MAGIC when opening
|
||||
a stream _and_ clear it to zero when closing a stream.
|
||||
All functions which operate on streams should check the validity
|
||||
of magic.
|
||||
*/
|
||||
|
||||
#define PA_STREAM_MAGIC 0x12345678
|
||||
|
||||
#define PA_CHECK_STREAM( stream )\
|
||||
if( ((PaStreamImplementation*)stream)->magic != PA_STREAM_MAGIC )\
|
||||
return paBadStreamPtr;
|
||||
|
||||
|
||||
/*
|
||||
PA_API allows the same implementation to be used for single
|
||||
driver model and multi-driver model operation. If
|
||||
PA_MULTIDRIVER not defined, PA_API will declare api
|
||||
functions as global, otherwise they will be static, and include
|
||||
the drivermodel code.
|
||||
|
||||
Usage would be something like:
|
||||
|
||||
int PA_API(CountDevices)();
|
||||
|
||||
The PA_MULTIDRIVER_SUPPORT macro declares the initialization and
|
||||
termination functions required by the multidriver support. it also
|
||||
allocates and deallocates the PaDriverModelImplementation structure.
|
||||
|
||||
TODO: add macros for initializing PaStreamImplementation PortAudioStream
|
||||
these would be PA_INITIALIZE_STREAM and PA_TERMINATE_STREAM
|
||||
they would assign and clear the magic number and assign the
|
||||
interface functions if neceassary.
|
||||
*/
|
||||
|
||||
#ifdef PA_MULTIDRIVER
|
||||
|
||||
#define PA_API( model, name ) static Pa ## model ## _ ## name
|
||||
|
||||
#define PA_MULTIDRIVER_SUPPORT( model )\
|
||||
PaError Pa_ ## model ## _MultiDriverTerminate( PaStreamImplementation *impl )\
|
||||
{\
|
||||
free( impl );\
|
||||
return Pa ## model ## _Terminate();\
|
||||
}\
|
||||
PaError Pa ## model ## _MultiDriverInitialize( PaStreamImplementation** impl )\
|
||||
{\
|
||||
PaError result = Pa ## model ## _Initialize();\
|
||||
\
|
||||
if( result == paNoError ){\
|
||||
*impl = malloc( sizeof( PaDriverModelImplementation ) );\
|
||||
if( impl == NULL ){\
|
||||
// TODO: call terminate, return an error
|
||||
}else{\
|
||||
(*impl)->terminate = Pa ## model ## _MultiDriverTerminate();\
|
||||
(*impl)->getDriverModelInfo = Pa ## model ## _GetDriverModelInfo();\
|
||||
(*impl)->getHostError = Pa ## model ## _GetHostError();\
|
||||
// TODO: assign the rest of the interface functions
|
||||
}\
|
||||
}\
|
||||
return result;\
|
||||
}
|
||||
|
||||
#else /* !PA_MULTIDRIVER */
|
||||
|
||||
#define PA_API( model, name ) Pa_ ## name
|
||||
|
||||
#define PA_MULTIDRIVER_SUPPORT
|
||||
|
||||
#endif /* PA_MULTIDRIVER */
|
||||
|
||||
|
||||
|
||||
#endif /* PA_MULTIDRIVERMODEL_H */
|
||||
197
DependentExtensions/portaudio_v18_1/docs/pa_impl_guide.html
Normal file
197
DependentExtensions/portaudio_v18_1/docs/pa_impl_guide.html
Normal file
@ -0,0 +1,197 @@
|
||||
<!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>
|
||||
190
DependentExtensions/portaudio_v18_1/docs/pa_impl_startstop.html
Normal file
190
DependentExtensions/portaudio_v18_1/docs/pa_impl_startstop.html
Normal file
@ -0,0 +1,190 @@
|
||||
<!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>
|
||||
108
DependentExtensions/portaudio_v18_1/docs/pa_tut_asio.html
Normal file
108
DependentExtensions/portaudio_v18_1/docs/pa_tut_asio.html
Normal file
@ -0,0 +1,108 @@
|
||||
<!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>
|
||||
<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></h2>
|
||||
|
||||
<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/en/ps/support/3rdparty/">download
|
||||
the ASIO SDK</a> from Steinberg. You also need to obtain ASIO drivers from
|
||||
the manufacturer of your audio hardware.
|
||||
<p>Note: I am using '/' as a file separator below. On Macintosh replace
|
||||
'/' with ':'. On Windows, replace '/' with '\'.
|
||||
<p>You may try compiling the "pa_tests/patest_saw.c" file first because
|
||||
it is the simplest.
|
||||
<p>Several files are common to all PortAudio implementations. Add the following
|
||||
source files to your project:
|
||||
<blockquote>pa_common/pa_lib.c
|
||||
<br>pa_common/portaudio.h
|
||||
<br>pa_common/pa_host.h</blockquote>
|
||||
To use ASIO with the PortAudio library add the following:
|
||||
<blockquote>
|
||||
<pre>pa_asio/pa_asio.cpp</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<h3>
|
||||
Macintosh Specific</h3>
|
||||
|
||||
<blockquote>Note: there is a bug in the <b>Macintosh</b> ASIO code. Mac
|
||||
users should read the file "pa_asio:readme_asio_sdk_patch.txt" for information
|
||||
on how to fix the bug.
|
||||
<p>Add these files from the ASIO SDK downloaded from Steinberg:</blockquote>
|
||||
|
||||
<blockquote>
|
||||
<blockquote><tt>host/asiodrivers.cpp</tt>
|
||||
<br><tt>host/mac/asioshlib.cpp</tt>
|
||||
<br><tt>host/mac/codefragements.cpp</tt></blockquote>
|
||||
The ASIO drivers should be in a folder called "ASIO Drivers" beneath your
|
||||
application.</blockquote>
|
||||
|
||||
<h3>
|
||||
Windows Specific</h3>
|
||||
|
||||
<blockquote>Add these files from the ASIO SDK downloaded from Steinberg:</blockquote>
|
||||
|
||||
<blockquote>
|
||||
<blockquote><tt>host/asiodrivers.cpp</tt>
|
||||
<br><tt>host/asiolist.cpp</tt>
|
||||
<br><tt>common/asio.cpp</tt></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<blockquote>Add these directories to the path for include files:</blockquote>
|
||||
|
||||
<blockquote>
|
||||
<blockquote><tt>host</tt>
|
||||
<br><tt>host/pc</tt>
|
||||
<br><tt>common</tt></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<blockquote>and link with the system library "<b>winmm.lib</b>". For MS
|
||||
Visual C++:
|
||||
<ul>
|
||||
<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>
|
||||
</ul>
|
||||
</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>
|
||||
@ -0,0 +1,91 @@
|
||||
<!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>
|
||||
65
DependentExtensions/portaudio_v18_1/docs/pa_tut_devs.html
Normal file
65
DependentExtensions/portaudio_v18_1/docs/pa_tut_devs.html
Normal file
@ -0,0 +1,65 @@
|
||||
<!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>
|
||||
42
DependentExtensions/portaudio_v18_1/docs/pa_tut_explore.html
Normal file
42
DependentExtensions/portaudio_v18_1/docs/pa_tut_explore.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!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>
|
||||
43
DependentExtensions/portaudio_v18_1/docs/pa_tut_init.html
Normal file
43
DependentExtensions/portaudio_v18_1/docs/pa_tut_init.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!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>
|
||||
41
DependentExtensions/portaudio_v18_1/docs/pa_tut_mac.html
Normal file
41
DependentExtensions/portaudio_v18_1/docs/pa_tut_mac.html
Normal file
@ -0,0 +1,41 @@
|
||||
<!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>
|
||||
84
DependentExtensions/portaudio_v18_1/docs/pa_tut_mac_osx.html
Normal file
84
DependentExtensions/portaudio_v18_1/docs/pa_tut_mac_osx.html
Normal file
@ -0,0 +1,84 @@
|
||||
<!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>
|
||||
<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></h2>
|
||||
|
||||
<h2>
|
||||
Compiling for Macintosh OS X</h2>
|
||||
|
||||
<blockquote>To compile a Macintosh OS X CoreAudio application with the
|
||||
PortAudio library you will use the following source files:
|
||||
<blockquote>pa_mac_core/pa_mac_core.c<br>
|
||||
pa_common/pa_lib.c<br>
|
||||
pa_common/portaudio.h<br>
|
||||
pa_common/pa_host.h<br>
|
||||
pa_common/pa_convert.c<br>
|
||||
pablio/ringbuffer.c<br>
|
||||
pablio/ringbuffer.h</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<h3>
|
||||
Using Apple Project Builder</h3>
|
||||
|
||||
<blockquote>Create a new ProjectBuilder project. You can use a "Tool" project
|
||||
to run the PortAudio examples.
|
||||
<p>Add the source files from above to your Project.
|
||||
<p>Add both the Apple CoreAudio.framework and the AudioToolbox.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>
|
||||
|
||||
<h3>
|
||||
Or Using Metrowerks CodeWarrior 8</h3>
|
||||
|
||||
<blockquote>by James Vanlommel</blockquote>
|
||||
|
||||
<blockquote>Create a new CodeWarrior project using Mac OS C++ Stationery.
|
||||
<br>Then choose Mac OS X Mach-O > Standard Console > C++ Console Mach-O.
|
||||
<p>In the project window, Clear the HelloWorld.cpp file and add the source
|
||||
files from above to your Project.
|
||||
<p>Add a test file of your choosing, like
|
||||
<br> patests /patest_sine8.c
|
||||
<br>
|
||||
<br>Add the frameworks to the Frameworks tab using Project > Add Files...
|
||||
<br> CoreAudio
|
||||
<br> AudioToolbox
|
||||
<p>(The System framework should already be a part of the project.)
|
||||
<p>Open the current target's settings, and in Language Settings > C/C++
|
||||
Language, uncheck (disable) the "ANSI Strict" setting. (Do this for both
|
||||
Debug and Release projects, if necessary.)
|
||||
<p>Edit pa_mac_core.c:
|
||||
<br> On line 1546, cast the PaHost_AllocateFastMemory() result
|
||||
to a (char *) or you will get a compile error.
|
||||
<br>
|
||||
<br>Compile and run. (may need to run from a terminal window)
|
||||
<p>I've successfully built patest_sine8.c this way using the CVS .tar version
|
||||
of portaudio (date: 2003-04-27). I get 17 warnings during compilation,
|
||||
all of which deal with unused variables or arguments.</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>
|
||||
56
DependentExtensions/portaudio_v18_1/docs/pa_tut_open.html
Normal file
56
DependentExtensions/portaudio_v18_1/docs/pa_tut_open.html
Normal file
@ -0,0 +1,56 @@
|
||||
<!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>
|
||||
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.
|
||||
<p>First declare a variable to receive the stream pointer:
|
||||
<blockquote>
|
||||
<pre>PortAudioStream *stream;</pre>
|
||||
</blockquote>
|
||||
There are two calls for opening streams, <tt>Pa_OpenStream</tt>() and <tt>Pa_OpenDefaultStream</tt>().
|
||||
P<tt>a_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>
|
||||
46
DependentExtensions/portaudio_v18_1/docs/pa_tut_oss.html
Normal file
46
DependentExtensions/portaudio_v18_1/docs/pa_tut_oss.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!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>
|
||||
92
DependentExtensions/portaudio_v18_1/docs/pa_tut_over.html
Normal file
92
DependentExtensions/portaudio_v18_1/docs/pa_tut_over.html
Normal file
@ -0,0 +1,92 @@
|
||||
<!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>
|
||||
114
DependentExtensions/portaudio_v18_1/docs/pa_tut_pc.html
Normal file
114
DependentExtensions/portaudio_v18_1/docs/pa_tut_pc.html
Normal file
@ -0,0 +1,114 @@
|
||||
<!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 Windows (WMME or DirectSound)</h2>
|
||||
|
||||
<blockquote>To compile PortAudio for Windows, you can choose between three
|
||||
options:
|
||||
<ul>
|
||||
<li>
|
||||
DirectSound API.</li>
|
||||
|
||||
<li>
|
||||
Windows MultiMedia Extensions API (aka WMME or WAVE).</li>
|
||||
|
||||
<li>
|
||||
<a href="pa_tut_asio.html">Steinberg's ASIO API</a></li>
|
||||
</ul>
|
||||
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. <b>So WMME is the best choice for most projects.</b><b></b>
|
||||
<p><b>Note: </b>If you are compiling one of the PortAudio test programs
|
||||
with Visual C++, then create a new Project of type "Win32 Console Application".
|
||||
<h3>
|
||||
All</h3>
|
||||
For any Windows 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>
|
||||
|
||||
<h3>
|
||||
WMME</h3>
|
||||
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>
|
||||
|
||||
<h3>
|
||||
DirectSound</h3>
|
||||
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 both system libraries "<b>dsound.lib</b>" and "<b>winmm.lib</b>"
|
||||
using the procedure described above for "winmm.lib".
|
||||
<br>
|
||||
<table BORDER >
|
||||
<tr>
|
||||
<td><b>Borland</b> users cannot link with the "dsound.lib" from Microsoft
|
||||
directly. Emmanuel offered this advice:
|
||||
<p>One can use implib from Borland to generate a new .lib file which is
|
||||
compatible with Borland C++.
|
||||
<p>Use: "implib dsound.dll dsound.lib" and include dsound.lib into your
|
||||
project.
|
||||
<p>I still had a problem executing the patest_record example. The thread
|
||||
ended with an error like 'Floating point overflow at...'. This problem
|
||||
was caused due to a fault in the compiler. Now I'm using Borland 5.02 (instead
|
||||
of 5.01). Everything seems to be working fine at the moment.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</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>
|
||||
56
DependentExtensions/portaudio_v18_1/docs/pa_tut_run.html
Normal file
56
DependentExtensions/portaudio_v18_1/docs/pa_tut_run.html
Normal file
@ -0,0 +1,56 @@
|
||||
<!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>
|
||||
79
DependentExtensions/portaudio_v18_1/docs/pa_tut_rw.html
Normal file
79
DependentExtensions/portaudio_v18_1/docs/pa_tut_rw.html
Normal file
@ -0,0 +1,79 @@
|
||||
<!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>
|
||||
47
DependentExtensions/portaudio_v18_1/docs/pa_tut_term.html
Normal file
47
DependentExtensions/portaudio_v18_1/docs/pa_tut_term.html
Normal file
@ -0,0 +1,47 @@
|
||||
<!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>
|
||||
55
DependentExtensions/portaudio_v18_1/docs/pa_tut_util.html
Normal file
55
DependentExtensions/portaudio_v18_1/docs/pa_tut_util.html
Normal file
@ -0,0 +1,55 @@
|
||||
<!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>
|
||||
46
DependentExtensions/portaudio_v18_1/docs/pa_tutorial.html
Normal file
46
DependentExtensions/portaudio_v18_1/docs/pa_tutorial.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!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>
|
||||
425
DependentExtensions/portaudio_v18_1/docs/portaudio_h.txt
Normal file
425
DependentExtensions/portaudio_v18_1/docs/portaudio_h.txt
Normal file
@ -0,0 +1,425 @@
|
||||
#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 */
|
||||
BIN
DependentExtensions/portaudio_v18_1/docs/portaudio_icmc2001.pdf
Normal file
BIN
DependentExtensions/portaudio_v18_1/docs/portaudio_icmc2001.pdf
Normal file
Binary file not shown.
BIN
DependentExtensions/portaudio_v18_1/docs/proposals.html
Normal file
BIN
DependentExtensions/portaudio_v18_1/docs/proposals.html
Normal file
Binary file not shown.
339
DependentExtensions/portaudio_v18_1/docs/releases.html
Normal file
339
DependentExtensions/portaudio_v18_1/docs/releases.html
Normal file
@ -0,0 +1,339 @@
|
||||
<!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>
|
||||
19
DependentExtensions/portaudio_v18_1/fixdir.bat
Normal file
19
DependentExtensions/portaudio_v18_1/fixdir.bat
Normal file
@ -0,0 +1,19 @@
|
||||
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 ..\
|
||||
7
DependentExtensions/portaudio_v18_1/fixfile.bat
Normal file
7
DependentExtensions/portaudio_v18_1/fixfile.bat
Normal file
@ -0,0 +1,7 @@
|
||||
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
|
||||
89
DependentExtensions/portaudio_v18_1/index.html
Normal file
89
DependentExtensions/portaudio_v18_1/index.html
Normal file
@ -0,0 +1,89 @@
|
||||
<!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 - Cross-Platform Audio API</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>
|
||||
251
DependentExtensions/portaudio_v18_1/install-sh
Normal file
251
DependentExtensions/portaudio_v18_1/install-sh
Normal file
@ -0,0 +1,251 @@
|
||||
#!/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
|
||||
Binary file not shown.
3084
DependentExtensions/portaudio_v18_1/pa_asio/pa_asio.cpp
Normal file
3084
DependentExtensions/portaudio_v18_1/pa_asio/pa_asio.cpp
Normal file
File diff suppressed because it is too large
Load Diff
BIN
DependentExtensions/portaudio_v18_1/pa_asio/pa_asio.pdf
Normal file
BIN
DependentExtensions/portaudio_v18_1/pa_asio/pa_asio.pdf
Normal file
Binary file not shown.
@ -0,0 +1,25 @@
|
||||
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;
|
||||
}
|
||||
|
||||
108
DependentExtensions/portaudio_v18_1/pa_beos/PlaybackNode.h
Normal file
108
DependentExtensions/portaudio_v18_1/pa_beos/PlaybackNode.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* $Id: PlaybackNode.h,v 1.1.1.1 2002/01/22 00:52:08 phil 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;
|
||||
|
||||
};
|
||||
|
||||
441
DependentExtensions/portaudio_v18_1/pa_beos/pa_beos_mk.cc
Normal file
441
DependentExtensions/portaudio_v18_1/pa_beos/pa_beos_mk.cc
Normal file
@ -0,0 +1,441 @@
|
||||
/*
|
||||
* $Id: pa_beos_mk.cc,v 1.1.1.1 2002/01/22 00:52:09 phil 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 );
|
||||
}
|
||||
538
DependentExtensions/portaudio_v18_1/pa_beos/playbacknode.cc
Normal file
538
DependentExtensions/portaudio_v18_1/pa_beos/playbacknode.cc
Normal file
@ -0,0 +1,538 @@
|
||||
/*
|
||||
* $Id: PlaybackNode.cc,v 1.1.1.1 2002/01/22 00:52:07 phil 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"));
|
||||
|
||||
470
DependentExtensions/portaudio_v18_1/pa_common/pa_convert.c
Normal file
470
DependentExtensions/portaudio_v18_1/pa_common/pa_convert.c
Normal file
@ -0,0 +1,470 @@
|
||||
/*
|
||||
* 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 = (long) (*sourceBuffer * 127.0f);
|
||||
CLIP( samp, -0x80, 0x7F );
|
||||
*targetBuffer = (char) samp;
|
||||
sourceBuffer += sourceStride;
|
||||
targetBuffer += targetStride;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
static void PaConvert_Float32_Int8_ClipDither(
|
||||
float *sourceBuffer, int sourceStride,
|
||||
char *targetBuffer, int targetStride,
|
||||
int numSamples )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<numSamples; i++ )
|
||||
{
|
||||
// use smaller scaler to prevent overflow when we add the dither
|
||||
float dither = PaConvert_TriangularDither() * PA_DITHER_SCALE;
|
||||
float dithered = (*sourceBuffer * (126.0f)) + dither;
|
||||
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 = (unsigned char)(128 + (*sourceBuffer * (127.0)));
|
||||
*targetBuffer = samp;
|
||||
sourceBuffer += sourceStride;
|
||||
targetBuffer += targetStride;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
static void PaConvert_UInt8_Float32(
|
||||
unsigned char *sourceBuffer, int sourceStride,
|
||||
float *targetBuffer, int targetStride,
|
||||
int numSamples )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<numSamples; i++ )
|
||||
{
|
||||
float samp = (*sourceBuffer - 128) * (1.0f / 128.0f);
|
||||
*targetBuffer = samp;
|
||||
sourceBuffer += sourceStride;
|
||||
targetBuffer += targetStride;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
static void PaConvert_Float32_Int32(
|
||||
float *sourceBuffer, int sourceStride,
|
||||
long *targetBuffer, int targetStride,
|
||||
int numSamples )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<numSamples; i++ )
|
||||
{
|
||||
int samp = (int) (*sourceBuffer * 0x7FFFFFFF);
|
||||
*targetBuffer = samp;
|
||||
sourceBuffer += sourceStride;
|
||||
targetBuffer += targetStride;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
static void PaConvert_Float32_Int32_Clip(
|
||||
float *sourceBuffer, int sourceStride,
|
||||
long *targetBuffer, int targetStride,
|
||||
int numSamples )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<numSamples; i++ )
|
||||
{
|
||||
int samp;
|
||||
float fs = *sourceBuffer;
|
||||
CLIP( fs, -1.0f, 0.999999f );
|
||||
samp = (int) (*sourceBuffer * 0x7FFFFFFF);
|
||||
*targetBuffer = samp;
|
||||
sourceBuffer += sourceStride;
|
||||
targetBuffer += targetStride;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
static void PaConvert_Int32_Float32(
|
||||
long *sourceBuffer, int sourceStride,
|
||||
float *targetBuffer, int targetStride,
|
||||
int numSamples )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<numSamples; i++ )
|
||||
{
|
||||
float samp = *sourceBuffer * (1.0f / 0x7FFFFFFF);
|
||||
*targetBuffer = samp;
|
||||
sourceBuffer += sourceStride;
|
||||
targetBuffer += targetStride;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
static PortAudioConverter *PaConvert_SelectProc( PaSampleFormat sourceFormat,
|
||||
PaSampleFormat targetFormat, int ifClip, int ifDither )
|
||||
{
|
||||
PortAudioConverter *proc = NULL;
|
||||
switch( sourceFormat )
|
||||
{
|
||||
case paUInt8:
|
||||
switch( targetFormat )
|
||||
{
|
||||
case paFloat32:
|
||||
proc = (PortAudioConverter *) PaConvert_UInt8_Float32;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case paInt8:
|
||||
switch( targetFormat )
|
||||
{
|
||||
case paFloat32:
|
||||
proc = (PortAudioConverter *) PaConvert_Int8_Float32;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case paInt16:
|
||||
switch( targetFormat )
|
||||
{
|
||||
case paFloat32:
|
||||
proc = (PortAudioConverter *) PaConvert_Int16_Float32;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case paInt32:
|
||||
switch( targetFormat )
|
||||
{
|
||||
case paFloat32:
|
||||
proc = (PortAudioConverter *) PaConvert_Int32_Float32;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case paFloat32:
|
||||
switch( targetFormat )
|
||||
{
|
||||
case paUInt8:
|
||||
proc = (PortAudioConverter *) PaConvert_Float32_UInt8;
|
||||
break;
|
||||
case paInt8:
|
||||
if( ifClip && ifDither ) proc = (PortAudioConverter *) PaConvert_Float32_Int8_ClipDither;
|
||||
else if( ifClip ) proc = (PortAudioConverter *) PaConvert_Float32_Int8_Clip;
|
||||
else if( ifDither ) proc = (PortAudioConverter *) PaConvert_Float32_Int8_Dither;
|
||||
else proc = (PortAudioConverter *) PaConvert_Float32_Int8;
|
||||
break;
|
||||
case paInt16:
|
||||
if( ifClip && ifDither ) proc = (PortAudioConverter *) PaConvert_Float32_Int16_ClipDither;
|
||||
else if( ifClip ) proc = (PortAudioConverter *) PaConvert_Float32_Int16_Clip;
|
||||
else if( ifDither ) proc = (PortAudioConverter *) PaConvert_Float32_Int16_Dither;
|
||||
else proc = (PortAudioConverter *) PaConvert_Float32_Int16;
|
||||
break;
|
||||
case paInt32:
|
||||
/* Don't bother dithering a 32 bit integer! */
|
||||
if( ifClip ) proc = (PortAudioConverter *) PaConvert_Float32_Int32_Clip;
|
||||
else proc = (PortAudioConverter *) PaConvert_Float32_Int32;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return proc;
|
||||
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
PaError PaConvert_SetupInput( internalPortAudioStream *past,
|
||||
PaSampleFormat nativeInputSampleFormat )
|
||||
{
|
||||
past->past_NativeInputSampleFormat = nativeInputSampleFormat;
|
||||
past->past_InputConversionSourceStride = 1;
|
||||
past->past_InputConversionTargetStride = 1;
|
||||
|
||||
if( nativeInputSampleFormat != past->past_InputSampleFormat )
|
||||
{
|
||||
int ifDither = (past->past_Flags & paDitherOff) == 0;
|
||||
past->past_InputConversionProc = PaConvert_SelectProc( nativeInputSampleFormat,
|
||||
past->past_InputSampleFormat, 0, ifDither );
|
||||
if( past->past_InputConversionProc == NULL ) return paSampleFormatNotSupported;
|
||||
}
|
||||
else
|
||||
{
|
||||
past->past_InputConversionProc = NULL; /* no conversion necessary */
|
||||
}
|
||||
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
PaError PaConvert_SetupOutput( internalPortAudioStream *past,
|
||||
PaSampleFormat nativeOutputSampleFormat )
|
||||
{
|
||||
|
||||
past->past_NativeOutputSampleFormat = nativeOutputSampleFormat;
|
||||
past->past_OutputConversionSourceStride = 1;
|
||||
past->past_OutputConversionTargetStride = 1;
|
||||
|
||||
if( nativeOutputSampleFormat != past->past_OutputSampleFormat )
|
||||
{
|
||||
int ifDither = (past->past_Flags & paDitherOff) == 0;
|
||||
int ifClip = (past->past_Flags & paClipOff) == 0;
|
||||
|
||||
past->past_OutputConversionProc = PaConvert_SelectProc( past->past_OutputSampleFormat,
|
||||
nativeOutputSampleFormat, ifClip, ifDither );
|
||||
if( past->past_OutputConversionProc == NULL ) return paSampleFormatNotSupported;
|
||||
}
|
||||
else
|
||||
{
|
||||
past->past_OutputConversionProc = NULL; /* no conversion necessary */
|
||||
}
|
||||
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
** Called by host code.
|
||||
** Convert input from native format to user format,
|
||||
** call user code,
|
||||
** then convert output to native format.
|
||||
** Returns result from user callback.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
189
DependentExtensions/portaudio_v18_1/pa_common/pa_host.h
Normal file
189
DependentExtensions/portaudio_v18_1/pa_common/pa_host.h
Normal file
@ -0,0 +1,189 @@
|
||||
#ifndef PA_HOST_H
|
||||
#define PA_HOST_H
|
||||
|
||||
/*
|
||||
* $Id: pa_host.h,v 1.3.4.1 2003/02/11 21:33:58 philburk 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. */
|
||||
|
||||
/* Begin user specified information. */
|
||||
uint32 past_FramesPerUserBuffer;
|
||||
uint32 past_NumUserBuffers;
|
||||
double past_SampleRate; /* Closest supported sample rate. */
|
||||
int past_NumInputChannels;
|
||||
int past_NumOutputChannels;
|
||||
PaDeviceID past_InputDeviceID;
|
||||
PaDeviceID past_OutputDeviceID;
|
||||
PaSampleFormat past_InputSampleFormat;
|
||||
PaSampleFormat past_OutputSampleFormat;
|
||||
PortAudioCallback *past_Callback;
|
||||
void *past_UserData;
|
||||
uint32 past_Flags;
|
||||
/* End user specified information. */
|
||||
|
||||
void *past_DeviceData;
|
||||
PaSampleFormat past_NativeOutputSampleFormat;
|
||||
PaSampleFormat past_NativeInputSampleFormat;
|
||||
|
||||
/* Flags for communicating between foreground and background. */
|
||||
volatile int past_IsActive; /* Background is still playing. */
|
||||
volatile int past_StopSoon; /* Background should keep playing when buffers empty. */
|
||||
volatile int past_StopNow; /* Background should stop playing now. */
|
||||
/* These buffers are used when the native format does not match the user format. */
|
||||
void *past_InputBuffer;
|
||||
uint32 past_InputBufferSize; /* Size in bytes of the input buffer. */
|
||||
void *past_OutputBuffer;
|
||||
uint32 past_OutputBufferSize;
|
||||
/* Measurements */
|
||||
uint32 past_NumCallbacks;
|
||||
PaTimestamp past_FrameCount; /* Frames output to buffer. */
|
||||
/* For measuring CPU utilization. */
|
||||
double past_AverageInsideCount;
|
||||
double past_AverageTotalCount;
|
||||
double past_Usage;
|
||||
int past_IfLastExitValid;
|
||||
/* Format Conversion */
|
||||
/* These are setup by PaConversion_Setup() */
|
||||
PortAudioConverter *past_InputConversionProc;
|
||||
int past_InputConversionSourceStride;
|
||||
int past_InputConversionTargetStride;
|
||||
PortAudioConverter *past_OutputConversionProc;
|
||||
int past_OutputConversionSourceStride;
|
||||
int past_OutputConversionTargetStride;
|
||||
}
|
||||
internalPortAudioStream;
|
||||
|
||||
/************************************************************************************/
|
||||
/******** These functions must be provided by a platform implementation. ************/
|
||||
/************************************************************************************/
|
||||
|
||||
PaError PaHost_Init( void );
|
||||
PaError PaHost_Term( void );
|
||||
|
||||
PaError PaHost_OpenStream( internalPortAudioStream *past );
|
||||
PaError PaHost_CloseStream( internalPortAudioStream *past );
|
||||
|
||||
PaError PaHost_StartOutput( internalPortAudioStream *past );
|
||||
PaError PaHost_StopOutput( internalPortAudioStream *past, int abort );
|
||||
PaError PaHost_StartInput( internalPortAudioStream *past );
|
||||
PaError PaHost_StopInput( internalPortAudioStream *past, int abort );
|
||||
PaError PaHost_StartEngine( internalPortAudioStream *past );
|
||||
PaError PaHost_StopEngine( internalPortAudioStream *past, int abort );
|
||||
PaError PaHost_StreamActive( internalPortAudioStream *past );
|
||||
|
||||
void *PaHost_AllocateFastMemory( 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 */
|
||||
806
DependentExtensions/portaudio_v18_1/pa_common/pa_lib.c
Normal file
806
DependentExtensions/portaudio_v18_1/pa_common/pa_lib.c
Normal file
@ -0,0 +1,806 @@
|
||||
/*
|
||||
* $Id: pa_lib.c,v 1.3.4.2 2003/03/15 02:50:14 pieter 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) ?
|
||||
(void*)nativeOutputBuffer : past->past_OutputBuffer;
|
||||
}
|
||||
/*
|
||||
AddTraceMessage("Pa_CallConvertInt16: inputBuffer = ", (int) inputBuffer );
|
||||
AddTraceMessage("Pa_CallConvertInt16: outputBuffer = ", (int) outputBuffer );
|
||||
*/
|
||||
/* Call user callback routine. */
|
||||
userResult = past->past_Callback(
|
||||
inputBuffer,
|
||||
outputBuffer,
|
||||
past->past_FramesPerUserBuffer,
|
||||
past->past_FrameCount,
|
||||
past->past_UserData );
|
||||
|
||||
past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;
|
||||
|
||||
/* Convert to native format if necessary. */
|
||||
if( outputBuffer != NULL )
|
||||
{
|
||||
unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels;
|
||||
switch(past->past_OutputSampleFormat)
|
||||
{
|
||||
case paFloat32:
|
||||
{
|
||||
float *outBufPtr = (float *) past->past_OutputBuffer;
|
||||
if( past->past_Flags & paDitherOff )
|
||||
{
|
||||
if( past->past_Flags & paClipOff ) /* NOTHING */
|
||||
{
|
||||
for( i=0; i<samplesPerBuffer; i++ )
|
||||
{
|
||||
*nativeOutputBuffer++ = (short) (outBufPtr[i] * (32767.0f));
|
||||
}
|
||||
}
|
||||
else /* CLIP */
|
||||
{
|
||||
for( i=0; i<samplesPerBuffer; i++ )
|
||||
{
|
||||
temp = (long)(outBufPtr[i] * 32767.0f);
|
||||
*nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If you dither then you have to clip because dithering could push the signal out of range! */
|
||||
for( i=0; i<samplesPerBuffer; i++ )
|
||||
{
|
||||
float dither = PaConvert_TriangularDither()*PA_DITHER_SCALE;
|
||||
float dithered = (outBufPtr[i] * (32767.0f)) + dither;
|
||||
temp = (long) (dithered);
|
||||
*nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case paInt32:
|
||||
{
|
||||
int *outBufPtr = (int *) past->past_OutputBuffer;
|
||||
if( past->past_Flags & paDitherOff )
|
||||
{
|
||||
for( i=0; i<samplesPerBuffer; i++ )
|
||||
{
|
||||
*nativeOutputBuffer++ = (short) (outBufPtr[i] >> 16 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i=0; i<samplesPerBuffer; i++ )
|
||||
{
|
||||
/* Shift one bit down before dithering so that we have room for overflow from add. */
|
||||
temp = (outBufPtr[i] >> 1) + PaConvert_TriangularDither();
|
||||
temp = temp >> 15;
|
||||
*nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case paInt8:
|
||||
{
|
||||
char *outBufPtr = (char *) past->past_OutputBuffer;
|
||||
for( i=0; i<samplesPerBuffer; i++ )
|
||||
{
|
||||
*nativeOutputBuffer++ = (short) (((int)outBufPtr[i]) << 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case paUInt8:
|
||||
{
|
||||
unsigned char *outBufPtr = (unsigned char *) past->past_OutputBuffer;
|
||||
for( i=0; i<samplesPerBuffer; i++ )
|
||||
{
|
||||
*nativeOutputBuffer++ = (short) (((int)(outBufPtr[i] - 0x80)) << 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return userResult;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
PaError Pa_Initialize( void )
|
||||
{
|
||||
if( gInitCount++ > 0 ) return paNoError;
|
||||
ResetTraceMessages();
|
||||
return PaHost_Init();
|
||||
}
|
||||
|
||||
PaError Pa_Terminate( void )
|
||||
{
|
||||
PaError result = paNoError;
|
||||
|
||||
if( gInitCount == 0 ) return paNoError;
|
||||
else if( --gInitCount == 0 )
|
||||
{
|
||||
result = PaHost_Term();
|
||||
DumpTraceMessages();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PaHost_IsInitialized()
|
||||
{
|
||||
return gInitCount;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
PaError Pa_GetSampleSize( PaSampleFormat format )
|
||||
{
|
||||
int size;
|
||||
switch(format )
|
||||
{
|
||||
|
||||
case paUInt8:
|
||||
case paInt8:
|
||||
size = 1;
|
||||
break;
|
||||
|
||||
case paInt16:
|
||||
size = 2;
|
||||
break;
|
||||
|
||||
case paPackedInt24:
|
||||
size = 3;
|
||||
break;
|
||||
|
||||
case paFloat32:
|
||||
case paInt32:
|
||||
case paInt24:
|
||||
size = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
size = paSampleFormatNotSupported;
|
||||
break;
|
||||
}
|
||||
return (PaError) size;
|
||||
}
|
||||
|
||||
|
||||
83
DependentExtensions/portaudio_v18_1/pa_common/pa_trace.c
Normal file
83
DependentExtensions/portaudio_v18_1/pa_common/pa_trace.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* $Id: pa_trace.c,v 1.1.1.1 2002/01/22 00:52:11 phil 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 TRACE_REALTIME_EVENTS
|
||||
|
||||
static char *traceTextArray[MAX_TRACE_RECORDS];
|
||||
static int traceIntArray[MAX_TRACE_RECORDS];
|
||||
static int traceIndex = 0;
|
||||
static int traceBlock = 0;
|
||||
|
||||
/*********************************************************************/
|
||||
void ResetTraceMessages()
|
||||
{
|
||||
traceIndex = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
void DumpTraceMessages()
|
||||
{
|
||||
int i;
|
||||
int numDump = (traceIndex < MAX_TRACE_RECORDS) ? traceIndex : MAX_TRACE_RECORDS;
|
||||
|
||||
printf("DumpTraceMessages: traceIndex = %d\n", traceIndex );
|
||||
for( i=0; i<numDump; i++ )
|
||||
{
|
||||
printf("%3d: %s = 0x%08X\n",
|
||||
i, traceTextArray[i], traceIntArray[i] );
|
||||
}
|
||||
ResetTraceMessages();
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
void AddTraceMessage( const char *msg, int data )
|
||||
{
|
||||
if( (traceIndex == MAX_TRACE_RECORDS) && (traceBlock == 0) )
|
||||
{
|
||||
traceBlock = 1;
|
||||
/* DumpTraceMessages(); */
|
||||
}
|
||||
else if( traceIndex < MAX_TRACE_RECORDS )
|
||||
{
|
||||
traceTextArray[traceIndex] = msg;
|
||||
traceIntArray[traceIndex] = data;
|
||||
traceIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
67
DependentExtensions/portaudio_v18_1/pa_common/pa_trace.h
Normal file
67
DependentExtensions/portaudio_v18_1/pa_common/pa_trace.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef PA_TRACE_H
|
||||
#define PA_TRACE_H
|
||||
/*
|
||||
* $Id: pa_trace.h,v 1.1.1.1 2002/01/22 00:52:11 phil 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.
|
||||
*/
|
||||
|
||||
|
||||
#define TRACE_REALTIME_EVENTS (0) /* Keep log of various real-time events. */
|
||||
#define MAX_TRACE_RECORDS (2048)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/************************************************************************************/
|
||||
/****************** Prototypes ******************************************************/
|
||||
/************************************************************************************/
|
||||
|
||||
#if TRACE_REALTIME_EVENTS
|
||||
|
||||
void DumpTraceMessages();
|
||||
void ResetTraceMessages();
|
||||
void AddTraceMessage( const char *msg, int data );
|
||||
|
||||
#else
|
||||
|
||||
#define AddTraceMessage(msg,data) /* noop */
|
||||
#define ResetTraceMessages() /* noop */
|
||||
#define DumpTraceMessages() /* noop */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* PA_TRACE_H */
|
||||
463
DependentExtensions/portaudio_v18_1/pa_common/portaudio.h
Normal file
463
DependentExtensions/portaudio_v18_1/pa_common/portaudio.h
Normal file
@ -0,0 +1,463 @@
|
||||
#ifndef PORT_AUDIO_H
|
||||
#define PORT_AUDIO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* $Id: portaudio.h,v 1.5 2002/03/26 18:04:22 philburk Exp $
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* PortAudio API Header File
|
||||
* Latest version available at: http://www.audiomulch.com/portaudio/
|
||||
*
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef int PaError;
|
||||
typedef enum {
|
||||
paNoError = 0,
|
||||
|
||||
paHostError = -10000,
|
||||
paInvalidChannelCount,
|
||||
paInvalidSampleRate,
|
||||
paInvalidDeviceId,
|
||||
paInvalidFlag,
|
||||
paSampleFormatNotSupported,
|
||||
paBadIODeviceCombination,
|
||||
paInsufficientMemory,
|
||||
paBufferTooBig,
|
||||
paBufferTooSmall,
|
||||
paNullCallback,
|
||||
paBadStreamPtr,
|
||||
paTimedOut,
|
||||
paInternalError,
|
||||
paDeviceUnavailable
|
||||
} PaErrorNum;
|
||||
|
||||
/*
|
||||
Pa_Initialize() is the library initialisation function - call this before
|
||||
using the library.
|
||||
|
||||
*/
|
||||
|
||||
PaError Pa_Initialize( void );
|
||||
|
||||
/*
|
||||
Pa_Terminate() is the library termination function - call this after
|
||||
using the library.
|
||||
|
||||
*/
|
||||
|
||||
PaError Pa_Terminate( void );
|
||||
|
||||
/*
|
||||
Pa_GetHostError() returns a host specific error code.
|
||||
This can be called after receiving a PortAudio error code of paHostError.
|
||||
|
||||
*/
|
||||
|
||||
long Pa_GetHostError( void );
|
||||
|
||||
/*
|
||||
Pa_GetErrorText() translates the supplied PortAudio error number
|
||||
into a human readable message.
|
||||
|
||||
*/
|
||||
|
||||
const char *Pa_GetErrorText( PaError errnum );
|
||||
|
||||
/*
|
||||
Sample formats
|
||||
|
||||
These are formats used to pass sound data between the callback and the
|
||||
stream. Each device has a "native" format which may be used when optimum
|
||||
efficiency or control over conversion is required.
|
||||
|
||||
Formats marked "always available" are supported (emulated) by all
|
||||
PortAudio implementations.
|
||||
|
||||
The floating point representation (paFloat32) uses +1.0 and -1.0 as the
|
||||
maximum and minimum respectively.
|
||||
|
||||
paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
|
||||
|
||||
*/
|
||||
|
||||
typedef 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))
|
||||
#define paCustomFormat ((PaSampleFormat) (1<<16))
|
||||
|
||||
/*
|
||||
Device enumeration mechanism.
|
||||
|
||||
Device ids range from 0 to Pa_CountDevices()-1.
|
||||
|
||||
Devices may support input, output or both.
|
||||
|
||||
*/
|
||||
|
||||
typedef int PaDeviceID;
|
||||
#define paNoDevice -1
|
||||
|
||||
int Pa_CountDevices( void );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int structVersion;
|
||||
const char *name;
|
||||
int maxInputChannels;
|
||||
int maxOutputChannels;
|
||||
/* Number of discrete rates, or -1 if range supported. */
|
||||
int numSampleRates;
|
||||
/* Array of supported sample rates, or {min,max} if range supported. */
|
||||
const double *sampleRates;
|
||||
PaSampleFormat nativeSampleFormats;
|
||||
}
|
||||
PaDeviceInfo;
|
||||
|
||||
/*
|
||||
Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID() return the
|
||||
default device ids for input and output respectively, or paNoDevice if
|
||||
no device is available.
|
||||
The result can be passed to Pa_OpenStream().
|
||||
|
||||
On the PC, the user can specify a default device by
|
||||
setting an environment variable. For example, to use device #1.
|
||||
|
||||
set PA_RECOMMENDED_OUTPUT_DEVICE=1
|
||||
|
||||
The user should first determine the available device ids by using
|
||||
the supplied application "pa_devs".
|
||||
|
||||
*/
|
||||
|
||||
PaDeviceID Pa_GetDefaultInputDeviceID( void );
|
||||
PaDeviceID Pa_GetDefaultOutputDeviceID( void );
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure
|
||||
for the device specified.
|
||||
If the device parameter is out of range the function returns NULL.
|
||||
|
||||
PortAudio manages the memory referenced by the returned pointer, the client
|
||||
must not manipulate or free the memory. The pointer is only guaranteed to be
|
||||
valid between calls to Pa_Initialize() and Pa_Terminate().
|
||||
|
||||
*/
|
||||
|
||||
const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID device );
|
||||
|
||||
/*
|
||||
PaTimestamp is used to represent a continuous sample clock with arbitrary
|
||||
start time that can be used for syncronization. The type is used for the
|
||||
outTime argument to the PortAudioCallback and as the result of Pa_StreamTime()
|
||||
|
||||
*/
|
||||
|
||||
typedef double PaTimestamp;
|
||||
|
||||
/*
|
||||
PortAudioCallback is implemented by PortAudio clients.
|
||||
|
||||
inputBuffer and outputBuffer are arrays of interleaved samples,
|
||||
the format, packing and number of channels used by the buffers are
|
||||
determined by parameters to Pa_OpenStream() (see below).
|
||||
|
||||
framesPerBuffer is the number of sample frames to be processed by the callback.
|
||||
|
||||
outTime is the time in samples when the buffer(s) processed by
|
||||
this callback will begin being played at the audio output.
|
||||
See also Pa_StreamTime()
|
||||
|
||||
userData is the value of a user supplied pointer passed to Pa_OpenStream()
|
||||
intended for storing synthesis data etc.
|
||||
|
||||
return value:
|
||||
The callback can return a non-zero value to stop the stream. This may be
|
||||
useful in applications such as soundfile players where a specific duration
|
||||
of output is required. However, it is not necessary to utilise this mechanism
|
||||
as StopStream() will also terminate the stream. A callback returning a
|
||||
non-zero value must fill the entire outputBuffer.
|
||||
|
||||
NOTE: None of the other stream functions may be called from within the
|
||||
callback function except for Pa_GetCPULoad().
|
||||
|
||||
*/
|
||||
|
||||
typedef int (PortAudioCallback)(
|
||||
void *inputBuffer, void *outputBuffer,
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#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;
|
||||
|
||||
/*
|
||||
A single PortAudioStream provides multiple channels of real-time
|
||||
input and output audio streaming to a client application.
|
||||
Pointers to PortAudioStream objects are passed between PortAudio functions.
|
||||
*/
|
||||
|
||||
typedef void PortAudioStream;
|
||||
#define PaStream PortAudioStream
|
||||
|
||||
/*
|
||||
Pa_OpenStream() opens a stream for either input, output or both.
|
||||
|
||||
stream is the address of a PortAudioStream pointer which will receive
|
||||
a pointer to the newly opened stream.
|
||||
|
||||
inputDevice is the id of the device used for input (see PaDeviceID above.)
|
||||
inputDevice may be paNoDevice to indicate that an input device is not required.
|
||||
|
||||
numInputChannels is the number of channels of sound to be delivered to the
|
||||
callback. It can range from 1 to the value of maxInputChannels in the
|
||||
PaDeviceInfo record for the device specified by the inputDevice parameter.
|
||||
If inputDevice is paNoDevice numInputChannels is ignored.
|
||||
|
||||
inputSampleFormat is the sample format of inputBuffer provided to the callback
|
||||
function. inputSampleFormat may be any of the formats described by the
|
||||
PaSampleFormat enumeration (see above). PortAudio guarantees support for
|
||||
the device's native formats (nativeSampleFormats in the device info record)
|
||||
and additionally 16 and 32 bit integer and 32 bit floating point formats.
|
||||
Support for other formats is implementation defined.
|
||||
|
||||
inputDriverInfo is a pointer to an optional driver specific data structure
|
||||
containing additional information for device setup or stream processing.
|
||||
inputDriverInfo is never required for correct operation. If not used
|
||||
inputDriverInfo should be NULL.
|
||||
|
||||
outputDevice is the id of the device used for output (see PaDeviceID above.)
|
||||
outputDevice may be paNoDevice to indicate that an output device is not required.
|
||||
|
||||
numOutputChannels is the number of channels of sound to be supplied by the
|
||||
callback. See the definition of numInputChannels above for more details.
|
||||
|
||||
outputSampleFormat is the sample format of the outputBuffer filled by the
|
||||
callback function. See the definition of inputSampleFormat above for more
|
||||
details.
|
||||
|
||||
outputDriverInfo is a pointer to an optional driver specific data structure
|
||||
containing additional information for device setup or stream processing.
|
||||
outputDriverInfo is never required for correct operation. If not used
|
||||
outputDriverInfo should be NULL.
|
||||
|
||||
sampleRate is the desired sampleRate. For full-duplex streams it is the
|
||||
sample rate for both input and output
|
||||
|
||||
framesPerBuffer is the length in sample frames of all internal sample buffers
|
||||
used for communication with platform specific audio routines. Wherever
|
||||
possible this corresponds to the framesPerBuffer parameter passed to the
|
||||
callback function.
|
||||
|
||||
numberOfBuffers is the number of buffers used for multibuffered communication
|
||||
with the platform specific audio routines. If you pass zero, then an optimum
|
||||
value will be chosen for you internally. This parameter is provided only
|
||||
as a guide - and does not imply that an implementation must use multibuffered
|
||||
i/o when reliable double buffering is available (such as SndPlayDoubleBuffer()
|
||||
on the Macintosh.)
|
||||
|
||||
streamFlags may contain a combination of flags ORed together.
|
||||
These flags modify the behaviour of the streaming process. Some flags may only
|
||||
be relevant to certain buffer formats.
|
||||
|
||||
callback is a pointer to a client supplied function that is responsible
|
||||
for processing and filling input and output buffers (see above for details.)
|
||||
|
||||
userData is a client supplied pointer which is passed to the callback
|
||||
function. It could for example, contain a pointer to instance data necessary
|
||||
for processing the audio buffers.
|
||||
|
||||
return value:
|
||||
Upon success Pa_OpenStream() returns PaNoError and places a pointer to a
|
||||
valid PortAudioStream in the stream argument. The stream is inactive (stopped).
|
||||
If a call to Pa_OpenStream() fails a non-zero error code is returned (see
|
||||
PaError above) and the value of stream is invalid.
|
||||
|
||||
*/
|
||||
|
||||
PaError Pa_OpenStream( PortAudioStream** stream,
|
||||
PaDeviceID inputDevice,
|
||||
int numInputChannels,
|
||||
PaSampleFormat inputSampleFormat,
|
||||
void *inputDriverInfo,
|
||||
PaDeviceID outputDevice,
|
||||
int numOutputChannels,
|
||||
PaSampleFormat outputSampleFormat,
|
||||
void *outputDriverInfo,
|
||||
double sampleRate,
|
||||
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 output devices. Most parameters have identical meaning
|
||||
to their Pa_OpenStream() counterparts, with the following exceptions:
|
||||
|
||||
If either numInputChannels or numOutputChannels is 0 the respective device
|
||||
is not opened. This has the same effect as passing paNoDevice in the device
|
||||
arguments to Pa_OpenStream().
|
||||
|
||||
sampleFormat applies to both the input and output buffers.
|
||||
|
||||
*/
|
||||
|
||||
PaError Pa_OpenDefaultStream( PortAudioStream** stream,
|
||||
int numInputChannels,
|
||||
int numOutputChannels,
|
||||
PaSampleFormat sampleFormat,
|
||||
double sampleRate,
|
||||
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 (1) when the stream is active (ie playing
|
||||
or recording audio), zero (0) when not playing, or a negative error number
|
||||
if the stream is invalid.
|
||||
The stream is active between calls to Pa_StartStream() and Pa_StopStream(),
|
||||
but may also become inactive if the callback returns a non-zero value.
|
||||
In the latter case, the stream is considered inactive after the last
|
||||
buffer has finished playing.
|
||||
|
||||
*/
|
||||
|
||||
PaError Pa_StreamActive( PortAudioStream *stream );
|
||||
|
||||
/*
|
||||
Pa_StreamTime() returns the current output time in samples for the stream.
|
||||
This time may be used as a time reference (for example synchronizing audio to
|
||||
MIDI).
|
||||
|
||||
*/
|
||||
|
||||
PaTimestamp Pa_StreamTime( PortAudioStream *stream );
|
||||
|
||||
/*
|
||||
Pa_GetCPULoad() returns the CPU Load for the stream.
|
||||
The "CPU Load" is a fraction of total CPU time consumed by the stream's
|
||||
audio processing routines including, but not limited to the client supplied
|
||||
callback.
|
||||
A value of 0.5 would imply that PortAudio and the sound generating
|
||||
callback was consuming roughly 50% of the available CPU time.
|
||||
This function may be called from the callback function or the application.
|
||||
|
||||
*/
|
||||
|
||||
double Pa_GetCPULoad( PortAudioStream* stream );
|
||||
|
||||
/*
|
||||
Pa_GetMinNumBuffers() returns the minimum number of buffers required by
|
||||
the current host based on minimum latency.
|
||||
On the PC, for the DirectSound implementation, latency can be optionally set
|
||||
by user by setting an environment variable.
|
||||
For example, to set latency to 200 msec, put:
|
||||
|
||||
set PA_MIN_LATENCY_MSEC=200
|
||||
|
||||
in the AUTOEXEC.BAT file and reboot.
|
||||
If the environment variable is not set, then the latency will be determined
|
||||
based on the OS. Windows NT has higher latency than Win95.
|
||||
|
||||
*/
|
||||
|
||||
int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate );
|
||||
|
||||
/*
|
||||
Pa_Sleep() puts the caller to sleep for at least 'msec' milliseconds.
|
||||
You may sleep longer than the requested time so don't rely on this for
|
||||
accurate musical timing.
|
||||
|
||||
Pa_Sleep() is provided as a convenience for authors of portable code (such as
|
||||
the tests and examples in the PortAudio distribution.)
|
||||
|
||||
*/
|
||||
|
||||
void Pa_Sleep( long msec );
|
||||
|
||||
/*
|
||||
Pa_GetSampleSize() returns the size in bytes of a single sample in the
|
||||
supplied PaSampleFormat, or paSampleFormatNotSupported if the format is
|
||||
no supported.
|
||||
|
||||
*/
|
||||
|
||||
PaError Pa_GetSampleSize( PaSampleFormat format );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* PORT_AUDIO_H */
|
||||
184
DependentExtensions/portaudio_v18_1/pa_dll_switch/PaDllEntry.h
Normal file
184
DependentExtensions/portaudio_v18_1/pa_dll_switch/PaDllEntry.h
Normal file
@ -0,0 +1,184 @@
|
||||
|
||||
/*
|
||||
* 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__
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
From: "Tim Flohrer" <flohrer@zplane.de>
|
||||
To: "Phil Burk" <philburk@softsynth.com>
|
||||
Subject: Re: suggestion - multiple backends
|
||||
Date: Friday, August 17, 2001 7:48 AM
|
||||
|
||||
Hi Phil,
|
||||
|
||||
here is what I did:
|
||||
|
||||
1. I changed the pa_lib.c and portaudio.h in order to provide a dll api
|
||||
if wanted
|
||||
|
||||
2. in my application I had a couple of function pointers defined (see
|
||||
excerpt loadPA_DLL.cpp) that get their value when the dll is loaded
|
||||
|
||||
3. all other files that use the PortAudio-functions had the PaDllEntry.h
|
||||
included
|
||||
|
||||
I extracted the loadPA_DLL.cpp out of my source so I hope it's
|
||||
understandable somehow. If not feel free to ask.
|
||||
|
||||
There are also functions for checking if DirectX is available. I am not
|
||||
really sure if this is 100% correct, but I noticed that on NT systems it
|
||||
is missing the function no. 7 in the dsound.dll so I just check if it's
|
||||
there ;O) On the other hand this doesn't tell you if Dsound is emulated
|
||||
or not (Dsound gets really bad when emulated, but i suppose you know that).
|
||||
Hope I didn't forget anything
|
||||
|
||||
cheers
|
||||
|
||||
tim
|
||||
|
||||
--
|
||||
tim flohrer
|
||||
flohrer@zplane.de
|
||||
|
||||
zplane.development
|
||||
holsteinische str. 39-42
|
||||
12161 berlin
|
||||
fon: +49.30.854 09 15.0
|
||||
fax: +49.30.854 09 15.5
|
||||
|
||||
203
DependentExtensions/portaudio_v18_1/pa_dll_switch/loadPA_DLL.cpp
Normal file
203
DependentExtensions/portaudio_v18_1/pa_dll_switch/loadPA_DLL.cpp
Normal file
@ -0,0 +1,203 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
...
|
||||
827
DependentExtensions/portaudio_v18_1/pa_dll_switch/pa_lib.c
Normal file
827
DependentExtensions/portaudio_v18_1/pa_dll_switch/pa_lib.c
Normal file
@ -0,0 +1,827 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
439
DependentExtensions/portaudio_v18_1/pa_dll_switch/portaudio.h
Normal file
439
DependentExtensions/portaudio_v18_1/pa_dll_switch/portaudio.h
Normal file
@ -0,0 +1,439 @@
|
||||
#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 */
|
||||
1687
DependentExtensions/portaudio_v18_1/pa_mac/pa_mac.c
Normal file
1687
DependentExtensions/portaudio_v18_1/pa_mac/pa_mac.c
Normal file
File diff suppressed because it is too large
Load Diff
34
DependentExtensions/portaudio_v18_1/pa_mac_core/notes.txt
Normal file
34
DependentExtensions/portaudio_v18_1/pa_mac_core/notes.txt
Normal file
@ -0,0 +1,34 @@
|
||||
Notes on Core Audio Implementation of PortAudio
|
||||
|
||||
by Phil Burk and Darren Gibbs
|
||||
|
||||
Document last updated October 18, 2002
|
||||
|
||||
WHAT WORKS
|
||||
|
||||
Output with very low latency, <10 msec.
|
||||
Half duplex input or output.
|
||||
Full duplex
|
||||
The paFLoat32, paInt16, paInt8, paUInt8 sample formats.
|
||||
Pa_GetCPULoad()
|
||||
Pa_StreamTime()
|
||||
|
||||
KNOWN BUGS OR LIMITATIONS
|
||||
|
||||
The iMic supports multiple sample rates.
|
||||
But there is a bug when changing sample rates:
|
||||
Run patest_record.c at rate A - it works.
|
||||
Then run patest_record.c at rate B - it FAIL!
|
||||
Then run patest_record.c again at rate B - it works!
|
||||
|
||||
|
||||
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.
|
||||
2203
DependentExtensions/portaudio_v18_1/pa_mac_core/pa_mac_core.c
Normal file
2203
DependentExtensions/portaudio_v18_1/pa_mac_core/pa_mac_core.c
Normal file
File diff suppressed because it is too large
Load Diff
63
DependentExtensions/portaudio_v18_1/pa_sgi/Makefile
Normal file
63
DependentExtensions/portaudio_v18_1/pa_sgi/Makefile
Normal file
@ -0,0 +1,63 @@
|
||||
# Makefile for pa_sgi. PortAudio for Silicon Graphics IRIX 6.2-6.5.
|
||||
# Pieter suurmond, march 15, 2003. (pa-V18-patch).
|
||||
# Tested under IRIX 6.5 with both GCC and MIPS compilers.
|
||||
# Based on SGI-specific sproc()-method to spawn children, not on POSIX-threads.
|
||||
|
||||
# Choose compiler in combination with options:
|
||||
|
||||
CC = cc
|
||||
CFLAGS = -O2
|
||||
|
||||
# Possible options with MIPSpro compiler are: -32, -o32, -n32, -64,
|
||||
# -mips1, -mips2, -mips3, -mips4, etc. Use -g, -g2, -g3 for debugging.
|
||||
# For GCC, use -Wall. And use for example -O2 or -O3 for better optimization:
|
||||
|
||||
#CC = gcc
|
||||
#CFLAGS = -O2 -Wall
|
||||
|
||||
# Instead of "-lpthread", as with linux, just the audio- and math-library for SGI:
|
||||
|
||||
LIBS = -laudio -lm
|
||||
|
||||
# So sourcefiles can find included headerfiles in pa_common:
|
||||
CDEFINES = -I../pa_common
|
||||
|
||||
PASRC = ../pa_common/pa_lib.c pa_sgi.c
|
||||
PAINC = ../pa_common/portaudio.h
|
||||
|
||||
# Tests performed on SGI Indy with R5000 @ 180MHz running IRIX 6.5:
|
||||
# Used GCC compiler version 3.0.4. and MIPS.
|
||||
|
||||
TESTC = $(PASRC) ../pa_tests/patest_record.c ## OK GCC march 2003 (MIPS sees errors in patest_record.c, refuses compilation).
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_latency.c ## OK GCC march 2003. (MIPS doesn't like //)
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_longsine.c ## OK GCC march 2003.
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_wire.c ## OK GCC Click free now. march 2003.
|
||||
#TESTC = $(PASRC) ../pa_tests/pa_fuzz.c ## OK GCC march 2003.
|
||||
|
||||
#TESTC = $(PASRC) ../pa_tests/pa_devs.c # Never knew my Indy had 16 input- and output-channels!
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_saw.c ## - Pa_sleep doesn't work anymore?!
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_sine.c # - Pa_sleep doesn't work anymore?!
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_many.c ## - Pa_sleep doesn't work anymore?!
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_sine_time.c ## Silence for 2 seconds doesn't work, sine sounds ok.
|
||||
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_sine8.c ## Silence for 2 seconds doesn't work, sine sounds ok.
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_leftright.c # OK GCC and MIPS-CC march 2003.
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_pink.c ## OK GCC march 2003
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_clip.c #
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_stop.c # MIPS doesn't like patest_stop.c Worked before but now
|
||||
# error AL_BAD_QSIZE on IRIX 6.5 (with GCC).
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_dither.c #
|
||||
#TESTC = $(PASRC) ../pa_tests/patest_sync.c # I don't hear the 6th beep, not really in sync @500ms lat.
|
||||
#TESTC = $(PASRC) ../pa_tests/paqa_devs.c # A lot of error messages but no coredump.
|
||||
#TESTC = $(PASRC) ../pa_tests/paqa_errs.c # Segmentation fault (core dumped)!
|
||||
|
||||
TESTH = $(PAINC)
|
||||
|
||||
all: patest
|
||||
|
||||
patest: $(TESTC) $(TESTH) Makefile
|
||||
$(CC) $(CFLAGS) $(TESTC) $(CDEFINES) $(LIBS) -o patest
|
||||
|
||||
run: patest
|
||||
./patest
|
||||
|
||||
1069
DependentExtensions/portaudio_v18_1/pa_sgi/pa_sgi.c
Normal file
1069
DependentExtensions/portaudio_v18_1/pa_sgi/pa_sgi.c
Normal file
File diff suppressed because it is too large
Load Diff
52
DependentExtensions/portaudio_v18_1/pa_sgi/pthread-Makefile
Normal file
52
DependentExtensions/portaudio_v18_1/pa_sgi/pthread-Makefile
Normal file
@ -0,0 +1,52 @@
|
||||
# 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
|
||||
|
||||
908
DependentExtensions/portaudio_v18_1/pa_sgi/pthread-pa_sgi.c
Normal file
908
DependentExtensions/portaudio_v18_1/pa_sgi/pthread-pa_sgi.c
Normal file
@ -0,0 +1,908 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
131
DependentExtensions/portaudio_v18_1/pa_tests/debug_convert.c
Normal file
131
DependentExtensions/portaudio_v18_1/pa_tests/debug_convert.c
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* $Id: debug_convert.c,v 1.1 2002/03/21 00:44:35 philburk 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;
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* $Id: debug_dither_calc.c,v 1.1 2002/03/21 00:44:35 philburk 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 );
|
||||
}
|
||||
183
DependentExtensions/portaudio_v18_1/pa_tests/debug_dual.c
Normal file
183
DependentExtensions/portaudio_v18_1/pa_tests/debug_dual.c
Normal file
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* $Id: debug_dual.c,v 1.1.1.1 2002/01/22 00:52:27 phil 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;
|
||||
}
|
||||
187
DependentExtensions/portaudio_v18_1/pa_tests/debug_multi_in.c
Normal file
187
DependentExtensions/portaudio_v18_1/pa_tests/debug_multi_in.c
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* $Id: debug_multi_in.c,v 1.1.1.1.4.3 2003/04/16 19:07:56 philburk 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 (44100)
|
||||
#define FRAMES_PER_BUFFER (256)
|
||||
#define MIN_LATENCY_MSEC (400)
|
||||
#define MAX_INPUT_CHANNELS (9999)
|
||||
#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;
|
||||
(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 stereo 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;
|
||||
}
|
||||
printf("Input Device name is %s\n", pdi->name );
|
||||
printf("Input Device has %d channels.\n", pdi->maxInputChannels);
|
||||
if( pdi->maxInputChannels <= MAX_INPUT_CHANNELS )
|
||||
{
|
||||
data.numChannels = pdi->maxInputChannels;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.numChannels = MAX_INPUT_CHANNELS;
|
||||
printf("Only use %d channels.\n", MAX_INPUT_CHANNELS );
|
||||
}
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
inputDevice,
|
||||
data.numChannels,
|
||||
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;
|
||||
}
|
||||
139
DependentExtensions/portaudio_v18_1/pa_tests/debug_multi_out.c
Normal file
139
DependentExtensions/portaudio_v18_1/pa_tests/debug_multi_out.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* $Id: debug_multi_out.c,v 1.3.4.1 2003/04/07 20:00:57 philburk Exp $
|
||||
* debug_multi_out.c
|
||||
* Output different numbers on each channels for step debugging,
|
||||
* 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;
|
||||
}
|
||||
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) ((channelIndex + 1) * 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PortAudioStream *stream;
|
||||
PaError err;
|
||||
const PaDeviceInfo *pdi;
|
||||
paTestData data = {0};
|
||||
printf("PortAudio Test: output channel number 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;
|
||||
}
|
||||
338
DependentExtensions/portaudio_v18_1/pa_tests/debug_record.c
Normal file
338
DependentExtensions/portaudio_v18_1/pa_tests/debug_record.c
Normal file
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* $Id: debug_record.c,v 1.3.4.3 2003/03/06 06:09:20 philburk 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 (44100)
|
||||
#define NUM_SECONDS (6)
|
||||
#define NUM_CHANNELS (2)
|
||||
#define FRAMES_PER_BUFFER (64)
|
||||
/* #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 0
|
||||
#define PA_SAMPLE_TYPE paInt32
|
||||
typedef long SAMPLE;
|
||||
#define SAMPLE_SILENCE (0)
|
||||
|
||||
#elif 0
|
||||
#define PA_SAMPLE_TYPE paInt16
|
||||
typedef short SAMPLE;
|
||||
#define SAMPLE_SILENCE (0)
|
||||
|
||||
#elif 0
|
||||
#define PA_SAMPLE_TYPE paInt8
|
||||
typedef char SAMPLE;
|
||||
#define SAMPLE_SILENCE (0)
|
||||
|
||||
#else
|
||||
#define PA_SAMPLE_TYPE paUInt8
|
||||
typedef unsigned char SAMPLE;
|
||||
#define SAMPLE_SILENCE (128)
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int frameIndex; /* Index into sample array. */
|
||||
int maxFrameIndex;
|
||||
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 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
framesToCalc = framesPerBuffer;
|
||||
finished = 0;
|
||||
}
|
||||
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 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*wptr++ = *rptr++; /* left */
|
||||
if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */
|
||||
}
|
||||
data->frameIndex += framesPerBuffer;
|
||||
finished = 0;
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PortAudioStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
int totalFrames;
|
||||
int numSamples;
|
||||
int numBytes;
|
||||
SAMPLE max, average, val;
|
||||
|
||||
printf("debug_record.c, sampleRate = %d, numChannels = %d\n",
|
||||
SAMPLE_RATE, NUM_CHANNELS );
|
||||
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_GetDefaultInputDeviceID(),
|
||||
NUM_CHANNELS, /* stereo input */
|
||||
PA_SAMPLE_TYPE,
|
||||
NULL,
|
||||
paNoDevice,
|
||||
0,
|
||||
PA_SAMPLE_TYPE,
|
||||
NULL,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER, /* frames per buffer */
|
||||
0, /* number of buffers, if zero then use default minimum */
|
||||
0, //paDitherOff, /* flags */
|
||||
recordCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
printf("Start recording!!\n"); fflush(stdout);
|
||||
|
||||
while( Pa_StreamActive( stream ) )
|
||||
{
|
||||
Pa_Sleep(1000);
|
||||
printf("index = %d\n", data.frameIndex ); fflush(stdout);
|
||||
}
|
||||
printf("Stop recording!!\n"); 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", (double) max );
|
||||
printf("sample average = %f\n", (double) average );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("sample max amplitude = %d\n", (int) max );
|
||||
printf("sample average = %d\n", (int) 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,
|
||||
NULL,
|
||||
Pa_GetDefaultOutputDeviceID(),
|
||||
NUM_CHANNELS, /* 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,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
if( stream )
|
||||
{
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
printf("Start playback!!\n"); fflush(stdout);
|
||||
|
||||
while( Pa_StreamActive( stream ) )
|
||||
{
|
||||
Pa_Sleep(1000);
|
||||
printf("index = %d\n", data.frameIndex ); fflush(stdout);
|
||||
}
|
||||
|
||||
printf("Stop playback!!\n"); fflush(stdout);
|
||||
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;
|
||||
}
|
||||
@ -0,0 +1,351 @@
|
||||
/*
|
||||
* $Id: debug_record_reuse.c,v 1.1 2002/05/02 20:16:29 philburk 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;
|
||||
}
|
||||
201
DependentExtensions/portaudio_v18_1/pa_tests/debug_sine.c
Normal file
201
DependentExtensions/portaudio_v18_1/pa_tests/debug_sine.c
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* $Id: debug_sine.c,v 1.2.4.2 2003/03/06 06:09:20 philburk 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)
|
||||
|
||||
#define MSEC_PER_BUFFER (1000 * FRAMES_PER_BUFFER / SAMPLE_RATE)
|
||||
|
||||
#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 */
|
||||
}
|
||||
// Pa_Sleep( 3 * MSEC_PER_BUFFER / 4 );
|
||||
// Pa_Sleep( MSEC_PER_BUFFER / 3 );
|
||||
|
||||
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 );
|
||||
printf("MSEC_PER_BUFFER = %d\n", MSEC_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
|
||||
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;
|
||||
}
|
||||
157
DependentExtensions/portaudio_v18_1/pa_tests/debug_sine_amp.c
Normal file
157
DependentExtensions/portaudio_v18_1/pa_tests/debug_sine_amp.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* $Id: debug_sine_amp.c,v 1.1 2002/03/21 00:44:35 philburk 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;
|
||||
}
|
||||
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* $Id: debug_sine_formats.c,v 1.1 2002/03/21 00:44:35 philburk 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;
|
||||
}
|
||||
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* $Id: debug_sine_getchar.c,v 1.1.2.2 2003/04/10 23:09:40 philburk Exp $
|
||||
*
|
||||
* Play a sine wave using the Portable Audio api until ENTER hit.
|
||||
*
|
||||
* 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 (48000)
|
||||
#define AMPLITUDE (0.3)
|
||||
#define FRAMES_PER_BUFFER (64)
|
||||
#define OUTPUT_DEVICE Pa_GetDefaultOutputDeviceID()
|
||||
//#define OUTPUT_DEVICE (2)
|
||||
|
||||
#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 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;
|
||||
}
|
||||
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, devID = %d\n",
|
||||
SAMPLE_RATE, FRAMES_PER_BUFFER, OUTPUT_DEVICE);
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) (AMPLITUDE * 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,
|
||||
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;
|
||||
printf("Press ENTER to stop.\n" ); fflush(stdout);
|
||||
getchar();
|
||||
|
||||
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;
|
||||
}
|
||||
265
DependentExtensions/portaudio_v18_1/pa_tests/debug_srate.c
Normal file
265
DependentExtensions/portaudio_v18_1/pa_tests/debug_srate.c
Normal file
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* $Id: debug_srate.c,v 1.1 2002/05/02 20:16:29 philburk 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;
|
||||
}
|
||||
114
DependentExtensions/portaudio_v18_1/pa_tests/debug_test1.c
Normal file
114
DependentExtensions/portaudio_v18_1/pa_tests/debug_test1.c
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* $Id: debug_test1.c,v 1.1.1.1 2002/01/22 00:52:30 phil 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;
|
||||
}
|
||||
99
DependentExtensions/portaudio_v18_1/pa_tests/pa_devs.c
Normal file
99
DependentExtensions/portaudio_v18_1/pa_tests/pa_devs.c
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* $Id: pa_devs.c,v 1.1.1.1.4.1 2003/02/11 21:41:32 philburk 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"
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
int i,j;
|
||||
int numDevices;
|
||||
const PaDeviceInfo *pdi;
|
||||
PaError err;
|
||||
Pa_Initialize();
|
||||
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++ )
|
||||
{
|
||||
pdi = Pa_GetDeviceInfo( i );
|
||||
printf("---------------------------------------------- #%d", i );
|
||||
if( i == Pa_GetDefaultInputDeviceID() ) printf(" DefaultInput");
|
||||
if( i == Pa_GetDefaultOutputDeviceID() ) printf(" DefaultOutput");
|
||||
printf("\nName = %s\n", pdi->name );
|
||||
printf("Max Inputs = %d", pdi->maxInputChannels );
|
||||
printf(", Max Outputs = %d\n", pdi->maxOutputChannels );
|
||||
if( pdi->numSampleRates == -1 )
|
||||
{
|
||||
printf("Sample Rate Range = %f to %f\n", pdi->sampleRates[0], pdi->sampleRates[1] );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Sample Rates =");
|
||||
for( j=0; j<pdi->numSampleRates; j++ )
|
||||
{
|
||||
printf(" %8.2f,", pdi->sampleRates[j] );
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("Native Sample Formats = ");
|
||||
if( pdi->nativeSampleFormats & paInt8 ) printf("paInt8, ");
|
||||
if( pdi->nativeSampleFormats & paUInt8 ) printf("paUInt8, ");
|
||||
if( pdi->nativeSampleFormats & paInt16 ) printf("paInt16, ");
|
||||
if( pdi->nativeSampleFormats & paInt32 ) printf("paInt32, ");
|
||||
if( pdi->nativeSampleFormats & paFloat32 ) printf("paFloat32, ");
|
||||
if( pdi->nativeSampleFormats & paInt24 ) printf("paInt24, ");
|
||||
if( pdi->nativeSampleFormats & paPackedInt24 ) printf("paPackedInt24, ");
|
||||
printf("\n");
|
||||
}
|
||||
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;
|
||||
}
|
||||
156
DependentExtensions/portaudio_v18_1/pa_tests/pa_fuzz.c
Normal file
156
DependentExtensions/portaudio_v18_1/pa_tests/pa_fuzz.c
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* $Id: pa_fuzz.c,v 1.1.1.1.4.1 2003/02/11 21:41:32 philburk 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,
|
||||
PaTimestamp outTime, 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,
|
||||
PaTimestamp outTime, void *userData )
|
||||
{
|
||||
SAMPLE *out = (SAMPLE*)outputBuffer;
|
||||
SAMPLE *in = (SAMPLE*)inputBuffer;
|
||||
unsigned int i;
|
||||
(void) outTime; /* Prevent unused variable warnings. */
|
||||
(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 0;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PortAudioStream *stream;
|
||||
PaError err;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
Pa_GetDefaultInputDeviceID(), /* default output device */
|
||||
2, /* stereo input */
|
||||
PA_SAMPLE_TYPE,
|
||||
NULL,
|
||||
Pa_GetDefaultOutputDeviceID(), /* default output device */
|
||||
2, /* stereo output */
|
||||
PA_SAMPLE_TYPE,
|
||||
NULL,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
0, /* number of buffers, if zero then use default minimum */
|
||||
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");
|
||||
fflush(stdout);
|
||||
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;
|
||||
}
|
||||
172
DependentExtensions/portaudio_v18_1/pa_tests/pa_minlat.c
Normal file
172
DependentExtensions/portaudio_v18_1/pa_tests/pa_minlat.c
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* $Id: pa_minlat.c,v 1.4 2002/04/30 18:19:00 philburk 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 (64)
|
||||
|
||||
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 )
|
||||
{
|
||||
PortAudioStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int go;
|
||||
int numBuffers = 0;
|
||||
int minBuffers = 0;
|
||||
int framesPerBuffer;
|
||||
double sampleRate = 44100.0;
|
||||
char str[256];
|
||||
printf("paminlat - Determine minimum latency for your computer.\n");
|
||||
printf(" usage: paminlat {framesPerBuffer}\n");
|
||||
printf(" for example: paminlat 256\n");
|
||||
printf("Adjust your stereo until you hear a smooth tone in each speaker.\n");
|
||||
printf("Then try to find the smallest number of buffers 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;
|
||||
/* Ask PortAudio for the recommended minimum number of buffers. */
|
||||
numBuffers = minBuffers = Pa_GetMinNumBuffers( framesPerBuffer, sampleRate );
|
||||
printf("NumBuffers set to %d based on a call to Pa_GetMinNumBuffers()\n", numBuffers );
|
||||
/* Try different numBuffers in a loop. */
|
||||
go = 1;
|
||||
while( go )
|
||||
{
|
||||
|
||||
printf("Latency = framesPerBuffer * numBuffers = %d * %d = %d frames = %d msecs.\n",
|
||||
framesPerBuffer, numBuffers, framesPerBuffer*numBuffers,
|
||||
(int)((1000 * framesPerBuffer * numBuffers) / sampleRate) );
|
||||
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,
|
||||
sampleRate,
|
||||
framesPerBuffer,
|
||||
numBuffers, /* number of buffers */
|
||||
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 number of buffers. */
|
||||
printf("\nMove windows around to see if the sound glitches.\n");
|
||||
printf("NumBuffers currently %d, enter new number, or 'q' to quit: ", numBuffers );
|
||||
gets( str );
|
||||
if( str[0] == 'q' ) go = 0;
|
||||
else
|
||||
{
|
||||
numBuffers = atol( str );
|
||||
if( numBuffers < minBuffers )
|
||||
{
|
||||
printf( "numBuffers below minimum of %d! Set to minimum!!!\n", minBuffers );
|
||||
numBuffers = minBuffers;
|
||||
}
|
||||
}
|
||||
/* 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 ) );
|
||||
}
|
||||
322
DependentExtensions/portaudio_v18_1/pa_tests/paqa_devs.c
Normal file
322
DependentExtensions/portaudio_v18_1/pa_tests/paqa_devs.c
Normal file
@ -0,0 +1,322 @@
|
||||
/*
|
||||
* $Id: paqa_devs.c,v 1.1.1.1.4.1 2003/02/11 21:41:32 philburk 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 simple 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(34567.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 ); /* */
|
||||
}
|
||||
/*******************************************************************/
|
||||
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);
|
||||
fflush(stdout);
|
||||
/* 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);
|
||||
fflush(stdout);
|
||||
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 );
|
||||
fflush(stdout);
|
||||
return result;
|
||||
}
|
||||
330
DependentExtensions/portaudio_v18_1/pa_tests/paqa_errs.c
Normal file
330
DependentExtensions/portaudio_v18_1/pa_tests/paqa_errs.c
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* $Id: paqa_errs.c,v 1.2.4.1 2003/02/11 21:41:32 philburk 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( msg, _exp) \
|
||||
do \
|
||||
{ \
|
||||
if ((_exp)) {\
|
||||
gNumPassed++; \
|
||||
} \
|
||||
else { \
|
||||
printf("\nERROR %s\n - 0x%x - %s for %s\n", (msg), result, Pa_GetErrorText(result), #_exp ); \
|
||||
gNumFailed++; \
|
||||
goto error; \
|
||||
} \
|
||||
} while(0)
|
||||
#define HOPEFOR( msg, _exp) \
|
||||
do \
|
||||
{ \
|
||||
if ((_exp)) {\
|
||||
gNumPassed++; \
|
||||
} \
|
||||
else { \
|
||||
printf("\nERROR %s\n - 0x%x - %s for %s\n", (msg), 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( "init", ((result=Pa_Initialize()) == 0) );
|
||||
TestBadActions();
|
||||
TestBadOpens();
|
||||
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 1 /* 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( "TestBadActions", ((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( "start", ((result = Pa_StartStream( NULL )) == paBadStreamPtr) );
|
||||
HOPEFOR( "stop", ((result = Pa_StopStream( NULL )) == paBadStreamPtr) );
|
||||
HOPEFOR( "active?", ((result = Pa_StreamActive( NULL )) == paBadStreamPtr) );
|
||||
HOPEFOR( "close", ((result = Pa_CloseStream( NULL )) == paBadStreamPtr) );
|
||||
HOPEFOR( "time?", ((result = (PaError)Pa_StreamTime( NULL )) != 0) );
|
||||
HOPEFOR( "CPULoad?", ((result = (PaError)Pa_GetCPULoad( NULL )) != 0) );
|
||||
error:
|
||||
if( stream != NULL ) Pa_CloseStream( stream );
|
||||
return result;
|
||||
}
|
||||
114
DependentExtensions/portaudio_v18_1/pa_tests/patest1.c
Normal file
114
DependentExtensions/portaudio_v18_1/pa_tests/patest1.c
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
$Id: patest1.c,v 1.1.1.1 2002/01/22 00:52:33 phil 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,
|
||||
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;
|
||||
/* 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_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 * 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_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;
|
||||
}
|
||||
180
DependentExtensions/portaudio_v18_1/pa_tests/patest_buffer.c
Normal file
180
DependentExtensions/portaudio_v18_1/pa_tests/patest_buffer.c
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* $Id: patest_buffer.c,v 1.1.1.1.4.1 2003/02/11 21:41:32 philburk 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 paSineCallback( 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 paSineCallback( 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 )
|
||||
{
|
||||
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) (30000.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 */
|
||||
paSineCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
printf("Waiting for sound to finish.\n");
|
||||
fflush(stdout);
|
||||
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;
|
||||
}
|
||||
156
DependentExtensions/portaudio_v18_1/pa_tests/patest_clip.c
Normal file
156
DependentExtensions/portaudio_v18_1/pa_tests/patest_clip.c
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* $Id: patest_clip.c,v 1.1.1.1 2002/01/22 00:52:34 phil 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;
|
||||
}
|
||||
152
DependentExtensions/portaudio_v18_1/pa_tests/patest_dither.c
Normal file
152
DependentExtensions/portaudio_v18_1/pa_tests/patest_dither.c
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* $Id: patest_dither.c,v 1.2 2002/03/21 00:58:45 philburk 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;
|
||||
}
|
||||
153
DependentExtensions/portaudio_v18_1/pa_tests/patest_hang.c
Normal file
153
DependentExtensions/portaudio_v18_1/pa_tests/patest_hang.c
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* $Id: patest_hang.c,v 1.1.4.1 2003/02/11 21:41:32 philburk 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;
|
||||
fflush(stdout);
|
||||
Pa_Sleep( ((i<1000) ? 1000 : i) );
|
||||
}
|
||||
|
||||
printf("Suffer for 10 seconds.\n");
|
||||
fflush(stdout);
|
||||
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;
|
||||
}
|
||||
176
DependentExtensions/portaudio_v18_1/pa_tests/patest_latency.c
Normal file
176
DependentExtensions/portaudio_v18_1/pa_tests/patest_latency.c
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* $Id: patest_latency.c,v 1.4 2002/03/21 00:58:45 philburk 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;
|
||||
}
|
||||
168
DependentExtensions/portaudio_v18_1/pa_tests/patest_leftright.c
Normal file
168
DependentExtensions/portaudio_v18_1/pa_tests/patest_leftright.c
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* $Id: patest_leftright.c,v 1.2 2002/02/22 21:46:18 philburk 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;
|
||||
}
|
||||
137
DependentExtensions/portaudio_v18_1/pa_tests/patest_longsine.c
Normal file
137
DependentExtensions/portaudio_v18_1/pa_tests/patest_longsine.c
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* $Id: patest_longsine.c,v 1.2 2002/04/30 21:21:30 philburk 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;
|
||||
}
|
||||
195
DependentExtensions/portaudio_v18_1/pa_tests/patest_many.c
Normal file
195
DependentExtensions/portaudio_v18_1/pa_tests/patest_many.c
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* $Id: patest_many.c,v 1.1.1.1.4.1 2003/02/11 21:41:32 philburk 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");
|
||||
fflush(stdout);
|
||||
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;
|
||||
}
|
||||
201
DependentExtensions/portaudio_v18_1/pa_tests/patest_maxsines.c
Normal file
201
DependentExtensions/portaudio_v18_1/pa_tests/patest_maxsines.c
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* $Id: patest_maxsines.c,v 1.4.4.1 2003/04/10 23:09:40 philburk 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;
|
||||
PortAudioStream *stream;
|
||||
PaError err;
|
||||
paTestData data = {0};
|
||||
double load;
|
||||
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
data.sine[TABLE_SIZE] = data.sine[0]; /* set guard point */
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
paNoDevice,
|
||||
0, /* no input */
|
||||
paFloat32,
|
||||
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;
|
||||
|
||||
/* Play an increasing number of sine waves until we hit MAX_USAGE */
|
||||
do
|
||||
{
|
||||
data.numSines++;
|
||||
Pa_Sleep( 200 );
|
||||
|
||||
load = Pa_GetCPULoad( stream );
|
||||
printf("numSines = %d, CPU load = %f\n", data.numSines, load );
|
||||
fflush( stdout );
|
||||
}
|
||||
while( (load < MAX_USAGE) && (data.numSines < MAX_SINES) );
|
||||
|
||||
printf("Press ENTER to stop.\n" ); fflush(stdout);
|
||||
getchar();
|
||||
|
||||
printf("CPU load = %f\n", Pa_GetCPULoad( stream ) );
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
fflush( stdout );
|
||||
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;
|
||||
}
|
||||
136
DependentExtensions/portaudio_v18_1/pa_tests/patest_mono.c
Normal file
136
DependentExtensions/portaudio_v18_1/pa_tests/patest_mono.c
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* $Id: patest_mono.c,v 1.1.2.3 2003/04/10 23:09:40 philburk Exp $
|
||||
* patest_sine.c
|
||||
* Play a monophonic 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.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 AMPLITUDE (0.8)
|
||||
#define FRAMES_PER_BUFFER (64)
|
||||
#define OUTPUT_DEVICE Pa_GetDefaultOutputDeviceID()
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (200)
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
int 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;
|
||||
(void) outTime; /* Prevent unused variable warnings. */
|
||||
(void) inputBuffer;
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->phase]; /* left */
|
||||
data->phase += 1;
|
||||
if( data->phase >= TABLE_SIZE ) data->phase -= TABLE_SIZE;
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PortAudioStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
printf("PortAudio Test: output MONO 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) (AMPLITUDE * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
|
||||
}
|
||||
data.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,
|
||||
OUTPUT_DEVICE,
|
||||
1, /* MONO 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;
|
||||
printf("Play for %d seconds.\n", NUM_SECONDS ); fflush(stdout);
|
||||
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;
|
||||
}
|
||||
144
DependentExtensions/portaudio_v18_1/pa_tests/patest_multi_sine.c
Normal file
144
DependentExtensions/portaudio_v18_1/pa_tests/patest_multi_sine.c
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* $Id: patest_multi_sine.c,v 1.1.4.2 2003/02/13 18:05:30 philburk 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_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;
|
||||
(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) (0.7 * 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;
|
||||
}
|
||||
245
DependentExtensions/portaudio_v18_1/pa_tests/patest_pink.c
Normal file
245
DependentExtensions/portaudio_v18_1/pa_tests/patest_pink.c
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* $Id: patest_pink.c,v 1.1.1.1 2002/01/22 00:52:36 phil 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 */
|
||||
325
DependentExtensions/portaudio_v18_1/pa_tests/patest_record.c
Normal file
325
DependentExtensions/portaudio_v18_1/pa_tests/patest_record.c
Normal file
@ -0,0 +1,325 @@
|
||||
/*
|
||||
* $Id: patest_record.c,v 1.2.4.4 2003/04/16 19:07:56 philburk Exp $
|
||||
* patest_record.c
|
||||
* Record input into an array.
|
||||
* Optionally 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) /**/
|
||||
#define FRAMES_PER_BUFFER (1024)
|
||||
|
||||
/* Select sample format. */
|
||||
#if 1
|
||||
#define PA_SAMPLE_TYPE paFloat32
|
||||
typedef float SAMPLE;
|
||||
#define SAMPLE_SILENCE (0.0f)
|
||||
#elif 0
|
||||
#define PA_SAMPLE_TYPE paInt16
|
||||
typedef short SAMPLE;
|
||||
#define SAMPLE_SILENCE (0)
|
||||
#elif 0
|
||||
#define PA_SAMPLE_TYPE paInt8
|
||||
typedef char SAMPLE;
|
||||
#define SAMPLE_SILENCE (0)
|
||||
#else
|
||||
#define PA_SAMPLE_TYPE paUInt8
|
||||
typedef unsigned char SAMPLE;
|
||||
#define SAMPLE_SILENCE (128)
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int frameIndex; /* Index into sample array. */
|
||||
int maxFrameIndex;
|
||||
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 framesToRecord;
|
||||
long i;
|
||||
int finished;
|
||||
unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
|
||||
int samplesToRecord;
|
||||
|
||||
(void) outputBuffer; /* Prevent unused variable warnings. */
|
||||
(void) outTime;
|
||||
|
||||
if( framesLeft < framesPerBuffer )
|
||||
{
|
||||
framesToRecord = framesLeft;
|
||||
finished = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
framesToRecord = framesPerBuffer;
|
||||
finished = 0;
|
||||
}
|
||||
|
||||
samplesToRecord = framesToRecord * NUM_CHANNELS;
|
||||
|
||||
if( inputBuffer == NULL )
|
||||
{
|
||||
for( i=0; i<samplesToRecord; i++ )
|
||||
{
|
||||
*wptr++ = SAMPLE_SILENCE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i=0; i<samplesToRecord; i++ )
|
||||
{
|
||||
*wptr++ = *rptr++;
|
||||
}
|
||||
}
|
||||
data->frameIndex += framesToRecord;
|
||||
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;
|
||||
int framesToPlay, samplesToPlay, samplesPerBuffer;
|
||||
|
||||
if( framesLeft < framesPerBuffer )
|
||||
{
|
||||
framesToPlay = framesLeft;
|
||||
finished = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
framesToPlay = framesPerBuffer;
|
||||
finished = 0;
|
||||
}
|
||||
|
||||
samplesToPlay = framesToPlay * NUM_CHANNELS;
|
||||
samplesPerBuffer = framesPerBuffer * NUM_CHANNELS;
|
||||
|
||||
for( i=0; i<samplesToPlay; i++ )
|
||||
{
|
||||
*wptr++ = *rptr++;
|
||||
}
|
||||
for( ; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*wptr++ = 0; /* left */
|
||||
if( NUM_CHANNELS == 2 ) *wptr++ = 0; /* right */
|
||||
}
|
||||
data->frameIndex += framesToPlay;
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PortAudioStream *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_GetDefaultInputDeviceID(),
|
||||
NUM_CHANNELS,
|
||||
PA_SAMPLE_TYPE,
|
||||
NULL,
|
||||
paNoDevice,
|
||||
0,
|
||||
PA_SAMPLE_TYPE,
|
||||
NULL,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER, /* frames per buffer */
|
||||
0, /* number of buffers, if zero then use default minimum */
|
||||
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_StreamActive( 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 ) /* This should be done at compile-time with "#if" ?? */
|
||||
{ /* MIPS-compiler warns at the int-version below. */
|
||||
printf("sample max amplitude = %f\n", max );
|
||||
printf("sample average = %f\n", average );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("sample max amplitude = %d\n", max ); /* <-- This IS compiled anyhow. */
|
||||
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,
|
||||
NULL,
|
||||
Pa_GetDefaultOutputDeviceID(),
|
||||
NUM_CHANNELS,
|
||||
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,
|
||||
&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_StreamActive( 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;
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
/* $Id: patest_ringmix.c,v 1.1.1.1 2002/01/22 00:52:37 phil 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;
|
||||
}
|
||||
118
DependentExtensions/portaudio_v18_1/pa_tests/patest_saw.c
Normal file
118
DependentExtensions/portaudio_v18_1/pa_tests/patest_saw.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* $Id: patest_saw.c,v 1.1.1.1 2002/01/22 00:52:38 phil 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;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user