mirror of https://github.com/PCSX2/pcsx2.git
Updated portaudio to the svn revision 1885.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5513 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
0046f4a6f7
commit
c46deeccde
|
@ -20,6 +20,11 @@ SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin/Win32)
|
|||
ENDIF(PA_CONFIG_LIB_OUTPUT_PATH)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
|
||||
OPTION(PA_ENABLE_DEBUG_OUTPUT "Enable debug output for Portaudio" OFF)
|
||||
IF(PA_ENABLE_DEBUG_OUTPUT)
|
||||
ADD_DEFINITIONS(-DPA_ENABLE_DEBUG_OUTPUT)
|
||||
ENDIF(PA_ENABLE_DEBUG_OUTPUT)
|
||||
|
||||
IF(WIN32 AND MSVC)
|
||||
OPTION(PA_DLL_LINK_WITH_STATIC_RUNTIME "Link with static runtime libraries (minimizes runtime dependencies)" ON)
|
||||
IF(PA_DLL_LINK_WITH_STATIC_RUNTIME)
|
||||
|
|
|
@ -84,10 +84,12 @@ WARN_LOGFILE =
|
|||
#---------------------------------------------------------------------------
|
||||
INPUT = doc/src \
|
||||
include \
|
||||
bindings/java \
|
||||
examples
|
||||
FILE_PATTERNS = *.h \
|
||||
*.c \
|
||||
*.cpp \
|
||||
*.java \
|
||||
*.dox
|
||||
RECURSIVE = YES
|
||||
EXCLUDE = src/hostapi/wasapi/mingw-include
|
||||
|
|
|
@ -84,6 +84,7 @@ WARN_LOGFILE =
|
|||
#---------------------------------------------------------------------------
|
||||
INPUT = doc/src \
|
||||
include \
|
||||
bindings/java \
|
||||
examples \
|
||||
src \
|
||||
test \
|
||||
|
@ -91,6 +92,7 @@ INPUT = doc/src \
|
|||
FILE_PATTERNS = *.h \
|
||||
*.c \
|
||||
*.cpp \
|
||||
*.java \
|
||||
*.dox
|
||||
RECURSIVE = YES
|
||||
EXCLUDE = src/hostapi/wasapi/mingw-include
|
||||
|
|
|
@ -15769,23 +15769,61 @@ case "${host_os}" in
|
|||
LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon"
|
||||
|
||||
if test "x$enable_mac_universal" = "xyes" ; then
|
||||
case "xcodebuild -version | sed -n 's/Xcode \(.*\)/\1/p'" in
|
||||
|
||||
12*|3.0|3.1)
|
||||
if [ -d /Developer/SDKs/MacOSX10.5.sdk ] ; then
|
||||
mac_version_min="-mmacosx-version-min=10.3"
|
||||
mac_arches="-arch i386 -arch ppc -arch x86_64 -arch ppc64"
|
||||
mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.5.sdk"
|
||||
elif [ -d /Developer/SDKs/MacOSX10.6.sdk ] ; then
|
||||
mac_version_min="-mmacosx-version-min=10.4"
|
||||
mac_arches="-arch i386 -arch x86_64"
|
||||
mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.6.sdk"
|
||||
elif [ -d /Developer/SDKs/MacOSX10.7.sdk ] ; then
|
||||
mac_version_min="-mmacosx-version-min=10.4"
|
||||
mac_arches="-arch i386 -arch x86_64"
|
||||
mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.7.sdk"
|
||||
else
|
||||
mac_version_min="-mmacosx-version-min=10.3"
|
||||
mac_arches="-arch i386 -arch ppc"
|
||||
mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.4u.sdk"
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
if xcodebuild -version -sdk macosx10.5 Path >/dev/null 2>&1 ; then
|
||||
mac_version_min="-mmacosx-version-min=10.3"
|
||||
mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.5 Path`"
|
||||
elif xcodebuild -version -sdk macosx10.6 Path >/dev/null 2>&1 ; then
|
||||
mac_version_min="-mmacosx-version-min=10.4"
|
||||
mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.6 Path`"
|
||||
elif xcodebuild -version -sdk macosx10.7 Path >/dev/null 2>&1 ; then
|
||||
mac_version_min="-mmacosx-version-min=10.4"
|
||||
mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.7 Path`"
|
||||
else
|
||||
as_fn_error $? "Couldn't find 10.5, 10.6, or 10.7 SDK" "$LINENO" 5
|
||||
fi
|
||||
esac
|
||||
|
||||
mac_arches=""
|
||||
for arch in i386 x86_64 ppc ppc64
|
||||
do
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -arch $arch"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
|
||||
if [ -z "$mac_arches" ] ; then
|
||||
mac_arches="-arch $arch"
|
||||
else
|
||||
mac_arches="$mac_arches -arch $arch"
|
||||
fi
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
CFLAGS="$save_CFLAGS"
|
||||
done
|
||||
else
|
||||
mac_arches=""
|
||||
mac_sysroot=""
|
||||
|
@ -15807,7 +15845,7 @@ case "${host_os}" in
|
|||
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_coinitialize.o src/os/win/pa_win_waveformat.o
|
||||
LIBS="-lwinmm -lm -ldsound -lole32"
|
||||
LIBS="${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"
|
||||
|
@ -15817,7 +15855,7 @@ case "${host_os}" in
|
|||
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/os/win/pa_win_coinitialize.o src/hostapi/asio/iasiothiscallresolver.o $ASIODIR/common/asio.o $ASIODIR/host/asiodrivers.o $ASIODIR/host/pc/asiolist.o
|
||||
LIBS="-lwinmm -lm -lole32 -luuid"
|
||||
LIBS="${LIBS} -lwinmm -lm -lole32 -luuid"
|
||||
DLL_LIBS="${DLL_LIBS} -lwinmm -lm -lole32 -luuid"
|
||||
CFLAGS="$CFLAGS -ffast-math -fomit-frame-pointer -I\$(top_srcdir)/src/hostapi/asio -I$ASIODIR/host/pc -I$ASIODIR/common -I$ASIODIR/host -UPA_USE_ASIO -DPA_USE_ASIO=1 -DWINDOWS"
|
||||
|
||||
|
@ -15828,8 +15866,8 @@ case "${host_os}" in
|
|||
|
||||
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"
|
||||
add_objects src/hostapi/wdmks/pa_win_wdmks.o src/common/pa_ringbuffer.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_wdmks_util.o src/os/win/pa_win_waveformat.o
|
||||
LIBS="${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"
|
||||
|
@ -15838,14 +15876,14 @@ case "${host_os}" in
|
|||
|
||||
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"
|
||||
LIBS="${LIBS} -lwinmm -lm -lole32 -luuid"
|
||||
DLL_LIBS="${DLL_LIBS} -lwinmm"
|
||||
CFLAGS="$CFLAGS -UPA_USE_WMME -DPA_USE_WMME=1"
|
||||
fi
|
||||
|
||||
if [ "x$with_wasapi" = "xyes" ]; then
|
||||
add_objects src/hostapi/wasapi/pa_win_wasapi.o src/common/pa_ringbuffer.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_coinitialize.o src/os/win/pa_win_waveformat.o
|
||||
LIBS="-lwinmm -lm -lole32 -luuid"
|
||||
LIBS="${LIBS} -lwinmm -lm -lole32 -luuid"
|
||||
DLL_LIBS="${DLL_LIBS} -lwinmm -lole32"
|
||||
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/hostapi/wasapi/mingw-include -UPA_USE_WASAPI -DPA_USE_WASAPI=1"
|
||||
fi
|
||||
|
|
|
@ -208,23 +208,63 @@ case "${host_os}" in
|
|||
LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon"
|
||||
|
||||
if test "x$enable_mac_universal" = "xyes" ; then
|
||||
case "xcodebuild -version | sed -n 's/Xcode \(.*\)/\1/p'" in
|
||||
|
||||
[12]*|3.0|3.1)
|
||||
dnl In pre-3.2 versions of Xcode, xcodebuild doesn't
|
||||
dnl support -sdk, so we can't use that to look for
|
||||
dnl SDKs. However, in those versions of Xcode, the
|
||||
dnl SDKs are under /Developer/SDKs, so we can just look
|
||||
dnl there. Also, we assume they had no SDKs later
|
||||
dnl than 10.5, as 3.2 was the version that came with
|
||||
dnl 10.6, at least if the Wikipedia page for Xcode
|
||||
dnl is to be believed.
|
||||
if [[ -d /Developer/SDKs/MacOSX10.5.sdk ]] ; then
|
||||
mac_version_min="-mmacosx-version-min=10.3"
|
||||
mac_arches="-arch i386 -arch ppc -arch x86_64 -arch ppc64"
|
||||
mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.5.sdk"
|
||||
elif [[ -d /Developer/SDKs/MacOSX10.6.sdk ]] ; then
|
||||
mac_version_min="-mmacosx-version-min=10.4"
|
||||
mac_arches="-arch i386 -arch x86_64"
|
||||
mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.6.sdk"
|
||||
elif [[ -d /Developer/SDKs/MacOSX10.7.sdk ]] ; then
|
||||
mac_version_min="-mmacosx-version-min=10.4"
|
||||
mac_arches="-arch i386 -arch x86_64"
|
||||
mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.7.sdk"
|
||||
else
|
||||
mac_version_min="-mmacosx-version-min=10.3"
|
||||
mac_arches="-arch i386 -arch ppc"
|
||||
mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.4u.sdk"
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
dnl In 3.2 and later, xcodebuild supports -sdk, and, in
|
||||
dnl 4.3 and later, the SDKs aren't under /Developer/SDKs
|
||||
dnl as there *is* no /Developer, so we use -sdk to check
|
||||
dnl what SDKs are available and to get the full path of
|
||||
dnl the SDKs.
|
||||
if xcodebuild -version -sdk macosx10.5 Path >/dev/null 2>&1 ; then
|
||||
mac_version_min="-mmacosx-version-min=10.3"
|
||||
mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.5 Path`"
|
||||
elif xcodebuild -version -sdk macosx10.6 Path >/dev/null 2>&1 ; then
|
||||
mac_version_min="-mmacosx-version-min=10.4"
|
||||
mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.6 Path`"
|
||||
elif xcodebuild -version -sdk macosx10.7 Path >/dev/null 2>&1 ; then
|
||||
mac_version_min="-mmacosx-version-min=10.4"
|
||||
mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.7 Path`"
|
||||
else
|
||||
AC_MSG_ERROR([Couldn't find 10.5, 10.6, or 10.7 SDK])
|
||||
fi
|
||||
esac
|
||||
|
||||
dnl Pick which architectures to build for based on what
|
||||
dnl the compiler supports.
|
||||
mac_arches=""
|
||||
for arch in i386 x86_64 ppc ppc64
|
||||
do
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -arch $arch"
|
||||
AC_TRY_COMPILE([], [return 0;],
|
||||
[
|
||||
if [[ -z "$mac_arches" ]] ; then
|
||||
mac_arches="-arch $arch"
|
||||
else
|
||||
mac_arches="$mac_arches -arch $arch"
|
||||
fi
|
||||
])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
done
|
||||
else
|
||||
mac_arches=""
|
||||
mac_sysroot=""
|
||||
|
@ -247,7 +287,7 @@ case "${host_os}" in
|
|||
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_coinitialize.o src/os/win/pa_win_waveformat.o
|
||||
LIBS="-lwinmm -lm -ldsound -lole32"
|
||||
LIBS="${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"
|
||||
|
@ -257,7 +297,7 @@ case "${host_os}" in
|
|||
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/os/win/pa_win_coinitialize.o src/hostapi/asio/iasiothiscallresolver.o $ASIODIR/common/asio.o $ASIODIR/host/asiodrivers.o $ASIODIR/host/pc/asiolist.o
|
||||
LIBS="-lwinmm -lm -lole32 -luuid"
|
||||
LIBS="${LIBS} -lwinmm -lm -lole32 -luuid"
|
||||
DLL_LIBS="${DLL_LIBS} -lwinmm -lm -lole32 -luuid"
|
||||
CFLAGS="$CFLAGS -ffast-math -fomit-frame-pointer -I\$(top_srcdir)/src/hostapi/asio -I$ASIODIR/host/pc -I$ASIODIR/common -I$ASIODIR/host -UPA_USE_ASIO -DPA_USE_ASIO=1 -DWINDOWS"
|
||||
|
||||
|
@ -272,8 +312,8 @@ case "${host_os}" in
|
|||
|
||||
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"
|
||||
add_objects src/hostapi/wdmks/pa_win_wdmks.o src/common/pa_ringbuffer.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_wdmks_util.o src/os/win/pa_win_waveformat.o
|
||||
LIBS="${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"
|
||||
|
@ -282,14 +322,14 @@ case "${host_os}" in
|
|||
|
||||
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"
|
||||
LIBS="${LIBS} -lwinmm -lm -lole32 -luuid"
|
||||
DLL_LIBS="${DLL_LIBS} -lwinmm"
|
||||
CFLAGS="$CFLAGS -UPA_USE_WMME -DPA_USE_WMME=1"
|
||||
fi
|
||||
|
||||
if [[ "x$with_wasapi" = "xyes" ]]; then
|
||||
add_objects src/hostapi/wasapi/pa_win_wasapi.o src/common/pa_ringbuffer.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_coinitialize.o src/os/win/pa_win_waveformat.o
|
||||
LIBS="-lwinmm -lm -lole32 -luuid"
|
||||
LIBS="${LIBS} -lwinmm -lm -lole32 -luuid"
|
||||
DLL_LIBS="${DLL_LIBS} -lwinmm -lole32"
|
||||
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/hostapi/wasapi/mingw-include -UPA_USE_WASAPI -DPA_USE_WASAPI=1"
|
||||
fi
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
@section overview Overview
|
||||
|
||||
PortAudio is a cross-platform, open-source C language library for real-time audio input and output. The library provides functions that allow your software to acquire and output real-time audio streams from your computer's hardware audio interfaces. It is designed to simplify writing cross-platform audio applications, and also to simplify the development of audio software in general by hiding the complexities of dealing directly with each native audio API. PortAudio is used to implement sound recording, editing and mixing applications, software synthesizers, effects processors, music players, internet telephony applications, software defined radios and more. Supported platforms include MS Windows, Mac OS X and Linux. Third-party language bindings make it possible to call PortAudio from other programming languages including C++, C#, Python, PureBasic, FreePascal and Lazarus.
|
||||
|
||||
PortAudio is a cross-platform, open-source C language library for real-time audio input and output.
|
||||
The library provides functions that allow your software to acquire and output real-time audio streams from your computer's hardware audio interfaces. It is designed to simplify writing cross-platform audio applications, and also to simplify the development of audio software in general by hiding the complexities of dealing directly with each native audio API. PortAudio is used to implement sound recording, editing and mixing applications, software synthesizers, effects processors, music players, internet telephony applications, software defined radios and more. Supported platforms include MS Windows, Mac OS X and Linux. Third-party language bindings make it possible to call PortAudio from other programming languages including @ref java_binding "Java", C++, C#, Python, PureBasic, FreePascal and Lazarus.
|
||||
|
||||
@section start_here Start here
|
||||
|
||||
|
@ -38,6 +38,8 @@ Documentation for non-portable platform-specific host API extensions
|
|||
|
||||
- <a href="http://www.assembla.com/spaces/portaudio/wiki">The PortAudio wiki</a>
|
||||
|
||||
- @ref java_binding<br>
|
||||
Documentation for the Java JNI interface to PortAudio
|
||||
|
||||
@section developer_resources Developer Resources
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@ You will need to add the following frameworks to your XCode project:
|
|||
- AudioToolbox.framework
|
||||
- AudioUnit.framework
|
||||
- CoreServices.framework
|
||||
- Carbon.framework
|
||||
|
||||
@section comp_mac_ca_5 Using the Library in Other Projects
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ If you want to get information about each device, simply loop through as follows
|
|||
}
|
||||
@endcode
|
||||
|
||||
The Pa_DeviceInfo structure contains a wealth of information such as the name of the devices, the default latency associated with the devices and more. The structure ihas the following fields:
|
||||
The Pa_DeviceInfo structure contains a wealth of information such as the name of the devices, the default latency associated with the devices and more. The structure has the following fields:
|
||||
|
||||
@code
|
||||
int structVersion
|
||||
|
|
|
@ -25,7 +25,7 @@ Many platforms with GCC/make can use the simple ./configure && make combination
|
|||
|
||||
@section tut_start3 Programming with PortAudio
|
||||
|
||||
Below are the steps to writing a PortAudio application:
|
||||
Below are the steps to writing a PortAudio application using the callback technique:
|
||||
|
||||
- Write a callback function that will be called by PortAudio when audio processing is needed.
|
||||
- Initialize the PA library and open a stream for audio I/O.
|
||||
|
@ -38,7 +38,7 @@ In addition to this "Callback" architecture, V19 also supports a "Blocking I/O"
|
|||
|
||||
In this tutorial, we'll show how to use the callback architecture to play a sawtooth wave. Much of the tutorial is taken from the file paex_saw.c, which is part of the PortAudio distribution. When you're done with this tutorial, you'll be armed with the basic knowledge you need to write an audio program. If you need more sample code, look in the "examples" and "test" directory of the PortAudio distribution. Another great source of info is the portaudio.h Doxygen page, which documents the entire V19 API. Also see the page for <a href="http://www.assembla.com/spaces/portaudio/wiki/Tips">tips on programming PortAudio</a> on the PortAudio wiki.
|
||||
|
||||
If you are upgrading from V18, you may want to look at the <a href="http://www.portaudio.com/docs/proposals/index.html">Proposed Enhancements to PortAudio</a>, which describes the differences between V18 and V19.
|
||||
@section tut_start4 Programming Tutorial Contents
|
||||
|
||||
- \ref writing_a_callback
|
||||
- \ref initializing_portaudio
|
||||
|
@ -49,6 +49,8 @@ If you are upgrading from V18, you may want to look at the <a href="http://www.p
|
|||
- \ref querying_devices
|
||||
- \ref blocking_read_write
|
||||
|
||||
If you are upgrading from V18, you may want to look at the <a href="http://www.portaudio.com/docs/proposals/index.html">Proposed Enhancements to PortAudio</a>, which describes the differences between V18 and V19.
|
||||
|
||||
Once you have a basic understanding of how to use PortAudio, you might be interested in \ref exploring.
|
||||
|
||||
Next: \ref writing_a_callback
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "portaudio.h"
|
||||
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
//#include <AudioToolbox/AudioToolbox.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PORTAUDIO_H
|
||||
#define PORTAUDIO_H
|
||||
/*
|
||||
* $Id: portaudio.h 1745 2011-08-25 17:44:01Z rossb $
|
||||
* $Id: portaudio.h 1859 2012-09-01 00:10:13Z philburk $
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* PortAudio API Header File
|
||||
* Latest version available at: http://www.portaudio.com/
|
||||
|
@ -1021,7 +1021,7 @@ typedef struct PaStreamInfo
|
|||
/** Retrieve a pointer to a PaStreamInfo structure containing information
|
||||
about the specified stream.
|
||||
@return A pointer to an immutable PaStreamInfo structure. If the stream
|
||||
parameter invalid, or an error is encountered, the function returns NULL.
|
||||
parameter is invalid, or an error is encountered, the function returns NULL.
|
||||
|
||||
@param stream A pointer to an open stream previously created with Pa_OpenStream.
|
||||
|
||||
|
|
|
@ -2,10 +2,14 @@ README for PABLIO
|
|||
Portable Audio Blocking I/O Library
|
||||
Author: Phil Burk
|
||||
|
||||
PABLIO is a simplified interface to PortAudio that provide
|
||||
PABLIO is a simplified interface to PortAudio that provides
|
||||
read/write style blocking I/O.
|
||||
|
||||
Please see the .DOC file for documentation.
|
||||
PABLIO is DEPRECATED. We recommend that people use the blocking I/O calls
|
||||
that are now part of the PortAudio API. These are Pa_ReadStream() and
|
||||
Pa_WriteStream().
|
||||
|
||||
http://portaudio.com/docs/v19-doxydocs/blocking_read_write.html
|
||||
|
||||
/*
|
||||
* More information on PortAudio at: http://www.portaudio.com
|
||||
|
|
|
@ -7,7 +7,7 @@ extern "C"
|
|||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* $Id: pablio.h 1083 2006-08-23 07:30:49Z rossb $
|
||||
* $Id: pablio.h 1854 2012-07-09 15:53:00Z philburk $
|
||||
* PABLIO.h
|
||||
* Portable Audio Blocking read/write utility.
|
||||
*
|
||||
|
@ -53,7 +53,7 @@ extern "C"
|
|||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "pa_ringbuffer.h"
|
||||
#include <string.h>
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_front.c 1730 2011-08-18 03:43:51Z rossb $
|
||||
* $Id: pa_front.c 1880 2012-12-04 18:39:48Z rbencina $
|
||||
* Portable Audio I/O Library Multi-Host API front end
|
||||
* Validate function parameters and manage multiple host APIs.
|
||||
*
|
||||
|
@ -824,7 +824,7 @@ static int SampleFormatIsValid( PaSampleFormat format )
|
|||
- 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.)
|
||||
- is not an 'absurd' rate (less than 1000. or greater than 384000.)
|
||||
- sampleRate is NOT validated against device capabilities
|
||||
|
||||
PaStreamFlags streamFlags
|
||||
|
@ -965,7 +965,7 @@ static PaError ValidateOpenStreamParameters(
|
|||
|
||||
|
||||
/* Check for absurd sample rates. */
|
||||
if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
|
||||
if( (sampleRate < 1000.0) || (sampleRate > 384000.0) )
|
||||
return paInvalidSampleRate;
|
||||
|
||||
if( ((streamFlags & ~paPlatformSpecificFlags) & ~(paClipOff | paDitherOff | paNeverDropInput | paPrimeOutputBuffersUsingStreamCallback ) ) != 0 )
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_HOSTAPI_H
|
||||
#define PA_HOSTAPI_H
|
||||
/*
|
||||
* $Id: pa_hostapi.h 1740 2011-08-25 07:17:48Z philburk $
|
||||
* $Id: pa_hostapi.h 1880 2012-12-04 18:39:48Z rbencina $
|
||||
* Portable Audio I/O Library
|
||||
* host api representation
|
||||
*
|
||||
|
@ -264,7 +264,7 @@ typedef struct PaUtilHostApiRepresentation {
|
|||
- 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.)
|
||||
- is not an 'absurd' rate (less than 1000. or greater than 384000.)
|
||||
- sampleRate is NOT validated against device capabilities
|
||||
|
||||
PaStreamFlags streamFlags
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_RINGBUFFER_H
|
||||
#define PA_RINGBUFFER_H
|
||||
/*
|
||||
* $Id: pa_ringbuffer.h 1734 2011-08-18 11:19:36Z rossb $
|
||||
* $Id: pa_ringbuffer.h 1873 2012-10-07 19:00:11Z philburk $
|
||||
* Portable Audio I/O Library
|
||||
* Ring Buffer utility.
|
||||
*
|
||||
|
@ -65,6 +65,9 @@
|
|||
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.
|
||||
|
||||
@note The ring buffer functions are not normally exposed in the PortAudio libraries.
|
||||
If you want to call them then you will need to add pa_ringbuffer.c to your application source code.
|
||||
*/
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_asio.cpp 1825 2012-04-02 07:58:04Z rbencina $
|
||||
* $Id: pa_asio.cpp 1879 2012-12-04 14:45:31Z rbencina $
|
||||
* Portable Audio I/O Library for ASIO Drivers
|
||||
*
|
||||
* Author: Stephane Letz
|
||||
|
@ -1751,7 +1751,7 @@ static unsigned long SelectHostBufferSizeForSpecifiedUserFramesPerBuffer(
|
|||
do {
|
||||
if( (x % userFramesPerBuffer) == 0 )
|
||||
{
|
||||
/* any power-of-two multiple of userFramesPerBuffer is acceptable */
|
||||
/* any multiple of userFramesPerBuffer is acceptable */
|
||||
result = x;
|
||||
if( result >= targetBufferingLatencyFrames )
|
||||
break; /* stop. a value >= to targetBufferingLatencyFrames is ideal. */
|
||||
|
@ -1774,7 +1774,7 @@ static unsigned long SelectHostBufferSizeForSpecifiedUserFramesPerBuffer(
|
|||
do {
|
||||
if( (x % userFramesPerBuffer) == 0 )
|
||||
{
|
||||
/* any power-of-two multiple of userFramesPerBuffer is acceptable */
|
||||
/* any multiple of userFramesPerBuffer is acceptable */
|
||||
result = x;
|
||||
if( result >= targetBufferingLatencyFrames )
|
||||
break; /* stop. a value >= to targetBufferingLatencyFrames is ideal. */
|
||||
|
@ -2454,10 +2454,10 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor ,
|
||||
inputChannelCount ,
|
||||
inputSampleFormat & ~paNonInterleaved , /* Ring buffer. */
|
||||
hostInputSampleFormat , /* Host format. */
|
||||
(hostInputSampleFormat | paNonInterleaved), /* Host format. */
|
||||
outputChannelCount ,
|
||||
outputSampleFormat & ~paNonInterleaved, /* Ring buffer. */
|
||||
hostOutputSampleFormat , /* Host format. */
|
||||
(hostOutputSampleFormat | paNonInterleaved), /* Host format. */
|
||||
sampleRate ,
|
||||
streamFlags ,
|
||||
framesPerBuffer , /* Frames per ring buffer block. */
|
||||
|
|
|
@ -1774,10 +1774,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
do is initialize everything so that if we fail, we know what hasn't
|
||||
been touched.
|
||||
*/
|
||||
bzero( stream, sizeof( PaMacCoreStream ) );
|
||||
|
||||
stream->inputAudioBufferList.mBuffers[0].mData = NULL;
|
||||
stream->inputRingBuffer.buffer = NULL;
|
||||
bzero( &stream->blio, sizeof( PaMacBlio ) );
|
||||
/*
|
||||
stream->blio.inputRingBuffer.buffer = NULL;
|
||||
stream->blio.outputRingBuffer.buffer = NULL;
|
||||
|
@ -1786,13 +1784,6 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
stream->blio.outputSampleFormat=outputParameters?outputParameters->sampleFormat:0;
|
||||
stream->blio.outputSampleSize = computeSampleSizeFromFormat(stream->blio.outputSampleFormat);
|
||||
*/
|
||||
stream->inputSRConverter = NULL;
|
||||
stream->inputUnit = NULL;
|
||||
stream->outputUnit = NULL;
|
||||
stream->inputFramesPerBuffer = 0;
|
||||
stream->outputFramesPerBuffer = 0;
|
||||
stream->bufferProcessorIsInitialized = FALSE;
|
||||
stream->timingInformationMutexIsInitialized = 0;
|
||||
|
||||
/* assert( streamCallback ) ; */ /* only callback mode is implemented */
|
||||
if( streamCallback )
|
||||
|
@ -2251,6 +2242,7 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
*/
|
||||
OSStatus err = 0;
|
||||
unsigned long frames;
|
||||
long bytesPerFrame = sizeof( float ) * ioData->mBuffers[0].mNumberChannels;
|
||||
|
||||
/* -- start processing -- */
|
||||
PaUtil_BeginBufferProcessing( &(stream->bufferProcessor),
|
||||
|
@ -2261,8 +2253,8 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
/* -- compute frames. do some checks -- */
|
||||
assert( ioData->mNumberBuffers == 1 );
|
||||
assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan );
|
||||
frames = ioData->mBuffers[0].mDataByteSize;
|
||||
frames /= sizeof( float ) * ioData->mBuffers[0].mNumberChannels;
|
||||
|
||||
frames = ioData->mBuffers[0].mDataByteSize / bytesPerFrame;
|
||||
/* -- copy and process input data -- */
|
||||
err= AudioUnitRender(stream->inputUnit,
|
||||
ioActionFlags,
|
||||
|
@ -2301,6 +2293,7 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
* is required on input, that is done here as well.
|
||||
*/
|
||||
unsigned long frames;
|
||||
long bytesPerFrame = sizeof( float ) * ioData->mBuffers[0].mNumberChannels;
|
||||
|
||||
/* Sometimes, when stopping a duplex stream we get erroneous
|
||||
xrun flags, so if this is our last run, clear the flags. */
|
||||
|
@ -2322,8 +2315,7 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
|
||||
/* -- Copy and process output data -- */
|
||||
assert( ioData->mNumberBuffers == 1 );
|
||||
frames = ioData->mBuffers[0].mDataByteSize;
|
||||
frames /= sizeof( float ) * ioData->mBuffers[0].mNumberChannels;
|
||||
frames = ioData->mBuffers[0].mDataByteSize / bytesPerFrame;
|
||||
assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan );
|
||||
PaUtil_SetOutputFrameCount( &(stream->bufferProcessor), frames );
|
||||
PaUtil_SetInterleavedOutputChannels( &(stream->bufferProcessor),
|
||||
|
@ -2337,6 +2329,8 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
/* Here, we read the data out of the ring buffer, through the
|
||||
audio converter. */
|
||||
int inChan = stream->inputAudioBufferList.mBuffers[0].mNumberChannels;
|
||||
long bytesPerFrame = flsz * inChan;
|
||||
|
||||
if( stream->inputSRConverter )
|
||||
{
|
||||
OSStatus err;
|
||||
|
@ -2353,8 +2347,13 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
{ /*the ring buffer callback underflowed */
|
||||
err = 0;
|
||||
bzero( ((char *)data) + size, sizeof(data)-size );
|
||||
/* The ring buffer can underflow normally when the stream is stopping.
|
||||
* So only report an error if the stream is active. */
|
||||
if( stream->state == ACTIVE )
|
||||
{
|
||||
stream->xrunFlags |= paInputUnderflow;
|
||||
}
|
||||
}
|
||||
ERR( err );
|
||||
assert( !err );
|
||||
|
||||
|
@ -2374,7 +2373,7 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
AudioConverter would otherwise handle for us. */
|
||||
void *data1, *data2;
|
||||
ring_buffer_size_t size1, size2;
|
||||
PaUtil_GetRingBufferReadRegions( &stream->inputRingBuffer,
|
||||
ring_buffer_size_t framesReadable = PaUtil_GetRingBufferReadRegions( &stream->inputRingBuffer,
|
||||
frames,
|
||||
&data1, &size1,
|
||||
&data2, &size2 );
|
||||
|
@ -2389,14 +2388,21 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
|
||||
&callbackResult );
|
||||
PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, size1 );
|
||||
} else if( size1 + size2 < frames ) {
|
||||
} else if( framesReadable < frames ) {
|
||||
|
||||
long sizeBytes1 = size1 * bytesPerFrame;
|
||||
long sizeBytes2 = size2 * bytesPerFrame;
|
||||
/*we underflowed. take what data we can, zero the rest.*/
|
||||
unsigned char data[frames*inChan*flsz];
|
||||
if( size1 )
|
||||
memcpy( data, data1, size1 );
|
||||
if( size2 )
|
||||
memcpy( data+size1, data2, size2 );
|
||||
bzero( data+size1+size2, frames*flsz*inChan - size1 - size2 );
|
||||
unsigned char data[ frames * bytesPerFrame ];
|
||||
if( size1 > 0 )
|
||||
{
|
||||
memcpy( data, data1, sizeBytes1 );
|
||||
}
|
||||
if( size2 > 0 )
|
||||
{
|
||||
memcpy( data+sizeBytes1, data2, sizeBytes2 );
|
||||
}
|
||||
bzero( data+sizeBytes1+sizeBytes2, (frames*bytesPerFrame) - sizeBytes1 - sizeBytes2 );
|
||||
|
||||
PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames );
|
||||
PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
|
||||
|
@ -2407,7 +2413,7 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
|
||||
&callbackResult );
|
||||
PaUtil_AdvanceRingBufferReadIndex( &stream->inputRingBuffer,
|
||||
size1+size2 );
|
||||
framesReadable );
|
||||
/* flag underflow */
|
||||
stream->xrunFlags |= paInputUnderflow;
|
||||
} else {
|
||||
|
@ -2425,7 +2431,7 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
framesProcessed =
|
||||
PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
|
||||
&callbackResult );
|
||||
PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, size1+size2 );
|
||||
PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, framesReadable );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -2463,14 +2469,14 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
{
|
||||
/* If this is duplex or we use a converter, put the data
|
||||
into the ring buffer. */
|
||||
long bytesIn, bytesOut;
|
||||
bytesIn = sizeof( float ) * inNumberFrames * chan;
|
||||
bytesOut = PaUtil_WriteRingBuffer( &stream->inputRingBuffer,
|
||||
ring_buffer_size_t framesWritten = PaUtil_WriteRingBuffer( &stream->inputRingBuffer,
|
||||
stream->inputAudioBufferList.mBuffers[0].mData,
|
||||
inNumberFrames );
|
||||
if( bytesIn != bytesOut )
|
||||
if( framesWritten != inNumberFrames )
|
||||
{
|
||||
stream->xrunFlags |= paInputOverflow ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* for simplex input w/o SR conversion,
|
||||
|
|
|
@ -359,8 +359,9 @@ int BlioCallback( const void *input, void *output, unsigned long frameCount,
|
|||
|
||||
/* check for underflow */
|
||||
if( avail < frameCount * blio->inputSampleSizeActual * blio->inChan )
|
||||
{
|
||||
OSAtomicOr32( paInputOverflow, &blio->statusFlags );
|
||||
|
||||
}
|
||||
toRead = MIN( avail, frameCount * blio->inputSampleSizeActual * blio->inChan );
|
||||
|
||||
/* copy the data */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_win_ds.c 1824 2012-04-02 07:45:18Z rbencina $
|
||||
* $Id: pa_win_ds.c 1877 2012-11-10 02:55:20Z rbencina $
|
||||
* Portable Audio I/O Library DirectSound implementation
|
||||
*
|
||||
* Authors: Phil Burk, Robert Marsanyi & Ross Bencina
|
||||
|
@ -208,9 +208,9 @@ static signed long GetStreamWriteAvailable( PaStream* stream );
|
|||
PaUtil_SetLastHostErrorInfo( paDirectSound, hr, "DirectSound error" )
|
||||
|
||||
/************************************************* DX Prototypes **********/
|
||||
static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID,
|
||||
LPCTSTR lpszDesc,
|
||||
LPCTSTR lpszDrvName,
|
||||
static BOOL CALLBACK CollectGUIDsProcA(LPGUID lpGUID,
|
||||
LPCSTR lpszDesc,
|
||||
LPCSTR lpszDrvName,
|
||||
LPVOID lpContext );
|
||||
|
||||
/************************************************************************************/
|
||||
|
@ -367,7 +367,7 @@ static double PaWinDs_GetMinLatencySeconds( double sampleRate )
|
|||
double minLatencySeconds = 0;
|
||||
|
||||
/* Let user determine minimal latency by setting environment variable. */
|
||||
hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );
|
||||
hresult = GetEnvironmentVariableA( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );
|
||||
if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )
|
||||
{
|
||||
minLatencySeconds = atoi( envbuf ) * SECONDS_PER_MSEC;
|
||||
|
@ -513,9 +513,9 @@ static PaError TerminateDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *gu
|
|||
/************************************************************************************
|
||||
** Collect preliminary device information during DirectSound enumeration
|
||||
*/
|
||||
static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID,
|
||||
LPCTSTR lpszDesc,
|
||||
LPCTSTR lpszDrvName,
|
||||
static BOOL CALLBACK CollectGUIDsProcA(LPGUID lpGUID,
|
||||
LPCSTR lpszDesc,
|
||||
LPCSTR lpszDrvName,
|
||||
LPVOID lpContext )
|
||||
{
|
||||
DSDeviceNameAndGUIDVector *namesAndGUIDs = (DSDeviceNameAndGUIDVector*)lpContext;
|
||||
|
@ -581,6 +581,14 @@ static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVI
|
|||
int i;
|
||||
DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs = (DSDeviceNamesAndGUIDs*)context;
|
||||
|
||||
/*
|
||||
Apparently data->Interface can be NULL in some cases.
|
||||
Possibly virtual devices without hardware.
|
||||
So we check for NULLs now. See mailing list message November 10, 2012:
|
||||
"[Portaudio] portaudio initialization crash in KsPropertySetEnumerateCallback(pa_win_ds.c)"
|
||||
*/
|
||||
if( data->Interface )
|
||||
{
|
||||
if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER )
|
||||
{
|
||||
for( i=0; i < deviceNamesAndGUIDs->outputNamesAndGUIDs.count; ++i )
|
||||
|
@ -607,6 +615,7 @@ static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVI
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1202,9 +1211,9 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
|
|||
if( result != paNoError )
|
||||
goto error;
|
||||
|
||||
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA( (LPDSENUMCALLBACK)CollectGUIDsProc, (void *)&deviceNamesAndGUIDs.inputNamesAndGUIDs );
|
||||
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA( (LPDSENUMCALLBACKA)CollectGUIDsProcA, (void *)&deviceNamesAndGUIDs.inputNamesAndGUIDs );
|
||||
|
||||
paWinDsDSoundEntryPoints.DirectSoundEnumerateA( (LPDSENUMCALLBACK)CollectGUIDsProc, (void *)&deviceNamesAndGUIDs.outputNamesAndGUIDs );
|
||||
paWinDsDSoundEntryPoints.DirectSoundEnumerateA( (LPDSENUMCALLBACKA)CollectGUIDsProcA, (void *)&deviceNamesAndGUIDs.outputNamesAndGUIDs );
|
||||
|
||||
if( deviceNamesAndGUIDs.inputNamesAndGUIDs.enumerationError != paNoError )
|
||||
{
|
||||
|
@ -2728,8 +2737,6 @@ static void CALLBACK WaitableTimerAPCProc(
|
|||
PA_THREAD_FUNC ProcessingThreadProc( void *pArg )
|
||||
{
|
||||
PaWinDsStream *stream = (PaWinDsStream *)pArg;
|
||||
MMRESULT mmResult;
|
||||
HANDLE hWaitableTimer;
|
||||
LARGE_INTEGER dueTime;
|
||||
int timerPeriodMs;
|
||||
|
||||
|
@ -2968,7 +2975,7 @@ static PaError StartStream( PaStream *s )
|
|||
we're using an MM timer callback via timeSetEvent or not.
|
||||
*/
|
||||
assert( stream->systemTimerResolutionPeriodMs == 0 );
|
||||
if( timeGetDevCaps( &timecaps, sizeof(TIMECAPS) == MMSYSERR_NOERROR && timecaps.wPeriodMin > 0 ) )
|
||||
if( timeGetDevCaps( &timecaps, sizeof(TIMECAPS) ) == MMSYSERR_NOERROR && timecaps.wPeriodMin > 0 )
|
||||
{
|
||||
/* aim for resolution 4 times higher than polling rate */
|
||||
stream->systemTimerResolutionPeriodMs = (UINT)((stream->pollingPeriodSeconds * MSECS_PER_SECOND) * .25);
|
||||
|
|
|
@ -257,7 +257,7 @@ typedef void (*MixMonoToStereoF) (void *__to, void *__from, UINT32 count);
|
|||
typedef BOOL (WINAPI *FAvRtCreateThreadOrderingGroup) (PHANDLE,PLARGE_INTEGER,GUID*,PLARGE_INTEGER);
|
||||
typedef BOOL (WINAPI *FAvRtDeleteThreadOrderingGroup) (HANDLE);
|
||||
typedef BOOL (WINAPI *FAvRtWaitOnThreadOrderingGroup) (HANDLE);
|
||||
typedef HANDLE (WINAPI *FAvSetMmThreadCharacteristics) (LPCTSTR,LPDWORD);
|
||||
typedef HANDLE (WINAPI *FAvSetMmThreadCharacteristics) (LPCSTR,LPDWORD);
|
||||
typedef BOOL (WINAPI *FAvRevertMmThreadCharacteristics)(HANDLE);
|
||||
typedef BOOL (WINAPI *FAvSetMmThreadPriority) (HANDLE,AVRT_PRIORITY);
|
||||
|
||||
|
@ -830,7 +830,7 @@ static BOOL IsWow64()
|
|||
// and GetProcAddress to get a pointer to the function if available.
|
||||
|
||||
fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
|
||||
GetModuleHandle(TEXT("kernel32")), TEXT("IsWow64Process"));
|
||||
GetModuleHandleA("kernel32"), "IsWow64Process");
|
||||
|
||||
if (fnIsWow64Process == NULL)
|
||||
return FALSE;
|
||||
|
@ -868,7 +868,7 @@ static UINT32 GetWindowsVersion()
|
|||
typedef DWORD (WINAPI *LPFN_GETVERSION)(VOID);
|
||||
LPFN_GETVERSION fnGetVersion;
|
||||
|
||||
fnGetVersion = (LPFN_GETVERSION) GetProcAddress(GetModuleHandle(TEXT("kernel32")), TEXT("GetVersion"));
|
||||
fnGetVersion = (LPFN_GETVERSION) GetProcAddress(GetModuleHandleA("kernel32"), "GetVersion");
|
||||
if (fnGetVersion == NULL)
|
||||
return WINDOWS_UNKNOWN;
|
||||
|
||||
|
@ -2128,16 +2128,26 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
const UINT32 userFramesPerBuffer = framesPerLatency;
|
||||
IAudioClient *audioClient = NULL;
|
||||
|
||||
// Assume default failure due to some reason
|
||||
(*pa_error) = paInvalidDevice;
|
||||
|
||||
// Validate parameters
|
||||
if (!pSub || !pInfo || !params)
|
||||
{
|
||||
(*pa_error) = paBadStreamPtr;
|
||||
return E_POINTER;
|
||||
}
|
||||
if ((UINT32)sampleRate == 0)
|
||||
{
|
||||
(*pa_error) = paInvalidSampleRate;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Get the audio client
|
||||
hr = IMMDevice_Activate(pInfo->device, &pa_IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&audioClient);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
(*pa_error) = paInsufficientMemory;
|
||||
LogHostError(hr);
|
||||
goto done;
|
||||
}
|
||||
|
@ -2145,9 +2155,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
// Get closest format
|
||||
if ((error = GetClosestFormat(audioClient, sampleRate, params, pSub->shareMode, &pSub->wavex, output)) != paFormatIsSupported)
|
||||
{
|
||||
if (pa_error)
|
||||
(*pa_error) = error;
|
||||
|
||||
LogHostError(hr = AUDCLNT_E_UNSUPPORTED_FORMAT);
|
||||
goto done; // fail, format not supported
|
||||
}
|
||||
|
@ -2165,6 +2173,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
pSub->monoMixer = _GetMonoToStereoMixer(WaveToPaFormat(&pSub->wavex), (pInfo->flow == eRender ? MIX_DIR__1TO2 : MIX_DIR__2TO1_L));
|
||||
if (pSub->monoMixer == NULL)
|
||||
{
|
||||
(*pa_error) = paInvalidChannelCount;
|
||||
LogHostError(hr = AUDCLNT_E_UNSUPPORTED_FORMAT);
|
||||
goto done; // fail, no mixer for format
|
||||
}
|
||||
|
@ -2320,6 +2329,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
hr = IMMDevice_Activate(pInfo->device, &pa_IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&audioClient);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
(*pa_error) = paInsufficientMemory;
|
||||
LogHostError(hr);
|
||||
goto done;
|
||||
}
|
||||
|
@ -2350,6 +2360,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
hr = IMMDevice_Activate(pInfo->device, &pa_IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&audioClient);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
(*pa_error) = paInsufficientMemory;
|
||||
LogHostError(hr);
|
||||
goto done;
|
||||
}
|
||||
|
@ -2375,6 +2386,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
hr = IAudioClient_GetBufferSize(audioClient, &frames);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
(*pa_error) = paInvalidDevice;
|
||||
LogHostError(hr);
|
||||
goto done;
|
||||
}
|
||||
|
@ -2388,6 +2400,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
hr = IMMDevice_Activate(pInfo->device, &pa_IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&audioClient);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
(*pa_error) = paInsufficientMemory;
|
||||
LogHostError(hr);
|
||||
goto done;
|
||||
}
|
||||
|
@ -2395,9 +2408,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
// Get closest format
|
||||
if ((error = GetClosestFormat(audioClient, sampleRate, params, pSub->shareMode, &pSub->wavex, output)) != paFormatIsSupported)
|
||||
{
|
||||
if (pa_error)
|
||||
(*pa_error) = error;
|
||||
|
||||
LogHostError(hr = AUDCLNT_E_UNSUPPORTED_FORMAT); // fail, format not supported
|
||||
goto done;
|
||||
}
|
||||
|
@ -2415,6 +2426,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
pSub->monoMixer = _GetMonoToStereoMixer(WaveToPaFormat(&pSub->wavex), (pInfo->flow == eRender ? MIX_DIR__1TO2 : MIX_DIR__2TO1_L));
|
||||
if (pSub->monoMixer == NULL)
|
||||
{
|
||||
(*pa_error) = paInvalidChannelCount;
|
||||
LogHostError(hr = AUDCLNT_E_UNSUPPORTED_FORMAT);
|
||||
goto done; // fail, no mixer for format
|
||||
}
|
||||
|
@ -2433,6 +2445,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
NULL);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
(*pa_error) = paInvalidDevice;
|
||||
LogHostError(hr);
|
||||
goto done;
|
||||
}
|
||||
|
@ -2440,6 +2453,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
else
|
||||
if (hr != S_OK)
|
||||
{
|
||||
(*pa_error) = paInvalidDevice;
|
||||
LogHostError(hr);
|
||||
goto done;
|
||||
}
|
||||
|
@ -2454,6 +2468,9 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
MakeFramesFromHns(pSub->period, pSub->wavex.Format.nSamplesPerSec),
|
||||
fullDuplex);
|
||||
|
||||
// No error, client is succesfully created
|
||||
(*pa_error) = paNoError;
|
||||
|
||||
done:
|
||||
|
||||
// Clean up
|
||||
|
@ -2475,7 +2492,7 @@ static PaError ActivateAudioClientOutput(PaWasapiStream *stream)
|
|||
hr = CreateAudioClient(stream, &stream->out, TRUE, &result);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
LogPaError(result = paInvalidDevice);
|
||||
LogPaError(result);
|
||||
goto error;
|
||||
}
|
||||
LogWAVEFORMATEXTENSIBLE(&stream->out.wavex);
|
||||
|
@ -2547,7 +2564,7 @@ static PaError ActivateAudioClientInput(PaWasapiStream *stream)
|
|||
hr = CreateAudioClient(stream, &stream->in, FALSE, &result);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
LogPaError(result = paInvalidDevice);
|
||||
LogPaError(result);
|
||||
goto error;
|
||||
}
|
||||
LogWAVEFORMATEXTENSIBLE(&stream->in.wavex);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_win_wdmks.c 1820 2012-02-25 07:43:10Z robiwan $
|
||||
* $Id: pa_win_wdmks.c 1885 2012-12-28 16:54:25Z robiwan $
|
||||
* PortAudio Windows WDM-KS interface
|
||||
*
|
||||
* Author: Andrew Baldwin, Robert Bielik (WaveRT)
|
||||
|
@ -69,6 +69,7 @@ of a device for the duration of active stream using those devices
|
|||
|
||||
#include <string.h> /* strlen() */
|
||||
#include <assert.h>
|
||||
#include <wchar.h> /* iswspace() */
|
||||
|
||||
#include "pa_util.h"
|
||||
#include "pa_allocation.h"
|
||||
|
@ -159,6 +160,21 @@ Default is to use the pin category.
|
|||
#endif
|
||||
|
||||
#include <setupapi.h>
|
||||
|
||||
#ifndef EXTERN_C
|
||||
#define EXTERN_C extern
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
/* For MinGW we reference mingw-include files supplied with WASAPI */
|
||||
#define WINBOOL BOOL
|
||||
|
||||
#include "../wasapi/mingw-include/ks.h"
|
||||
#include "../wasapi/mingw-include/ksmedia.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <mmreg.h>
|
||||
#include <ks.h>
|
||||
|
||||
|
@ -167,18 +183,17 @@ Default is to use the pin category.
|
|||
an "old" ksmedia.h), so the proper ksmedia.h is used */
|
||||
#include <ksmedia.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* These next definitions allow the use of the KSUSER DLL */
|
||||
typedef KSDDKAPI DWORD WINAPI KSCREATEPIN(HANDLE, PKSPIN_CONNECT, ACCESS_MASK, PHANDLE);
|
||||
typedef /*KSDDKAPI*/ DWORD WINAPI KSCREATEPIN(HANDLE, PKSPIN_CONNECT, ACCESS_MASK, PHANDLE);
|
||||
extern HMODULE DllKsUser;
|
||||
extern KSCREATEPIN* FunctionKsCreatePin;
|
||||
|
||||
/* These definitions allows the use of AVRT.DLL on Vista and later OSs */
|
||||
extern HMODULE DllAvRt;
|
||||
typedef HANDLE WINAPI AVSETMMTHREADCHARACTERISTICS(LPCSTR, LPDWORD TaskIndex);
|
||||
typedef BOOL WINAPI AVREVERTMMTHREADCHARACTERISTICS(HANDLE);
|
||||
typedef enum _PA_AVRT_PRIORITY
|
||||
{
|
||||
PA_AVRT_PRIORITY_LOW = -1,
|
||||
|
@ -186,10 +201,17 @@ typedef enum _PA_AVRT_PRIORITY
|
|||
PA_AVRT_PRIORITY_HIGH,
|
||||
PA_AVRT_PRIORITY_CRITICAL
|
||||
} PA_AVRT_PRIORITY, *PPA_AVRT_PRIORITY;
|
||||
typedef BOOL WINAPI AVSETMMTHREADPRIORITY(HANDLE, PA_AVRT_PRIORITY);
|
||||
extern AVSETMMTHREADCHARACTERISTICS* FunctionAvSetMmThreadCharacteristics;
|
||||
extern AVREVERTMMTHREADCHARACTERISTICS* FunctionAvRevertMmThreadCharacteristics;
|
||||
extern AVSETMMTHREADPRIORITY* FunctionAvSetMmThreadPriority;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HINSTANCE hInstance;
|
||||
|
||||
HANDLE (WINAPI *AvSetMmThreadCharacteristics) (LPCSTR, LPDWORD);
|
||||
BOOL (WINAPI *AvRevertMmThreadCharacteristics) (HANDLE);
|
||||
BOOL (WINAPI *AvSetMmThreadPriority) (HANDLE, PA_AVRT_PRIORITY);
|
||||
} PaWinWDMKSAvRtEntryPoints;
|
||||
|
||||
static PaWinWDMKSAvRtEntryPoints paWinWDMKSAvRtEntryPoints = {0};
|
||||
|
||||
/* An unspecified channel count (-1) is not treated correctly, so we replace it with
|
||||
* an arbitrarily large number */
|
||||
|
@ -408,11 +430,6 @@ static const unsigned cPacketsArrayMask = 3;
|
|||
HMODULE DllKsUser = NULL;
|
||||
KSCREATEPIN* FunctionKsCreatePin = NULL;
|
||||
|
||||
HMODULE DllAvRt = NULL;
|
||||
AVSETMMTHREADCHARACTERISTICS* FunctionAvSetMmThreadCharacteristics = NULL;
|
||||
AVREVERTMMTHREADCHARACTERISTICS* FunctionAvRevertMmThreadCharacteristics = NULL;
|
||||
AVSETMMTHREADPRIORITY* FunctionAvSetMmThreadPriority = NULL;
|
||||
|
||||
/* prototypes for functions declared in this file */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -434,13 +451,13 @@ static PaError WdmSyncIoctl(HANDLE handle,
|
|||
void* outBuffer,
|
||||
unsigned long outBufferCount,
|
||||
unsigned long* bytesReturned);
|
||||
|
||||
static PaError WdmGetPropertySimple(HANDLE handle,
|
||||
const GUID* const guidPropertySet,
|
||||
unsigned long property,
|
||||
void* value,
|
||||
unsigned long valueCount,
|
||||
void* instance,
|
||||
unsigned long instanceCount);
|
||||
unsigned long valueCount);
|
||||
|
||||
static PaError WdmSetPropertySimple(HANDLE handle,
|
||||
const GUID* const guidPropertySet,
|
||||
unsigned long property,
|
||||
|
@ -456,11 +473,13 @@ static PaError WdmGetPinPropertySimple(HANDLE handle,
|
|||
void* value,
|
||||
unsigned long valueCount,
|
||||
unsigned long* byteCount);
|
||||
|
||||
static PaError WdmGetPinPropertyMulti(HANDLE handle,
|
||||
unsigned long pinId,
|
||||
const GUID* const guidPropertySet,
|
||||
unsigned long property,
|
||||
KSMULTIPLE_ITEM** ksMultipleItem);
|
||||
|
||||
static PaError WdmGetPropertyMulti(HANDLE handle,
|
||||
const GUID* const guidPropertySet,
|
||||
unsigned long property,
|
||||
|
@ -692,7 +711,17 @@ static PaError WdmSyncIoctl(
|
|||
( ioctlNumber == IOCTL_KS_PROPERTY ) &&
|
||||
( outBufferCount == 0 ) ) )
|
||||
{
|
||||
PaWinWDM_SetLastErrorInfo(result, "WdmSyncIoctl: DeviceIoControl GLE = 0x%08X", error);
|
||||
KSPROPERTY* ksProperty = (KSPROPERTY*)inBuffer;
|
||||
|
||||
PaWinWDM_SetLastErrorInfo(result, "WdmSyncIoctl: DeviceIoControl GLE = 0x%08X (prop_set = {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}, prop_id = %u)",
|
||||
error,
|
||||
ksProperty->Set.Data1, ksProperty->Set.Data2, ksProperty->Set.Data3,
|
||||
ksProperty->Set.Data4[0], ksProperty->Set.Data4[1],
|
||||
ksProperty->Set.Data4[2], ksProperty->Set.Data4[3],
|
||||
ksProperty->Set.Data4[4], ksProperty->Set.Data4[5],
|
||||
ksProperty->Set.Data4[6], ksProperty->Set.Data4[7],
|
||||
ksProperty->Id
|
||||
);
|
||||
result = paUnanticipatedHostError;
|
||||
}
|
||||
}
|
||||
|
@ -703,36 +732,20 @@ static PaError WdmGetPropertySimple(HANDLE handle,
|
|||
const GUID* const guidPropertySet,
|
||||
unsigned long property,
|
||||
void* value,
|
||||
unsigned long valueCount,
|
||||
void* instance,
|
||||
unsigned long instanceCount)
|
||||
unsigned long valueCount)
|
||||
{
|
||||
PaError result;
|
||||
KSPROPERTY* ksProperty;
|
||||
unsigned long propertyCount;
|
||||
KSPROPERTY ksProperty;
|
||||
|
||||
propertyCount = sizeof(KSPROPERTY) + instanceCount;
|
||||
ksProperty = (KSPROPERTY*)_alloca( propertyCount );
|
||||
if( !ksProperty )
|
||||
{
|
||||
return paInsufficientMemory;
|
||||
}
|
||||
|
||||
FillMemory((void*)ksProperty,sizeof(ksProperty),0);
|
||||
ksProperty->Set = *guidPropertySet;
|
||||
ksProperty->Id = property;
|
||||
ksProperty->Flags = KSPROPERTY_TYPE_GET;
|
||||
|
||||
if( instance )
|
||||
{
|
||||
memcpy( (void*)(((char*)ksProperty)+sizeof(KSPROPERTY)), instance, instanceCount );
|
||||
}
|
||||
ksProperty.Set = *guidPropertySet;
|
||||
ksProperty.Id = property;
|
||||
ksProperty.Flags = KSPROPERTY_TYPE_GET;
|
||||
|
||||
result = WdmSyncIoctl(
|
||||
handle,
|
||||
IOCTL_KS_PROPERTY,
|
||||
ksProperty,
|
||||
propertyCount,
|
||||
&ksProperty,
|
||||
sizeof(KSPROPERTY),
|
||||
value,
|
||||
valueCount,
|
||||
NULL);
|
||||
|
@ -2090,9 +2103,7 @@ static PaError PinInstantiate(PaWinWdmPin* pin)
|
|||
&KSPROPSETID_Connection,
|
||||
KSPROPERTY_CONNECTION_ALLOCATORFRAMING,
|
||||
&ksaf,
|
||||
sizeof(ksaf),
|
||||
NULL,
|
||||
0);
|
||||
sizeof(ksaf));
|
||||
|
||||
if( result != paNoError )
|
||||
{
|
||||
|
@ -2101,9 +2112,7 @@ static PaError PinInstantiate(PaWinWdmPin* pin)
|
|||
&KSPROPSETID_Connection,
|
||||
KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX,
|
||||
&ksafex,
|
||||
sizeof(ksafex),
|
||||
NULL,
|
||||
0);
|
||||
sizeof(ksafex));
|
||||
if( result == paNoError )
|
||||
{
|
||||
pin->frameSize = ksafex.FramingItem[0].FramingRange.Range.MinFrameSize;
|
||||
|
@ -2672,7 +2681,7 @@ static PaWinWdmFilter* FilterNew( PaWDMKSType type, DWORD devNode, const wchar_t
|
|||
/* Get product GUID (it might not be supported) */
|
||||
{
|
||||
KSCOMPONENTID compId;
|
||||
if (WdmGetPropertySimple(filter->handle, &KSPROPSETID_General, KSPROPERTY_GENERAL_COMPONENTID, &compId, sizeof(KSCOMPONENTID), NULL, 0) == paNoError)
|
||||
if (WdmGetPropertySimple(filter->handle, &KSPROPSETID_General, KSPROPERTY_GENERAL_COMPONENTID, &compId, sizeof(KSCOMPONENTID)) == paNoError)
|
||||
{
|
||||
filter->devInfo.deviceProductGuid = compId.Product;
|
||||
}
|
||||
|
@ -3668,7 +3677,7 @@ PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
PaError result = paNoError;
|
||||
int deviceCount = 0;
|
||||
void *scanResults = 0;
|
||||
PaWinWdmHostApiRepresentation *wdmHostApi;
|
||||
PaWinWdmHostApiRepresentation *wdmHostApi = NULL;
|
||||
|
||||
PA_LOGE_;
|
||||
|
||||
|
@ -3686,23 +3695,25 @@ PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
if(DllKsUser == NULL)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Attempt to load AVRT.DLL, if we can't, then we'll just use time critical prio instead... */
|
||||
if(DllAvRt == NULL)
|
||||
{
|
||||
DllAvRt = LoadLibrary(TEXT("avrt.dll"));
|
||||
if (DllAvRt != NULL)
|
||||
{
|
||||
FunctionAvSetMmThreadCharacteristics = (AVSETMMTHREADCHARACTERISTICS*)GetProcAddress(DllAvRt,"AvSetMmThreadCharacteristicsA");
|
||||
FunctionAvRevertMmThreadCharacteristics = (AVREVERTMMTHREADCHARACTERISTICS*)GetProcAddress(DllAvRt, "AvRevertMmThreadCharacteristics");
|
||||
FunctionAvSetMmThreadPriority = (AVSETMMTHREADPRIORITY*)GetProcAddress(DllAvRt, "AvSetMmThreadPriority");
|
||||
}
|
||||
}
|
||||
|
||||
FunctionKsCreatePin = (KSCREATEPIN*)GetProcAddress(DllKsUser, "KsCreatePin");
|
||||
if(FunctionKsCreatePin == NULL)
|
||||
goto error;
|
||||
|
||||
/* Attempt to load AVRT.DLL, if we can't, then we'll just use time critical prio instead... */
|
||||
if(paWinWDMKSAvRtEntryPoints.hInstance == NULL)
|
||||
{
|
||||
paWinWDMKSAvRtEntryPoints.hInstance = LoadLibrary(TEXT("avrt.dll"));
|
||||
if (paWinWDMKSAvRtEntryPoints.hInstance != NULL)
|
||||
{
|
||||
paWinWDMKSAvRtEntryPoints.AvSetMmThreadCharacteristics =
|
||||
(HANDLE(WINAPI*)(LPCSTR,LPDWORD))GetProcAddress(paWinWDMKSAvRtEntryPoints.hInstance,"AvSetMmThreadCharacteristicsA");
|
||||
paWinWDMKSAvRtEntryPoints.AvRevertMmThreadCharacteristics =
|
||||
(BOOL(WINAPI*)(HANDLE))GetProcAddress(paWinWDMKSAvRtEntryPoints.hInstance, "AvRevertMmThreadCharacteristics");
|
||||
paWinWDMKSAvRtEntryPoints.AvSetMmThreadPriority =
|
||||
(BOOL(WINAPI*)(HANDLE,PA_AVRT_PRIORITY))GetProcAddress(paWinWDMKSAvRtEntryPoints.hInstance, "AvSetMmThreadPriority");
|
||||
}
|
||||
}
|
||||
|
||||
wdmHostApi = (PaWinWdmHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinWdmHostApiRepresentation) );
|
||||
if( !wdmHostApi )
|
||||
{
|
||||
|
@ -3778,10 +3789,10 @@ static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
|
|||
DllKsUser = NULL;
|
||||
}
|
||||
|
||||
if( DllAvRt != NULL )
|
||||
if( paWinWDMKSAvRtEntryPoints.hInstance != NULL )
|
||||
{
|
||||
FreeLibrary( DllAvRt );
|
||||
DllAvRt = NULL;
|
||||
FreeLibrary( paWinWDMKSAvRtEntryPoints.hInstance );
|
||||
paWinWDMKSAvRtEntryPoints.hInstance = NULL;
|
||||
}
|
||||
|
||||
if( wdmHostApi)
|
||||
|
@ -4948,8 +4959,18 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
|
||||
if (result != paNoError)
|
||||
{
|
||||
unsigned long pos = 0xdeadc0de;
|
||||
PA_DEBUG(("Failed to register capture position register, using PinGetAudioPositionViaIOCTL\n"));
|
||||
stream->capture.pPin->fnAudioPosition = PinGetAudioPositionViaIOCTL;
|
||||
/* Test position function */
|
||||
result = (stream->capture.pPin->fnAudioPosition)(stream->capture.pPin, &pos);
|
||||
if (result != paNoError || pos != 0x0)
|
||||
{
|
||||
PA_DEBUG(("Failed to read capture position register (IOCTL)\n"));
|
||||
PaWinWDM_SetLastErrorInfo(paUnanticipatedHostError, "Failed to read capture position register (IOCTL)");
|
||||
result = paUnanticipatedHostError;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5060,8 +5081,18 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
|
||||
if (result != paNoError)
|
||||
{
|
||||
unsigned long pos = 0xdeadc0de;
|
||||
PA_DEBUG(("Failed to register rendering position register, using PinGetAudioPositionViaIOCTL\n"));
|
||||
stream->render.pPin->fnAudioPosition = PinGetAudioPositionViaIOCTL;
|
||||
/* Test position function */
|
||||
result = (stream->render.pPin->fnAudioPosition)(stream->render.pPin, &pos);
|
||||
if (result != paNoError || pos != 0x0)
|
||||
{
|
||||
PA_DEBUG(("Failed to read render position register (IOCTL)\n"));
|
||||
PaWinWDM_SetLastErrorInfo(paUnanticipatedHostError, "Failed to read render position register (IOCTL)");
|
||||
result = paUnanticipatedHostError;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5343,12 +5374,12 @@ static HANDLE BumpThreadPriority()
|
|||
HANDLE hAVRT = NULL;
|
||||
|
||||
/* If we have access to AVRT.DLL (Vista and later), use it */
|
||||
if (FunctionAvSetMmThreadCharacteristics != NULL)
|
||||
if (paWinWDMKSAvRtEntryPoints.AvSetMmThreadCharacteristics != NULL)
|
||||
{
|
||||
hAVRT = FunctionAvSetMmThreadCharacteristics("Pro Audio", &dwTask);
|
||||
hAVRT = paWinWDMKSAvRtEntryPoints.AvSetMmThreadCharacteristics("Pro Audio", &dwTask);
|
||||
if (hAVRT != NULL && hAVRT != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
BOOL bret = FunctionAvSetMmThreadPriority(hAVRT, PA_AVRT_PRIORITY_CRITICAL);
|
||||
BOOL bret = paWinWDMKSAvRtEntryPoints.AvSetMmThreadPriority(hAVRT, PA_AVRT_PRIORITY_CRITICAL);
|
||||
if (!bret)
|
||||
{
|
||||
PA_DEBUG(("Set mm thread prio to critical failed!\n"));
|
||||
|
@ -5385,8 +5416,8 @@ static void DropThreadPriority(HANDLE hAVRT)
|
|||
|
||||
if (hAVRT != NULL)
|
||||
{
|
||||
FunctionAvSetMmThreadPriority(hAVRT, PA_AVRT_PRIORITY_NORMAL);
|
||||
FunctionAvRevertMmThreadCharacteristics(hAVRT);
|
||||
paWinWDMKSAvRtEntryPoints.AvSetMmThreadPriority(hAVRT, PA_AVRT_PRIORITY_NORMAL);
|
||||
paWinWDMKSAvRtEntryPoints.AvRevertMmThreadCharacteristics(hAVRT);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5564,7 +5595,7 @@ static PaError PaDoProcessing(PaProcessThreadInfo* pInfo)
|
|||
if (inputFramesAvailable && (!pInfo->stream->userOutputChannels || inputFramesAvailable >= (int)pInfo->stream->render.framesPerBuffer))
|
||||
{
|
||||
unsigned wrapCntr = 0;
|
||||
char* data[2] = {0};
|
||||
void* data[2] = {0};
|
||||
ring_buffer_size_t size[2] = {0};
|
||||
|
||||
/* If full-duplex, we just extract output buffer number of frames */
|
||||
|
@ -6042,10 +6073,14 @@ static PaError StartStream( PaStream *s )
|
|||
{
|
||||
PaError result = paNoError;
|
||||
PaWinWdmStream *stream = (PaWinWdmStream*)s;
|
||||
DWORD dwID;
|
||||
|
||||
PA_LOGE_;
|
||||
|
||||
if (stream->streamThread != NULL)
|
||||
{
|
||||
return paStreamIsNotStopped;
|
||||
}
|
||||
|
||||
stream->streamStop = 0;
|
||||
stream->streamAbort = 0;
|
||||
|
||||
|
@ -6060,7 +6095,7 @@ static PaError StartStream( PaStream *s )
|
|||
/*ret = SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
|
||||
PA_DEBUG(("Class ret = %d;",ret));*/
|
||||
|
||||
stream->streamThread = CREATE_THREAD_FUNCTION (NULL, 0, ProcessingThread, stream, CREATE_SUSPENDED, &dwID);
|
||||
stream->streamThread = CREATE_THREAD_FUNCTION (NULL, 0, ProcessingThread, stream, CREATE_SUSPENDED, NULL);
|
||||
if(stream->streamThread == NULL)
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
|
@ -6101,14 +6136,14 @@ static PaError StopStream( PaStream *s )
|
|||
{
|
||||
PaError result = paNoError;
|
||||
PaWinWdmStream *stream = (PaWinWdmStream*)s;
|
||||
int doCb = 0;
|
||||
BOOL doCb = FALSE;
|
||||
|
||||
PA_LOGE_;
|
||||
|
||||
if(stream->streamActive)
|
||||
{
|
||||
DWORD dwExitCode;
|
||||
doCb = 1;
|
||||
doCb = TRUE;
|
||||
stream->streamStop = 1;
|
||||
if (GetExitCodeThread(stream->streamThread, &dwExitCode) && dwExitCode == STILL_ACTIVE)
|
||||
{
|
||||
|
@ -6136,8 +6171,11 @@ static PaError StopStream( PaStream *s )
|
|||
}
|
||||
}
|
||||
|
||||
if (stream->streamThread != NULL)
|
||||
{
|
||||
CloseHandle(stream->streamThread);
|
||||
stream->streamThread = 0;
|
||||
}
|
||||
stream->streamStarted = 0;
|
||||
stream->streamActive = 0;
|
||||
|
||||
|
@ -6325,6 +6363,7 @@ static signed long GetStreamWriteAvailable( PaStream* s )
|
|||
|
||||
static PaError PaPinCaptureEventHandler_WaveCyclic(PaProcessThreadInfo* pInfo, unsigned eventIndex)
|
||||
{
|
||||
PaError result = paNoError;
|
||||
ring_buffer_size_t frameCount;
|
||||
DATAPACKET* packet = pInfo->stream->capture.packets + eventIndex;
|
||||
|
||||
|
@ -6332,22 +6371,26 @@ static PaError PaPinCaptureEventHandler_WaveCyclic(PaProcessThreadInfo* pInfo, u
|
|||
|
||||
if (packet->Header.DataUsed == 0)
|
||||
{
|
||||
PA_HP_TRACE((pInfo->stream->hLog, ">>> Capture bogus event: idx=%u (DataUsed=%u)", eventIndex, packet->Header.DataUsed));
|
||||
PA_HP_TRACE((pInfo->stream->hLog, ">>> Capture bogus event (no data): idx=%u", eventIndex));
|
||||
|
||||
/* Bogus event, reset! This is to handle the behavior of this USB mic: http://shop.xtz.se/measurement-system/microphone-to-dirac-live-room-correction-suite
|
||||
on startup of streaming, where it erroneously sets the event without the corresponding buffer being filled (DataUsed == 0) */
|
||||
ResetEvent(packet->Signal.hEvent);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = -1; /* Only need this to be NOT paNoError */
|
||||
}
|
||||
else
|
||||
{
|
||||
pInfo->capturePackets[pInfo->captureHead & cPacketsArrayMask].packet = packet;
|
||||
|
||||
frameCount = PaUtil_WriteRingBuffer(&pInfo->stream->ringBuffer, packet->Header.Data, pInfo->stream->capture.framesPerBuffer);
|
||||
|
||||
PA_HP_TRACE((pInfo->stream->hLog, ">>> Capture event: idx=%u (frames=%u)", eventIndex, frameCount));
|
||||
++pInfo->captureHead;
|
||||
--pInfo->pending;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
--pInfo->pending; /* This needs to be done in either case */
|
||||
return result;
|
||||
}
|
||||
|
||||
static PaError PaPinCaptureSubmitHandler_WaveCyclic(PaProcessThreadInfo* pInfo, unsigned eventIndex)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_win_wmme.c 1739 2011-08-25 07:15:31Z rossb $
|
||||
* $Id: pa_win_wmme.c 1874 2012-10-31 06:20:59Z rbencina $
|
||||
* pa_win_wmme.c
|
||||
* Implementation of PortAudio for Windows MultiMedia Extensions (WMME)
|
||||
*
|
||||
|
@ -450,7 +450,7 @@ static PaDeviceIndex GetEnvDefaultDeviceID( char *envName )
|
|||
#ifndef WIN32_PLATFORM_PSPC /* no GetEnvironmentVariable on PocketPC */
|
||||
|
||||
/* Let user determine default device by setting environment variable. */
|
||||
hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE_ );
|
||||
hresult = GetEnvironmentVariableA( envName, envbuf, PA_ENV_BUF_SIZE_ );
|
||||
if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE_) )
|
||||
{
|
||||
recommendedIndex = atoi( envbuf );
|
||||
|
@ -709,7 +709,8 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
|
|||
{
|
||||
/* Append I/O suffix to WAVE_MAPPER device. */
|
||||
deviceName = (char *)PaUtil_GroupAllocateMemory(
|
||||
winMmeHostApi->allocations, StrTLen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_) );
|
||||
winMmeHostApi->allocations,
|
||||
(long) (StrTLen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_)) );
|
||||
if( !deviceName )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
|
@ -721,7 +722,8 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
|
|||
else
|
||||
{
|
||||
deviceName = (char*)PaUtil_GroupAllocateMemory(
|
||||
winMmeHostApi->allocations, StrTLen( wic.szPname ) + 1 );
|
||||
winMmeHostApi->allocations,
|
||||
(long) (StrTLen( wic.szPname ) + 1) );
|
||||
if( !deviceName )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
|
@ -835,7 +837,8 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
|
|||
{
|
||||
/* Append I/O suffix to WAVE_MAPPER device. */
|
||||
deviceName = (char *)PaUtil_GroupAllocateMemory(
|
||||
winMmeHostApi->allocations, StrTLen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_) );
|
||||
winMmeHostApi->allocations,
|
||||
(long) (StrTLen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_)) );
|
||||
if( !deviceName )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
|
@ -847,7 +850,8 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
|
|||
else
|
||||
{
|
||||
deviceName = (char*)PaUtil_GroupAllocateMemory(
|
||||
winMmeHostApi->allocations, StrTLen( woc.szPname ) + 1 );
|
||||
winMmeHostApi->allocations,
|
||||
(long) (StrTLen( woc.szPname ) + 1) );
|
||||
if( !deviceName )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
|
|
|
@ -104,7 +104,6 @@ void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
|
|||
*((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = guid;
|
||||
}
|
||||
|
||||
|
||||
PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels )
|
||||
{
|
||||
switch( numChannels ){
|
||||
|
@ -129,11 +128,16 @@ PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels )
|
|||
return PAWIN_SPEAKER_5POINT1;
|
||||
/* case 7: */
|
||||
case 8:
|
||||
return PAWIN_SPEAKER_7POINT1;
|
||||
/* RoBi: PAWIN_SPEAKER_7POINT1_SURROUND fits normal surround sound setups better than PAWIN_SPEAKER_7POINT1, f.i. NVidia HDMI Audio
|
||||
output is silent on channels 5&6 with NVidia drivers, and channel 7&8 with Micrsoft HD Audio driver using PAWIN_SPEAKER_7POINT1.
|
||||
With PAWIN_SPEAKER_7POINT1_SURROUND both setups work OK. */
|
||||
return PAWIN_SPEAKER_7POINT1_SURROUND;
|
||||
}
|
||||
|
||||
/* Apparently some Audigy drivers will output silence
|
||||
if the direct-out constant (0) is used. So this is not ideal.
|
||||
|
||||
RoBi 2012-12-19: Also, NVidia driver seem to output garbage instead. Again not very ideal.
|
||||
*/
|
||||
return PAWIN_SPEAKER_DIRECTOUT;
|
||||
|
||||
|
|
|
@ -47,15 +47,26 @@
|
|||
#define _INC_MMREG // for STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
|
||||
#endif
|
||||
#include <winioctl.h> // MinGW32 does not define this automatically
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
#include "../../hostapi/wasapi/mingw-include/ks.h"
|
||||
#include "../../hostapi/wasapi/mingw-include/ksmedia.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <ks.h>
|
||||
#include <ksmedia.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdio.h> // just for some development printfs
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_util.h"
|
||||
#include "pa_win_wdmks_utils.h"
|
||||
|
||||
#if !defined(PA_WDMKS_NO_KSGUID_LIB) && !defined(PAWIN_WDMKS_NO_KSGUID_LIB)
|
||||
#if !defined(PA_WDMKS_NO_KSGUID_LIB) && !defined(PAWIN_WDMKS_NO_KSGUID_LIB) && !defined(__GNUC__)
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200) && (_MSC_VER < 1600))) /* MSC version 6 up to 2008 */
|
||||
#pragma comment( lib, "ksguid.lib" )
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue