Sync with portaudio r1541 at rama's request.

Too many changes to list here, check portaudio svn log from r1505 to r1541 if you are curious.
Hope it works fine.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3879 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gigaherz 2010-10-05 20:52:42 +00:00
parent 53ebbc0242
commit d61d46bd7b
100 changed files with 36804 additions and 35489 deletions

View File

@ -1,239 +1,239 @@
# Doxyfile 1.4.6
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = PortAudio
PROJECT_NUMBER = 2.0
OUTPUT_DIRECTORY = ./doc/
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
BUILTIN_STL_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = doc/src \
src \
include \
test
FILE_PATTERNS = *.h \
*.c \
*.cpp \
*.dox
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = NO
HIDE_UNDOC_RELATIONS = NO
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = YES
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
# Doxyfile 1.4.6
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = PortAudio
PROJECT_NUMBER = 2.0
OUTPUT_DIRECTORY = ./doc/
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
BUILTIN_STL_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = doc/src \
src \
include \
test
FILE_PATTERNS = *.h \
*.c \
*.cpp \
*.dox
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = NO
HIDE_UNDOC_RELATIONS = NO
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = YES
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO

View File

@ -1,81 +1,81 @@
Portable header file to contain:
>>>>>
/*
* PortAudio Portable Real-Time Audio Library
* PortAudio API Header File
* Latest version available at: http://www.portaudio.com
*
* Copyright (c) 1999-2006 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.
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
<<<<<
Implementation files to contain:
>>>>>
/*
* PortAudio Portable Real-Time Audio Library
* Latest version at: http://www.portaudio.com
* <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.
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
Portable header file to contain:
>>>>>
/*
* PortAudio Portable Real-Time Audio Library
* PortAudio API Header File
* Latest version available at: http://www.portaudio.com
*
* Copyright (c) 1999-2006 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.
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
<<<<<
Implementation files to contain:
>>>>>
/*
* PortAudio Portable Real-Time Audio Library
* Latest version at: http://www.portaudio.com
* <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.
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
<<<<<

View File

@ -1,223 +1,223 @@
#
# PortAudio V19 Makefile.in
#
# Dominic Mazzoni
# Modifications by Mikael Magnusson
# Modifications by Stelios Bounanos
#
top_srcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
top_builddir = .
PREFIX = @prefix@
prefix = $(PREFIX)
exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
CC = @CC@
CXX = @CXX@
CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/common -I$(top_srcdir)/src/os/unix @CFLAGS@ @DEFS@
LIBS = @LIBS@
AR = @AR@
RANLIB = @RANLIB@
LIBTOOL = @LIBTOOL@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
SHARED_FLAGS = @SHARED_FLAGS@
LDFLAGS = @LDFLAGS@
DLL_LIBS = @DLL_LIBS@
CXXFLAGS = @CXXFLAGS@
NASM = @NASM@
NASMOPT = @NASMOPT@
LN_S = @LN_S@
LT_CURRENT=@LT_CURRENT@
LT_REVISION=@LT_REVISION@
LT_AGE=@LT_AGE@
OTHER_OBJS = @OTHER_OBJS@
PALIB = libportaudio.la
PAINC = include/portaudio.h
PA_LDFLAGS = $(LDFLAGS) $(SHARED_FLAGS) -rpath $(libdir) -no-undefined \
-export-symbols-regex "(Pa|PaMacCore|PaJack|PaAlsa|PaAsio)_.*" \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
COMMON_OBJS = \
src/common/pa_allocation.o \
src/common/pa_converters.o \
src/common/pa_cpuload.o \
src/common/pa_dither.o \
src/common/pa_debugprint.o \
src/common/pa_front.o \
src/common/pa_process.o \
src/common/pa_skeleton.o \
src/common/pa_stream.o \
src/common/pa_trace.o
TESTS = \
bin/paqa_devs \
bin/paqa_errs \
bin/patest1 \
bin/patest_buffer \
bin/patest_callbackstop \
bin/patest_clip \
bin/patest_dither \
bin/patest_hang \
bin/patest_in_overflow \
bin/patest_latency \
bin/patest_leftright \
bin/patest_longsine \
bin/patest_many \
bin/patest_maxsines \
bin/patest_multi_sine \
bin/patest_out_underflow \
bin/patest_pink \
bin/patest_prime \
bin/patest_read_record \
bin/patest_read_write_wire \
bin/patest_record \
bin/patest_ringmix \
bin/patest_saw \
bin/patest_sine8 \
bin/patest_sine \
bin/patest_sine_channelmaps \
bin/patest_sine_formats \
bin/patest_sine_time \
bin/patest_sine_srate \
bin/patest_start_stop \
bin/patest_stop \
bin/patest_stop_playout \
bin/patest_toomanysines \
bin/patest_underflow \
bin/patest_wire \
bin/patest_write_sine \
bin/pa_devs \
bin/pa_fuzz \
bin/pa_minlat
# Most of these don't compile yet. Put them in TESTS, above, if
# you want to try to compile them...
ALL_TESTS = \
$(TESTS) \
bin/patest_sync \
bin/debug_convert \
bin/debug_dither_calc \
bin/debug_dual \
bin/debug_multi_in \
bin/debug_multi_out \
bin/debug_record \
bin/debug_record_reuse \
bin/debug_sine_amp \
bin/debug_sine \
bin/debug_sine_formats \
bin/debug_srate \
bin/debug_test1
OBJS := $(COMMON_OBJS) $(OTHER_OBJS)
LTOBJS := $(OBJS:.o=.lo)
SRC_DIRS = \
src/common \
src/hostapi/alsa \
src/hostapi/asihpi \
src/hostapi/asio \
src/hostapi/coreaudio \
src/hostapi/dsound \
src/hostapi/jack \
src/hostapi/oss \
src/hostapi/wasapi \
src/hostapi/wdmks \
src/hostapi/wmme \
src/os/mac_osx \
src/os/unix \
src/os/win
SUBDIRS =
@ENABLE_CXX_TRUE@SUBDIRS += bindings/cpp
all: lib/$(PALIB) all-recursive tests
tests: bin-stamp $(TESTS)
# With ASIO enabled we must link libportaudio and all test programs with CXX
lib/$(PALIB): lib-stamp $(LTOBJS) $(MAKEFILE) $(PAINC)
@WITH_ASIO_FALSE@ $(LIBTOOL) --mode=link $(CC) $(PA_LDFLAGS) -o lib/$(PALIB) $(LTOBJS) $(DLL_LIBS)
@WITH_ASIO_TRUE@ $(LIBTOOL) --mode=link --tag=CXX $(CXX) $(PA_LDFLAGS) -o lib/$(PALIB) $(LTOBJS) $(DLL_LIBS)
$(ALL_TESTS): bin/%: lib/$(PALIB) $(MAKEFILE) $(PAINC) test/%.c
@WITH_ASIO_FALSE@ $(LIBTOOL) --mode=link $(CC) -o $@ $(CFLAGS) $(top_srcdir)/test/$*.c lib/$(PALIB) $(LIBS)
@WITH_ASIO_TRUE@ $(LIBTOOL) --mode=link --tag=CXX $(CXX) -o $@ $(CXXFLAGS) $(top_srcdir)/test/$*.c lib/$(PALIB) $(LIBS)
install: lib/$(PALIB) portaudio-2.0.pc
$(INSTALL) -d $(DESTDIR)$(libdir)
$(LIBTOOL) --mode=install $(INSTALL) lib/$(PALIB) $(DESTDIR)$(libdir)
$(INSTALL) -d $(DESTDIR)$(includedir)
$(INSTALL_DATA) -m 644 $(top_srcdir)/$(PAINC) $(DESTDIR)$(includedir)/portaudio.h
$(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig
$(INSTALL) -m 644 portaudio-2.0.pc $(DESTDIR)$(libdir)/pkgconfig/portaudio-2.0.pc
@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 $(libdir)"
@echo "------------------------------------------------------------"
@echo ""
$(MAKE) install-recursive
uninstall:
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$(PALIB)
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(includedir)/portaudio.h
$(MAKE) uninstall-recursive
clean:
$(LIBTOOL) --mode=clean rm -f $(LTOBJS) $(ALL_TESTS) lib/$(PALIB)
$(RM) bin-stamp lib-stamp
-$(RM) -r bin lib
distclean: clean
$(RM) config.log config.status Makefile libtool portaudio-2.0.pc
%.o: %.c $(MAKEFILE) $(PAINC)
$(CC) -c $(CFLAGS) $< -o $@
%.lo: %.c $(MAKEFILE) $(PAINC)
$(LIBTOOL) --mode=compile $(CC) -c $(CFLAGS) $< -o $@
%.lo: %.cpp $(MAKEFILE) $(PAINC)
$(LIBTOOL) --mode=compile --tag=CXX $(CXX) -c $(CXXFLAGS) $< -o $@
%.o: %.cpp $(MAKEFILE) $(PAINC)
$(CXX) -c $(CXXFLAGS) $< -o $@
%.o: %.asm
$(NASM) $(NASMOPT) -o $@ $<
bin-stamp:
-mkdir bin
touch $@
lib-stamp:
-mkdir lib
-mkdir -p $(SRC_DIRS)
touch $@
Makefile: Makefile.in config.status
$(SHELL) config.status
all-recursive:
if test -n "$(SUBDIRS)" ; then for dir in "$(SUBDIRS)"; do $(MAKE) -C $$dir all; done ; fi
install-recursive:
if test -n "$(SUBDIRS)" ; then for dir in "$(SUBDIRS)"; do $(MAKE) -C $$dir install; done ; fi
uninstall-recursive:
if test -n "$(SUBDIRS)" ; then for dir in "$(SUBDIRS)"; do $(MAKE) -C $$dir uninstall; done ; fi
#
# PortAudio V19 Makefile.in
#
# Dominic Mazzoni
# Modifications by Mikael Magnusson
# Modifications by Stelios Bounanos
#
top_srcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
top_builddir = .
PREFIX = @prefix@
prefix = $(PREFIX)
exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
CC = @CC@
CXX = @CXX@
CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/common -I$(top_srcdir)/src/os/unix @CFLAGS@ @DEFS@
LIBS = @LIBS@
AR = @AR@
RANLIB = @RANLIB@
LIBTOOL = @LIBTOOL@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
SHARED_FLAGS = @SHARED_FLAGS@
LDFLAGS = @LDFLAGS@
DLL_LIBS = @DLL_LIBS@
CXXFLAGS = @CXXFLAGS@
NASM = @NASM@
NASMOPT = @NASMOPT@
LN_S = @LN_S@
LT_CURRENT=@LT_CURRENT@
LT_REVISION=@LT_REVISION@
LT_AGE=@LT_AGE@
OTHER_OBJS = @OTHER_OBJS@
PALIB = libportaudio.la
PAINC = include/portaudio.h
PA_LDFLAGS = $(LDFLAGS) $(SHARED_FLAGS) -rpath $(libdir) -no-undefined \
-export-symbols-regex "(Pa|PaMacCore|PaJack|PaAlsa|PaAsio)_.*" \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
COMMON_OBJS = \
src/common/pa_allocation.o \
src/common/pa_converters.o \
src/common/pa_cpuload.o \
src/common/pa_dither.o \
src/common/pa_debugprint.o \
src/common/pa_front.o \
src/common/pa_process.o \
src/common/pa_skeleton.o \
src/common/pa_stream.o \
src/common/pa_trace.o
TESTS = \
bin/paqa_devs \
bin/paqa_errs \
bin/patest1 \
bin/patest_buffer \
bin/patest_callbackstop \
bin/patest_clip \
bin/patest_dither \
bin/patest_hang \
bin/patest_in_overflow \
bin/patest_latency \
bin/patest_leftright \
bin/patest_longsine \
bin/patest_many \
bin/patest_maxsines \
bin/patest_multi_sine \
bin/patest_out_underflow \
bin/patest_pink \
bin/patest_prime \
bin/patest_read_record \
bin/patest_read_write_wire \
bin/patest_record \
bin/patest_ringmix \
bin/patest_saw \
bin/patest_sine8 \
bin/patest_sine \
bin/patest_sine_channelmaps \
bin/patest_sine_formats \
bin/patest_sine_time \
bin/patest_sine_srate \
bin/patest_start_stop \
bin/patest_stop \
bin/patest_stop_playout \
bin/patest_toomanysines \
bin/patest_underflow \
bin/patest_wire \
bin/patest_write_sine \
bin/pa_devs \
bin/pa_fuzz \
bin/pa_minlat
# Most of these don't compile yet. Put them in TESTS, above, if
# you want to try to compile them...
ALL_TESTS = \
$(TESTS) \
bin/patest_sync \
bin/debug_convert \
bin/debug_dither_calc \
bin/debug_dual \
bin/debug_multi_in \
bin/debug_multi_out \
bin/debug_record \
bin/debug_record_reuse \
bin/debug_sine_amp \
bin/debug_sine \
bin/debug_sine_formats \
bin/debug_srate \
bin/debug_test1
OBJS := $(COMMON_OBJS) $(OTHER_OBJS)
LTOBJS := $(OBJS:.o=.lo)
SRC_DIRS = \
src/common \
src/hostapi/alsa \
src/hostapi/asihpi \
src/hostapi/asio \
src/hostapi/coreaudio \
src/hostapi/dsound \
src/hostapi/jack \
src/hostapi/oss \
src/hostapi/wasapi \
src/hostapi/wdmks \
src/hostapi/wmme \
src/os/mac_osx \
src/os/unix \
src/os/win
SUBDIRS =
@ENABLE_CXX_TRUE@SUBDIRS += bindings/cpp
all: lib/$(PALIB) all-recursive tests
tests: bin-stamp $(TESTS)
# With ASIO enabled we must link libportaudio and all test programs with CXX
lib/$(PALIB): lib-stamp $(LTOBJS) $(MAKEFILE) $(PAINC)
@WITH_ASIO_FALSE@ $(LIBTOOL) --mode=link $(CC) $(PA_LDFLAGS) -o lib/$(PALIB) $(LTOBJS) $(DLL_LIBS)
@WITH_ASIO_TRUE@ $(LIBTOOL) --mode=link --tag=CXX $(CXX) $(PA_LDFLAGS) -o lib/$(PALIB) $(LTOBJS) $(DLL_LIBS)
$(ALL_TESTS): bin/%: lib/$(PALIB) $(MAKEFILE) $(PAINC) test/%.c
@WITH_ASIO_FALSE@ $(LIBTOOL) --mode=link $(CC) -o $@ $(CFLAGS) $(top_srcdir)/test/$*.c lib/$(PALIB) $(LIBS)
@WITH_ASIO_TRUE@ $(LIBTOOL) --mode=link --tag=CXX $(CXX) -o $@ $(CXXFLAGS) $(top_srcdir)/test/$*.c lib/$(PALIB) $(LIBS)
install: lib/$(PALIB) portaudio-2.0.pc
$(INSTALL) -d $(DESTDIR)$(libdir)
$(LIBTOOL) --mode=install $(INSTALL) lib/$(PALIB) $(DESTDIR)$(libdir)
$(INSTALL) -d $(DESTDIR)$(includedir)
$(INSTALL_DATA) -m 644 $(top_srcdir)/$(PAINC) $(DESTDIR)$(includedir)/portaudio.h
$(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig
$(INSTALL) -m 644 portaudio-2.0.pc $(DESTDIR)$(libdir)/pkgconfig/portaudio-2.0.pc
@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 $(libdir)"
@echo "------------------------------------------------------------"
@echo ""
$(MAKE) install-recursive
uninstall:
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$(PALIB)
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(includedir)/portaudio.h
$(MAKE) uninstall-recursive
clean:
$(LIBTOOL) --mode=clean rm -f $(LTOBJS) $(ALL_TESTS) lib/$(PALIB)
$(RM) bin-stamp lib-stamp
-$(RM) -r bin lib
distclean: clean
$(RM) config.log config.status Makefile libtool portaudio-2.0.pc
%.o: %.c $(MAKEFILE) $(PAINC)
$(CC) -c $(CFLAGS) $< -o $@
%.lo: %.c $(MAKEFILE) $(PAINC)
$(LIBTOOL) --mode=compile $(CC) -c $(CFLAGS) $< -o $@
%.lo: %.cpp $(MAKEFILE) $(PAINC)
$(LIBTOOL) --mode=compile --tag=CXX $(CXX) -c $(CXXFLAGS) $< -o $@
%.o: %.cpp $(MAKEFILE) $(PAINC)
$(CXX) -c $(CXXFLAGS) $< -o $@
%.o: %.asm
$(NASM) $(NASMOPT) -o $@ $<
bin-stamp:
-mkdir bin
touch $@
lib-stamp:
-mkdir lib
-mkdir -p $(SRC_DIRS)
touch $@
Makefile: Makefile.in config.status
$(SHELL) config.status
all-recursive:
if test -n "$(SUBDIRS)" ; then for dir in "$(SUBDIRS)"; do $(MAKE) -C $$dir all; done ; fi
install-recursive:
if test -n "$(SUBDIRS)" ; then for dir in "$(SUBDIRS)"; do $(MAKE) -C $$dir install; done ; fi
uninstall-recursive:
if test -n "$(SUBDIRS)" ; then for dir in "$(SUBDIRS)"; do $(MAKE) -C $$dir uninstall; done ; fi

View File

@ -1,98 +1,98 @@
README for PortAudio
/*
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
*
* Copyright (c) 1999-2008 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.
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
PortAudio is a portable audio I/O library designed for cross-platform
support of audio. It uses either a callback mechanism to request audio
processing, or blocking read/write calls to buffer data between the
native audio subsystem and the client. Audio can be processed in various
formats, including 32 bit floating point, and will be converted to the
native format internally.
Documentation:
Documentation is available in "/doc/html/index.html"
Also see "src/common/portaudio.h" for API spec.
Also see http://www.portaudio.com/docs/
And see the "test/" directory for many examples of usage
(we suggest "test/patest_saw.c" for an example)
For information on compiling programs with PortAudio, please see the
tutorial at:
http://portaudio.com/trac/wiki/TutorialDir/TutorialStart
We have an active mailing list for user and developer discussions.
Please feel free to join. See http://www.portaudio.com for details.
Important Files and Folders:
include/portaudio.h = header file for PortAudio API. Specifies API.
src/common/ = platform independant code, host independant
code for all implementations.
src/os = os specific (but host api neutral) code
src/hostapi = implementations for different host apis
Host API Implementations:
src/hostapi/alsa = Advanced Linux Sound Architecture (ALSA)
src/hostapi/asihpi = AudioScience HPI
src/hostapi/asio = ASIO for Windows and Macintosh
src/hostapi/coreaudio = Macintosh Core Audio for OS X
src/hostapi/dsound = Windows Direct Sound
src/hostapi/jack = JACK Audio Connection Kit
src/hostapi/oss = Unix Open Sound System (OSS)
src/hostapi/wasapi = Windows Vista WASAPI
src/hostapi/wdmks = Windows WDM Kernel Streaming
src/hostapi/wmme = Windows MultiMedia Extensions (MME)
Test Programs:
test/pa_fuzz.c = guitar fuzz box
test/pa_devs.c = print a list of available devices
test/pa_minlat.c = determine minimum latency for your machine
test/paqa_devs.c = self test that opens all devices
test/paqa_errs.c = test error detection and reporting
test/patest_clip.c = hear a sine wave clipped and unclipped
test/patest_dither.c = hear effects of dithering (extremely subtle)
test/patest_pink.c = fun with pink noise
test/patest_record.c = record and playback some audio
test/patest_maxsines.c = how many sine waves can we play? Tests Pa_GetCPULoad().
test/patest_sine.c = output a sine wave in a simple PA app
test/patest_sync.c = test syncronization of audio and video
test/patest_wire.c = pass input to output, wire simulator
README for PortAudio
/*
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
*
* Copyright (c) 1999-2008 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.
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
PortAudio is a portable audio I/O library designed for cross-platform
support of audio. It uses either a callback mechanism to request audio
processing, or blocking read/write calls to buffer data between the
native audio subsystem and the client. Audio can be processed in various
formats, including 32 bit floating point, and will be converted to the
native format internally.
Documentation:
Documentation is available in "/doc/html/index.html"
Also see "src/common/portaudio.h" for API spec.
Also see http://www.portaudio.com/docs/
And see the "test/" directory for many examples of usage
(we suggest "test/patest_saw.c" for an example)
For information on compiling programs with PortAudio, please see the
tutorial at:
http://portaudio.com/trac/wiki/TutorialDir/TutorialStart
We have an active mailing list for user and developer discussions.
Please feel free to join. See http://www.portaudio.com for details.
Important Files and Folders:
include/portaudio.h = header file for PortAudio API. Specifies API.
src/common/ = platform independant code, host independant
code for all implementations.
src/os = os specific (but host api neutral) code
src/hostapi = implementations for different host apis
Host API Implementations:
src/hostapi/alsa = Advanced Linux Sound Architecture (ALSA)
src/hostapi/asihpi = AudioScience HPI
src/hostapi/asio = ASIO for Windows and Macintosh
src/hostapi/coreaudio = Macintosh Core Audio for OS X
src/hostapi/dsound = Windows Direct Sound
src/hostapi/jack = JACK Audio Connection Kit
src/hostapi/oss = Unix Open Sound System (OSS)
src/hostapi/wasapi = Windows Vista WASAPI
src/hostapi/wdmks = Windows WDM Kernel Streaming
src/hostapi/wmme = Windows MultiMedia Extensions (MME)
Test Programs:
test/pa_fuzz.c = guitar fuzz box
test/pa_devs.c = print a list of available devices
test/pa_minlat.c = determine minimum latency for your machine
test/paqa_devs.c = self test that opens all devices
test/paqa_errs.c = test error detection and reporting
test/patest_clip.c = hear a sine wave clipped and unclipped
test/patest_dither.c = hear effects of dithering (extremely subtle)
test/patest_pink.c = fun with pink noise
test/patest_record.c = record and playback some audio
test/patest_maxsines.c = how many sine waves can we play? Tests Pa_GetCPULoad().
test/patest_sine.c = output a sine wave in a simple PA app
test/patest_sync.c = test syncronization of audio and video
test/patest_wire.c = pass input to output, wire simulator

View File

@ -1,197 +1,197 @@
import sys, os.path
def rsplit(toSplit, sub, max=-1):
""" str.rsplit seems to have been introduced in 2.4 :( """
l = []
i = 0
while i != max:
try: idx = toSplit.rindex(sub)
except ValueError: break
toSplit, splitOff = toSplit[:idx], toSplit[idx + len(sub):]
l.insert(0, splitOff)
i += 1
l.insert(0, toSplit)
return l
sconsDir = os.path.join("build", "scons")
SConscript(os.path.join(sconsDir, "SConscript_common"))
Import("Platform", "Posix", "ApiVer")
# SConscript_opts exports PortAudio options
optsDict = SConscript(os.path.join(sconsDir, "SConscript_opts"))
optionsCache = os.path.join(sconsDir, "options.cache") # Save options between runs in this cache
options = Options(optionsCache, args=ARGUMENTS)
for k in ("Installation Dirs", "Build Targets", "Host APIs", "Build Parameters", "Bindings"):
options.AddOptions(*optsDict[k])
# Propagate options into environment
env = Environment(options=options)
# Save options for next run
options.Save(optionsCache, env)
# Generate help text for options
env.Help(options.GenerateHelpText(env))
buildDir = os.path.join("#", sconsDir, env["PLATFORM"])
# Determine parameters to build tools
if Platform in Posix:
threadCFlags = ''
if Platform != 'darwin':
threadCFlags = "-pthread "
baseLinkFlags = threadCFlags
baseCxxFlags = baseCFlags = "-Wall -pedantic -pipe " + threadCFlags
debugCxxFlags = debugCFlags = "-g"
optCxxFlags = optCFlags = "-O2"
env.Append(CCFLAGS = baseCFlags)
env.Append(CXXFLAGS = baseCxxFlags)
env.Append(LINKFLAGS = baseLinkFlags)
if env["enableDebug"]:
env.AppendUnique(CCFLAGS=debugCFlags.split())
env.AppendUnique(CXXFLAGS=debugCxxFlags.split())
if env["enableOptimize"]:
env.AppendUnique(CCFLAGS=optCFlags.split())
env.AppendUnique(CXXFLAGS=optCxxFlags.split())
if not env["enableAsserts"]:
env.AppendUnique(CPPDEFINES=["-DNDEBUG"])
if env["customCFlags"]:
env.Append(CCFLAGS=Split(env["customCFlags"]))
if env["customCxxFlags"]:
env.Append(CXXFLAGS=Split(env["customCxxFlags"]))
if env["customLinkFlags"]:
env.Append(LINKFLAGS=Split(env["customLinkFlags"]))
env.Append(CPPPATH=[os.path.join("#", "include"), "common"])
# Store all signatures in one file, otherwise .sconsign files will get installed along with our own files
env.SConsignFile(os.path.join(sconsDir, ".sconsign"))
env.SConscriptChdir(False)
sources, sharedLib, staticLib, tests, portEnv, hostApis = env.SConscript(os.path.join("src", "SConscript"),
build_dir=buildDir, duplicate=False, exports=["env"])
if Platform in Posix:
prefix = env["prefix"]
includeDir = os.path.join(prefix, "include")
libDir = os.path.join(prefix, "lib")
env.Alias("install", includeDir)
env.Alias("install", libDir)
# pkg-config
def installPkgconfig(env, target, source):
tgt = str(target[0])
src = str(source[0])
f = open(src)
try: txt = f.read()
finally: f.close()
txt = txt.replace("@prefix@", prefix)
txt = txt.replace("@exec_prefix@", prefix)
txt = txt.replace("@libdir@", libDir)
txt = txt.replace("@includedir@", includeDir)
txt = txt.replace("@LIBS@", " ".join(["-l%s" % l for l in portEnv["LIBS"]]))
txt = txt.replace("@THREAD_CFLAGS@", threadCFlags)
f = open(tgt, "w")
try: f.write(txt)
finally: f.close()
pkgconfigTgt = "portaudio-%d.0.pc" % int(ApiVer.split(".", 1)[0])
env.Command(os.path.join(libDir, "pkgconfig", pkgconfigTgt),
os.path.join("#", pkgconfigTgt + ".in"), installPkgconfig)
# Default to None, since if the user disables all targets and no Default is set, all targets
# are built by default
env.Default(None)
if env["enableTests"]:
env.Default(tests)
if env["enableShared"]:
env.Default(sharedLib)
if Platform in Posix:
def symlink(env, target, source):
trgt = str(target[0])
src = str(source[0])
if os.path.islink(trgt) or os.path.exists(trgt):
os.remove(trgt)
os.symlink(os.path.basename(src), trgt)
major, minor, micro = [int(c) for c in ApiVer.split(".")]
soFile = "%s.%s" % (os.path.basename(str(sharedLib[0])), ApiVer)
env.InstallAs(target=os.path.join(libDir, soFile), source=sharedLib)
# Install symlinks
symTrgt = os.path.join(libDir, soFile)
env.Command(os.path.join(libDir, "libportaudio.so.%d.%d" % (major, minor)),
symTrgt, symlink)
symTrgt = rsplit(symTrgt, ".", 1)[0]
env.Command(os.path.join(libDir, "libportaudio.so.%d" % major), symTrgt, symlink)
symTrgt = rsplit(symTrgt, ".", 1)[0]
env.Command(os.path.join(libDir, "libportaudio.so"), symTrgt, symlink)
if env["enableStatic"]:
env.Default(staticLib)
env.Install(libDir, staticLib)
env.Install(includeDir, os.path.join("include", "portaudio.h"))
if env["enableCxx"]:
env.SConscriptChdir(True)
cxxEnv = env.Copy()
sharedLibs, staticLibs, headers = env.SConscript(os.path.join("bindings", "cpp", "SConscript"),
exports={"env": cxxEnv, "buildDir": buildDir}, build_dir=os.path.join(buildDir, "portaudiocpp"), duplicate=False)
if env["enableStatic"]:
env.Default(staticLibs)
env.Install(libDir, staticLibs)
if env["enableShared"]:
env.Default(sharedLibs)
env.Install(libDir, sharedLibs)
env.Install(os.path.join(includeDir, "portaudiocpp"), headers)
# Generate portaudio_config.h header with compile-time definitions of which PA
# back-ends are available, and which includes back-end extension headers
# Host-specific headers
hostApiHeaders = {"ALSA": "pa_linux_alsa.h",
"ASIO": "pa_asio.h",
"COREAUDIO": "pa_mac_core.h",
"JACK": "pa_jack.h",
"WMME": "pa_winwmme.h",
}
def buildConfigH(target, source, env):
"""builder for portaudio_config.h"""
global hostApiHeaders, hostApis
out = ""
for hostApi in hostApis:
out += "#define PA_HAVE_%s\n" % hostApi
hostApiSpecificHeader = hostApiHeaders.get(hostApi, None)
if hostApiSpecificHeader:
out += "#include \"%s\"\n" % hostApiSpecificHeader
out += "\n"
# Strip the last newline
if out and out[-1] == "\n":
out = out[:-1]
f = file(str(target[0]), 'w')
try: f.write(out)
finally: f.close()
return 0
# Define the builder for the config header
env.Append(BUILDERS={"portaudioConfig": env.Builder(
action=Action(buildConfigH), target_factory=env.fs.File)})
confH = env.portaudioConfig(File("portaudio_config.h", "include"),
File("portaudio.h", "include"))
env.Default(confH)
env.Install(os.path.join(includeDir, "portaudio"), confH)
for api in hostApis:
if api in hostApiHeaders:
env.Install(os.path.join(includeDir, "portaudio"),
File(hostApiHeaders[api], "include"))
import sys, os.path
def rsplit(toSplit, sub, max=-1):
""" str.rsplit seems to have been introduced in 2.4 :( """
l = []
i = 0
while i != max:
try: idx = toSplit.rindex(sub)
except ValueError: break
toSplit, splitOff = toSplit[:idx], toSplit[idx + len(sub):]
l.insert(0, splitOff)
i += 1
l.insert(0, toSplit)
return l
sconsDir = os.path.join("build", "scons")
SConscript(os.path.join(sconsDir, "SConscript_common"))
Import("Platform", "Posix", "ApiVer")
# SConscript_opts exports PortAudio options
optsDict = SConscript(os.path.join(sconsDir, "SConscript_opts"))
optionsCache = os.path.join(sconsDir, "options.cache") # Save options between runs in this cache
options = Options(optionsCache, args=ARGUMENTS)
for k in ("Installation Dirs", "Build Targets", "Host APIs", "Build Parameters", "Bindings"):
options.AddOptions(*optsDict[k])
# Propagate options into environment
env = Environment(options=options)
# Save options for next run
options.Save(optionsCache, env)
# Generate help text for options
env.Help(options.GenerateHelpText(env))
buildDir = os.path.join("#", sconsDir, env["PLATFORM"])
# Determine parameters to build tools
if Platform in Posix:
threadCFlags = ''
if Platform != 'darwin':
threadCFlags = "-pthread "
baseLinkFlags = threadCFlags
baseCxxFlags = baseCFlags = "-Wall -pedantic -pipe " + threadCFlags
debugCxxFlags = debugCFlags = "-g"
optCxxFlags = optCFlags = "-O2"
env.Append(CCFLAGS = baseCFlags)
env.Append(CXXFLAGS = baseCxxFlags)
env.Append(LINKFLAGS = baseLinkFlags)
if env["enableDebug"]:
env.AppendUnique(CCFLAGS=debugCFlags.split())
env.AppendUnique(CXXFLAGS=debugCxxFlags.split())
if env["enableOptimize"]:
env.AppendUnique(CCFLAGS=optCFlags.split())
env.AppendUnique(CXXFLAGS=optCxxFlags.split())
if not env["enableAsserts"]:
env.AppendUnique(CPPDEFINES=["-DNDEBUG"])
if env["customCFlags"]:
env.Append(CCFLAGS=Split(env["customCFlags"]))
if env["customCxxFlags"]:
env.Append(CXXFLAGS=Split(env["customCxxFlags"]))
if env["customLinkFlags"]:
env.Append(LINKFLAGS=Split(env["customLinkFlags"]))
env.Append(CPPPATH=[os.path.join("#", "include"), "common"])
# Store all signatures in one file, otherwise .sconsign files will get installed along with our own files
env.SConsignFile(os.path.join(sconsDir, ".sconsign"))
env.SConscriptChdir(False)
sources, sharedLib, staticLib, tests, portEnv, hostApis = env.SConscript(os.path.join("src", "SConscript"),
build_dir=buildDir, duplicate=False, exports=["env"])
if Platform in Posix:
prefix = env["prefix"]
includeDir = os.path.join(prefix, "include")
libDir = os.path.join(prefix, "lib")
env.Alias("install", includeDir)
env.Alias("install", libDir)
# pkg-config
def installPkgconfig(env, target, source):
tgt = str(target[0])
src = str(source[0])
f = open(src)
try: txt = f.read()
finally: f.close()
txt = txt.replace("@prefix@", prefix)
txt = txt.replace("@exec_prefix@", prefix)
txt = txt.replace("@libdir@", libDir)
txt = txt.replace("@includedir@", includeDir)
txt = txt.replace("@LIBS@", " ".join(["-l%s" % l for l in portEnv["LIBS"]]))
txt = txt.replace("@THREAD_CFLAGS@", threadCFlags)
f = open(tgt, "w")
try: f.write(txt)
finally: f.close()
pkgconfigTgt = "portaudio-%d.0.pc" % int(ApiVer.split(".", 1)[0])
env.Command(os.path.join(libDir, "pkgconfig", pkgconfigTgt),
os.path.join("#", pkgconfigTgt + ".in"), installPkgconfig)
# Default to None, since if the user disables all targets and no Default is set, all targets
# are built by default
env.Default(None)
if env["enableTests"]:
env.Default(tests)
if env["enableShared"]:
env.Default(sharedLib)
if Platform in Posix:
def symlink(env, target, source):
trgt = str(target[0])
src = str(source[0])
if os.path.islink(trgt) or os.path.exists(trgt):
os.remove(trgt)
os.symlink(os.path.basename(src), trgt)
major, minor, micro = [int(c) for c in ApiVer.split(".")]
soFile = "%s.%s" % (os.path.basename(str(sharedLib[0])), ApiVer)
env.InstallAs(target=os.path.join(libDir, soFile), source=sharedLib)
# Install symlinks
symTrgt = os.path.join(libDir, soFile)
env.Command(os.path.join(libDir, "libportaudio.so.%d.%d" % (major, minor)),
symTrgt, symlink)
symTrgt = rsplit(symTrgt, ".", 1)[0]
env.Command(os.path.join(libDir, "libportaudio.so.%d" % major), symTrgt, symlink)
symTrgt = rsplit(symTrgt, ".", 1)[0]
env.Command(os.path.join(libDir, "libportaudio.so"), symTrgt, symlink)
if env["enableStatic"]:
env.Default(staticLib)
env.Install(libDir, staticLib)
env.Install(includeDir, os.path.join("include", "portaudio.h"))
if env["enableCxx"]:
env.SConscriptChdir(True)
cxxEnv = env.Copy()
sharedLibs, staticLibs, headers = env.SConscript(os.path.join("bindings", "cpp", "SConscript"),
exports={"env": cxxEnv, "buildDir": buildDir}, build_dir=os.path.join(buildDir, "portaudiocpp"), duplicate=False)
if env["enableStatic"]:
env.Default(staticLibs)
env.Install(libDir, staticLibs)
if env["enableShared"]:
env.Default(sharedLibs)
env.Install(libDir, sharedLibs)
env.Install(os.path.join(includeDir, "portaudiocpp"), headers)
# Generate portaudio_config.h header with compile-time definitions of which PA
# back-ends are available, and which includes back-end extension headers
# Host-specific headers
hostApiHeaders = {"ALSA": "pa_linux_alsa.h",
"ASIO": "pa_asio.h",
"COREAUDIO": "pa_mac_core.h",
"JACK": "pa_jack.h",
"WMME": "pa_winwmme.h",
}
def buildConfigH(target, source, env):
"""builder for portaudio_config.h"""
global hostApiHeaders, hostApis
out = ""
for hostApi in hostApis:
out += "#define PA_HAVE_%s\n" % hostApi
hostApiSpecificHeader = hostApiHeaders.get(hostApi, None)
if hostApiSpecificHeader:
out += "#include \"%s\"\n" % hostApiSpecificHeader
out += "\n"
# Strip the last newline
if out and out[-1] == "\n":
out = out[:-1]
f = file(str(target[0]), 'w')
try: f.write(out)
finally: f.close()
return 0
# Define the builder for the config header
env.Append(BUILDERS={"portaudioConfig": env.Builder(
action=Action(buildConfigH), target_factory=env.fs.File)})
confH = env.portaudioConfig(File("portaudio_config.h", "include"),
File("portaudio.h", "include"))
env.Default(confH)
env.Install(os.path.join(includeDir, "portaudio"), confH)
for api in hostApis:
if api in hostApiHeaders:
env.Install(os.path.join(includeDir, "portaudio"),
File(hostApiHeaders[api], "include"))

File diff suppressed because it is too large Load Diff

View File

@ -1,78 +1,78 @@
# Project: portaudio-dll
# Makefile created by Dev-C++ 4.9.8.2
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
RES =
OBJ = ./pa_skeleton.o ./pa_stream.o ./pa_trace.o ./pa_allocation.o ./pa_converters.o ./pa_cpuload.o ./pa_dither.o ./pa_front.o ./pa_process.o ./pa_asio.o ./pa_win_util.o ./pa_win_hostapis.o ./pa_win_ds.o ./dsound_wrapper.o ./pa_win_wmme.o ./iasiothiscallresolver.o $(RES)
LINKOBJ = ./pa_skeleton.o ./pa_stream.o ./pa_trace.o ./pa_allocation.o ./pa_converters.o ./pa_cpuload.o ./pa_dither.o ./pa_front.o ./pa_process.o ./pa_asio.o ./pa_win_util.o ./pa_win_hostapis.o ./pa_win_ds.o ./dsound_wrapper.o ./pa_win_wmme.o ./iasiothiscallresolver.o $(RES)
LIBS = -L"C:/Dev-CPP/lib" -fmessage-length=0 --no-export-all-symbols --add-stdcall-alias ../../../asiosdk2/asiosdk2.a -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lwinmm -O3 -s
INCS = -I"C:/Dev-CPP/include" -I"../../../asiosdk2" -I"../../../asiosdk2/common" -I"../../../asiosdk2/host" -I"../../../asiosdk2/host/pc" -I"../../pa_common"
CXXINCS = -I"C:/Dev-CPP/include/c++" -I"C:/Dev-CPP/include/c++/mingw32" -I"C:/Dev-CPP/include/c++/backward" -I"C:/Dev-CPP/include" -I"../../../asiosdk2" -I"../../../asiosdk2/common" -I"../../../asiosdk2/host" -I"../../../asiosdk2/host/pc" -I"../../pa_common"
BIN = portaudio-dll.dll
CXXFLAGS = $(CXXINCS)-O3 -fmessage-length=0 -Wall
CFLAGS = $(INCS)-DBUILDING_DLL=1 -O3 -fmessage-length=0 -Wall
.PHONY: all all-before all-after clean clean-custom
all: all-before portaudio-dll.dll all-after
clean: clean-custom
rm -f $(OBJ) $(BIN)
DLLWRAP=dllwrap.exe
DEFFILE=libportaudio-dll.def
STATICLIB=libportaudio-dll.a
$(BIN): $(LINKOBJ)
$(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
./pa_skeleton.o: ../../pa_common/pa_skeleton.c
$(CPP) -c ../../pa_common/pa_skeleton.c -o ./pa_skeleton.o $(CXXFLAGS)
./pa_stream.o: ../../pa_common/pa_stream.c
$(CPP) -c ../../pa_common/pa_stream.c -o ./pa_stream.o $(CXXFLAGS)
./pa_trace.o: ../../pa_common/pa_trace.c
$(CPP) -c ../../pa_common/pa_trace.c -o ./pa_trace.o $(CXXFLAGS)
./pa_allocation.o: ../../pa_common/pa_allocation.c
$(CPP) -c ../../pa_common/pa_allocation.c -o ./pa_allocation.o $(CXXFLAGS)
./pa_converters.o: ../../pa_common/pa_converters.c
$(CPP) -c ../../pa_common/pa_converters.c -o ./pa_converters.o $(CXXFLAGS)
./pa_cpuload.o: ../../pa_common/pa_cpuload.c
$(CPP) -c ../../pa_common/pa_cpuload.c -o ./pa_cpuload.o $(CXXFLAGS)
./pa_dither.o: ../../pa_common/pa_dither.c
$(CPP) -c ../../pa_common/pa_dither.c -o ./pa_dither.o $(CXXFLAGS)
./pa_front.o: ../../pa_common/pa_front.c
$(CPP) -c ../../pa_common/pa_front.c -o ./pa_front.o $(CXXFLAGS)
./pa_process.o: ../../pa_common/pa_process.c
$(CPP) -c ../../pa_common/pa_process.c -o ./pa_process.o $(CXXFLAGS)
./pa_asio.o: ../../pa_asio/pa_asio.cpp
$(CPP) -c ../../pa_asio/pa_asio.cpp -o ./pa_asio.o $(CXXFLAGS)
./pa_win_util.o: ../pa_win_util.c
$(CPP) -c ../pa_win_util.c -o ./pa_win_util.o $(CXXFLAGS)
./pa_win_hostapis.o: ../pa_win_hostapis.c
$(CPP) -c ../pa_win_hostapis.c -o ./pa_win_hostapis.o $(CXXFLAGS)
./pa_win_ds.o: ../../pa_win_ds/pa_win_ds.c
$(CPP) -c ../../pa_win_ds/pa_win_ds.c -o ./pa_win_ds.o $(CXXFLAGS)
./dsound_wrapper.o: ../../pa_win_ds/dsound_wrapper.c
$(CPP) -c ../../pa_win_ds/dsound_wrapper.c -o ./dsound_wrapper.o $(CXXFLAGS)
./pa_win_wmme.o: ../../pa_win_wmme/pa_win_wmme.c
$(CPP) -c ../../pa_win_wmme/pa_win_wmme.c -o ./pa_win_wmme.o $(CXXFLAGS)
./iasiothiscallresolver.o: ../../pa_asio/iasiothiscallresolver.cpp
$(CPP) -c ../../pa_asio/iasiothiscallresolver.cpp -o ./iasiothiscallresolver.o $(CXXFLAGS)
# Project: portaudio-dll
# Makefile created by Dev-C++ 4.9.8.2
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
RES =
OBJ = ./pa_skeleton.o ./pa_stream.o ./pa_trace.o ./pa_allocation.o ./pa_converters.o ./pa_cpuload.o ./pa_dither.o ./pa_front.o ./pa_process.o ./pa_asio.o ./pa_win_util.o ./pa_win_hostapis.o ./pa_win_ds.o ./dsound_wrapper.o ./pa_win_wmme.o ./iasiothiscallresolver.o $(RES)
LINKOBJ = ./pa_skeleton.o ./pa_stream.o ./pa_trace.o ./pa_allocation.o ./pa_converters.o ./pa_cpuload.o ./pa_dither.o ./pa_front.o ./pa_process.o ./pa_asio.o ./pa_win_util.o ./pa_win_hostapis.o ./pa_win_ds.o ./dsound_wrapper.o ./pa_win_wmme.o ./iasiothiscallresolver.o $(RES)
LIBS = -L"C:/Dev-CPP/lib" -fmessage-length=0 --no-export-all-symbols --add-stdcall-alias ../../../asiosdk2/asiosdk2.a -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lwinmm -O3 -s
INCS = -I"C:/Dev-CPP/include" -I"../../../asiosdk2" -I"../../../asiosdk2/common" -I"../../../asiosdk2/host" -I"../../../asiosdk2/host/pc" -I"../../pa_common"
CXXINCS = -I"C:/Dev-CPP/include/c++" -I"C:/Dev-CPP/include/c++/mingw32" -I"C:/Dev-CPP/include/c++/backward" -I"C:/Dev-CPP/include" -I"../../../asiosdk2" -I"../../../asiosdk2/common" -I"../../../asiosdk2/host" -I"../../../asiosdk2/host/pc" -I"../../pa_common"
BIN = portaudio-dll.dll
CXXFLAGS = $(CXXINCS)-O3 -fmessage-length=0 -Wall
CFLAGS = $(INCS)-DBUILDING_DLL=1 -O3 -fmessage-length=0 -Wall
.PHONY: all all-before all-after clean clean-custom
all: all-before portaudio-dll.dll all-after
clean: clean-custom
rm -f $(OBJ) $(BIN)
DLLWRAP=dllwrap.exe
DEFFILE=libportaudio-dll.def
STATICLIB=libportaudio-dll.a
$(BIN): $(LINKOBJ)
$(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
./pa_skeleton.o: ../../pa_common/pa_skeleton.c
$(CPP) -c ../../pa_common/pa_skeleton.c -o ./pa_skeleton.o $(CXXFLAGS)
./pa_stream.o: ../../pa_common/pa_stream.c
$(CPP) -c ../../pa_common/pa_stream.c -o ./pa_stream.o $(CXXFLAGS)
./pa_trace.o: ../../pa_common/pa_trace.c
$(CPP) -c ../../pa_common/pa_trace.c -o ./pa_trace.o $(CXXFLAGS)
./pa_allocation.o: ../../pa_common/pa_allocation.c
$(CPP) -c ../../pa_common/pa_allocation.c -o ./pa_allocation.o $(CXXFLAGS)
./pa_converters.o: ../../pa_common/pa_converters.c
$(CPP) -c ../../pa_common/pa_converters.c -o ./pa_converters.o $(CXXFLAGS)
./pa_cpuload.o: ../../pa_common/pa_cpuload.c
$(CPP) -c ../../pa_common/pa_cpuload.c -o ./pa_cpuload.o $(CXXFLAGS)
./pa_dither.o: ../../pa_common/pa_dither.c
$(CPP) -c ../../pa_common/pa_dither.c -o ./pa_dither.o $(CXXFLAGS)
./pa_front.o: ../../pa_common/pa_front.c
$(CPP) -c ../../pa_common/pa_front.c -o ./pa_front.o $(CXXFLAGS)
./pa_process.o: ../../pa_common/pa_process.c
$(CPP) -c ../../pa_common/pa_process.c -o ./pa_process.o $(CXXFLAGS)
./pa_asio.o: ../../pa_asio/pa_asio.cpp
$(CPP) -c ../../pa_asio/pa_asio.cpp -o ./pa_asio.o $(CXXFLAGS)
./pa_win_util.o: ../pa_win_util.c
$(CPP) -c ../pa_win_util.c -o ./pa_win_util.o $(CXXFLAGS)
./pa_win_hostapis.o: ../pa_win_hostapis.c
$(CPP) -c ../pa_win_hostapis.c -o ./pa_win_hostapis.o $(CXXFLAGS)
./pa_win_ds.o: ../../pa_win_ds/pa_win_ds.c
$(CPP) -c ../../pa_win_ds/pa_win_ds.c -o ./pa_win_ds.o $(CXXFLAGS)
./dsound_wrapper.o: ../../pa_win_ds/dsound_wrapper.c
$(CPP) -c ../../pa_win_ds/dsound_wrapper.c -o ./dsound_wrapper.o $(CXXFLAGS)
./pa_win_wmme.o: ../../pa_win_wmme/pa_win_wmme.c
$(CPP) -c ../../pa_win_wmme/pa_win_wmme.c -o ./pa_win_wmme.o $(CXXFLAGS)
./iasiothiscallresolver.o: ../../pa_asio/iasiothiscallresolver.cpp
$(CPP) -c ../../pa_asio/iasiothiscallresolver.cpp -o ./iasiothiscallresolver.o $(CXXFLAGS)

View File

@ -1,75 +1,75 @@
# Project: portaudio-static
# Makefile created by Dev-C++ 4.9.8.2
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
RES =
OBJ = ./pa_skeleton.o ./pa_stream.o ./pa_trace.o ./pa_allocation.o ./pa_converters.o ./pa_cpuload.o ./pa_dither.o ./pa_front.o ./pa_process.o ./pa_asio.o ./pa_win_util.o ./pa_win_hostapis.o ./pa_win_ds.o ./dsound_wrapper.o ./pa_win_wmme.o ./iasiothiscallresolver.o $(RES)
LINKOBJ = ./pa_skeleton.o ./pa_stream.o ./pa_trace.o ./pa_allocation.o ./pa_converters.o ./pa_cpuload.o ./pa_dither.o ./pa_front.o ./pa_process.o ./pa_asio.o ./pa_win_util.o ./pa_win_hostapis.o ./pa_win_ds.o ./dsound_wrapper.o ./pa_win_wmme.o ./iasiothiscallresolver.o $(RES)
LIBS = -L"C:/Dev-CPP/lib" -fmessage-length=0 -O3 -s
INCS = -I"C:/Dev-CPP/include" -I"../../../asiosdk2" -I"../../../asiosdk2/common" -I"../../../asiosdk2/host" -I"../../../asiosdk2/host/pc" -I"../../pa_common"
CXXINCS = -I"C:/Dev-CPP/include/c++" -I"C:/Dev-CPP/include/c++/mingw32" -I"C:/Dev-CPP/include/c++/backward" -I"C:/Dev-CPP/include" -I"../../../asiosdk2" -I"../../../asiosdk2/common" -I"../../../asiosdk2/host" -I"../../../asiosdk2/host/pc" -I"../../pa_common"
BIN = portaudio-static.a
CXXFLAGS = $(CXXINCS)-O3 -fmessage-length=0 -Wall
CFLAGS = $(INCS)-O3 -fmessage-length=0 -Wall
.PHONY: all all-before all-after clean clean-custom
all: all-before portaudio-static.a all-after
clean: clean-custom
rm -f $(OBJ) $(BIN)
$(BIN): $(LINKOBJ)
ar r $(BIN) $(LINKOBJ)
ranlib $(BIN)
./pa_skeleton.o: ../../pa_common/pa_skeleton.c
$(CPP) -c ../../pa_common/pa_skeleton.c -o ./pa_skeleton.o $(CXXFLAGS)
./pa_stream.o: ../../pa_common/pa_stream.c
$(CPP) -c ../../pa_common/pa_stream.c -o ./pa_stream.o $(CXXFLAGS)
./pa_trace.o: ../../pa_common/pa_trace.c
$(CPP) -c ../../pa_common/pa_trace.c -o ./pa_trace.o $(CXXFLAGS)
./pa_allocation.o: ../../pa_common/pa_allocation.c
$(CPP) -c ../../pa_common/pa_allocation.c -o ./pa_allocation.o $(CXXFLAGS)
./pa_converters.o: ../../pa_common/pa_converters.c
$(CPP) -c ../../pa_common/pa_converters.c -o ./pa_converters.o $(CXXFLAGS)
./pa_cpuload.o: ../../pa_common/pa_cpuload.c
$(CPP) -c ../../pa_common/pa_cpuload.c -o ./pa_cpuload.o $(CXXFLAGS)
./pa_dither.o: ../../pa_common/pa_dither.c
$(CPP) -c ../../pa_common/pa_dither.c -o ./pa_dither.o $(CXXFLAGS)
./pa_front.o: ../../pa_common/pa_front.c
$(CPP) -c ../../pa_common/pa_front.c -o ./pa_front.o $(CXXFLAGS)
./pa_process.o: ../../pa_common/pa_process.c
$(CPP) -c ../../pa_common/pa_process.c -o ./pa_process.o $(CXXFLAGS)
./pa_asio.o: ../../pa_asio/pa_asio.cpp
$(CPP) -c ../../pa_asio/pa_asio.cpp -o ./pa_asio.o $(CXXFLAGS)
./pa_win_util.o: ../pa_win_util.c
$(CPP) -c ../pa_win_util.c -o ./pa_win_util.o $(CXXFLAGS)
./pa_win_hostapis.o: ../pa_win_hostapis.c
$(CPP) -c ../pa_win_hostapis.c -o ./pa_win_hostapis.o $(CXXFLAGS)
./pa_win_ds.o: ../../pa_win_ds/pa_win_ds.c
$(CPP) -c ../../pa_win_ds/pa_win_ds.c -o ./pa_win_ds.o $(CXXFLAGS)
./dsound_wrapper.o: ../../pa_win_ds/dsound_wrapper.c
$(CPP) -c ../../pa_win_ds/dsound_wrapper.c -o ./dsound_wrapper.o $(CXXFLAGS)
./pa_win_wmme.o: ../../pa_win_wmme/pa_win_wmme.c
$(CPP) -c ../../pa_win_wmme/pa_win_wmme.c -o ./pa_win_wmme.o $(CXXFLAGS)
./iasiothiscallresolver.o: ../../pa_asio/iasiothiscallresolver.cpp
$(CPP) -c ../../pa_asio/iasiothiscallresolver.cpp -o ./iasiothiscallresolver.o $(CXXFLAGS)
# Project: portaudio-static
# Makefile created by Dev-C++ 4.9.8.2
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
RES =
OBJ = ./pa_skeleton.o ./pa_stream.o ./pa_trace.o ./pa_allocation.o ./pa_converters.o ./pa_cpuload.o ./pa_dither.o ./pa_front.o ./pa_process.o ./pa_asio.o ./pa_win_util.o ./pa_win_hostapis.o ./pa_win_ds.o ./dsound_wrapper.o ./pa_win_wmme.o ./iasiothiscallresolver.o $(RES)
LINKOBJ = ./pa_skeleton.o ./pa_stream.o ./pa_trace.o ./pa_allocation.o ./pa_converters.o ./pa_cpuload.o ./pa_dither.o ./pa_front.o ./pa_process.o ./pa_asio.o ./pa_win_util.o ./pa_win_hostapis.o ./pa_win_ds.o ./dsound_wrapper.o ./pa_win_wmme.o ./iasiothiscallresolver.o $(RES)
LIBS = -L"C:/Dev-CPP/lib" -fmessage-length=0 -O3 -s
INCS = -I"C:/Dev-CPP/include" -I"../../../asiosdk2" -I"../../../asiosdk2/common" -I"../../../asiosdk2/host" -I"../../../asiosdk2/host/pc" -I"../../pa_common"
CXXINCS = -I"C:/Dev-CPP/include/c++" -I"C:/Dev-CPP/include/c++/mingw32" -I"C:/Dev-CPP/include/c++/backward" -I"C:/Dev-CPP/include" -I"../../../asiosdk2" -I"../../../asiosdk2/common" -I"../../../asiosdk2/host" -I"../../../asiosdk2/host/pc" -I"../../pa_common"
BIN = portaudio-static.a
CXXFLAGS = $(CXXINCS)-O3 -fmessage-length=0 -Wall
CFLAGS = $(INCS)-O3 -fmessage-length=0 -Wall
.PHONY: all all-before all-after clean clean-custom
all: all-before portaudio-static.a all-after
clean: clean-custom
rm -f $(OBJ) $(BIN)
$(BIN): $(LINKOBJ)
ar r $(BIN) $(LINKOBJ)
ranlib $(BIN)
./pa_skeleton.o: ../../pa_common/pa_skeleton.c
$(CPP) -c ../../pa_common/pa_skeleton.c -o ./pa_skeleton.o $(CXXFLAGS)
./pa_stream.o: ../../pa_common/pa_stream.c
$(CPP) -c ../../pa_common/pa_stream.c -o ./pa_stream.o $(CXXFLAGS)
./pa_trace.o: ../../pa_common/pa_trace.c
$(CPP) -c ../../pa_common/pa_trace.c -o ./pa_trace.o $(CXXFLAGS)
./pa_allocation.o: ../../pa_common/pa_allocation.c
$(CPP) -c ../../pa_common/pa_allocation.c -o ./pa_allocation.o $(CXXFLAGS)
./pa_converters.o: ../../pa_common/pa_converters.c
$(CPP) -c ../../pa_common/pa_converters.c -o ./pa_converters.o $(CXXFLAGS)
./pa_cpuload.o: ../../pa_common/pa_cpuload.c
$(CPP) -c ../../pa_common/pa_cpuload.c -o ./pa_cpuload.o $(CXXFLAGS)
./pa_dither.o: ../../pa_common/pa_dither.c
$(CPP) -c ../../pa_common/pa_dither.c -o ./pa_dither.o $(CXXFLAGS)
./pa_front.o: ../../pa_common/pa_front.c
$(CPP) -c ../../pa_common/pa_front.c -o ./pa_front.o $(CXXFLAGS)
./pa_process.o: ../../pa_common/pa_process.c
$(CPP) -c ../../pa_common/pa_process.c -o ./pa_process.o $(CXXFLAGS)
./pa_asio.o: ../../pa_asio/pa_asio.cpp
$(CPP) -c ../../pa_asio/pa_asio.cpp -o ./pa_asio.o $(CXXFLAGS)
./pa_win_util.o: ../pa_win_util.c
$(CPP) -c ../pa_win_util.c -o ./pa_win_util.o $(CXXFLAGS)
./pa_win_hostapis.o: ../pa_win_hostapis.c
$(CPP) -c ../pa_win_hostapis.c -o ./pa_win_hostapis.o $(CXXFLAGS)
./pa_win_ds.o: ../../pa_win_ds/pa_win_ds.c
$(CPP) -c ../../pa_win_ds/pa_win_ds.c -o ./pa_win_ds.o $(CXXFLAGS)
./dsound_wrapper.o: ../../pa_win_ds/dsound_wrapper.c
$(CPP) -c ../../pa_win_ds/dsound_wrapper.c -o ./dsound_wrapper.o $(CXXFLAGS)
./pa_win_wmme.o: ../../pa_win_wmme/pa_win_wmme.c
$(CPP) -c ../../pa_win_wmme/pa_win_wmme.c -o ./pa_win_wmme.o $(CXXFLAGS)
./iasiothiscallresolver.o: ../../pa_asio/iasiothiscallresolver.cpp
$(CPP) -c ../../pa_asio/iasiothiscallresolver.cpp -o ./iasiothiscallresolver.o $(CXXFLAGS)

View File

@ -1,209 +1,209 @@
[Project]
FileName=portaudio-dll.dev
Name=portaudio-dll
UnitCount=16
Type=3
Ver=1
ObjFiles=
Includes=..\..\..\asiosdk2;..\..\..\asiosdk2\common;..\..\..\asiosdk2\host;..\..\..\asiosdk2\host\pc;..\..\pa_common
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=-DBUILDING_DLL=1_@@_-O3_@@_
CppCompiler=-O3_@@_
Linker=--no-export-all-symbols --add-stdcall-alias_@@_../../../asiosdk2/asiosdk2.a_@@_-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lwinmm_@@_-O3 -s_@@_
IsCpp=1
Icon=
ExeOutput=.
ObjectOutput=.
OverrideOutput=0
OverrideOutputName=portaudio.a
HostApplication=
Folders=
CommandLine=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000000000000000
UseCustomMakefile=0
CustomMakefile=
[Unit1]
FileName=..\..\pa_common\pa_skeleton.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_skeleton.c -o ./pa_skeleton.o $(CFLAGS)
[Unit2]
FileName=..\..\pa_common\pa_stream.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_stream.c -o ./pa_stream.o $(CFLAGS)
[Unit3]
FileName=..\..\pa_common\pa_trace.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_trace.c -o ./pa_trace.o $(CFLAGS)
[Unit4]
FileName=..\..\pa_common\pa_allocation.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_allocation.c -o ./pa_allocation.o $(CFLAGS)
[Unit5]
FileName=..\..\pa_common\pa_converters.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_converters.c -o ./pa_converters.o $(CFLAGS)
[Unit6]
FileName=..\..\pa_common\pa_cpuload.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_cpuload.c -o ./pa_cpuload.o $(CFLAGS)
[Unit7]
FileName=..\..\pa_common\pa_dither.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_dither.c -o ./pa_dither.o $(CFLAGS)
[Unit8]
FileName=..\..\pa_common\pa_front.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_front.c -o ./pa_front.o $(CFLAGS)
[Unit9]
FileName=..\..\pa_common\pa_process.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_process.c -o ./pa_process.o $(CFLAGS)
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
[Unit10]
FileName=..\..\pa_asio\pa_asio.cpp
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CPP) -c pa_asio.cpp -o ./pa_asio.o $(CXXFLAGS)
[Unit11]
FileName=..\pa_win_util.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_util.c -o ./pa_win_util.o $(CFLAGS)
[Unit12]
FileName=..\pa_win_hostapis.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_hostapis.c -o ./pa_win_hostapis.o $(CFLAGS)
[Unit13]
FileName=..\..\pa_win_ds\pa_win_ds.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_ds.c -o ./pa_win_ds.o $(CFLAGS)
[Unit14]
FileName=..\..\pa_win_ds\dsound_wrapper.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c dsound_wrapper.c -o ./dsound_wrapper.o $(CFLAGS)
[Unit15]
FileName=..\..\pa_win_wmme\pa_win_wmme.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_wmme.c -o ./pa_win_wmme.o $(CFLAGS)
[Unit16]
FileName=..\..\pa_asio\iasiothiscallresolver.cpp
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Project]
FileName=portaudio-dll.dev
Name=portaudio-dll
UnitCount=16
Type=3
Ver=1
ObjFiles=
Includes=..\..\..\asiosdk2;..\..\..\asiosdk2\common;..\..\..\asiosdk2\host;..\..\..\asiosdk2\host\pc;..\..\pa_common
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=-DBUILDING_DLL=1_@@_-O3_@@_
CppCompiler=-O3_@@_
Linker=--no-export-all-symbols --add-stdcall-alias_@@_../../../asiosdk2/asiosdk2.a_@@_-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lwinmm_@@_-O3 -s_@@_
IsCpp=1
Icon=
ExeOutput=.
ObjectOutput=.
OverrideOutput=0
OverrideOutputName=portaudio.a
HostApplication=
Folders=
CommandLine=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000000000000000
UseCustomMakefile=0
CustomMakefile=
[Unit1]
FileName=..\..\pa_common\pa_skeleton.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_skeleton.c -o ./pa_skeleton.o $(CFLAGS)
[Unit2]
FileName=..\..\pa_common\pa_stream.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_stream.c -o ./pa_stream.o $(CFLAGS)
[Unit3]
FileName=..\..\pa_common\pa_trace.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_trace.c -o ./pa_trace.o $(CFLAGS)
[Unit4]
FileName=..\..\pa_common\pa_allocation.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_allocation.c -o ./pa_allocation.o $(CFLAGS)
[Unit5]
FileName=..\..\pa_common\pa_converters.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_converters.c -o ./pa_converters.o $(CFLAGS)
[Unit6]
FileName=..\..\pa_common\pa_cpuload.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_cpuload.c -o ./pa_cpuload.o $(CFLAGS)
[Unit7]
FileName=..\..\pa_common\pa_dither.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_dither.c -o ./pa_dither.o $(CFLAGS)
[Unit8]
FileName=..\..\pa_common\pa_front.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_front.c -o ./pa_front.o $(CFLAGS)
[Unit9]
FileName=..\..\pa_common\pa_process.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_process.c -o ./pa_process.o $(CFLAGS)
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
[Unit10]
FileName=..\..\pa_asio\pa_asio.cpp
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CPP) -c pa_asio.cpp -o ./pa_asio.o $(CXXFLAGS)
[Unit11]
FileName=..\pa_win_util.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_util.c -o ./pa_win_util.o $(CFLAGS)
[Unit12]
FileName=..\pa_win_hostapis.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_hostapis.c -o ./pa_win_hostapis.o $(CFLAGS)
[Unit13]
FileName=..\..\pa_win_ds\pa_win_ds.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_ds.c -o ./pa_win_ds.o $(CFLAGS)
[Unit14]
FileName=..\..\pa_win_ds\dsound_wrapper.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c dsound_wrapper.c -o ./dsound_wrapper.o $(CFLAGS)
[Unit15]
FileName=..\..\pa_win_wmme\pa_win_wmme.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_wmme.c -o ./pa_win_wmme.o $(CFLAGS)
[Unit16]
FileName=..\..\pa_asio\iasiothiscallresolver.cpp
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

View File

@ -1,209 +1,209 @@
[Project]
FileName=portaudio-static.dev
Name=portaudio-static
UnitCount=16
Type=2
Ver=1
ObjFiles=
Includes=..\..\..\asiosdk2;..\..\..\asiosdk2\common;..\..\..\asiosdk2\host;..\..\..\asiosdk2\host\pc;..\..\pa_common
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=-O3_@@_
CppCompiler=-O3_@@_
Linker=-O3 -s_@@_
IsCpp=1
Icon=
ExeOutput=.
ObjectOutput=.
OverrideOutput=0
OverrideOutputName=portaudio.a
HostApplication=
Folders=
CommandLine=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000000000000000
UseCustomMakefile=0
CustomMakefile=
[Unit1]
FileName=..\..\pa_common\pa_skeleton.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_skeleton.c -o ./pa_skeleton.o $(CFLAGS)
[Unit2]
FileName=..\..\pa_common\pa_stream.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_stream.c -o ./pa_stream.o $(CFLAGS)
[Unit3]
FileName=..\..\pa_common\pa_trace.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_trace.c -o ./pa_trace.o $(CFLAGS)
[Unit4]
FileName=..\..\pa_common\pa_allocation.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_allocation.c -o ./pa_allocation.o $(CFLAGS)
[Unit5]
FileName=..\..\pa_common\pa_converters.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_converters.c -o ./pa_converters.o $(CFLAGS)
[Unit6]
FileName=..\..\pa_common\pa_cpuload.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_cpuload.c -o ./pa_cpuload.o $(CFLAGS)
[Unit7]
FileName=..\..\pa_common\pa_dither.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_dither.c -o ./pa_dither.o $(CFLAGS)
[Unit8]
FileName=..\..\pa_common\pa_front.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_front.c -o ./pa_front.o $(CFLAGS)
[Unit9]
FileName=..\..\pa_common\pa_process.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_process.c -o ./pa_process.o $(CFLAGS)
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
[Unit10]
FileName=..\..\pa_asio\pa_asio.cpp
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CPP) -c pa_asio.cpp -o ./pa_asio.o $(CXXFLAGS)
[Unit11]
FileName=..\..\pa_win\pa_win_util.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_util.c -o ./pa_win_util.o $(CFLAGS)
[Unit12]
FileName=..\..\pa_win\pa_win_hostapis.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_hostapis.c -o ./pa_win_hostapis.o $(CFLAGS)
[Unit13]
FileName=..\..\pa_win_ds\pa_win_ds.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_ds.c -o ./pa_win_ds.o $(CFLAGS)
[Unit14]
FileName=..\..\pa_win_ds\dsound_wrapper.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c dsound_wrapper.c -o ./dsound_wrapper.o $(CFLAGS)
[Unit15]
FileName=..\..\pa_win_wmme\pa_win_wmme.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_wmme.c -o ./pa_win_wmme.o $(CFLAGS)
[Unit16]
FileName=..\..\pa_asio\iasiothiscallresolver.cpp
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Project]
FileName=portaudio-static.dev
Name=portaudio-static
UnitCount=16
Type=2
Ver=1
ObjFiles=
Includes=..\..\..\asiosdk2;..\..\..\asiosdk2\common;..\..\..\asiosdk2\host;..\..\..\asiosdk2\host\pc;..\..\pa_common
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=-O3_@@_
CppCompiler=-O3_@@_
Linker=-O3 -s_@@_
IsCpp=1
Icon=
ExeOutput=.
ObjectOutput=.
OverrideOutput=0
OverrideOutputName=portaudio.a
HostApplication=
Folders=
CommandLine=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000000000000000
UseCustomMakefile=0
CustomMakefile=
[Unit1]
FileName=..\..\pa_common\pa_skeleton.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_skeleton.c -o ./pa_skeleton.o $(CFLAGS)
[Unit2]
FileName=..\..\pa_common\pa_stream.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_stream.c -o ./pa_stream.o $(CFLAGS)
[Unit3]
FileName=..\..\pa_common\pa_trace.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_trace.c -o ./pa_trace.o $(CFLAGS)
[Unit4]
FileName=..\..\pa_common\pa_allocation.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_allocation.c -o ./pa_allocation.o $(CFLAGS)
[Unit5]
FileName=..\..\pa_common\pa_converters.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_converters.c -o ./pa_converters.o $(CFLAGS)
[Unit6]
FileName=..\..\pa_common\pa_cpuload.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_cpuload.c -o ./pa_cpuload.o $(CFLAGS)
[Unit7]
FileName=..\..\pa_common\pa_dither.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_dither.c -o ./pa_dither.o $(CFLAGS)
[Unit8]
FileName=..\..\pa_common\pa_front.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_front.c -o ./pa_front.o $(CFLAGS)
[Unit9]
FileName=..\..\pa_common\pa_process.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_process.c -o ./pa_process.o $(CFLAGS)
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
[Unit10]
FileName=..\..\pa_asio\pa_asio.cpp
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CPP) -c pa_asio.cpp -o ./pa_asio.o $(CXXFLAGS)
[Unit11]
FileName=..\..\pa_win\pa_win_util.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_util.c -o ./pa_win_util.o $(CFLAGS)
[Unit12]
FileName=..\..\pa_win\pa_win_hostapis.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_hostapis.c -o ./pa_win_hostapis.o $(CFLAGS)
[Unit13]
FileName=..\..\pa_win_ds\pa_win_ds.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_ds.c -o ./pa_win_ds.o $(CFLAGS)
[Unit14]
FileName=..\..\pa_win_ds\dsound_wrapper.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c dsound_wrapper.c -o ./dsound_wrapper.o $(CFLAGS)
[Unit15]
FileName=..\..\pa_win_wmme\pa_win_wmme.c
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c pa_win_wmme.c -o ./pa_win_wmme.o $(CFLAGS)
[Unit16]
FileName=..\..\pa_asio\iasiothiscallresolver.cpp
CompileCpp=1
Folder=portaudio
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

View File

@ -1,23 +1,23 @@
From: "Peter L Jones"
Sent: Wednesday, September 17, 2003 5:18 AM
Subject: Dev-C++ project files
I attach two project files intended for portaudio/pa_win/dev-cpp (i.e. in
parallel with the msvc directory), if you want them. One is for a static
library build and one for a DLL. I've used the static library (in building
a single monolithic DLL) but I can't guarantee the DLL version will build a
working library (I think it's mostly there, though!).
I also attach the resulting makefiles, which may be of use to other MinGW
users.
They're rooted in the directory given above and drop their object and
library files in the same place. They assume the asiosdk2 files are in the
same directory as portaudio/ in a sub-directory called asiosdk2/. Oh! The
DLL is built against a static asiosdk2.a library... maybe not the best way
to do it... I ought to figure out how to link against a "home made" dll in
Dev-C++, I guess ;-)
Cheers,
-- Peter
From: "Peter L Jones"
Sent: Wednesday, September 17, 2003 5:18 AM
Subject: Dev-C++ project files
I attach two project files intended for portaudio/pa_win/dev-cpp (i.e. in
parallel with the msvc directory), if you want them. One is for a static
library build and one for a DLL. I've used the static library (in building
a single monolithic DLL) but I can't guarantee the DLL version will build a
working library (I think it's mostly there, though!).
I also attach the resulting makefiles, which may be of use to other MinGW
users.
They're rooted in the directory given above and drop their object and
library files in the same place. They assume the asiosdk2 files are in the
same directory as portaudio/ in a sub-directory called asiosdk2/. Oh! The
DLL is built against a static asiosdk2.a library... maybe not the best way
to do it... I ought to figure out how to link against a "home made" dll in
Dev-C++, I guess ;-)
Cheers,
-- Peter

View File

@ -1,48 +1,50 @@
EXPORTS
;
Pa_GetVersion @1
Pa_GetVersionText @2
Pa_GetErrorText @3
Pa_Initialize @4
Pa_Terminate @5
Pa_GetHostApiCount @6
Pa_GetDefaultHostApi @7
Pa_GetHostApiInfo @8
Pa_HostApiTypeIdToHostApiIndex @9
Pa_HostApiDeviceIndexToDeviceIndex @10
Pa_GetLastHostErrorInfo @11
Pa_GetDeviceCount @12
Pa_GetDefaultInputDevice @13
Pa_GetDefaultOutputDevice @14
Pa_GetDeviceInfo @15
Pa_IsFormatSupported @16
Pa_OpenStream @17
Pa_OpenDefaultStream @18
Pa_CloseStream @19
Pa_SetStreamFinishedCallback @20
Pa_StartStream @21
Pa_StopStream @22
Pa_AbortStream @23
Pa_IsStreamStopped @24
Pa_IsStreamActive @25
Pa_GetStreamInfo @26
Pa_GetStreamTime @27
Pa_GetStreamCpuLoad @28
Pa_ReadStream @29
Pa_WriteStream @30
Pa_GetStreamReadAvailable @31
Pa_GetStreamWriteAvailable @32
Pa_GetSampleSize @33
Pa_Sleep @34
PaAsio_GetAvailableLatencyValues @50
PaAsio_ShowControlPanel @51
PaUtil_InitializeX86PlainConverters @52
PaAsio_GetInputChannelName @53
PaAsio_GetOutputChannelName @54
PaUtil_SetDebugPrintFunction @55
PaWasapi_GetDeviceDefaultFormat @56
PaWasapi_GetDeviceRole @57
PaWasapi_ThreadPriorityBoost @58
PaWasapi_ThreadPriorityRevert @59
PaWasapi_GetFramesPerHostBuffer @60
EXPORTS
;
Pa_GetVersion @1
Pa_GetVersionText @2
Pa_GetErrorText @3
Pa_Initialize @4
Pa_Terminate @5
Pa_GetHostApiCount @6
Pa_GetDefaultHostApi @7
Pa_GetHostApiInfo @8
Pa_HostApiTypeIdToHostApiIndex @9
Pa_HostApiDeviceIndexToDeviceIndex @10
Pa_GetLastHostErrorInfo @11
Pa_GetDeviceCount @12
Pa_GetDefaultInputDevice @13
Pa_GetDefaultOutputDevice @14
Pa_GetDeviceInfo @15
Pa_IsFormatSupported @16
Pa_OpenStream @17
Pa_OpenDefaultStream @18
Pa_CloseStream @19
Pa_SetStreamFinishedCallback @20
Pa_StartStream @21
Pa_StopStream @22
Pa_AbortStream @23
Pa_IsStreamStopped @24
Pa_IsStreamActive @25
Pa_GetStreamInfo @26
Pa_GetStreamTime @27
Pa_GetStreamCpuLoad @28
Pa_ReadStream @29
Pa_WriteStream @30
Pa_GetStreamReadAvailable @31
Pa_GetStreamWriteAvailable @32
Pa_GetSampleSize @33
Pa_Sleep @34
PaAsio_GetAvailableLatencyValues @50
PaAsio_ShowControlPanel @51
PaUtil_InitializeX86PlainConverters @52
PaAsio_GetInputChannelName @53
PaAsio_GetOutputChannelName @54
PaUtil_SetDebugPrintFunction @55
PaWasapi_GetDeviceDefaultFormat @56
PaWasapi_GetDeviceRole @57
PaWasapi_ThreadPriorityBoost @58
PaWasapi_ThreadPriorityRevert @59
PaWasapi_GetFramesPerHostBuffer @60
PaWasapi_GetJackDescription @61
PaWasapi_GetJackCount @62

View File

@ -42,3 +42,5 @@ PaWasapi_GetDeviceRole @57
PaWasapi_ThreadPriorityBoost @58
PaWasapi_ThreadPriorityRevert @59
PaWasapi_GetFramesPerHostBuffer @60
PaWasapi_GetJackDescription @61
PaWasapi_GetJackCount @62

109
3rdparty/portaudio/build/msvc/readme.txt vendored Normal file
View File

@ -0,0 +1,109 @@
Hello
This is a small list of steps in order to build portaudio
(Currently v19-devel) into a VC6 DLL and lib file.
This DLL contains all 3 current win32 PA APIS (MM/DS/ASIO)
1)Copy the source dirs that comes with the ASIO SDK inside src\hostapi\asio\ASIOSDK
so you should now have example:
portaudio19svn\src\hostapi\asio\ASIOSDK\common
portaudio19svn\src\hostapi\asio\ASIOSDK\host
portaudio19svn\src\hostapi\asio\ASIOSDK\host\sample
portaudio19svn\src\hostapi\asio\ASIOSDK\host\pc
portaudio19svn\src\hostapi\asio\ASIOSDK\host\mac (not needed)
You dont need "driver"
To build without ASIO (or another Host API) see the "Building without ASIO support" section below.
2)
*If you have Visual Studio 6.0*, please make sure you have it updated with the latest (and final)
microsoft libraries for it, namely:
Service pack 5:
Latest known URL:
http://msdn2.microsoft.com/en-us/vstudio/aa718363.aspx
Yes there EXISTS a service pack 6 , but the processor pack (below) isnt compatible with it.
Processor Pack(only works with above SP5)
Latest known URL:
http://msdn2.microsoft.com/en-us/vstudio/Aa718349.aspx
This isnt absolutely required for portaudio, but if you plan on using SSE intrinsics and similar things.
Up to you to decide upon Service pack 5 or 6 depending on your need for intrinsics.
Platform SDK (Feb 2003) :
Latest known URL:
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
(This will allow your code base to be x64 friendly, with correct defines
for LONG_PTR and such)
NOTE A) Yes you have to use IE activex scripts to install that - wont work in Firefox, you
may have to temporarily change tyour default browser(aint life unfair)
NOTE B) Dont forget to hit "Register PSDK Directories with Visual Studio".
you can make sure its right in VC6 if you open tools/options/directories/include files and you see SDK 2003 as the FIRST entry
(it must be the same for libs)
DirectX 9.0 SDK Update - (Summer 2003)
Latest known URL:
http://www.microsoft.com/downloads/details.aspx?familyid=9216652f-51e0-402e-b7b5-feb68d00f298&displaylang=en
Again register the links in VC6, and check inside vc6 if headers are in second place right after SDk 2003
*If you have 7.0(VC.NET/2001) or 7.1(VC.2003) *
then I suggest you open portaudio.dsp (and convert if needed)
*If you have Visual Studio 2005*, I suggest you open the portaudio.sln file
which contains 4 configurations. Win32/x64 in both Release and Debug variants
hit compile and hope for the best.
3)Now in any project, in which you require portaudio,
you can just link with portaudio_x86.lib, (or _x64) and of course include the
relevant headers
(portaudio.h, and/or pa_asio.h , pa_x86_plain_converters.h) See (*)
4) Your new exe should now use portaudio_xXX.dll.
Have fun!
(*): you may want to add/remove some DLL entry points.
Right now those 6 entries are _not_ from portaudio.h
(from portaudio.def)
(...)
PaAsio_GetAvailableLatencyValues @50
PaAsio_ShowControlPanel @51
PaUtil_InitializeX86PlainConverters @52
PaAsio_GetInputChannelName @53
PaAsio_GetOutputChannelName @54
PaUtil_SetLogPrintFunction @55
*** Building without ASIO support ***
To build PortAudio without ASIO support you need to:
A. Make sure your project doesn't try to build any ASIO SDK files.
If you're using one of the shipped projects, remove the ASIO related files
from the project.
B. Make sure your project doesn't try to build the PortAudio ASIO
implementation files:
src/hostapi/pa_asio.cpp src/hostapi/iasiothiscallresolver.cpp
If you're using one of the shipped projects remove them from the project.
C. Define the PA_NO_ASIO preprocessor symbol in the project properties.
In VS2005 this can be added under
Project Properties > Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions
Defining PA_NO_ASIO stops src/os/win/pa_win_hostapis.c
from trying to initialize the PA ASIO implementation.
D. Remove PaAsio_* entry points from portaudio.def
A similar procedure can be used to omit any of the other host APIs from the
build. The relevant preprocessor symbols used by pa_win_hostapis.c are:
PA_NO_WMME, PA_NO_DS, PA_NO_ASIO, PA_NO_WASAPI and PA_NO_WDMKS
-----
David Viens, davidv@plogue.com

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,427 +1,427 @@
dnl
dnl portaudio V19 configure.in script
dnl
dnl Dominic Mazzoni, Arve Knudsen, Stelios Bounanos
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([include/portaudio.h])
dnl Define build, build_cpu, build_vendor, build_os
AC_CANONICAL_BUILD
dnl Define host, host_cpu, host_vendor, host_os
AC_CANONICAL_HOST
dnl Define target, target_cpu, target_vendor, target_os
AC_CANONICAL_TARGET
dnl Specify options
AC_ARG_WITH(alsa,
AS_HELP_STRING([--with-alsa], [Enable support for ALSA @<:@autodetect@:>@]),
[with_alsa=$withval])
AC_ARG_WITH(jack,
AS_HELP_STRING([--with-jack], [Enable support for JACK @<:@autodetect@:>@]),
[with_jack=$withval])
AC_ARG_WITH(oss,
AS_HELP_STRING([--with-oss], [Enable support for OSS @<:@autodetect@:>@]),
[with_oss=$withval])
AC_ARG_WITH(asihpi,
AS_HELP_STRING([--with-asihpi], [Enable support for ASIHPI @<:@autodetect@:>@]),
[with_asihpi=$withval])
AC_ARG_WITH(winapi,
AS_HELP_STRING([--with-winapi],
[Select Windows API support (@<:@wmme|directx|asio|wasapi|wdmks@:>@@<:@,...@:>@) @<:@wmme@:>@]),
[with_winapi=$withval], [with_winapi="wmme"])
case "$target_os" in *mingw* | *cygwin*)
with_wmme=no
with_directx=no
with_asio=no
with_wasapi=no
with_wdmks=no
for api in $(echo $with_winapi | sed 's/,/ /g'); do
case "$api" in
wmme|directx|asio|wasapi|wdmks)
eval with_$api=yes
;;
*)
AC_MSG_ERROR([unknown Windows API \"$api\" (do you need --help?)])
;;
esac
done
;;
esac
AC_ARG_WITH(asiodir,
AS_HELP_STRING([--with-asiodir], [ASIO directory @<:@/usr/local/asiosdk2@:>@]),
with_asiodir=$withval, with_asiodir="/usr/local/asiosdk2")
AC_ARG_WITH(dxdir,
AS_HELP_STRING([--with-dxdir], [DirectX directory @<:@/usr/local/dx7sdk@:>@]),
with_dxdir=$withval, with_dxdir="/usr/local/dx7sdk")
debug_output=no
AC_ARG_ENABLE(debug-output,
AS_HELP_STRING([--enable-debug-output], [Enable debug output @<:@no@:>@]),
[if test "x$enableval" != "xno" ; then
AC_DEFINE(PA_ENABLE_DEBUG_OUTPUT,,[Enable debugging messages])
debug_output=yes
fi
])
AC_ARG_ENABLE(cxx,
AS_HELP_STRING([--enable-cxx], [Enable C++ bindings @<:@no@:>@]),
enable_cxx=$enableval, enable_cxx="no")
AC_ARG_ENABLE(mac-debug,
AS_HELP_STRING([--enable-mac-debug], [Enable Mac debug @<:@no@:>@]),
enable_mac_debug=$enableval, enable_mac_debug="no")
AC_ARG_ENABLE(mac-universal,
AS_HELP_STRING([--enable-mac-universal], [Build Mac universal binaries @<:@yes@:>@]),
enable_mac_universal=$enableval, enable_mac_universal="yes")
dnl Continue to accept --host_os for compatibility but do not document
dnl it (the correct way to change host_os is with --host=...). Moved
dnl here because the empty help string generates a blank line which we
dnl can use to separate PA options from libtool options.
AC_ARG_WITH(host_os, [], host_os=$withval)
dnl Checks for programs.
AC_PROG_CC
AC_LIBTOOL_WIN32_DLL
AC_PROG_LIBTOOL
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PATH_PROG(AR, ar, no)
if [[ $AR = "no" ]] ; then
AC_MSG_ERROR("Could not find ar - needed to create a library")
fi
dnl This must be one of the first tests we do or it will fail...
AC_C_BIGENDIAN
dnl checks for various host APIs and arguments to configure that
dnl turn them on or off
have_alsa=no
if test "x$with_alsa" != "xno"; then
AC_CHECK_LIB(asound, snd_pcm_open, have_alsa=yes, have_alsa=no)
fi
have_asihpi=no
if test "x$with_asihpi" != "xno"; then
AC_CHECK_LIB(hpi, HPI_SubSysCreate, have_asihpi=yes, have_asihpi=no, -lm)
fi
have_libossaudio=no
have_oss=no
if test "x$with_oss" != "xno"; then
AC_CHECK_HEADERS([sys/soundcard.h linux/soundcard.h machine/soundcard.h], [have_oss=yes])
if test "x$have_oss" = "xyes"; then
AC_CHECK_LIB(ossaudio, _oss_ioctl, have_libossaudio=yes, have_libossaudio=no)
fi
fi
have_jack=no
if test "x$with_jack" != "xno"; then
PKG_CHECK_MODULES(JACK, jack, have_jack=yes, have_jack=no)
fi
dnl sizeof checks: we will need a 16-bit and a 32-bit type
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
save_LIBS="${LIBS}"
AC_CHECK_LIB(rt, clock_gettime, [rt_libs=" -lrt"])
LIBS="${LIBS}${rt_libs}"
DLL_LIBS="${DLL_LIBS}${rt_libs}"
AC_CHECK_FUNCS([clock_gettime nanosleep])
LIBS="${save_LIBS}"
dnl LT_RELEASE=19
LT_CURRENT=2
LT_REVISION=0
LT_AGE=0
AC_SUBST(LT_CURRENT)
AC_SUBST(LT_REVISION)
AC_SUBST(LT_AGE)
dnl extra variables
AC_SUBST(OTHER_OBJS)
AC_SUBST(PADLL)
AC_SUBST(SHARED_FLAGS)
AC_SUBST(THREAD_CFLAGS)
AC_SUBST(DLL_LIBS)
AC_SUBST(CXXFLAGS)
AC_SUBST(NASM)
AC_SUBST(NASMOPT)
dnl -g is optional on darwin
if ( echo "${host_os}" | grep ^darwin >> /dev/null ) &&
[[ "$enable_mac_universal" = "yes" ] &&
[ "$enable_mac_debug" != "yes" ]] ; then
CFLAGS="-O2 -Wall -pedantic -pipe -fPIC -DNDEBUG"
else
CFLAGS=${CFLAGS:-"-g -O2 -Wall -pedantic -pipe -fPIC"}
fi
if [[ $ac_cv_c_bigendian = "yes" ]] ; then
CFLAGS="$CFLAGS -DPA_BIG_ENDIAN"
else
CFLAGS="$CFLAGS -DPA_LITTLE_ENDIAN"
fi
add_objects()
{
for o in $@; do
test "${OTHER_OBJS#*${o}*}" = "${OTHER_OBJS}" && OTHER_OBJS="$OTHER_OBJS $o"
done
}
case "${host_os}" in
darwin* )
dnl Mac OS X configuration
AC_DEFINE(PA_USE_COREAUDIO)
CFLAGS="$CFLAGS -Werror"
LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon"
if test "x$enable_mac_universal" = "xyes" ; then
mac_version_min="-mmacosx-version-min=10.3"
if [[ -d /Developer/SDKs/MacOSX10.5.sdk ]] ; then
mac_arches="-arch i386 -arch ppc -arch x86_64 -arch ppc64"
mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.5.sdk"
else
mac_arches="-arch i386 -arch ppc"
mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.4u.sdk"
fi
else
mac_arches=""
mac_sysroot=""
mac_version=""
fi
SHARED_FLAGS="$LIBS -dynamiclib $mac_arches $mac_sysroot $mac_version_min"
CFLAGS="-std=c99 $CFLAGS $mac_arches $mac_sysroot $mac_version_min"
OTHER_OBJS="src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o src/hostapi/coreaudio/pa_mac_core.o src/hostapi/coreaudio/pa_mac_core_utilities.o src/hostapi/coreaudio/pa_mac_core_blocking.o src/common/pa_ringbuffer.o"
PADLL="libportaudio.dylib"
;;
mingw* )
dnl MingW configuration
PADLL="portaudio.dll"
THREAD_CFLAGS="-mthreads"
SHARED_FLAGS="-shared"
CFLAGS="$CFLAGS -I\$(top_srcdir)/include -DPA_NO_WMME -DPA_NO_ASIO -DPA_NO_WDMKS -DPA_NO_DS -DPA_NO_WASAPI"
if [[ "x$with_directx" = "xyes" ]]; then
DXDIR="$with_dxdir"
add_objects src/hostapi/dsound/pa_win_ds.o src/hostapi/dsound/pa_win_ds_dynlink.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_waveformat.o
LIBS="-lwinmm -lm -ldsound -lole32"
DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L$DXDIR/lib -ldsound -lole32"
#VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\""
#CFLAGS="$CFLAGS -I$VC98 -DPA_NO_WMME -DPA_NO_ASIO"
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/os/win -I$DXDIR/include -UPA_NO_DS"
fi
if [[ "x$with_asio" = "xyes" ]]; then
ASIODIR="$with_asiodir"
add_objects src/hostapi/asio/pa_asio.o src/common/pa_ringbuffer.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/hostapi/asio/iasiothiscallresolver.o $ASIODIR/common/asio.o $ASIODIR/host/asiodrivers.o $ASIODIR/host/pc/asiolist.o
LIBS="-lwinmm -lm -lole32 -luuid"
DLL_LIBS="${DLL_LIBS} -lwinmm -lm -lole32 -luuid"
CFLAGS="$CFLAGS -ffast-math -fomit-frame-pointer -I\$(top_srcdir)/src/common -I\$(top_srcdir)/src/hostapi/asio -I$ASIODIR/host/pc -I$ASIODIR/common -I$ASIODIR/host -UPA_NO_ASIO -DWINDOWS"
CXXFLAGS="$CFLAGS"
fi
if [[ "x$with_wdmks" = "xyes" ]]; then
DXDIR="$with_dxdir"
add_objects src/hostapi/wdmks/pa_win_wdmks.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o
LIBS="-lwinmm -lm -luuid -lsetupapi -lole32"
DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L$DXDIR/lib -luuid -lsetupapi -lole32"
#VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\""
#CFLAGS="$CFLAGS -I$VC98 -DPA_NO_WMME -DPA_NO_ASIO"
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/common -I$DXDIR/include -UPA_NO_WDMKS"
fi
if [[ "x$with_wmme" = "xyes" ]]; then
add_objects src/hostapi/wmme/pa_win_wmme.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_waveformat.o
LIBS="-lwinmm -lm -lole32 -luuid"
DLL_LIBS="${DLL_LIBS} -lwinmm"
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/common -UPA_NO_WMME"
fi
if [[ "x$with_wasapi" = "xyes" ]]; then
add_objects src/hostapi/wasapi/pa_win_wasapi.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_waveformat.o
LIBS="-lwinmm -lm -lole32 -luuid"
DLL_LIBS="${DLL_LIBS} -lwinmm"
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/common -I\$(top_srcdir)/src/hostapi/wasapi/mingw-include -UPA_NO_WASAPI"
fi
;;
cygwin* )
dnl Cygwin configuration
OTHER_OBJS="src/hostapi/wmme/pa_win_wmme.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_waveformat.o"
CFLAGS="$CFLAGS -DPA_NO_DS -DPA_NO_WDMKS -DPA_NO_ASIO -DPA_NO_WASAPI"
LIBS="-lwinmm -lm"
PADLL="portaudio.dll"
THREAD_CFLAGS="-mthreads"
SHARED_FLAGS="-shared"
DLL_LIBS="${DLL_LIBS} -lwinmm"
;;
irix* )
dnl SGI IRIX audio library (AL) configuration (Pieter, oct 2-13, 2003).
dnl The 'dmedia' library is needed to read the Unadjusted System Time (UST).
dnl
AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR([IRIX posix thread library not found!]))
AC_CHECK_LIB(audio, alOpenPort, , AC_MSG_ERROR([IRIX audio library not found!]))
AC_CHECK_LIB(dmedia, dmGetUST, , AC_MSG_ERROR([IRIX digital media library not found!]))
dnl See the '#ifdef PA_USE_SGI' in file pa_unix/pa_unix_hostapis.c
dnl which selects the appropriate PaXXX_Initialize() function.
dnl
AC_DEFINE(PA_USE_SGI)
dnl The _REENTRANT option for pthread safety. Perhaps not necessary but it 'll do no harm.
dnl
THREAD_CFLAGS="-D_REENTRANT"
OTHER_OBJS="pa_sgi/pa_sgi.o src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o"
dnl SGI books say -lpthread should be the last of the libs mentioned.
dnl
LIBS="-lm -ldmedia -laudio -lpthread"
PADLL="libportaudio.so"
SHARED_FLAGS=""
;;
*)
dnl Unix configuration
AC_CHECK_LIB(pthread, pthread_create,[have_pthread="yes"],
AC_MSG_ERROR([libpthread not found!]))
if [[ "$have_alsa" = "yes" ] && [ "$with_alsa" != "no" ]] ; then
DLL_LIBS="$DLL_LIBS -lasound"
LIBS="$LIBS -lasound"
OTHER_OBJS="$OTHER_OBJS src/hostapi/alsa/pa_linux_alsa.o"
AC_DEFINE(PA_USE_ALSA)
fi
if [[ "$have_jack" = "yes" ] && [ "$with_jack" != "no" ]] ; then
DLL_LIBS="$DLL_LIBS $JACK_LIBS"
CFLAGS="$CFLAGS $JACK_CFLAGS"
OTHER_OBJS="$OTHER_OBJS src/hostapi/jack/pa_jack.o src/common/pa_ringbuffer.o"
AC_DEFINE(PA_USE_JACK)
fi
if [[ "$with_oss" != "no" ]] ; then
OTHER_OBJS="$OTHER_OBJS src/hostapi/oss/pa_unix_oss.o"
if [[ "$have_libossaudio" = "yes" ]] ; then
DLL_LIBS="$DLL_LIBS -lossaudio"
LIBS="$LIBS -lossaudio"
fi
AC_DEFINE(PA_USE_OSS)
fi
if [[ "$have_asihpi" = "yes" ] && [ "$with_asihpi" != "no" ]] ; then
LIBS="$LIBS -lhpi"
DLL_LIBS="$DLL_LIBS -lhpi"
OTHER_OBJS="$OTHER_OBJS src/hostapi/asihpi/pa_linux_asihpi.o"
AC_DEFINE(PA_USE_ASIHPI)
fi
DLL_LIBS="$DLL_LIBS -lm -lpthread"
LIBS="$LIBS -lm -lpthread"
PADLL="libportaudio.so"
## support sun cc compiler flags
case "${host_os}" in
solaris*)
SHARED_FLAGS="-G"
THREAD_CFLAGS="-mt"
;;
*)
SHARED_FLAGS="-shared -fPIC"
THREAD_CFLAGS="-pthread"
;;
esac
OTHER_OBJS="$OTHER_OBJS src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o"
esac
CFLAGS="$CFLAGS $THREAD_CFLAGS"
if test "$enable_cxx" = "yes"; then
AC_CONFIG_SUBDIRS([bindings/cpp])
ENABLE_CXX_TRUE=""
ENABLE_CXX_FALSE="#"
else
ENABLE_CXX_TRUE="#"
ENABLE_CXX_FALSE=""
fi
AC_SUBST(ENABLE_CXX_TRUE)
AC_SUBST(ENABLE_CXX_FALSE)
if test "x$with_asio" = "xyes"; then
WITH_ASIO_TRUE=""
WITH_ASIO_FALSE="@ #"
else
WITH_ASIO_TRUE="@ #"
WITH_ASIO_FALSE=""
fi
AC_SUBST(WITH_ASIO_TRUE)
AC_SUBST(WITH_ASIO_FALSE)
AC_OUTPUT([Makefile portaudio-2.0.pc])
AC_MSG_RESULT([
Configuration summary:
Target ...................... $target
C++ bindings ................ $enable_cxx
Debug output ................ $debug_output])
case "$target_os" in *linux*)
AC_MSG_RESULT([
ALSA ........................ $have_alsa
ASIHPI ...................... $have_asihpi])
;;
esac
case "$target_os" in
*mingw* | *cygwin*)
test "x$with_directx" = "xyes" && with_directx="$with_directx (${with_dxdir})"
test "x$with_wdmks" = "xyes" && with_wdmks="$with_wdmks (${with_dxdir})"
test "x$with_asio" = "xyes" && with_asio="$with_asio (${with_asiodir})"
test "x$with_wasapi" = "xyes"
AC_MSG_RESULT([
WMME ........................ $with_wmme
DSound ...................... $with_directx
ASIO ........................ $with_asio
WASAPI ...................... $with_wasapi
WDMKS ....................... $with_wdmks
])
;;
*darwin*)
AC_MSG_RESULT([
Mac debug flags ............. $enable_mac_debug
])
;;
*)
AC_MSG_RESULT([
OSS ......................... $have_oss
JACK ........................ $have_jack
])
;;
esac
dnl
dnl portaudio V19 configure.in script
dnl
dnl Dominic Mazzoni, Arve Knudsen, Stelios Bounanos
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([include/portaudio.h])
dnl Define build, build_cpu, build_vendor, build_os
AC_CANONICAL_BUILD
dnl Define host, host_cpu, host_vendor, host_os
AC_CANONICAL_HOST
dnl Define target, target_cpu, target_vendor, target_os
AC_CANONICAL_TARGET
dnl Specify options
AC_ARG_WITH(alsa,
AS_HELP_STRING([--with-alsa], [Enable support for ALSA @<:@autodetect@:>@]),
[with_alsa=$withval])
AC_ARG_WITH(jack,
AS_HELP_STRING([--with-jack], [Enable support for JACK @<:@autodetect@:>@]),
[with_jack=$withval])
AC_ARG_WITH(oss,
AS_HELP_STRING([--with-oss], [Enable support for OSS @<:@autodetect@:>@]),
[with_oss=$withval])
AC_ARG_WITH(asihpi,
AS_HELP_STRING([--with-asihpi], [Enable support for ASIHPI @<:@autodetect@:>@]),
[with_asihpi=$withval])
AC_ARG_WITH(winapi,
AS_HELP_STRING([--with-winapi],
[Select Windows API support (@<:@wmme|directx|asio|wasapi|wdmks@:>@@<:@,...@:>@) @<:@wmme@:>@]),
[with_winapi=$withval], [with_winapi="wmme"])
case "$target_os" in *mingw* | *cygwin*)
with_wmme=no
with_directx=no
with_asio=no
with_wasapi=no
with_wdmks=no
for api in $(echo $with_winapi | sed 's/,/ /g'); do
case "$api" in
wmme|directx|asio|wasapi|wdmks)
eval with_$api=yes
;;
*)
AC_MSG_ERROR([unknown Windows API \"$api\" (do you need --help?)])
;;
esac
done
;;
esac
AC_ARG_WITH(asiodir,
AS_HELP_STRING([--with-asiodir], [ASIO directory @<:@/usr/local/asiosdk2@:>@]),
with_asiodir=$withval, with_asiodir="/usr/local/asiosdk2")
AC_ARG_WITH(dxdir,
AS_HELP_STRING([--with-dxdir], [DirectX directory @<:@/usr/local/dx7sdk@:>@]),
with_dxdir=$withval, with_dxdir="/usr/local/dx7sdk")
debug_output=no
AC_ARG_ENABLE(debug-output,
AS_HELP_STRING([--enable-debug-output], [Enable debug output @<:@no@:>@]),
[if test "x$enableval" != "xno" ; then
AC_DEFINE(PA_ENABLE_DEBUG_OUTPUT,,[Enable debugging messages])
debug_output=yes
fi
])
AC_ARG_ENABLE(cxx,
AS_HELP_STRING([--enable-cxx], [Enable C++ bindings @<:@no@:>@]),
enable_cxx=$enableval, enable_cxx="no")
AC_ARG_ENABLE(mac-debug,
AS_HELP_STRING([--enable-mac-debug], [Enable Mac debug @<:@no@:>@]),
enable_mac_debug=$enableval, enable_mac_debug="no")
AC_ARG_ENABLE(mac-universal,
AS_HELP_STRING([--enable-mac-universal], [Build Mac universal binaries @<:@yes@:>@]),
enable_mac_universal=$enableval, enable_mac_universal="yes")
dnl Continue to accept --host_os for compatibility but do not document
dnl it (the correct way to change host_os is with --host=...). Moved
dnl here because the empty help string generates a blank line which we
dnl can use to separate PA options from libtool options.
AC_ARG_WITH(host_os, [], host_os=$withval)
dnl Checks for programs.
AC_PROG_CC
AC_LIBTOOL_WIN32_DLL
AC_PROG_LIBTOOL
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PATH_PROG(AR, ar, no)
if [[ $AR = "no" ]] ; then
AC_MSG_ERROR("Could not find ar - needed to create a library")
fi
dnl This must be one of the first tests we do or it will fail...
AC_C_BIGENDIAN
dnl checks for various host APIs and arguments to configure that
dnl turn them on or off
have_alsa=no
if test "x$with_alsa" != "xno"; then
AC_CHECK_LIB(asound, snd_pcm_open, have_alsa=yes, have_alsa=no)
fi
have_asihpi=no
if test "x$with_asihpi" != "xno"; then
AC_CHECK_LIB(hpi, HPI_SubSysCreate, have_asihpi=yes, have_asihpi=no, -lm)
fi
have_libossaudio=no
have_oss=no
if test "x$with_oss" != "xno"; then
AC_CHECK_HEADERS([sys/soundcard.h linux/soundcard.h machine/soundcard.h], [have_oss=yes])
if test "x$have_oss" = "xyes"; then
AC_CHECK_LIB(ossaudio, _oss_ioctl, have_libossaudio=yes, have_libossaudio=no)
fi
fi
have_jack=no
if test "x$with_jack" != "xno"; then
PKG_CHECK_MODULES(JACK, jack, have_jack=yes, have_jack=no)
fi
dnl sizeof checks: we will need a 16-bit and a 32-bit type
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
save_LIBS="${LIBS}"
AC_CHECK_LIB(rt, clock_gettime, [rt_libs=" -lrt"])
LIBS="${LIBS}${rt_libs}"
DLL_LIBS="${DLL_LIBS}${rt_libs}"
AC_CHECK_FUNCS([clock_gettime nanosleep])
LIBS="${save_LIBS}"
dnl LT_RELEASE=19
LT_CURRENT=2
LT_REVISION=0
LT_AGE=0
AC_SUBST(LT_CURRENT)
AC_SUBST(LT_REVISION)
AC_SUBST(LT_AGE)
dnl extra variables
AC_SUBST(OTHER_OBJS)
AC_SUBST(PADLL)
AC_SUBST(SHARED_FLAGS)
AC_SUBST(THREAD_CFLAGS)
AC_SUBST(DLL_LIBS)
AC_SUBST(CXXFLAGS)
AC_SUBST(NASM)
AC_SUBST(NASMOPT)
dnl -g is optional on darwin
if ( echo "${host_os}" | grep ^darwin >> /dev/null ) &&
[[ "$enable_mac_universal" = "yes" ] &&
[ "$enable_mac_debug" != "yes" ]] ; then
CFLAGS="-O2 -Wall -pedantic -pipe -fPIC -DNDEBUG"
else
CFLAGS=${CFLAGS:-"-g -O2 -Wall -pedantic -pipe -fPIC"}
fi
if [[ $ac_cv_c_bigendian = "yes" ]] ; then
CFLAGS="$CFLAGS -DPA_BIG_ENDIAN"
else
CFLAGS="$CFLAGS -DPA_LITTLE_ENDIAN"
fi
add_objects()
{
for o in $@; do
test "${OTHER_OBJS#*${o}*}" = "${OTHER_OBJS}" && OTHER_OBJS="$OTHER_OBJS $o"
done
}
case "${host_os}" in
darwin* )
dnl Mac OS X configuration
AC_DEFINE(PA_USE_COREAUDIO)
CFLAGS="$CFLAGS -Werror"
LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon"
if test "x$enable_mac_universal" = "xyes" ; then
mac_version_min="-mmacosx-version-min=10.3"
if [[ -d /Developer/SDKs/MacOSX10.5.sdk ]] ; then
mac_arches="-arch i386 -arch ppc -arch x86_64 -arch ppc64"
mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.5.sdk"
else
mac_arches="-arch i386 -arch ppc"
mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.4u.sdk"
fi
else
mac_arches=""
mac_sysroot=""
mac_version=""
fi
SHARED_FLAGS="$LIBS -dynamiclib $mac_arches $mac_sysroot $mac_version_min"
CFLAGS="-std=c99 $CFLAGS $mac_arches $mac_sysroot $mac_version_min"
OTHER_OBJS="src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o src/hostapi/coreaudio/pa_mac_core.o src/hostapi/coreaudio/pa_mac_core_utilities.o src/hostapi/coreaudio/pa_mac_core_blocking.o src/common/pa_ringbuffer.o"
PADLL="libportaudio.dylib"
;;
mingw* )
dnl MingW configuration
PADLL="portaudio.dll"
THREAD_CFLAGS="-mthreads"
SHARED_FLAGS="-shared"
CFLAGS="$CFLAGS -I\$(top_srcdir)/include -DPA_NO_WMME -DPA_NO_ASIO -DPA_NO_WDMKS -DPA_NO_DS -DPA_NO_WASAPI"
if [[ "x$with_directx" = "xyes" ]]; then
DXDIR="$with_dxdir"
add_objects src/hostapi/dsound/pa_win_ds.o src/hostapi/dsound/pa_win_ds_dynlink.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_waveformat.o
LIBS="-lwinmm -lm -ldsound -lole32"
DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L$DXDIR/lib -ldsound -lole32"
#VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\""
#CFLAGS="$CFLAGS -I$VC98 -DPA_NO_WMME -DPA_NO_ASIO"
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/os/win -I$DXDIR/include -UPA_NO_DS"
fi
if [[ "x$with_asio" = "xyes" ]]; then
ASIODIR="$with_asiodir"
add_objects src/hostapi/asio/pa_asio.o src/common/pa_ringbuffer.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/hostapi/asio/iasiothiscallresolver.o $ASIODIR/common/asio.o $ASIODIR/host/asiodrivers.o $ASIODIR/host/pc/asiolist.o
LIBS="-lwinmm -lm -lole32 -luuid"
DLL_LIBS="${DLL_LIBS} -lwinmm -lm -lole32 -luuid"
CFLAGS="$CFLAGS -ffast-math -fomit-frame-pointer -I\$(top_srcdir)/src/common -I\$(top_srcdir)/src/hostapi/asio -I$ASIODIR/host/pc -I$ASIODIR/common -I$ASIODIR/host -UPA_NO_ASIO -DWINDOWS"
CXXFLAGS="$CFLAGS"
fi
if [[ "x$with_wdmks" = "xyes" ]]; then
DXDIR="$with_dxdir"
add_objects src/hostapi/wdmks/pa_win_wdmks.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o
LIBS="-lwinmm -lm -luuid -lsetupapi -lole32"
DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L$DXDIR/lib -luuid -lsetupapi -lole32"
#VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\""
#CFLAGS="$CFLAGS -I$VC98 -DPA_NO_WMME -DPA_NO_ASIO"
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/common -I$DXDIR/include -UPA_NO_WDMKS"
fi
if [[ "x$with_wmme" = "xyes" ]]; then
add_objects src/hostapi/wmme/pa_win_wmme.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_waveformat.o
LIBS="-lwinmm -lm -lole32 -luuid"
DLL_LIBS="${DLL_LIBS} -lwinmm"
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/common -UPA_NO_WMME"
fi
if [[ "x$with_wasapi" = "xyes" ]]; then
add_objects src/hostapi/wasapi/pa_win_wasapi.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_waveformat.o
LIBS="-lwinmm -lm -lole32 -luuid"
DLL_LIBS="${DLL_LIBS} -lwinmm"
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/common -I\$(top_srcdir)/src/hostapi/wasapi/mingw-include -UPA_NO_WASAPI"
fi
;;
cygwin* )
dnl Cygwin configuration
OTHER_OBJS="src/hostapi/wmme/pa_win_wmme.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_waveformat.o"
CFLAGS="$CFLAGS -DPA_NO_DS -DPA_NO_WDMKS -DPA_NO_ASIO -DPA_NO_WASAPI"
LIBS="-lwinmm -lm"
PADLL="portaudio.dll"
THREAD_CFLAGS="-mthreads"
SHARED_FLAGS="-shared"
DLL_LIBS="${DLL_LIBS} -lwinmm"
;;
irix* )
dnl SGI IRIX audio library (AL) configuration (Pieter, oct 2-13, 2003).
dnl The 'dmedia' library is needed to read the Unadjusted System Time (UST).
dnl
AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR([IRIX posix thread library not found!]))
AC_CHECK_LIB(audio, alOpenPort, , AC_MSG_ERROR([IRIX audio library not found!]))
AC_CHECK_LIB(dmedia, dmGetUST, , AC_MSG_ERROR([IRIX digital media library not found!]))
dnl See the '#ifdef PA_USE_SGI' in file pa_unix/pa_unix_hostapis.c
dnl which selects the appropriate PaXXX_Initialize() function.
dnl
AC_DEFINE(PA_USE_SGI)
dnl The _REENTRANT option for pthread safety. Perhaps not necessary but it 'll do no harm.
dnl
THREAD_CFLAGS="-D_REENTRANT"
OTHER_OBJS="pa_sgi/pa_sgi.o src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o"
dnl SGI books say -lpthread should be the last of the libs mentioned.
dnl
LIBS="-lm -ldmedia -laudio -lpthread"
PADLL="libportaudio.so"
SHARED_FLAGS=""
;;
*)
dnl Unix configuration
AC_CHECK_LIB(pthread, pthread_create,[have_pthread="yes"],
AC_MSG_ERROR([libpthread not found!]))
if [[ "$have_alsa" = "yes" ] && [ "$with_alsa" != "no" ]] ; then
DLL_LIBS="$DLL_LIBS -lasound"
LIBS="$LIBS -lasound"
OTHER_OBJS="$OTHER_OBJS src/hostapi/alsa/pa_linux_alsa.o"
AC_DEFINE(PA_USE_ALSA)
fi
if [[ "$have_jack" = "yes" ] && [ "$with_jack" != "no" ]] ; then
DLL_LIBS="$DLL_LIBS $JACK_LIBS"
CFLAGS="$CFLAGS $JACK_CFLAGS"
OTHER_OBJS="$OTHER_OBJS src/hostapi/jack/pa_jack.o src/common/pa_ringbuffer.o"
AC_DEFINE(PA_USE_JACK)
fi
if [[ "$with_oss" != "no" ]] ; then
OTHER_OBJS="$OTHER_OBJS src/hostapi/oss/pa_unix_oss.o"
if [[ "$have_libossaudio" = "yes" ]] ; then
DLL_LIBS="$DLL_LIBS -lossaudio"
LIBS="$LIBS -lossaudio"
fi
AC_DEFINE(PA_USE_OSS)
fi
if [[ "$have_asihpi" = "yes" ] && [ "$with_asihpi" != "no" ]] ; then
LIBS="$LIBS -lhpi"
DLL_LIBS="$DLL_LIBS -lhpi"
OTHER_OBJS="$OTHER_OBJS src/hostapi/asihpi/pa_linux_asihpi.o"
AC_DEFINE(PA_USE_ASIHPI)
fi
DLL_LIBS="$DLL_LIBS -lm -lpthread"
LIBS="$LIBS -lm -lpthread"
PADLL="libportaudio.so"
## support sun cc compiler flags
case "${host_os}" in
solaris*)
SHARED_FLAGS="-G"
THREAD_CFLAGS="-mt"
;;
*)
SHARED_FLAGS="-shared -fPIC"
THREAD_CFLAGS="-pthread"
;;
esac
OTHER_OBJS="$OTHER_OBJS src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o"
esac
CFLAGS="$CFLAGS $THREAD_CFLAGS"
if test "$enable_cxx" = "yes"; then
AC_CONFIG_SUBDIRS([bindings/cpp])
ENABLE_CXX_TRUE=""
ENABLE_CXX_FALSE="#"
else
ENABLE_CXX_TRUE="#"
ENABLE_CXX_FALSE=""
fi
AC_SUBST(ENABLE_CXX_TRUE)
AC_SUBST(ENABLE_CXX_FALSE)
if test "x$with_asio" = "xyes"; then
WITH_ASIO_TRUE=""
WITH_ASIO_FALSE="@ #"
else
WITH_ASIO_TRUE="@ #"
WITH_ASIO_FALSE=""
fi
AC_SUBST(WITH_ASIO_TRUE)
AC_SUBST(WITH_ASIO_FALSE)
AC_OUTPUT([Makefile portaudio-2.0.pc])
AC_MSG_RESULT([
Configuration summary:
Target ...................... $target
C++ bindings ................ $enable_cxx
Debug output ................ $debug_output])
case "$target_os" in *linux*)
AC_MSG_RESULT([
ALSA ........................ $have_alsa
ASIHPI ...................... $have_asihpi])
;;
esac
case "$target_os" in
*mingw* | *cygwin*)
test "x$with_directx" = "xyes" && with_directx="$with_directx (${with_dxdir})"
test "x$with_wdmks" = "xyes" && with_wdmks="$with_wdmks (${with_dxdir})"
test "x$with_asio" = "xyes" && with_asio="$with_asio (${with_asiodir})"
test "x$with_wasapi" = "xyes"
AC_MSG_RESULT([
WMME ........................ $with_wmme
DSound ...................... $with_directx
ASIO ........................ $with_asio
WASAPI ...................... $with_wasapi
WDMKS ....................... $with_wdmks
])
;;
*darwin*)
AC_MSG_RESULT([
Mac debug flags ............. $enable_mac_debug
])
;;
*)
AC_MSG_RESULT([
OSS ......................... $have_oss
JACK ........................ $have_jack
])
;;
esac

View File

@ -1,19 +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 ..\
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 ..\

View File

@ -1,7 +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
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

View File

@ -28,13 +28,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -59,7 +59,7 @@ extern "C"
@param minLatency A pointer to the location which will recieve the minimum latency value.
@param maxLatency A pointer to the location which will recieve the maximum latency value.
@param preferredLatency A pointer to the location which will recieve the preferred latency value.
@param granularity A pointer to the location which will recieve the granularity. This value
@param granularity A pointer to the location which will recieve the granularity. This value
determines which values between minLatency and maxLatency are available. ie the step size,
if granularity is -1 then available latency settings are powers of two.
@ -70,7 +70,7 @@ extern "C"
PaError PaAsio_GetAvailableLatencyValues( PaDeviceIndex device,
long *minLatency, long *maxLatency, long *preferredLatency, long *granularity );
/** Display the ASIO control panel for the specified device.
@param device The global index of the device whose control panel is to be displayed.
@ -90,7 +90,7 @@ PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific );
PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex,
const char** channelName );
/** Retrieve a pointer to a string containing the name of the specified
input channel. The string is valid until Pa_Terminate is called.
@ -101,11 +101,11 @@ PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex,
/** Set the sample rate of an open paASIO stream.
@param stream The stream to operate on.
@param sampleRate The new sample rate.
@param sampleRate The new sample rate.
Note that this function may fail if the stream is alredy running and the
Note that this function may fail if the stream is alredy running and the
ASIO driver does not support switching the sample rate of a running stream.
Returns paIncompatibleStreamHostApi if stream is not a paASIO stream.

View File

@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -28,13 +28,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -64,8 +64,8 @@ typedef struct
PaHostApiTypeId hostApiType; /**host API for which this data is intended */
unsigned long version; /**structure version */
unsigned long flags; /* flags to modify behaviour */
SInt32 const * channelMap; /* Channel map for HAL channel mapping , if not needed, use NULL;*/
unsigned long channelMapSize; /* Channel map size for HAL channel mapping , if not needed, use 0;*/
SInt32 const * channelMap; /* Channel map for HAL channel mapping , if not needed, use NULL;*/
unsigned long channelMapSize; /* Channel map size for HAL channel mapping , if not needed, use 0;*/
} PaMacCoreStreamInfo;
/*
@ -96,7 +96,7 @@ void PaMacCore_SetupChannelMap( PaMacCoreStreamInfo *data, const SInt32 * const
* @return A valid AudioDeviceID, or NULL if an error occurred.
*/
AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s );
/*
* Retrieve the AudioDeviceID of the output device assigned to an open stream
*

View File

@ -28,13 +28,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -83,7 +83,7 @@ typedef struct PaWinDirectSoundStreamInfo{
/*
support for WAVEFORMATEXTENSIBLE channel masks. If flags contains
paWinDirectSoundUseChannelMask this allows you to specify which speakers
paWinDirectSoundUseChannelMask this allows you to specify which speakers
to address in a multichannel stream. Constants for channelMask
are specified in pa_win_waveformat.h
@ -98,4 +98,4 @@ typedef struct PaWinDirectSoundStreamInfo{
}
#endif /* __cplusplus */
#endif /* PA_WIN_DS_H */
#endif /* PA_WIN_DS_H */

View File

@ -28,13 +28,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -69,7 +69,7 @@ typedef enum PaWasapiFlags
method can only provide 15-20ms latency. */
paWinWasapiPolling = (1 << 3),
/* forces custom thread priority setting. must be used if PaWasapiStreamInfo::threadPriority
/* forces custom thread priority setting. must be used if PaWasapiStreamInfo::threadPriority
is set to custom value. */
paWinWasapiThreadPriority = (1 << 4)
}
@ -81,7 +81,7 @@ PaWasapiFlags;
#define paWinWasapiThreadPriority (paWinWasapiThreadPriority)
/* Host processor. Allows to skip internal PA processing completely.
/* Host processor. Allows to skip internal PA processing completely.
You must set paWinWasapiRedirectHostProcessor flag to PaWasapiStreamInfo::flags member
in order to have host processor redirected to your callback.
Use with caution! inputFrames and outputFrames depend solely on final device setup.
@ -109,6 +109,70 @@ typedef enum PaWasapiDeviceRole
PaWasapiDeviceRole;
/* Jack connection type */
typedef enum PaWasapiJackConnectionType
{
eJackConnTypeUnknown,
eJackConnType3Point5mm,
eJackConnTypeQuarter,
eJackConnTypeAtapiInternal,
eJackConnTypeRCA,
eJackConnTypeOptical,
eJackConnTypeOtherDigital,
eJackConnTypeOtherAnalog,
eJackConnTypeMultichannelAnalogDIN,
eJackConnTypeXlrProfessional,
eJackConnTypeRJ11Modem,
eJackConnTypeCombination
}
PaWasapiJackConnectionType;
/* Jack geometric location */
typedef enum PaWasapiJackGeoLocation
{
eJackGeoLocUnk = 0,
eJackGeoLocRear = 0x1, /* matches EPcxGeoLocation::eGeoLocRear */
eJackGeoLocFront,
eJackGeoLocLeft,
eJackGeoLocRight,
eJackGeoLocTop,
eJackGeoLocBottom,
eJackGeoLocRearPanel,
eJackGeoLocRiser,
eJackGeoLocInsideMobileLid,
eJackGeoLocDrivebay,
eJackGeoLocHDMI,
eJackGeoLocOutsideMobileLid,
eJackGeoLocATAPI,
eJackGeoLocReserved5,
eJackGeoLocReserved6,
}
PaWasapiJackGeoLocation;
/* Jack general location */
typedef enum PaWasapiJackGenLocation
{
eJackGenLocPrimaryBox = 0,
eJackGenLocInternal,
eJackGenLocSeparate,
eJackGenLocOther
}
PaWasapiJackGenLocation;
/* Jack's type of port */
typedef enum PaWasapiJackPortConnection
{
eJackPortConnJack = 0,
eJackPortConnIntegratedDevice,
eJackPortConnBothIntegratedAndJack,
eJackPortConnUnknown
}
PaWasapiJackPortConnection;
/* Thread priority */
typedef enum PaWasapiThreadPriority
{
@ -125,7 +189,21 @@ PaWasapiThreadPriority;
/* Stream descriptor. */
typedef struct PaWasapiStreamInfo
typedef struct PaWasapiJackDescription
{
unsigned long channelMapping;
unsigned long color; /* derived from macro: #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) */
PaWasapiJackConnectionType connectionType;
PaWasapiJackGeoLocation geoLocation;
PaWasapiJackGenLocation genLocation;
PaWasapiJackPortConnection portConnection;
unsigned int isConnected;
}
PaWasapiJackDescription;
/* Stream descriptor. */
typedef struct PaWasapiStreamInfo
{
unsigned long size; /**< sizeof(PaWasapiStreamInfo) */
PaHostApiTypeId hostApiType; /**< paWASAPI */
@ -134,16 +212,16 @@ typedef struct PaWasapiStreamInfo
unsigned long flags; /**< collection of PaWasapiFlags */
/* Support for WAVEFORMATEXTENSIBLE channel masks. If flags contains
paWinWasapiUseChannelMask this allows you to specify which speakers
paWinWasapiUseChannelMask this allows you to specify which speakers
to address in a multichannel stream. Constants for channelMask
are specified in pa_win_waveformat.h. Will be used only if
are specified in pa_win_waveformat.h. Will be used only if
paWinWasapiUseChannelMask flag is specified.
*/
PaWinWaveFormatChannelMask channelMask;
/* Delivers raw data to callback obtained from GetBuffer() methods skipping
internal PortAudio processing inventory completely. userData parameter will
be the same that was passed to Pa_OpenStream method. Will be used only if
/* Delivers raw data to callback obtained from GetBuffer() methods skipping
internal PortAudio processing inventory completely. userData parameter will
be the same that was passed to Pa_OpenStream method. Will be used only if
paWinWasapiRedirectHostProcessor flag is specified.
*/
PaWasapiHostProcessorCallback hostProcessorOutput;
@ -157,11 +235,11 @@ typedef struct PaWasapiStreamInfo
to setup thread priority.
*/
PaWasapiThreadPriority threadPriority;
}
}
PaWasapiStreamInfo;
/** Returns default sound format for device. Format is represented by PaWinWaveFormat or
/** Returns default sound format for device. Format is represented by PaWinWaveFormat or
WAVEFORMATEXTENSIBLE structure.
@param pFormat Pointer to PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure.
@ -191,7 +269,7 @@ int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex nDevice );
@param hTask Handle to pointer to priority task. Must be used with PaWasapi_RevertThreadPriority
method to revert thread priority to initial state.
@param nPriorityClass Id of thread priority of PaWasapiThreadPriority type. Specifying
@param nPriorityClass Id of thread priority of PaWasapiThreadPriority type. Specifying
eThreadPriorityNone does nothing.
@return Error code indicating success or failure.
@ -210,8 +288,8 @@ PaError PaWasapi_ThreadPriorityBoost( void **hTask, PaWasapiThreadPriority nPrio
PaError PaWasapi_ThreadPriorityRevert( void *hTask );
/** Get number of frames per host buffer. This is maximal value of frames of WASAPI buffer which
can be locked for operations. Use this method as helper to findout maximal values of
/** Get number of frames per host buffer. This is maximal value of frames of WASAPI buffer which
can be locked for operations. Use this method as helper to findout maximal values of
inputFrames/outputFrames of PaWasapiHostProcessorCallback.
@param pStream Pointer to PaStream to query.
@ -223,12 +301,37 @@ PaError PaWasapi_ThreadPriorityRevert( void *hTask );
PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput, unsigned int *nOutput );
/** Get number of jacks associated with a WASAPI device. Use this method to determine if
there are any jacks associated with the provided WASAPI device. Not all audio devices
will support this capability. This is valid for both input and output devices.
@param nDevice device index.
@param jcount Number of jacks is returned in this variable
@return Error code indicating success or failure
@see PaWasapi_GetJackDescription
*/
PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount);
/** Get the jack description associated with a WASAPI device and jack number
Before this function is called, use PaWasapi_GetJackCount to determine the
number of jacks associated with device. If jcount is greater than zero, then
each jack from 0 to jcount can be queried with this function to get the jack
description.
@param nDevice device index.
@param jindex Which jack to return information
@param KSJACK_DESCRIPTION This structure filled in on success.
@return Error code indicating success or failure
@see PaWasapi_GetJackCount
*/
PaError PaWasapi_GetJackDescription(PaDeviceIndex nDevice, int jindex, PaWasapiJackDescription *pJackDescription);
/*
IMPORTANT:
WASAPI is implemented for Callback and Blocking interfaces. It supports Shared and Exclusive
share modes.
share modes.
Exclusive Mode:
Exclusive mode allows to deliver audio data directly to hardware bypassing
@ -237,20 +340,20 @@ PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput
Callback Interface:
Provides best audio quality with low latency. Callback interface is implemented in
Provides best audio quality with low latency. Callback interface is implemented in
two versions:
1) Event-Driven:
This is the most powerful WASAPI implementation which provides glitch-free
audio at around 3ms latency in Exclusive mode. Lowest possible latency for this mode is
usually - 1.4(Vista only)-3ms(Windows 7+) for HD Audio class audio chips. For the
Shared mode latency can not be lower than 20ms.
audio at around 3ms latency in Exclusive mode. Lowest possible latency for this mode is
3 ms for HD Audio class audio chips. For the Shared mode latency can not be
lower than 20 ms.
2) Poll-Driven:
Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven
and provides latency at around 10-13ms. Polling must be used to overcome a system bug
under Windows Vista x64 when application is WOW64(32-bit) and Event-Driven method simply
times out (event handle is never signalled on buffer completion). Please note, such WOW64 bug
under Windows Vista x64 when application is WOW64(32-bit) and Event-Driven method simply
times out (event handle is never signalled on buffer completion). Please note, such WOW64 bug
does not exist in Vista x86 or Windows 7.
Polling can be setup by speciying 'paWinWasapiPolling' flag. Our WASAPI implementation detects
WOW64 bug and sets 'paWinWasapiPolling' automatically.
@ -259,25 +362,25 @@ PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput
Normally thread priority is set automatically and does not require modification. Although
if user wants some tweaking thread priority can be modified by setting 'paWinWasapiThreadPriority'
flag and specifying 'PaWasapiStreamInfo::threadPriority' with value from PaWasapiThreadPriority
flag and specifying 'PaWasapiStreamInfo::threadPriority' with value from PaWasapiThreadPriority
enum.
Blocking Interface:
Blocking interface is implemented but due to above described Poll-Driven method can not
deliver lowest possible latency. Specifying too low latency in Shared mode will result in
deliver lowest possible latency. Specifying too low latency in Shared mode will result in
distorted audio although Exclusive mode adds stability.
Pa_IsFormatSupported:
To check format with correct Share Mode (Exclusive/Shared) you must supply
PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
PaStreamParameters::hostApiSpecificStreamInfo structure.
Pa_OpenStream:
To set desired Share Mode (Exclusive/Shared) you must supply
PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
PaStreamParameters::hostApiSpecificStreamInfo structure.
*/
@ -285,4 +388,4 @@ PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput
}
#endif /* __cplusplus */
#endif /* PA_WIN_WASAPI_H */
#endif /* PA_WIN_WASAPI_H */

View File

@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -125,11 +125,11 @@ typedef unsigned long PaWinWaveFormatChannelMask;
/*
PaWinWaveFormat is defined here to provide compatibility with
compilation environments which don't have headers defining
compilation environments which don't have headers defining
WAVEFORMATEXTENSIBLE (e.g. older versions of MSVC, Borland C++ etc.
The fields for WAVEFORMATEX and WAVEFORMATEXTENSIBLE are declared as an
unsigned char array here to avoid clients who include this file having
unsigned char array here to avoid clients who include this file having
a dependency on windows.h and mmsystem.h, and also to to avoid having
to write separate packing pragmas for each compiler.
*/
@ -138,18 +138,18 @@ typedef unsigned long PaWinWaveFormatChannelMask;
typedef struct{
unsigned char fields[ PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE ];
unsigned long extraLongForAlignment; /* ensure that compiler aligns struct to DWORD */
unsigned long extraLongForAlignment; /* ensure that compiler aligns struct to DWORD */
} PaWinWaveFormat;
/*
WAVEFORMATEXTENSIBLE fields:
union {
WORD wValidBitsPerSample;
WORD wSamplesPerBlock;
WORD wReserved;
WORD wValidBitsPerSample;
WORD wSamplesPerBlock;
WORD wReserved;
} Samples;
DWORD dwChannelMask;
DWORD dwChannelMask;
GUID SubFormat;
*/
@ -179,11 +179,11 @@ int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat );
Use the following two functions to initialize the waveformat structure.
*/
void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate );
void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate,
PaWinWaveFormatChannelMask channelMask );
@ -196,4 +196,4 @@ PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels );
}
#endif /* __cplusplus */
#endif /* PA_WIN_WAVEFORMAT_H */
#endif /* PA_WIN_WAVEFORMAT_H */

View File

@ -28,13 +28,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -53,7 +53,7 @@ extern "C"
#endif /* __cplusplus */
/* The following are flags which can be set in
/* The following are flags which can be set in
PaWinMmeStreamInfo's flags field.
*/
@ -101,7 +101,7 @@ typedef struct PaWinMmeStreamInfo{
Pa_OpenStream().
*/
unsigned long framesPerBuffer;
unsigned long bufferCount; /* formerly numBuffers */
unsigned long bufferCount; /* formerly numBuffers */
/* multiple devices per direction support
If flags contains the PaWinMmeUseMultipleDevices flag,
@ -119,7 +119,7 @@ typedef struct PaWinMmeStreamInfo{
/*
support for WAVEFORMATEXTENSIBLE channel masks. If flags contains
paWinMmeUseChannelMask this allows you to specify which speakers
paWinMmeUseChannelMask this allows you to specify which speakers
to address in a multichannel stream. Constants for channelMask
are specified in pa_win_waveformat.h
@ -156,7 +156,7 @@ HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* stream, int handleIndex );
/** Retrieve the number of wave out handles used by a PortAudio WinMME stream.
Returns zero if the stream is input only.
@return A non-negative value indicating the number of wave out handles
or, a PaErrorCode (which are always negative) if PortAudio is not initialized
or an error is encountered.
@ -183,4 +183,4 @@ HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* stream, int handleIndex );
}
#endif /* __cplusplus */
#endif /* PA_WIN_WMME_H */
#endif /* PA_WIN_WMME_H */

View File

@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -50,7 +50,7 @@ extern "C"
{
#endif /* __cplusplus */
/** Retrieve the release number of the currently running PortAudio build,
eg 1900.
*/
@ -116,9 +116,9 @@ const char *Pa_GetErrorText( PaError errorCode );
and Pa_GetErrorText(), this function MUST be called before using any other
PortAudio API functions.
If Pa_Initialize() is called multiple times, each successful
call must be matched with a corresponding call to Pa_Terminate().
Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not
If Pa_Initialize() is called multiple times, each successful
call must be matched with a corresponding call to Pa_Terminate().
Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not
required to be fully nested.
Note that if Pa_Initialize() returns an error code, Pa_Terminate() should
@ -145,7 +145,7 @@ PaError Pa_Initialize( void );
@return paNoError if successful, otherwise an error code indicating the cause
of failure.
@see Pa_Initialize
*/
PaError Pa_Terminate( void );
@ -269,7 +269,7 @@ typedef struct PaHostApiInfo
if no default output device is available.
*/
PaDeviceIndex defaultOutputDevice;
} PaHostApiInfo;
@ -298,7 +298,7 @@ const PaHostApiInfo * Pa_GetHostApiInfo( PaHostApiIndex hostApi );
@return A valid PaHostApiIndex ranging from 0 to (Pa_GetHostApiCount()-1) or,
a PaErrorCode (which are always negative) if PortAudio is not initialized
or an error is encountered.
The paHostApiNotFound error code indicates that the host API specified by the
type parameter is not available.
@ -325,7 +325,7 @@ PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type );
A paInvalidDevice error code indicates that the hostApiDeviceIndex parameter
is out of range.
@see PaHostApiInfo
*/
PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi,
@ -401,7 +401,7 @@ PaDeviceIndex Pa_GetDefaultOutputDevice( void );
/** The type used to represent monotonic time in seconds that can be used
for syncronisation. The type is used for the outTime argument to the
PaStreamCallback and as the result of Pa_GetStreamTime().
@see PaStreamCallback, Pa_GetStreamTime
*/
typedef double PaTime;
@ -447,7 +447,7 @@ typedef struct PaDeviceInfo
int structVersion; /* this is struct version 2 */
const char *name;
PaHostApiIndex hostApi; /* note this is a host API index, not a type id*/
int maxInputChannels;
int maxOutputChannels;
@ -489,7 +489,7 @@ typedef struct PaStreamParameters
This field must not be set to paNoDevice.
*/
PaDeviceIndex device;
/** The number of channels of sound to be delivered to the
stream callback or accessed by Pa_ReadStream() or Pa_WriteStream().
It can range from 1 to the value of maxInputChannels in the
@ -564,9 +564,9 @@ PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
A single PaStream can provide multiple channels of real-time
streaming audio input and output to a client application. A stream
provides access to audio hardware represented by one or more
PaDevices. Depending on the underlying Host API, it may be possible
to open multiple streams using the same device, however this behavior
is implementation defined. Portable applications should assume that
PaDevices. Depending on the underlying Host API, it may be possible
to open multiple streams using the same device, however this behavior
is implementation defined. Portable applications should assume that
a PaDevice may be simultaneously used by at most one PaStream.
Pointers to PaStream objects are passed between PortAudio functions that
@ -624,7 +624,7 @@ typedef unsigned long PaStreamFlags;
/** Call the stream callback to fill initial output buffers, rather than the
default behavior of priming the buffers with zeros (silence). This flag has
no effect for input-only and blocking read/write streams.
@see PaStreamFlags
*/
#define paPrimeOutputBuffersUsingStreamCallback ((PaStreamFlags) 0x00000008)
@ -703,11 +703,11 @@ typedef enum PaStreamCallbackResult
Functions of type PaStreamCallback are implemented by PortAudio clients.
They consume, process or generate audio in response to requests from an
active PortAudio stream.
@param input and @param output are arrays of interleaved samples,
the format, packing and number of channels used by the buffers are
determined by parameters to Pa_OpenStream().
@param frameCount The number of sample frames to be processed by
the stream callback.
@ -752,10 +752,10 @@ typedef int PaStreamCallback(
/** Opens a stream for either input, output or both.
@param stream The address of a PaStream pointer which will receive
a pointer to the newly opened stream.
@param inputParameters A structure that describes the input parameters used by
the opened stream. See PaStreamParameters for a description of these parameters.
inputParameters must be NULL for output-only streams.
@ -763,10 +763,10 @@ typedef int PaStreamCallback(
@param outputParameters A structure that describes the output parameters used by
the opened stream. See PaStreamParameters for a description of these parameters.
outputParameters must be NULL for input-only streams.
@param sampleRate The desired sampleRate. For full-duplex streams it is the
sample rate for both input and output
@param framesPerBuffer The number of frames passed to the stream callback
function, or the preferred block granularity for a blocking read/write stream.
The special value paFramesPerBufferUnspecified (0) may be used to request that
@ -778,11 +778,11 @@ typedef int PaStreamCallback(
will be kept to the theoretical minimum however, it is strongly recommended
that a non-zero framesPerBuffer value only be used when your algorithm
requires a fixed number of frames per stream callback.
@param streamFlags Flags which modify the behaviour of the streaming process.
This parameter may contain a combination of flags ORed together. Some flags may
only be relevant to certain buffer formats.
@param streamCallback A pointer to a client supplied function that is responsible
for processing and filling input and output buffers. If this parameter is NULL
the stream will be opened in 'blocking read/write' mode. In blocking mode,
@ -795,7 +795,7 @@ typedef int PaStreamCallback(
function. It could for example, contain a pointer to instance data necessary
for processing the audio buffers. This parameter is ignored if streamCallback
is NULL.
@return
Upon success Pa_OpenStream() returns paNoError and places a pointer to a
valid PaStream in the stream argument. The stream is inactive (stopped).
@ -820,7 +820,7 @@ PaError Pa_OpenStream( PaStream** stream,
@param stream The address of a PaStream pointer which will receive
a pointer to the newly opened stream.
@param numInputChannels The number of channels of sound that will be supplied
to the stream callback or returned by Pa_ReadStream. It can range from 1 to
the value of maxInputChannels in the PaDeviceInfo record for the default input
@ -835,7 +835,7 @@ PaError Pa_OpenStream( PaStream** stream,
provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream.
sampleFormat may be any of the formats described by the PaSampleFormat
enumeration.
@param sampleRate Same as Pa_OpenStream parameter of the same name.
@param framesPerBuffer Same as Pa_OpenStream parameter of the same name.
@param streamCallback Same as Pa_OpenStream parameter of the same name.
@ -861,7 +861,7 @@ PaError Pa_OpenDefaultStream( PaStream** stream,
PaError Pa_CloseStream( PaStream *stream );
/** Functions of type PaStreamFinishedCallback are implemented by PortAudio
/** Functions of type PaStreamFinishedCallback are implemented by PortAudio
clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback
function. Once registered they are called when the stream becomes inactive
(ie once a call to Pa_StopStream() will not block).
@ -870,7 +870,7 @@ PaError Pa_CloseStream( PaStream *stream );
output, if the stream callback returns paComplete, or Pa_StopStream is called,
the stream finished callback will not be called until all generated sample data
has been played.
@param userData The userData parameter supplied to Pa_OpenStream()
@see Pa_SetStreamFinishedCallback
@ -878,12 +878,12 @@ PaError Pa_CloseStream( PaStream *stream );
typedef void PaStreamFinishedCallback( void *userData );
/** Register a stream finished callback function which will be called when the
stream becomes inactive. See the description of PaStreamFinishedCallback for
/** Register a stream finished callback function which will be called when the
stream becomes inactive. See the description of PaStreamFinishedCallback for
further details about when the callback will be called.
@param stream a pointer to a PaStream that is in the stopped state - if the
stream is not stopped, the stream's finished callback will remain unchanged
stream is not stopped, the stream's finished callback will remain unchanged
and an error code will be returned.
@param streamFinishedCallback a pointer to a function with the same signature
@ -896,7 +896,7 @@ typedef void PaStreamFinishedCallback( void *userData );
@see PaStreamFinishedCallback
*/
PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback );
PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback );
/** Commences audio processing.
@ -981,7 +981,7 @@ typedef struct PaStreamInfo
parameter passed to Pa_OpenStream().
*/
double sampleRate;
} PaStreamInfo;
@ -1004,7 +1004,7 @@ const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream );
/** Determine the current time for the stream according to the same clock used
to generate buffer timestamps. This time may be used for syncronising other
events to the audio stream, for example synchronizing audio to MIDI.
@return The stream's current time in seconds, or 0 if an error occurred.
@see PaTime, PaStreamCallback
@ -1019,7 +1019,7 @@ PaTime Pa_GetStreamTime( PaStream *stream );
This function may be called from the stream callback function or the
application.
@return
A floating point value, typically between 0.0 and 1.0, where 1.0 indicates
that the stream callback is consuming the maximum number of CPU cycles possible
@ -1036,7 +1036,7 @@ double Pa_GetStreamCpuLoad( PaStream* stream );
system to supply the data.
@param stream A pointer to an open stream previously created with Pa_OpenStream.
@param buffer A pointer to a buffer of sample frames. The buffer contains
samples in the format specified by the inputParameters->sampleFormat field
used to open the stream, and the number of channels specified by

View File

@ -1,105 +1,105 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
<meta name="Author" content="Phil Burk">
<meta name="Description" content="PortAudio is a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
<meta name="KeyWords" content="audio, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
<title>PortAudio Implementations for DirectSound</title>
</head>
<body>
&nbsp;
<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
<tr>
<td>
<center>
<h1>
PortAudio - Portable Audio Library</h1></center>
</td>
</tr>
</table></center>
<p>PortAudio is a cross platform, <a href="#License">open-source</a>, audio
I/O library proposed by <b>Ross Bencina</b> to the <a href="http://shoko.calarts.edu/~glmrboy/musicdsp/music-dsp.html">music-dsp</a>
mailing list. It lets you write simple audio programs in 'C' that will
compile and run on <b>Windows, Macintosh, Unix, BeOS</b>. PortAudio is
intended to promote the exchange of audio synthesis software between developers
on different platforms.
<p>For complete information on PortAudio and to download the latest releases,
please visit "<b><font size=+2><a href="http://www.portaudio.com">http://www.portaudio.com</a></font></b>".
<br>&nbsp;
<br>&nbsp;
<center>
<h2>
<b><a href="doc/html/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>.</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>
<table width="600">
<tr><td>
<p>
PortAudio Portable Real-Time Audio Library
<br>Copyright &copy; 1999-2006 Ross Bencina and Phil Burk
</p>
<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:
</p>
<p>
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
</p>
<p>
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.
</p>
<p><i>
The text above constitutes the entire PortAudio license; however,
the PortAudio community also makes the following non-binding requests:
</i></p>
<p><i>
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. It is also
requested that these non-binding requests be included along with the
license above.
</i></p>
</td></tr></table>
<br>&nbsp;
</body>
</html>
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
<meta name="Author" content="Phil Burk">
<meta name="Description" content="PortAudio is a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
<meta name="KeyWords" content="audio, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
<title>PortAudio Implementations for DirectSound</title>
</head>
<body>
&nbsp;
<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
<tr>
<td>
<center>
<h1>
PortAudio - Portable Audio Library</h1></center>
</td>
</tr>
</table></center>
<p>PortAudio is a cross platform, <a href="#License">open-source</a>, audio
I/O library proposed by <b>Ross Bencina</b> to the <a href="http://shoko.calarts.edu/~glmrboy/musicdsp/music-dsp.html">music-dsp</a>
mailing list. It lets you write simple audio programs in 'C' that will
compile and run on <b>Windows, Macintosh, Unix, BeOS</b>. PortAudio is
intended to promote the exchange of audio synthesis software between developers
on different platforms.
<p>For complete information on PortAudio and to download the latest releases,
please visit "<b><font size=+2><a href="http://www.portaudio.com">http://www.portaudio.com</a></font></b>".
<br>&nbsp;
<br>&nbsp;
<center>
<h2>
<b><a href="doc/html/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>.</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>
<table width="600">
<tr><td>
<p>
PortAudio Portable Real-Time Audio Library
<br>Copyright &copy; 1999-2006 Ross Bencina and Phil Burk
</p>
<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:
</p>
<p>
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
</p>
<p>
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.
</p>
<p><i>
The text above constitutes the entire PortAudio license; however,
the PortAudio community also makes the following non-binding requests:
</i></p>
<p><i>
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. It is also
requested that these non-binding requests be included along with the
license above.
</i></p>
</td></tr></table>
<br>&nbsp;
</body>
</html>

View File

@ -1,251 +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
#!/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

View File

@ -1,45 +1,45 @@
README for PABLIO
Portable Audio Blocking I/O Library
Author: Phil Burk
PABLIO is a simplified interface to PortAudio that provide
read/write style blocking I/O.
Please see the .DOC file for documentation.
/*
* More information on PortAudio at: http://www.portaudio.com
* Copyright (c) 1999-2000 Phil Burk
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
README for PABLIO
Portable Audio Blocking I/O Library
Author: Phil Burk
PABLIO is a simplified interface to PortAudio that provide
read/write style blocking I/O.
Please see the .DOC file for documentation.
/*
* More information on PortAudio at: http://www.portaudio.com
* Copyright (c) 1999-2000 Phil Burk
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 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.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -30,13 +30,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -1,35 +1,35 @@
LIBRARY PABLIO
DESCRIPTION 'PABLIO Portable Audio Blocking I/O'
EXPORTS
; Explicit exports can go here
Pa_Initialize @1
Pa_Terminate @2
Pa_GetHostError @3
Pa_GetErrorText @4
Pa_CountDevices @5
Pa_GetDefaultInputDeviceID @6
Pa_GetDefaultOutputDeviceID @7
Pa_GetDeviceInfo @8
Pa_OpenStream @9
Pa_OpenDefaultStream @10
Pa_CloseStream @11
Pa_StartStream @12
Pa_StopStream @13
Pa_StreamActive @14
Pa_StreamTime @15
Pa_GetCPULoad @16
Pa_GetMinNumBuffers @17
Pa_Sleep @18
OpenAudioStream @19
CloseAudioStream @20
WriteAudioStream @21
ReadAudioStream @22
Pa_GetSampleSize @23
;123456789012345678901234567890123456
;000000000111111111122222222223333333
LIBRARY PABLIO
DESCRIPTION 'PABLIO Portable Audio Blocking I/O'
EXPORTS
; Explicit exports can go here
Pa_Initialize @1
Pa_Terminate @2
Pa_GetHostError @3
Pa_GetErrorText @4
Pa_CountDevices @5
Pa_GetDefaultInputDeviceID @6
Pa_GetDefaultOutputDeviceID @7
Pa_GetDeviceInfo @8
Pa_OpenStream @9
Pa_OpenDefaultStream @10
Pa_CloseStream @11
Pa_StartStream @12
Pa_StopStream @13
Pa_StreamActive @14
Pa_StreamTime @15
Pa_GetCPULoad @16
Pa_GetMinNumBuffers @17
Pa_Sleep @18
OpenAudioStream @19
CloseAudioStream @20
WriteAudioStream @21
ReadAudioStream @22
Pa_GetSampleSize @23
;123456789012345678901234567890123456
;000000000111111111122222222223333333

View File

@ -39,13 +39,13 @@ extern "C"
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -31,13 +31,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -36,13 +36,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -32,13 +32,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -32,13 +32,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -1,12 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: PortAudio
Description: Portable audio I/O
Requires:
Version: 19
Libs: -L${libdir} -lportaudio @LIBS@
Cflags: -I${includedir} @THREAD_CFLAGS@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: PortAudio
Description: Portable audio I/O
Requires:
Version: 19
Libs: -L${libdir} -lportaudio @LIBS@
Cflags: -I${includedir} @THREAD_CFLAGS@

View File

@ -1,219 +1,219 @@
import os.path, copy, sys
def checkSymbol(conf, header, library=None, symbol=None, autoAdd=True, critical=False, pkgName=None):
""" Check for symbol in library, optionally look only for header.
@param conf: Configure instance.
@param header: The header file where the symbol is declared.
@param library: The library in which the symbol exists, if None it is taken to be the standard C library.
@param symbol: The symbol to look for, if None only the header will be looked up.
@param autoAdd: Automatically link with this library if check is positive.
@param critical: Raise on error?
@param pkgName: Optional name of pkg-config entry for library, to determine build parameters.
@return: True/False
"""
origEnv = conf.env.Copy() # Copy unmodified environment so we can restore it upon error
env = conf.env
if library is None:
library = "c" # Standard library
autoAdd = False
if pkgName is not None:
origLibs = copy.copy(env.get("LIBS", None))
try: env.ParseConfig("pkg-config --silence-errors %s --cflags --libs" % pkgName)
except: pass
else:
# I see no other way of checking that the parsing succeeded, if it did add no more linking parameters
if env.get("LIBS", None) != origLibs:
autoAdd = False
try:
if not conf.CheckCHeader(header, include_quotes="<>"):
raise ConfigurationError("missing header %s" % header)
if symbol is not None and not conf.CheckLib(library, symbol, language="C", autoadd=autoAdd):
raise ConfigurationError("missing symbol %s in library %s" % (symbol, library))
except ConfigurationError:
conf.env = origEnv
if not critical:
return False
raise
return True
import SCons.Errors
# Import common variables
# Could use '#' to refer to top-level SConstruct directory, but looks like env.SConsignFile doesn't interpret this at least :(
sconsDir = os.path.abspath(os.path.join("build", "scons"))
try:
Import("Platform", "Posix", "ConfigurationError", "ApiVer")
except SCons.Errors.UserError:
# The common objects must be exported first
SConscript(os.path.join(sconsDir, "SConscript_common"))
Import("Platform", "Posix", "ConfigurationError", "ApiVer")
Import("env")
# This will be manipulated
env = env.Copy()
# We operate with a set of needed libraries and optional libraries, the latter stemming from host API implementations.
# For libraries of both types we record a set of values that is used to look for the library in question, during
# configuration. If the corresponding library for a host API implementation isn't found, the implementation is left out.
neededLibs = []
optionalImpls = {}
if Platform in Posix:
env.Append(CPPPATH=os.path.join("os", "unix"))
neededLibs += [("pthread", "pthread.h", "pthread_create"), ("m", "math.h", "sin")]
if env["useALSA"]:
optionalImpls["ALSA"] = ("asound", "alsa/asoundlib.h", "snd_pcm_open")
if env["useJACK"]:
optionalImpls["JACK"] = ("jack", "jack/jack.h", "jack_client_new")
if env["useOSS"]:
# TODO: It looks like the prefix for soundcard.h depends on the platform
optionalImpls["OSS"] = ("oss", "sys/soundcard.h", None)
if Platform == 'netbsd':
optionalImpls["OSS"] = ("ossaudio", "sys/soundcard.h", "_oss_ioctl")
if env["useASIHPI"]:
optionalImpls["ASIHPI"] = ("hpi", "asihpi/hpi.h", "HPI_SubSysCreate")
if env["useCOREAUDIO"]:
optionalImpls["COREAUDIO"] = ("CoreAudio", "CoreAudio/CoreAudio.h", None)
else:
raise ConfigurationError("unknown platform %s" % Platform)
if Platform == "darwin":
env.Append(LINKFLAGS="-framework CoreFoundation -framework CoreServices -framework CoreAudio -framework AudioToolBox -framework AudioUnit")
elif Platform == "cygwin":
env.Append(LIBS=["winmm"])
elif Platform == "irix":
neededLibs += [("audio", "dmedia/audio.h", "alOpenPort"), ("dmedia", "dmedia/dmedia.h", "dmGetUST")]
env.Append(CPPDEFINES=["PA_USE_SGI"])
def CheckCTypeSize(context, tp):
""" Check size of C type.
@param context: A configuration context.
@param tp: The type to check.
@return: Size of type, in bytes.
"""
context.Message("Checking the size of C type %s..." % tp)
ret = context.TryRun("""
#include <stdio.h>
int main() {
printf("%%d", sizeof(%s));
return 0;
}
""" % tp, ".c")
if not ret[0]:
context.Result(" Couldn't obtain size of type %s!" % tp)
return None
assert ret[1]
sz = int(ret[1])
context.Result("%d" % sz)
return sz
"""
if sys.byteorder == "little":
env.Append(CPPDEFINES=["PA_LITTLE_ENDIAN"])
elif sys.byteorder == "big":
env.Append(CPPDEFINES=["PA_BIG_ENDIAN"])
else:
raise ConfigurationError("unknown byte order: %s" % sys.byteorder)
"""
if env["enableDebugOutput"]:
env.Append(CPPDEFINES=["PA_ENABLE_DEBUG_OUTPUT"])
# Start configuration
# Use an absolute path for conf_dir, otherwise it gets created both relative to current directory and build directory
conf = env.Configure(log_file=os.path.join(sconsDir, "sconf.log"), custom_tests={"CheckCTypeSize": CheckCTypeSize},
conf_dir=os.path.join(sconsDir, ".sconf_temp"))
conf.env.Append(CPPDEFINES=["SIZEOF_SHORT=%d" % conf.CheckCTypeSize("short")])
conf.env.Append(CPPDEFINES=["SIZEOF_INT=%d" % conf.CheckCTypeSize("int")])
conf.env.Append(CPPDEFINES=["SIZEOF_LONG=%d" % conf.CheckCTypeSize("long")])
if checkSymbol(conf, "time.h", "rt", "clock_gettime"):
conf.env.Append(CPPDEFINES=["HAVE_CLOCK_GETTIME"])
if checkSymbol(conf, "time.h", symbol="nanosleep"):
conf.env.Append(CPPDEFINES=["HAVE_NANOSLEEP"])
if conf.CheckCHeader("sys/soundcard.h"):
conf.env.Append(CPPDEFINES=["HAVE_SYS_SOUNDCARD_H"])
if conf.CheckCHeader("linux/soundcard.h"):
conf.env.Append(CPPDEFINES=["HAVE_LINUX_SOUNDCARD_H"])
if conf.CheckCHeader("machine/soundcard.h"):
conf.env.Append(CPPDEFINES=["HAVE_MACHINE_SOUNDCARD_H"])
# Look for needed libraries and link with them
for lib, hdr, sym in neededLibs:
checkSymbol(conf, hdr, lib, sym, critical=True)
# Look for host API libraries, if a library isn't found disable corresponding host API implementation.
for name, val in optionalImpls.items():
lib, hdr, sym = val
if checkSymbol(conf, hdr, lib, sym, critical=False, pkgName=name.lower()):
conf.env.Append(CPPDEFINES=["PA_USE_%s=1" % name.upper()])
else:
del optionalImpls[name]
# Configuration finished
env = conf.Finish()
# PA infrastructure
CommonSources = [os.path.join("common", f) for f in "pa_allocation.c pa_converters.c pa_cpuload.c pa_dither.c pa_front.c \
pa_process.c pa_skeleton.c pa_stream.c pa_trace.c pa_debugprint.c pa_ringbuffer.c".split()]
# Host APIs implementations
ImplSources = []
if Platform in Posix:
ImplSources += [os.path.join("os", "unix", f) for f in "pa_unix_hostapis.c pa_unix_util.c".split()]
if "ALSA" in optionalImpls:
ImplSources.append(os.path.join("hostapi", "alsa", "pa_linux_alsa.c"))
if "JACK" in optionalImpls:
ImplSources.append(os.path.join("hostapi", "jack", "pa_jack.c"))
if "OSS" in optionalImpls:
ImplSources.append(os.path.join("hostapi", "oss", "pa_unix_oss.c"))
if "ASIHPI" in optionalImpls:
ImplSources.append(os.path.join("hostapi", "asihpi", "pa_linux_asihpi.c"))
if "COREAUDIO" in optionalImpls:
ImplSources.append([os.path.join("hostapi", "coreaudio", f) for f in """
pa_mac_core.c pa_mac_core_blocking.c pa_mac_core_utilities.c
""".split()])
sources = CommonSources + ImplSources
sharedLibEnv = env.Copy()
if Platform in Posix:
# Add soname to library, this is so a reference is made to the versioned library in programs linking against libportaudio.so
if Platform != 'darwin':
sharedLibEnv.AppendUnique(SHLINKFLAGS="-Wl,-soname=libportaudio.so.%d" % int(ApiVer.split(".")[0]))
sharedLib = sharedLibEnv.SharedLibrary(target="portaudio", source=sources)
staticLib = env.StaticLibrary(target="portaudio", source=sources)
if Platform in Posix:
prefix = env["prefix"]
includeDir = os.path.join(prefix, "include")
libDir = os.path.join(prefix, "lib")
testNames = ["patest_sine", "paqa_devs", "paqa_errs", "patest1", "patest_buffer", "patest_callbackstop", "patest_clip", \
"patest_dither", "patest_hang", "patest_in_overflow", "patest_latency", "patest_leftright", "patest_longsine", \
"patest_many", "patest_maxsines", "patest_multi_sine", "patest_out_underflow", "patest_pink", "patest_prime", \
"patest_read_record", "patest_record", "patest_ringmix", "patest_saw", "patest_sine8", "patest_sine", \
"patest_sine_time", "patest_start_stop", "patest_stop", "patest_sync", "patest_toomanysines", \
"patest_underflow", "patest_wire", "patest_write_sine", "pa_devs", "pa_fuzz", "pa_minlat", \
"patest_sine_channelmaps",]
# The test directory ("bin") should be in the top-level PA directory
tests = [env.Program(target=os.path.join("#", "bin", name), source=[os.path.join("#", "test", name + ".c"),
staticLib]) for name in testNames]
# Detect host APIs
hostApis = []
for cppdef in env["CPPDEFINES"]:
if cppdef.startswith("PA_USE_"):
hostApis.append(cppdef[7:-2])
Return("sources", "sharedLib", "staticLib", "tests", "env", "hostApis")
import os.path, copy, sys
def checkSymbol(conf, header, library=None, symbol=None, autoAdd=True, critical=False, pkgName=None):
""" Check for symbol in library, optionally look only for header.
@param conf: Configure instance.
@param header: The header file where the symbol is declared.
@param library: The library in which the symbol exists, if None it is taken to be the standard C library.
@param symbol: The symbol to look for, if None only the header will be looked up.
@param autoAdd: Automatically link with this library if check is positive.
@param critical: Raise on error?
@param pkgName: Optional name of pkg-config entry for library, to determine build parameters.
@return: True/False
"""
origEnv = conf.env.Copy() # Copy unmodified environment so we can restore it upon error
env = conf.env
if library is None:
library = "c" # Standard library
autoAdd = False
if pkgName is not None:
origLibs = copy.copy(env.get("LIBS", None))
try: env.ParseConfig("pkg-config --silence-errors %s --cflags --libs" % pkgName)
except: pass
else:
# I see no other way of checking that the parsing succeeded, if it did add no more linking parameters
if env.get("LIBS", None) != origLibs:
autoAdd = False
try:
if not conf.CheckCHeader(header, include_quotes="<>"):
raise ConfigurationError("missing header %s" % header)
if symbol is not None and not conf.CheckLib(library, symbol, language="C", autoadd=autoAdd):
raise ConfigurationError("missing symbol %s in library %s" % (symbol, library))
except ConfigurationError:
conf.env = origEnv
if not critical:
return False
raise
return True
import SCons.Errors
# Import common variables
# Could use '#' to refer to top-level SConstruct directory, but looks like env.SConsignFile doesn't interpret this at least :(
sconsDir = os.path.abspath(os.path.join("build", "scons"))
try:
Import("Platform", "Posix", "ConfigurationError", "ApiVer")
except SCons.Errors.UserError:
# The common objects must be exported first
SConscript(os.path.join(sconsDir, "SConscript_common"))
Import("Platform", "Posix", "ConfigurationError", "ApiVer")
Import("env")
# This will be manipulated
env = env.Copy()
# We operate with a set of needed libraries and optional libraries, the latter stemming from host API implementations.
# For libraries of both types we record a set of values that is used to look for the library in question, during
# configuration. If the corresponding library for a host API implementation isn't found, the implementation is left out.
neededLibs = []
optionalImpls = {}
if Platform in Posix:
env.Append(CPPPATH=os.path.join("os", "unix"))
neededLibs += [("pthread", "pthread.h", "pthread_create"), ("m", "math.h", "sin")]
if env["useALSA"]:
optionalImpls["ALSA"] = ("asound", "alsa/asoundlib.h", "snd_pcm_open")
if env["useJACK"]:
optionalImpls["JACK"] = ("jack", "jack/jack.h", "jack_client_new")
if env["useOSS"]:
# TODO: It looks like the prefix for soundcard.h depends on the platform
optionalImpls["OSS"] = ("oss", "sys/soundcard.h", None)
if Platform == 'netbsd':
optionalImpls["OSS"] = ("ossaudio", "sys/soundcard.h", "_oss_ioctl")
if env["useASIHPI"]:
optionalImpls["ASIHPI"] = ("hpi", "asihpi/hpi.h", "HPI_SubSysCreate")
if env["useCOREAUDIO"]:
optionalImpls["COREAUDIO"] = ("CoreAudio", "CoreAudio/CoreAudio.h", None)
else:
raise ConfigurationError("unknown platform %s" % Platform)
if Platform == "darwin":
env.Append(LINKFLAGS="-framework CoreFoundation -framework CoreServices -framework CoreAudio -framework AudioToolBox -framework AudioUnit")
elif Platform == "cygwin":
env.Append(LIBS=["winmm"])
elif Platform == "irix":
neededLibs += [("audio", "dmedia/audio.h", "alOpenPort"), ("dmedia", "dmedia/dmedia.h", "dmGetUST")]
env.Append(CPPDEFINES=["PA_USE_SGI"])
def CheckCTypeSize(context, tp):
""" Check size of C type.
@param context: A configuration context.
@param tp: The type to check.
@return: Size of type, in bytes.
"""
context.Message("Checking the size of C type %s..." % tp)
ret = context.TryRun("""
#include <stdio.h>
int main() {
printf("%%d", sizeof(%s));
return 0;
}
""" % tp, ".c")
if not ret[0]:
context.Result(" Couldn't obtain size of type %s!" % tp)
return None
assert ret[1]
sz = int(ret[1])
context.Result("%d" % sz)
return sz
"""
if sys.byteorder == "little":
env.Append(CPPDEFINES=["PA_LITTLE_ENDIAN"])
elif sys.byteorder == "big":
env.Append(CPPDEFINES=["PA_BIG_ENDIAN"])
else:
raise ConfigurationError("unknown byte order: %s" % sys.byteorder)
"""
if env["enableDebugOutput"]:
env.Append(CPPDEFINES=["PA_ENABLE_DEBUG_OUTPUT"])
# Start configuration
# Use an absolute path for conf_dir, otherwise it gets created both relative to current directory and build directory
conf = env.Configure(log_file=os.path.join(sconsDir, "sconf.log"), custom_tests={"CheckCTypeSize": CheckCTypeSize},
conf_dir=os.path.join(sconsDir, ".sconf_temp"))
conf.env.Append(CPPDEFINES=["SIZEOF_SHORT=%d" % conf.CheckCTypeSize("short")])
conf.env.Append(CPPDEFINES=["SIZEOF_INT=%d" % conf.CheckCTypeSize("int")])
conf.env.Append(CPPDEFINES=["SIZEOF_LONG=%d" % conf.CheckCTypeSize("long")])
if checkSymbol(conf, "time.h", "rt", "clock_gettime"):
conf.env.Append(CPPDEFINES=["HAVE_CLOCK_GETTIME"])
if checkSymbol(conf, "time.h", symbol="nanosleep"):
conf.env.Append(CPPDEFINES=["HAVE_NANOSLEEP"])
if conf.CheckCHeader("sys/soundcard.h"):
conf.env.Append(CPPDEFINES=["HAVE_SYS_SOUNDCARD_H"])
if conf.CheckCHeader("linux/soundcard.h"):
conf.env.Append(CPPDEFINES=["HAVE_LINUX_SOUNDCARD_H"])
if conf.CheckCHeader("machine/soundcard.h"):
conf.env.Append(CPPDEFINES=["HAVE_MACHINE_SOUNDCARD_H"])
# Look for needed libraries and link with them
for lib, hdr, sym in neededLibs:
checkSymbol(conf, hdr, lib, sym, critical=True)
# Look for host API libraries, if a library isn't found disable corresponding host API implementation.
for name, val in optionalImpls.items():
lib, hdr, sym = val
if checkSymbol(conf, hdr, lib, sym, critical=False, pkgName=name.lower()):
conf.env.Append(CPPDEFINES=["PA_USE_%s=1" % name.upper()])
else:
del optionalImpls[name]
# Configuration finished
env = conf.Finish()
# PA infrastructure
CommonSources = [os.path.join("common", f) for f in "pa_allocation.c pa_converters.c pa_cpuload.c pa_dither.c pa_front.c \
pa_process.c pa_skeleton.c pa_stream.c pa_trace.c pa_debugprint.c pa_ringbuffer.c".split()]
# Host APIs implementations
ImplSources = []
if Platform in Posix:
ImplSources += [os.path.join("os", "unix", f) for f in "pa_unix_hostapis.c pa_unix_util.c".split()]
if "ALSA" in optionalImpls:
ImplSources.append(os.path.join("hostapi", "alsa", "pa_linux_alsa.c"))
if "JACK" in optionalImpls:
ImplSources.append(os.path.join("hostapi", "jack", "pa_jack.c"))
if "OSS" in optionalImpls:
ImplSources.append(os.path.join("hostapi", "oss", "pa_unix_oss.c"))
if "ASIHPI" in optionalImpls:
ImplSources.append(os.path.join("hostapi", "asihpi", "pa_linux_asihpi.c"))
if "COREAUDIO" in optionalImpls:
ImplSources.append([os.path.join("hostapi", "coreaudio", f) for f in """
pa_mac_core.c pa_mac_core_blocking.c pa_mac_core_utilities.c
""".split()])
sources = CommonSources + ImplSources
sharedLibEnv = env.Copy()
if Platform in Posix:
# Add soname to library, this is so a reference is made to the versioned library in programs linking against libportaudio.so
if Platform != 'darwin':
sharedLibEnv.AppendUnique(SHLINKFLAGS="-Wl,-soname=libportaudio.so.%d" % int(ApiVer.split(".")[0]))
sharedLib = sharedLibEnv.SharedLibrary(target="portaudio", source=sources)
staticLib = env.StaticLibrary(target="portaudio", source=sources)
if Platform in Posix:
prefix = env["prefix"]
includeDir = os.path.join(prefix, "include")
libDir = os.path.join(prefix, "lib")
testNames = ["patest_sine", "paqa_devs", "paqa_errs", "patest1", "patest_buffer", "patest_callbackstop", "patest_clip", \
"patest_dither", "patest_hang", "patest_in_overflow", "patest_latency", "patest_leftright", "patest_longsine", \
"patest_many", "patest_maxsines", "patest_multi_sine", "patest_out_underflow", "patest_pink", "patest_prime", \
"patest_read_record", "patest_record", "patest_ringmix", "patest_saw", "patest_sine8", "patest_sine", \
"patest_sine_time", "patest_start_stop", "patest_stop", "patest_sync", "patest_toomanysines", \
"patest_underflow", "patest_wire", "patest_write_sine", "pa_devs", "pa_fuzz", "pa_minlat", \
"patest_sine_channelmaps",]
# The test directory ("bin") should be in the top-level PA directory
tests = [env.Program(target=os.path.join("#", "bin", name), source=[os.path.join("#", "test", name + ".c"),
staticLib]) for name in testNames]
# Detect host APIs
hostApis = []
for cppdef in env["CPPDEFINES"]:
if cppdef.startswith("PA_USE_"):
hostApis.append(cppdef[7:-2])
Return("sources", "sharedLib", "staticLib", "tests", "env", "hostApis")

View File

@ -27,13 +27,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -78,7 +78,7 @@ static struct PaUtilAllocationGroupLink *AllocateLinks( long count,
{
struct PaUtilAllocationGroupLink *result;
int i;
result = (struct PaUtilAllocationGroupLink *)PaUtil_AllocateMemory(
sizeof(struct PaUtilAllocationGroupLink) * count );
if( result )
@ -95,7 +95,7 @@ static struct PaUtilAllocationGroupLink *AllocateLinks( long count,
}
result[count-1].next = nextSpare;
}
return result;
}
@ -147,7 +147,7 @@ void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size )
{
struct PaUtilAllocationGroupLink *links, *link;
void *result = 0;
/* allocate more links if necessary */
if( !group->spareLinks )
{
@ -176,7 +176,7 @@ void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size )
}
}
return result;
return result;
}
@ -208,7 +208,7 @@ void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer )
break;
}
previous = current;
current = current->next;
}

View File

@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -44,7 +44,7 @@
@brief Allocation Group prototypes. An Allocation Group makes it easy to
allocate multiple blocks of memory and free them all at once.
An allocation group is useful for keeping track of multiple blocks
of memory which are allocated at the same time (such as during initialization)
and need to be deallocated at the same time. The allocation group maintains

View File

@ -26,13 +26,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -40,7 +40,7 @@
@ingroup common_src
@brief Conversion function implementations.
If the C9x function lrintf() is available, define PA_USE_C99_LRINTF to use it
@todo Consider whether functions which dither but don't clip should exist,
@ -49,7 +49,7 @@
@todo implement the converters marked IMPLEMENT ME: Float32_To_UInt8_Dither,
Float32_To_UInt8_Clip, Float32_To_UInt8_DitherClip, Int32_To_Int24_Dither,
Int32_To_UInt8_Dither, Int24_To_Int16_Dither, Int24_To_Int8_Dither,
Int32_To_UInt8_Dither, Int24_To_Int16_Dither, Int24_To_Int8_Dither,
Int24_To_UInt8_Dither, Int16_To_Int8_Dither, Int16_To_UInt8_Dither,
@todo review the converters marked REVIEW: Float32_To_Int32,
@ -71,7 +71,7 @@ PaSampleFormat PaUtil_SelectClosestAvailableFormat(
format &= ~paNonInterleaved;
availableFormats &= ~paNonInterleaved;
if( (format & availableFormats) == 0 )
{
/* NOTE: this code depends on the sample format constants being in
@ -94,7 +94,7 @@ PaSampleFormat PaUtil_SelectClosestAvailableFormat(
{
result = 0;
}
if( result == 0 ){
/* scan for worse formats */
result = format;
@ -107,7 +107,7 @@ PaSampleFormat PaUtil_SelectClosestAvailableFormat(
if( (result & availableFormats) == 0 )
result = paSampleFormatNotSupported;
}
}else{
result = format;
}
@ -283,7 +283,7 @@ PaUtilConverterTable paConverters = {
0, /* PaUtilConverter *Int24_To_Int8_Dither; */
0, /* PaUtilConverter *Int24_To_UInt8; */
0, /* PaUtilConverter *Int24_To_UInt8_Dither; */
0, /* PaUtilConverter *Int16_To_Float32; */
0, /* PaUtilConverter *Int16_To_Int32; */
0, /* PaUtilConverter *Int16_To_Int24; */
@ -345,9 +345,9 @@ static void Float32_To_Int32(
*dest = lrintf(scaled-0.5f);
#else
double scaled = *src * 0x7FFFFFFF;
*dest = (PaInt32) scaled;
*dest = (PaInt32) scaled;
#endif
src += sourceStride;
dest += destinationStride;
}
@ -392,7 +392,7 @@ static void Float32_To_Int32_Clip(
float *src = (float*)sourceBuffer;
PaInt32 *dest = (PaInt32*)destinationBuffer;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
/* REVIEW */
@ -455,13 +455,13 @@ static void Float32_To_Int24(
PaInt32 temp;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
/* convert to 32 bit and drop the low 8 bits */
double scaled = *src * 0x7FFFFFFF;
temp = (PaInt32) scaled;
#if defined(PA_LITTLE_ENDIAN)
dest[0] = (unsigned char)(temp >> 8);
dest[1] = (unsigned char)(temp >> 16);
@ -495,7 +495,7 @@ static void Float32_To_Int24_Dither(
double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
/* use smaller scaler to prevent overflow when we add the dither */
double dithered = ((double)*src * (2147483646.0)) + dither;
temp = (PaInt32) dithered;
#if defined(PA_LITTLE_ENDIAN)
@ -525,7 +525,7 @@ static void Float32_To_Int24_Clip(
PaInt32 temp;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
/* convert to 32 bit and drop the low 8 bits */
@ -558,16 +558,16 @@ static void Float32_To_Int24_DitherClip(
float *src = (float*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
PaInt32 temp;
while( count-- )
{
/* convert to 32 bit and drop the low 8 bits */
double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
/* use smaller scaler to prevent overflow when we add the dither */
double dithered = ((double)*src * (2147483646.0)) + dither;
PA_CLIP_( dithered, -2147483648., 2147483647. );
temp = (PaInt32) dithered;
#if defined(PA_LITTLE_ENDIAN)
@ -898,7 +898,7 @@ static void Int32_To_Int24(
PaInt32 *src = (PaInt32*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
/* REVIEW */
@ -1029,7 +1029,7 @@ static void Int32_To_UInt8(
while( count-- )
{
(*dest) = (unsigned char)(((*src) >> 24) + 128);
(*dest) = (unsigned char)(((*src) >> 24) + 128);
src += sourceStride;
dest += destinationStride;
@ -1068,12 +1068,12 @@ static void Int24_To_Float32(
PaInt32 temp;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
#if defined(PA_LITTLE_ENDIAN)
temp = (((PaInt32)src[0]) << 8);
temp = (((PaInt32)src[0]) << 8);
temp = temp | (((PaInt32)src[1]) << 16);
temp = temp | (((PaInt32)src[2]) << 24);
#elif defined(PA_BIG_ENDIAN)
@ -1101,12 +1101,12 @@ static void Int24_To_Int32(
PaInt32 temp;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
#if defined(PA_LITTLE_ENDIAN)
temp = (((PaInt32)src[0]) << 8);
temp = (((PaInt32)src[0]) << 8);
temp = temp | (((PaInt32)src[1]) << 16);
temp = temp | (((PaInt32)src[2]) << 24);
#elif defined(PA_BIG_ENDIAN)
@ -1131,14 +1131,14 @@ static void Int24_To_Int16(
{
unsigned char *src = (unsigned char*)sourceBuffer;
PaInt16 *dest = (PaInt16*)destinationBuffer;
PaInt16 temp;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
#if defined(PA_LITTLE_ENDIAN)
/* src[0] is discarded */
temp = (((PaInt16)src[1]));
@ -1179,7 +1179,7 @@ static void Int24_To_Int16_Dither(
{
dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
/* downscale 24-bit int to 16-bit int placed into 32-bit float container,
/* downscale 24-bit int to 16-bit int placed into 32-bit float container,
16-bit scaler is decreased by 2 to leave space for dither in order not to overflow
*/
dithered = _PA_INT24_TO_FLOAT(src, -2.0f) + dither;
@ -1205,12 +1205,12 @@ static void Int24_To_Int8(
{
unsigned char *src = (unsigned char*)sourceBuffer;
signed char *dest = (signed char*)destinationBuffer;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
{
#if defined(PA_LITTLE_ENDIAN)
/* src[0] is discarded */
/* src[1] is discarded */
@ -1251,12 +1251,12 @@ static void Int24_To_UInt8(
{
unsigned char *src = (unsigned char*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
#if defined(PA_LITTLE_ENDIAN)
/* src[0] is discarded */
/* src[1] is discarded */
@ -1264,7 +1264,7 @@ static void Int24_To_UInt8(
#elif defined(PA_BIG_ENDIAN)
*dest = (unsigned char)(src[0] + 128);
/* src[1] is discarded */
/* src[2] is discarded */
/* src[2] is discarded */
#endif
src += sourceStride * 3;
@ -1325,7 +1325,7 @@ static void Int16_To_Int32(
/* REVIEW: we should consider something like
(*src << 16) | (*src & 0xFFFF)
*/
*dest = *src << 16;
src += sourceStride;
@ -1345,11 +1345,11 @@ static void Int16_To_Int24(
PaInt16 temp;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
temp = *src;
#if defined(PA_LITTLE_ENDIAN)
dest[0] = 0;
dest[1] = (unsigned char)(temp);
@ -1418,7 +1418,7 @@ static void Int16_To_UInt8(
while( count-- )
{
(*dest) = (unsigned char)(((*src) >> 8) + 128);
(*dest) = (unsigned char)(((*src) >> 8) + 128);
src += sourceStride;
dest += destinationStride;
@ -1606,7 +1606,7 @@ static void UInt8_To_Int24(
unsigned char *src = (unsigned char*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
(void) ditherGenerator; /* unused parameters */
while( count-- )
{
@ -1619,9 +1619,9 @@ static void UInt8_To_Int24(
dest[1] = 0;
dest[2] = 0;
#endif
src += sourceStride;
dest += destinationStride * 3;
dest += destinationStride * 3;
}
}
@ -1674,7 +1674,7 @@ static void Copy_8_To_8(
{
unsigned char *src = (unsigned char*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
(void) ditherGenerator; /* unused parameter */
while( count-- )
@ -1695,9 +1695,9 @@ static void Copy_16_To_16(
{
PaUint16 *src = (PaUint16 *)sourceBuffer;
PaUint16 *dest = (PaUint16 *)destinationBuffer;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
*dest = *src;
@ -1718,7 +1718,7 @@ static void Copy_24_To_24(
unsigned char *dest = (unsigned char*)destinationBuffer;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
dest[0] = src[0];
@ -1741,7 +1741,7 @@ static void Copy_32_To_32(
PaUint32 *src = (PaUint32 *)sourceBuffer;
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
*dest = *src;
@ -1763,7 +1763,7 @@ PaUtilConverterTable paConverters = {
Float32_To_Int24_Dither, /* PaUtilConverter *Float32_To_Int24_Dither; */
Float32_To_Int24_Clip, /* PaUtilConverter *Float32_To_Int24_Clip; */
Float32_To_Int24_DitherClip, /* PaUtilConverter *Float32_To_Int24_DitherClip; */
Float32_To_Int16, /* PaUtilConverter *Float32_To_Int16; */
Float32_To_Int16_Dither, /* PaUtilConverter *Float32_To_Int16_Dither; */
Float32_To_Int16_Clip, /* PaUtilConverter *Float32_To_Int16_Clip; */

View File

@ -28,13 +28,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -119,7 +119,7 @@ PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat,
typedef void PaUtilZeroer(
void *destinationBuffer, signed int destinationStride, unsigned int count );
/** Find a buffer zeroer function for the given destination format.
@return
A pointer to a PaUtilZeroer which will perform the requested
@ -145,7 +145,7 @@ typedef struct{
PaUtilConverter *Float32_To_Int24_Dither;
PaUtilConverter *Float32_To_Int24_Clip;
PaUtilConverter *Float32_To_Int24_DitherClip;
PaUtilConverter *Float32_To_Int16;
PaUtilConverter *Float32_To_Int16_Dither;
PaUtilConverter *Float32_To_Int16_Clip;
@ -193,7 +193,7 @@ typedef struct{
PaUtilConverter *Int8_To_Int24;
PaUtilConverter *Int8_To_Int16;
PaUtilConverter *Int8_To_UInt8;
PaUtilConverter *UInt8_To_Float32;
PaUtilConverter *UInt8_To_Int32;
PaUtilConverter *UInt8_To_Int24;

View File

@ -27,13 +27,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -68,5 +68,5 @@ double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* PA_CPULOAD_H */

View File

@ -81,7 +81,7 @@ void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb)
/* Some Windows Mobile SDKs don't define vsnprintf but all define _vsnprintf (hopefully).
According to MSDN "vsnprintf is identical to _vsnprintf". So we use _vsnprintf with MSC.
*/
#define VSNPRINTF _vsnprintf
#define VSNPRINTF _vsnprintf
#else
#define VSNPRINTF vsnprintf
#endif

View File

@ -101,7 +101,7 @@ void PaUtil_DebugPrint( const char *format, ... );
#ifdef PA_LOG_API_CALLS
#define PA_LOGAPI(x) PaUtil_DebugPrint x
#define PA_LOGAPI(x) PaUtil_DebugPrint x
#define PA_LOGAPI_ENTER(functionName) PaUtil_DebugPrint( functionName " called.\n" )
@ -133,7 +133,7 @@ void PaUtil_DebugPrint( const char *format, ... );
#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result )
#endif
typedef void (*PaUtilLogCallback ) (const char *log);
/**

View File

@ -26,13 +26,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -72,10 +72,10 @@ PaInt32 PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *s
/* 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.
* Also shift an extra bit for the high pass filter.
*/
#define DITHER_SHIFT_ ((sizeof(PaInt32)*8 - PA_DITHER_BITS_) + 1)
current = (((PaInt32)state->randSeed1)>>DITHER_SHIFT_) +
(((PaInt32)state->randSeed2)>>DITHER_SHIFT_);
@ -100,7 +100,7 @@ float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *sta
/* 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.
* Also shift an extra bit for the high pass filter.
*/
current = (((PaInt32)state->randSeed1)>>DITHER_SHIFT_) +
(((PaInt32)state->randSeed2)>>DITHER_SHIFT_);
@ -137,7 +137,7 @@ things like this: r3=(r1 & 0x7F)<<8; instead of calling rand() again.
float s1, s2; //error feedback buffers
float s = 0.5f; //set to 0.0f for no noise shaping
float w = pow(2.0,bits-1); //word length (usually bits=16)
float wi= 1.0f/w;
float wi= 1.0f/w;
float d = wi / RAND_MAX; //dither amplitude (2 lsb)
float o = wi * 0.5f; //remove dc offset
float in, tmp;
@ -148,19 +148,19 @@ things like this: r3=(r1 & 0x7F)<<8; instead of calling rand() again.
r2=r1; //can make HP-TRI dither by
r1=rand(); //subtracting previous rand()
in += s * (s1 + s1 - s2); //error feedback
tmp = in + o + d * (float)(r1 - r2); //dc offset and dither
tmp = in + o + d * (float)(r1 - r2); //dc offset and dither
out = (int)(w * tmp); //truncate downwards
if(tmp<0.0f) out--; //this is faster than floor()
s2 = s1;
s2 = s1;
s1 = in - wi * (float)out; //error
--
--
paul.kellett@maxim.abel.co.uk
http://www.maxim.abel.co.uk
*/
@ -172,7 +172,7 @@ http://www.maxim.abel.co.uk
Type : First order error feedforward dithering code
References : Posted by Jon Watte
Notes :
Notes :
This is about as simple a dithering algorithm as you can implement, but it's
likely to sound better than just truncating to N bits.
@ -183,36 +183,36 @@ and integer SIMD type instructions, or CMOV.
Last, if sound quality is paramount (such as when going from > 16 bits to 16
bits) you probably want to use a higher-order dither function found elsewhere
on this site.
on this site.
Code :
// This code will down-convert and dither a 16-bit signed short
// mono signal into an 8-bit unsigned char signal, using a first
// order forward-feeding error term dither.
Code :
// This code will down-convert and dither a 16-bit signed short
// mono signal into an 8-bit unsigned char signal, using a first
// order forward-feeding error term dither.
#define uchar unsigned char
#define uchar unsigned char
void dither_one_channel_16_to_8( short * input, uchar * output, int count, int * memory )
{
int m = *memory;
while( count-- > 0 ) {
int i = *input++;
i += m;
int j = i + 32768 - 128;
uchar o;
if( j < 0 ) {
o = 0;
}
else if( j > 65535 ) {
o = 255;
}
else {
o = (uchar)((j>>8)&0xff);
}
m = ((j-32768+128)-i);
*output++ = o;
}
*memory = m;
}
void dither_one_channel_16_to_8( short * input, uchar * output, int count, int * memory )
{
int m = *memory;
while( count-- > 0 ) {
int i = *input++;
i += m;
int j = i + 32768 - 128;
uchar o;
if( j < 0 ) {
o = 0;
}
else if( j > 65535 ) {
o = 255;
}
else {
o = (uchar)((j>>8)&0xff);
}
m = ((j-32768+128)-i);
*output++ = o;
}
*memory = m;
}
*/

View File

@ -28,13 +28,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -28,13 +28,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -27,26 +27,26 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup common_src
@brief Implements PortAudio API functions defined in portaudio.h, checks
@brief Implements PortAudio API functions defined in portaudio.h, checks
some errors, delegates platform-specific behavior to host API implementations.
Implements the functions defined in the PortAudio API (portaudio.h),
validates some parameters and checks for state inconsistencies before
forwarding API requests to specific Host API implementations (via the
interface declared in pa_hostapi.h), and Streams (via the interface
Implements the functions defined in the PortAudio API (portaudio.h),
validates some parameters and checks for state inconsistencies before
forwarding API requests to specific Host API implementations (via the
interface declared in pa_hostapi.h), and Streams (via the interface
declared in pa_stream.h).
This file manages initialization and termination of Host API
@ -180,7 +180,7 @@ static PaError InitializeHostApis( void )
if( !hostApis_ )
{
result = paInsufficientMemory;
goto error;
goto error;
}
hostApisCount_ = 0;
@ -233,7 +233,7 @@ error:
<device> belongs and returns it. if <hostSpecificDeviceIndex> is
non-null, the host specific device index is returned in it.
returns -1 if <device> is out of range.
*/
static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex )
{
@ -323,7 +323,7 @@ PaError Pa_Initialize( void )
{
PA_VALIDATE_TYPE_SIZES;
PA_VALIDATE_ENDIANNESS;
PaUtil_InitializeClock();
PaUtil_ResetTraceMessages();
@ -410,11 +410,11 @@ const char *Pa_GetErrorText( PaError errorCode )
case paCanNotWriteToAnInputOnlyStream: result = "Can't write to an input only stream"; break;
case paIncompatibleStreamHostApi: result = "Incompatible stream host API"; break;
case paBadBufferPtr: result = "Bad buffer pointer"; break;
default:
default:
if( errorCode > 0 )
result = "Invalid error code (value greater than zero)";
result = "Invalid error code (value greater than zero)";
else
result = "Invalid error code";
result = "Invalid error code";
break;
}
return result;
@ -425,7 +425,7 @@ PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type )
{
PaHostApiIndex result;
int i;
PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiTypeIdToHostApiIndex" );
PA_LOGAPI(("\tPaHostApiTypeId type: %d\n", type ));
@ -436,14 +436,14 @@ PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type )
else
{
result = paHostApiNotFound;
for( i=0; i < hostApisCount_; ++i )
{
if( hostApis_[i]->info.type == type )
{
result = i;
break;
}
}
}
}
@ -458,7 +458,7 @@ PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **ho
{
PaError result;
int i;
if( !PA_IS_INITIALISED_ )
{
result = paNotInitialized;
@ -466,7 +466,7 @@ PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **ho
else
{
result = paHostApiNotFound;
for( i=0; i < hostApisCount_; ++i )
{
if( hostApis_[i]->info.type == type )
@ -487,7 +487,7 @@ PaError PaUtil_DeviceIndexToHostApiDeviceIndex(
{
PaError result;
PaDeviceIndex x;
x = device - hostApi->privatePaFrontInfo.baseDeviceIndex;
if( x < 0 || x >= hostApi->info.deviceCount )
@ -572,7 +572,7 @@ const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi )
else if( hostApi < 0 || hostApi >= hostApisCount_ )
{
info = NULL;
PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" ));
PA_LOGAPI(("\tPaHostApiInfo*: NULL [ hostApi out of range ]\n" ));
@ -681,7 +681,7 @@ PaDeviceIndex Pa_GetDefaultOutputDevice( void )
{
PaHostApiIndex hostApi;
PaDeviceIndex result;
PA_LOGAPI_ENTER( "Pa_GetDefaultOutputDevice" );
hostApi = Pa_GetDefaultHostApi();
@ -765,7 +765,7 @@ static int SampleFormatIsValid( PaSampleFormat format )
ValidateOpenStreamParameters() checks that parameters to Pa_OpenStream()
conform to the expected values as described below. This function is
also designed to be used with the proposed Pa_IsFormatSupported() function.
There are basically two types of validation that could be performed:
Generic conformance validation, and device capability mismatch
validation. This function performs only generic conformance validation.
@ -774,21 +774,21 @@ static int SampleFormatIsValid( PaSampleFormat format )
combinations of parameters - for example, even if the sampleRate
seems ok, it might not be for a duplex stream - we have no way of
checking this in an API-neutral way, so we don't try.
On success the function returns PaNoError and fills in hostApi,
hostApiInputDeviceID, and hostApiOutputDeviceID fields. On failure
the function returns an error code indicating the first encountered
parameter error.
If ValidateOpenStreamParameters() returns paNoError, the following
assertions are guaranteed to be true.
- at least one of inputParameters & outputParmeters is valid (not NULL)
- if inputParameters & outputParameters are both valid, that
inputParameters->device & outputParameters->device both use the same host api
PaDeviceIndex inputParameters->device
- is within range (0 to Pa_GetDeviceCount-1) Or:
- is paUseHostApiSpecificDeviceSpecification and
@ -798,30 +798,30 @@ static int SampleFormatIsValid( PaSampleFormat format )
int inputParameters->channelCount
- if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, channelCount is > 0
- upper bound is NOT validated against device capabilities
PaSampleFormat inputParameters->sampleFormat
- is one of the sample formats defined in portaudio.h
void *inputParameters->hostApiSpecificStreamInfo
- if supplied its hostApi field matches the input device's host Api
PaDeviceIndex outputParmeters->device
- is within range (0 to Pa_GetDeviceCount-1)
int outputParmeters->channelCount
- if inputDevice is valid, channelCount is > 0
- upper bound is NOT validated against device capabilities
PaSampleFormat outputParmeters->sampleFormat
- is one of the sample formats defined in portaudio.h
void *outputParmeters->hostApiSpecificStreamInfo
- if supplied its hostApi field matches the output device's host Api
double sampleRate
- is not an 'absurd' rate (less than 1000. or greater than 200000.)
- sampleRate is NOT validated against device capabilities
PaStreamFlags streamFlags
- unused platform neutral flags are zero
- paNeverDropInput is only used for full-duplex callback streams with
@ -948,7 +948,7 @@ static PaError ValidateOpenStreamParameters(
!= (*hostApi)->info.type )
return paIncompatibleHostApiSpecificStreamInfo;
}
}
}
if( (inputParameters != NULL) && (outputParameters != NULL) )
{
@ -957,8 +957,8 @@ static PaError ValidateOpenStreamParameters(
return paBadIODeviceCombination;
}
}
/* Check for absurd sample rates. */
if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
return paInvalidSampleRate;
@ -980,7 +980,7 @@ static PaError ValidateOpenStreamParameters(
if( framesPerBuffer != paFramesPerBufferUnspecified )
return paInvalidFlag;
}
return paNoError;
}
@ -1020,7 +1020,7 @@ PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency ));
PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo ));
}
PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate ));
#endif
@ -1043,7 +1043,7 @@ PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result );
return result;
}
if( inputParameters )
{
@ -1130,7 +1130,7 @@ PaError Pa_OpenStream( PaStream** stream,
PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency ));
PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo ));
}
PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate ));
PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer ));
PA_LOGAPI(("\tPaStreamFlags streamFlags: 0x%x\n", streamFlags ));
@ -1177,7 +1177,7 @@ PaError Pa_OpenStream( PaStream** stream,
PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
return result;
}
if( inputParameters )
{
@ -1251,8 +1251,8 @@ PaError Pa_OpenDefaultStream( PaStream** stream,
{
hostApiInputParameters.device = Pa_GetDefaultInputDevice();
if( hostApiInputParameters.device == paNoDevice )
return paDeviceUnavailable;
return paDeviceUnavailable;
hostApiInputParameters.channelCount = inputChannelCount;
hostApiInputParameters.sampleFormat = sampleFormat;
/* defaultHighInputLatency is used below instead of
@ -1260,7 +1260,7 @@ PaError Pa_OpenDefaultStream( PaStream** stream,
stream to work reliably than it is for it to work with the lowest
latency.
*/
hostApiInputParameters.suggestedLatency =
hostApiInputParameters.suggestedLatency =
Pa_GetDeviceInfo( hostApiInputParameters.device )->defaultHighInputLatency;
hostApiInputParameters.hostApiSpecificStreamInfo = NULL;
hostApiInputParametersPtr = &hostApiInputParameters;
@ -1274,7 +1274,7 @@ PaError Pa_OpenDefaultStream( PaStream** stream,
{
hostApiOutputParameters.device = Pa_GetDefaultOutputDevice();
if( hostApiOutputParameters.device == paNoDevice )
return paDeviceUnavailable;
return paDeviceUnavailable;
hostApiOutputParameters.channelCount = outputChannelCount;
hostApiOutputParameters.sampleFormat = sampleFormat;
@ -1658,7 +1658,7 @@ PaError Pa_WriteStream( PaStream* stream,
else if( result == 1 )
{
result = paStreamIsStopped;
}
}
}
}

View File

@ -29,20 +29,20 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup common_src
@brief Interfaces and representation structures used by pa_front.c
@brief Interfaces and representation structures used by pa_front.c
to manage and communicate with host API implementations.
*/
@ -112,13 +112,13 @@ typedef struct PaUtilHostApiRepresentation {
The inputParameters and outputParameters pointers should not be saved
as they will not remain valid after OpenStream is called.
The following guarantees are made about parameters to (*OpenStream)():
[NOTE: the following list up to *END PA FRONT VALIDATIONS* should be
kept in sync with the one for ValidateOpenStreamParameters and
Pa_OpenStream in pa_front.c]
PaHostApiRepresentation *hostApi
- is valid for this implementation
@ -129,7 +129,7 @@ typedef struct PaUtilHostApiRepresentation {
- if inputParameters & outputParmeters are both valid, that
inputParameters->device & outputParmeters->device both use the same host api
PaDeviceIndex inputParameters->device
- is within range (0 to Pa_CountDevices-1) Or:
- is paUseHostApiSpecificDeviceSpecification and
@ -139,30 +139,30 @@ typedef struct PaUtilHostApiRepresentation {
int inputParameters->numChannels
- if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, numInputChannels is > 0
- upper bound is NOT validated against device capabilities
PaSampleFormat inputParameters->sampleFormat
- is one of the sample formats defined in portaudio.h
void *inputParameters->hostApiSpecificStreamInfo
- if supplied its hostApi field matches the input device's host Api
PaDeviceIndex outputParmeters->device
- is within range (0 to Pa_CountDevices-1)
int outputParmeters->numChannels
- if inputDevice is valid, numInputChannels is > 0
- upper bound is NOT validated against device capabilities
PaSampleFormat outputParmeters->sampleFormat
- is one of the sample formats defined in portaudio.h
void *outputParmeters->hostApiSpecificStreamInfo
- if supplied its hostApi field matches the output device's host Api
double sampleRate
- is not an 'absurd' rate (less than 1000. or greater than 200000.)
- sampleRate is NOT validated against device capabilities
PaStreamFlags streamFlags
- unused platform neutral flags are zero
- paNeverDropInput is only used for full-duplex callback streams
@ -174,7 +174,7 @@ typedef struct PaUtilHostApiRepresentation {
The following validations MUST be performed by (*OpenStream)():
- check that input device can support numInputChannels
- check that input device can support inputSampleFormat, or that
we have the capability to convert from outputSampleFormat to
a native format
@ -183,7 +183,7 @@ typedef struct PaUtilHostApiRepresentation {
or return an error if no inputStreamInfo is expected
- check that output device can support numOutputChannels
- check that output device can support outputSampleFormat, or that
we have the capability to convert from outputSampleFormat to
a native format
@ -223,11 +223,11 @@ typedef struct PaUtilHostApiRepresentation {
/** Prototype for the initialization function which must be implemented by every
host API.
This function should only return an error other than paNoError if it encounters
an unexpected and fatal error (memory allocation error for example). In general,
there may be conditions under which it returns a NULL interface pointer and also
returns paNoError. For example, if the ASIO implementation detects that ASIO is
This function should only return an error other than paNoError if it encounters
an unexpected and fatal error (memory allocation error for example). In general,
there may be conditions under which it returns a NULL interface pointer and also
returns paNoError. For example, if the ASIO implementation detects that ASIO is
not installed, it should return a NULL interface, and paNoError.
@see paHostApiInitializers
@ -246,7 +246,7 @@ extern PaUtilHostApiInitializer *paHostApiInitializers[];
/** The index of the default host API in the paHostApiInitializers array.
There is a platform specific file which defines paDefaultHostApiIndex for that
platform, see pa_win/pa_win_hostapis.c for example.
*/

View File

@ -30,13 +30,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -1,5 +1,5 @@
/*
* $Id: pa_process.c 1408 2009-03-13 16:41:39Z rossb $
* $Id: pa_process.c 1523 2010-07-10 17:41:25Z dmitrykos $
* Portable Audio I/O Library
* streamCallback <-> host buffer processing adapter
*
@ -27,13 +27,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -41,7 +41,7 @@
@ingroup common_src
@brief Buffer Processor implementation.
The code in this file is not optimised yet - although it's not clear that
it needs to be. there may appear to be redundancies
that could be factored into common functions, but the redundanceis are left
@ -232,7 +232,7 @@ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,
bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer;
bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer;
if( inputChannelCount > 0 )
{
bytesPerSample = Pa_GetSampleSize( hostInputSampleFormat );
@ -261,20 +261,23 @@ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,
PaUtil_SelectConverter( hostInputSampleFormat, userInputSampleFormat, streamFlags );
bp->inputZeroer = PaUtil_SelectZeroer( hostInputSampleFormat );
bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1;
bp->hostInputIsInterleaved = (hostInputSampleFormat & paNonInterleaved)?0:1;
bp->userInputSampleFormatIsEqualToHost = ((userInputSampleFormat & ~paNonInterleaved) == (hostInputSampleFormat & ~paNonInterleaved));
tempInputBufferSize =
bp->framesPerTempBuffer * bp->bytesPerUserInputSample * inputChannelCount;
bp->tempInputBuffer = PaUtil_AllocateMemory( tempInputBufferSize );
if( bp->tempInputBuffer == 0 )
{
result = paInsufficientMemory;
goto error;
}
if( bp->framesInTempInputBuffer > 0 )
memset( bp->tempInputBuffer, 0, tempInputBufferSize );
@ -331,6 +334,10 @@ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,
bp->userOutputIsInterleaved = (userOutputSampleFormat & paNonInterleaved)?0:1;
bp->hostOutputIsInterleaved = (hostOutputSampleFormat & paNonInterleaved)?0:1;
bp->userOutputSampleFormatIsEqualToHost = ((userOutputSampleFormat & ~paNonInterleaved) == (hostOutputSampleFormat & ~paNonInterleaved));
tempOutputBufferSize =
bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * outputChannelCount;
@ -343,7 +350,7 @@ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,
if( bp->framesInTempOutputBuffer > 0 )
memset( bp->tempOutputBuffer, 0, tempOutputBufferSize );
if( userOutputSampleFormat & paNonInterleaved )
{
bp->tempOutputBufferPtrs =
@ -358,7 +365,7 @@ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,
bp->hostOutputChannels[0] = (PaUtilChannelDescriptor*)
PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor)*outputChannelCount * 2 );
if( bp->hostOutputChannels[0] == 0 )
{
{
result = paInsufficientMemory;
goto error;
}
@ -408,7 +415,7 @@ void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bp )
if( bp->hostInputChannels[0] )
PaUtil_FreeMemory( bp->hostInputChannels[0] );
if( bp->tempOutputBuffer )
PaUtil_FreeMemory( bp->tempOutputBuffer );
@ -435,7 +442,7 @@ void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bp )
}
if( bp->framesInTempOutputBuffer > 0 )
{
{
tempOutputBufferSize =
bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * bp->outputChannelCount;
memset( bp->tempOutputBuffer, 0, tempOutputBufferSize );
@ -463,7 +470,7 @@ void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bp,
else
bp->hostInputFrameCount[0] = frameCount;
}
void PaUtil_SetNoInput( PaUtilBufferProcessor* bp )
{
@ -477,7 +484,7 @@ void PaUtil_SetInputChannel( PaUtilBufferProcessor* bp,
unsigned int channel, void *data, unsigned int stride )
{
assert( channel < bp->inputChannelCount );
bp->hostInputChannels[0][channel].data = data;
bp->hostInputChannels[0][channel].stride = stride;
}
@ -495,6 +502,7 @@ void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bp,
assert( firstChannel < bp->inputChannelCount );
assert( firstChannel + channelCount <= bp->inputChannelCount );
assert( bp->hostInputIsInterleaved );
for( i=0; i< channelCount; ++i )
{
@ -509,7 +517,8 @@ void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bp,
unsigned int channel, void *data )
{
assert( channel < bp->inputChannelCount );
assert( !bp->hostInputIsInterleaved );
bp->hostInputChannels[0][channel].data = data;
bp->hostInputChannels[0][channel].stride = 1;
}
@ -544,7 +553,8 @@ void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bp,
assert( firstChannel < bp->inputChannelCount );
assert( firstChannel + channelCount <= bp->inputChannelCount );
assert( bp->hostInputIsInterleaved );
for( i=0; i< channelCount; ++i )
{
bp->hostInputChannels[1][channel+i].data = p;
@ -553,12 +563,13 @@ void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bp,
}
}
void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bp,
unsigned int channel, void *data )
{
assert( channel < bp->inputChannelCount );
assert( !bp->hostInputIsInterleaved );
bp->hostInputChannels[1][channel].data = data;
bp->hostInputChannels[1][channel].stride = 1;
}
@ -605,7 +616,8 @@ void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bp,
assert( firstChannel < bp->outputChannelCount );
assert( firstChannel + channelCount <= bp->outputChannelCount );
assert( bp->hostOutputIsInterleaved );
for( i=0; i< channelCount; ++i )
{
PaUtil_SetOutputChannel( bp, channel + i, p, channelCount );
@ -618,6 +630,7 @@ void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bp,
unsigned int channel, void *data )
{
assert( channel < bp->outputChannelCount );
assert( !bp->hostOutputIsInterleaved );
PaUtil_SetOutputChannel( bp, channel, data, 1 );
}
@ -653,7 +666,8 @@ void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bp,
assert( firstChannel < bp->outputChannelCount );
assert( firstChannel + channelCount <= bp->outputChannelCount );
assert( bp->hostOutputIsInterleaved );
for( i=0; i< channelCount; ++i )
{
PaUtil_Set2ndOutputChannel( bp, channel + i, p, channelCount );
@ -661,12 +675,13 @@ void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bp,
}
}
void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bp,
unsigned int channel, void *data )
{
assert( channel < bp->outputChannelCount );
assert( !bp->hostOutputIsInterleaved );
PaUtil_Set2ndOutputChannel( bp, channel, data, 1 );
}
@ -678,11 +693,11 @@ void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bp,
/* the first streamCallback will be called to process samples which are
currently in the input buffer before the ones starting at the timeInfo time */
bp->timeInfo->inputBufferAdcTime -= bp->framesInTempInputBuffer * bp->samplePeriod;
/* We just pass through timeInfo->currentTime provided by the caller. This is
not strictly conformant to the word of the spec, since the buffer processor
not strictly conformant to the word of the spec, since the buffer processor
might call the callback multiple times, and we never refresh currentTime. */
/* the first streamCallback will be called to generate samples which will be
@ -722,6 +737,8 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
unsigned long frameCount;
unsigned long framesToGo = framesToProcess;
unsigned long framesProcessed = 0;
int skipOutputConvert = 0;
int skipInputConvert = 0;
if( *streamCallbackResult == paContinue )
@ -738,18 +755,25 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
}
else /* there are input channels */
{
/*
could use more elaborate logic here and sometimes process
buffers in-place.
*/
destBytePtr = (unsigned char *)bp->tempInputBuffer;
if( bp->userInputIsInterleaved )
{
destSampleStrideSamples = bp->inputChannelCount;
destChannelStrideBytes = bp->bytesPerUserInputSample;
userInput = bp->tempInputBuffer;
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */
if( bp->userInputSampleFormatIsEqualToHost && bp->hostInputIsInterleaved )
{
userInput = hostInputChannels[0].data;
destBytePtr = (unsigned char *)hostInputChannels[0].data;
skipInputConvert = 1;
}
else
{
userInput = bp->tempInputBuffer;
}
}
else /* user input is not interleaved */
{
@ -757,12 +781,23 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
destChannelStrideBytes = frameCount * bp->bytesPerUserInputSample;
/* setup non-interleaved ptrs */
for( i=0; i<bp->inputChannelCount; ++i )
if( bp->userInputSampleFormatIsEqualToHost && !bp->hostInputIsInterleaved )
{
bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
i * bp->bytesPerUserInputSample * frameCount;
for( i=0; i<bp->inputChannelCount; ++i )
{
bp->tempInputBufferPtrs[i] = hostInputChannels[i].data;
}
skipInputConvert = 1;
}
else
{
for( i=0; i<bp->inputChannelCount; ++i )
{
bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
i * bp->bytesPerUserInputSample * frameCount;
}
}
userInput = bp->tempInputBufferPtrs;
}
@ -778,19 +813,31 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
}
}
else
{
for( i=0; i<bp->inputChannelCount; ++i )
{
if( skipInputConvert )
{
bp->inputConverter( destBytePtr, destSampleStrideSamples,
hostInputChannels[i].data,
hostInputChannels[i].stride,
frameCount, &bp->ditherGenerator );
for( i=0; i<bp->inputChannelCount; ++i )
{
/* advance src ptr for next iteration */
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
}
}
else
{
for( i=0; i<bp->inputChannelCount; ++i )
{
bp->inputConverter( destBytePtr, destSampleStrideSamples,
hostInputChannels[i].data,
hostInputChannels[i].stride,
frameCount, &bp->ditherGenerator );
destBytePtr += destChannelStrideBytes; /* skip to next destination channel */
destBytePtr += destChannelStrideBytes; /* skip to next destination channel */
/* advance src ptr for next iteration */
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
/* advance src ptr for next iteration */
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
}
}
}
}
@ -805,20 +852,40 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
{
if( bp->userOutputIsInterleaved )
{
userOutput = bp->tempOutputBuffer;
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */
if( bp->userOutputSampleFormatIsEqualToHost && bp->hostOutputIsInterleaved )
{
userOutput = hostOutputChannels[0].data;
skipOutputConvert = 1;
}
else
{
userOutput = bp->tempOutputBuffer;
}
}
else /* user output is not interleaved */
{
for( i = 0; i < bp->outputChannelCount; ++i )
if( bp->userOutputSampleFormatIsEqualToHost && !bp->hostOutputIsInterleaved )
{
bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
i * bp->bytesPerUserOutputSample * frameCount;
for( i=0; i<bp->outputChannelCount; ++i )
{
bp->tempOutputBufferPtrs[i] = hostOutputChannels[i].data;
}
skipOutputConvert = 1;
}
else
{
for( i=0; i<bp->outputChannelCount; ++i )
{
bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
i * bp->bytesPerUserOutputSample * frameCount;
}
}
userOutput = bp->tempOutputBufferPtrs;
}
}
*streamCallbackResult = bp->streamCallback( userInput, userOutput,
frameCount, bp->timeInfo, bp->callbackStatusFlags, bp->userData );
@ -833,42 +900,50 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
bp->timeInfo->outputBufferDacTime += frameCount * bp->samplePeriod;
/* convert output data (user -> host) */
if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data )
{
/*
could use more elaborate logic here and sometimes process
buffers in-place.
*/
if( skipOutputConvert )
{
for( i=0; i<bp->outputChannelCount; ++i )
{
/* advance dest ptr for next iteration */
hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
}
}
else
{
srcBytePtr = (unsigned char *)bp->tempOutputBuffer;
srcBytePtr = (unsigned char *)bp->tempOutputBuffer;
if( bp->userOutputIsInterleaved )
{
srcSampleStrideSamples = bp->outputChannelCount;
srcChannelStrideBytes = bp->bytesPerUserOutputSample;
}
else /* user output is not interleaved */
{
srcSampleStrideSamples = 1;
srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample;
}
if( bp->userOutputIsInterleaved )
{
srcSampleStrideSamples = bp->outputChannelCount;
srcChannelStrideBytes = bp->bytesPerUserOutputSample;
}
else /* user output is not interleaved */
{
srcSampleStrideSamples = 1;
srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample;
}
for( i=0; i<bp->outputChannelCount; ++i )
{
bp->outputConverter( hostOutputChannels[i].data,
hostOutputChannels[i].stride,
srcBytePtr, srcSampleStrideSamples,
frameCount, &bp->ditherGenerator );
for( i=0; i<bp->outputChannelCount; ++i )
{
bp->outputConverter( hostOutputChannels[i].data,
hostOutputChannels[i].stride,
srcBytePtr, srcSampleStrideSamples,
frameCount, &bp->ditherGenerator );
srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */
srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */
/* advance dest ptr for next iteration */
hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
}
/* advance dest ptr for next iteration */
hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
}
}
}
framesProcessed += frameCount;
framesToGo -= frameCount;
@ -923,7 +998,7 @@ static unsigned long AdaptingInputOnlyProcess( PaUtilBufferProcessor *bp,
unsigned long frameCount;
unsigned long framesToGo = framesToProcess;
unsigned long framesProcessed = 0;
userOutput = 0;
do
@ -939,7 +1014,7 @@ static unsigned long AdaptingInputOnlyProcess( PaUtilBufferProcessor *bp,
destBytePtr = ((unsigned char*)bp->tempInputBuffer) +
bp->bytesPerUserInputSample * bp->inputChannelCount *
bp->framesInTempInputBuffer;
destSampleStrideSamples = bp->inputChannelCount;
destChannelStrideBytes = bp->bytesPerUserInputSample;
@ -959,7 +1034,7 @@ static unsigned long AdaptingInputOnlyProcess( PaUtilBufferProcessor *bp,
bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
i * bp->bytesPerUserInputSample * bp->framesPerUserBuffer;
}
userInput = bp->tempInputBufferPtrs;
}
@ -999,7 +1074,7 @@ static unsigned long AdaptingInputOnlyProcess( PaUtilBufferProcessor *bp,
bp->timeInfo->inputBufferAdcTime += bp->framesPerUserBuffer * bp->samplePeriod;
}
bp->framesInTempInputBuffer = 0;
}
@ -1054,7 +1129,7 @@ static unsigned long AdaptingOutputOnlyProcess( PaUtilBufferProcessor *bp,
}
bp->timeInfo->inputBufferAdcTime = 0;
*streamCallbackResult = bp->streamCallback( userInput, userOutput,
bp->framesPerUserBuffer, bp->timeInfo,
bp->callbackStatusFlags, bp->userData );
@ -1091,7 +1166,7 @@ static unsigned long AdaptingOutputOnlyProcess( PaUtilBufferProcessor *bp,
srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
bp->bytesPerUserOutputSample *
(bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
srcSampleStrideSamples = 1;
srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;
}
@ -1132,9 +1207,9 @@ static unsigned long AdaptingOutputOnlyProcess( PaUtilBufferProcessor *bp,
frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
}
}
framesProcessed += frameCount;
framesToGo -= frameCount;
}while( framesToGo > 0 );
@ -1144,7 +1219,7 @@ static unsigned long AdaptingOutputOnlyProcess( PaUtilBufferProcessor *bp,
/* CopyTempOutputBuffersToHostOutputBuffers is called from AdaptingProcess to copy frames from
tempOutputBuffer to hostOutputChannels. This includes data conversion
and interleaving.
and interleaving.
*/
static void CopyTempOutputBuffersToHostOutputBuffers( PaUtilBufferProcessor *bp)
{
@ -1179,7 +1254,7 @@ static void CopyTempOutputBuffersToHostOutputBuffers( PaUtilBufferProcessor *bp)
srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
bp->bytesPerUserOutputSample * bp->outputChannelCount *
(bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
srcSampleStrideSamples = bp->outputChannelCount;
srcChannelStrideBytes = bp->bytesPerUserOutputSample;
}
@ -1241,7 +1316,7 @@ static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp,
unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */
unsigned int i, j;
framesAvailable = bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1];/* this is assumed to be the same as the output buffer's frame count */
@ -1251,9 +1326,9 @@ static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp,
endProcessingMinFrameCount = (bp->framesPerUserBuffer - 1);
/* Fill host output with remaining frames in user output (tempOutputBuffer) */
CopyTempOutputBuffersToHostOutputBuffers( bp );
CopyTempOutputBuffersToHostOutputBuffers( bp );
while( framesAvailable > endProcessingMinFrameCount )
while( framesAvailable > endProcessingMinFrameCount )
{
if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult != paContinue )
@ -1267,7 +1342,7 @@ static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp,
if( frameCount > 0 )
{
hostOutputChannels = bp->hostOutputChannels[i];
for( j=0; j<bp->outputChannelCount; ++j )
{
bp->outputZeroer( hostOutputChannels[j].data,
@ -1281,7 +1356,7 @@ static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp,
bp->hostOutputFrameCount[i] = 0;
}
}
}
}
/* copy frames from host to user input buffers */
@ -1339,7 +1414,7 @@ static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp,
bp->hostInputFrameCount[0] -= frameCount;
else
bp->hostInputFrameCount[1] -= frameCount;
bp->framesInTempInputBuffer += frameCount;
/* update framesAvailable and framesProcessed based on input consumed
@ -1411,13 +1486,13 @@ static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp,
}
}
/* copy frames from user (tempOutputBuffer) to host output buffers (hostOutputChannels)
/* copy frames from user (tempOutputBuffer) to host output buffers (hostOutputChannels)
Means to process the user output provided by the callback. Has to be called after
each callback. */
CopyTempOutputBuffersToHostOutputBuffers( bp );
CopyTempOutputBuffersToHostOutputBuffers( bp );
}
return framesProcessed;
}
@ -1426,7 +1501,7 @@ unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bp, int *stream
{
unsigned long framesToProcess, framesToGo;
unsigned long framesProcessed = 0;
if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0
&& bp->hostInputChannels[0][0].data /* input was supplied (see PaUtil_SetNoInput) */
&& bp->hostOutputChannels[0][0].data /* output was supplied (see PaUtil_SetNoOutput) */ )
@ -1501,17 +1576,17 @@ unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bp, int *stream
*hostOutputFrameCount );
assert( framesToProcess != 0 );
framesProcessedThisIteration = NonAdaptingProcess( bp, streamCallbackResult,
hostInputChannels, hostOutputChannels,
framesToProcess );
framesToProcess );
*hostInputFrameCount -= framesProcessedThisIteration;
*hostOutputFrameCount -= framesProcessedThisIteration;
framesProcessed += framesProcessedThisIteration;
framesToGo -= framesProcessedThisIteration;
}while( framesToGo > 0 );
}
else
@ -1528,7 +1603,7 @@ unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bp, int *stream
framesToProcess );
/* process second buffer if provided */
framesToProcess = (bp->inputChannelCount != 0)
? bp->hostInputFrameCount[1]
: bp->hostOutputFrameCount[1];
@ -1546,7 +1621,7 @@ unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bp, int *stream
if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 )
{
/* full duplex */
if( bp->hostBufferSizeMode == paUtilVariableHostBufferSizePartialUsageAllowed )
{
framesProcessed = AdaptingProcess( bp, streamCallbackResult,
@ -1597,7 +1672,7 @@ unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bp, int *stream
int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bp )
{
return (bp->framesInTempOutputBuffer) ? 0 : 1;
}
}
unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
@ -1617,7 +1692,7 @@ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
if( bp->userInputIsInterleaved )
{
destBytePtr = (unsigned char*)*buffer;
destSampleStrideSamples = bp->inputChannelCount;
destChannelStrideBytes = bp->bytesPerUserInputSample;
@ -1642,11 +1717,11 @@ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
else
{
/* user input is not interleaved */
nonInterleavedDestPtrs = (void**)*buffer;
destSampleStrideSamples = 1;
for( i=0; i<bp->inputChannelCount; ++i )
{
destBytePtr = (unsigned char*)nonInterleavedDestPtrs[i];
@ -1659,7 +1734,7 @@ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
/* advance callers dest pointer (nonInterleavedDestPtrs[i]) */
destBytePtr += bp->bytesPerUserInputSample * framesToCopy;
nonInterleavedDestPtrs[i] = destBytePtr;
/* advance dest ptr for next iteration */
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
@ -1667,7 +1742,7 @@ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
}
bp->hostInputFrameCount[0] -= framesToCopy;
return framesToCopy;
}
@ -1688,7 +1763,7 @@ unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bp,
if( bp->userOutputIsInterleaved )
{
srcBytePtr = (unsigned char*)*buffer;
srcSampleStrideSamples = bp->outputChannelCount;
srcChannelStrideBytes = bp->bytesPerUserOutputSample;
@ -1714,15 +1789,15 @@ unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bp,
else
{
/* user output is not interleaved */
nonInterleavedSrcPtrs = (void**)*buffer;
srcSampleStrideSamples = 1;
for( i=0; i<bp->outputChannelCount; ++i )
{
srcBytePtr = (unsigned char*)nonInterleavedSrcPtrs[i];
bp->outputConverter( hostOutputChannels[i].data,
hostOutputChannels[i].stride,
srcBytePtr, srcSampleStrideSamples,
@ -1732,7 +1807,7 @@ unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bp,
/* advance callers source pointer (nonInterleavedSrcPtrs[i]) */
srcBytePtr += bp->bytesPerUserOutputSample * framesToCopy;
nonInterleavedSrcPtrs[i] = srcBytePtr;
/* advance dest ptr for next iteration */
hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
@ -1740,7 +1815,7 @@ unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bp,
}
bp->hostOutputFrameCount[0] += framesToCopy;
return framesToCopy;
}
@ -1767,6 +1842,6 @@ unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bp, unsigned long frameC
}
bp->hostOutputFrameCount[0] += framesToZero;
return framesToZero;
}

View File

@ -1,7 +1,7 @@
#ifndef PA_PROCESS_H
#define PA_PROCESS_H
/*
* $Id: pa_process.h 1097 2006-08-26 08:27:53Z rossb $
* $Id: pa_process.h 1523 2010-07-10 17:41:25Z dmitrykos $
* Portable Audio I/O Library callback buffer processing adapters
*
* Based on the Open Source API proposed by Ross Bencina
@ -28,16 +28,16 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup common_src
@ -72,7 +72,7 @@
The following sections provide an overview of how to use the buffer processor.
Interested readers are advised to consult the host API implementations for
examples of buffer processor usage.
<h4>Initialization, resetting and termination</h4>
@ -92,7 +92,7 @@
When the buffer processor is no longer used call
PaUtil_TerminateBufferProcessor.
<h4>Using the buffer processor for a callback stream</h4>
The buffer processor's role in a callback stream is to take host input buffers
@ -176,7 +176,7 @@
host buffer(s), so the above steps need to be repeated until the user
buffer(s) are full.
To copy data to the host output buffer from the user buffers(s) supplied
to Pa_WriteStream use the following calling sequence.
@ -192,7 +192,7 @@
-# Call PaUtil_CopyOutput with the user buffer pointer (or a copy of the
array of buffer pointers for a non-interleaved stream) passed to
Pa_WriteStream, along with the number of frames in the user buffer(s).
Be careful to pass a <i>copy</i> of the user buffer pointers to
Be careful to pass a <i>copy</i> of the user buffer pointers to
PaUtil_CopyOutput because PaUtil_CopyOutput advances the pointers to
the start of the next region to copy.
- PaUtil_CopyOutput will not copy more data than fits in the host buffer(s),
@ -256,6 +256,8 @@ typedef struct {
PaUtilHostBufferSizeMode hostBufferSizeMode;
int useNonAdaptingProcess;
int userOutputSampleFormatIsEqualToHost;
int userInputSampleFormatIsEqualToHost;
unsigned long framesPerTempBuffer;
unsigned int inputChannelCount;
@ -264,7 +266,7 @@ typedef struct {
int userInputIsInterleaved;
PaUtilConverter *inputConverter;
PaUtilZeroer *inputZeroer;
unsigned int outputChannelCount;
unsigned int bytesPerHostOutputSample;
unsigned int bytesPerUserOutputSample;
@ -287,12 +289,14 @@ typedef struct {
PaStreamCallbackFlags callbackStatusFlags;
int hostInputIsInterleaved;
unsigned long hostInputFrameCount[2];
PaUtilChannelDescriptor *hostInputChannels[2]; /**< pointers to arrays of channel descriptors.
pointers are NULL for half-duplex output processing.
hostInputChannels[i].data is NULL when the caller
calls PaUtil_SetNoInput()
*/
int hostOutputIsInterleaved;
unsigned long hostOutputFrameCount[2];
PaUtilChannelDescriptor *hostOutputChannels[2]; /**< pointers to arrays of channel descriptors.
pointers are NULL for half-duplex input processing.
@ -323,7 +327,7 @@ typedef struct {
@param userInputSampleFormat Format of user input samples, as passed to
Pa_OpenStream. This parameter is ignored for ouput-only streams.
@param hostInputSampleFormat Format of host input samples. This parameter is
ignored for output-only streams. See note about host buffer interleave below.
@ -332,17 +336,17 @@ typedef struct {
@param userOutputSampleFormat Format of user output samples, as passed to
Pa_OpenStream. This parameter is ignored for input-only streams.
@param hostOutputSampleFormat Format of host output samples. This parameter is
ignored for input-only streams. See note about host buffer interleave below.
@param sampleRate Sample rate of the stream. The more accurate this is the
better - it is used for updating time stamps when adapting buffers.
@param streamFlags Stream flags as passed to Pa_OpenStream, this parameter is
used for selecting special sample conversion options such as clipping and
dithering.
@param framesPerUserBuffer Number of frames per user buffer, as requested
by the framesPerBuffer parameter to Pa_OpenStream. This parameter may be
zero to indicate that the user will accept any (and varying) buffer sizes.
@ -355,11 +359,11 @@ typedef struct {
@param hostBufferSizeMode A mode flag indicating the size variability of
host buffers that will be passed to the buffer processor. See
PaUtilHostBufferSizeMode for further details.
@param streamCallback The user stream callback passed to Pa_OpenStream.
@param userData The user data field passed to Pa_OpenStream.
@note The interleave flag is ignored for host buffer formats. Host
interleave is determined by the use of different SetInput and SetOutput
functions.
@ -367,7 +371,7 @@ typedef struct {
@return An error code indicating whether the initialization was successful.
If the error code is not PaNoError, the buffer processor was not initialized
and should not be used.
@see Pa_OpenStream, PaUtilHostBufferSizeMode, PaUtil_TerminateBufferProcessor
*/
PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bufferProcessor,
@ -385,7 +389,7 @@ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bufferProcessor
/** Terminate a buffer processor's representation. Deallocates any temporary
buffers allocated by PaUtil_InitializeBufferProcessor.
@param bufferProcessor The buffer processor structure to terminate.
@see PaUtil_InitializeBufferProcessor.
@ -430,7 +434,7 @@ unsigned long PaUtil_GetBufferProcessorOutputLatency( PaUtilBufferProcessor* buf
Functions to set host input and output buffers, used by both callback streams
and blocking read/write streams.
*/
/*@{*/
/*@{*/
/** Set the number of frames in the input host buffer(s) specified by the
@ -447,7 +451,7 @@ unsigned long PaUtil_GetBufferProcessorOutputLatency( PaUtilBufferProcessor* buf
void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bufferProcessor,
unsigned long frameCount );
/** Indicate that no input is avalable. This function should be used when
priming the output of a full-duplex stream opened with the
paPrimeOutputBuffersUsingStreamCallback flag. Note that it is not necessary
@ -520,7 +524,7 @@ void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bufferProcess
void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor,
unsigned int channel, void *data );
/** Set the number of frames in the output host buffer(s) specified by the
PaUtil_Set*OutputChannel functions.
@ -570,7 +574,7 @@ void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bufferProcessor,
void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor,
unsigned int firstChannel, void *data, unsigned int channelCount );
/** Provide the buffer processor with a pointer to one non-interleaved host
output channel.
@ -628,12 +632,12 @@ void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProc
void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bufferProcessor,
PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags );
/** Finish processing a host buffer (or a pair of host buffers in the
full-duplex case) for a callback stream.
@param bufferProcessor The buffer processor.
@param callbackResult On input, indicates a previous callback result, and on
exit, the result of the user stream callback, if it is called.
On entry callbackResult should contain one of { paContinue, paComplete, or
@ -662,7 +666,7 @@ unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bufferProcessor
a callbackResult of paComplete.
@param bufferProcessor The buffer processor.
@return Returns non-zero when callback generated output remains in the internal
buffer and zero (0) when there internal buffer contains no callback generated
data.
@ -734,7 +738,7 @@ unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bufferProcessor,
@param bufferProcessor The buffer processor.
@param frameCount The maximum number of frames to zero.
@return The number of frames zeroed.
*/
unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bufferProcessor,

View File

@ -7,7 +7,7 @@
* modified for SMP safety on Mac OS X by Bjorn Roche
* modified for SMP safety on Linux by Leland Lucius
* also, allowed for const where possible
* modified for multiple-byte-sized data elements by Sven Fischer
* modified for multiple-byte-sized data elements by Sven Fischer
*
* Note that this is safe only for a single-thread reader and a
* single-thread writer.
@ -37,13 +37,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -8,7 +8,7 @@
* Author: Phil Burk, http://www.softsynth.com
* modified for SMP safety on OS X by Bjorn Roche.
* also allowed for const where possible.
* modified for multiple-byte-sized data elements by Sven Fischer
* modified for multiple-byte-sized data elements by Sven Fischer
*
* Note that this is safe only for a single-thread reader
* and a single-thread writer.
@ -38,13 +38,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -58,11 +58,11 @@
a single reader and a single writer (ie. one thread or callback writes
to the ring buffer, another thread or callback reads from it).
The PaUtilRingBuffer structure manages a ring buffer containing N
elements, where N must be a power of two. An element may be any size
The PaUtilRingBuffer structure manages a ring buffer containing N
elements, where N must be a power of two. An element may be any size
(specified in bytes).
The memory area used to store the buffer elements must be allocated by
The memory area used to store the buffer elements must be allocated by
the client prior to calling PaUtil_InitializeRingBuffer() and must outlive
the use of the ring buffer.
*/

View File

@ -28,13 +28,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -152,10 +152,10 @@ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiI
(*hostApi)->info.defaultInputDevice = paNoDevice; /* IMPLEMENT ME */
(*hostApi)->info.defaultOutputDevice = paNoDevice; /* IMPLEMENT ME */
(*hostApi)->info.deviceCount = 0;
(*hostApi)->info.deviceCount = 0;
deviceCount = 0; /* IMPLEMENT ME */
if( deviceCount > 0 )
{
(*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
@ -193,14 +193,14 @@ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiI
deviceInfo->maxInputChannels = 0; /* IMPLEMENT ME */
deviceInfo->maxOutputChannels = 0; /* IMPLEMENT ME */
deviceInfo->defaultLowInputLatency = 0.; /* IMPLEMENT ME */
deviceInfo->defaultLowOutputLatency = 0.; /* IMPLEMENT ME */
deviceInfo->defaultHighInputLatency = 0.; /* IMPLEMENT ME */
deviceInfo->defaultHighOutputLatency = 0.; /* IMPLEMENT ME */
deviceInfo->defaultHighOutputLatency = 0.; /* IMPLEMENT ME */
deviceInfo->defaultSampleRate = 0.; /* IMPLEMENT ME */
(*hostApi)->deviceInfos[i] = deviceInfo;
++(*hostApi)->info.deviceCount;
}
@ -231,7 +231,7 @@ error:
PaUtil_FreeAllAllocations( skeletonHostApi->allocations );
PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations );
}
PaUtil_FreeMemory( skeletonHostApi );
}
return result;
@ -264,7 +264,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
{
int inputChannelCount, outputChannelCount;
PaSampleFormat inputSampleFormat, outputSampleFormat;
if( inputParameters )
{
inputChannelCount = inputParameters->channelCount;
@ -274,7 +274,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
this implementation doesn't support any custom sample formats */
if( inputSampleFormat & paCustomFormat )
return paSampleFormatNotSupported;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
@ -303,7 +303,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
this implementation doesn't support any custom sample formats */
if( outputSampleFormat & paCustomFormat )
return paSampleFormatNotSupported;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
@ -322,7 +322,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
{
outputChannelCount = 0;
}
/*
IMPLEMENT ME:
@ -420,7 +420,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
{
outputChannelCount = outputParameters->channelCount;
outputSampleFormat = outputParameters->sampleFormat;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
@ -499,10 +499,10 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
/* we assume a fixed host buffer size in this example, but the buffer processor
can also support bounded and unknown host buffer sizes by passing
can also support bounded and unknown host buffer sizes by passing
paUtilBoundedHostBufferSize or paUtilUnknownHostBufferSize instead of
paUtilFixedHostBufferSize below. */
result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
inputChannelCount, inputSampleFormat, hostInputSampleFormat,
outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
@ -523,7 +523,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor);
stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
/*
IMPLEMENT ME:
- additional stream setup + opening
@ -545,7 +545,7 @@ error:
/*
ExampleHostProcessingLoop() illustrates the kind of processing which may
occur in a host implementation.
*/
static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, void *userData )
{
@ -553,9 +553,9 @@ static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, vo
PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* IMPLEMENT ME */
int callbackResult;
unsigned long framesProcessed;
PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
/*
IMPLEMENT ME:
- generate timing information
@ -576,7 +576,7 @@ static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, vo
or a mixture, you will want to call PaUtil_SetInterleaved*Channels(),
PaUtil_SetNonInterleaved*Channel() or PaUtil_Set*Channel() here.
*/
PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor,
0, /* first channel of inputBuffer is channel 0 */
@ -598,7 +598,7 @@ static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, vo
callbackResult = paContinue;
framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );
/*
If you need to byte swap or shift outputBuffer to convert it to
host format, do it here.
@ -694,7 +694,7 @@ static PaError AbortStream( PaStream *s )
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior */
return result;
@ -707,7 +707,7 @@ static PaError IsStreamStopped( PaStream *s )
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior */
return 0;
@ -720,7 +720,7 @@ static PaError IsStreamActive( PaStream *s )
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior */
return 0;
@ -733,7 +733,7 @@ static PaTime GetStreamTime( PaStream *s )
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior*/
return 0;
@ -764,7 +764,7 @@ static PaError ReadStream( PaStream* s,
(void) buffer;
(void) frames;
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior*/
return paNoError;
@ -781,7 +781,7 @@ static PaError WriteStream( PaStream* s,
(void) buffer;
(void) frames;
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior*/
return paNoError;
@ -794,7 +794,7 @@ static signed long GetStreamReadAvailable( PaStream* s )
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior*/
return 0;
@ -807,7 +807,7 @@ static signed long GetStreamWriteAvailable( PaStream* s )
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior*/
return 0;

View File

@ -27,13 +27,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -164,7 +164,7 @@ void PaUtil_InitializeStreamRepresentation(
PaUtilStreamInterface *streamInterface,
PaStreamCallback *streamCallback,
void *userData );
/** Clean up a PaUtilStreamRepresentation structure previously initialized
by a call to PaUtil_InitializeStreamRepresentation.
@ -198,7 +198,7 @@ PaError PaUtil_ValidateStreamPointer( PaStream *stream );
PA_STREAM_REP( (stream) )->streamInterface
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -27,13 +27,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -45,8 +45,8 @@
@brief Real-time safe event trace logging facility for debugging.
Allows data to be logged to a fixed size trace buffer in a real-time
execution context (such as at interrupt time). Each log entry consists
of a message comprising a string pointer and an int. The trace buffer
execution context (such as at interrupt time). Each log entry consists
of a message comprising a string pointer and an int. The trace buffer
may be dumped to stdout later.
This facility is only active if PA_TRACE_REALTIME_EVENTS is set to 1,
@ -57,8 +57,8 @@
@fn PaUtil_AddTraceMessage
@brief Add a message to the trace buffer. A message consists of string and an int.
@param msg The string pointer must remain valid until PaUtil_DumpTraceMessages
is called. As a result, usually only string literals should be passed as
@param msg The string pointer must remain valid until PaUtil_DumpTraceMessages
is called. As a result, usually only string literals should be passed as
the msg parameter.
@fn PaUtil_DumpTraceMessages
@ -70,7 +70,7 @@
#endif
#ifndef PA_MAX_TRACE_RECORDS
#define PA_MAX_TRACE_RECORDS (2048) /**< Maximum number of records stored in trace buffer */
#define PA_MAX_TRACE_RECORDS (2048) /**< Maximum number of records stored in trace buffer */
#endif
#ifdef __cplusplus
@ -84,7 +84,7 @@ extern "C"
void PaUtil_ResetTraceMessages();
void PaUtil_AddTraceMessage( const char *msg, int data );
void PaUtil_DumpTraceMessages();
#else
#define PaUtil_ResetTraceMessages() /* noop */

View File

@ -1,7 +1,7 @@
#ifndef PA_TYPES_H
#define PA_TYPES_H
/*
/*
* Portable Audio I/O Library
* integer type definitions
*
@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -115,7 +115,7 @@ void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode,
const char *errorText );
/* the following functions are implemented in a platform platform specific
.c file
*/

View File

@ -1,5 +1,5 @@
/*
* $Id: pa_linux_alsa.c 1415 2009-06-03 18:57:56Z aknudsen $
* $Id: pa_linux_alsa.c 1540 2010-09-20 16:23:30Z dmitrykos $
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
* ALSA implementation by Joshua Haberman and Arve Knudsen
@ -149,7 +149,7 @@ typedef struct PaAlsaStream
int primeBuffers;
int callbackMode; /* bool: are we running in callback mode? */
int pcmsSynced; /* Have we successfully synced pcms */
int pcmsSynced; /* Have we successfully synced pcms */
int rtSched;
/* the callback thread uses these to poll the sound device(s), waiting
@ -486,10 +486,10 @@ static const HwDevInfo *FindDeviceName( const char *name )
for( i = 0; predefinedNames[i].alsaName; i++ )
{
if( strcmp( name, predefinedNames[i].alsaName ) == 0 )
{
return &predefinedNames[i];
}
if( strcmp( name, predefinedNames[i].alsaName ) == 0 )
{
return &predefinedNames[i];
}
}
return NULL;
@ -765,7 +765,7 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
int err = 0;
char *alsaDeviceName, *deviceName;
const HwDevInfo *predefined = NULL;
const HwDevInfo *predefined = NULL;
snd_config_t *n = snd_config_iterator_entry( i ), * tp = NULL;;
if( (err = snd_config_search( n, "type", &tp )) < 0 )
@ -802,22 +802,22 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
paInsufficientMemory );
}
predefined = FindDeviceName( alsaDeviceName );
predefined = FindDeviceName( alsaDeviceName );
hwDevInfos[numDeviceNames - 1].alsaName = alsaDeviceName;
hwDevInfos[numDeviceNames - 1].name = deviceName;
hwDevInfos[numDeviceNames - 1].isPlug = 1;
if( predefined )
{
if( predefined )
{
hwDevInfos[numDeviceNames - 1].hasPlayback = predefined->hasPlayback;
hwDevInfos[numDeviceNames - 1].hasCapture = predefined->hasCapture;
}
else
{
hwDevInfos[numDeviceNames - 1].hasPlayback = 1;
hwDevInfos[numDeviceNames - 1].hasCapture = 1;
}
}
else
{
hwDevInfos[numDeviceNames - 1].hasPlayback = 1;
hwDevInfos[numDeviceNames - 1].hasCapture = 1;
}
}
}
else
@ -1251,47 +1251,56 @@ static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *se
if( self->userInterleaved )
{
accessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED;
accessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED;
alternateAccessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;
/* test if MMAP supported */
self->canMmap = snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ||
snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0;
PA_DEBUG(("%s: device MMAP SND_PCM_ACCESS_MMAP_INTERLEAVED: %s\n", __FUNCTION__, (snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ? "YES" : "NO")));
PA_DEBUG(("%s: device MMAP SND_PCM_ACCESS_MMAP_NONINTERLEAVED: %s\n", __FUNCTION__, (snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0 ? "YES" : "NO")));
if (!self->canMmap)
{
accessMode = SND_PCM_ACCESS_RW_INTERLEAVED;
alternateAccessMode = SND_PCM_ACCESS_RW_NONINTERLEAVED;
}
}
}
else
{
accessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;
accessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;
alternateAccessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED;
/* test if MMAP supported */
self->canMmap = snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ||
snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0;
PA_DEBUG(("%s: device MMAP SND_PCM_ACCESS_MMAP_NONINTERLEAVED: %s\n", __FUNCTION__, (snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ? "YES" : "NO")));
PA_DEBUG(("%s: device MMAP SND_PCM_ACCESS_MMAP_INTERLEAVED: %s\n", __FUNCTION__, (snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0 ? "YES" : "NO")));
if (!self->canMmap)
{
accessMode = SND_PCM_ACCESS_RW_NONINTERLEAVED;
alternateAccessMode = SND_PCM_ACCESS_RW_INTERLEAVED;
}
}
}
PA_DEBUG(("%s: device can MMAP: %s\n", __FUNCTION__, (self->canMmap ? "YES" : "NO")));
PA_DEBUG(("%s: device can MMAP: %s\n", __FUNCTION__, (self->canMmap ? "YES" : "NO")));
/* If requested access mode fails, try alternate mode */
if( snd_pcm_hw_params_set_access( pcm, hwParams, accessMode ) < 0 )
{
int err = 0;
int err = 0;
if( (err = snd_pcm_hw_params_set_access( pcm, hwParams, alternateAccessMode )) < 0)
{
result = paUnanticipatedHostError;
PaUtil_SetLastHostErrorInfo( paALSA, err, snd_strerror( err ) );
goto error;
}
/* Flip mode */
self->hostInterleaved = !self->userInterleaved;
{
result = paUnanticipatedHostError;
PaUtil_SetLastHostErrorInfo( paALSA, err, snd_strerror( err ) );
goto error;
}
/* Flip mode */
self->hostInterleaved = !self->userInterleaved;
}
ENSURE_( snd_pcm_hw_params_set_format( pcm, hwParams, self->nativeFormat ), paUnanticipatedHostError );
@ -1465,6 +1474,40 @@ static int CalculatePollTimeout( const PaAlsaStream *stream, unsigned long frame
return (int)ceil( 1000 * frames / stream->streamRepresentation.streamInfo.sampleRate );
}
/** Align value in backward direction.
*
* @param v: Value to align.
* @param align: Alignment.
*/
static unsigned long PaAlsa_AlignBackward(unsigned long v, unsigned long align)
{
return ((v - (align ? v % align : 0)));
}
/** Align value in forward direction.
*
* @param v: Value to align.
* @param align: Alignment.
*/
static unsigned long PaAlsa_AlignForward(unsigned long v, unsigned long align)
{
unsigned long remainder = (align ? (v % align) : 0);
return (remainder != 0 ? v + (align - remainder) : v);
}
/** Get size of host buffer maintained from the number of user frames, sample rate and suggested latency. Minimum double buffering
* is maintained to allow 100% CPU usage inside user callback.
*
* @param userFramesPerBuffer: User buffer size in number of frames.
* @param suggestedLatency: User provided desired latency.
* @param sampleRate: Sample rate.
*/
static unsigned long PaAlsa_GetFramesPerHostBuffer(unsigned long userFramesPerBuffer, PaTime suggestedLatency, double sampleRate)
{
unsigned long frames = userFramesPerBuffer + PA_MAX( userFramesPerBuffer, (unsigned long)(suggestedLatency * sampleRate) );
return frames;
}
/** Determine size per host buffer.
*
* During this method call, the component's framesPerBuffer attribute gets computed, and the corresponding period size
@ -1475,18 +1518,20 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo
unsigned long framesPerUserBuffer, double sampleRate, snd_pcm_hw_params_t* hwParams, int* accurate )
{
PaError result = paNoError;
unsigned long bufferSize = params->suggestedLatency * sampleRate, framesPerHostBuffer;
unsigned long bufferSize, framesPerHostBuffer;
int dir = 0;
{
snd_pcm_uframes_t tmp;
snd_pcm_hw_params_get_buffer_size_min( hwParams, &tmp );
bufferSize = PA_MAX( bufferSize, tmp );
snd_pcm_hw_params_get_buffer_size_max( hwParams, &tmp );
bufferSize = PA_MIN( bufferSize, tmp );
}
/* Calculate host buffer size */
bufferSize = PaAlsa_GetFramesPerHostBuffer(framesPerUserBuffer, params->suggestedLatency, sampleRate);
assert( bufferSize > 0 );
/* Log */
PA_DEBUG(( "%s: user-buffer (frames) = %lu\n", __FUNCTION__, framesPerUserBuffer ));
PA_DEBUG(( "%s: user-buffer (sec) = %f\n", __FUNCTION__, (double)(framesPerUserBuffer / sampleRate) ));
PA_DEBUG(( "%s: suggested latency (sec) = %f\n", __FUNCTION__, params->suggestedLatency ));
PA_DEBUG(( "%s: suggested host buffer (frames) = %lu\n", __FUNCTION__, bufferSize ));
PA_DEBUG(( "%s: suggested host buffer (sec) = %f\n", __FUNCTION__, (double)(bufferSize / sampleRate) ));
#ifdef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC
if( framesPerUserBuffer != paFramesPerBufferUnspecified )
{
@ -1528,15 +1573,62 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo
}
}
/* Using the base number of periods, we try to approximate the suggested latency (+1 period),
finding a combination of period/buffer size which best fits these constraints */
{
unsigned numPeriods = numPeriods_, maxPeriods = 0;
#endif
{
unsigned numPeriods = numPeriods_, maxPeriods = 0, minPeriods = numPeriods_;
/* It may be that the device only supports 2 periods for instance */
dir = 0;
ENSURE_( snd_pcm_hw_params_get_periods_min( hwParams, &minPeriods, &dir ), paUnanticipatedHostError )
ENSURE_( snd_pcm_hw_params_get_periods_max( hwParams, &maxPeriods, &dir ), paUnanticipatedHostError );
assert( maxPeriods > 1 );
numPeriods = PA_MIN( maxPeriods, numPeriods );
/* Clamp to min/max */
numPeriods = PA_MIN(maxPeriods, PA_MAX(minPeriods, numPeriods));
PA_DEBUG(( "%s: periods min = %lu, max = %lu, req = %lu \n", __FUNCTION__, minPeriods, maxPeriods, numPeriods ));
#ifndef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC
/* Calculate period size */
framesPerHostBuffer = (bufferSize / numPeriods);
/* Align & test size */
if( framesPerUserBuffer != paFramesPerBufferUnspecified )
{
/* Align to user buffer size */
framesPerHostBuffer = PaAlsa_AlignForward(framesPerHostBuffer, framesPerUserBuffer);
/* Test (borrowed from older implementation) */
if( framesPerHostBuffer < framesPerUserBuffer )
{
assert( framesPerUserBuffer % framesPerHostBuffer == 0 );
if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 )
{
if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer * 2, 0 ) == 0 )
framesPerHostBuffer *= 2;
else
if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 )
framesPerHostBuffer /= 2;
}
}
else
{
assert( framesPerHostBuffer % framesPerUserBuffer == 0 );
if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 )
{
if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer + framesPerUserBuffer, 0 ) == 0 )
framesPerHostBuffer += framesPerUserBuffer;
else
if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer - framesPerUserBuffer, 0 ) == 0 )
framesPerHostBuffer -= framesPerUserBuffer;
}
}
}
#endif
#ifdef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC
if( framesPerUserBuffer != paFramesPerBufferUnspecified )
{
@ -1594,41 +1686,49 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo
{
framesPerHostBuffer = bufferSize / numPeriods;
}
}
/* non-mmap mode needs a reasonably-sized buffer or it'll stutter */
if( !self->canMmap && framesPerHostBuffer < 2048 )
framesPerHostBuffer = 2048;
/* non-mmap mode needs a reasonably-sized buffer or it'll stutter */
if( !self->canMmap && framesPerHostBuffer < 2048 )
framesPerHostBuffer = 2048;
#endif
PA_DEBUG(( "%s: suggested host buffer period = %lu \n", __FUNCTION__, framesPerHostBuffer ));
}
assert( framesPerHostBuffer > 0 );
{
snd_pcm_uframes_t min = 0, max = 0;
/* Get min/max period sizes and adjust our chosen */
snd_pcm_uframes_t min = 0, max = 0, minmax_diff;
ENSURE_( snd_pcm_hw_params_get_period_size_min( hwParams, &min, NULL ), paUnanticipatedHostError );
ENSURE_( snd_pcm_hw_params_get_period_size_max( hwParams, &max, NULL ), paUnanticipatedHostError );
minmax_diff = max - min;
if( framesPerHostBuffer < min )
{
PA_DEBUG(( "%s: The determined period size (%lu) is less than minimum (%lu)\n", __FUNCTION__,
framesPerHostBuffer, min ));
framesPerHostBuffer = min;
PA_DEBUG(( "%s: The determined period size (%lu) is less than minimum (%lu)\n", __FUNCTION__, framesPerHostBuffer, min ));
framesPerHostBuffer = ((minmax_diff == 2) ? min + 1 : min);
}
else if( framesPerHostBuffer > max )
else
if( framesPerHostBuffer > max )
{
PA_DEBUG(( "%s: The determined period size (%lu) is greater than maximum (%lu)\n", __FUNCTION__,
framesPerHostBuffer, max ));
framesPerHostBuffer = max;
PA_DEBUG(( "%s: The determined period size (%lu) is greater than maximum (%lu)\n", __FUNCTION__, framesPerHostBuffer, max ));
framesPerHostBuffer = ((minmax_diff == 2) ? max - 1 : max);
}
assert( framesPerHostBuffer >= min && framesPerHostBuffer <= max );
PA_DEBUG(( "%s: device period minimum = %lu\n", __FUNCTION__, min ));
PA_DEBUG(( "%s: device period maximum = %lu\n", __FUNCTION__, max ));
PA_DEBUG(( "%s: host buffer period = %lu\n", __FUNCTION__, framesPerHostBuffer ));
PA_DEBUG(( "%s: host buffer period latency = %f\n", __FUNCTION__, (double)(framesPerHostBuffer / sampleRate) ));
/* Try setting period size */
dir = 0;
ENSURE_( snd_pcm_hw_params_set_period_size_near( self->pcm, hwParams, &framesPerHostBuffer, &dir ),
paUnanticipatedHostError );
ENSURE_( snd_pcm_hw_params_set_period_size_near( self->pcm, hwParams, &framesPerHostBuffer, &dir ), paUnanticipatedHostError );
if( dir != 0 )
{
PA_DEBUG(( "%s: The configured period size is non-integer.\n", __FUNCTION__, dir ));
*accurate = 0;
}
}
/* Set result */
self->framesPerBuffer = framesPerHostBuffer;
error:
@ -1996,8 +2096,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
PA_ENSURE( PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer,
&inputLatency, &outputLatency, &hostBufferSizeMode ) );
hostInputSampleFormat = stream->capture.hostSampleFormat;
hostOutputSampleFormat = stream->playback.hostSampleFormat;
hostInputSampleFormat = stream->capture.hostSampleFormat | (!stream->capture.hostInterleaved ? paNonInterleaved : 0);
hostOutputSampleFormat = stream->playback.hostSampleFormat | (!stream->playback.hostInterleaved ? paNonInterleaved : 0);
PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
numInputChannels, inputSampleFormat, hostInputSampleFormat,
@ -2013,6 +2113,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
stream->streamRepresentation.streamInfo.outputLatency = outputLatency + (PaTime)(
PaUtil_GetBufferProcessorOutputLatency( &stream->bufferProcessor ) / sampleRate);
PA_DEBUG(( "%s: Stream: framesPerBuffer = %lu, maxFramesPerHostBuffer = %lu, latency = i(%f)/o(%f), \n", __FUNCTION__, framesPerBuffer, stream->maxFramesPerHostBuffer, stream->streamRepresentation.streamInfo.inputLatency, stream->streamRepresentation.streamInfo.outputLatency));
*s = (PaStream*)stream;
return result;
@ -2032,9 +2134,6 @@ static PaError CloseStream( PaStream* s )
PaError result = paNoError;
PaAlsaStream *stream = (PaAlsaStream*)s;
free(stream->playback.nonMmapBuffer);
free(stream->capture.nonMmapBuffer);
PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
@ -2345,6 +2444,7 @@ static double GetStreamCpuLoad( PaStream* s )
static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate )
{
PaError result = paNoError;
unsigned long approx = (unsigned long) sampleRate;
int dir = 0;
double fraction = sampleRate - approx;
@ -2362,7 +2462,24 @@ static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwPara
dir = 1;
}
return snd_pcm_hw_params_set_rate( pcm, hwParams, approx, dir );
if( snd_pcm_hw_params_set_rate( pcm, hwParams, approx, dir ) < 0)
result = paInvalidSampleRate;
end:
return result;
error:
/* Log */
{
unsigned int _min = 0, _max = 0; int _dir = 0;
ENSURE_( snd_pcm_hw_params_get_rate_min( hwParams, &_min, &_dir ), paUnanticipatedHostError );
ENSURE_( snd_pcm_hw_params_get_rate_max( hwParams, &_max, &_dir ), paUnanticipatedHostError );
PA_DEBUG(( "%s: SR min = %d, max = %d, req = %lu\n", __FUNCTION__, _min, _max, approx ));
}
goto end;
}
/* Return exact sample rate in param sampleRate */
@ -2425,8 +2542,8 @@ static PaError PaAlsaStream_HandleXrun( PaAlsaStream *self )
{
PA_DEBUG(( "%s: [playback] non-MMAP-PCM failed recovering from XRUN, will restart Alsa\n", __FUNCTION__ ));
++ restartAlsa; /* did not manage to recover */
}
}
}
}
else
++ restartAlsa; /* always restart MMAPed device */
}
@ -2445,8 +2562,8 @@ static PaError PaAlsaStream_HandleXrun( PaAlsaStream *self )
{
PA_DEBUG(( "%s: [capture] non-MMAP-PCM failed recovering from XRUN, will restart Alsa\n", __FUNCTION__ ));
++ restartAlsa; /* did not manage to recover */
}
}
}
}
else
++ restartAlsa; /* always restart MMAPed device */
}
@ -2987,6 +3104,8 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr
/* not else ! */
if (timeouts >= 64) /* audio device not working, shall return error to notify waiters */
{
*framesAvail = 0; /* no frames available for processing */
PA_DEBUG(( "%s: poll timed out, returning error\n", __FUNCTION__, timeouts ));
PA_ENSURE( paTimedOut );
}
@ -2997,19 +3116,19 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr
/* reset timouts counter */
timeouts = 0;
/* check the return status of our pfds */
if( pollCapture )
{
PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->capture, capturePfds, &pollCapture, &xrun ) );
}
if( pollPlayback )
{
PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->playback, playbackPfds, &pollPlayback, &xrun ) );
}
if( xrun )
{
break;
}
/* check the return status of our pfds */
if( pollCapture )
{
PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->capture, capturePfds, &pollCapture, &xrun ) );
}
if( pollPlayback )
{
PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->playback, playbackPfds, &pollPlayback, &xrun ) );
}
if( xrun )
{
break;
}
}
/* @concern FullDuplex If only one of two pcms is ready we may want to compromise between the two.
@ -3113,19 +3232,15 @@ static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* se
}
else
{
/* using realloc for optimisation
free( self->nonMmapBuffer );
self->nonMmapBuffer = calloc( self->numHostChannels, snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 ) );
*/
unsigned int bufferSize = self->numHostChannels * snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 );
unsigned int bufferSize = self->numHostChannels * snd_pcm_format_size( self->nativeFormat, *numFrames );
if (bufferSize > self->nonMmapBufferSize)
{
self->nonMmapBuffer = realloc(self->nonMmapBuffer, (self->nonMmapBufferSize = bufferSize));
if (!self->nonMmapBuffer)
if (!self->nonMmapBuffer)
{
result = paInsufficientMemory;
goto error;
}
}
}
}
@ -3144,20 +3259,22 @@ static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* se
else
{
if( self->canMmap )
{
for( i = 0; i < self->numUserChannels; ++i )
{
area = areas + i;
buffer = ExtractAddress( area, self->offset );
setChannel( bp, i, buffer, 1 );
}
}
else
{
int bufsize = snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 );
unsigned int buf_per_ch_size = self->nonMmapBufferSize / self->numHostChannels;
buffer = self->nonMmapBuffer;
for( i = 0; i < self->numUserChannels; ++i )
{
setChannel( bp, i, buffer, 1 );
buffer += bufsize;
buffer += buf_per_ch_size;
}
}
}
@ -3171,13 +3288,13 @@ static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* se
else
{
void *bufs[self->numHostChannels];
int bufsize = snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 );
unsigned int buf_per_ch_size = self->nonMmapBufferSize / self->numHostChannels;
unsigned char *buffer = self->nonMmapBuffer;
int i;
for( i = 0; i < self->numHostChannels; ++i )
{
bufs[i] = buffer;
buffer += bufsize;
buffer += buf_per_ch_size;
}
res = snd_pcm_readn( self->pcm, bufs, *numFrames );
}
@ -3185,11 +3302,6 @@ static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* se
{
*xrun = 1;
*numFrames = 0;
/* using realloc for optimisation
free( self->nonMmapBuffer );
self->nonMmapBuffer = NULL;
*/
}
}

View File

@ -1950,10 +1950,10 @@ static PaError PaAsiHpi_PrimeOutputWithSilence( PaAsiHpiStream *stream )
zeroer(out->tempBuffer, 1, out->tempBufferSize / Pa_GetSampleSize(outputFormat) );
/* Write temp buffer to hardware fifo twice, to get started */
#if (HPI_VER >= HPI_VERSION_CONSTRUCTOR( 3, 5, 5 ))
PA_ASIHPI_UNLESS_( HPI_OutStreamWriteBuf( out->hpiDevice->subSys, out->hpiStream,
PA_ASIHPI_UNLESS_( HPI_OutStreamWriteBuf( out->hpiDevice->subSys, out->hpiStream,
out->tempBuffer, out->tempBufferSize, &out->hpiFormat),
paUnanticipatedHostError );
PA_ASIHPI_UNLESS_( HPI_OutStreamWriteBuf( out->hpiDevice->subSys, out->hpiStream,
PA_ASIHPI_UNLESS_( HPI_OutStreamWriteBuf( out->hpiDevice->subSys, out->hpiStream,
out->tempBuffer, out->tempBufferSize, &out->hpiFormat),
paUnanticipatedHostError );
#else
@ -2482,7 +2482,7 @@ static PaError PaAsiHpi_BeginProcessing( PaAsiHpiStream *stream, unsigned long *
if( stream->input )
{
PaAsiHpiStreamInfo info;
#if (HPI_VER < HPI_VERSION_CONSTRUCTOR( 3, 5, 5 ))
HPI_DATA data;
#endif
@ -2514,7 +2514,7 @@ static PaError PaAsiHpi_BeginProcessing( PaAsiHpiStream *stream, unsigned long *
#if (HPI_VER >= HPI_VERSION_CONSTRUCTOR( 3, 5, 5 ))
/* Read block of data into temp buffer */
PA_ASIHPI_UNLESS_( HPI_InStreamReadBuf( stream->input->hpiDevice->subSys,
stream->input->hpiStream,
stream->input->hpiStream,
stream->input->tempBuffer,
framesToGet * stream->input->bytesPerFrame),
paUnanticipatedHostError );
@ -2583,9 +2583,9 @@ static PaError PaAsiHpi_EndProcessing( PaAsiHpiStream *stream, unsigned long num
#if (HPI_VER >= HPI_VERSION_CONSTRUCTOR( 3, 5, 5 ))
/* Write temp buffer to HPI stream */
PA_ASIHPI_UNLESS_( HPI_OutStreamWriteBuf( stream->output->hpiDevice->subSys,
stream->output->hpiStream,
stream->output->hpiStream,
stream->output->tempBuffer,
numFrames * stream->output->bytesPerFrame,
numFrames * stream->output->bytesPerFrame,
&stream->output->hpiFormat),
paUnanticipatedHostError );
#else

View File

@ -1,140 +1,140 @@
ASIO-README.txt
This document contains information to help you compile PortAudio with
ASIO support. If you find any omissions or errors in this document
please notify us on the PortAudio mailing list.
Building PortAudio with ASIO support
------------------------------------
To build PortAudio with ASIO support you need to compile and link with
pa_asio.c, and files from the ASIO SDK (see below), along with the common
files from src/common/ and platform specific files from src/os/win/ (for Win32)
or src/os/mac/ (for Macintosh).
If you are compiling with a non-Microsoft compiler on Windows, also
compile and link with iasiothiscallresolver.cpp (see below for
an explanation).
For some platforms (MingW, possibly Mac), you may simply
be able to type:
./configure --with-host_os=mingw --with-winapi=asio [--with-asiodir=/usr/local/asiosdk2]
make
./configure --with-host_os=darwin --with-winapi=asio [--with-asiodir=/usr/local/asiosdk2]
make
and life will be good.
Obtaining the ASIO SDK
----------------------
In order to build PortAudio with ASIO support, you need to download
the ASIO SDK (version 2.0) from Steinberg. Steinberg makes the ASIO
SDK available to anyone free of charge, however they do not permit its
source code to be distributed.
NOTE: In some cases the ASIO SDK may require patching, see below
for further details.
http://www.steinberg.de/329+M52087573ab0.html
If the above link is broken search Google for:
"download steinberg ASIO SDK"
Building the ASIO SDK on Macintosh
----------------------------------
To build the ASIO SDK on Macintosh you need to compile and link with the
following files from the ASIO SDK:
host/asiodrivers.cpp
host/mac/asioshlib.cpp
host/mac/codefragements.cpp
You may also need to adjust your include paths to support inclusion of
header files from the above directories.
Building the ASIO SDK on Windows
--------------------------------
To build the ASIO SDK on Windows you need to compile and link with the
following files from the ASIO SDK:
asio_sdk\common\asio.cpp
asio_sdk\host\asiodrivers.cpp
asio_sdk\host\pc\asiolist.cpp
You may also need to adjust your include paths to support inclusion of
header files from the above directories.
The ASIO SDK depends on the following COM API functions:
CoInitialize, CoUninitialize, CoCreateInstance, CLSIDFromString
For compilation with MinGW you will need to link with -lole32, for
Borland compilers link with Import32.lib.
Non-Microsoft (MSVC) Compilers on Windows including Borland and GCC
-------------------------------------------------------------------
Steinberg did not specify a calling convention in the IASIO interface
definition. This causes the Microsoft compiler to use the proprietary
thiscall convention which is not compatible with other compilers, such
as compilers from Borland (BCC and C++Builder) and GNU (gcc).
Steinberg's ASIO SDK will compile but crash on initialization if
compiled with a non-Microsoft compiler on Windows.
PortAudio solves this problem using the iasiothiscallresolver library
which is included in the distribution. When building ASIO support for
non-Microsoft compilers, be sure to compile and link with
iasiothiscallresolver.cpp. Note that iasiothiscallresolver includes
conditional directives which cause it to have no effect if it is
compiled with a Microsoft compiler, or on the Macintosh.
If you use configure and make (see above), this should be handled
automatically for you.
For further information about the IASIO thiscall problem see this page:
http://www.audiomulch.com/~rossb/code/calliasio
Macintosh ASIO SDK Bug Patch
----------------------------
There is a bug in the ASIO SDK that causes the Macintosh version to
often fail during initialization. Below is a patch that you can apply.
In codefragments.cpp replace getFrontProcessDirectory function with
the following one (GetFrontProcess replaced by GetCurrentProcess).
bool CodeFragments::getFrontProcessDirectory(void *specs)
{
FSSpec *fss = (FSSpec *)specs;
ProcessInfoRec pif;
ProcessSerialNumber psn;
memset(&psn,0,(long)sizeof(ProcessSerialNumber));
// if(GetFrontProcess(&psn) == noErr) // wrong !!!
if(GetCurrentProcess(&psn) == noErr) // correct !!!
{
pif.processName = 0;
pif.processAppSpec = fss;
pif.processInfoLength = sizeof(ProcessInfoRec);
if(GetProcessInformation(&psn, &pif) == noErr)
return true;
}
return false;
}
---
ASIO-README.txt
This document contains information to help you compile PortAudio with
ASIO support. If you find any omissions or errors in this document
please notify us on the PortAudio mailing list.
Building PortAudio with ASIO support
------------------------------------
To build PortAudio with ASIO support you need to compile and link with
pa_asio.c, and files from the ASIO SDK (see below), along with the common
files from src/common/ and platform specific files from src/os/win/ (for Win32)
or src/os/mac/ (for Macintosh).
If you are compiling with a non-Microsoft compiler on Windows, also
compile and link with iasiothiscallresolver.cpp (see below for
an explanation).
For some platforms (MingW, possibly Mac), you may simply
be able to type:
./configure --with-host_os=mingw --with-winapi=asio [--with-asiodir=/usr/local/asiosdk2]
make
./configure --with-host_os=darwin --with-winapi=asio [--with-asiodir=/usr/local/asiosdk2]
make
and life will be good.
Obtaining the ASIO SDK
----------------------
In order to build PortAudio with ASIO support, you need to download
the ASIO SDK (version 2.0) from Steinberg. Steinberg makes the ASIO
SDK available to anyone free of charge, however they do not permit its
source code to be distributed.
NOTE: In some cases the ASIO SDK may require patching, see below
for further details.
http://www.steinberg.de/329+M52087573ab0.html
If the above link is broken search Google for:
"download steinberg ASIO SDK"
Building the ASIO SDK on Macintosh
----------------------------------
To build the ASIO SDK on Macintosh you need to compile and link with the
following files from the ASIO SDK:
host/asiodrivers.cpp
host/mac/asioshlib.cpp
host/mac/codefragements.cpp
You may also need to adjust your include paths to support inclusion of
header files from the above directories.
Building the ASIO SDK on Windows
--------------------------------
To build the ASIO SDK on Windows you need to compile and link with the
following files from the ASIO SDK:
asio_sdk\common\asio.cpp
asio_sdk\host\asiodrivers.cpp
asio_sdk\host\pc\asiolist.cpp
You may also need to adjust your include paths to support inclusion of
header files from the above directories.
The ASIO SDK depends on the following COM API functions:
CoInitialize, CoUninitialize, CoCreateInstance, CLSIDFromString
For compilation with MinGW you will need to link with -lole32, for
Borland compilers link with Import32.lib.
Non-Microsoft (MSVC) Compilers on Windows including Borland and GCC
-------------------------------------------------------------------
Steinberg did not specify a calling convention in the IASIO interface
definition. This causes the Microsoft compiler to use the proprietary
thiscall convention which is not compatible with other compilers, such
as compilers from Borland (BCC and C++Builder) and GNU (gcc).
Steinberg's ASIO SDK will compile but crash on initialization if
compiled with a non-Microsoft compiler on Windows.
PortAudio solves this problem using the iasiothiscallresolver library
which is included in the distribution. When building ASIO support for
non-Microsoft compilers, be sure to compile and link with
iasiothiscallresolver.cpp. Note that iasiothiscallresolver includes
conditional directives which cause it to have no effect if it is
compiled with a Microsoft compiler, or on the Macintosh.
If you use configure and make (see above), this should be handled
automatically for you.
For further information about the IASIO thiscall problem see this page:
http://www.audiomulch.com/~rossb/code/calliasio
Macintosh ASIO SDK Bug Patch
----------------------------
There is a bug in the ASIO SDK that causes the Macintosh version to
often fail during initialization. Below is a patch that you can apply.
In codefragments.cpp replace getFrontProcessDirectory function with
the following one (GetFrontProcess replaced by GetCurrentProcess).
bool CodeFragments::getFrontProcessDirectory(void *specs)
{
FSSpec *fss = (FSSpec *)specs;
ProcessInfoRec pif;
ProcessSerialNumber psn;
memset(&psn,0,(long)sizeof(ProcessSerialNumber));
// if(GetFrontProcess(&psn) == noErr) // wrong !!!
if(GetCurrentProcess(&psn) == noErr) // correct !!!
{
pif.processName = 0;
pif.processAppSpec = fss;
pif.processInfoLength = sizeof(ProcessInfoRec);
if(GetProcessInformation(&psn, &pif) == noErr)
return true;
}
return false;
}
---

View File

@ -71,7 +71,7 @@
(IUnknown functions)
0 virtual HRESULT STDMETHODCALLTYPE (*QueryInterface)(REFIID riid, void **ppv) = 0;
4 virtual ULONG STDMETHODCALLTYPE (*AddRef)() = 0;
8 virtual ULONG STDMETHODCALLTYPE (*Release)() = 0;
8 virtual ULONG STDMETHODCALLTYPE (*Release)() = 0;
(IASIO functions)
12 virtual ASIOBool (*init)(void *sysHandle) = 0;
@ -128,7 +128,7 @@
with MSVC, and requires that you ship the OpenASIO DLL with your
application.
ACKNOWLEDGEMENTS
Ross Bencina: worked out the thiscall details above, wrote the original
@ -186,7 +186,7 @@ extern IASIO* theAsioDriver;
// The following macros define the inline assembler for BORLAND first then gcc
#if defined(__BCPLUSPLUS__) || defined(__BORLANDC__)
#if defined(__BCPLUSPLUS__) || defined(__BORLANDC__)
#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )\
@ -392,7 +392,7 @@ ULONG STDMETHODCALLTYPE IASIOThiscallResolver::AddRef()
ULONG STDMETHODCALLTYPE IASIOThiscallResolver::Release()
{
assert( false ); // this function should never be called by the ASIO SDK.
return 1;
}
@ -474,7 +474,7 @@ ASIOError IASIOThiscallResolver::getSampleRate(ASIOSampleRate *sampleRate)
}
ASIOError IASIOThiscallResolver::setSampleRate(ASIOSampleRate sampleRate)
{
{
ASIOBool result;
CALL_THISCALL_1_DOUBLE( result, that_, 56, sampleRate );
return result;

View File

@ -1,5 +1,5 @@
/*
* $Id: pa_asio.cpp 1436 2009-12-10 08:09:21Z rossb $
* $Id: pa_asio.cpp 1525 2010-07-14 06:45:25Z rossb $
* Portable Audio I/O Library for ASIO Drivers
*
* Author: Stephane Letz
@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -83,7 +83,7 @@
@todo review ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable
@todo review Blocking i/o latency computations in OpenStream(), changing ring
@todo review Blocking i/o latency computations in OpenStream(), changing ring
buffer to a non-power-of-two structure could reduce blocking i/o latency.
@todo implement IsFormatSupported
@ -169,10 +169,16 @@
*/
/* winmm.lib is needed for timeGetTime() (this is in winmm.a if you're using gcc) */
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
#pragma comment(lib, "winmm.lib")
#endif
/* external reference to ASIO SDK's asioDrivers.
This is a bit messy because we want to explicitly manage
allocation/deallocation of this structure, but some layers of the SDK
This is a bit messy because we want to explicitly manage
allocation/deallocation of this structure, but some layers of the SDK
which we currently use (eg the implementation in asio.cpp) still
use this global version.
@ -322,7 +328,7 @@ typedef struct
AsioDrivers *asioDrivers;
void *systemSpecific;
/* the ASIO C API only allows one ASIO driver to be open at a time,
so we keep track of whether we have the driver open here, and
use this information to return errors from OpenStream if the
@ -987,7 +993,7 @@ static PaError LoadAsioDriver( PaAsioHostApiRepresentation *asioHostApi, const c
ASIOError asioError;
int asioIsInitialized = 0;
/*
/*
ASIO uses CoCreateInstance() to load a driver. That requires that
CoInitialize(0) be called for every thread that loads a driver.
It is OK to call CoInitialize(0) multiple times form one thread as long
@ -1097,7 +1103,7 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
try
{
asioHostApi->asioDrivers = new AsioDrivers(); /* calls CoInitialize(0) */
}
}
catch (std::bad_alloc)
{
asioHostApi->asioDrivers = 0;
@ -1175,7 +1181,7 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
// we face fact that some drivers were not meant for it, drivers which act
// like shells on top of REAL drivers, for instance.
// so we get duplicate handles, locks and other problems.
// so lets NOT try to load any such wrappers.
// so lets NOT try to load any such wrappers.
// The ones i [davidv] know of so far are:
if ( strcmp (names[i],"ASIO DirectX Full Duplex Driver") == 0
@ -1189,16 +1195,16 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
}
if( IsDebuggerPresent_ && IsDebuggerPresent_() )
if( IsDebuggerPresent_ && IsDebuggerPresent_() )
{
/* ASIO Digidesign Driver uses PACE copy protection which quits out
if a debugger is running. So we don't load it if a debugger is running. */
if( strcmp(names[i], "ASIO Digidesign Driver") == 0 )
if( strcmp(names[i], "ASIO Digidesign Driver") == 0 )
{
PA_DEBUG(("BLACKLISTED!!! ASIO Digidesign Driver would quit the debugger\n"));
continue;
}
}
PA_DEBUG(("BLACKLISTED!!! ASIO Digidesign Driver would quit the debugger\n"));
continue;
}
}
/* Attempt to load the asio driver... */
@ -1263,11 +1269,11 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
defaultHighLatencyBufferSize / deviceInfo->defaultSampleRate;
if( defaultHighLatency < defaultLowLatency )
defaultHighLatency = defaultLowLatency; /* just incase the driver returns something strange */
defaultHighLatency = defaultLowLatency; /* just incase the driver returns something strange */
deviceInfo->defaultHighInputLatency = defaultHighLatency;
deviceInfo->defaultHighOutputLatency = defaultHighLatency;
}else{
deviceInfo->defaultLowInputLatency = 0.;
@ -1416,9 +1422,9 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
PaAsioDriverInfo *driverInfo = &asioHostApi->openAsioDriverInfo;
int inputChannelCount, outputChannelCount;
PaSampleFormat inputSampleFormat, outputSampleFormat;
PaDeviceIndex asioDeviceIndex;
PaDeviceIndex asioDeviceIndex;
ASIOError asioError;
if( inputParameters && outputParameters )
{
/* full duplex ASIO stream must use the same device for input and output */
@ -1426,7 +1432,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
if( inputParameters->device != outputParameters->device )
return paBadIODeviceCombination;
}
if( inputParameters )
{
inputChannelCount = inputParameters->channelCount;
@ -1436,7 +1442,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
this implementation doesn't support any custom sample formats */
if( inputSampleFormat & paCustomFormat )
return paSampleFormatNotSupported;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
@ -1464,7 +1470,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
this implementation doesn't support any custom sample formats */
if( outputSampleFormat & paCustomFormat )
return paSampleFormatNotSupported;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
@ -1487,7 +1493,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
/* if an ASIO device is open we can only get format information for the currently open device */
if( asioHostApi->openAsioDeviceIndex != paNoDevice
if( asioHostApi->openAsioDeviceIndex != paNoDevice
&& asioHostApi->openAsioDeviceIndex != asioDeviceIndex )
{
return paDeviceUnavailable;
@ -1525,7 +1531,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
goto done;
}
}
/* query for sample rate support */
asioError = ASIOCanSampleRate( sampleRate );
if( asioError == ASE_NoClock || asioError == ASE_NotPresent )
@ -1746,7 +1752,7 @@ static PaError ValidateAsioSpecificStreamInfo(
if( (*channelSelectors)[i] < 0
|| (*channelSelectors)[i] >= deviceChannelCount ){
return paInvalidChannelCount;
}
}
}
}
@ -1764,7 +1770,7 @@ static bool IsUsingExternalClockSource()
/* davidv: listing ASIO Clock sources. there is an ongoing investigation by
me about whether or not to call ASIOSetSampleRate if an external Clock is
used. A few drivers expected different things here */
asioError = ASIOGetClockSources(clocks, &numSources);
if( asioError != ASE_OK ){
PA_DEBUG(("ERROR: ASIOGetClockSources: %s\n", PaAsio_GetAsioErrorText(asioError) ));
@ -1772,7 +1778,7 @@ static bool IsUsingExternalClockSource()
PA_DEBUG(("INFO ASIOGetClockSources listing %d clocks\n", numSources ));
for (int i=0;i<numSources;++i){
PA_DEBUG(("ASIOClockSource%d %s current:%d\n", i, clocks[i].name, clocks[i].isCurrentSource ));
if (clocks[i].isCurrentSource)
result = true;
}
@ -1787,7 +1793,7 @@ static PaError ValidateAndSetSampleRate( double sampleRate )
PaError result = paNoError;
ASIOError asioError;
// check that the device supports the requested sample rate
// check that the device supports the requested sample rate
asioError = ASIOCanSampleRate( sampleRate );
PA_DEBUG(("ASIOCanSampleRate(%f):%d\n", sampleRate, asioError ));
@ -1818,7 +1824,7 @@ static PaError ValidateAndSetSampleRate( double sampleRate )
PA_DEBUG(("before ASIOSetSampleRate(%f)\n",sampleRate));
/*
If you have problems with some drivers when externally clocked,
If you have problems with some drivers when externally clocked,
try switching on the following line and commenting out the one after it.
See IsUsingExternalClockSource() for more info.
*/
@ -2107,7 +2113,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
}else{
info->channelNum = i;
}
info->buffers[0] = info->buffers[1] = 0;
}
@ -2528,8 +2534,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
else /* Using callback interface... */
{
result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
inputChannelCount, inputSampleFormat, hostInputSampleFormat,
outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
inputChannelCount, inputSampleFormat, (hostInputSampleFormat | paNonInterleaved),
outputChannelCount, outputSampleFormat, (hostOutputSampleFormat | paNonInterleaved),
sampleRate, streamFlags, framesPerBuffer,
framesPerHostBuffer, paUtilFixedHostBufferSize,
streamCallback, userData );
@ -2551,14 +2557,14 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
// buffer processor latency. it reports the added latency separately
PA_DEBUG(("PaAsio : ASIO InputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n",
stream->inputLatency,
(long)((stream->inputLatency*1000)/ sampleRate),
(long)((stream->inputLatency*1000)/ sampleRate),
PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor),
(long)((PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)*1000)/ sampleRate)
));
PA_DEBUG(("PaAsio : ASIO OuputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n",
stream->outputLatency,
(long)((stream->outputLatency*1000)/ sampleRate),
(long)((stream->outputLatency*1000)/ sampleRate),
PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor),
(long)((PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)*1000)/ sampleRate)
));
@ -2572,7 +2578,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
stream->postOutput = driverInfo->postOutput;
stream->isStopped = 1;
stream->isActive = 0;
asioHostApi->openAsioDeviceIndex = asioDeviceIndex;
theAsioStream = stream;
@ -2798,17 +2804,17 @@ static ASIOTime *bufferSwitchTimeInfo( ASIOTime *timeInfo, long index, ASIOBool
}
int buffersDone = 0;
do
{
if( buffersDone > 0 )
{
// this is a reentered buffer, we missed processing it on time
// set the input overflow and output underflow flags as appropriate
if( theAsioStream->inputChannelCount > 0 )
theAsioStream->callbackFlags |= paInputOverflow;
if( theAsioStream->outputChannelCount > 0 )
theAsioStream->callbackFlags |= paOutputUnderflow;
}
@ -2998,7 +3004,7 @@ previousTime = paTimeInfo.currentTime;
}
}
}
++buffersDone;
}while( PaAsio_AtomicDecrement(&theAsioStream->reenterCount) >= 0 );
@ -3335,7 +3341,7 @@ static PaError AbortStream( PaStream *s )
static PaError IsStreamStopped( PaStream *s )
{
PaAsioStream *stream = (PaAsioStream*)s;
return stream->isStopped;
}
@ -3493,7 +3499,7 @@ static PaError ReadStream( PaStream *s ,
&lRingBufferSize2nd);
/* Set number of frames to be copied from the ring buffer. */
PaUtil_SetInputFrameCount( pBp, lRingBufferSize1st );
PaUtil_SetInputFrameCount( pBp, lRingBufferSize1st );
/* Setup ring buffer access. */
PaUtil_SetInterleavedInputChannels(pBp , /* Buffer processor. */
0 , /* The first channel's index. */
@ -3640,7 +3646,7 @@ static PaError WriteStream( PaStream *s ,
/* If block processing has stopped, abort! */
if( blockingState->stopFlag ) { return result = paStreamIsStopped; }
/* If a timeout is encountered, give up eventually. */
return result = paTimedOut;
}
@ -3665,7 +3671,7 @@ static PaError WriteStream( PaStream *s ,
&lRingBufferSize2nd);
/* Set number of frames to be copied to the ring buffer. */
PaUtil_SetOutputFrameCount( pBp, lRingBufferSize1st );
PaUtil_SetOutputFrameCount( pBp, lRingBufferSize1st );
/* Setup ring buffer access. */
PaUtil_SetInterleavedOutputChannels(pBp , /* Buffer processor. */
0 , /* The first channel's index. */
@ -3907,10 +3913,10 @@ PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific )
}
PA_DEBUG(("PaAsio_ShowControlPanel: ASIOInit(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
PA_DEBUG(("asioVersion: ASIOInit(): %ld\n", asioDriverInfo.asioVersion ));
PA_DEBUG(("driverVersion: ASIOInit(): %ld\n", asioDriverInfo.driverVersion ));
PA_DEBUG(("Name: ASIOInit(): %s\n", asioDriverInfo.name ));
PA_DEBUG(("ErrorMessage: ASIOInit(): %s\n", asioDriverInfo.errorMessage ));
PA_DEBUG(("asioVersion: ASIOInit(): %ld\n", asioDriverInfo.asioVersion ));
PA_DEBUG(("driverVersion: ASIOInit(): %ld\n", asioDriverInfo.driverVersion ));
PA_DEBUG(("Name: ASIOInit(): %s\n", asioDriverInfo.name ));
PA_DEBUG(("ErrorMessage: ASIOInit(): %s\n", asioDriverInfo.errorMessage ));
asioError = ASIOControlPanel();
if( asioError != ASE_OK )
@ -3975,7 +3981,7 @@ PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex,
*channelName = asioDeviceInfo->asioChannelInfos[channelIndex].name;
return paNoError;
error:
return result;
}
@ -4009,7 +4015,7 @@ PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex,
asioDeviceInfo->commonDeviceInfo.maxInputChannels + channelIndex].name;
return paNoError;
error:
return result;
}
@ -4025,7 +4031,7 @@ static PaError GetAsioStreamPointer( PaAsioStream **stream, PaStream *s )
PaError result;
PaUtilHostApiRepresentation *hostApi;
PaAsioHostApiRepresentation *asioHostApi;
result = PaUtil_ValidateStreamPointer( s );
if( result != paNoError )
return result;
@ -4035,7 +4041,7 @@ static PaError GetAsioStreamPointer( PaAsioStream **stream, PaStream *s )
return result;
asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
if( PA_STREAM_REP( s )->streamInterface == &asioHostApi->callbackStreamInterface
|| PA_STREAM_REP( s )->streamInterface == &asioHostApi->blockingStreamInterface )
{

View File

@ -1,196 +1,196 @@
Notes on status of CoreAudio Implementation of PortAudio
Document Last Updated December 9, 2005
There are currently two implementations of PortAudio for Mac Core Audio.
The original is in pa_mac_core_old.c, and the newer, default implementation
is in pa_mac_core.c.
Only pa_mac_core.c is currently developed and supported as it uses apple's
current core audio technology. To select use the old implementation, replace
pa_mac_core.c with pa_mac_core_old.c (eg. "cp pa_mac_core_auhal.c
pa_mac_core.c"), then run configure and make as usual.
-------------------------------------------
Notes on Newer/Default AUHAL implementation:
by Bjorn Roche
Last Updated December 9, 2005
Principle of Operation:
This implementation uses AUHAL for audio I/O. To some extent, it also
operates at the "HAL" Layer, though this behavior can be limited by
platform specific flags (see pa_mac_core.h for details). The default
settings should be reasonable: they don't change the SR of the device and
don't cause interruptions if other devices are using the device.
Major Software Elements Used: Apple's HAL AUs provide output SR
conversion transparently, however, only on output, so this
implementation uses AudioConverters to convert the sample rate on input.
A PortAudio ring buffer is used to buffer input when sample rate
conversion is required or when separate audio units are used for duplex
IO. Finally, a PortAudio buffer processor is used to convert formats and
provide additional buffers if needed. Internally, interleaved floating
point data streams are used exclusively - the audio unit converts from
the audio hardware's native format to interleaved float PCM and
PortAudio's Buffer processor is used for conversion to user formats.
Simplex Input: Simplex input uses a single callback. If sample rate
conversion is required, a ring buffer and AudioConverter are used as
well.
Simplex output: Simplex output uses a single callback. No ring buffer or
audio converter is used because AUHAL does its own output SR conversion.
Duplex, one device (no SR conversion): When one device is used, a single
callback is used. This achieves very low latency.
Duplex, separate devices or SR conversion: When SR conversion is
required, data must be buffered before it is converted and data is not
always available at the same times on input and output, so SR conversion
requires the same treatment as separate devices. The input callback
reads data and puts it in the ring buffer. The output callback reads the
data off the ring buffer, into an audio converter and finally to the
buffer processor.
Platform Specific Options:
By using the flags in pa_mac_core.h, the user may specify several options.
For example, the user can specify the sample-rate conversion quality, and
the extent to which PA will attempt to "play nice" and to what extent it
will interrupt other apps to improve performance. For example, if 44100 Hz
sample rate is requested but the device is set at 48000 Hz, PA can either
change the device for optimal playback ("Pro" mode), which may interrupt
other programs playing back audio, or simple use a sample-rate coversion,
which allows for friendlier sharing of the device ("Play Nice" mode).
Additionally, the user may define a "channel mapping" by calling
paSetupMacCoreChannelMap() on their stream info structure before opening
the stream with it. See below for creating a channel map.
Known issues:
- Buffering: No buffering beyond that provided by core audio is provided
except where absolutely needed for the implementation to work. This may cause
issues with large framesPerBuffer settings and it also means that no additional
latency will be provided even if a large latency setting is selected.
- Latency: Latency settings are generally ignored. They may be used as a
hint for buffer size in paHostFramesPerBufferUnspecified, or the value may
be used in cases where additional buffering is needed, such as doing input and
output on seperate devices. Latency settings are always automatically bound
to "safe" values, however, so setting extreme values here should not be
an issue.
- Buffer Size: paHostFramesPerBufferUnspecified and specific host buffer sizes
are supported. paHostFramesPerBufferUnspecified works best in "pro" mode,
where the buffer size and sample rate of the audio device is most likely
to match the expected values. In the case of paHostFramesPerBuffer, an
appropriate framesPerBuffer value will be used that guarantees minimum
requested latency if that's possible.
- Timing info. It reports on stream time, but I'm probably doing something
wrong since patest_sine_time often reports negative latency numbers. Also,
there are currently issues with some devices whehn plugging/unplugging
devices.
- xrun detection: The only xrun detection performed is when reading
and writing the ring buffer. There is probably more that can be done.
- abort/stop issues: stopping a stream is always a complete operation,
but latency should be low enough to make the lack of a separate abort
unnecessary. Apple clarifies its AudioOutputUnitStop() call here:
http://lists.apple.com/archives/coreaudio-api/2005/Dec/msg00055.html
- blocking interface: should work fine.
- multichannel: It has been tested successfully on multichannel hardware
from MOTU: traveler and 896HD. Also Presonus firepod and others. It is
believed to work with all Core Audio devices, including virtual devices
such as soundflower.
- sample rate conversion quality: By default, SR conversion is the maximum
available. This can be tweaked using flags pa_mac_core.h. Note that the AU
render quyality property is used to set the sample rate conversion quality
as "documented" here:
http://lists.apple.com/archives/coreaudio-api/2004/Jan/msg00141.html
- x86/Universal Binary: Universal binaries can be build.
Creating a channel map:
How to create the map array - Text taken From AUHAL.rtfd :
[3] Channel Maps
Clients can tell the AUHAL units which channels of the device they are interested in. For example, the client may be processing stereo data, but outputting to a six-channel device. This is done by using the kAudioOutputUnitProperty_ChannelMap property. To use this property:
For Output:
Create an array of SInt32 that is the size of the number of channels of the device (Get the Format of the AUHAL's output Element == 0)
Initialize each of the array's values to -1 (-1 indicates that that channel is NOT to be presented in the conversion.)
Next, for each channel of your app's output, set:
channelMapArray[deviceOutputChannel] = desiredAppOutputChannel.
For example: we have a 6 channel output device and our application has a stereo source it wants to provide to the device. Suppose we want that stereo source to go to the 3rd and 4th channels of the device. The channel map would look like this: { -1, -1, 0, 1, -1, -1 }
Where the formats are:
Input Element == 0: 2 channels (- client format - settable)
Output Element == 0: 6 channels (- device format - NOT settable)
So channel 2 (zero-based) of the device will take the first channel of output and channel 3 will take the second channel of output. (This translates to the 3rd and 4th plugs of the 6 output plugs of the device of course!)
For Input:
Create an array of SInt32 that is the size of the number of channels of the format you require for input. Get (or Set in this case as needed) the AUHAL's output Element == 1.
Next, for each channel of input you require, set:
channelMapArray[desiredAppInputChannel] = deviceOutputChannel;
For example: we have a 6 channel input device from which we wish to receive stereo input from the 3rd and 4th channels. The channel map looks like this: { 2, 3 }
Where the formats are:
Input Element == 0: 2 channels (- device format - NOT settable)
Output Element == 0: 6 channels (- client format - settable)
----------------------------------------
Notes on Original implementation:
by Phil Burk and Darren Gibbs
Last updated March 20, 2002
WHAT WORKS
Output with very low latency, <10 msec.
Half duplex input or output.
Full duplex on the same CoreAudio device.
The paFLoat32, paInt16, paInt8, paUInt8 sample formats.
Pa_GetCPULoad()
Pa_StreamTime()
KNOWN BUGS OR LIMITATIONS
We do not yet support simultaneous input and output on different
devices. Note that some CoreAudio devices like the Roland UH30 look
like one device but are actually two different CoreAudio devices. The
Built-In audio is typically one CoreAudio device.
Mono doesn't work.
DEVICE MAPPING
CoreAudio devices can support both input and output. But the sample
rates supported may be different. So we have map one or two PortAudio
device to each CoreAudio device depending on whether it supports
input, output or both.
When we query devices, we first get a list of CoreAudio devices. Then
we scan the list and add a PortAudio device for each CoreAudio device
that supports input. Then we make a scan for output devices.
Notes on status of CoreAudio Implementation of PortAudio
Document Last Updated December 9, 2005
There are currently two implementations of PortAudio for Mac Core Audio.
The original is in pa_mac_core_old.c, and the newer, default implementation
is in pa_mac_core.c.
Only pa_mac_core.c is currently developed and supported as it uses apple's
current core audio technology. To select use the old implementation, replace
pa_mac_core.c with pa_mac_core_old.c (eg. "cp pa_mac_core_auhal.c
pa_mac_core.c"), then run configure and make as usual.
-------------------------------------------
Notes on Newer/Default AUHAL implementation:
by Bjorn Roche
Last Updated December 9, 2005
Principle of Operation:
This implementation uses AUHAL for audio I/O. To some extent, it also
operates at the "HAL" Layer, though this behavior can be limited by
platform specific flags (see pa_mac_core.h for details). The default
settings should be reasonable: they don't change the SR of the device and
don't cause interruptions if other devices are using the device.
Major Software Elements Used: Apple's HAL AUs provide output SR
conversion transparently, however, only on output, so this
implementation uses AudioConverters to convert the sample rate on input.
A PortAudio ring buffer is used to buffer input when sample rate
conversion is required or when separate audio units are used for duplex
IO. Finally, a PortAudio buffer processor is used to convert formats and
provide additional buffers if needed. Internally, interleaved floating
point data streams are used exclusively - the audio unit converts from
the audio hardware's native format to interleaved float PCM and
PortAudio's Buffer processor is used for conversion to user formats.
Simplex Input: Simplex input uses a single callback. If sample rate
conversion is required, a ring buffer and AudioConverter are used as
well.
Simplex output: Simplex output uses a single callback. No ring buffer or
audio converter is used because AUHAL does its own output SR conversion.
Duplex, one device (no SR conversion): When one device is used, a single
callback is used. This achieves very low latency.
Duplex, separate devices or SR conversion: When SR conversion is
required, data must be buffered before it is converted and data is not
always available at the same times on input and output, so SR conversion
requires the same treatment as separate devices. The input callback
reads data and puts it in the ring buffer. The output callback reads the
data off the ring buffer, into an audio converter and finally to the
buffer processor.
Platform Specific Options:
By using the flags in pa_mac_core.h, the user may specify several options.
For example, the user can specify the sample-rate conversion quality, and
the extent to which PA will attempt to "play nice" and to what extent it
will interrupt other apps to improve performance. For example, if 44100 Hz
sample rate is requested but the device is set at 48000 Hz, PA can either
change the device for optimal playback ("Pro" mode), which may interrupt
other programs playing back audio, or simple use a sample-rate coversion,
which allows for friendlier sharing of the device ("Play Nice" mode).
Additionally, the user may define a "channel mapping" by calling
paSetupMacCoreChannelMap() on their stream info structure before opening
the stream with it. See below for creating a channel map.
Known issues:
- Buffering: No buffering beyond that provided by core audio is provided
except where absolutely needed for the implementation to work. This may cause
issues with large framesPerBuffer settings and it also means that no additional
latency will be provided even if a large latency setting is selected.
- Latency: Latency settings are generally ignored. They may be used as a
hint for buffer size in paHostFramesPerBufferUnspecified, or the value may
be used in cases where additional buffering is needed, such as doing input and
output on seperate devices. Latency settings are always automatically bound
to "safe" values, however, so setting extreme values here should not be
an issue.
- Buffer Size: paHostFramesPerBufferUnspecified and specific host buffer sizes
are supported. paHostFramesPerBufferUnspecified works best in "pro" mode,
where the buffer size and sample rate of the audio device is most likely
to match the expected values. In the case of paHostFramesPerBuffer, an
appropriate framesPerBuffer value will be used that guarantees minimum
requested latency if that's possible.
- Timing info. It reports on stream time, but I'm probably doing something
wrong since patest_sine_time often reports negative latency numbers. Also,
there are currently issues with some devices whehn plugging/unplugging
devices.
- xrun detection: The only xrun detection performed is when reading
and writing the ring buffer. There is probably more that can be done.
- abort/stop issues: stopping a stream is always a complete operation,
but latency should be low enough to make the lack of a separate abort
unnecessary. Apple clarifies its AudioOutputUnitStop() call here:
http://lists.apple.com/archives/coreaudio-api/2005/Dec/msg00055.html
- blocking interface: should work fine.
- multichannel: It has been tested successfully on multichannel hardware
from MOTU: traveler and 896HD. Also Presonus firepod and others. It is
believed to work with all Core Audio devices, including virtual devices
such as soundflower.
- sample rate conversion quality: By default, SR conversion is the maximum
available. This can be tweaked using flags pa_mac_core.h. Note that the AU
render quyality property is used to set the sample rate conversion quality
as "documented" here:
http://lists.apple.com/archives/coreaudio-api/2004/Jan/msg00141.html
- x86/Universal Binary: Universal binaries can be build.
Creating a channel map:
How to create the map array - Text taken From AUHAL.rtfd :
[3] Channel Maps
Clients can tell the AUHAL units which channels of the device they are interested in. For example, the client may be processing stereo data, but outputting to a six-channel device. This is done by using the kAudioOutputUnitProperty_ChannelMap property. To use this property:
For Output:
Create an array of SInt32 that is the size of the number of channels of the device (Get the Format of the AUHAL's output Element == 0)
Initialize each of the array's values to -1 (-1 indicates that that channel is NOT to be presented in the conversion.)
Next, for each channel of your app's output, set:
channelMapArray[deviceOutputChannel] = desiredAppOutputChannel.
For example: we have a 6 channel output device and our application has a stereo source it wants to provide to the device. Suppose we want that stereo source to go to the 3rd and 4th channels of the device. The channel map would look like this: { -1, -1, 0, 1, -1, -1 }
Where the formats are:
Input Element == 0: 2 channels (- client format - settable)
Output Element == 0: 6 channels (- device format - NOT settable)
So channel 2 (zero-based) of the device will take the first channel of output and channel 3 will take the second channel of output. (This translates to the 3rd and 4th plugs of the 6 output plugs of the device of course!)
For Input:
Create an array of SInt32 that is the size of the number of channels of the format you require for input. Get (or Set in this case as needed) the AUHAL's output Element == 1.
Next, for each channel of input you require, set:
channelMapArray[desiredAppInputChannel] = deviceOutputChannel;
For example: we have a 6 channel input device from which we wish to receive stereo input from the 3rd and 4th channels. The channel map looks like this: { 2, 3 }
Where the formats are:
Input Element == 0: 2 channels (- device format - NOT settable)
Output Element == 0: 6 channels (- client format - settable)
----------------------------------------
Notes on Original implementation:
by Phil Burk and Darren Gibbs
Last updated March 20, 2002
WHAT WORKS
Output with very low latency, <10 msec.
Half duplex input or output.
Full duplex on the same CoreAudio device.
The paFLoat32, paInt16, paInt8, paUInt8 sample formats.
Pa_GetCPULoad()
Pa_StreamTime()
KNOWN BUGS OR LIMITATIONS
We do not yet support simultaneous input and output on different
devices. Note that some CoreAudio devices like the Roland UH30 look
like one device but are actually two different CoreAudio devices. The
Built-In audio is typically one CoreAudio device.
Mono doesn't work.
DEVICE MAPPING
CoreAudio devices can support both input and output. But the sample
rates supported may be different. So we have map one or two PortAudio
device to each CoreAudio device depending on whether it supports
input, output or both.
When we query devices, we first get a list of CoreAudio devices. Then
we scan the list and add a PortAudio device for each CoreAudio device
that supports input. Then we make a scan for output devices.

View File

@ -15,7 +15,7 @@
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, Phil Burk
@ -41,13 +41,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -249,7 +249,6 @@ static PaError AbortStream( PaStream *stream );
static PaError IsStreamStopped( PaStream *s );
static PaError IsStreamActive( PaStream *stream );
static PaTime GetStreamTime( PaStream *stream );
static void setStreamStartTime( PaStream *stream );
static OSStatus AudioIOProc( void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
@ -373,7 +372,7 @@ static PaError gatherDeviceInfo(PaMacAUHAL *auhalHostApi)
break;
}
}
}
}
if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
&size,
&auhalHostApi->defaultOut) ) {
@ -390,7 +389,7 @@ static PaError gatherDeviceInfo(PaMacAUHAL *auhalHostApi)
break;
}
}
}
}
VDBUG( ( "Default in : %ld\n", auhalHostApi->defaultIn ) );
VDBUG( ( "Default out: %ld\n", auhalHostApi->defaultOut ) );
@ -433,7 +432,7 @@ static PaError GetChannelInfo( PaMacAUHAL *auhalHostApi,
deviceInfo->maxInputChannels = numChannels;
else
deviceInfo->maxOutputChannels = numChannels;
if (numChannels > 0) /* do not try to retrieve the latency if there is no channels. */
{
/* Get the latency. Don't fail if we can't get this. */
@ -535,12 +534,12 @@ PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIn
int unixErr;
VVDBUG(("PaMacCore_Initialize(): hostApiIndex=%d\n", hostApiIndex));
SInt32 major;
SInt32 minor;
Gestalt(gestaltSystemVersionMajor, &major);
Gestalt(gestaltSystemVersionMinor, &minor);
// Starting with 10.6 systems, the HAL notification thread is created internally
if (major == 10 && minor >= 6) {
CFRunLoopRef theRunLoop = NULL;
@ -550,7 +549,7 @@ PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIn
goto error;
}
}
unixErr = initializeXRunListenerList();
if( 0 != unixErr ) {
return UNIX_ERR(unixErr);
@ -586,7 +585,7 @@ PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIn
(*hostApi)->info.defaultInputDevice = paNoDevice;
(*hostApi)->info.defaultOutputDevice = paNoDevice;
(*hostApi)->info.deviceCount = 0;
(*hostApi)->info.deviceCount = 0;
if( auhalHostApi->devCount > 0 )
{
@ -665,7 +664,7 @@ error:
PaUtil_FreeAllAllocations( auhalHostApi->allocations );
PaUtil_DestroyAllocationGroup( auhalHostApi->allocations );
}
PaUtil_FreeMemory( auhalHostApi );
}
return result;
@ -714,7 +713,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
outputParameters ? outputParameters->channelCount : -1,
outputParameters ? outputParameters->sampleFormat : -1,
(float) sampleRate ));
/** These first checks are standard PA checks. We do some fancier checks
later. */
if( inputParameters )
@ -726,7 +725,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
this implementation doesn't support any custom sample formats */
if( inputSampleFormat & paCustomFormat )
return paSampleFormatNotSupported;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
@ -751,7 +750,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
this implementation doesn't support any custom sample formats */
if( outputSampleFormat & paCustomFormat )
return paSampleFormatNotSupported;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
@ -767,7 +766,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
{
outputChannelCount = 0;
}
/* FEEDBACK */
/* I think the only way to check a given format SR combo is */
/* to try opening it. This could be disruptive, is that Okay? */
@ -785,7 +784,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
if( err != paNoError && err != paInvalidSampleRate )
DBUG( ( "OpenStream @ %g returned: %d: %s\n",
(float) sampleRate, err, Pa_GetErrorText( err ) ) );
if( err )
if( err )
return err;
err = CloseStream( s );
if( err ) {
@ -798,6 +797,75 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
return paFormatIsSupported;
}
static void UpdateReciprocalOfActualOutputSampleRateFromDeviceProperty( PaMacCoreStream *stream )
{
/* FIXME: not sure if this should be the sample rate of the output device or the output unit */
Float64 actualOutputSampleRate = stream->outDeviceSampleRate;
UInt32 propSize = sizeof(Float64);
OSStatus osErr = AudioDeviceGetProperty( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyActualSampleRate, &propSize, &actualOutputSampleRate);
if( osErr != noErr || actualOutputSampleRate < .01 ) // avoid divide by zero if there's an error
actualOutputSampleRate = stream->outDeviceSampleRate;
stream->recipricalOfActualOutputSampleRate = 1. / actualOutputSampleRate;
}
static OSStatus AudioDevicePropertyActualSampleRateListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData )
{
PaMacCoreStream *stream = (PaMacCoreStream*)inClientData;
pthread_mutex_lock( &stream->timingInformationMutex );
UpdateReciprocalOfActualOutputSampleRateFromDeviceProperty( stream );
pthread_mutex_unlock( &stream->timingInformationMutex );
return noErr;
}
static void UpdateOutputLatencySamplesFromDeviceProperty( PaMacCoreStream *stream )
{
UInt32 deviceOutputLatencySamples = 0;
UInt32 propSize = sizeof(UInt32);
OSStatus osErr = AudioDeviceGetProperty( stream->outputDevice, 0, /* isInput= */ FALSE, kAudioDevicePropertyLatency, &propSize, &deviceOutputLatencySamples);
if( osErr != noErr )
deviceOutputLatencySamples = 0;
stream->deviceOutputLatencySamples = deviceOutputLatencySamples;
}
static OSStatus AudioDevicePropertyOutputLatencySamplesListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData )
{
PaMacCoreStream *stream = (PaMacCoreStream*)inClientData;
pthread_mutex_lock( &stream->timingInformationMutex );
UpdateOutputLatencySamplesFromDeviceProperty( stream );
pthread_mutex_unlock( &stream->timingInformationMutex );
return noErr;
}
static void UpdateInputLatencySamplesFromDeviceProperty( PaMacCoreStream *stream )
{
UInt32 deviceInputLatencySamples = 0;
UInt32 propSize = sizeof(UInt32);
OSStatus osErr = AudioDeviceGetProperty( stream->inputDevice, 0, /* isInput= */ TRUE, kAudioDevicePropertyLatency, &propSize, &deviceInputLatencySamples);
if( osErr != noErr )
deviceInputLatencySamples = 0;
stream->deviceInputLatencySamples = deviceInputLatencySamples;
}
static OSStatus AudioDevicePropertyInputLatencySamplesListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData )
{
PaMacCoreStream *stream = (PaMacCoreStream*)inClientData;
pthread_mutex_lock( &stream->timingInformationMutex );
UpdateInputLatencySamplesFromDeviceProperty( stream );
pthread_mutex_unlock( &stream->timingInformationMutex );
return noErr;
}
static PaError OpenAndSetupOneAudioUnit(
const PaMacCoreStream *stream,
const PaStreamParameters *inStreamParams,
@ -861,7 +929,7 @@ static PaError OpenAndSetupOneAudioUnit(
outChannelMap = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo)
->channelMap;
outChannelMapSize = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo)
->channelMapSize;
->channelMapSize;
}
/* Override user's flags here, if desired for testing. */
@ -1166,7 +1234,7 @@ static PaError OpenAndSetupOneAudioUnit(
(float)sourceFormat.mSampleRate,
(float)desiredFormat.mSampleRate ) );
/* create our converter */
ERR_WRAP( AudioConverterNew(
ERR_WRAP( AudioConverterNew(
&sourceFormat,
&desiredFormat,
srConverter ) );
@ -1302,7 +1370,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
{
outputChannelCount = outputParameters->channelCount;
outputSampleFormat = outputParameters->sampleFormat;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
@ -1356,6 +1424,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
stream->inputFramesPerBuffer = 0;
stream->outputFramesPerBuffer = 0;
stream->bufferProcessorIsInitialized = FALSE;
stream->timingInformationMutexIsInitialized = 0;
/* assert( streamCallback ) ; */ /* only callback mode is implemented */
if( streamCallback )
@ -1517,7 +1586,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
result = paInsufficientMemory;
goto error;
}
/*
* If input and output devs are different or we are doing SR conversion,
* we also need a
@ -1656,7 +1725,39 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
stream->userInChan = inputChannelCount;
stream->userOutChan = outputChannelCount;
stream->isTimeSet = FALSE;
pthread_mutex_init( &stream->timingInformationMutex, NULL );
stream->timingInformationMutexIsInitialized = 1;
if( stream->outputUnit ) {
UpdateReciprocalOfActualOutputSampleRateFromDeviceProperty( stream );
stream->recipricalOfActualOutputSampleRate_ioProcCopy = stream->recipricalOfActualOutputSampleRate;
AudioDeviceAddPropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyActualSampleRate,
AudioDevicePropertyActualSampleRateListenerProc, stream );
UpdateOutputLatencySamplesFromDeviceProperty( stream );
stream->deviceOutputLatencySamples_ioProcCopy = stream->deviceOutputLatencySamples;
AudioDeviceAddPropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyLatency,
AudioDevicePropertyOutputLatencySamplesListenerProc, stream );
}else{
stream->recipricalOfActualOutputSampleRate = 1.;
stream->recipricalOfActualOutputSampleRate_ioProcCopy = 0.;
stream->deviceOutputLatencySamples_ioProcCopy = 0;
}
if( stream->inputUnit ) {
UpdateInputLatencySamplesFromDeviceProperty( stream );
stream->deviceInputLatencySamples_ioProcCopy = stream->deviceInputLatencySamples;
AudioDeviceAddPropertyListener( stream->inputDevice, 0, /* isInput = */ TRUE, kAudioDevicePropertyLatency,
AudioDevicePropertyInputLatencySamplesListenerProc, stream );
}else{
stream->deviceInputLatencySamples = 0;
stream->deviceInputLatencySamples_ioProcCopy = 0;
}
stream->state = STOPPED;
stream->xrunFlags = 0;
@ -1669,63 +1770,19 @@ error:
return result;
}
#define HOST_TIME_TO_PA_TIME( x ) ( AudioConvertHostTimeToNanos( (x) ) * 1.0E-09) /* convert to nanoseconds and then to seconds */
PaTime GetStreamTime( PaStream *s )
{
/* FIXME: I am not at all sure this timing info stuff is right.
patest_sine_time reports negative latencies, which is wierd.*/
PaMacCoreStream *stream = (PaMacCoreStream*)s;
AudioTimeStamp timeStamp;
VVDBUG(("GetStreamTime()\n"));
if ( !stream->isTimeSet )
return (PaTime)0;
if ( stream->outputDevice ) {
AudioDeviceGetCurrentTime( stream->outputDevice, &timeStamp);
return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->outDeviceSampleRate;
} else if ( stream->inputDevice ) {
AudioDeviceGetCurrentTime( stream->inputDevice, &timeStamp);
return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->inDeviceSampleRate;
} else {
return (PaTime)0;
}
}
static void setStreamStartTime( PaStream *stream )
{
/* FIXME: I am not at all sure this timing info stuff is right.
patest_sine_time reports negative latencies, which is wierd.*/
PaMacCoreStream *s = (PaMacCoreStream *) stream;
VVDBUG(("setStreamStartTime()\n"));
if( s->outputDevice )
AudioDeviceGetCurrentTime( s->outputDevice, &s->startTime);
else if( s->inputDevice )
AudioDeviceGetCurrentTime( s->inputDevice, &s->startTime);
else
bzero( &s->startTime, sizeof( s->startTime ) );
//FIXME: we need a memory barier here
s->isTimeSet = TRUE;
}
static PaTime TimeStampToSecs(PaMacCoreStream *stream, const AudioTimeStamp* timeStamp)
{
VVDBUG(("TimeStampToSecs()\n"));
//printf( "ATS: %lu, %g, %g\n", timeStamp->mFlags, timeStamp->mSampleTime, timeStamp->mRateScalar );
if (timeStamp->mFlags & kAudioTimeStampSampleTimeValid)
return (timeStamp->mSampleTime / stream->sampleRate);
else
return 0;
return HOST_TIME_TO_PA_TIME( AudioGetCurrentHostTime() );
}
#define RING_BUFFER_EMPTY (1000)
static OSStatus ringBufferIOProc( AudioConverterRef inAudioConverter,
UInt32*ioDataSize,
void** outData,
static OSStatus ringBufferIOProc( AudioConverterRef inAudioConverter,
UInt32*ioDataSize,
void** outData,
void*inUserData )
{
void *dummyData;
@ -1741,9 +1798,9 @@ static OSStatus ringBufferIOProc( AudioConverterRef inAudioConverter,
}
assert(sizeof(UInt32) == sizeof(ring_buffer_size_t));
PaUtil_GetRingBufferReadRegions( rb, *ioDataSize,
outData, (ring_buffer_size_t *)ioDataSize,
outData, (ring_buffer_size_t *)ioDataSize,
&dummyData, &dummySize );
assert( *ioDataSize );
PaUtil_AdvanceRingBufferReadIndex( rb, *ioDataSize );
@ -1799,24 +1856,68 @@ static OSStatus AudioIOProc( void *inRefCon,
}
----------------------------------------------------------------- */
if( !stream->isTimeSet )
setStreamStartTime( stream );
if( isRender ) {
AudioTimeStamp currentTime;
timeInfo.outputBufferDacTime = TimeStampToSecs(stream, inTimeStamp);
AudioDeviceGetCurrentTime(stream->outputDevice, &currentTime);
timeInfo.currentTime = TimeStampToSecs(stream, &currentTime);
}
if( isRender && stream->inputUnit == stream->outputUnit )
timeInfo.inputBufferAdcTime = TimeStampToSecs(stream, inTimeStamp);
if( !isRender ) {
AudioTimeStamp currentTime;
timeInfo.inputBufferAdcTime = TimeStampToSecs(stream, inTimeStamp);
AudioDeviceGetCurrentTime(stream->inputDevice, &currentTime);
timeInfo.currentTime = TimeStampToSecs(stream, &currentTime);
}
/* compute PaStreamCallbackTimeInfo */
if( pthread_mutex_trylock( &stream->timingInformationMutex ) == 0 ){
/* snapshot the ioproc copy of timing information */
stream->deviceOutputLatencySamples_ioProcCopy = stream->deviceOutputLatencySamples;
stream->recipricalOfActualOutputSampleRate_ioProcCopy = stream->recipricalOfActualOutputSampleRate;
stream->deviceInputLatencySamples_ioProcCopy = stream->deviceInputLatencySamples;
pthread_mutex_unlock( &stream->timingInformationMutex );
}
/* For timeInfo.currentTime we could calculate current time backwards from the HAL audio
output time to give a more accurate impression of the current timeslice but it doesn't
seem worth it at the moment since other PA host APIs don't do any better.
*/
timeInfo.currentTime = HOST_TIME_TO_PA_TIME( AudioGetCurrentHostTime() );
/*
For an input HAL AU, inTimeStamp is the time the samples are received from the hardware,
for an output HAL AU inTimeStamp is the time the samples are sent to the hardware.
PA expresses timestamps in terms of when the samples enter the ADC or leave the DAC
so we add or subtract kAudioDevicePropertyLatency below.
*/
/* FIXME: not sure what to do below if the host timestamps aren't valid (kAudioTimeStampHostTimeValid isn't set)
Could ask on CA mailing list if it is possible for it not to be set. If so, could probably grab a now timestamp
at the top and compute from there (modulo scheduling jitter) or ask on mailing list for other options. */
if( isRender )
{
if( stream->inputUnit ) /* full duplex */
{
if( stream->inputUnit == stream->outputUnit ) /* full duplex AUHAL IOProc */
{
/* FIXME: review. i'm not sure this computation of inputBufferAdcTime is correct for a full-duplex AUHAL */
timeInfo.inputBufferAdcTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
- stream->deviceInputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy; // FIXME should be using input sample rate here?
timeInfo.outputBufferDacTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
+ stream->deviceOutputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy;
}
else /* full duplex with ring-buffer from a separate input AUHAL ioproc */
{
/* FIXME: review. this computation of inputBufferAdcTime is definitely wrong since it doesn't take the ring buffer latency into account */
timeInfo.inputBufferAdcTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
- stream->deviceInputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy; // FIXME should be using input sample rate here?
timeInfo.outputBufferDacTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
+ stream->deviceOutputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy;
}
}
else /* output only */
{
timeInfo.inputBufferAdcTime = 0;
timeInfo.outputBufferDacTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
+ stream->deviceOutputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy;
}
}
else /* input only */
{
timeInfo.inputBufferAdcTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
- stream->deviceInputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy; // FIXME should be using input sample rate here?
timeInfo.outputBufferDacTime = 0;
}
//printf( "---%g, %g, %g\n", timeInfo.inputBufferAdcTime, timeInfo.currentTime, timeInfo.outputBufferDacTime );
if( isRender && stream->inputUnit == stream->outputUnit
@ -1876,7 +1977,7 @@ static OSStatus AudioIOProc( void *inRefCon,
* -- OR Simplex Output
*
* This case handles output data as in the full duplex case,
* and, if there is input data, reads it off the ring buffer
* and, if there is input data, reads it off the ring buffer
* and into the PA buffer processor. If sample rate conversion
* is required on input, that is done here as well.
*/
@ -1923,7 +2024,7 @@ static OSStatus AudioIOProc( void *inRefCon,
UInt32 size;
float data[ inChan * frames ];
size = sizeof( data );
err = AudioConverterFillBuffer(
err = AudioConverterFillBuffer(
stream->inputSRConverter,
ringBufferIOProc,
&stream->inputRingBuffer,
@ -1937,7 +2038,7 @@ static OSStatus AudioIOProc( void *inRefCon,
}
ERR( err );
assert( !err );
PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames );
PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
0,
@ -2092,7 +2193,7 @@ static OSStatus AudioIOProc( void *inRefCon,
long f;
size = sizeof( data );
err = AudioConverterFillBuffer(
err = AudioConverterFillBuffer(
stream->inputSRConverter,
ringBufferIOProc,
&stream->inputRingBuffer,
@ -2128,7 +2229,6 @@ static OSStatus AudioIOProc( void *inRefCon,
case paContinue: break;
case paComplete:
case paAbort:
stream->isTimeSet = FALSE;
stream->state = CALLBACK_STOPPED ;
if( stream->outputUnit )
AudioOutputUnitStop(stream->outputUnit);
@ -2157,6 +2257,19 @@ static PaError CloseStream( PaStream* s )
VDBUG( ( "Closing stream.\n" ) );
if( stream ) {
if( stream->outputUnit ) {
AudioDeviceRemovePropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyActualSampleRate,
AudioDevicePropertyActualSampleRateListenerProc );
AudioDeviceRemovePropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyLatency,
AudioDevicePropertyOutputLatencySamplesListenerProc );
}
if( stream->inputUnit ) {
AudioDeviceRemovePropertyListener( stream->inputDevice, 0, /* isInput = */ TRUE, kAudioDevicePropertyLatency,
AudioDevicePropertyInputLatencySamplesListenerProc );
}
if( stream->outputUnit ) {
int count = removeFromXRunListenerList( stream );
if( count == 0 )
@ -2203,6 +2316,10 @@ static PaError CloseStream( PaStream* s )
return result;
if( stream->bufferProcessorIsInitialized )
PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
if( stream->timingInformationMutexIsInitialized )
pthread_mutex_destroy( &stream->timingInformationMutex );
PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
PaUtil_FreeMemory( stream );
}
@ -2232,10 +2349,7 @@ static PaError StartStream( PaStream *s )
if( stream->outputUnit && stream->outputUnit != stream->inputUnit ) {
ERR_WRAP( AudioOutputUnitStart(stream->outputUnit) );
}
//setStreamStartTime( stream );
//stream->isTimeSet = TRUE;
return paNoError;
#undef ERR_WRAP
}
@ -2266,7 +2380,6 @@ static PaError StopStream( PaStream *s )
waitUntilBlioWriteBufferIsFlushed( &stream->blio );
VDBUG( ( "Stopping stream.\n" ) );
stream->isTimeSet = FALSE;
stream->state = STOPPING;
#define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0)
@ -2314,10 +2427,6 @@ static PaError StopStream( PaStream *s )
if( paErr )
return paErr;
/*
//stream->isTimeSet = FALSE;
*/
VDBUG( ( "Stream Stopped.\n" ) );
return paNoError;
#undef ERR_WRAP

View File

@ -15,7 +15,7 @@
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, Phil Burk
@ -41,13 +41,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -15,7 +15,7 @@
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, Phil Burk
@ -41,13 +41,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -15,7 +15,7 @@
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, Phil Burk
@ -41,13 +41,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -142,7 +142,6 @@ typedef struct PaMacCoreStream
AudioTimeStamp startTime;
/* FIXME: instead of volatile, these should be properly memory barriered */
volatile PaStreamCallbackFlags xrunFlags;
volatile bool isTimeSet;
volatile enum {
STOPPED = 0, /* playback is completely stopped,
and the user has called StopStream(). */
@ -159,6 +158,18 @@ typedef struct PaMacCoreStream
//these may be different from the stream sample rate due to SR conversion:
double outDeviceSampleRate;
double inDeviceSampleRate;
/* data updated by main thread and notifications, protected by timingInformationMutex */
int timingInformationMutexIsInitialized;
pthread_mutex_t timingInformationMutex;
Float64 recipricalOfActualOutputSampleRate;
UInt32 deviceOutputLatencySamples;
UInt32 deviceInputLatencySamples;
/* while the io proc is active, the following values are only accessed and manipulated by the ioproc */
Float64 recipricalOfActualOutputSampleRate_ioProcCopy;
UInt32 deviceOutputLatencySamples_ioProcCopy;
UInt32 deviceInputLatencySamples_ioProcCopy;
}
PaMacCoreStream;

View File

@ -1,8 +1,8 @@
/*
* $Id: pa_mac_core_old.c 1083 2006-08-23 07:30:49Z rossb $
* pa_mac_core.c
* Implementation of PortAudio for Mac OS X CoreAudio
*
* Implementation of PortAudio for Mac OS X CoreAudio
*
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
*
@ -30,13 +30,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -67,7 +67,7 @@ typedef struct PaMacCore_HAR
PaUtilHostApiRepresentation inheritedHostApiRep;
PaUtilStreamInterface callbackStreamInterface;
PaUtilStreamInterface blockingStreamInterface;
PaUtilAllocationGroup *allocations;
AudioDeviceID *macCoreDeviceIds;
}
@ -85,28 +85,28 @@ typedef struct PaMacCore_S
PaUtilStreamRepresentation streamRepresentation;
PaUtilCpuLoadMeasurer cpuLoadMeasurer;
PaUtilBufferProcessor bufferProcessor;
int primeStreamUsingCallback;
AudioDeviceID inputDevice;
AudioDeviceID outputDevice;
// Processing thread management --------------
// HANDLE abortEvent;
// HANDLE processingThread;
// DWORD processingThreadId;
char throttleProcessingThreadOnOverload; // 0 -> don't throtte, non-0 -> throttle
int processingThreadPriority;
int highThreadPriority;
int throttledThreadPriority;
unsigned long throttledSleepMsecs;
int isStopped;
volatile int isActive;
volatile int stopProcessing; // stop thread once existing buffers have been returned
volatile int abortProcessing; // stop thread immediately
// DWORD allBuffersDurationMs; // used to calculate timeouts
}
PaMacCoreStream;
@ -136,7 +136,7 @@ PaMacClientData;
static PaError conv_err(OSStatus error)
{
PaError result;
switch (error) {
case kAudioHardwareNoError:
result = paNoError; break;
@ -163,7 +163,7 @@ static PaError conv_err(OSStatus error)
default:
result = paInternalError;
}
return result;
}
@ -175,7 +175,7 @@ static AudioStreamBasicDescription *InitializeStreamDescription(const PaStreamPa
streamDescription->mFormatID = kAudioFormatLinearPCM;
streamDescription->mFormatFlags = 0;
streamDescription->mFramesPerPacket = 1;
if (parameters->sampleFormat & paNonInterleaved) {
streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsNonInterleaved;
streamDescription->mChannelsPerFrame = 1;
@ -185,10 +185,10 @@ static AudioStreamBasicDescription *InitializeStreamDescription(const PaStreamPa
else {
streamDescription->mChannelsPerFrame = parameters->channelCount;
}
streamDescription->mBytesPerFrame = Pa_GetSampleSize(parameters->sampleFormat) * streamDescription->mChannelsPerFrame;
streamDescription->mBytesPerPacket = streamDescription->mBytesPerFrame * streamDescription->mFramesPerPacket;
if (parameters->sampleFormat & paFloat32) {
streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
streamDescription->mBitsPerChannel = 32;
@ -208,11 +208,11 @@ static AudioStreamBasicDescription *InitializeStreamDescription(const PaStreamPa
else if (parameters->sampleFormat & paInt8) {
streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
streamDescription->mBitsPerChannel = 8;
}
}
else if (parameters->sampleFormat & paInt32) {
streamDescription->mBitsPerChannel = 8;
}
return streamDescription;
}
*/
@ -220,11 +220,11 @@ static AudioStreamBasicDescription *InitializeStreamDescription(const PaStreamPa
static PaStreamCallbackTimeInfo *InitializeTimeInfo(const AudioTimeStamp* now, const AudioTimeStamp* inputTime, const AudioTimeStamp* outputTime)
{
PaStreamCallbackTimeInfo *timeInfo = PaUtil_AllocateMemory(sizeof(PaStreamCallbackTimeInfo));
timeInfo->inputBufferAdcTime = inputTime->mSampleTime;
timeInfo->currentTime = now->mSampleTime;
timeInfo->outputBufferDacTime = outputTime->mSampleTime;
return timeInfo;
}
@ -238,8 +238,8 @@ static void CleanUp(PaMacCoreHostApiRepresentation *macCoreHostApi)
PaUtil_FreeAllAllocations( macCoreHostApi->allocations );
PaUtil_DestroyAllocationGroup( macCoreHostApi->allocations );
}
PaUtil_FreeMemory( macCoreHostApi );
PaUtil_FreeMemory( macCoreHostApi );
}
static PaError GetChannelInfo(PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, int isInput)
@ -257,12 +257,12 @@ static PaError GetChannelInfo(PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDev
for (i = 0; i < buflist->mNumberBuffers; ++i) {
numChannels += buflist->mBuffers[i].mNumberChannels;
}
if (isInput)
deviceInfo->maxInputChannels = numChannels;
else
deviceInfo->maxOutputChannels = numChannels;
int frameLatency;
propSize = sizeof(UInt32);
err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyLatency, &propSize, &frameLatency));
@ -279,7 +279,7 @@ static PaError GetChannelInfo(PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDev
}
}
PaUtil_FreeMemory(buflist);
return err;
}
@ -288,7 +288,7 @@ static PaError InitializeDeviceInfo(PaMacCoreDeviceInfo *macCoreDeviceInfo, Aud
PaDeviceInfo *deviceInfo = &macCoreDeviceInfo->inheritedDeviceInfo;
deviceInfo->structVersion = 2;
deviceInfo->hostApi = hostApiIndex;
PaError err = paNoError;
UInt32 propSize;
@ -299,7 +299,7 @@ static PaError InitializeDeviceInfo(PaMacCoreDeviceInfo *macCoreDeviceInfo, Aud
if (!err) {
deviceInfo->name = name;
}
Float64 sampleRate;
propSize = sizeof(Float64);
err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &sampleRate));
@ -326,7 +326,7 @@ static PaError InitializeDeviceInfos( PaMacCoreHostApiRepresentation *macCoreHos
hostApi->info.deviceCount = 0;
hostApi->info.defaultInputDevice = paNoDevice;
hostApi->info.defaultOutputDevice = paNoDevice;
UInt32 propsize;
AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propsize, NULL);
int numDevices = propsize / sizeof(AudioDeviceID);
@ -346,7 +346,7 @@ static PaError InitializeDeviceInfos( PaMacCoreHostApiRepresentation *macCoreHos
{
return paInsufficientMemory;
}
macCoreHostApi->macCoreDeviceIds = PaUtil_GroupAllocateMemory(macCoreHostApi->allocations, propsize);
AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propsize, macCoreHostApi->macCoreDeviceIds);
@ -354,7 +354,7 @@ static PaError InitializeDeviceInfos( PaMacCoreHostApiRepresentation *macCoreHos
propsize = sizeof(AudioDeviceID);
AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &propsize, &defaultInputDevice);
AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &propsize, &defaultOutputDevice);
UInt32 i;
for (i = 0; i < numDevices; ++i) {
if (macCoreHostApi->macCoreDeviceIds[i] == defaultInputDevice) {
@ -364,7 +364,7 @@ static PaError InitializeDeviceInfos( PaMacCoreHostApiRepresentation *macCoreHos
hostApi->info.defaultOutputDevice = i;
}
InitializeDeviceInfo(&deviceInfoArray[i], macCoreHostApi->macCoreDeviceIds[i], hostApiIndex);
hostApi->deviceInfos[i] = &(deviceInfoArray[i].inheritedDeviceInfo);
hostApi->deviceInfos[i] = &(deviceInfoArray[i].inheritedDeviceInfo);
}
}
@ -402,7 +402,7 @@ static OSStatus CopyInputData(PaMacClientData* destination, const AudioBufferLis
frameSpacing = destination->inputChannelCount;
channelSpacing = 1;
}
AudioBuffer const *inputBuffer = &source->mBuffers[0];
void *coreAudioBuffer = inputBuffer->mData;
void *portAudioBuffer = destination->inputBuffer;
@ -432,7 +432,7 @@ static OSStatus CopyOutputData(AudioBufferList* destination, PaMacClientData *so
frameSpacing = source->outputChannelCount;
channelSpacing = 1;
}
AudioBuffer *outputBuffer = &destination->mBuffers[0];
void *coreAudioBuffer = outputBuffer->mData;
void *portAudioBuffer = source->outputBuffer;
@ -455,15 +455,15 @@ static OSStatus AudioIOProc( AudioDeviceID inDevice,
const AudioTimeStamp* inNow,
const AudioBufferList* inInputData,
const AudioTimeStamp* inInputTime,
AudioBufferList* outOutputData,
AudioBufferList* outOutputData,
const AudioTimeStamp* inOutputTime,
void* inClientData)
{
PaMacClientData *clientData = (PaMacClientData *)inClientData;
PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);
PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );
AudioBuffer *outputBuffer = &outOutputData->mBuffers[0];
unsigned long frameCount = outputBuffer->mDataByteSize / (outputBuffer->mNumberChannels * sizeof(Float32));
@ -476,7 +476,7 @@ static OSStatus AudioIOProc( AudioDeviceID inDevice,
}
PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
if (result == paComplete || result == paAbort) {
Pa_StopStream(clientData->stream);
}
@ -490,7 +490,7 @@ static OSStatus AudioInputProc( AudioDeviceID inDevice,
const AudioTimeStamp* inNow,
const AudioBufferList* inInputData,
const AudioTimeStamp* inInputTime,
AudioBufferList* outOutputData,
AudioBufferList* outOutputData,
const AudioTimeStamp* inOutputTime,
void* inClientData)
{
@ -504,7 +504,7 @@ static OSStatus AudioInputProc( AudioDeviceID inDevice,
CopyInputData(clientData, inInputData, frameCount);
PaStreamCallbackResult result = clientData->callback(clientData->inputBuffer, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);
PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
if( result == paComplete || result == paAbort )
Pa_StopStream(clientData->stream);
@ -517,7 +517,7 @@ static OSStatus AudioOutputProc( AudioDeviceID inDevice,
const AudioTimeStamp* inNow,
const AudioBufferList* inInputData,
const AudioTimeStamp* inInputTime,
AudioBufferList* outOutputData,
AudioBufferList* outOutputData,
const AudioTimeStamp* inOutputTime,
void* inClientData)
{
@ -540,18 +540,18 @@ static OSStatus AudioOutputProc( AudioDeviceID inDevice,
static PaError SetSampleRate(AudioDeviceID device, double sampleRate, int isInput)
{
PaError result = paNoError;
double actualSampleRate;
UInt32 propSize = sizeof(double);
result = conv_err(AudioDeviceSetProperty(device, NULL, 0, isInput, kAudioDevicePropertyNominalSampleRate, propSize, &sampleRate));
result = conv_err(AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyNominalSampleRate, &propSize, &actualSampleRate));
if (result == paNoError && actualSampleRate != sampleRate) {
result = paInvalidSampleRate;
}
return result;
return result;
}
static PaError SetFramesPerBuffer(AudioDeviceID device, unsigned long framesPerBuffer, int isInput)
@ -561,13 +561,13 @@ static PaError SetFramesPerBuffer(AudioDeviceID device, unsigned long framesPerB
// while (preferredFramesPerBuffer > UINT32_MAX) {
// preferredFramesPerBuffer /= 2;
// }
UInt32 actualFramesPerBuffer;
UInt32 propSize = sizeof(UInt32);
result = conv_err(AudioDeviceSetProperty(device, NULL, 0, isInput, kAudioDevicePropertyBufferFrameSize, propSize, &preferredFramesPerBuffer));
result = conv_err(AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propSize, &actualFramesPerBuffer));
if (result != paNoError) {
// do nothing
}
@ -577,10 +577,10 @@ static PaError SetFramesPerBuffer(AudioDeviceID device, unsigned long framesPerB
else if (actualFramesPerBuffer < framesPerBuffer) {
result = paBufferTooBig;
}
return result;
return result;
}
static PaError SetUpUnidirectionalStream(AudioDeviceID device, double sampleRate, unsigned long framesPerBuffer, int isInput)
{
PaError err = paNoError;
@ -597,9 +597,9 @@ static PaError SetUpUnidirectionalStream(AudioDeviceID device, double sampleRate
extern "C"
{
#endif // __cplusplus
PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
#ifdef __cplusplus
}
#endif // __cplusplus
@ -607,7 +607,7 @@ extern "C"
static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
{
PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation*)hostApi;
CleanUp(macCoreHostApi);
}
@ -618,7 +618,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
{
PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation*)hostApi;
PaDeviceInfo *deviceInfo;
PaError result = paNoError;
if (inputParameters) {
deviceInfo = macCoreHostApi->inheritedHostApiRep.deviceInfos[inputParameters->device];
@ -657,14 +657,14 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
stream->isStopped = 1;
stream->inputDevice = kAudioDeviceUnknown;
stream->outputDevice = kAudioDeviceUnknown;
PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
( (streamCallback)
? &macCoreHostApi->callbackStreamInterface
: &macCoreHostApi->blockingStreamInterface ),
streamCallback, userData );
PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
*s = (PaStream*)stream;
PaMacClientData *clientData = PaUtil_AllocateMemory(sizeof(PaMacClientData));
clientData->stream = stream;
@ -674,7 +674,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
clientData->outputBuffer = 0;
clientData->ditherGenerator = PaUtil_AllocateMemory(sizeof(PaUtilTriangularDitherGenerator));
PaUtil_InitializeTriangularDitherState(clientData->ditherGenerator);
if (inputParameters != NULL) {
stream->inputDevice = macCoreHostApi->macCoreDeviceIds[inputParameters->device];
clientData->inputConverter = PaUtil_SelectConverter(paFloat32, inputParameters->sampleFormat, streamFlags);
@ -683,7 +683,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
clientData->inputSampleFormat = inputParameters->sampleFormat;
err = SetUpUnidirectionalStream(stream->inputDevice, sampleRate, framesPerBuffer, 1);
}
if (err == paNoError && outputParameters != NULL) {
stream->outputDevice = macCoreHostApi->macCoreDeviceIds[outputParameters->device];
clientData->outputConverter = PaUtil_SelectConverter(outputParameters->sampleFormat, paFloat32, streamFlags);
@ -703,7 +703,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
AudioDeviceAddIOProc(stream->inputDevice, AudioInputProc, clientData);
AudioDeviceAddIOProc(stream->outputDevice, AudioOutputProc, clientData);
}
return err;
}
@ -727,7 +727,7 @@ static PaError CloseStream( PaStream* s )
else {
err = conv_err(AudioDeviceRemoveIOProc(stream->outputDevice, AudioIOProc));
}
return err;
}
@ -749,7 +749,7 @@ static PaError StartStream( PaStream *s )
else {
err = conv_err(AudioDeviceStart(stream->outputDevice, AudioIOProc));
}
stream->isActive = 1;
stream->isStopped = 0;
return err;
@ -759,7 +759,7 @@ static PaError AbortStream( PaStream *s )
{
PaError err = paNoError;
PaMacCoreStream *stream = (PaMacCoreStream*)s;
if (stream->inputDevice != kAudioDeviceUnknown) {
if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
err = conv_err(AudioDeviceStop(stream->inputDevice, AudioIOProc));
@ -772,11 +772,11 @@ static PaError AbortStream( PaStream *s )
else {
err = conv_err(AudioDeviceStop(stream->outputDevice, AudioIOProc));
}
stream->isActive = 0;
stream->isStopped = 1;
return err;
}
}
static PaError StopStream( PaStream *s )
{
@ -787,7 +787,7 @@ static PaError StopStream( PaStream *s )
static PaError IsStreamStopped( PaStream *s )
{
PaMacCoreStream *stream = (PaMacCoreStream*)s;
return stream->isStopped;
}
@ -813,7 +813,7 @@ static PaTime GetStreamTime( PaStream *s )
else {
err = AudioDeviceGetCurrentTime(stream->outputDevice, timeStamp);
}
result = err ? 0 : timeStamp->mSampleTime;
PaUtil_FreeMemory(timeStamp);
@ -824,7 +824,7 @@ static PaTime GetStreamTime( PaStream *s )
static double GetStreamCpuLoad( PaStream* s )
{
PaMacCoreStream *stream = (PaMacCoreStream*)s;
return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
}
@ -868,14 +868,14 @@ PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIn
result = paInsufficientMemory;
goto error;
}
macCoreHostApi->allocations = PaUtil_CreateAllocationGroup();
if( !macCoreHostApi->allocations )
{
result = paInsufficientMemory;
goto error;
}
*hostApi = &macCoreHostApi->inheritedHostApiRep;
(*hostApi)->info.structVersion = 1;
(*hostApi)->info.type = paCoreAudio;
@ -885,29 +885,29 @@ PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIn
if (result != paNoError) {
goto error;
}
// Set up the proper callbacks to this HostApi's functions
(*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported;
PaUtil_InitializeStreamInterface( &macCoreHostApi->callbackStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive,
GetStreamTime, GetStreamCpuLoad,
PaUtil_DummyRead, PaUtil_DummyWrite,
PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
PaUtil_InitializeStreamInterface( &macCoreHostApi->blockingStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive,
GetStreamTime, PaUtil_DummyGetCpuLoad,
ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
return result;
error:
if( macCoreHostApi ) {
CleanUp(macCoreHostApi);
}
return result;
}

View File

@ -15,7 +15,7 @@
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, Phil Burk
@ -41,13 +41,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -97,16 +97,16 @@ PaError PaMacCore_SetError(OSStatus error, int line, int isError)
/*FIXME: still need to handle possible ComponentResult values.*/
/* unfortunately, they don't seem to be documented anywhere.*/
PaError result;
const char *errorType;
const char *errorType;
const char *errorText;
switch (error) {
case kAudioHardwareNoError:
return paNoError;
case kAudioHardwareNotRunningError:
errorText = "Audio Hardware Not Running";
result = paInternalError; break;
case kAudioHardwareUnspecifiedError:
case kAudioHardwareUnspecifiedError:
errorText = "Unspecified Audio Hardware Error";
result = paInternalError; break;
case kAudioHardwareUnknownPropertyError:
@ -115,7 +115,7 @@ PaError PaMacCore_SetError(OSStatus error, int line, int isError)
case kAudioHardwareBadPropertySizeError:
errorText = "Audio Hardware: Bad Property Size";
result = paInternalError; break;
case kAudioHardwareIllegalOperationError:
case kAudioHardwareIllegalOperationError:
errorText = "Audio Hardware: Illegal Operation";
result = paInternalError; break;
case kAudioHardwareBadDeviceError:
@ -261,7 +261,7 @@ long computeRingBufferSize( const PaStreamParameters *inputParameters,
framesPerBufferTimesChannelCount = MAX(
inputFramesPerBuffer * inputParameters->channelCount,
outputFramesPerBuffer * outputParameters->channelCount );
}
}
else if( outputParameters )
{
latencyTimesChannelCount
@ -316,17 +316,17 @@ long computeRingBufferSize( const PaStreamParameters *inputParameters,
*/
OSStatus propertyProc(
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
void* inClientData )
{
// this is where we would set the condition variable
return noErr;
}
/* sets the value of the given property and waits for the change to
/* sets the value of the given property and waits for the change to
be acknowledged, and returns the final value, which is not guaranteed
by this function to be the same as the desired value. Obviously, this
function can only be used for data whose input and output are the
@ -337,10 +337,10 @@ OSStatus propertyProc(
determining if the property was read. */
PaError AudioDeviceSetPropertyNowAndWaitForChange(
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
UInt32 inPropertyDataSize,
UInt32 inPropertyDataSize,
const void *inPropertyData,
void *outPropertyData )
{
@ -349,7 +349,7 @@ PaError AudioDeviceSetPropertyNowAndWaitForChange(
/* First, see if it already has that value. If so, return. */
macErr = AudioDeviceGetProperty( inDevice, inChannel,
isInput, inPropertyID,
isInput, inPropertyID,
&outPropertyDataSize, outPropertyData );
if( macErr ) {
memset( outPropertyData, 0, inPropertyDataSize );
@ -367,7 +367,7 @@ PaError AudioDeviceSetPropertyNowAndWaitForChange(
but for now, this is just to make 10.6 happy. */
macErr = AudioDeviceAddPropertyListener( inDevice, inChannel, isInput,
inPropertyID, propertyProc,
NULL );
NULL );
if( macErr )
/* we couldn't add a listener. */
goto failMac;
@ -389,7 +389,7 @@ PaError AudioDeviceSetPropertyNowAndWaitForChange(
while( tv2.tv_sec - tv1.tv_sec < 30 ) {
/* now read the property back out */
macErr = AudioDeviceGetProperty( inDevice, inChannel,
isInput, inPropertyID,
isInput, inPropertyID,
&outPropertyDataSize, outPropertyData );
if( macErr ) {
memset( outPropertyData, 0, inPropertyDataSize );
@ -405,7 +405,7 @@ PaError AudioDeviceSetPropertyNowAndWaitForChange(
gettimeofday( &tv2, NULL );
}
DBUG( ("Timeout waiting for device setting.\n" ) );
AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc );
return paNoError;
@ -481,7 +481,7 @@ PaError setBestSampleRateForDevice( const AudioDeviceID device,
(float) ranges[i].mMaximum ) );
#endif
VDBUG(("-----\n"));
/* -- now pick the best available sample rate -- */
for( i=0; i<propsize/sizeof(AudioValueRange); ++i )
{
@ -529,7 +529,7 @@ PaError setBestSampleRateForDevice( const AudioDeviceID device,
*/
PaError setBestFramesPerBuffer( const AudioDeviceID device,
const bool isOutput,
UInt32 requestedFramesPerBuffer,
UInt32 requestedFramesPerBuffer,
UInt32 *actualFramesPerBuffer )
{
UInt32 afpb;
@ -584,7 +584,7 @@ PaError setBestFramesPerBuffer( const AudioDeviceID device,
(float) ranges[i].mMaximum ) );
#endif
VDBUG(("-----\n"));
/* --- now pick the best available framesPerBuffer -- */
for( i=0; i<propsize/sizeof(AudioValueRange); ++i )
{
@ -638,10 +638,10 @@ static int xRunListSize;
static pthread_mutex_t xrunMutex;
OSStatus xrunCallback(
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
void* inClientData)
{
PaMacXRunListNode *node = (PaMacXRunListNode *) inClientData;

View File

@ -15,7 +15,7 @@
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, Phil Burk
@ -41,13 +41,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -73,7 +73,7 @@
#define MAX(a, b) (((a)<(b))?(b):(a))
#endif
#define ERR(mac_error) PaMacCore_SetError(mac_error, __LINE__, 1 )
#define ERR(mac_error) PaMacCore_SetError(mac_error, __LINE__, 1 )
#define WARNING(mac_error) PaMacCore_SetError(mac_error, __LINE__, 0 )
@ -144,23 +144,23 @@ long computeRingBufferSize( const PaStreamParameters *inputParameters,
double sampleRate );
OSStatus propertyProc(
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
void* inClientData );
/* sets the value of the given property and waits for the change to
/* sets the value of the given property and waits for the change to
be acknowledged, and returns the final value, which is not guaranteed
by this function to be the same as the desired value. Obviously, this
function can only be used for data whose input and output are the
same size and format, and their size and format are known in advance.*/
PaError AudioDeviceSetPropertyNowAndWaitForChange(
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
UInt32 inPropertyDataSize,
UInt32 inPropertyDataSize,
const void *inPropertyData,
void *outPropertyData );
@ -188,7 +188,7 @@ PaError setBestSampleRateForDevice( const AudioDeviceID device,
*/
PaError setBestFramesPerBuffer( const AudioDeviceID device,
const bool isOutput,
UInt32 requestedFramesPerBuffer,
UInt32 requestedFramesPerBuffer,
UInt32 *actualFramesPerBuffer );
@ -199,10 +199,10 @@ PaError setBestFramesPerBuffer( const AudioDeviceID device,
*********************/
OSStatus xrunCallback(
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
void* inClientData ) ;
/** returns zero on success or a unix style error code. */

View File

@ -1,5 +1,5 @@
/*
* $Id: pa_win_ds.c 1450 2010-02-03 00:28:29Z rossb $
* $Id: pa_win_ds.c 1534 2010-08-03 21:02:52Z dmitrykos $
* Portable Audio I/O Library DirectSound implementation
*
* Authors: Phil Burk, Robert Marsanyi & Ross Bencina
@ -27,13 +27,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -41,7 +41,7 @@
@ingroup hostapi_src
@todo implement paInputOverflow callback status flag
@todo implement paNeverDropInput.
@todo implement host api specific extension to set i/o buffer sizes in frames
@ -244,7 +244,7 @@ typedef struct PaWinDsStream
/* Try to detect play buffer underflows. */
LARGE_INTEGER perfCounterTicksPerBuffer; /* counter ticks it should take to play a full buffer */
LARGE_INTEGER previousPlayTime;
UINT previousPlayCursor;
DWORD previousPlayCursor;
UINT outputUnderflowCount;
BOOL outputIsRunning;
INT finalZeroBytesWritten; /* used to determine when we've flushed the whole buffer */
@ -256,7 +256,7 @@ typedef struct PaWinDsStream
UINT readOffset; /* last read position */
UINT inputSize;
MMRESULT timerID;
int framesPerDSBuffer;
double framesWritten;
@ -267,7 +267,7 @@ typedef struct PaWinDsStream
PaStreamFlags streamFlags;
int callbackResult;
HANDLE processingCompleted;
/* FIXME - move all below to PaUtilStreamRepresentation */
volatile int isStarted;
volatile int isActive;
@ -284,7 +284,7 @@ typedef struct PaWinDsStream
static char *DuplicateDeviceNameString( PaUtilAllocationGroup *allocations, const char* src )
{
char *result = 0;
if( src != NULL )
{
size_t len = strlen(src);
@ -341,7 +341,7 @@ static PaError InitializeDSDeviceNameAndGUIDVector(
guidVector->items = (DSDeviceNameAndGUID*)LocalAlloc( LMEM_FIXED, sizeof(DSDeviceNameAndGUID) * guidVector->free );
if( guidVector->items == NULL )
result = paInsufficientMemory;
return result;
}
@ -350,7 +350,7 @@ static PaError ExpandDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidV
PaError result = paNoError;
DSDeviceNameAndGUID *newItems;
int i;
/* double size of vector */
int size = guidVector->count + guidVector->free;
guidVector->free += size;
@ -379,7 +379,7 @@ static PaError ExpandDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidV
LocalFree( guidVector->items );
guidVector->items = newItems;
}
}
return result;
}
@ -403,7 +403,7 @@ static PaError TerminateDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *gu
}
/************************************************************************************
** Collect preliminary device information during DirectSound enumeration
** Collect preliminary device information during DirectSound enumeration
*/
static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID,
LPCTSTR lpszDesc,
@ -424,7 +424,7 @@ static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID,
return FALSE;
}
}
/* Set GUID pointer, copy GUID to storage in DSDeviceNameAndGUIDVector. */
if( lpGUID == NULL )
{
@ -434,7 +434,7 @@ static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID,
{
namesAndGUIDs->items[namesAndGUIDs->count].lpGUID =
&namesAndGUIDs->items[namesAndGUIDs->count].guid;
memcpy( &namesAndGUIDs->items[namesAndGUIDs->count].guid, lpGUID, sizeof(GUID) );
}
@ -450,7 +450,7 @@ static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID,
++namesAndGUIDs->count;
--namesAndGUIDs->free;
return TRUE;
}
@ -479,7 +479,7 @@ static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVI
if( deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID
&& memcmp( &data->DeviceId, deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 )
{
deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].pnpInterface =
deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].pnpInterface =
(char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface );
break;
}
@ -492,7 +492,7 @@ static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVI
if( deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID
&& memcmp( &data->DeviceId, deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 )
{
deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].pnpInterface =
deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].pnpInterface =
(char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface );
break;
}
@ -503,13 +503,13 @@ static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVI
}
static GUID pawin_CLSID_DirectSoundPrivate =
static GUID pawin_CLSID_DirectSoundPrivate =
{ 0x11ab3ec0, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x00, 0xc0, 0x4f, 0xc2, 0x8a, 0xca };
static GUID pawin_DSPROPSETID_DirectSoundDevice =
static GUID pawin_DSPROPSETID_DirectSoundDevice =
{ 0x84624f82, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x00, 0xc0, 0x4f, 0xc2, 0x8a, 0xca };
static GUID pawin_IID_IKsPropertySet =
static GUID pawin_IID_IKsPropertySet =
{ 0x31efac30, 0x515c, 0x11d0, 0xa9, 0xaa, 0x00, 0xaa, 0x00, 0x61, 0xbe, 0x93 };
@ -517,17 +517,17 @@ static GUID pawin_IID_IKsPropertySet =
FindDevicePnpInterfaces fills in the pnpInterface fields in deviceNamesAndGUIDs
with UNICODE file paths to the devices. The DS documentation mentions
at least two techniques by which these Interface paths can be found using IKsPropertySet on
the DirectSound class object. One is using the DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION
the DirectSound class object. One is using the DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION
property, and the other is using DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE.
I tried both methods and only the second worked. I found two postings on the
net from people who had the same problem with the first method, so I think the method used here is
net from people who had the same problem with the first method, so I think the method used here is
more common/likely to work. The probem is that IKsPropertySet_Get returns S_OK
but the fields of the device description are not filled in.
The mechanism we use works by registering an enumeration callback which is called for
The mechanism we use works by registering an enumeration callback which is called for
every DSound device. Our callback searches for a device in our deviceNamesAndGUIDs list
with the matching GUID and copies the pointer to the Interface path.
Note that we could have used this enumeration callback to perform the original
Note that we could have used this enumeration callback to perform the original
device enumeration, however we choose not to so we can disable this step easily.
Apparently the IKsPropertySet mechanism was added in DirectSound 9c 2004
@ -538,11 +538,11 @@ static GUID pawin_IID_IKsPropertySet =
static void FindDevicePnpInterfaces( DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs )
{
IClassFactory *pClassFactory;
if( paWinDsDSoundEntryPoints.DllGetClassObject(&pawin_CLSID_DirectSoundPrivate, &IID_IClassFactory, (PVOID *) &pClassFactory) == S_OK ){
IKsPropertySet *pPropertySet;
if( pClassFactory->lpVtbl->CreateInstance( pClassFactory, NULL, &pawin_IID_IKsPropertySet, (PVOID *) &pPropertySet) == S_OK ){
DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
ULONG bytesReturned;
@ -558,14 +558,14 @@ static void FindDevicePnpInterfaces( DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs
sizeof(data),
&bytesReturned
);
IKsPropertySet_Release( pPropertySet );
}
pClassFactory->lpVtbl->Release( pClassFactory );
}
/*
The following code fragment, which I chose not to use, queries for the
The following code fragment, which I chose not to use, queries for the
device interface for a device with a specific GUID:
ULONG BytesReturned;
@ -573,7 +573,7 @@ static void FindDevicePnpInterfaces( DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs
memset (&Property, 0, sizeof(Property));
Property.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
Property.DeviceId = *lpGUID;
Property.DeviceId = *lpGUID;
hr = IKsPropertySet_Get( pPropertySet,
&pawin_DSPROPSETID_DirectSoundDevice,
@ -594,7 +594,7 @@ static void FindDevicePnpInterfaces( DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
/*
/*
GUIDs for emulated devices which we blacklist below.
are there more than two of them??
*/
@ -638,7 +638,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) );
winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid;
}
if( lpGUID )
{
if (IsEqualGUID (&IID_IRolandVSCEmulated1,lpGUID) ||
@ -669,7 +669,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
hr = IDirectSound_Initialize( lpDirectSound, lpGUID );
}
*/
if( hr != DS_OK )
{
if (hr == DSERR_ALLOCATED)
@ -695,7 +695,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
else
{
/* Query device characteristics. */
memset( &caps, 0, sizeof(caps) );
memset( &caps, 0, sizeof(caps) );
caps.dwSize = sizeof(caps);
hr = IDirectSound_GetCaps( lpDirectSound, &caps );
if( hr != DS_OK )
@ -726,7 +726,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
set deviceOutputChannelCountIsKnown to 0 (unknown).
In this case OpenStream will try to open the device
when the user requests more than 2 channels, rather than
returning an error.
returning an error.
*/
if( caps.dwFlags & DSCAPS_PRIMARYSTEREO )
{
@ -739,7 +739,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
winDsDeviceInfo->deviceOutputChannelCountIsKnown = 1;
}
/* Guess channels count from speaker configuration. We do it only when
/* Guess channels count from speaker configuration. We do it only when
pnpInterface is NULL or when PAWIN_USE_WDMKS_DEVICE_INFO is undefined.
*/
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
@ -792,9 +792,9 @@ static PaError AddOutputDeviceInfoFromDirectSound(
deviceInfo->defaultLowOutputLatency = 0.; /** @todo IMPLEMENT ME */
deviceInfo->defaultHighInputLatency = 0.; /** @todo IMPLEMENT ME */
deviceInfo->defaultHighOutputLatency = 0.; /** @todo IMPLEMENT ME */
/* initialize defaultSampleRate */
if( caps.dwFlags & DSCAPS_CONTINUOUSRATE )
{
/* initialize to caps.dwMaxSecondarySampleRate incase none of the standard rates match */
@ -841,7 +841,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
//printf( "min %d max %d\n", caps.dwMinSecondarySampleRate, caps.dwMaxSecondarySampleRate );
// dwFlags | DSCAPS_CONTINUOUSRATE
// dwFlags | DSCAPS_CONTINUOUSRATE
}
}
@ -854,7 +854,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
if( lpGUID == NULL )
hostApi->info.defaultOutputDevice = hostApi->info.deviceCount;
hostApi->info.deviceCount++;
}
@ -880,7 +880,7 @@ static PaError AddInputDeviceInfoFromDirectSoundCapture(
DSCCAPS caps;
int deviceOK = TRUE;
PaError result = paNoError;
/* Copy GUID to the device info structure. Set pointer. */
if( lpGUID == NULL )
{
@ -1016,7 +1016,7 @@ static PaError AddInputDeviceInfoFromDirectSoundCapture(
else deviceInfo->defaultSampleRate = 0.;
}
}
IDirectSoundCapture_Release( lpDirectSoundCapture );
}
@ -1049,7 +1049,7 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
If COM is already initialized CoInitialize will either return
FALSE, or RPC_E_CHANGED_MODE if it was initialised in a different
threading mode. In either case we shouldn't consider it an error
but we need to be careful to not call CoUninitialize() if
but we need to be careful to not call CoUninitialize() if
RPC_E_CHANGED_MODE was returned.
*/
@ -1087,12 +1087,12 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
(*hostApi)->info.structVersion = 1;
(*hostApi)->info.type = paDirectSound;
(*hostApi)->info.name = "Windows DirectSound";
(*hostApi)->info.deviceCount = 0;
(*hostApi)->info.defaultInputDevice = paNoDevice;
(*hostApi)->info.defaultOutputDevice = paNoDevice;
/* DSound - enumerate devices to count them and to gather their GUIDs */
result = InitializeDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs, winDsHostApi->allocations );
@ -1177,7 +1177,7 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
if( result != paNoError )
goto error;
}
}
}
result = TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs );
if( result != paNoError )
@ -1187,7 +1187,7 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
if( result != paNoError )
goto error;
(*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported;
@ -1213,7 +1213,7 @@ error:
PaUtil_FreeAllAllocations( winDsHostApi->allocations );
PaUtil_DestroyAllocationGroup( winDsHostApi->allocations );
}
PaUtil_FreeMemory( winDsHostApi );
}
@ -1349,7 +1349,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
outputChannelCount = outputParameters->channelCount;
outputSampleFormat = outputParameters->sampleFormat;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
@ -1370,7 +1370,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
{
outputChannelCount = 0;
}
/*
IMPLEMENT ME:
@ -1439,12 +1439,12 @@ static int PaWinDs_GetMinLatencyFrames( double sampleRate )
static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
PaWinDsDeviceInfo *inputDevice,
PaSampleFormat hostInputSampleFormat,
WORD inputChannelCount,
WORD inputChannelCount,
int bytesPerInputBuffer,
PaWinWaveFormatChannelMask inputChannelMask,
PaWinDsDeviceInfo *outputDevice,
PaSampleFormat hostOutputSampleFormat,
WORD outputChannelCount,
WORD outputChannelCount,
int bytesPerOutputBuffer,
PaWinWaveFormatChannelMask outputChannelMask,
unsigned long nFrameRate
@ -1461,7 +1461,7 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
// capture buffer description
// only try wave format extensible. assume it's available on all ds 8 systems
PaWin_InitializeWaveFormatExtensible( &captureWaveFormat, inputChannelCount,
PaWin_InitializeWaveFormatExtensible( &captureWaveFormat, inputChannelCount,
hostInputSampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( hostInputSampleFormat ),
nFrameRate, inputChannelMask );
@ -1473,7 +1473,7 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
// render buffer description
PaWin_InitializeWaveFormatExtensible( &renderWaveFormat, outputChannelCount,
PaWin_InitializeWaveFormatExtensible( &renderWaveFormat, outputChannelCount,
hostOutputSampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( hostOutputSampleFormat ),
nFrameRate, outputChannelMask );
@ -1485,7 +1485,7 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
/* note that we don't create a primary buffer here at all */
hr = paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8(
hr = paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8(
inputDevice->lpGUID, outputDevice->lpGUID,
&captureDesc, &secondaryRenderDesc,
GetDesktopWindow(), /* see InitOutputBuffer() for a discussion of whether this is a good idea */
@ -1493,7 +1493,7 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
&stream->pDirectSoundFullDuplex8,
&pCaptureBuffer8,
&pRenderBuffer8,
NULL /* pUnkOuter must be NULL */
NULL /* pUnkOuter must be NULL */
);
if( hr == DS_OK )
@ -1502,10 +1502,10 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
/* retrieve the pre ds 8 buffer interfaces which are used by the rest of the code */
hr = IUnknown_QueryInterface( pCaptureBuffer8, &IID_IDirectSoundCaptureBuffer, &stream->pDirectSoundInputBuffer );
hr = IUnknown_QueryInterface( pCaptureBuffer8, &IID_IDirectSoundCaptureBuffer, (LPVOID *)&stream->pDirectSoundInputBuffer );
if( hr == DS_OK )
hr = IUnknown_QueryInterface( pRenderBuffer8, &IID_IDirectSoundBuffer, &stream->pDirectSoundOutputBuffer );
hr = IUnknown_QueryInterface( pRenderBuffer8, &IID_IDirectSoundBuffer, (LPVOID *)&stream->pDirectSoundOutputBuffer );
/* release the ds 8 interfaces, we don't need them */
IUnknown_Release( pCaptureBuffer8 );
@ -1524,7 +1524,7 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
IUnknown_Release( stream->pDirectSoundOutputBuffer );
stream->pDirectSoundOutputBuffer = NULL;
}
IUnknown_Release( stream->pDirectSoundFullDuplex8 );
stream->pDirectSoundFullDuplex8 = NULL;
}
@ -1544,8 +1544,8 @@ static HRESULT InitInputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *device
DSCBUFFERDESC captureDesc;
PaWinWaveFormat waveFormat;
HRESULT result;
if( (result = paWinDsDSoundEntryPoints.DirectSoundCaptureCreate(
if( (result = paWinDsDSoundEntryPoints.DirectSoundCaptureCreate(
device->lpGUID, &stream->pDirectSoundCapture, NULL) ) != DS_OK ){
ERR_RPT(("PortAudio: DirectSoundCaptureCreate() failed!\n"));
return result;
@ -1557,18 +1557,18 @@ static HRESULT InitInputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *device
captureDesc.dwFlags = 0;
captureDesc.dwBufferBytes = bytesPerBuffer;
captureDesc.lpwfxFormat = (WAVEFORMATEX*)&waveFormat;
// Create the capture buffer
// first try WAVEFORMATEXTENSIBLE. if this fails, fall back to WAVEFORMATEX
PaWin_InitializeWaveFormatExtensible( &waveFormat, nChannels,
PaWin_InitializeWaveFormatExtensible( &waveFormat, nChannels,
sampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ),
nFrameRate, channelMask );
if( IDirectSoundCapture_CreateCaptureBuffer( stream->pDirectSoundCapture,
&captureDesc, &stream->pDirectSoundInputBuffer, NULL) != DS_OK )
{
PaWin_InitializeWaveFormatEx( &waveFormat, nChannels, sampleFormat,
PaWin_InitializeWaveFormatEx( &waveFormat, nChannels, sampleFormat,
PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ), nFrameRate );
if ((result = IDirectSoundCapture_CreateCaptureBuffer( stream->pDirectSoundCapture,
@ -1588,8 +1588,8 @@ static HRESULT InitOutputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *devic
PaWinWaveFormat waveFormat;
DSBUFFERDESC primaryDesc;
DSBUFFERDESC secondaryDesc;
if( (hr = paWinDsDSoundEntryPoints.DirectSoundCreate(
if( (hr = paWinDsDSoundEntryPoints.DirectSoundCreate(
device->lpGUID, &stream->pDirectSound, NULL )) != DS_OK ){
ERR_RPT(("PortAudio: DirectSoundCreate() failed!\n"));
return hr;
@ -1632,13 +1632,13 @@ static HRESULT InitOutputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *devic
// Set the primary buffer's format
// first try WAVEFORMATEXTENSIBLE. if this fails, fall back to WAVEFORMATEX
PaWin_InitializeWaveFormatExtensible( &waveFormat, nChannels,
PaWin_InitializeWaveFormatExtensible( &waveFormat, nChannels,
sampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ),
nFrameRate, channelMask );
if( IDirectSoundBuffer_SetFormat( stream->pDirectSoundPrimaryBuffer, (WAVEFORMATEX*)&waveFormat) != DS_OK )
{
PaWin_InitializeWaveFormatEx( &waveFormat, nChannels, sampleFormat,
PaWin_InitializeWaveFormatEx( &waveFormat, nChannels, sampleFormat,
PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ), nFrameRate );
if((result = IDirectSoundBuffer_SetFormat( stream->pDirectSoundPrimaryBuffer, (WAVEFORMATEX*)&waveFormat)) != DS_OK)
@ -1656,7 +1656,7 @@ static HRESULT InitOutputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *devic
if ((result = IDirectSound_CreateSoundBuffer( stream->pDirectSound,
&secondaryDesc, &stream->pDirectSoundOutputBuffer, NULL)) != DS_OK)
goto error;
return DS_OK;
error:
@ -1708,7 +1708,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
/* IDEA: the following 3 checks could be performed by default by pa_front
unless some flag indicated otherwise */
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
@ -1718,7 +1718,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
if( inputWinDsDeviceInfo->deviceInputChannelCountIsKnown
&& inputChannelCount > inputDeviceInfo->maxInputChannels )
return paInvalidChannelCount;
/* validate hostApiSpecificStreamInfo */
inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
@ -1759,7 +1759,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
/* validate hostApiSpecificStreamInfo */
outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
if( result != paNoError ) return result;
if( result != paNoError ) return result;
if( outputStreamInfo && outputStreamInfo->flags & paWinDirectSoundUseChannelMask )
outputChannelMask = outputStreamInfo->channelMask;
@ -1823,7 +1823,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
&winDsHostApi->blockingStreamInterface, streamCallback, userData );
}
streamRepresentationIsInitialized = 1;
stream->streamFlags = streamFlags;
@ -1878,15 +1878,15 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor); /* FIXME: not initialised anywhere else */
stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
/* DirectSound specific initialization */
/* DirectSound specific initialization */
{
HRESULT hr;
int bytesPerDirectSoundInputBuffer, bytesPerDirectSoundOutputBuffer;
int userLatencyFrames;
int minLatencyFrames;
unsigned long integerSampleRate = (unsigned long) (sampleRate + 0.5);
stream->timerID = 0;
stream->processingCompleted = CreateEvent( NULL, /* bManualReset = */ TRUE, /* bInitialState = */ FALSE, NULL );
@ -1941,7 +1941,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ outputParameters->device ];
DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", outputParameters->device));
*/
int bytesPerSample = Pa_GetSampleSize(hostOutputSampleFormat);
bytesPerDirectSoundOutputBuffer = stream->framesPerDSBuffer * outputParameters->channelCount * bytesPerSample;
if( bytesPerDirectSoundOutputBuffer < DSBSIZE_MIN )
@ -1983,7 +1983,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ inputParameters->device ];
DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", inputParameters->device));
*/
int bytesPerSample = Pa_GetSampleSize(hostInputSampleFormat);
bytesPerDirectSoundInputBuffer = stream->framesPerDSBuffer * inputParameters->channelCount * bytesPerSample;
if( bytesPerDirectSoundInputBuffer < DSBSIZE_MIN )
@ -2010,7 +2010,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
assert( stream->pDirectSound == NULL );
assert( stream->pDirectSoundPrimaryBuffer == NULL );
assert( stream->pDirectSoundOutputBuffer == NULL );
if( inputParameters && outputParameters )
{
@ -2030,14 +2030,14 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
integerSampleRate
);
DBUG(("InitFullDuplexInputOutputBuffers() returns %x\n", hr));
/* ignore any error returned by InitFullDuplexInputOutputBuffers.
/* ignore any error returned by InitFullDuplexInputOutputBuffers.
we retry opening the buffers below */
#endif /* PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE */
}
/* create half duplex buffers. also used for full-duplex streams which didn't
/* create half duplex buffers. also used for full-duplex streams which didn't
succeed when using the full duplex API. that could happen because
DX8 or greater isnt installed, the i/o devices aren't the same
DX8 or greater isnt installed, the i/o devices aren't the same
physical device. etc.
*/
@ -2205,11 +2205,11 @@ static HRESULT QueryOutputSpace( PaWinDsStream *stream, long *bytesEmpty )
/*
From MSDN:
The write cursor indicates the position at which it is safe
The write cursor indicates the position at which it is safe
to write new data to the buffer. The write cursor always leads the
play cursor, typically by about 15 milliseconds' worth of audio
data.
It is always safe to change data that is behind the position
It is always safe to change data that is behind the position
indicated by the lpdwCurrentPlayCursor parameter.
*/
@ -2234,7 +2234,7 @@ static int TimeSlice( PaWinDsStream *stream )
HRESULT hresult;
double outputLatency = 0;
PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement inputBufferAdcTime */
/* Input */
LPBYTE lpInBuf1 = NULL;
LPBYTE lpInBuf2 = NULL;
@ -2265,7 +2265,7 @@ static int TimeSlice( PaWinDsStream *stream )
}
// FIXME: what happens if IDirectSoundCaptureBuffer_GetCurrentPosition fails?
framesToXfer = numInFramesReady = bytesFilled / stream->bytesPerInputFrame;
framesToXfer = numInFramesReady = bytesFilled / stream->bytesPerInputFrame;
outputLatency = ((double)bytesFilled) * stream->secondsPerHostByte; // FIXME: this doesn't look right. we're calculating output latency in input branch. also secondsPerHostByte is only initialized for the output stream
/** @todo Check for overflow */
@ -2301,7 +2301,7 @@ static int TimeSlice( PaWinDsStream *stream )
PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, stream->callbackFlags );
stream->callbackFlags = 0;
/* Input */
if( stream->bufferProcessor.inputChannelCount > 0 )
{
@ -2363,7 +2363,7 @@ static int TimeSlice( PaWinDsStream *stream )
numFrames = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &stream->callbackResult );
stream->framesWritten += numFrames;
if( stream->bufferProcessor.outputChannelCount > 0 )
{
/* FIXME: an underflow could happen here */
@ -2386,7 +2386,7 @@ error1:
}
error2:
PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, numFrames );
PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, numFrames );
}
if( stream->callbackResult == paComplete && !PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) )
@ -2444,7 +2444,7 @@ static void CALLBACK TimerCallback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD
(void) uMsg;
(void) dw1;
(void) dw2;
stream = (PaWinDsStream *) dwUser;
if( stream == NULL ) return;
@ -2475,8 +2475,8 @@ static void CALLBACK TimerCallback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD
int callbackResult = TimeSlice( stream );
if( callbackResult != paContinue )
{
/* FIXME implement handling of paComplete and paAbort if possible
At the moment this should behave as if paComplete was called and
/* FIXME implement handling of paComplete and paAbort if possible
At the moment this should behave as if paComplete was called and
flush the buffer.
*/
@ -2577,7 +2577,7 @@ static HRESULT ClearOutputBuffer( PaWinDsStream *stream )
// Unlock the DS buffer
if ((hr = IDirectSoundBuffer_Unlock( stream->pDirectSoundOutputBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK)
return hr;
// Let DSound set the starting write position because if we set it to zero, it looks like the
// buffer is full to begin with. This causes a long pause before sound starts when using large buffers.
if ((hr = IDirectSoundBuffer_GetCurrentPosition( stream->pDirectSoundOutputBuffer,
@ -2594,10 +2594,10 @@ static PaError StartStream( PaStream *s )
PaError result = paNoError;
PaWinDsStream *stream = (PaWinDsStream*)s;
HRESULT hr;
stream->callbackResult = paContinue;
PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
ResetEvent( stream->processingCompleted );
if( stream->bufferProcessor.inputChannelCount > 0 )
@ -2674,7 +2674,7 @@ static PaError StartStream( PaStream *s )
resolution = msecPerWakeup/4;
stream->timerID = timeSetEvent( msecPerWakeup, resolution, (LPTIMECALLBACK) TimerCallback,
(DWORD_PTR) stream, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS );
if( stream->timerID == 0 )
{
stream->isActive = 0;
@ -2854,7 +2854,7 @@ static signed long GetStreamWriteAvailable( PaStream* s )
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior*/
return 0;

View File

@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -180,7 +180,7 @@ void PaWinDs_InitializeDSoundEntryPoints(void)
#ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE
paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 =
(HRESULT (WINAPI *)(LPCGUID, LPCGUID, LPCDSCBUFFERDESC, LPCDSBUFFERDESC,
HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *,
HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *,
LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN))
GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundFullDuplexCreate" );
if( paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 == NULL )
@ -221,4 +221,4 @@ void PaWinDs_TerminateDSoundEntryPoints(void)
FreeLibrary( paWinDsDSoundEntryPoints.hInstance_ );
paWinDsDSoundEntryPoints.hInstance_ = NULL;
}
}
}

View File

@ -29,13 +29,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -74,7 +74,7 @@ extern "C"
typedef struct
{
HINSTANCE hInstance_;
HRESULT (WINAPI *DllGetClassObject)(REFCLSID , REFIID , LPVOID *);
HRESULT (WINAPI *DirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
@ -88,7 +88,7 @@ typedef struct
#ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE
HRESULT (WINAPI *DirectSoundFullDuplexCreate8)(
LPCGUID, LPCGUID, LPCDSCBUFFERDESC, LPCDSBUFFERDESC,
HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *,
HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *,
LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN );
#endif
}PaWinDsDSoundEntryPoints;

View File

@ -1,5 +1,5 @@
/*
* $Id: pa_jack.c 1346 2008-02-20 10:09:20Z rossb $
* $Id: pa_jack.c 1541 2010-09-22 06:33:47Z dmitrykos $
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
* JACK Implementation by Joshua Haberman
@ -71,8 +71,6 @@
#include "pa_ringbuffer.h"
#include "pa_debugprint.h"
static int aErr_;
static PaError paErr_; /* For use with ENSURE_PA */
static pthread_t mainThread_;
static char *jackErr_ = NULL;
static const char* clientName_ = "PortAudio";
@ -83,15 +81,17 @@ static const char* clientName_ = "PortAudio";
/* Check PaError */
#define ENSURE_PA(expr) \
do { \
if( (paErr_ = (expr)) < paNoError ) \
PaError paErr; \
if( (paErr = (expr)) < paNoError ) \
{ \
if( (paErr_) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
if( (paErr) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
{ \
if (! jackErr_ ) jackErr_ = "unknown error";\
PaUtil_SetLastHostErrorInfo( paJACK, -1, jackErr_ ); \
const char *err = jackErr_; \
if (! err ) err = "unknown error"; \
PaUtil_SetLastHostErrorInfo( paJACK, -1, err ); \
} \
PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
result = paErr_; \
result = paErr; \
goto error; \
} \
} while( 0 )
@ -102,8 +102,9 @@ static const char* clientName_ = "PortAudio";
{ \
if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
{ \
if (!jackErr_) jackErr_ = "unknown error";\
PaUtil_SetLastHostErrorInfo( paJACK, -1, jackErr_ ); \
const char *err = jackErr_; \
if (!err) err = "unknown error"; \
PaUtil_SetLastHostErrorInfo( paJACK, -1, err ); \
} \
PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
result = (code); \
@ -112,8 +113,10 @@ static const char* clientName_ = "PortAudio";
} while( 0 )
#define ASSERT_CALL(expr, success) \
aErr_ = (expr); \
assert( aErr_ == success );
do { \
int err = (expr); \
assert( err == success ); \
} while( 0 )
/*
* Functions that directly map to the PortAudio stream interface
@ -826,6 +829,7 @@ static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
PaUtil_FreeMemory( jackHostApi );
free( jackErr_ );
jackErr_ = NULL;
}
static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
@ -1000,7 +1004,7 @@ static PaError WaitCondition( PaJackHostApiRepresentation *hostApi )
PaTime pt = PaUtil_GetTime();
struct timespec ts;
ts.tv_sec = (time_t) floor( pt + 1 );
ts.tv_sec = (time_t) floor( pt + 10 * 60 /* 10 minutes */ );
ts.tv_nsec = (long) ((pt - floor( pt )) * 1000000000);
/* XXX: Best enclose in loop, in case of spurious wakeups? */
err = pthread_cond_timedwait( &hostApi->cond, &hostApi->mtx, &ts );
@ -1177,7 +1181,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
minimum_buffer_frames = jackHostApi->jack_buffer_size * 3;
/* setup blocking API data structures (FIXME: can fail) */
BlockingBegin( stream, minimum_buffer_frames );
BlockingBegin( stream, minimum_buffer_frames );
/* install our own callback for the blocking API */
streamCallback = BlockingCallback;
@ -1276,10 +1280,10 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
&stream->bufferProcessor,
inputChannelCount,
inputSampleFormat,
paFloat32, /* hostInputSampleFormat */
paFloat32 | paNonInterleaved, /* hostInputSampleFormat */
outputChannelCount,
outputSampleFormat,
paFloat32, /* hostOutputSampleFormat */
paFloat32 | paNonInterleaved, /* hostOutputSampleFormat */
jackSr,
streamFlags,
framesPerBuffer,

View File

@ -1,5 +1,5 @@
/*
* $Id: pa_unix_oss.c 1385 2008-06-05 21:13:54Z aknudsen $
* $Id: pa_unix_oss.c 1509 2010-06-06 17:36:33Z dmitrykos $
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
* OSS implementation by:
@ -185,7 +185,7 @@ typedef struct PaOssStream
double sampleRate;
int callbackMode;
int callbackStop, callbackAbort;
volatile int callbackStop, callbackAbort;
PaOssStreamComponent *capture, *playback;
unsigned long pollTimeout;
@ -1317,7 +1317,17 @@ static PaError PaOssStream_WaitForFrames( PaOssStream *stream, unsigned long *fr
while( pollPlayback || pollCapture )
{
#ifdef PTHREAD_CANCELED
pthread_testcancel();
#else
/* avoid indefinite waiting on thread not supporting cancelation */
if( stream->callbackStop || stream->callbackAbort )
{
PA_DEBUG(( "Cancelling PaOssStream_WaitForFrames\n" ));
(*frames) = 0;
return paNoError;
}
#endif
/* select may modify the timeout parameter */
selectTimeval.tv_usec = timeout;
@ -1341,8 +1351,17 @@ static PaError PaOssStream_WaitForFrames( PaOssStream *stream, unsigned long *fr
ENSURE_( -1, paUnanticipatedHostError );
}
*/
#ifdef PTHREAD_CANCELED
pthread_testcancel();
#else
/* avoid indefinite waiting on thread not supporting cancelation */
if( stream->callbackStop || stream->callbackAbort )
{
PA_DEBUG(( "Cancelling PaOssStream_WaitForFrames\n" ));
(*frames) = 0;
return paNoError;
}
#endif
if( pollCapture )
{
if( FD_ISSET( captureFd, &readFds ) )
@ -1603,8 +1622,15 @@ static void *PaOSS_AudioThreadProc( void *userData )
while( 1 )
{
#ifdef PTHREAD_CANCELED
pthread_testcancel();
#else
if( stream->callbackAbort ) /* avoid indefinite waiting on thread not supporting cancelation */
{
PA_DEBUG(( "Aborting callback thread\n" ));
break;
}
#endif
if( stream->callbackStop && callbackResult == paContinue )
{
PA_DEBUG(( "Setting callbackResult to paComplete\n" ));
@ -1631,8 +1657,21 @@ static void *PaOSS_AudioThreadProc( void *userData )
{
unsigned long frames = framesAvail;
#ifdef PTHREAD_CANCELED
pthread_testcancel();
#else
if( stream->callbackStop )
{
PA_DEBUG(( "Setting callbackResult to paComplete\n" ));
callbackResult = paComplete;
}
if( stream->callbackAbort ) /* avoid indefinite waiting on thread not supporting cancelation */
{
PA_DEBUG(( "Aborting callback thread\n" ));
break;
}
#endif
PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
/* Read data */

View File

@ -2,7 +2,7 @@
* recplay.c
* Phil Burk
* Minimal record and playback test.
*
*
*/
#include <stdio.h>
#include <unistd.h>

File diff suppressed because it is too large Load Diff

View File

@ -27,13 +27,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -1565,10 +1565,10 @@ static PaError FilterCanCreateCapturePin(PaWinWdmFilter* filter,
/**
* Build the list of available filters
* Use the SetupDi API to enumerate all devices in the KSCATEGORY_AUDIO which
* have a KSCATEGORY_RENDER or KSCATEGORY_CAPTURE alias. For each of these
* devices initialise a PaWinWdmFilter structure by calling our NewFilter()
* function. We enumerate devices twice, once to count how many there are,
* Use the SetupDi API to enumerate all devices in the KSCATEGORY_AUDIO which
* have a KSCATEGORY_RENDER or KSCATEGORY_CAPTURE alias. For each of these
* devices initialise a PaWinWdmFilter structure by calling our NewFilter()
* function. We enumerate devices twice, once to count how many there are,
* and once to initialize the PaWinWdmFilter structures.
*/
static PaError BuildFilterList(PaWinWdmHostApiRepresentation* wdmHostApi)
@ -2255,7 +2255,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
stream->recordingPin = FilterCreateCapturePin(pFilter, (const WAVEFORMATEX*)&wfx, &result);
stream->deviceInputChannels = stream->userInputChannels;
}
if(result != paNoError)
{ /* Search through all PaSampleFormats to find one that works */
hostInputSampleFormat = paFloat32;
@ -2265,7 +2265,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
stream->bytesPerInputFrame = wfx.Format.nBlockAlign;
stream->recordingPin = FilterCreateCapturePin(pFilter, (const WAVEFORMATEX*)&wfx, &result);
stream->deviceInputChannels = stream->userInputChannels;
if(stream->recordingPin == NULL) result = paSampleFormatNotSupported;
if(result != paNoError) hostInputSampleFormat <<= 1;
}
@ -2374,7 +2374,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
{
hostOutputSampleFormat =
PaUtil_SelectClosestAvailableFormat( pFilter->formats, outputSampleFormat );
/* Try a WAVE_FORMAT_PCM instead */
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
wfx.Format.cbSize = 0;
@ -2384,7 +2384,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
stream->playbackPin = FilterCreateRenderPin(pFilter,(WAVEFORMATEX*)&wfx,&result);
if(stream->playbackPin == NULL) result = paSampleFormatNotSupported;
}
if( result != paNoError )
{
/* Some or all KS devices can only handle the exact number of channels
@ -2543,7 +2543,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
p->Header.Size = sizeof(p->Header);
p->Header.PresentationTime.Numerator = 1;
p->Header.PresentationTime.Denominator = 1;
p = &(stream->packets[3]);
p->Signal.hEvent = stream->events[3];
p->Header.Data = stream->hostBuffer + 2*stream->framesPerHostIBuffer*stream->bytesPerInputFrame + stream->framesPerHostOBuffer*stream->bytesPerOutputFrame;
@ -2916,7 +2916,7 @@ static DWORD WINAPI ProcessingThread(LPVOID pParam)
PaUtil_SetInputChannel(&stream->bufferProcessor,i,((unsigned char*)(stream->packets[inbuf].Header.Data))+(i*stream->inputSampleSize),stream->deviceInputChannels);
}
}
if (stream->recordingPin && stream->playbackPin) /* full duplex */
{
/* Only call the EndBufferProcessing function when the total input frames == total output frames */
@ -2931,7 +2931,7 @@ static DWORD WINAPI ProcessingThread(LPVOID pParam)
framesProcessed = 0;
}
}
else
else
{
framesProcessed = PaUtil_EndBufferProcessing(&stream->bufferProcessor,&cbResult);
}
@ -2962,7 +2962,7 @@ static DWORD WINAPI ProcessingThread(LPVOID pParam)
fillPlaybuf = 0;
emptyRecordbuf = 0;
}
/*
if(cbResult != paContinue)
{
@ -3301,4 +3301,4 @@ static signed long GetStreamWriteAvailable( PaStream* s )
/* IMPLEMENT ME, see portaudio.h for required behavior*/
PA_LOGL_;
return 0;
}
}

View File

@ -1,82 +1,82 @@
Notes about WDM-KS host API
---------------------------
Status history
--------------
10th November 2005:
Made following changes:
* OpenStream: Try all PaSampleFormats internally if the the chosen
format is not supported natively. This fixed several problems
with soundcards that soundcards that did not take kindly to
using 24-bit 3-byte formats.
* OpenStream: Make the minimum framesPerHostIBuffer (and framesPerHostOBuffer)
the default frameSize for the playback/recording pin.
* ProcessingThread: Added a switch to only call PaUtil_EndBufferProcessing
if the total input frames equals the total output frames
5th September 2004:
This is the first public version of the code. It should be considered
an alpha release with zero guarantee not to crash on any particular
system. So far it has only been tested in the author's development
environment, which means a Win2k/SP2 PIII laptop with integrated
SoundMAX driver and USB Tascam US-428 compiled with both MinGW
(GCC 3.3) and MSVC++6 using the MS DirectX 9 SDK.
It has been most widely tested with the MinGW build, with most of the
test programs (particularly paqa_devs and paqa_errs) passing.
There are some notable failures: patest_out_underflow and both of the
blocking I/O tests (as blocking I/O is not implemented).
At this point the code needs to be tested with a much wider variety
of configurations and feedback provided from testers regarding
both working and failing cases.
What is the WDM-KS host API?
----------------------------
PortAudio for Windows currently has 3 functional host implementations.
MME uses the oldest Windows audio API which does not offer good
play/record latency.
DirectX improves this, but still imposes a penalty
of 10s of milliseconds due to the system mixing of streams from
multiple applications.
ASIO offers very good latency, but requires special drivers which are
not always available for cheaper audio hardware. Also, when ASIO
drivers are available, they are not always so robust because they
bypass all of the standardised Windows device driver architecture
and hit the hardware their own way.
Alternatively there are a couple of free (but closed source) ASIO
implementations which connect to the lower level Windows
"Kernel Streaming" API, but again these require special installation
by the user, and can be limited in functionality or difficult to use.
This is where the PortAudio "WDM-KS" host implementation comes in.
It directly connects PortAudio to the same Kernel Streaming API which
those ASIO bridges use. This avoids the mixing penatly of DirectX,
giving at least as good latency as any ASIO driver, but it has the
advantage of working with ANY Windows audio hardware which is available
through the normal MME/DirectX routes without the user requiring
any additional device drivers to be installed, and allowing all
device selection to be done through the normal PortAudio API.
Note that in general you should only be using this host API if your
application has a real requirement for very low latency audio (<20ms),
either because you are generating sounds in real-time based upon
user input, or you a processing recorded audio in real time.
The only thing to be aware of is that using the KS interface will
block that device from being used by the rest of system through
the higher level APIs, or conversely, if the system is using
a device, the KS API will not be able to use it. MS recommend that
you should keep the device open only when your application has focus.
In PortAudio terms, this means having a stream Open on a WDMKS device.
Usage
-----
To add the WDMKS backend to your program which is already using
PortAudio, you must undefine PA_NO_WDMKS from your build file,
and include the pa_win_wdmks\pa_win_wdmks.c into your build.
The file should compile in both C and C++.
You will need a DirectX SDK installed on your system for the
ks.h and ksmedia.h header files.
You will need to link to the system "setupapi" library.
Note that if you use MinGW, you will get more warnings from
the DX header files when using GCC(C), and still a few warnings
Notes about WDM-KS host API
---------------------------
Status history
--------------
10th November 2005:
Made following changes:
* OpenStream: Try all PaSampleFormats internally if the the chosen
format is not supported natively. This fixed several problems
with soundcards that soundcards that did not take kindly to
using 24-bit 3-byte formats.
* OpenStream: Make the minimum framesPerHostIBuffer (and framesPerHostOBuffer)
the default frameSize for the playback/recording pin.
* ProcessingThread: Added a switch to only call PaUtil_EndBufferProcessing
if the total input frames equals the total output frames
5th September 2004:
This is the first public version of the code. It should be considered
an alpha release with zero guarantee not to crash on any particular
system. So far it has only been tested in the author's development
environment, which means a Win2k/SP2 PIII laptop with integrated
SoundMAX driver and USB Tascam US-428 compiled with both MinGW
(GCC 3.3) and MSVC++6 using the MS DirectX 9 SDK.
It has been most widely tested with the MinGW build, with most of the
test programs (particularly paqa_devs and paqa_errs) passing.
There are some notable failures: patest_out_underflow and both of the
blocking I/O tests (as blocking I/O is not implemented).
At this point the code needs to be tested with a much wider variety
of configurations and feedback provided from testers regarding
both working and failing cases.
What is the WDM-KS host API?
----------------------------
PortAudio for Windows currently has 3 functional host implementations.
MME uses the oldest Windows audio API which does not offer good
play/record latency.
DirectX improves this, but still imposes a penalty
of 10s of milliseconds due to the system mixing of streams from
multiple applications.
ASIO offers very good latency, but requires special drivers which are
not always available for cheaper audio hardware. Also, when ASIO
drivers are available, they are not always so robust because they
bypass all of the standardised Windows device driver architecture
and hit the hardware their own way.
Alternatively there are a couple of free (but closed source) ASIO
implementations which connect to the lower level Windows
"Kernel Streaming" API, but again these require special installation
by the user, and can be limited in functionality or difficult to use.
This is where the PortAudio "WDM-KS" host implementation comes in.
It directly connects PortAudio to the same Kernel Streaming API which
those ASIO bridges use. This avoids the mixing penatly of DirectX,
giving at least as good latency as any ASIO driver, but it has the
advantage of working with ANY Windows audio hardware which is available
through the normal MME/DirectX routes without the user requiring
any additional device drivers to be installed, and allowing all
device selection to be done through the normal PortAudio API.
Note that in general you should only be using this host API if your
application has a real requirement for very low latency audio (<20ms),
either because you are generating sounds in real-time based upon
user input, or you a processing recorded audio in real time.
The only thing to be aware of is that using the KS interface will
block that device from being used by the rest of system through
the higher level APIs, or conversely, if the system is using
a device, the KS API will not be able to use it. MS recommend that
you should keep the device open only when your application has focus.
In PortAudio terms, this means having a stream Open on a WDMKS device.
Usage
-----
To add the WDMKS backend to your program which is already using
PortAudio, you must undefine PA_NO_WDMKS from your build file,
and include the pa_win_wdmks\pa_win_wdmks.c into your build.
The file should compile in both C and C++.
You will need a DirectX SDK installed on your system for the
ks.h and ksmedia.h header files.
You will need to link to the system "setupapi" library.
Note that if you use MinGW, you will get more warnings from
the DX header files when using GCC(C), and still a few warnings
with G++(CPP).

File diff suppressed because it is too large Load Diff

View File

@ -26,13 +26,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -83,7 +83,7 @@ PaUtilHostApiInitializer *paHostApiInitializers[] =
PaJack_Initialize,
#endif
/* Added for IRIX, Pieter, oct 2, 2003: */
#ifdef PA_USE_SGI
#ifdef PA_USE_SGI
PaSGI_Initialize,
#endif

View File

@ -1,5 +1,5 @@
/*
* $Id: pa_unix_util.c 1419 2009-10-22 17:28:35Z bjornroche $
* $Id: pa_unix_util.c 1510 2010-06-10 08:05:29Z dmitrykos $
* Portable Audio I/O Library
* UNIX platform-specific support functions
*
@ -27,20 +27,20 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup unix_src
*/
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
@ -129,7 +129,7 @@ void Pa_Sleep( long msec )
/*
Discussion on the CoreAudio mailing list suggests that calling
gettimeofday (or anything else in the BSD layer) is not real-time
safe, so we use mach_absolute_time on OSX. This implementation is
safe, so we use mach_absolute_time on OSX. This implementation is
based on these two links:
Technical Q&A QA1398 - Mach Absolute Time Units
@ -140,7 +140,7 @@ void Pa_Sleep( long msec )
*/
/* Scaler to convert the result of mach_absolute_time to seconds */
static double machSecondsConversionScaler_ = 0.0;
static double machSecondsConversionScaler_ = 0.0;
#endif
void PaUtil_InitializeClock( void )
@ -193,9 +193,15 @@ PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *e
if( exitResult )
*exitResult = paNoError;
/* If pthread_cancel is not supported (Android platform) whole this function can lead to indefinite waiting if
working thread (callbackThread) has'n received any stop signals from outside, please keep
this in mind when considering using PaUtil_CancelThreading
*/
#ifdef PTHREAD_CANCELED
/* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */
if( !wait )
pthread_cancel( threading->callbackThread ); /* XXX: Safe to call this if the thread has exited on its own? */
#endif
pthread_join( threading->callbackThread, &pret );
#ifdef PTHREAD_CANCELED
@ -214,7 +220,7 @@ PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *e
}
/* Threading */
/* paUnixMainThread
/* paUnixMainThread
* We have to be a bit careful with defining this global variable,
* as explained below. */
#ifdef __APPLE__
@ -294,7 +300,7 @@ PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void
PA_UNLESS( !pthread_attr_init( &attr ), paInternalError );
/* Priority relative to other processes */
PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError );
PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError );
PA_UNLESS( !pthread_create( &self->thread, &attr, threadFunc, threadArg ), paInternalError );
started = 1;
@ -344,7 +350,7 @@ PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void
pthread_getschedparam(self->thread, &policy, &spm);
}
}
if( self->parentWaiting )
{
PaTime till;
@ -427,12 +433,19 @@ PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResul
{
PA_DEBUG(( "%s: Canceling thread %d\n", __FUNCTION__, self->thread ));
/* XXX: Safe to call this if the thread has exited on its own? */
#ifdef PTHREAD_CANCELED
pthread_cancel( self->thread );
#endif
}
PA_DEBUG(( "%s: Joining thread %d\n", __FUNCTION__, self->thread ));
PA_ENSURE_SYSTEM( pthread_join( self->thread, &pret ), 0 );
#ifdef PTHREAD_CANCELED
if( pret && PTHREAD_CANCELED != pret )
#else
/* !wait means the thread may have been canceled */
if( pret && wait )
#endif
{
if( exitResult )
{
@ -500,15 +513,17 @@ PaError PaUnixMutex_Terminate( PaUnixMutex* self )
/** Lock mutex.
*
* We're disabling thread cancellation while the thread is holding a lock, so mutexes are
* We're disabling thread cancellation while the thread is holding a lock, so mutexes are
* properly unlocked at termination time.
*/
PaError PaUnixMutex_Lock( PaUnixMutex* self )
{
PaError result = paNoError;
int oldState;
#ifdef PTHREAD_CANCEL
int oldState;
PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldState ), 0 );
#endif
PA_ENSURE_SYSTEM( pthread_mutex_lock( &self->mtx ), 0 );
error:
@ -522,10 +537,12 @@ error:
PaError PaUnixMutex_Unlock( PaUnixMutex* self )
{
PaError result = paNoError;
int oldState;
PA_ENSURE_SYSTEM( pthread_mutex_unlock( &self->mtx ), 0 );
#ifdef PTHREAD_CANCEL
int oldState;
PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldState ), 0 );
#endif
error:
return result;
@ -578,7 +595,7 @@ static void *WatchdogFunc( void *userData )
while( 1 )
{
double lowpassCoeff = 0.9, lowpassCoeff1 = 0.99999 - lowpassCoeff;
/* Test before and after in case whatever underlying sleep call isn't interrupted by pthread_cancel */
pthread_testcancel();
Pa_Sleep( intervalMsec );
@ -663,7 +680,7 @@ error:
/* Pass on error code */
pres = malloc( sizeof (PaError) );
*pres = result;
pthread_exit( pres );
}

View File

@ -27,13 +27,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -26,13 +26,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/

View File

@ -27,13 +27,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -45,7 +45,7 @@
@todo Implement workaround for QueryPerformanceCounter() skipping forward
bug. (see msdn kb Q274323).
*/
#include <windows.h>
#include <mmsystem.h> /* for timeGetTime() */
@ -142,10 +142,10 @@ double PaUtil_GetTime( void )
}
else
{
#ifndef UNDER_CE
#ifndef UNDER_CE
return timeGetTime() * .001;
#else
return GetTickCount() * .001;
#endif
#endif
}
}

View File

@ -26,13 +26,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -47,7 +47,7 @@
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
#endif
static GUID pawin_ksDataFormatSubtypeGuidBase =
static GUID pawin_ksDataFormatSubtypeGuidBase =
{ (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 };
@ -55,18 +55,18 @@ int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat )
{
if( sampleFormat == paFloat32 )
return PAWIN_WAVE_FORMAT_IEEE_FLOAT;
return PAWIN_WAVE_FORMAT_PCM;
}
void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate )
{
WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
int bytesPerSample = Pa_GetSampleSize(sampleFormat);
unsigned long bytesPerFrame = numChannels * bytesPerSample;
waveFormatEx->wFormatTag = waveFormatTag;
waveFormatEx->nChannels = (WORD)numChannels;
waveFormatEx->nSamplesPerSec = (DWORD)sampleRate;
@ -77,7 +77,7 @@ void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
}
void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate,
PaWinWaveFormatChannelMask channelMask )
{
@ -98,7 +98,7 @@ void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
waveFormatEx->wBitsPerSample;
*((DWORD*)&waveFormat->fields[PAWIN_INDEXOF_DWCHANNELMASK]) = channelMask;
guid = pawin_ksDataFormatSubtypeGuidBase;
guid.Data1 = (USHORT)waveFormatTag;
*((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = guid;
@ -111,7 +111,7 @@ PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels )
case 1:
return PAWIN_SPEAKER_MONO;
case 2:
return PAWIN_SPEAKER_STEREO;
return PAWIN_SPEAKER_STEREO;
case 3:
return PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_FRONT_RIGHT;
case 4:
@ -122,22 +122,22 @@ PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels )
/* The meaning of the PAWIN_SPEAKER_5POINT1 flag has changed over time:
http://msdn2.microsoft.com/en-us/library/aa474707.aspx
We use PAWIN_SPEAKER_5POINT1 (not PAWIN_SPEAKER_5POINT1_SURROUND)
because on some cards (eg Audigy) PAWIN_SPEAKER_5POINT1_SURROUND
results in a virtual mixdown placing the rear output in the
because on some cards (eg Audigy) PAWIN_SPEAKER_5POINT1_SURROUND
results in a virtual mixdown placing the rear output in the
front _and_ rear speakers.
*/
return PAWIN_SPEAKER_5POINT1;
return PAWIN_SPEAKER_5POINT1;
/* case 7: */
case 8:
return PAWIN_SPEAKER_7POINT1;
}
/* Apparently some Audigy drivers will output silence
if the direct-out constant (0) is used. So this is not ideal.
/* Apparently some Audigy drivers will output silence
if the direct-out constant (0) is used. So this is not ideal.
*/
return PAWIN_SPEAKER_DIRECTOUT;
/* Note that Alec Rogers proposed the following as an alternate method to
/* Note that Alec Rogers proposed the following as an alternate method to
generate the default channel mask, however it doesn't seem to be an improvement
over the above, since some drivers will matrix outputs mapping to non-present
speakers accross multiple physical speakers.

View File

@ -25,51 +25,55 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
#include <windows.h>
#include <mmreg.h>
#ifndef WAVE_FORMAT_IEEE_FLOAT
#define WAVE_FORMAT_IEEE_FLOAT 0x0003 // MinGW32 does not define this
#endif
#ifndef _WAVEFORMATEXTENSIBLE_
#define _WAVEFORMATEXTENSIBLE_ // MinGW32 does not define this
#endif
#ifndef _INC_MMREG
#define _INC_MMREG // for STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
#endif
#include <winioctl.h> // MinGW32 does not define this automatically
#include <ks.h>
#include <ksmedia.h>
#include <stdio.h> // just for some development printfs
#include <stdio.h> // just for some development printfs
#include "portaudio.h"
#include "pa_util.h"
#include "pa_win_wdmks_utils.h"
#ifndef PA_WDMKS_NO_KSGUID_LIB
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
#pragma comment( lib, "ksguid.lib" )
#endif
#define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO
#define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
#define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM
#define pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX KSDATAFORMAT_SUBTYPE_WAVEFORMATEX
#define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard
#define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard
#define pa_KSPROPSETID_Pin KSPROPSETID_Pin
#if !defined(PA_WDMKS_NO_KSGUID_LIB) && !defined(PAWIN_WDMKS_NO_KSGUID_LIB)
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
#pragma comment( lib, "ksguid.lib" )
#endif
#define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO
#define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
#define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM
#define pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX KSDATAFORMAT_SUBTYPE_WAVEFORMATEX
#define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard
#define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard
#define pa_KSPROPSETID_Pin KSPROPSETID_Pin
#else
static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX };
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX };
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
#endif
@ -182,7 +186,7 @@ static KSPIN_DATAFLOW GetKSFilterPinPropertyDataflow( HANDLE deviceHandle, int p
}
static int KSFilterPinPropertyIdentifiersInclude(
static int KSFilterPinPropertyIdentifiersInclude(
HANDLE deviceHandle, int pinId, unsigned long property, const GUID *identifierSet, unsigned long identifierId )
{
KSMULTIPLE_ITEM* item = NULL;
@ -192,7 +196,7 @@ static int KSFilterPinPropertyIdentifiersInclude(
if( WdmGetPinPropertyMulti( deviceHandle, pinId, property, &item) != paNoError )
return 0;
identifier = (KSIDENTIFIER*)(item+1);
for( i = 0; i < (int)item->Count; i++ )
@ -211,7 +215,7 @@ static int KSFilterPinPropertyIdentifiersInclude(
}
/* return the maximum channel count supported by any pin on the device.
/* return the maximum channel count supported by any pin on the device.
if isInput is non-zero we query input pins, otherwise output pins.
*/
int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput )
@ -221,7 +225,7 @@ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInp
int pinCount, pinId;
int result = 0;
KSPIN_DATAFLOW requiredDataflowDirection = (isInput ? KSPIN_DATAFLOW_OUT : KSPIN_DATAFLOW_IN );
if( !wcharDevicePath )
return 0;
@ -236,12 +240,12 @@ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInp
KSPIN_DATAFLOW dataflow = GetKSFilterPinPropertyDataflow( deviceHandle, pinId );
if( ( dataflow == requiredDataflowDirection ) &&
(( communication == KSPIN_COMMUNICATION_SINK) ||
( communication == KSPIN_COMMUNICATION_BOTH))
&& ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
( communication == KSPIN_COMMUNICATION_BOTH))
&& ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_STREAMING )
|| KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
|| KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_LOOPED_STREAMING ) )
&& KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
&& KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
KSPROPERTY_PIN_MEDIUMS, &pa_KSMEDIUMSETID_Standard, KSMEDIUM_STANDARD_DEVIO ) )
{
KSMULTIPLE_ITEM* item = NULL;
@ -258,10 +262,10 @@ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInp
&& ( memcmp( (void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID) ) == 0 ) ) )
{
KSDATARANGE_AUDIO *dataRangeAudio = (KSDATARANGE_AUDIO*)dataRange;
/*
printf( ">>> %d %d %d %d %S\n", isInput, dataflow, communication, dataRangeAudio->MaximumChannels, devicePath );
if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, sizeof(GUID) ) == 0 )
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WAVEFORMATEX\n" );
else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_DSOUND, sizeof(GUID) ) == 0 )
@ -279,7 +283,7 @@ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInp
if( dataRangeAudio->MaximumChannels < 0xFFFFUL && (int)dataRangeAudio->MaximumChannels > result )
result = (int)dataRangeAudio->MaximumChannels;
}
dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize);
}
@ -287,7 +291,7 @@ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInp
}
}
}
CloseHandle( deviceHandle );
return result;
}

View File

@ -28,13 +28,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -62,4 +62,4 @@ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInp
}
#endif /* __cplusplus */
#endif /* PA_WIN_WDMKS_UTILS_H */
#endif /* PA_WIN_WDMKS_UTILS_H */

View File

@ -23,13 +23,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
@ -186,9 +186,9 @@ static void Float32_To_Int32(
mov ecx, count
imul ecx, eax
add ecx, esi
mov edi, destinationBuffer
mov ebx, destinationStride
imul ebx, edx
@ -273,9 +273,9 @@ static void Float32_To_Int32_Clip(
mov ecx, count
imul ecx, eax
add ecx, esi
mov edi, destinationBuffer
mov ebx, destinationStride
imul ebx, edx
@ -301,7 +301,7 @@ static void Float32_To_Int32_Clip(
fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFFFF, (int)0x7FFFFFFF
fistp dword ptr [edi] // pop st(0) into dest, stack: (int)0x7FFFFFFF
jmp Float32_To_Int32_Clip_stored
Float32_To_Int32_Clip_clamp:
mov edx, dword ptr [esi] // load floating point value into integer register
shr edx, 31 // move sign bit into bit 0
@ -363,7 +363,7 @@ static void Float32_To_Int32_DitherClip(
unsigned long ditherPrevious = ditherGenerator->previous;
unsigned long ditherRandSeed1 = ditherGenerator->randSeed1;
unsigned long ditherRandSeed2 = ditherGenerator->randSeed2;
__asm{
// esi -> source ptr
// eax -> source byte stride
@ -381,9 +381,9 @@ static void Float32_To_Int32_DitherClip(
mov ecx, count
imul ecx, eax
add ecx, esi
mov edi, destinationBuffer
mov ebx, destinationStride
imul ebx, edx
@ -447,11 +447,11 @@ static void Float32_To_Int32_DitherClip(
fild highpassedDither
fmul const_float_dither_scale_
// end generate dither, dither signal in st(0)
faddp st(1), st(0) // stack: dither + value*(int scaler), int scaler
fistp dword ptr [edi] // pop st(0) into dest, stack: int scaler
jmp Float32_To_Int32_DitherClip_stored
Float32_To_Int32_DitherClip_clamp:
mov edx, dword ptr [esi] // load floating point value into integer register
shr edx, 31 // move sign bit into bit 0
@ -494,7 +494,7 @@ static void Float32_To_Int24(
signed long temp;
(void) ditherGenerator; // unused parameter
while( count-- )
{
// convert to 32 bit and drop the low 8 bits
@ -511,11 +511,11 @@ static void Float32_To_Int24(
*/
short savedFpuControlWord;
signed long tempInt32;
(void) ditherGenerator; /* unused parameter */
__asm{
// esi -> source ptr
// eax -> source byte stride
@ -590,7 +590,7 @@ static void Float32_To_Int24_Clip(
signed long temp;
(void) ditherGenerator; // unused parameter
while( count-- )
{
// convert to 32 bit and drop the low 8 bits
@ -608,11 +608,11 @@ static void Float32_To_Int24_Clip(
*/
short savedFpuControlWord;
signed long tempInt32;
(void) ditherGenerator; /* unused parameter */
__asm{
// esi -> source ptr
// eax -> source byte stride
@ -660,7 +660,7 @@ static void Float32_To_Int24_Clip(
fistp tempInt32 // pop st(0) into tempInt32, stack: (int)0x7FFFFF
mov edx, tempInt32
jmp Float32_To_Int24_Clip_store
Float32_To_Int24_Clip_clamp:
mov edx, dword ptr [esi] // load floating point value into integer register
shr edx, 31 // move sign bit into bit 0
@ -702,7 +702,7 @@ static void Float32_To_Int24_DitherClip(
float *src = (float*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
signed long temp;
while( count-- )
{
// convert to 32 bit and drop the low 8 bits
@ -712,7 +712,7 @@ static void Float32_To_Int24_DitherClip(
// use smaller scaler to prevent overflow when we add the dither
double dithered = ((double)*src * (2147483646.0)) + dither;
PA_CLIP_( dithered, -2147483648., 2147483647. );
temp = (signed long) dithered;
dest[0] = (unsigned char)(temp >> 8);
@ -734,9 +734,9 @@ static void Float32_To_Int24_DitherClip(
unsigned long ditherPrevious = ditherGenerator->previous;
unsigned long ditherRandSeed1 = ditherGenerator->randSeed1;
unsigned long ditherRandSeed2 = ditherGenerator->randSeed2;
signed long tempInt32;
__asm{
// esi -> source ptr
// eax -> source byte stride
@ -792,7 +792,7 @@ static void Float32_To_Int24_DitherClip(
mov ecx, sourceEnd // restore ecx
mov eax, sourceByteStride // restore eax
*/
// generate dither
mov sourceByteStride, eax // save eax
mov edx, 196314165
@ -826,7 +826,7 @@ static void Float32_To_Int24_DitherClip(
fistp tempInt32 // pop st(0) into tempInt32, stack: int scaler
mov edx, tempInt32
jmp Float32_To_Int24_DitherClip_store
Float32_To_Int24_DitherClip_clamp:
mov edx, dword ptr [esi] // load floating point value into integer register
shr edx, 31 // move sign bit into bit 0
@ -885,7 +885,7 @@ static void Float32_To_Int16(
*/
short savedFpuControlWord;
(void) ditherGenerator; /* unused parameter */
__asm{
@ -929,7 +929,7 @@ static void Float32_To_Int16(
add edi, ebx // increment destination ptr
//lea edi, [edi+ebx]
cmp esi, ecx // has src ptr reached end?
jne Float32_To_Int16_loop
@ -966,7 +966,7 @@ static void Float32_To_Int16_Clip(
*/
short savedFpuControlWord;
(void) ditherGenerator; /* unused parameter */
__asm{
@ -1015,7 +1015,7 @@ static void Float32_To_Int16_Clip(
fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFF, (int)0x7FFF
fistp word ptr [edi] // store scaled int into dest, stack: (int)0x7FFF
jmp Float32_To_Int16_Clip_stored
Float32_To_Int16_Clip_clamp:
mov edx, dword ptr [esi] // load floating point value into integer register
shr edx, 31 // move sign bit into bit 0
@ -1028,7 +1028,7 @@ static void Float32_To_Int16_Clip(
add edi, ebx // increment destination ptr
//lea edi, [edi+ebx]
cmp esi, ecx // has src ptr reached end?
jne Float32_To_Int16_Clip_loop
@ -1057,7 +1057,7 @@ static void Float32_To_Int16_DitherClip(
{
float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
// use smaller scaler to prevent overflow when we add the dither
// use smaller scaler to prevent overflow when we add the dither
float dithered = (*src * (32766.0f)) + dither;
signed long samp = (signed long) dithered;
PA_CLIP_( samp, -0x8000, 0x7FFF );
@ -1163,11 +1163,11 @@ static void Float32_To_Int16_DitherClip(
fild highpassedDither
fmul const_float_dither_scale_
// end generate dither, dither signal in st(0)
faddp st(1), st(0) // stack: dither * value*(int scaler), int scaler
fistp word ptr [edi] // store scaled int into dest, stack: int scaler
jmp Float32_To_Int16_DitherClip_stored
Float32_To_Int16_DitherClip_clamp:
mov edx, dword ptr [esi] // load floating point value into integer register
shr edx, 31 // move sign bit into bit 0
@ -1180,7 +1180,7 @@ static void Float32_To_Int16_DitherClip(
add edi, ebx // increment destination ptr
//lea edi, [edi+ebx]
cmp esi, ecx // has src ptr reached end?
jne Float32_To_Int16_DitherClip_loop
@ -1208,7 +1208,7 @@ void PaUtil_InitializeX86PlainConverters( void )
paConverters.Float32_To_Int24 = Float32_To_Int24;
paConverters.Float32_To_Int24_Clip = Float32_To_Int24_Clip;
paConverters.Float32_To_Int24_DitherClip = Float32_To_Int24_DitherClip;
paConverters.Float32_To_Int16 = Float32_To_Int16;
paConverters.Float32_To_Int16_Clip = Float32_To_Int16_Clip;
paConverters.Float32_To_Int16_DitherClip = Float32_To_Int16_DitherClip;

View File

@ -23,13 +23,13 @@
*/
/*
* The text above constitutes the entire PortAudio license; however,
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* 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. It is also
* requested that these non-binding requests be included along with the
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/