From c46deeccdedb634b96cf35aac2014505bca8328b Mon Sep 17 00:00:00 2001 From: gigaherz Date: Wed, 16 Jan 2013 18:28:22 +0000 Subject: [PATCH 01/13] Updated portaudio to the svn revision 1885. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5513 96395faa-99c1-11dd-bbfe-3dabce05a288 --- 3rdparty/portaudio/CMakeLists.txt | 5 + 3rdparty/portaudio/Doxyfile | 2 + 3rdparty/portaudio/Doxyfile.developer | 2 + 3rdparty/portaudio/build/msvc/portaudio.def | 98 +- 3rdparty/portaudio/build/msvc/readme.txt | 224 +-- 3rdparty/portaudio/configure | 84 +- 3rdparty/portaudio/configure.in | 86 +- 3rdparty/portaudio/doc/src/mainpage.dox | 6 +- .../src/tutorial/compile_mac_coreaudio.dox | 3 +- .../doc/src/tutorial/querying_devices.dox | 2 +- .../doc/src/tutorial/tutorial_start.dox | 6 +- 3rdparty/portaudio/include/pa_mac_core.h | 2 +- 3rdparty/portaudio/include/portaudio.h | 4 +- 3rdparty/portaudio/pablio/README.txt | 8 +- 3rdparty/portaudio/pablio/pablio.h | 4 +- 3rdparty/portaudio/src/common/pa_front.c | 6 +- 3rdparty/portaudio/src/common/pa_hostapi.h | 4 +- 3rdparty/portaudio/src/common/pa_ringbuffer.h | 5 +- .../src/hostapi/alsa/pa_linux_alsa.c | 1383 ++++------------- .../portaudio/src/hostapi/asio/pa_asio.cpp | 10 +- .../src/hostapi/coreaudio/pa_mac_core.c | 80 +- .../hostapi/coreaudio/pa_mac_core_blocking.c | 3 +- .../portaudio/src/hostapi/dsound/pa_win_ds.c | 61 +- .../src/hostapi/wasapi/pa_win_wasapi.c | 39 +- .../src/hostapi/wdmks/pa_win_wdmks.c | 217 +-- .../portaudio/src/hostapi/wmme/pa_win_wmme.c | 16 +- .../portaudio/src/os/win/pa_win_waveformat.c | 8 +- .../portaudio/src/os/win/pa_win_wdmks_utils.c | 13 +- 28 files changed, 917 insertions(+), 1464 deletions(-) diff --git a/3rdparty/portaudio/CMakeLists.txt b/3rdparty/portaudio/CMakeLists.txt index febdf2f017..ad7611837d 100644 --- a/3rdparty/portaudio/CMakeLists.txt +++ b/3rdparty/portaudio/CMakeLists.txt @@ -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) diff --git a/3rdparty/portaudio/Doxyfile b/3rdparty/portaudio/Doxyfile index c679e72153..ce2ad3960f 100644 --- a/3rdparty/portaudio/Doxyfile +++ b/3rdparty/portaudio/Doxyfile @@ -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 diff --git a/3rdparty/portaudio/Doxyfile.developer b/3rdparty/portaudio/Doxyfile.developer index f018ed3e00..0bfb0daffb 100644 --- a/3rdparty/portaudio/Doxyfile.developer +++ b/3rdparty/portaudio/Doxyfile.developer @@ -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 diff --git a/3rdparty/portaudio/build/msvc/portaudio.def b/3rdparty/portaudio/build/msvc/portaudio.def index bdaa8eef1c..2eabdcd854 100644 --- a/3rdparty/portaudio/build/msvc/portaudio.def +++ b/3rdparty/portaudio/build/msvc/portaudio.def @@ -1,50 +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_GetAvailableBufferSizes @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 +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_GetAvailableBufferSizes @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 \ No newline at end of file diff --git a/3rdparty/portaudio/build/msvc/readme.txt b/3rdparty/portaudio/build/msvc/readme.txt index 5fe5e28cdc..dabdd1ec73 100644 --- a/3rdparty/portaudio/build/msvc/readme.txt +++ b/3rdparty/portaudio/build/msvc/readme.txt @@ -1,112 +1,112 @@ -Hello - - This is a small list of steps in order to build portaudio -(Currently v19-devel) into a VS2005 DLL and lib file. -This DLL contains all 5 current Win32 PA APIS (MME/DS/ASIO/WASAPI/WDMKS) - -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 isn't 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 * (or later), I suggest you open the portaudio.sln file - which contains 2 projects (portaudio & portaudio_static) each with 6 configurations: Win32/x64 in both Debug, Release and ReleaseMinDependency, - last of which removes dependency of all but basic OS system DLLs. - - 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. Set the PA_USE_ASIO preprocessor symbol to zero (i.e. PA_USE_ASIO=0) in the project properties. - In VS2005 this can be added under - Project Properties > Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions - - Setting PA_USE_ASIO=0 stops src/os/win/pa_win_hostapis.c - from trying to initialize the PA ASIO implementation. - - D. Remove PaAsio_* entry points from portaudio.def, or comment them out with ; - - -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_USE_WMME, PA_USE_DSOUND, PA_USE_ASIO, PA_USE_WASAPI and PA_USE_WDMKS - ------ -David Viens, davidv@plogue.com -Robert Bielik, robert@xponaut.se +Hello + + This is a small list of steps in order to build portaudio +(Currently v19-devel) into a VS2005 DLL and lib file. +This DLL contains all 5 current Win32 PA APIS (MME/DS/ASIO/WASAPI/WDMKS) + +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 isn't 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 * (or later), I suggest you open the portaudio.sln file + which contains 2 projects (portaudio & portaudio_static) each with 6 configurations: Win32/x64 in both Debug, Release and ReleaseMinDependency, + last of which removes dependency of all but basic OS system DLLs. + + 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. Set the PA_USE_ASIO preprocessor symbol to zero (i.e. PA_USE_ASIO=0) in the project properties. + In VS2005 this can be added under + Project Properties > Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions + + Setting PA_USE_ASIO=0 stops src/os/win/pa_win_hostapis.c + from trying to initialize the PA ASIO implementation. + + D. Remove PaAsio_* entry points from portaudio.def, or comment them out with ; + + +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_USE_WMME, PA_USE_DSOUND, PA_USE_ASIO, PA_USE_WASAPI and PA_USE_WDMKS + +----- +David Viens, davidv@plogue.com +Robert Bielik, robert@xponaut.se diff --git a/3rdparty/portaudio/configure b/3rdparty/portaudio/configure index 733ebd8249..528023a3be 100644 --- a/3rdparty/portaudio/configure +++ b/3rdparty/portaudio/configure @@ -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 - 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 + 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_sysroot="-isysroot /Developer/SDKs/MacOSX10.5.sdk" + else + mac_version_min="-mmacosx-version-min=10.3" + 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 diff --git a/3rdparty/portaudio/configure.in b/3rdparty/portaudio/configure.in index 3fd768a527..58cd61e43e 100644 --- a/3rdparty/portaudio/configure.in +++ b/3rdparty/portaudio/configure.in @@ -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 - 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 + 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_sysroot="-isysroot /Developer/SDKs/MacOSX10.5.sdk" + else + mac_version_min="-mmacosx-version-min=10.3" + 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 diff --git a/3rdparty/portaudio/doc/src/mainpage.dox b/3rdparty/portaudio/doc/src/mainpage.dox index 8f40edeb79..bbcbd628bc 100644 --- a/3rdparty/portaudio/doc/src/mainpage.dox +++ b/3rdparty/portaudio/doc/src/mainpage.dox @@ -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 - The PortAudio wiki +- @ref java_binding
+Documentation for the Java JNI interface to PortAudio @section developer_resources Developer Resources diff --git a/3rdparty/portaudio/doc/src/tutorial/compile_mac_coreaudio.dox b/3rdparty/portaudio/doc/src/tutorial/compile_mac_coreaudio.dox index 6984d1e7c6..e16ce33dbd 100644 --- a/3rdparty/portaudio/doc/src/tutorial/compile_mac_coreaudio.dox +++ b/3rdparty/portaudio/doc/src/tutorial/compile_mac_coreaudio.dox @@ -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 @@ -118,4 +119,4 @@ Note, there used to be a special makefile just for darwin. This is no longer sup Back to the Tutorial: \ref tutorial_start -*/ \ No newline at end of file +*/ diff --git a/3rdparty/portaudio/doc/src/tutorial/querying_devices.dox b/3rdparty/portaudio/doc/src/tutorial/querying_devices.dox index 0c23274954..1eac41a278 100644 --- a/3rdparty/portaudio/doc/src/tutorial/querying_devices.dox +++ b/3rdparty/portaudio/doc/src/tutorial/querying_devices.dox @@ -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 diff --git a/3rdparty/portaudio/doc/src/tutorial/tutorial_start.dox b/3rdparty/portaudio/doc/src/tutorial/tutorial_start.dox index b80bc236e5..d6b5e69fce 100644 --- a/3rdparty/portaudio/doc/src/tutorial/tutorial_start.dox +++ b/3rdparty/portaudio/doc/src/tutorial/tutorial_start.dox @@ -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 tips on programming PortAudio on the PortAudio wiki. -If you are upgrading from V18, you may want to look at the Proposed Enhancements to PortAudio, 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 Proposed Enhancements to PortAudio, 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 diff --git a/3rdparty/portaudio/include/pa_mac_core.h b/3rdparty/portaudio/include/pa_mac_core.h index 1d615feed4..83e40a6ac5 100644 --- a/3rdparty/portaudio/include/pa_mac_core.h +++ b/3rdparty/portaudio/include/pa_mac_core.h @@ -46,7 +46,7 @@ #include "portaudio.h" #include -//#include +#include #ifdef __cplusplus extern "C" { diff --git a/3rdparty/portaudio/include/portaudio.h b/3rdparty/portaudio/include/portaudio.h index b80e1d1ef9..5e11dad017 100644 --- a/3rdparty/portaudio/include/portaudio.h +++ b/3rdparty/portaudio/include/portaudio.h @@ -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. diff --git a/3rdparty/portaudio/pablio/README.txt b/3rdparty/portaudio/pablio/README.txt index b0d95d9b16..a73a8e0c0b 100644 --- a/3rdparty/portaudio/pablio/README.txt +++ b/3rdparty/portaudio/pablio/README.txt @@ -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 diff --git a/3rdparty/portaudio/pablio/pablio.h b/3rdparty/portaudio/pablio/pablio.h index d996a03429..e941bcf228 100644 --- a/3rdparty/portaudio/pablio/pablio.h +++ b/3rdparty/portaudio/pablio/pablio.h @@ -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 #include #include "portaudio.h" -#include "ringbuffer.h" +#include "pa_ringbuffer.h" #include typedef struct diff --git a/3rdparty/portaudio/src/common/pa_front.c b/3rdparty/portaudio/src/common/pa_front.c index 957d1eac47..95d238b41e 100644 --- a/3rdparty/portaudio/src/common/pa_front.c +++ b/3rdparty/portaudio/src/common/pa_front.c @@ -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 ) diff --git a/3rdparty/portaudio/src/common/pa_hostapi.h b/3rdparty/portaudio/src/common/pa_hostapi.h index 1437f629dc..d38b8fe916 100644 --- a/3rdparty/portaudio/src/common/pa_hostapi.h +++ b/3rdparty/portaudio/src/common/pa_hostapi.h @@ -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 diff --git a/3rdparty/portaudio/src/common/pa_ringbuffer.h b/3rdparty/portaudio/src/common/pa_ringbuffer.h index 51577f0707..0cab3a58e0 100644 --- a/3rdparty/portaudio/src/common/pa_ringbuffer.h +++ b/3rdparty/portaudio/src/common/pa_ringbuffer.h @@ -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__) diff --git a/3rdparty/portaudio/src/hostapi/alsa/pa_linux_alsa.c b/3rdparty/portaudio/src/hostapi/alsa/pa_linux_alsa.c index 796b612f23..c51726cb3d 100644 --- a/3rdparty/portaudio/src/hostapi/alsa/pa_linux_alsa.c +++ b/3rdparty/portaudio/src/hostapi/alsa/pa_linux_alsa.c @@ -1,5 +1,5 @@ /* - * $Id: pa_linux_alsa.c 1822 2012-03-28 16:14:49Z dmitrykos $ + * $Id: pa_linux_alsa.c 1834 2012-05-18 16:04:30Z gineera $ * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * ALSA implementation by Joshua Haberman and Arve Knudsen @@ -7,7 +7,6 @@ * Copyright (c) 2002 Joshua Haberman * Copyright (c) 2005-2009 Arve Knudsen * Copyright (c) 2008 Kevin Kofler - * Copyright (c) 2011 Dmitry Kostjuchenko * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk @@ -80,7 +79,7 @@ #include "pa_linux_alsa.h" -/* Add missing define (for compatibility with older ALSA versions). */ +/* Add missing define (for compatibility with older ALSA versions) */ #ifndef SND_PCM_TSTAMP_ENABLE #define SND_PCM_TSTAMP_ENABLE SND_PCM_TSTAMP_MMAP #endif @@ -88,11 +87,8 @@ /* Combine version elements into a single (unsigned) integer */ #define ALSA_VERSION_INT(major, minor, subminor) ((major << 16) | (minor << 8) | subminor) -/* Specifies that hardware audio sample needs byte-swapping into platfom native value representation. */ -#define paSwapEndian ((PaSampleFormat) 0x40000000) /**< @see PaSampleFormat */ - -/* Remove paSwapEndian and paNonInterleaved flags to get pure format value. */ -#define PA_ALSA_TO_FORMAT(X) ((X) & ~(paSwapEndian|paNonInterleaved)) +/* The acceptable tolerance of sample rate set, to that requested (as a ratio, eg 50 is 2%, 100 is 1%) */ +#define RATE_MAX_DEVIATE_RATIO 100 /* Defines Alsa function types and pointers to these functions. */ #define _PA_DEFINE_FUNC(x) typedef typeof(x) x##_ft; static x##_ft *alsa_##x = 0 @@ -197,9 +193,6 @@ _PA_DEFINE_FUNC(snd_pcm_info_set_subdevice); _PA_DEFINE_FUNC(snd_pcm_info_set_stream); _PA_DEFINE_FUNC(snd_pcm_info_get_name); _PA_DEFINE_FUNC(snd_pcm_info_get_card); -_PA_DEFINE_FUNC(snd_pcm_info_get_subdevices_count); -_PA_DEFINE_FUNC(snd_pcm_info_get_subdevice_name); -_PA_DEFINE_FUNC(snd_pcm_info_get_subdevices_avail); #define alsa_snd_pcm_info_alloca(ptr) __alsa_snd_alloca(ptr, snd_pcm_info) _PA_DEFINE_FUNC(snd_ctl_pcm_next_device); @@ -261,7 +254,7 @@ int _PA_LOCAL_IMPL(snd_pcm_hw_params_set_rate_near) (snd_pcm_t *pcm, snd_pcm_hw_ { int ret; - if ((ret = alsa_snd_pcm_hw_params_set_rate(pcm, params, (*val), (*dir))) < 0) + if(( ret = alsa_snd_pcm_hw_params_set_rate(pcm, params, (*val), (*dir)) ) < 0 ) return ret; return 0; @@ -271,7 +264,7 @@ int _PA_LOCAL_IMPL(snd_pcm_hw_params_set_buffer_size_near) (snd_pcm_t *pcm, snd_ { int ret; - if ((ret = alsa_snd_pcm_hw_params_set_buffer_size(pcm, params, (*val))) < 0) + if(( ret = alsa_snd_pcm_hw_params_set_buffer_size(pcm, params, (*val)) ) < 0 ) return ret; return 0; @@ -281,7 +274,7 @@ int _PA_LOCAL_IMPL(snd_pcm_hw_params_set_period_size_near) (snd_pcm_t *pcm, snd_ { int ret; - if ((ret = alsa_snd_pcm_hw_params_set_period_size(pcm, params, (*val), (*dir))) < 0) + if(( ret = alsa_snd_pcm_hw_params_set_period_size(pcm, params, (*val), (*dir)) ) < 0 ) return ret; return 0; @@ -330,9 +323,9 @@ int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_buffer_size_max) (const snd_pcm_hw_para snd_pcm_uframes_t pmax = 0; unsigned int pcnt = 0; - if ((ret = _PA_LOCAL_IMPL(snd_pcm_hw_params_get_period_size_max)(params, &pmax, &dir)) < 0) + if(( ret = _PA_LOCAL_IMPL(snd_pcm_hw_params_get_period_size_max)(params, &pmax, &dir) ) < 0 ) return ret; - if ((ret = _PA_LOCAL_IMPL(snd_pcm_hw_params_get_periods_max)(params, &pcnt, &dir)) < 0) + if(( ret = _PA_LOCAL_IMPL(snd_pcm_hw_params_get_periods_max)(params, &pcnt, &dir) ) < 0 ) return ret; (*val) = pmax * pcnt; @@ -363,7 +356,7 @@ static int PaAlsa_LoadLibrary() PA_DEBUG(( "%s: loading ALSA library file - %s\n", __FUNCTION__, g_AlsaLibName )); dlerror(); - g_AlsaLib = dlopen(g_AlsaLibName, (RTLD_NOW|RTLD_GLOBAL)); + g_AlsaLib = dlopen(g_AlsaLibName, (RTLD_NOW|RTLD_GLOBAL) ); if (g_AlsaLib == NULL) { PA_DEBUG(( "%s: failed dlopen() ALSA library file - %s, error: %s\n", __FUNCTION__, g_AlsaLibName, dlerror() )); @@ -373,8 +366,8 @@ static int PaAlsa_LoadLibrary() PA_DEBUG(( "%s: loading ALSA API\n", __FUNCTION__ )); #define _PA_LOAD_FUNC(x) do { \ - alsa_##x = dlsym(g_AlsaLib, #x); \ - if (alsa_##x == NULL) { \ + alsa_##x = dlsym( g_AlsaLib, #x ); \ + if( alsa_##x == NULL ) { \ PA_DEBUG(( "%s: symbol [%s] not found in - %s, error: %s\n", __FUNCTION__, #x, g_AlsaLibName, dlerror() )); }\ } while(0) @@ -384,137 +377,134 @@ static int PaAlsa_LoadLibrary() #endif -_PA_LOAD_FUNC(snd_pcm_open); -_PA_LOAD_FUNC(snd_pcm_close); -_PA_LOAD_FUNC(snd_pcm_nonblock); -_PA_LOAD_FUNC(snd_pcm_frames_to_bytes); -_PA_LOAD_FUNC(snd_pcm_prepare); -_PA_LOAD_FUNC(snd_pcm_start); -_PA_LOAD_FUNC(snd_pcm_resume); -_PA_LOAD_FUNC(snd_pcm_wait); -_PA_LOAD_FUNC(snd_pcm_state); -_PA_LOAD_FUNC(snd_pcm_avail_update); -_PA_LOAD_FUNC(snd_pcm_areas_silence); -_PA_LOAD_FUNC(snd_pcm_mmap_begin); -_PA_LOAD_FUNC(snd_pcm_mmap_commit); -_PA_LOAD_FUNC(snd_pcm_readi); -_PA_LOAD_FUNC(snd_pcm_readn); -_PA_LOAD_FUNC(snd_pcm_writei); -_PA_LOAD_FUNC(snd_pcm_writen); -_PA_LOAD_FUNC(snd_pcm_drain); -_PA_LOAD_FUNC(snd_pcm_recover); -_PA_LOAD_FUNC(snd_pcm_drop); -_PA_LOAD_FUNC(snd_pcm_area_copy); -_PA_LOAD_FUNC(snd_pcm_poll_descriptors); -_PA_LOAD_FUNC(snd_pcm_poll_descriptors_count); -_PA_LOAD_FUNC(snd_pcm_poll_descriptors_revents); -_PA_LOAD_FUNC(snd_pcm_format_size); -_PA_LOAD_FUNC(snd_pcm_link); -_PA_LOAD_FUNC(snd_pcm_delay); + _PA_LOAD_FUNC(snd_pcm_open); + _PA_LOAD_FUNC(snd_pcm_close); + _PA_LOAD_FUNC(snd_pcm_nonblock); + _PA_LOAD_FUNC(snd_pcm_frames_to_bytes); + _PA_LOAD_FUNC(snd_pcm_prepare); + _PA_LOAD_FUNC(snd_pcm_start); + _PA_LOAD_FUNC(snd_pcm_resume); + _PA_LOAD_FUNC(snd_pcm_wait); + _PA_LOAD_FUNC(snd_pcm_state); + _PA_LOAD_FUNC(snd_pcm_avail_update); + _PA_LOAD_FUNC(snd_pcm_areas_silence); + _PA_LOAD_FUNC(snd_pcm_mmap_begin); + _PA_LOAD_FUNC(snd_pcm_mmap_commit); + _PA_LOAD_FUNC(snd_pcm_readi); + _PA_LOAD_FUNC(snd_pcm_readn); + _PA_LOAD_FUNC(snd_pcm_writei); + _PA_LOAD_FUNC(snd_pcm_writen); + _PA_LOAD_FUNC(snd_pcm_drain); + _PA_LOAD_FUNC(snd_pcm_recover); + _PA_LOAD_FUNC(snd_pcm_drop); + _PA_LOAD_FUNC(snd_pcm_area_copy); + _PA_LOAD_FUNC(snd_pcm_poll_descriptors); + _PA_LOAD_FUNC(snd_pcm_poll_descriptors_count); + _PA_LOAD_FUNC(snd_pcm_poll_descriptors_revents); + _PA_LOAD_FUNC(snd_pcm_format_size); + _PA_LOAD_FUNC(snd_pcm_link); + _PA_LOAD_FUNC(snd_pcm_delay); -_PA_LOAD_FUNC(snd_pcm_hw_params_sizeof); -_PA_LOAD_FUNC(snd_pcm_hw_params_malloc); -_PA_LOAD_FUNC(snd_pcm_hw_params_free); -_PA_LOAD_FUNC(snd_pcm_hw_params_any); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_access); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_format); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_channels); -//_PA_LOAD_FUNC(snd_pcm_hw_params_set_periods_near); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_rate_near); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_rate); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_rate_resample); -//_PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_time_near); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_size); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_near); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_min); -//_PA_LOAD_FUNC(snd_pcm_hw_params_set_period_time_near); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_period_size_near); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_periods_integer); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_periods_min); + _PA_LOAD_FUNC(snd_pcm_hw_params_sizeof); + _PA_LOAD_FUNC(snd_pcm_hw_params_malloc); + _PA_LOAD_FUNC(snd_pcm_hw_params_free); + _PA_LOAD_FUNC(snd_pcm_hw_params_any); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_access); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_format); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_channels); +// _PA_LOAD_FUNC(snd_pcm_hw_params_set_periods_near); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_rate_near); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_rate); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_rate_resample); +// _PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_time_near); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_size); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_near); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_min); +// _PA_LOAD_FUNC(snd_pcm_hw_params_set_period_time_near); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_period_size_near); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_periods_integer); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_periods_min); -_PA_LOAD_FUNC(snd_pcm_hw_params_get_buffer_size); -//_PA_LOAD_FUNC(snd_pcm_hw_params_get_period_size); -//_PA_LOAD_FUNC(snd_pcm_hw_params_get_access); -//_PA_LOAD_FUNC(snd_pcm_hw_params_get_periods); -//_PA_LOAD_FUNC(snd_pcm_hw_params_get_rate); -_PA_LOAD_FUNC(snd_pcm_hw_params_get_channels_min); -_PA_LOAD_FUNC(snd_pcm_hw_params_get_channels_max); + _PA_LOAD_FUNC(snd_pcm_hw_params_get_buffer_size); +// _PA_LOAD_FUNC(snd_pcm_hw_params_get_period_size); +// _PA_LOAD_FUNC(snd_pcm_hw_params_get_access); +// _PA_LOAD_FUNC(snd_pcm_hw_params_get_periods); +// _PA_LOAD_FUNC(snd_pcm_hw_params_get_rate); + _PA_LOAD_FUNC(snd_pcm_hw_params_get_channels_min); + _PA_LOAD_FUNC(snd_pcm_hw_params_get_channels_max); -_PA_LOAD_FUNC(snd_pcm_hw_params_test_period_size); -_PA_LOAD_FUNC(snd_pcm_hw_params_test_format); -_PA_LOAD_FUNC(snd_pcm_hw_params_test_access); -_PA_LOAD_FUNC(snd_pcm_hw_params_dump); -_PA_LOAD_FUNC(snd_pcm_hw_params); + _PA_LOAD_FUNC(snd_pcm_hw_params_test_period_size); + _PA_LOAD_FUNC(snd_pcm_hw_params_test_format); + _PA_LOAD_FUNC(snd_pcm_hw_params_test_access); + _PA_LOAD_FUNC(snd_pcm_hw_params_dump); + _PA_LOAD_FUNC(snd_pcm_hw_params); -_PA_LOAD_FUNC(snd_pcm_hw_params_get_periods_min); -_PA_LOAD_FUNC(snd_pcm_hw_params_get_periods_max); -_PA_LOAD_FUNC(snd_pcm_hw_params_set_period_size); -_PA_LOAD_FUNC(snd_pcm_hw_params_get_period_size_min); -_PA_LOAD_FUNC(snd_pcm_hw_params_get_period_size_max); -_PA_LOAD_FUNC(snd_pcm_hw_params_get_buffer_size_max); -_PA_LOAD_FUNC(snd_pcm_hw_params_get_rate_min); -_PA_LOAD_FUNC(snd_pcm_hw_params_get_rate_max); -_PA_LOAD_FUNC(snd_pcm_hw_params_get_rate_numden); + _PA_LOAD_FUNC(snd_pcm_hw_params_get_periods_min); + _PA_LOAD_FUNC(snd_pcm_hw_params_get_periods_max); + _PA_LOAD_FUNC(snd_pcm_hw_params_set_period_size); + _PA_LOAD_FUNC(snd_pcm_hw_params_get_period_size_min); + _PA_LOAD_FUNC(snd_pcm_hw_params_get_period_size_max); + _PA_LOAD_FUNC(snd_pcm_hw_params_get_buffer_size_max); + _PA_LOAD_FUNC(snd_pcm_hw_params_get_rate_min); + _PA_LOAD_FUNC(snd_pcm_hw_params_get_rate_max); + _PA_LOAD_FUNC(snd_pcm_hw_params_get_rate_numden); -_PA_LOAD_FUNC(snd_pcm_sw_params_sizeof); -_PA_LOAD_FUNC(snd_pcm_sw_params_malloc); -_PA_LOAD_FUNC(snd_pcm_sw_params_current); -_PA_LOAD_FUNC(snd_pcm_sw_params_set_avail_min); -_PA_LOAD_FUNC(snd_pcm_sw_params); -_PA_LOAD_FUNC(snd_pcm_sw_params_free); -_PA_LOAD_FUNC(snd_pcm_sw_params_set_start_threshold); -_PA_LOAD_FUNC(snd_pcm_sw_params_set_stop_threshold); -_PA_LOAD_FUNC(snd_pcm_sw_params_get_boundary); -_PA_LOAD_FUNC(snd_pcm_sw_params_set_silence_threshold); -_PA_LOAD_FUNC(snd_pcm_sw_params_set_silence_size); -_PA_LOAD_FUNC(snd_pcm_sw_params_set_xfer_align); -_PA_LOAD_FUNC(snd_pcm_sw_params_set_tstamp_mode); + _PA_LOAD_FUNC(snd_pcm_sw_params_sizeof); + _PA_LOAD_FUNC(snd_pcm_sw_params_malloc); + _PA_LOAD_FUNC(snd_pcm_sw_params_current); + _PA_LOAD_FUNC(snd_pcm_sw_params_set_avail_min); + _PA_LOAD_FUNC(snd_pcm_sw_params); + _PA_LOAD_FUNC(snd_pcm_sw_params_free); + _PA_LOAD_FUNC(snd_pcm_sw_params_set_start_threshold); + _PA_LOAD_FUNC(snd_pcm_sw_params_set_stop_threshold); + _PA_LOAD_FUNC(snd_pcm_sw_params_get_boundary); + _PA_LOAD_FUNC(snd_pcm_sw_params_set_silence_threshold); + _PA_LOAD_FUNC(snd_pcm_sw_params_set_silence_size); + _PA_LOAD_FUNC(snd_pcm_sw_params_set_xfer_align); + _PA_LOAD_FUNC(snd_pcm_sw_params_set_tstamp_mode); -_PA_LOAD_FUNC(snd_pcm_info); -_PA_LOAD_FUNC(snd_pcm_info_sizeof); -_PA_LOAD_FUNC(snd_pcm_info_malloc); -_PA_LOAD_FUNC(snd_pcm_info_free); -_PA_LOAD_FUNC(snd_pcm_info_set_device); -_PA_LOAD_FUNC(snd_pcm_info_set_subdevice); -_PA_LOAD_FUNC(snd_pcm_info_set_stream); -_PA_LOAD_FUNC(snd_pcm_info_get_name); -_PA_LOAD_FUNC(snd_pcm_info_get_card); -_PA_LOAD_FUNC(snd_pcm_info_get_subdevices_count); -_PA_LOAD_FUNC(snd_pcm_info_get_subdevice_name); -_PA_LOAD_FUNC(snd_pcm_info_get_subdevices_avail); + _PA_LOAD_FUNC(snd_pcm_info); + _PA_LOAD_FUNC(snd_pcm_info_sizeof); + _PA_LOAD_FUNC(snd_pcm_info_malloc); + _PA_LOAD_FUNC(snd_pcm_info_free); + _PA_LOAD_FUNC(snd_pcm_info_set_device); + _PA_LOAD_FUNC(snd_pcm_info_set_subdevice); + _PA_LOAD_FUNC(snd_pcm_info_set_stream); + _PA_LOAD_FUNC(snd_pcm_info_get_name); + _PA_LOAD_FUNC(snd_pcm_info_get_card); -_PA_LOAD_FUNC(snd_ctl_pcm_next_device); -_PA_LOAD_FUNC(snd_ctl_pcm_info); -_PA_LOAD_FUNC(snd_ctl_open); -_PA_LOAD_FUNC(snd_ctl_close); -_PA_LOAD_FUNC(snd_ctl_card_info_malloc); -_PA_LOAD_FUNC(snd_ctl_card_info_free); -_PA_LOAD_FUNC(snd_ctl_card_info); -_PA_LOAD_FUNC(snd_ctl_card_info_sizeof); -_PA_LOAD_FUNC(snd_ctl_card_info_get_name); + _PA_LOAD_FUNC(snd_ctl_pcm_next_device); + _PA_LOAD_FUNC(snd_ctl_pcm_info); + _PA_LOAD_FUNC(snd_ctl_open); + _PA_LOAD_FUNC(snd_ctl_close); + _PA_LOAD_FUNC(snd_ctl_card_info_malloc); + _PA_LOAD_FUNC(snd_ctl_card_info_free); + _PA_LOAD_FUNC(snd_ctl_card_info); + _PA_LOAD_FUNC(snd_ctl_card_info_sizeof); + _PA_LOAD_FUNC(snd_ctl_card_info_get_name); -_PA_LOAD_FUNC(snd_config); -_PA_LOAD_FUNC(snd_config_update); -_PA_LOAD_FUNC(snd_config_search); -_PA_LOAD_FUNC(snd_config_iterator_entry); -_PA_LOAD_FUNC(snd_config_iterator_first); -_PA_LOAD_FUNC(snd_config_iterator_end); -_PA_LOAD_FUNC(snd_config_iterator_next); -_PA_LOAD_FUNC(snd_config_get_string); -_PA_LOAD_FUNC(snd_config_get_id); -_PA_LOAD_FUNC(snd_config_update_free_global); + _PA_LOAD_FUNC(snd_config); + _PA_LOAD_FUNC(snd_config_update); + _PA_LOAD_FUNC(snd_config_search); + _PA_LOAD_FUNC(snd_config_iterator_entry); + _PA_LOAD_FUNC(snd_config_iterator_first); + _PA_LOAD_FUNC(snd_config_iterator_end); + _PA_LOAD_FUNC(snd_config_iterator_next); + _PA_LOAD_FUNC(snd_config_get_string); + _PA_LOAD_FUNC(snd_config_get_id); + _PA_LOAD_FUNC(snd_config_update_free_global); -_PA_LOAD_FUNC(snd_pcm_status); -_PA_LOAD_FUNC(snd_pcm_status_sizeof); -_PA_LOAD_FUNC(snd_pcm_status_get_tstamp); -_PA_LOAD_FUNC(snd_pcm_status_get_state); -_PA_LOAD_FUNC(snd_pcm_status_get_trigger_tstamp); -_PA_LOAD_FUNC(snd_pcm_status_get_delay); + _PA_LOAD_FUNC(snd_pcm_status); + _PA_LOAD_FUNC(snd_pcm_status_sizeof); + _PA_LOAD_FUNC(snd_pcm_status_get_tstamp); + _PA_LOAD_FUNC(snd_pcm_status_get_state); + _PA_LOAD_FUNC(snd_pcm_status_get_trigger_tstamp); + _PA_LOAD_FUNC(snd_pcm_status_get_delay); -_PA_LOAD_FUNC(snd_card_next); -_PA_LOAD_FUNC(snd_asoundlib_version); -_PA_LOAD_FUNC(snd_strerror); -_PA_LOAD_FUNC(snd_output_stdio_attach); + _PA_LOAD_FUNC(snd_card_next); + _PA_LOAD_FUNC(snd_asoundlib_version); + _PA_LOAD_FUNC(snd_strerror); + _PA_LOAD_FUNC(snd_output_stdio_attach); #undef _PA_LOAD_FUNC #ifdef PA_ALSA_DYNAMIC @@ -522,7 +512,7 @@ _PA_LOAD_FUNC(snd_output_stdio_attach); #define _PA_VALIDATE_LOAD_REPLACEMENT(x)\ do {\ - if (alsa_##x == NULL)\ + if( alsa_##x == NULL )\ {\ alsa_##x = &_PA_LOCAL_IMPL(x);\ PA_DEBUG(( "%s: replacing [%s] with local implementation\n", __FUNCTION__, #x ));\ @@ -738,9 +728,6 @@ static const PaAlsaDeviceInfo *GetDeviceInfo( const PaUtilHostApiRepresentation return (const PaAlsaDeviceInfo *)hostApi->deviceInfos[device]; } -static void CheckAndReplaceConverterForSwapEndian(PaAlsaStream *stream, PaSampleFormat hostInputSampleFormat, - PaSampleFormat hostOutputSampleFormat); - /** Uncommented because AlsaErrorHandler is unused for anything good yet. If AlsaErrorHandler is to be used, do not forget to register this callback in PaAlsa_Initialize, and unregister in Terminate. */ @@ -888,6 +875,7 @@ static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, in if( SetApproximateSampleRate( pcm, hwParams, defaultSr ) < 0 ) { defaultSr = -1.; + alsa_snd_pcm_hw_params_any( pcm, hwParams ); /* Clear any params (rate) that might have been set */ PA_DEBUG(( "%s: Original default samplerate failed, trying again ..\n", __FUNCTION__ )); } } @@ -895,7 +883,10 @@ static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, in if( defaultSr < 0. ) /* Default sample rate not set */ { unsigned int sampleRate = 44100; /* Will contain approximate rate returned by alsa-lib */ - if( alsa_snd_pcm_hw_params_set_rate_near( pcm, hwParams, &sampleRate, NULL ) < 0) + + /* Don't allow rate resampling when probing for the default rate (but ignore if this call fails) */ + alsa_snd_pcm_hw_params_set_rate_resample( pcm, hwParams, 0 ); + if( alsa_snd_pcm_hw_params_set_rate_near( pcm, hwParams, &sampleRate, NULL ) < 0 ) { result = paUnanticipatedHostError; goto error; @@ -937,8 +928,9 @@ static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, in */ ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &lowLatency ), paUnanticipatedHostError ); - /* Have to reset hwParams, to set new buffer size */ + /* Have to reset hwParams, to set new buffer size; need to also set sample rate again */ ENSURE_( alsa_snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError ); + ENSURE_( SetApproximateSampleRate( pcm, hwParams, defaultSr ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &highLatency ), paUnanticipatedHostError ); *minChannels = (int)minChans; @@ -1027,11 +1019,11 @@ HwDevInfo predefinedNames[] = { { "AndroidPlayback_ExtraDockSpeaker_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_TvOut_normal", NULL, 0, 1, 0 }, - { "AndroidRecord_Microphone", NULL, 0, 0, 1 }, + { "AndroidRecord_Microphone", NULL, 0, 0, 1 }, { "AndroidRecord_Earpiece_normal", NULL, 0, 0, 1 }, - { "AndroidRecord_Speaker_normal", NULL, 0, 0, 1 }, + { "AndroidRecord_Speaker_normal", NULL, 0, 0, 1 }, { "AndroidRecord_Headset_normal", NULL, 0, 0, 1 }, - { "AndroidRecord_Bluetooth_normal", NULL, 0, 0, 1 }, + { "AndroidRecord_Bluetooth_normal", NULL, 0, 0, 1 }, { "AndroidRecord_Speaker_Headset_normal", NULL, 0, 0, 1 }, { NULL, NULL, 0, 1, 0 } @@ -1115,7 +1107,7 @@ static int OpenPcm( snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, } else { - if (ret < 0) + if( ret < 0 ) PA_DEBUG(( "%s: Opened device '%s' ptr[%p] - result: [%d:%s]\n", __FUNCTION__, name, *pcmp, ret, alsa_snd_strerror(ret) )); } @@ -1145,7 +1137,7 @@ static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* d if( GropeDevice( pcm, deviceName->isPlug, StreamDirection_In, blocking, devInfo ) != paNoError ) { /* Error */ - PA_DEBUG(("%s: Failed groping %s for capture\n", __FUNCTION__, deviceName->alsaName)); + PA_DEBUG(( "%s: Failed groping %s for capture\n", __FUNCTION__, deviceName->alsaName )); goto end; } } @@ -1157,16 +1149,16 @@ static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* d if( GropeDevice( pcm, deviceName->isPlug, StreamDirection_Out, blocking, devInfo ) != paNoError ) { /* Error */ - PA_DEBUG(("%s: Failed groping %s for playback\n", __FUNCTION__, deviceName->alsaName)); + PA_DEBUG(( "%s: Failed groping %s for playback\n", __FUNCTION__, deviceName->alsaName )); goto end; } } baseDeviceInfo->structVersion = 2; - baseDeviceInfo->hostApi = alsaApi->hostApiIndex; - baseDeviceInfo->name = deviceName->name; - devInfo->alsaName = deviceName->alsaName; - devInfo->isPlug = deviceName->isPlug; + baseDeviceInfo->hostApi = alsaApi->hostApiIndex; + baseDeviceInfo->name = deviceName->name; + devInfo->alsaName = deviceName->alsaName; + devInfo->isPlug = deviceName->isPlug; /* A: Storing pointer to PaAlsaDeviceInfo object as pointer to PaDeviceInfo object. * Should now be safe to add device info, unless the device supports neither capture nor playback @@ -1174,19 +1166,19 @@ static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* d if( baseDeviceInfo->maxInputChannels > 0 || baseDeviceInfo->maxOutputChannels > 0 ) { /* Make device default if there isn't already one or it is the ALSA "default" device */ - if( (baseApi->info.defaultInputDevice == paNoDevice || - !strcmp(deviceName->alsaName, "default" )) && baseDeviceInfo->maxInputChannels > 0 ) + if( ( baseApi->info.defaultInputDevice == paNoDevice || + !strcmp( deviceName->alsaName, "default" ) ) && baseDeviceInfo->maxInputChannels > 0 ) { baseApi->info.defaultInputDevice = *devIdx; - PA_DEBUG(("Default input device: %s\n", deviceName->name)); + PA_DEBUG(( "Default input device: %s\n", deviceName->name )); } - if( (baseApi->info.defaultOutputDevice == paNoDevice || - !strcmp(deviceName->alsaName, "default" )) && baseDeviceInfo->maxOutputChannels > 0 ) + if( ( baseApi->info.defaultOutputDevice == paNoDevice || + !strcmp( deviceName->alsaName, "default" ) ) && baseDeviceInfo->maxOutputChannels > 0 ) { baseApi->info.defaultOutputDevice = *devIdx; - PA_DEBUG(("Default output device: %s\n", deviceName->name)); + PA_DEBUG(( "Default output device: %s\n", deviceName->name )); } - PA_DEBUG(("%s: Adding device %s: %d\n", __FUNCTION__, deviceName->name, *devIdx)); + PA_DEBUG(( "%s: Adding device %s: %d\n", __FUNCTION__, deviceName->name, *devIdx )); baseApi->deviceInfos[*devIdx] = (PaDeviceInfo *) devInfo; (*devIdx) += 1; } @@ -1213,6 +1205,7 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi ) snd_pcm_info_t *pcmInfo; int res; int blocking = SND_PCM_NONBLOCK; + char alsaCardName[50]; #ifdef PA_ENABLE_DEBUG_OUTPUT PaTime startTime = PaUtil_GetTime(); #endif @@ -1237,118 +1230,74 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi ) alsa_snd_pcm_info_alloca( &pcmInfo ); while( alsa_snd_card_next( &cardIdx ) == 0 && cardIdx >= 0 ) { - char alsaCardNameId[64] = { 0 }; char *cardName; int devIdx = -1; snd_ctl_t *ctl; + char buf[50]; - /* Make card name */ - snprintf( alsaCardNameId, sizeof (alsaCardNameId)-1, "hw:%d", cardIdx ); + snprintf( alsaCardName, sizeof (alsaCardName), "hw:%d", cardIdx ); - /* Try opening card */ - if( alsa_snd_ctl_open( &ctl, alsaCardNameId, 0 ) < 0 ) + /* Acquire name of card */ + if( alsa_snd_ctl_open( &ctl, alsaCardName, 0 ) < 0 ) { /* Unable to open card :( */ - PA_DEBUG(( "%s: Unable to open device %s\n", __FUNCTION__, alsaCardNameId )); + PA_DEBUG(( "%s: Unable to open device %s\n", __FUNCTION__, alsaCardName )); continue; } alsa_snd_ctl_card_info( ctl, cardInfo ); PA_ENSURE( PaAlsa_StrDup( alsaApi, &cardName, alsa_snd_ctl_card_info_get_name( cardInfo )) ); - PA_DEBUG(( "%s: Open card: id[%s] name[%s]\n", __FUNCTION__, alsaCardNameId, cardName )); - - /* Iterate devices */ while( alsa_snd_ctl_pcm_next_device( ctl, &devIdx ) == 0 && devIdx >= 0 ) { char *alsaDeviceName, *deviceName; size_t len; int hasPlayback = 0, hasCapture = 0; - int subDevIdx, subDevCount = 1; + snprintf( buf, sizeof (buf), "hw:%d,%d", cardIdx, devIdx ); - PA_DEBUG(( "%s: - idx = %d:\n", __FUNCTION__, devIdx )); - - /* Make this device current */ + /* Obtain info about this particular device */ alsa_snd_pcm_info_set_device( pcmInfo, devIdx ); - - /* Iterate sub-devices */ - for( subDevIdx = 0; subDevIdx < subDevCount; ++subDevIdx ) + alsa_snd_pcm_info_set_subdevice( pcmInfo, 0 ); + alsa_snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_CAPTURE ); + if( alsa_snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 ) { - char buf[64] = { 0 }; - - /* Make this sub-device current */ - alsa_snd_pcm_info_set_subdevice( pcmInfo, subDevIdx ); - - /* Test for Capture capability */ - alsa_snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_CAPTURE ); - if( alsa_snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 ) - { - hasCapture = 1; - } - - /* Test for Playback capability */ - alsa_snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_PLAYBACK ); - if( alsa_snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 ) - { - hasPlayback = 1; - } - - /* If neither supported, such device is stub or failed */ - if( !hasPlayback && !hasCapture ) - { - continue; - } - - /* Get sub-device count */ - if( subDevIdx == 0 ) - { - subDevCount = alsa_snd_pcm_info_get_subdevices_count( pcmInfo ); - PA_DEBUG(( "%s: sub-devices: %d/%d\n", __FUNCTION__, alsa_snd_pcm_info_get_subdevices_avail( pcmInfo ), subDevCount)); - } - - PA_DEBUG(( "%s: - sub: %d\n", __FUNCTION__, subDevIdx )); - if( hasCapture ) PA_DEBUG(( "%s: - cap: CAPTURE\n", __FUNCTION__ )); - if( hasPlayback ) PA_DEBUG(( "%s: - cap: PLAYBACK\n", __FUNCTION__ )); - - /* Make name Id */ - snprintf( buf, sizeof(buf)-1, ( subDevCount > 1 ? "hw:%d,%d,%d" : "hw:%d,%d" ), cardIdx, devIdx, subDevIdx ); - - /* Make name */ - if( subDevCount <= 1 ) - { - const char *snd_deviceName = alsa_snd_pcm_info_get_name( pcmInfo ); - - len = snprintf( NULL, 0, "%s: %s (%s)", cardName, snd_deviceName, buf ) + 1; - PA_UNLESS( deviceName = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ), paInsufficientMemory ); - snprintf( deviceName, len, "%s: %s (%s)", cardName, snd_deviceName, buf ); - } - else - { - const char *snd_deviceName = alsa_snd_pcm_info_get_name( pcmInfo ); - const char *snd_subDeviceName = alsa_snd_pcm_info_get_subdevice_name( pcmInfo ); - - len = snprintf( NULL, 0, "%s: %s (%s) {%s}", cardName, snd_deviceName, buf, snd_subDeviceName ) + 1; - PA_UNLESS( deviceName = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ), paInsufficientMemory ); - snprintf( deviceName, len, "%s: %s (%s) {%s}", cardName, snd_deviceName, buf, snd_subDeviceName ); - } - - ++numDeviceNames; - if( !hwDevInfos || numDeviceNames > maxDeviceNames ) - { - maxDeviceNames *= 2; - PA_UNLESS( hwDevInfos = (HwDevInfo *) realloc( hwDevInfos, maxDeviceNames * sizeof (HwDevInfo) ), paInsufficientMemory ); - } - - PA_ENSURE( PaAlsa_StrDup( alsaApi, &alsaDeviceName, buf ) ); - - hwDevInfos[ numDeviceNames - 1 ].alsaName = alsaDeviceName; - hwDevInfos[ numDeviceNames - 1 ].name = deviceName; - hwDevInfos[ numDeviceNames - 1 ].isPlug = 0; - hwDevInfos[ numDeviceNames - 1 ].hasPlayback = hasPlayback; - hwDevInfos[ numDeviceNames - 1 ].hasCapture = hasCapture; - - PA_DEBUG(( "%s: Registered device: id[%s] name[%s]\n", __FUNCTION__, alsaDeviceName, deviceName )); + hasCapture = 1; } + + alsa_snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_PLAYBACK ); + if( alsa_snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 ) + { + hasPlayback = 1; + } + + if( !hasPlayback && !hasCapture ) + { + /* Error */ + continue; + } + + /* The length of the string written by snprintf plus terminating 0 */ + len = snprintf( NULL, 0, "%s: %s (%s)", cardName, alsa_snd_pcm_info_get_name( pcmInfo ), buf ) + 1; + PA_UNLESS( deviceName = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ), + paInsufficientMemory ); + snprintf( deviceName, len, "%s: %s (%s)", cardName, + alsa_snd_pcm_info_get_name( pcmInfo ), buf ); + + ++numDeviceNames; + if( !hwDevInfos || numDeviceNames > maxDeviceNames ) + { + maxDeviceNames *= 2; + PA_UNLESS( hwDevInfos = (HwDevInfo *) realloc( hwDevInfos, maxDeviceNames * sizeof (HwDevInfo) ), + paInsufficientMemory ); + } + + PA_ENSURE( PaAlsa_StrDup( alsaApi, &alsaDeviceName, buf ) ); + + hwDevInfos[ numDeviceNames - 1 ].alsaName = alsaDeviceName; + hwDevInfos[ numDeviceNames - 1 ].name = deviceName; + hwDevInfos[ numDeviceNames - 1 ].isPlug = 0; + hwDevInfos[ numDeviceNames - 1 ].hasPlayback = hasPlayback; + hwDevInfos[ numDeviceNames - 1 ].hasCapture = hasCapture; } alsa_snd_ctl_close( ctl ); } @@ -1361,7 +1310,7 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi ) PA_DEBUG(( "Updating snd_config\n" )); } assert( *alsa_snd_config ); - if( (res = alsa_snd_config_search( *alsa_snd_config, "pcm", &topNode )) >= 0 ) + if( ( res = alsa_snd_config_search( *alsa_snd_config, "pcm", &topNode ) ) >= 0 ) { snd_config_iterator_t i, next; @@ -1393,17 +1342,19 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi ) } PA_DEBUG(( "%s: Found plugin [%s] of type [%s]\n", __FUNCTION__, idStr, tpStr )); - PA_UNLESS( alsaDeviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations, strlen(idStr) + 6 ), paInsufficientMemory ); + PA_UNLESS( alsaDeviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations, + strlen(idStr) + 6 ), paInsufficientMemory ); strcpy( alsaDeviceName, idStr ); - - PA_UNLESS( deviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations, strlen(idStr) + 1 ), paInsufficientMemory ); + PA_UNLESS( deviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations, + strlen(idStr) + 1 ), paInsufficientMemory ); strcpy( deviceName, idStr ); ++numDeviceNames; if( !hwDevInfos || numDeviceNames > maxDeviceNames ) { maxDeviceNames *= 2; - PA_UNLESS( hwDevInfos = (HwDevInfo *) realloc( hwDevInfos, maxDeviceNames * sizeof (HwDevInfo) ), paInsufficientMemory ); + PA_UNLESS( hwDevInfos = (HwDevInfo *) realloc( hwDevInfos, maxDeviceNames * sizeof (HwDevInfo) ), + paInsufficientMemory ); } predefined = FindDeviceName( alsaDeviceName ); @@ -1428,10 +1379,12 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi ) PA_DEBUG(( "%s: Iterating over ALSA plugins failed: %s\n", __FUNCTION__, alsa_snd_strerror( res ) )); /* allocate deviceInfo memory based on the number of devices */ - PA_UNLESS( baseApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( alsaApi->allocations, sizeof(PaDeviceInfo*) * (numDeviceNames) ), paInsufficientMemory ); + PA_UNLESS( baseApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( + alsaApi->allocations, sizeof(PaDeviceInfo*) * (numDeviceNames) ), paInsufficientMemory ); /* allocate all device info structs in a contiguous block */ - PA_UNLESS( deviceInfoArray = (PaAlsaDeviceInfo*)PaUtil_GroupAllocateMemory( alsaApi->allocations, sizeof(PaAlsaDeviceInfo) * numDeviceNames ), paInsufficientMemory ); + PA_UNLESS( deviceInfoArray = (PaAlsaDeviceInfo*)PaUtil_GroupAllocateMemory( + alsaApi->allocations, sizeof(PaAlsaDeviceInfo) * numDeviceNames ), paInsufficientMemory ); /* Loop over list of cards, filling in info. If a device is deemed unavailable (can't get name), * it's ignored. @@ -1511,8 +1464,8 @@ static PaError ValidateParameters( const PaStreamParameters *parameters, PaUtilH assert( deviceInfo ); assert( parameters->hostApiSpecificStreamInfo == NULL ); - maxChans = (StreamDirection_In == mode ? deviceInfo->baseDeviceInfo.maxInputChannels : - deviceInfo->baseDeviceInfo.maxOutputChannels); + maxChans = ( StreamDirection_In == mode ? deviceInfo->baseDeviceInfo.maxInputChannels : + deviceInfo->baseDeviceInfo.maxOutputChannels ); PA_UNLESS( parameters->channelCount <= maxChans, paInvalidChannelCount ); error: @@ -1528,58 +1481,32 @@ static PaSampleFormat GetAvailableFormats( snd_pcm_t *pcm ) alsa_snd_pcm_hw_params_any( pcm, hwParams ); - if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT ) >= 0 ) + if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT ) >= 0) available |= paFloat32; - if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S32 ) >= 0 ) + if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S32 ) >= 0) available |= paInt32; - if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) >= 0 ) +#ifdef PA_LITTLE_ENDIAN + if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) >= 0) available |= paInt24; - else - if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0 ) +#elif defined PA_BIG_ENDIAN + if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0) available |= paInt24; +#endif - if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16 ) >= 0 ) + if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16 ) >= 0) available |= paInt16; - if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U8 ) >= 0 ) + if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U8 ) >= 0) available |= paUInt8; - if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S8 ) >= 0 ) + if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S8 ) >= 0) available |= paInt8; return available; } -/* Check if format is available in native endianness, if not apply paSwapEndian flag for futher - processing by Alsa swapping converters. -*/ -static void CheckAndApplyEndianSwapToFormat( PaSampleFormat *format, snd_pcm_t *pcm ) -{ - snd_pcm_hw_params_t *hwParams; - alsa_snd_pcm_hw_params_alloca( &hwParams ); - - alsa_snd_pcm_hw_params_any( pcm, hwParams ); - - if( *format & paInt24 ) - { -#ifdef PA_LITTLE_ENDIAN - if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) < 0 ) - { - if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0 ) - *format |= paSwapEndian; - } -#elif defined PA_BIG_ENDIAN - if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) < 0 ) - { - if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) >= 0 ) - *format |= paSwapEndian; - } -#endif - } -} - /* Output to console all formats supported by device */ static void LogAllAvailableFormats( snd_pcm_t *pcm ) { @@ -1704,7 +1631,7 @@ static void LogAllAvailableFormats( snd_pcm_t *pcm ) static snd_pcm_format_t Pa2AlsaFormat( PaSampleFormat paFormat ) { - switch( PA_ALSA_TO_FORMAT(paFormat) ) + switch( paFormat ) { case paFloat32: return SND_PCM_FORMAT_FLOAT; @@ -1714,10 +1641,11 @@ static snd_pcm_format_t Pa2AlsaFormat( PaSampleFormat paFormat ) case paInt24: #ifdef PA_LITTLE_ENDIAN - return ( paFormat & paSwapEndian ? SND_PCM_FORMAT_S24_3BE : SND_PCM_FORMAT_S24_3LE ); + return SND_PCM_FORMAT_S24_3LE; #elif defined PA_BIG_ENDIAN - return ( paFormat & paSwapEndian ? SND_PCM_FORMAT_S24_3LE : SND_PCM_FORMAT_S24_3BE ); + return SND_PCM_FORMAT_S24_3BE; #endif + case paInt32: return SND_PCM_FORMAT_S32; @@ -1820,10 +1748,7 @@ static PaError TestParameters( const PaUtilHostApiRepresentation *hostApi, const /* See if we can find a best possible match */ availableFormats = GetAvailableFormats( pcm ); - PA_ENSURE( hostFormat = PaUtil_SelectClosestAvailableFormat( PA_ALSA_TO_FORMAT(availableFormats), parameters->sampleFormat ) ); - - /* Append endiannes conversion flag */ - CheckAndApplyEndianSwapToFormat( &hostFormat, pcm ); + PA_ENSURE( hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, parameters->sampleFormat ) ); /* Some specific hardware (reported: Audio8 DJ) can fail with assertion during this step. */ ENSURE_( alsa_snd_pcm_hw_params_set_format( pcm, hwParams, Pa2AlsaFormat( hostFormat ) ), paUnanticipatedHostError ); @@ -1831,7 +1756,7 @@ static PaError TestParameters( const PaUtilHostApiRepresentation *hostApi, const { /* It happens that this call fails because the device is busy */ int ret = 0; - if( (ret = alsa_snd_pcm_hw_params( pcm, hwParams )) < 0) + if( ( ret = alsa_snd_pcm_hw_params( pcm, hwParams ) ) < 0 ) { if( -EINVAL == ret ) { @@ -1891,13 +1816,13 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, if( inputChannelCount ) { - if( (result = TestParameters( hostApi, inputParameters, sampleRate, StreamDirection_In )) + if( ( result = TestParameters( hostApi, inputParameters, sampleRate, StreamDirection_In ) ) != paNoError ) goto error; } if ( outputChannelCount ) { - if( (result = TestParameters( hostApi, outputParameters, sampleRate, StreamDirection_Out )) + if( ( result = TestParameters( hostApi, outputParameters, sampleRate, StreamDirection_Out ) ) != paNoError ) goto error; } @@ -1912,7 +1837,6 @@ error: static PaError PaAlsaStreamComponent_Initialize( PaAlsaStreamComponent *self, PaAlsaHostApiRepresentation *alsaApi, const PaStreamParameters *params, StreamDirection streamDir, int callbackMode ) { - PaSampleFormat availableFormats; PaError result = paNoError; PaSampleFormat userSampleFormat = params->sampleFormat, hostSampleFormat = paNoError; assert( params->channelCount > 0 ); @@ -1943,16 +1867,11 @@ static PaError PaAlsaStreamComponent_Initialize( PaAlsaStreamComponent *self, Pa PA_ENSURE( AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm ) ); self->nfds = alsa_snd_pcm_poll_descriptors_count( self->pcm ); - /* Get host sample format */ - availableFormats = GetAvailableFormats( self->pcm ); - PA_ENSURE( hostSampleFormat = PaUtil_SelectClosestAvailableFormat( PA_ALSA_TO_FORMAT(availableFormats), userSampleFormat ) ); - - /* Append endiannes conversion flag */ - CheckAndApplyEndianSwapToFormat( &hostSampleFormat, self->pcm ); + PA_ENSURE( hostSampleFormat = PaUtil_SelectClosestAvailableFormat( GetAvailableFormats( self->pcm ), userSampleFormat ) ); self->hostSampleFormat = hostSampleFormat; self->nativeFormat = Pa2AlsaFormat( hostSampleFormat ); - self->hostInterleaved = self->userInterleaved = !(userSampleFormat & paNonInterleaved); + self->hostInterleaved = self->userInterleaved = !( userSampleFormat & paNonInterleaved ); self->numUserChannels = params->channelCount; self->streamDir = streamDir; self->canMmap = 0; @@ -2033,10 +1952,10 @@ static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *se self->canMmap = alsa_snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 || alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0; - PA_DEBUG(("%s: device MMAP SND_PCM_ACCESS_MMAP_INTERLEAVED: %s\n", __FUNCTION__, (alsa_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__, (alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0 ? "YES" : "NO"))); + PA_DEBUG(( "%s: device MMAP SND_PCM_ACCESS_MMAP_INTERLEAVED: %s\n", __FUNCTION__, ( alsa_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__, ( alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0 ? "YES" : "NO" ) )); - if (!self->canMmap) + if( !self->canMmap ) { accessMode = SND_PCM_ACCESS_RW_INTERLEAVED; alternateAccessMode = SND_PCM_ACCESS_RW_NONINTERLEAVED; @@ -2051,23 +1970,23 @@ static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *se self->canMmap = alsa_snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 || alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0; - PA_DEBUG(("%s: device MMAP SND_PCM_ACCESS_MMAP_NONINTERLEAVED: %s\n", __FUNCTION__, (alsa_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__, (alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0 ? "YES" : "NO"))); + PA_DEBUG((" %s: device MMAP SND_PCM_ACCESS_MMAP_NONINTERLEAVED: %s\n", __FUNCTION__, ( alsa_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__, ( alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0 ? "YES" : "NO" ) )); - if (!self->canMmap) + 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( alsa_snd_pcm_hw_params_set_access( pcm, hwParams, accessMode ) < 0 ) { int err = 0; - if( (err = alsa_snd_pcm_hw_params_set_access( pcm, hwParams, alternateAccessMode )) < 0) + if( ( err = alsa_snd_pcm_hw_params_set_access( pcm, hwParams, alternateAccessMode )) < 0 ) { result = paUnanticipatedHostError; PaUtil_SetLastHostErrorInfo( paALSA, err, alsa_snd_strerror( err ) ); @@ -2080,13 +1999,18 @@ static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *se /* Some specific hardware (reported: Audio8 DJ) can fail with assertion during this step. */ ENSURE_( alsa_snd_pcm_hw_params_set_format( pcm, hwParams, self->nativeFormat ), paUnanticipatedHostError ); - ENSURE_( SetApproximateSampleRate( pcm, hwParams, sr ), paInvalidSampleRate ); - ENSURE_( GetExactSampleRate( hwParams, &sr ), paUnanticipatedHostError ); - /* reject if there's no sample rate within 1% of the one requested */ - if( (fabs( *sampleRate - sr ) / *sampleRate) > 0.01 ) + if( ( result = SetApproximateSampleRate( pcm, hwParams, sr )) != paUnanticipatedHostError ) { - PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr )); - PA_ENSURE( paInvalidSampleRate ); + ENSURE_( GetExactSampleRate( hwParams, &sr ), paUnanticipatedHostError ); + if( result == paInvalidSampleRate ) /* From the SetApproximateSampleRate() call above */ + { /* The sample rate was returned as 'out of tolerance' of the one requested */ + PA_DEBUG(( "%s: Wanted %.3f, closest sample rate was %.3f\n", __FUNCTION__, sampleRate, sr )); + PA_ENSURE( paInvalidSampleRate ); + } + } + else + { + PA_ENSURE( paUnanticipatedHostError ); } ENSURE_( alsa_snd_pcm_hw_params_set_channels( pcm, hwParams, self->numHostChannels ), paInvalidChannelCount ); @@ -2130,9 +2054,9 @@ static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *sel alsa_snd_pcm_hw_params_dump( hwParams, output ); } #endif - ENSURE_(r, paUnanticipatedHostError ); + ENSURE_( r, paUnanticipatedHostError ); } - if (alsa_snd_pcm_hw_params_get_buffer_size != NULL) + if( alsa_snd_pcm_hw_params_get_buffer_size != NULL ) { ENSURE_( alsa_snd_pcm_hw_params_get_buffer_size( hwParams, &self->bufferSize ), paUnanticipatedHostError ); } @@ -2177,7 +2101,7 @@ static PaError PaAlsaStream_Initialize( PaAlsaStream *self, PaAlsaHostApiReprese PaError result = paNoError; assert( self ); - memset( self, 0, sizeof (PaAlsaStream) ); + memset( self, 0, sizeof( PaAlsaStream ) ); if( NULL != callback ) { @@ -2213,8 +2137,8 @@ static PaError PaAlsaStream_Initialize( PaAlsaStream *self, PaAlsaHostApiReprese assert( self->capture.nfds || self->playback.nfds ); - PA_UNLESS( self->pfds = (struct pollfd*)PaUtil_AllocateMemory( (self->capture.nfds + - self->playback.nfds) * sizeof (struct pollfd) ), paInsufficientMemory ); + PA_UNLESS( self->pfds = (struct pollfd*)PaUtil_AllocateMemory( ( self->capture.nfds + + self->playback.nfds ) * sizeof( struct pollfd ) ), paInsufficientMemory ); PaUtil_InitializeCpuLoadMeasurer( &self->cpuLoadMeasurer, sampleRate ); ASSERT_CALL_( PaUnixMutex_Initialize( &self->stateMtx ), paNoError ); @@ -2265,7 +2189,7 @@ static int CalculatePollTimeout( const PaAlsaStream *stream, unsigned long frame */ static unsigned long PaAlsa_AlignBackward(unsigned long v, unsigned long align) { - return ((v - (align ? v % align : 0))); + return ( v - ( align ? v % align : 0 ) ); } /** Align value in forward direction. @@ -2275,8 +2199,8 @@ static unsigned long PaAlsa_AlignBackward(unsigned long v, unsigned long align) */ 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); + 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 @@ -2288,7 +2212,7 @@ static unsigned long PaAlsa_AlignForward(unsigned long v, unsigned long align) */ static unsigned long PaAlsa_GetFramesPerHostBuffer(unsigned long userFramesPerBuffer, PaTime suggestedLatency, double sampleRate) { - unsigned long frames = userFramesPerBuffer + PA_MAX( userFramesPerBuffer, (unsigned long)(suggestedLatency * sampleRate) ); + unsigned long frames = userFramesPerBuffer + PA_MAX( userFramesPerBuffer, (unsigned long)( suggestedLatency * sampleRate ) ); return frames; } @@ -2392,8 +2316,7 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo { if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer * 2, 0 ) == 0 ) framesPerHostBuffer *= 2; - else - if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 ) + else if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 ) framesPerHostBuffer /= 2; } } @@ -2404,8 +2327,7 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo { if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer + framesPerUserBuffer, 0 ) == 0 ) framesPerHostBuffer += framesPerUserBuffer; - else - if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer - framesPerUserBuffer, 0 ) == 0 ) + else if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer - framesPerUserBuffer, 0 ) == 0 ) framesPerHostBuffer -= framesPerUserBuffer; } } @@ -2434,7 +2356,7 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo { while( bufferSize / framesPerHostBuffer < numPeriods ) { - if( framesPerUserBuffer % (framesPerHostBuffer / 2) != 0 ) + if( framesPerUserBuffer % ( framesPerHostBuffer / 2 ) != 0 ) { /* Can't be divided any further */ break; @@ -2488,19 +2410,18 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo if( 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); + 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 = ((minmax_diff == 2) ? max - 1 : max); + framesPerHostBuffer = (( minmax_diff == 2 ) ? max - 1 : 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) )); + PA_DEBUG(( "%s: host buffer period latency = %f\n", __FUNCTION__, (double)( framesPerHostBuffer / sampleRate ) )); /* Try setting period size */ dir = 0; @@ -2583,8 +2504,8 @@ static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double maxPeriodSize = PA_MIN( maxPlayback, maxCapture ); PA_UNLESS( minPeriodSize <= maxPeriodSize, paBadIODeviceCombination ); - desiredBufSz = (snd_pcm_uframes_t)(PA_MIN( outputParameters->suggestedLatency, inputParameters->suggestedLatency ) - * sampleRate); + desiredBufSz = (snd_pcm_uframes_t)( PA_MIN( outputParameters->suggestedLatency, inputParameters->suggestedLatency ) + * sampleRate ); /* Clamp desiredBufSz */ { snd_pcm_uframes_t maxBufferSize; @@ -2598,7 +2519,7 @@ static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double /* Find the closest power of 2 */ e = ilogb( minPeriodSize ); - if( minPeriodSize & (minPeriodSize - 1) ) + if( minPeriodSize & ( minPeriodSize - 1 ) ) e += 1; periodSize = (snd_pcm_uframes_t)pow( 2, e ); @@ -2849,7 +2770,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, /* XXX: Use Bounded by default? Output tends to get stuttery with Fixed ... */ PaUtilHostBufferSizeMode hostBufferSizeMode = paUtilFixedHostBufferSize; - if( (streamFlags & paPlatformSpecificFlags) != 0 ) + if( ( streamFlags & paPlatformSpecificFlags ) != 0 ) return paInvalidFlag; if( inputParameters ) @@ -2884,16 +2805,11 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, hostOutputSampleFormat = stream->playback.hostSampleFormat | (!stream->playback.hostInterleaved ? paNonInterleaved : 0); PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, - numInputChannels, inputSampleFormat, (hostInputSampleFormat & ~paSwapEndian), - numOutputChannels, outputSampleFormat, (hostOutputSampleFormat & ~paSwapEndian), + numInputChannels, inputSampleFormat, hostInputSampleFormat, + numOutputChannels, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, stream->maxFramesPerHostBuffer, hostBufferSizeMode, callback, userData ) ); - /* Some drivers may work only in Big-Endian format (like Audio4DJ), check it and replace - original converter with our specific with swapping capability. - */ - CheckAndReplaceConverterForSwapEndian(stream, hostInputSampleFormat, hostOutputSampleFormat); - /* Ok, buffer processor is initialized, now we can deduce it's latency */ if( numInputChannels > 0 ) stream->streamRepresentation.streamInfo.inputLatency = inputLatency + (PaTime)( @@ -3231,50 +3147,43 @@ static double GetStreamCpuLoad( PaStream* s ) return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } +/* Set the stream sample rate to a nominal value requested; allow only a defined tolerance range */ 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; + unsigned int reqRate, setRate, deviation; assert( pcm && hwParams ); - if( fraction > 0.0 ) - { - if( fraction > 0.5 ) - { - ++approx; - dir = -1; - } - else - dir = 1; - } + /* The Alsa sample rate is set by integer value; also the actual rate may differ */ + reqRate = setRate = (unsigned int) sampleRate; - if( alsa_snd_pcm_hw_params_set_rate( pcm, hwParams, approx, dir ) < 0) + ENSURE_( alsa_snd_pcm_hw_params_set_rate_near( pcm, hwParams, &setRate, NULL ), paUnanticipatedHostError ); + /* The value actually set will be put in 'setRate' (may be way off); check the deviation as a proportion + * of the requested-rate with reference to the max-deviate-ratio (larger values allow less deviation) */ + deviation = abs( setRate - reqRate ); + if( deviation > 0 && deviation * RATE_MAX_DEVIATE_RATIO > reqRate ) result = paInvalidSampleRate; end: - return result; error: - /* Log */ { - unsigned int _min = 0, _max = 0; int _dir = 0; + unsigned int _min = 0, _max = 0; + int _dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_rate_min( hwParams, &_min, &_dir ), paUnanticipatedHostError ); ENSURE_( alsa_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 )); + PA_DEBUG(( "%s: SR min = %u, max = %u, req = %u\n", __FUNCTION__, _min, _max, reqRate )); } - goto end; } /* Return exact sample rate in param sampleRate */ static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate ) { - unsigned int num, den; + unsigned int num, den = 1; int err; assert( hwParams ); @@ -3323,11 +3232,11 @@ static PaError PaAlsaStream_HandleXrun( PaAlsaStream *self ) if( alsa_snd_pcm_status_get_state( st ) == SND_PCM_STATE_XRUN ) { alsa_snd_pcm_status_get_trigger_tstamp( st, &t ); - self->underrun = now * 1000 - ((PaTime) t.tv_sec * 1000 + (PaTime) t.tv_usec / 1000); + self->underrun = now * 1000 - ( (PaTime)t.tv_sec * 1000 + (PaTime)t.tv_usec / 1000 ); - if (!self->playback.canMmap) + if( !self->playback.canMmap ) { - if (alsa_snd_pcm_recover( self->playback.pcm, -EPIPE, 0 ) < 0) + if( alsa_snd_pcm_recover( self->playback.pcm, -EPIPE, 0 ) < 0 ) { PA_DEBUG(( "%s: [playback] non-MMAP-PCM failed recovering from XRUN, will restart Alsa\n", __FUNCTION__ )); ++ restartAlsa; /* did not manage to recover */ @@ -3394,7 +3303,7 @@ static PaError ContinuePoll( const PaAlsaStream *stream, StreamDirection streamD } /* ALSA docs say that negative delay should indicate xrun, but in my experience alsa_snd_pcm_delay returns -EPIPE */ - if( (err = alsa_snd_pcm_delay( otherComponent->pcm, &delay )) < 0 ) + if( ( err = alsa_snd_pcm_delay( otherComponent->pcm, &delay ) ) < 0 ) { if( err == -EPIPE ) { @@ -3470,7 +3379,7 @@ static void CalculateTimeInfo( PaAlsaStream *stream, PaStreamCallbackTimeInfo *t alsa_snd_pcm_status_get_tstamp( capture_status, &capture_timestamp ); capture_time = capture_timestamp.tv_sec + - ((PaTime)capture_timestamp.tv_usec / 1000000.0); + ( (PaTime)capture_timestamp.tv_usec / 1000000.0 ); timeInfo->currentTime = capture_time; capture_delay = alsa_snd_pcm_status_get_delay( capture_status ); @@ -3492,7 +3401,7 @@ static void CalculateTimeInfo( PaAlsaStream *stream, PaStreamCallbackTimeInfo *t /* Hmm, we have both a playback and a capture timestamp. * Hopefully they are the same... */ if( fabs( capture_time - playback_time ) > 0.01 ) - PA_DEBUG(("Capture time and playback time differ by %f\n", fabs(capture_time-playback_time))); + PA_DEBUG(( "Capture time and playback time differ by %f\n", fabs( capture_time-playback_time ) )); } else timeInfo->currentTime = playback_time; @@ -3568,7 +3477,7 @@ error: /* Extract buffer from channel area */ static unsigned char *ExtractAddress( const snd_pcm_channel_area_t *area, snd_pcm_uframes_t offset ) { - return (unsigned char *) area->addr + (area->first + offset * area->step) / 8; + return (unsigned char *) area->addr + ( area->first + offset * area->step ) / 8; } /** Do necessary adaption between user and host channels. @@ -3583,7 +3492,7 @@ static PaError PaAlsaStreamComponent_DoChannelAdaption( PaAlsaStreamComponent *s int i; int unusedChans = self->numHostChannels - self->numUserChannels; unsigned char *src, *dst; - int convertMono = (self->numHostChannels % 2) == 0 && (self->numUserChannels % 2) != 0; + int convertMono = ( self->numHostChannels % 2 ) == 0 && ( self->numUserChannels % 2 ) != 0; assert( StreamDirection_Out == self->streamDir ); @@ -3598,7 +3507,7 @@ static PaError PaAlsaStreamComponent_DoChannelAdaption( PaAlsaStreamComponent *s if( convertMono ) { /* Convert the last user channel into stereo pair */ - src = buffer + (self->numUserChannels - 1) * swidth; + src = buffer + ( self->numUserChannels - 1 ) * swidth; for( i = 0; i < numFrames; ++i ) { dst = src + swidth; @@ -3627,12 +3536,12 @@ static PaError PaAlsaStreamComponent_DoChannelAdaption( PaAlsaStreamComponent *s if( convertMono ) { ENSURE_( alsa_snd_pcm_area_copy( self->channelAreas + self->numUserChannels, self->offset, self->channelAreas + - (self->numUserChannels - 1), self->offset, numFrames, self->nativeFormat ), paUnanticipatedHostError ); + ( self->numUserChannels - 1 ), self->offset, numFrames, self->nativeFormat ), paUnanticipatedHostError ); --unusedChans; } if( unusedChans > 0 ) { - alsa_snd_pcm_areas_silence( self->channelAreas + (self->numHostChannels - unusedChans), self->offset, unusedChans, numFrames, + alsa_snd_pcm_areas_silence( self->channelAreas + ( self->numHostChannels - unusedChans ), self->offset, unusedChans, numFrames, self->nativeFormat ); } } @@ -3721,8 +3630,7 @@ static PaError PaAlsaStreamComponent_EndPolling( PaAlsaStreamComponent* self, st { *xrun = 1; } - else - if( revents & POLLHUP ) + else if( revents & POLLHUP ) { *xrun = 1; PA_DEBUG(( "%s: revents has POLLHUP, processing as XRUN\n", __FUNCTION__ )); @@ -3733,15 +3641,15 @@ static PaError PaAlsaStreamComponent_EndPolling( PaAlsaStreamComponent* self, st *shouldPoll = 0; } else /* (A zero revent occurred) */ - /* Work around an issue with Alsa older than 1.0.16 using some plugins (eg default with plug + dmix) where - * POLLIN or POLLOUT are zeroed by Alsa-lib if _mmap_avail() is a few frames short of avail_min at period - * boundary, possibly due to erratic dma interrupts at period boundary? Treat as a valid event. - */ - if( self->useReventFix ) - { - self->ready = 1; - *shouldPoll = 0; - } + /* Work around an issue with Alsa older than 1.0.16 using some plugins (eg default with plug + dmix) where + * POLLIN or POLLOUT are zeroed by Alsa-lib if _mmap_avail() is a few frames short of avail_min at period + * boundary, possibly due to erratic dma interrupts at period boundary? Treat as a valid event. + */ + if( self->useReventFix ) + { + self->ready = 1; + *shouldPoll = 0; + } error: return result; @@ -3883,10 +3791,8 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr /* TODO: Add macro for checking system calls */ PA_ENSURE( paInternalError ); } - else - if (pollResults == 0) + else if( pollResults == 0 ) { - /* Suspended, paused or failed device can provide 0 poll results. To avoid deadloop in such situation * we simply run counter 'timeouts' which detects 0 poll result and accumulates. As soon as 2048 timouts (around 2 seconds) * are achieved we simply fail function with paTimedOut to notify waiting methods that device is not capable @@ -3895,14 +3801,13 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr */ /*PA_DEBUG(( "%s: poll == 0 results, timed out, %d times left\n", __FUNCTION__, 2048 - timeouts ));*/ - ++ timeouts; - if (timeouts > 1) /* sometimes device times out, but normally once, so we do not sleep any time */ + if( timeouts > 1 ) /* sometimes device times out, but normally once, so we do not sleep any time */ { Pa_Sleep( 1 ); /* avoid hot loop */ } /* not else ! */ - if (timeouts >= 2048) /* audio device not working, shall return error to notify waiters */ + if( timeouts >= 2048 ) /* audio device not working, shall return error to notify waiters */ { *framesAvail = 0; /* no frames available for processing */ xrun = 1; /* try recovering device */ @@ -3911,8 +3816,7 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr goto end;/*PA_ENSURE( paTimedOut );*/ } } - else - if (pollResults > 0) + else if( pollResults > 0 ) { /* reset timouts counter */ timeouts = 0; @@ -4034,10 +3938,10 @@ static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* se else { unsigned int bufferSize = self->numHostChannels * alsa_snd_pcm_format_size( self->nativeFormat, *numFrames ); - if (bufferSize > self->nonMmapBufferSize) + if( bufferSize > self->nonMmapBufferSize ) { - self->nonMmapBuffer = realloc(self->nonMmapBuffer, (self->nonMmapBufferSize = bufferSize)); - if (!self->nonMmapBuffer) + self->nonMmapBuffer = realloc( self->nonMmapBuffer, ( self->nonMmapBufferSize = bufferSize ) ); + if( !self->nonMmapBuffer ) { result = paInsufficientMemory; goto error; @@ -4297,7 +4201,7 @@ static void *CallbackThreadFunc( void *userData ) if( paContinue != callbackResult ) { - stream->callbackAbort = (paAbort == callbackResult); + stream->callbackAbort = ( paAbort == callbackResult ); if( stream->callbackAbort || /** @concern BlockAdaption: Go on if adaption buffers are empty */ PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) @@ -4644,7 +4548,8 @@ error: return paNoError; } -PaError PaAlsa_GetStreamInputCard(PaStream* s, int* card) { +PaError PaAlsa_GetStreamInputCard( PaStream* s, int* card ) +{ PaAlsaStream *stream; PaError result = paNoError; snd_pcm_info_t* pcmInfo; @@ -4662,7 +4567,8 @@ error: return result; } -PaError PaAlsa_GetStreamOutputCard(PaStream* s, int* card) { +PaError PaAlsa_GetStreamOutputCard( PaStream* s, int* card ) +{ PaAlsaStream *stream; PaError result = paNoError; snd_pcm_info_t* pcmInfo; @@ -4685,648 +4591,3 @@ PaError PaAlsa_SetRetriesBusy( int retries ) busyRetries_ = retries; return paNoError; } - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -/* CONVERTERS (Swapping SRC/DST) */ -/* -------------------------------------------------------------------------- */ - -#define PA_CLIP_( val, min, max )\ - { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); } - -static const double const_1_div_2147483648_ = 1.0 / 2147483648.0; /* 32 bit multiplier */ - -/* -------------------------------------------------------------------------- */ - -static void Copy_24_To_24_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - unsigned char *src = (unsigned char*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - - (void) ditherGenerator; /* unused parameter */ - - while( count-- ) - { - dest[2] = src[0]; - dest[1] = src[1]; - dest[0] = src[2]; - - src += sourceStride * 3; - dest += destinationStride * 3; - } -} - -/* -------------------------------------------------------------------------- */ - -static void UInt8_To_Int24_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - unsigned char *src = (unsigned char*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - (void) ditherGenerator; /* unused parameters */ - - while( count-- ) - { - -#if defined(PA_LITTLE_ENDIAN) - dest[2] = 0; - dest[1] = 0; - dest[0] = (unsigned char)(*src - 128); -#elif defined(PA_BIG_ENDIAN) - dest[2] = (unsigned char)(*src - 128); - dest[1] = 0; - dest[0] = 0; -#endif - - src += sourceStride; - dest += destinationStride * 3; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Int8_To_Int24_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - signed char *src = (signed char*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - (void)ditherGenerator; /* unused parameter */ - - while( count-- ) - { - -#if defined(PA_LITTLE_ENDIAN) - dest[2] = 0; - dest[1] = 0; - dest[0] = (*src); -#elif defined(PA_BIG_ENDIAN) - dest[2] = (*src); - dest[1] = 0; - dest[0] = 0; -#endif - - src += sourceStride; - dest += destinationStride * 3; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Int16_To_Int24_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - PaInt16 *src = (PaInt16*) sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - PaInt16 temp; - - (void) ditherGenerator; /* unused parameter */ - - while( count-- ) - { - temp = *src; - -#if defined(PA_LITTLE_ENDIAN) - dest[2] = 0; - dest[1] = (unsigned char)(temp); - dest[0] = (unsigned char)(temp >> 8); -#elif defined(PA_BIG_ENDIAN) - dest[2] = (unsigned char)(temp >> 8); - dest[1] = (unsigned char)(temp); - dest[0] = 0; -#endif - - src += sourceStride; - dest += destinationStride * 3; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Int32_To_Int24_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - PaInt32 *src = (PaInt32*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - (void) ditherGenerator; /* unused parameter */ - - while( count-- ) - { - /* REVIEW */ -#if defined(PA_LITTLE_ENDIAN) - dest[2] = (unsigned char)(*src >> 8); - dest[1] = (unsigned char)(*src >> 16); - dest[0] = (unsigned char)(*src >> 24); -#elif defined(PA_BIG_ENDIAN) - dest[2] = (unsigned char)(*src >> 24); - dest[1] = (unsigned char)(*src >> 16); - dest[0] = (unsigned char)(*src >> 8); -#endif - src += sourceStride; - dest += destinationStride * 3; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int24_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - float *src = (float*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - PaInt32 temp; - - (void) ditherGenerator; /* unused parameter */ - - while( count-- ) - { - /* convert to 32 bit and drop the low 8 bits */ - double scaled = (double)(*src) * 2147483647.0; - temp = (PaInt32) scaled; - -#if defined(PA_LITTLE_ENDIAN) - dest[2] = (unsigned char)(temp >> 8); - dest[1] = (unsigned char)(temp >> 16); - dest[0] = (unsigned char)(temp >> 24); -#elif defined(PA_BIG_ENDIAN) - dest[2] = (unsigned char)(temp >> 24); - dest[1] = (unsigned char)(temp >> 16); - dest[0] = (unsigned char)(temp >> 8); -#endif - - src += sourceStride; - dest += destinationStride * 3; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int24_Dither_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - float *src = (float*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - PaInt32 temp; - - while( count-- ) - { - /* convert to 32 bit and drop the low 8 bits */ - - double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); - /* use smaller scaler to prevent overflow when we add the dither */ - double dithered = ((double)*src * (2147483646.0)) + dither; - - temp = (PaInt32) dithered; - -#if defined(PA_LITTLE_ENDIAN) - dest[2] = (unsigned char)(temp >> 8); - dest[1] = (unsigned char)(temp >> 16); - dest[0] = (unsigned char)(temp >> 24); -#elif defined(PA_BIG_ENDIAN) - dest[2] = (unsigned char)(temp >> 24); - dest[1] = (unsigned char)(temp >> 16); - dest[0] = (unsigned char)(temp >> 8); -#endif - - src += sourceStride; - dest += destinationStride * 3; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int24_Clip_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - float *src = (float*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - PaInt32 temp; - - (void) ditherGenerator; /* unused parameter */ - - while( count-- ) - { - /* convert to 32 bit and drop the low 8 bits */ - double scaled = *src * 0x7FFFFFFF; - PA_CLIP_( scaled, -2147483648., 2147483647. ); - temp = (PaInt32) scaled; - -#if defined(PA_LITTLE_ENDIAN) - dest[2] = (unsigned char)(temp >> 8); - dest[1] = (unsigned char)(temp >> 16); - dest[0] = (unsigned char)(temp >> 24); -#elif defined(PA_BIG_ENDIAN) - dest[2] = (unsigned char)(temp >> 24); - dest[1] = (unsigned char)(temp >> 16); - dest[0] = (unsigned char)(temp >> 8); -#endif - - src += sourceStride; - dest += destinationStride * 3; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int24_DitherClip_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - float *src = (float*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - PaInt32 temp; - - while( count-- ) - { - /* convert to 32 bit and drop the low 8 bits */ - - double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); - /* use smaller scaler to prevent overflow when we add the dither */ - double dithered = ((double)*src * (2147483646.0)) + dither; - PA_CLIP_( dithered, -2147483648., 2147483647. ); - - temp = (PaInt32) dithered; - -#if defined(PA_LITTLE_ENDIAN) - dest[2] = (unsigned char)(temp >> 8); - dest[1] = (unsigned char)(temp >> 16); - dest[0] = (unsigned char)(temp >> 24); -#elif defined(PA_BIG_ENDIAN) - dest[2] = (unsigned char)(temp >> 24); - dest[1] = (unsigned char)(temp >> 16); - dest[0] = (unsigned char)(temp >> 8); -#endif - - src += sourceStride; - dest += destinationStride * 3; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Int24_To_Float32_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - unsigned char *src = (unsigned char*)sourceBuffer; - float *dest = (float*)destinationBuffer; - PaInt32 temp; - - (void) ditherGenerator; /* unused parameter */ - - while( count-- ) - { - -#if defined(PA_LITTLE_ENDIAN) - temp = (((PaInt32)src[2]) << 8); - temp = temp | (((PaInt32)src[1]) << 16); - temp = temp | (((PaInt32)src[0]) << 24); -#elif defined(PA_BIG_ENDIAN) - temp = (((PaInt32)src[2]) << 24); - temp = temp | (((PaInt32)src[1]) << 16); - temp = temp | (((PaInt32)src[0]) << 8); -#endif - - *dest = (float) ((double)temp * const_1_div_2147483648_); - - src += sourceStride * 3; - dest += destinationStride; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Int24_To_Int32_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - unsigned char *src = (unsigned char*)sourceBuffer; - PaInt32 *dest = (PaInt32*) destinationBuffer; - PaInt32 temp; - - (void) ditherGenerator; /* unused parameter */ - - while( count-- ) - { - -#if defined(PA_LITTLE_ENDIAN) - temp = (((PaInt32)src[2]) << 8); - temp = temp | (((PaInt32)src[1]) << 16); - temp = temp | (((PaInt32)src[0]) << 24); -#elif defined(PA_BIG_ENDIAN) - temp = (((PaInt32)src[2]) << 24); - temp = temp | (((PaInt32)src[1]) << 16); - temp = temp | (((PaInt32)src[0]) << 8); -#endif - - *dest = temp; - - src += sourceStride * 3; - dest += destinationStride; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Int24_To_Int16_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - unsigned char *src = (unsigned char*)sourceBuffer; - PaInt16 *dest = (PaInt16*)destinationBuffer; - - PaInt16 temp; - - (void) ditherGenerator; /* unused parameter */ - - while( count-- ) - { - -#if defined(PA_LITTLE_ENDIAN) - /* src[2] is discarded */ - temp = (((PaInt16)src[1])); - temp = temp | (PaInt16)(((PaInt16)src[0]) << 8); -#elif defined(PA_BIG_ENDIAN) - /* src[0] is discarded */ - temp = (PaInt16)(((PaInt16)src[2]) << 8); - temp = temp | (((PaInt16)src[1])); -#endif - - *dest = temp; - - src += sourceStride * 3; - dest += destinationStride; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Int24_To_Int16_Dither_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - unsigned char *src = (unsigned char*)sourceBuffer; - PaInt16 *dest = (PaInt16*)destinationBuffer; - - PaInt32 temp, dither; - - while( count-- ) - { - -#if defined(PA_LITTLE_ENDIAN) - temp = (((PaInt32)src[2]) << 8); - temp = temp | (((PaInt32)src[1]) << 16); - temp = temp | (((PaInt32)src[0]) << 24); -#elif defined(PA_BIG_ENDIAN) - temp = (((PaInt32)src[2]) << 24); - temp = temp | (((PaInt32)src[1]) << 16); - temp = temp | (((PaInt32)src[0]) << 8); -#endif - - /* REVIEW */ - dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); - *dest = (PaInt16) (((temp >> 1) + dither) >> 15); - - src += sourceStride * 3; - dest += destinationStride; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Int24_To_Int8_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - unsigned char *src = (unsigned char*)sourceBuffer; - signed char *dest = (signed char*)destinationBuffer; - - (void) ditherGenerator; /* unused parameter */ - - while( count-- ) - { - -#if defined(PA_LITTLE_ENDIAN) - /* src[0] is discarded */ - /* src[1] is discarded */ - *dest = src[0]; -#elif defined(PA_BIG_ENDIAN) - /* src[2] is discarded */ - /* src[1] is discarded */ - *dest = src[2]; -#endif - - src += sourceStride * 3; - dest += destinationStride; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Int24_To_Int8_Dither_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - unsigned char *src = (unsigned char*)sourceBuffer; - signed char *dest = (signed char*)destinationBuffer; - - PaInt32 temp, dither; - - while( count-- ) - { - -#if defined(PA_LITTLE_ENDIAN) - temp = (((PaInt32)src[2]) << 8); - temp = temp | (((PaInt32)src[1]) << 16); - temp = temp | (((PaInt32)src[0]) << 24); -#elif defined(PA_BIG_ENDIAN) - temp = (((PaInt32)src[2]) << 24); - temp = temp | (((PaInt32)src[1]) << 16); - temp = temp | (((PaInt32)src[0]) << 8); -#endif - - /* REVIEW */ - dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); - *dest = (signed char) (((temp >> 1) + dither) >> 23); - - src += sourceStride * 3; - dest += destinationStride; - } -} - -/* -------------------------------------------------------------------------- */ - -static void Int24_To_UInt8_Swap( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - unsigned char *src = (unsigned char*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - - (void) ditherGenerator; /* unused parameter */ - - while( count-- ) - { - -#if defined(PA_LITTLE_ENDIAN) - /* src[0] is discarded */ - /* src[1] is discarded */ - *dest = (unsigned char)(src[0] + 128); -#elif defined(PA_BIG_ENDIAN) - *dest = (unsigned char)(src[2] + 128); - /* src[1] is discarded */ - /* src[2] is discarded */ -#endif - - src += sourceStride * 3; - dest += destinationStride; - } -} - -/* -------------------------------------------------------------------------- */ - -static void X_To_X_Stub( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - (void) destinationBuffer; /* unused parameters */ - (void) destinationStride; /* unused parameters */ - (void) sourceBuffer; /* unused parameters */ - (void) sourceStride; /* unused parameters */ - (void) count; /* unused parameters */ - (void) ditherGenerator; /* unused parameters */ - /* IMPLEMENT ME */ - - assert(0 && "input/output format needs additional swapping converter"); -} - -/* -------------------------------------------------------------------------- */ - -static PaUtilConverterTable paAlsaSwapConverters = { - X_To_X_Stub, /* PaUtilConverter *Float32_To_Int32; */ - X_To_X_Stub, /* PaUtilConverter *Float32_To_Int32_Dither; */ - X_To_X_Stub, /* PaUtilConverter *Float32_To_Int32_Clip; */ - X_To_X_Stub, /* PaUtilConverter *Float32_To_Int32_DitherClip; */ - - Float32_To_Int24_Swap, /* PaUtilConverter *Float32_To_Int24; */ - Float32_To_Int24_Dither_Swap, /* PaUtilConverter *Float32_To_Int24_Dither; */ - Float32_To_Int24_Clip_Swap, /* PaUtilConverter *Float32_To_Int24_Clip; */ - Float32_To_Int24_DitherClip_Swap, /* PaUtilConverter *Float32_To_Int24_DitherClip; */ - - X_To_X_Stub, /* PaUtilConverter *Float32_To_Int16; */ - X_To_X_Stub, /* PaUtilConverter *Float32_To_Int16_Dither; */ - X_To_X_Stub, /* PaUtilConverter *Float32_To_Int16_Clip; */ - X_To_X_Stub, /* PaUtilConverter *Float32_To_Int16_DitherClip; */ - - X_To_X_Stub, /* PaUtilConverter *Float32_To_Int8; */ - X_To_X_Stub, /* PaUtilConverter *Float32_To_Int8_Dither; */ - X_To_X_Stub, /* PaUtilConverter *Float32_To_Int8_Clip; */ - X_To_X_Stub, /* PaUtilConverter *Float32_To_Int8_DitherClip; */ - - X_To_X_Stub, /* PaUtilConverter *Float32_To_UInt8; */ - X_To_X_Stub, /* PaUtilConverter *Float32_To_UInt8_Dither; */ - X_To_X_Stub, /* PaUtilConverter *Float32_To_UInt8_Clip; */ - X_To_X_Stub, /* PaUtilConverter *Float32_To_UInt8_DitherClip; */ - - X_To_X_Stub, /* PaUtilConverter *Int32_To_Float32; */ - Int32_To_Int24_Swap, /* PaUtilConverter *Int32_To_Int24; */ - X_To_X_Stub,/*TO-DO*//* PaUtilConverter *Int32_To_Int24_Dither; */ - X_To_X_Stub, /* PaUtilConverter *Int32_To_Int16; */ - X_To_X_Stub, /* PaUtilConverter *Int32_To_Int16_Dither; */ - X_To_X_Stub, /* PaUtilConverter *Int32_To_Int8; */ - X_To_X_Stub, /* PaUtilConverter *Int32_To_Int8_Dither; */ - X_To_X_Stub, /* PaUtilConverter *Int32_To_UInt8; */ - X_To_X_Stub, /* PaUtilConverter *Int32_To_UInt8_Dither; */ - - Int24_To_Float32_Swap, /* PaUtilConverter *Int24_To_Float32; */ - Int24_To_Int32_Swap, /* PaUtilConverter *Int24_To_Int32; */ - Int24_To_Int16_Swap, /* PaUtilConverter *Int24_To_Int16; */ - Int24_To_Int16_Dither_Swap, /* PaUtilConverter *Int24_To_Int16_Dither; */ - Int24_To_Int8_Swap, /* PaUtilConverter *Int24_To_Int8; */ - Int24_To_Int8_Dither_Swap, /* PaUtilConverter *Int24_To_Int8_Dither; */ - Int24_To_UInt8_Swap, /* PaUtilConverter *Int24_To_UInt8; */ - X_To_X_Stub, /* PaUtilConverter *Int24_To_UInt8_Dither; */ - - X_To_X_Stub, /* PaUtilConverter *Int16_To_Float32; */ - X_To_X_Stub, /* PaUtilConverter *Int16_To_Int32; */ - Int16_To_Int24_Swap, /* PaUtilConverter *Int16_To_Int24; */ - X_To_X_Stub, /* PaUtilConverter *Int16_To_Int8; */ - X_To_X_Stub, /* PaUtilConverter *Int16_To_Int8_Dither; */ - X_To_X_Stub, /* PaUtilConverter *Int16_To_UInt8; */ - X_To_X_Stub, /* PaUtilConverter *Int16_To_UInt8_Dither; */ - - X_To_X_Stub, /* PaUtilConverter *Int8_To_Float32; */ - X_To_X_Stub, /* PaUtilConverter *Int8_To_Int32; */ - Int8_To_Int24_Swap, /* PaUtilConverter *Int8_To_Int24 */ - X_To_X_Stub, /* PaUtilConverter *Int8_To_Int16; */ - X_To_X_Stub, /* PaUtilConverter *Int8_To_UInt8; */ - - X_To_X_Stub, /* PaUtilConverter *UInt8_To_Float32; */ - X_To_X_Stub, /* PaUtilConverter *UInt8_To_Int32; */ - UInt8_To_Int24_Swap, /* PaUtilConverter *UInt8_To_Int24; */ - X_To_X_Stub, /* PaUtilConverter *UInt8_To_Int16; */ - X_To_X_Stub, /* PaUtilConverter *UInt8_To_Int8; */ - - X_To_X_Stub, /* PaUtilConverter *Copy_8_To_8; */ - X_To_X_Stub, /* PaUtilConverter *Copy_16_To_16; */ - Copy_24_To_24_Swap, /* PaUtilConverter *Copy_24_To_24; */ - X_To_X_Stub /* PaUtilConverter *Copy_32_To_32; */ -}; -void CheckAndReplaceConverterForSwapEndian(PaAlsaStream *stream, PaSampleFormat hostInputSampleFormat, - PaSampleFormat hostOutputSampleFormat) -{ - PaUtilConverter **cv_org = (PaUtilConverter **)&paConverters, - **cv_swp = (PaUtilConverter **)&paAlsaSwapConverters; - - int i, i_max = sizeof(PaUtilConverterTable)/sizeof(PaUtilConverter *); - - if (hostInputSampleFormat & paSwapEndian) - { - for (i = 0; i < i_max; ++i) - { - if (cv_org[i] == stream->bufferProcessor.inputConverter) - { - stream->bufferProcessor.inputConverter = cv_swp[i]; - break; - } - } - } - - if (hostOutputSampleFormat & paSwapEndian) - { - for (i = 0; i < i_max; ++i) - { - if (cv_org[i] == stream->bufferProcessor.outputConverter) - { - stream->bufferProcessor.outputConverter = cv_swp[i]; - break; - } - } - } -} diff --git a/3rdparty/portaudio/src/hostapi/asio/pa_asio.cpp b/3rdparty/portaudio/src/hostapi/asio/pa_asio.cpp index 3ecc2170ae..59f6baaf66 100644 --- a/3rdparty/portaudio/src/hostapi/asio/pa_asio.cpp +++ b/3rdparty/portaudio/src/hostapi/asio/pa_asio.cpp @@ -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. */ diff --git a/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core.c b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core.c index 339e2afa33..1cef082a33 100644 --- a/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core.c +++ b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core.c @@ -1774,25 +1774,16 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, do is initialize everything so that if we fail, we know what hasn't been touched. */ - - stream->inputAudioBufferList.mBuffers[0].mData = NULL; - stream->inputRingBuffer.buffer = NULL; - bzero( &stream->blio, sizeof( PaMacBlio ) ); -/* + bzero( stream, sizeof( PaMacCoreStream ) ); + + /* stream->blio.inputRingBuffer.buffer = NULL; stream->blio.outputRingBuffer.buffer = NULL; stream->blio.inputSampleFormat = inputParameters?inputParameters->sampleFormat:0; stream->blio.inputSampleSize = computeSampleSizeFromFormat(stream->blio.inputSampleFormat); 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 ) @@ -2145,11 +2136,11 @@ static OSStatus AudioIOProc( void *inRefCon, const bool isRender = inBusNumber == OUTPUT_ELEMENT; int callbackResult = paContinue ; double hostTimeStampInPaTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime); - + VVDBUG(("AudioIOProc()\n")); PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); - + /* -----------------------------------------------------------------*\ This output may be useful for debugging, But printing durring the callback is a bad enough idea that @@ -2250,7 +2241,8 @@ static OSStatus AudioIOProc( void *inRefCon, * */ OSStatus err = 0; - unsigned long frames; + 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, @@ -2300,7 +2292,8 @@ static OSStatus AudioIOProc( void *inRefCon, * and into the PA buffer processor. If sample rate conversion * is required on input, that is done here as well. */ - unsigned long frames; + 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,7 +2347,12 @@ static OSStatus AudioIOProc( void *inRefCon, { /*the ring buffer callback underflowed */ err = 0; bzero( ((char *)data) + size, sizeof(data)-size ); - stream->xrunFlags |= paInputUnderflow; + /* 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,13 +2469,13 @@ 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 ) - stream->xrunFlags |= paInputOverflow ; + if( framesWritten != inNumberFrames ) + { + stream->xrunFlags |= paInputOverflow ; + } } else { diff --git a/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c index b514f64119..e366aa3eea 100644 --- a/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c +++ b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c @@ -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 */ diff --git a/3rdparty/portaudio/src/hostapi/dsound/pa_win_ds.c b/3rdparty/portaudio/src/hostapi/dsound/pa_win_ds.c index 24c322bbee..98afb5c39f 100644 --- a/3rdparty/portaudio/src/hostapi/dsound/pa_win_ds.c +++ b/3rdparty/portaudio/src/hostapi/dsound/pa_win_ds.c @@ -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,29 +581,38 @@ static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVI int i; DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs = (DSDeviceNamesAndGUIDs*)context; - if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ) + /* + 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 ) { - for( i=0; i < deviceNamesAndGUIDs->outputNamesAndGUIDs.count; ++i ) + if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ) { - if( deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID - && memcmp( &data->DeviceId, deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 ) + for( i=0; i < deviceNamesAndGUIDs->outputNamesAndGUIDs.count; ++i ) { - deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].pnpInterface = + if( deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID + && memcmp( &data->DeviceId, deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 ) + { + deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].pnpInterface = (char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface ); - break; + break; + } } } - } - else if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ) - { - for( i=0; i < deviceNamesAndGUIDs->inputNamesAndGUIDs.count; ++i ) + else if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ) { - if( deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID - && memcmp( &data->DeviceId, deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 ) + for( i=0; i < deviceNamesAndGUIDs->inputNamesAndGUIDs.count; ++i ) { - deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].pnpInterface = + if( deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID + && memcmp( &data->DeviceId, deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 ) + { + deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].pnpInterface = (char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface ); - break; + break; + } } } } @@ -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); diff --git a/3rdparty/portaudio/src/hostapi/wasapi/pa_win_wasapi.c b/3rdparty/portaudio/src/hostapi/wasapi/pa_win_wasapi.c index 3cb5ecc739..9761e83cb1 100644 --- a/3rdparty/portaudio/src/hostapi/wasapi/pa_win_wasapi.c +++ b/3rdparty/portaudio/src/hostapi/wasapi/pa_win_wasapi.c @@ -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; - + (*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; - + (*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); diff --git a/3rdparty/portaudio/src/hostapi/wdmks/pa_win_wdmks.c b/3rdparty/portaudio/src/hostapi/wdmks/pa_win_wdmks.c index 3277bd3a23..5ae13f95ce 100644 --- a/3rdparty/portaudio/src/hostapi/wdmks/pa_win_wdmks.c +++ b/3rdparty/portaudio/src/hostapi/wdmks/pa_win_wdmks.c @@ -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 /* strlen() */ #include +#include /* iswspace() */ #include "pa_util.h" #include "pa_allocation.h" @@ -159,6 +160,21 @@ Default is to use the pin category. #endif #include + +#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 #include @@ -167,18 +183,17 @@ Default is to use the pin category. an "old" ksmedia.h), so the proper ksmedia.h is used */ #include +#endif + #include #include /* 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 ) } } - CloseHandle(stream->streamThread); - stream->streamThread = 0; + 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->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) diff --git a/3rdparty/portaudio/src/hostapi/wmme/pa_win_wmme.c b/3rdparty/portaudio/src/hostapi/wmme/pa_win_wmme.c index ec891a94ed..7c9f5f93a0 100644 --- a/3rdparty/portaudio/src/hostapi/wmme/pa_win_wmme.c +++ b/3rdparty/portaudio/src/hostapi/wmme/pa_win_wmme.c @@ -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; diff --git a/3rdparty/portaudio/src/os/win/pa_win_waveformat.c b/3rdparty/portaudio/src/os/win/pa_win_waveformat.c index beae5825e4..c128c321aa 100644 --- a/3rdparty/portaudio/src/os/win/pa_win_waveformat.c +++ b/3rdparty/portaudio/src/os/win/pa_win_waveformat.c @@ -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; diff --git a/3rdparty/portaudio/src/os/win/pa_win_wdmks_utils.c b/3rdparty/portaudio/src/os/win/pa_win_wdmks_utils.c index 3e12c4e04b..cd30a487ad 100644 --- a/3rdparty/portaudio/src/os/win/pa_win_wdmks_utils.c +++ b/3rdparty/portaudio/src/os/win/pa_win_wdmks_utils.c @@ -47,15 +47,26 @@ #define _INC_MMREG // for STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT #endif #include // 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 #include + +#endif + #include // 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 From f000b3603e4dcaf583f2d6d0860dc1a01a13a000 Mon Sep 17 00:00:00 2001 From: "refraction@gmail.com" Date: Wed, 16 Jan 2013 21:00:07 +0000 Subject: [PATCH 02/13] VIF: Fixed a logic error from r5380 which broke The Simpsons Game git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5517 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/Vif_Transfer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pcsx2/Vif_Transfer.cpp b/pcsx2/Vif_Transfer.cpp index 096845509b..4b4361a70e 100644 --- a/pcsx2/Vif_Transfer.cpp +++ b/pcsx2/Vif_Transfer.cpp @@ -98,12 +98,12 @@ _vifT static __fi bool vifTransfer(u32 *data, int size, bool TTE) { if (vifXch.chcr.STR) hwDmacSrcTadrInc(vifXch); + vifX.irqoffset.enabled = false; + if(!vifXch.qwc) vifX.inprogress &= ~0x1; else if(vifX.irqoffset.value != 0) vifX.irqoffset.enabled = true; - else - vifX.irqoffset.enabled = false; } else { From 82e4b1166ae5f5124ab8418f34b07380e913a966 Mon Sep 17 00:00:00 2001 From: ramapcsx2 Date: Sat, 19 Jan 2013 19:33:10 +0000 Subject: [PATCH 03/13] Fix for blockdumps, thanks gigaherz. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5530 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/AsyncFileReader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcsx2/AsyncFileReader.h b/pcsx2/AsyncFileReader.h index c16af0a06a..05046bb544 100644 --- a/pcsx2/AsyncFileReader.h +++ b/pcsx2/AsyncFileReader.h @@ -10,7 +10,7 @@ class AsyncFileReader { protected: - AsyncFileReader(void) {} + AsyncFileReader(void) {m_dataoffset=0;} wxString m_filename; From 26cac4d8379b62851af608110b3a723357accfcf Mon Sep 17 00:00:00 2001 From: "refraction@gmail.com" Date: Sun, 27 Jan 2013 16:56:58 +0000 Subject: [PATCH 04/13] VU Interpreter: It seems doing JALR in a delay slot is not taken ( Evil Dead - Fistfull of Boomstick) So the game now works in VU1 interpreter only. Tried fixing up MicroVU but its too confusing. Got close but lots of missing textures :( git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5538 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/VU.h | 1 + pcsx2/VU0microInterp.cpp | 13 ++++++++++--- pcsx2/VU1microInterp.cpp | 13 ++++++++++--- pcsx2/VUops.cpp | 28 +++++++++++++++++----------- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/pcsx2/VU.h b/pcsx2/VU.h index af87cd16b6..95d4d67d33 100644 --- a/pcsx2/VU.h +++ b/pcsx2/VU.h @@ -140,6 +140,7 @@ struct __aligned16 VURegs { u32 branch; u32 branchpc; u32 delaybranchpc; + u32 linkreg; bool takedelaybranch; // MAC/Status flags -- these are used by interpreters and superVU, but are kind of hacky diff --git a/pcsx2/VU0microInterp.cpp b/pcsx2/VU0microInterp.cpp index debbee9fd3..068300807c 100644 --- a/pcsx2/VU0microInterp.cpp +++ b/pcsx2/VU0microInterp.cpp @@ -148,14 +148,21 @@ static void _vu0Exec(VURegs* VU) VU->branch--; if (VU->branch == 0) { VU->VI[REG_TPC].UL = VU->branchpc; - if(VU->takedelaybranch == true) - { + if(VU->takedelaybranch == true && VU->linkreg == 0) + { //DevCon.Warning("Setting VU0 Delay branch to next branch, treating first as delay slot"); + + VU->branch = 2; VU->branchpc = VU->delaybranchpc; VU->delaybranchpc = 0; - VU->branch = 2; + VU->takedelaybranch = false; } + else + { + VU->takedelaybranch = false; + VU->linkreg = 0; + } } } diff --git a/pcsx2/VU1microInterp.cpp b/pcsx2/VU1microInterp.cpp index 8e3b7e32d5..47dc3511e2 100644 --- a/pcsx2/VU1microInterp.cpp +++ b/pcsx2/VU1microInterp.cpp @@ -144,14 +144,21 @@ static void _vu1Exec(VURegs* VU) if (VU->branch > 0) { if (VU->branch-- == 1) { VU->VI[REG_TPC].UL = VU->branchpc; - if(VU->takedelaybranch == true) - { + if(VU->takedelaybranch == true && VU->linkreg == 0) + { //DevCon.Warning("Setting VU1 Delay branch to next branch, treating first as delay slot"); + + VU->branch = 2; VU->branchpc = VU->delaybranchpc; VU->delaybranchpc = 0; - VU->branch = 2; + VU->takedelaybranch = false; } + else + { + VU->takedelaybranch = false; + VU->linkreg = 0; + } } } diff --git a/pcsx2/VUops.cpp b/pcsx2/VUops.cpp index 6ce659cdf3..7522649c90 100644 --- a/pcsx2/VUops.cpp +++ b/pcsx2/VUops.cpp @@ -1872,9 +1872,13 @@ s32 _branchAddr(VURegs * VU) { return bpc; } -static __fi void _setBranch(VURegs * VU, u32 bpc) { +static __fi void _setBranch(VURegs * VU, u32 bpc, bool islink) { if(VU->branch == 1) { + if(islink) + { + VU->linkreg = _It_; + } //DevCon.Warning("Branch in Branch Delay slot!"); VU->delaybranchpc = bpc; VU->takedelaybranch = true; @@ -1889,68 +1893,70 @@ static __fi void _setBranch(VURegs * VU, u32 bpc) { static __ri void _vuIBEQ(VURegs * VU) { if (VU->VI[_It_].US[0] == VU->VI[_Is_].US[0]) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } } static __ri void _vuIBGEZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] >= 0) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } } static __ri void _vuIBGTZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] > 0) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } } static __ri void _vuIBLEZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] <= 0) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } } static __ri void _vuIBLTZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] < 0) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } } static __ri void _vuIBNE(VURegs * VU) { if (VU->VI[_It_].US[0] != VU->VI[_Is_].US[0]) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } } static __ri void _vuB(VURegs * VU) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } +// NOTE!! This might fall in a delay slot, if it does, the BAL won't be taken. Not sure if this is correct static __ri void _vuBAL(VURegs * VU) { s32 bpc = _branchAddr(VU); if (_It_) VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; - _setBranch(VU, bpc); + _setBranch(VU, bpc, true); } static __ri void _vuJR(VURegs * VU) { u32 bpc = VU->VI[_Is_].US[0] * 8; - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } +//If this is in a branch delay, the jump isn't taken ( Evil Dead - Fistfull of Boomstick ) static __ri void _vuJALR(VURegs * VU) { u32 bpc = VU->VI[_Is_].US[0] * 8; if (_It_) VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; - _setBranch(VU, bpc); + _setBranch(VU, bpc, true); } static __ri void _vuMFP(VURegs * VU) { From 73a08536d1c37d8207f9c0048e8b6d06ebaf66cf Mon Sep 17 00:00:00 2001 From: "refraction@gmail.com" Date: Mon, 28 Jan 2013 23:05:18 +0000 Subject: [PATCH 05/13] VU Interpreter Branch Delays: Rethink of this. As it's completely undocumented and nobody seems to know exactly what goes on, i have made my own guess... If the first branch is a branch instruction, then ignore the second. If the first branch is a jump instruction, execute 1 instruction from the first jump, then execute the second branch. (This is the only confirmed thing i can find from people testing this) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5539 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/VU.h | 2 +- pcsx2/VU0microInterp.cpp | 28 ++++++++++++++++------------ pcsx2/VU1microInterp.cpp | 29 +++++++++++++++++------------ pcsx2/VUops.cpp | 17 +++++++++-------- 4 files changed, 43 insertions(+), 33 deletions(-) diff --git a/pcsx2/VU.h b/pcsx2/VU.h index 95d4d67d33..9bf094645c 100644 --- a/pcsx2/VU.h +++ b/pcsx2/VU.h @@ -140,7 +140,7 @@ struct __aligned16 VURegs { u32 branch; u32 branchpc; u32 delaybranchpc; - u32 linkreg; + u32 firstbranchisjump; bool takedelaybranch; // MAC/Status flags -- these are used by interpreters and superVU, but are kind of hacky diff --git a/pcsx2/VU0microInterp.cpp b/pcsx2/VU0microInterp.cpp index 068300807c..02350aba4e 100644 --- a/pcsx2/VU0microInterp.cpp +++ b/pcsx2/VU0microInterp.cpp @@ -145,24 +145,28 @@ static void _vu0Exec(VURegs* VU) _vuTestPipes(VU); if (VU->branch > 0) { - VU->branch--; - if (VU->branch == 0) { + if (VU->branch-- == 1) { VU->VI[REG_TPC].UL = VU->branchpc; - if(VU->takedelaybranch == true && VU->linkreg == 0) + if(VU->takedelaybranch == true) { - //DevCon.Warning("Setting VU0 Delay branch to next branch, treating first as delay slot"); + //DevCon.Warning("VU0 - Branch/Jump in Delay Slot"); + if(VU->firstbranchisjump == 1) + { + //DevCon.Warning("Jump first, so reading 1 instruction from first branch, then jumping second"); - VU->branch = 2; - VU->branchpc = VU->delaybranchpc; + VU->branch = 1; + VU->branchpc = VU->delaybranchpc; + } + else + { + //DevCon.Warning("Branch first, so ignoring second branch"); + } + VU->delaybranchpc = 0; - VU->takedelaybranch = false; } - else - { - VU->takedelaybranch = false; - VU->linkreg = 0; - } + + VU->firstbranchisjump = 0; } } diff --git a/pcsx2/VU1microInterp.cpp b/pcsx2/VU1microInterp.cpp index 47dc3511e2..a1430de847 100644 --- a/pcsx2/VU1microInterp.cpp +++ b/pcsx2/VU1microInterp.cpp @@ -24,7 +24,7 @@ extern void _vuFlushAll(VURegs* VU); void _vu1ExecUpper(VURegs* VU, u32 *ptr) { VU->code = ptr[1]; - IdebugUPPER(VU1); + //IdebugUPPER(VU1); VU1_UPPER_OPCODE[VU->code & 0x3f](); } @@ -68,7 +68,7 @@ static void _vu1Exec(VURegs* VU) } } - VUM_LOG("VU->cycle = %d (flags st=%x;mac=%x;clip=%x,q=%f)", VU->cycle, VU->statusflag, VU->macflag, VU->clipflag, VU->q.F); + //VUM_LOG("VU->cycle = %d (flags st=%x;mac=%x;clip=%x,q=%f)", VU->cycle, VU->statusflag, VU->macflag, VU->clipflag, VU->q.F); VU->code = ptr[1]; VU1regs_UPPER_OPCODE[VU->code & 0x3f](&uregs); @@ -144,21 +144,26 @@ static void _vu1Exec(VURegs* VU) if (VU->branch > 0) { if (VU->branch-- == 1) { VU->VI[REG_TPC].UL = VU->branchpc; - if(VU->takedelaybranch == true && VU->linkreg == 0) + if(VU->takedelaybranch == true) { - //DevCon.Warning("Setting VU1 Delay branch to next branch, treating first as delay slot"); + //DevCon.Warning("VU1 - Branch/Jump in Delay Slot"); + if(VU->firstbranchisjump == 1) + { + //DevCon.Warning("Jump first, so reading 1 instruction from first branch, then jumping second"); - VU->branch = 2; - VU->branchpc = VU->delaybranchpc; + VU->branch = 1; + VU->branchpc = VU->delaybranchpc; + } + else + { + //DevCon.Warning("Branch first, so ignoring second branch"); + } + VU->delaybranchpc = 0; - VU->takedelaybranch = false; } - else - { - VU->takedelaybranch = false; - VU->linkreg = 0; - } + + VU->firstbranchisjump = 0; } } diff --git a/pcsx2/VUops.cpp b/pcsx2/VUops.cpp index 7522649c90..80d22585b5 100644 --- a/pcsx2/VUops.cpp +++ b/pcsx2/VUops.cpp @@ -1872,19 +1872,20 @@ s32 _branchAddr(VURegs * VU) { return bpc; } -static __fi void _setBranch(VURegs * VU, u32 bpc, bool islink) { +static __fi void _setBranch(VURegs * VU, u32 bpc, bool isjump) { if(VU->branch == 1) - { - if(islink) - { - VU->linkreg = _It_; - } + { //DevCon.Warning("Branch in Branch Delay slot!"); VU->delaybranchpc = bpc; VU->takedelaybranch = true; } else { + if(isjump) + { + VU->firstbranchisjump = 1; + } + VU->branch = 2; VU->branchpc = bpc; } @@ -1943,12 +1944,12 @@ static __ri void _vuBAL(VURegs * VU) { if (_It_) VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; - _setBranch(VU, bpc, true); + _setBranch(VU, bpc, false); } static __ri void _vuJR(VURegs * VU) { u32 bpc = VU->VI[_Is_].US[0] * 8; - _setBranch(VU, bpc, false); + _setBranch(VU, bpc, true); } //If this is in a branch delay, the jump isn't taken ( Evil Dead - Fistfull of Boomstick ) From c78b6157cb2b39eb5941dad6806b253886ea08ba Mon Sep 17 00:00:00 2001 From: "refraction@gmail.com" Date: Thu, 31 Jan 2013 23:02:32 +0000 Subject: [PATCH 06/13] VU Interpreter Branch Delays: After some brainstorming amongst the team, we came up with a theory on what should be happening. I'm pleased to say it works in all cases. As a bonus, the Tony Hawk Project 8 game (possibly the others using the same engine too) now have perfect graphics in VU Interpreter :) (software mode still required to get rid of lighting garbage however. Skipdraw 2 "kinda" works, but not overly well) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5541 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/VU.h | 1 - pcsx2/VU0microInterp.cpp | 21 ++++---------- pcsx2/VU1microInterp.cpp | 23 ++++------------ pcsx2/VUops.cpp | 59 +++++++++++++++++++++++++++------------- 4 files changed, 51 insertions(+), 53 deletions(-) diff --git a/pcsx2/VU.h b/pcsx2/VU.h index 9bf094645c..af87cd16b6 100644 --- a/pcsx2/VU.h +++ b/pcsx2/VU.h @@ -140,7 +140,6 @@ struct __aligned16 VURegs { u32 branch; u32 branchpc; u32 delaybranchpc; - u32 firstbranchisjump; bool takedelaybranch; // MAC/Status flags -- these are used by interpreters and superVU, but are kind of hacky diff --git a/pcsx2/VU0microInterp.cpp b/pcsx2/VU0microInterp.cpp index 02350aba4e..c4aca7aa71 100644 --- a/pcsx2/VU0microInterp.cpp +++ b/pcsx2/VU0microInterp.cpp @@ -147,26 +147,15 @@ static void _vu0Exec(VURegs* VU) if (VU->branch > 0) { if (VU->branch-- == 1) { VU->VI[REG_TPC].UL = VU->branchpc; + if(VU->takedelaybranch == true) { - //DevCon.Warning("VU0 - Branch/Jump in Delay Slot"); - if(VU->firstbranchisjump == 1) - { - //DevCon.Warning("Jump first, so reading 1 instruction from first branch, then jumping second"); - - VU->branch = 1; - VU->branchpc = VU->delaybranchpc; - } - else - { - //DevCon.Warning("Branch first, so ignoring second branch"); - } - + VU->branch = 2; + DevCon.Warning("VU0 - Branch/Jump in Delay Slot"); + VU->branchpc = VU->delaybranchpc; VU->delaybranchpc = 0; VU->takedelaybranch = false; - } - - VU->firstbranchisjump = 0; + } } } diff --git a/pcsx2/VU1microInterp.cpp b/pcsx2/VU1microInterp.cpp index a1430de847..85ce8ff550 100644 --- a/pcsx2/VU1microInterp.cpp +++ b/pcsx2/VU1microInterp.cpp @@ -140,30 +140,19 @@ static void _vu1Exec(VURegs* VU) _vuAddLowerStalls(VU, &lregs); _vuTestPipes(VU); - + if (VU->branch > 0) { if (VU->branch-- == 1) { VU->VI[REG_TPC].UL = VU->branchpc; + if(VU->takedelaybranch == true) { - //DevCon.Warning("VU1 - Branch/Jump in Delay Slot"); - if(VU->firstbranchisjump == 1) - { - //DevCon.Warning("Jump first, so reading 1 instruction from first branch, then jumping second"); - - VU->branch = 1; - VU->branchpc = VU->delaybranchpc; - } - else - { - //DevCon.Warning("Branch first, so ignoring second branch"); - } - + VU->branch = 2; + //DevCon.Warning("VU1 - Branch/Jump in Delay Slot"); + VU->branchpc = VU->delaybranchpc; VU->delaybranchpc = 0; VU->takedelaybranch = false; - } - - VU->firstbranchisjump = 0; + } } } diff --git a/pcsx2/VUops.cpp b/pcsx2/VUops.cpp index 80d22585b5..f619927311 100644 --- a/pcsx2/VUops.cpp +++ b/pcsx2/VUops.cpp @@ -1872,7 +1872,7 @@ s32 _branchAddr(VURegs * VU) { return bpc; } -static __fi void _setBranch(VURegs * VU, u32 bpc, bool isjump) { +static __fi void _setBranch(VURegs * VU, u32 bpc) { if(VU->branch == 1) { //DevCon.Warning("Branch in Branch Delay slot!"); @@ -1881,11 +1881,7 @@ static __fi void _setBranch(VURegs * VU, u32 bpc, bool isjump) { } else { - if(isjump) - { - VU->firstbranchisjump = 1; - } - + VU->branch = 2; VU->branchpc = bpc; } @@ -1894,70 +1890,95 @@ static __fi void _setBranch(VURegs * VU, u32 bpc, bool isjump) { static __ri void _vuIBEQ(VURegs * VU) { if (VU->VI[_It_].US[0] == VU->VI[_Is_].US[0]) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc, false); + _setBranch(VU, bpc); } } static __ri void _vuIBGEZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] >= 0) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc, false); + _setBranch(VU, bpc); } } static __ri void _vuIBGTZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] > 0) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc, false); + _setBranch(VU, bpc); } } static __ri void _vuIBLEZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] <= 0) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc, false); + _setBranch(VU, bpc); } } static __ri void _vuIBLTZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] < 0) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc, false); + _setBranch(VU, bpc); } } static __ri void _vuIBNE(VURegs * VU) { if (VU->VI[_It_].US[0] != VU->VI[_Is_].US[0]) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc, false); + _setBranch(VU, bpc); } } static __ri void _vuB(VURegs * VU) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc, false); + _setBranch(VU, bpc); } -// NOTE!! This might fall in a delay slot, if it does, the BAL won't be taken. Not sure if this is correct static __ri void _vuBAL(VURegs * VU) { s32 bpc = _branchAddr(VU); - if (_It_) VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; + + if(_It_) + { + //If we are in the branch delay slot, the instruction after the first + //instruction in the first branches target becomes the linked reg. + if(VU->branch == 1) + { + VU->VI[_It_].US[0] = (VU->branchpc + 8)/8; + } + else + { + VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL+8)/8; + } + } - _setBranch(VU, bpc, false); + _setBranch(VU, bpc); } static __ri void _vuJR(VURegs * VU) { u32 bpc = VU->VI[_Is_].US[0] * 8; - _setBranch(VU, bpc, true); + _setBranch(VU, bpc); } //If this is in a branch delay, the jump isn't taken ( Evil Dead - Fistfull of Boomstick ) static __ri void _vuJALR(VURegs * VU) { u32 bpc = VU->VI[_Is_].US[0] * 8; - if (_It_) VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; + + if(_It_) + { + //If we are in the branch delay slot, the instruction after the first + //instruction in the first branches target becomes the linked reg. + if(VU->branch == 1) + { + VU->VI[_It_].US[0] = (VU->branchpc + 8)/8; + } + else + { + VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL+8)/8; + } + } - _setBranch(VU, bpc, true); + _setBranch(VU, bpc); } static __ri void _vuMFP(VURegs * VU) { From 580f7a2e3d45938c0f5b71810bba5b00f190f93e Mon Sep 17 00:00:00 2001 From: "gregory.hainaut" Date: Sun, 3 Feb 2013 15:46:42 +0000 Subject: [PATCH 07/13] gsdx (ogl): * Don't try to allocate a "null" array when shader log is empty * glsl: hopefully implicit cast error on Nvidia driver git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5542 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/GSDeviceOGL.cpp | 19 +++++++++++-------- plugins/GSdx/res/tfx.glsl | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index 629330a4d3..168699c65b 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -1359,7 +1359,7 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st #endif // Check the correctness of the (AMD) driver - // Note: glGetFragDataLocation crash too!!! Catalyst 12.10 => HD 6XXX + // Note: glGetFragDataLocation crash too!!! Catalyst 12.10 (and later) => HD 5XXX,6XXX !!! if (theApp.GetConfig("renderer", 0) == 12) { GLint slot = glGetFragDataLocation(*program, "SV_Target1"); if (slot == 0) { // <=> SV_Target1 used same slot as SV_Target0 @@ -1378,16 +1378,19 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st if (theApp.GetConfig("debug_ogl_shader", 1) == 1) { // Print a nice debug log - GLint log_length = 0; - glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &log_length); - - char* log = (char*)malloc(log_length); - glGetProgramInfoLog(*program, log_length, NULL, log); - fprintf(stderr, "%s (entry %s, prog %d) :", glsl_file.c_str(), entry.c_str(), *program); fprintf(stderr, "\n%s", macro_sel.c_str()); - fprintf(stderr, "%s\n", log); + + GLint log_length = 0; + glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &log_length); + if (log_length > 0) { + char* log = (char*)malloc(log_length); + glGetProgramInfoLog(*program, log_length, NULL, log); + fprintf(stderr, "%s", log); free(log); + } + fprintf(stderr, "\n"); + } } diff --git a/plugins/GSdx/res/tfx.glsl b/plugins/GSdx/res/tfx.glsl index 73a29419de..127014ca42 100644 --- a/plugins/GSdx/res/tfx.glsl +++ b/plugins/GSdx/res/tfx.glsl @@ -443,7 +443,7 @@ vec4 sample_color(vec2 st, float q) } // PERF: see the impact of the exansion before/after the interpolation - for (uint i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { if((PS_FMT & ~FMT_PAL) == FMT_24) { From c30f67b76750fa42d060ee7ff6e6355bf353bd6a Mon Sep 17 00:00:00 2001 From: "refraction@gmail.com" Date: Tue, 5 Feb 2013 00:42:44 +0000 Subject: [PATCH 08/13] VIF/VU: Fixes for Everblue and Hitman 2 from r5404, details below. Savestate bump needed, sorry. Also fixed a copy/paste bug i noticed along the way in vif0FBRST. Everblue: Slightly messy fix, not as nice as id hope, but it seems to work, we need to remember VU programs written to the VU so we can check if an unpack is modifying it. This retains the behaviour of the Snowblind engines whilst fixing everblue. Hitman 2: Our vif0/1VUFinish() routing which works in conjunction with the delays wasn't paying attention to if the VIF was stalled or not and reran it before the game wanted it to, now fixed. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5544 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/SaveState.h | 2 +- pcsx2/Vif.cpp | 4 +++- pcsx2/Vif0_Dma.cpp | 2 +- pcsx2/Vif1_Dma.cpp | 2 +- pcsx2/Vif_Codes.cpp | 20 ++++++++++++++++++++ pcsx2/Vif_Dma.h | 3 +++ pcsx2/Vif_Unpack.cpp | 21 ++++++++++++++++++++- 7 files changed, 49 insertions(+), 5 deletions(-) diff --git a/pcsx2/SaveState.h b/pcsx2/SaveState.h index 45684b16e1..747708bbd6 100644 --- a/pcsx2/SaveState.h +++ b/pcsx2/SaveState.h @@ -24,7 +24,7 @@ // the lower 16 bit value. IF the change is breaking of all compatibility with old // states, increment the upper 16 bit value, and clear the lower 16 bits to 0. -static const u32 g_SaveVersion = (0x9A0A << 16) | 0x0000; +static const u32 g_SaveVersion = (0x9A0B << 16) | 0x0000; // this function is meant to be used in the place of GSfreeze, and provides a safe layer // between the GS saving function and the MTGS's needs. :) diff --git a/pcsx2/Vif.cpp b/pcsx2/Vif.cpp index c313a36a51..13db69cf63 100644 --- a/pcsx2/Vif.cpp +++ b/pcsx2/Vif.cpp @@ -98,11 +98,12 @@ __fi void vif0FBRST(u32 value) { psHu64(VIF0_FIFO) = 0; psHu64(VIF0_FIFO + 8) = 0; vif0.vifstalled.enabled = false; - vif1.irqoffset.enabled = false; + vif0.irqoffset.enabled = false; vif0.inprogress = 0; vif0.cmd = 0; vif0.done = true; vif0ch.chcr.STR = false; + vif0.LoadedMicroProgs = 0; vif0Regs.err.reset(); vif0Regs.stat.clear_flags(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0 } @@ -177,6 +178,7 @@ __fi void vif1FBRST(u32 value) { psHu64(VIF1_FIFO) = 0; psHu64(VIF1_FIFO + 8) = 0; vif1.done = true; + vif1.LoadedMicroProgs = 0; vif1ch.chcr.STR = false; #if USE_OLD_GIF == 1 // ... diff --git a/pcsx2/Vif0_Dma.cpp b/pcsx2/Vif0_Dma.cpp index b540052e42..ecd8a4978c 100644 --- a/pcsx2/Vif0_Dma.cpp +++ b/pcsx2/Vif0_Dma.cpp @@ -162,7 +162,7 @@ __fi void vif0VUFinish() vif0.waitforvu = false; ExecuteVU(0); //Make sure VIF0 isnt already scheduled to spin. - if(!(cpuRegs.interrupt & 0x1) && vif0ch.chcr.STR == true) + if(!(cpuRegs.interrupt & 0x1) && vif0ch.chcr.STR == true && !vif0Regs.stat.INT) vif0Interrupt(); } //DevCon.Warning("VU0 state cleared"); diff --git a/pcsx2/Vif1_Dma.cpp b/pcsx2/Vif1_Dma.cpp index b3388d42d5..0b3724af9b 100644 --- a/pcsx2/Vif1_Dma.cpp +++ b/pcsx2/Vif1_Dma.cpp @@ -235,7 +235,7 @@ __fi void vif1VUFinish() vif1.waitforvu = false; ExecuteVU(1); //Check if VIF is already scheduled to interrupt, if it's waiting, kick it :P - if((cpuRegs.interrupt & (1<> 16); vifX.tag.addr = (u16)(vifXRegs.code << 3) & (idx ? 0x3fff : 0xfff); vifX.tag.size = vifNum ? (vifNum*2) : 512; vifFlush(idx); + + //Make a note of the VU programs we're loading, checked in VIF Unpacks + for( u32 i = 0; i < vifX.LoadedMicroProgs; i++ ) + { + if(vifX.MicroProgAddrS[i] == vifX.tag.addr) + { + bProgramExists = true; + vifX.MicroProgAddrS[i] = vifX.tag.addr; + vifX.MicroProgAddrE[i] = vifX.tag.addr + (vifX.tag.size * 4); + break; + } + } + if(bProgramExists == false) + { + vifX.MicroProgAddrS[vifX.LoadedMicroProgs] = vifX.tag.addr; + vifX.MicroProgAddrE[vifX.LoadedMicroProgs] = vifX.tag.addr + (vifX.tag.size * 4); + vifX.LoadedMicroProgs++; + } + if(vifX.vifstalled.enabled == true) return 0; else { diff --git a/pcsx2/Vif_Dma.h b/pcsx2/Vif_Dma.h index 14d20a1d1d..ac2e6ea25e 100644 --- a/pcsx2/Vif_Dma.h +++ b/pcsx2/Vif_Dma.h @@ -93,6 +93,9 @@ struct vifStruct { bool queued_program; u32 queued_pc; + u32 LoadedMicroProgs; //Note how many microprograms we have on the VU. + u32 MicroProgAddrS[100]; //Start Addresses + u32 MicroProgAddrE[100]; //End Addresses }; extern __aligned16 vifStruct vif0, vif1; diff --git a/pcsx2/Vif_Unpack.cpp b/pcsx2/Vif_Unpack.cpp index bf76364cc7..f6ff281674 100644 --- a/pcsx2/Vif_Unpack.cpp +++ b/pcsx2/Vif_Unpack.cpp @@ -185,7 +185,7 @@ __aligned16 const UNPACKFUNCTYPE VIFfuncTable[2][3][4 * 4 * 2 * 2] = //---------------------------------------------------------------------------- _vifT void vifUnpackSetup(const u32 *data) { - + bool bModifyingVUProg = false; vifStruct& vifX = GetVifX; if ((vifXRegs.cycle.wl == 0) && (vifXRegs.cycle.wl < vifXRegs.cycle.cl)) { @@ -226,6 +226,25 @@ _vifT void vifUnpackSetup(const u32 *data) { if (idx && ((addr>>15)&1)) addr += vif1Regs.tops; vifX.tag.addr = (addr<<4) & (idx ? 0x3ff0 : 0xff0); + //The Snowblind Engine modifies VU programs with unpacks (seemingly), + //however some games (like everblue) don't like the vu waiting until the + //last minute, so as long as the unpack isn't editing a microprogram, we're safe. + if(vifX.queued_program == true && vifX.LoadedMicroProgs > 0) + { + for(u32 i = 0; i < vifX.LoadedMicroProgs; i++) + { + if(vifX.MicroProgAddrS[i] <= vifX.tag.addr && vifX.MicroProgAddrE[i] > vifX.tag.addr) + { + bModifyingVUProg = true; + break; + } + } + if(bModifyingVUProg == false) + vifExecQueue(idx); + } + + + VIF_LOG("Unpack VIF%x, QWC %x tagsize %x", idx, vifNum, vif0.tag.size); vifX.cl = 0; From 8d80ff0652a99a354e5c854149a2bad5936d423c Mon Sep 17 00:00:00 2001 From: ramapcsx2 Date: Tue, 5 Feb 2013 14:21:24 +0000 Subject: [PATCH 09/13] SPU2-X: Adding a log for bad pitch settings, in preparation of changing current behavior. (Need to check some games that do it first) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5545 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/spu2-x/src/spu2sys.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/spu2-x/src/spu2sys.cpp b/plugins/spu2-x/src/spu2sys.cpp index cc6e16c034..7def4589cd 100644 --- a/plugins/spu2-x/src/spu2sys.cpp +++ b/plugins/spu2-x/src/spu2sys.cpp @@ -814,6 +814,7 @@ static void __fastcall RegWrite_VoiceParams( u16 value ) break; case 2: + if (value > 0x3fff) ConLog( "* SPU2: Pitch setting too big: 0x%x\n", value); thisvoice.Pitch = value & 0x3fff; break; @@ -829,7 +830,7 @@ static void __fastcall RegWrite_VoiceParams( u16 value ) // [Air] : Mysterious ADSR set code. Too bad none of my games ever use it. // (as usual... ) thisvoice.ADSR.Value = (value << 16) | value; - ConLog( "* SPU2: Mysterious ADSR Volume Set to 0x%x", value ); + ConLog( "* SPU2: Mysterious ADSR Volume Set to 0x%x\n", value ); break; case 6: thisvoice.Volume.Left.RegSet( value ); break; From 0e80111499bba62d5a7221d59493b29433e4fbff Mon Sep 17 00:00:00 2001 From: "refraction@gmail.com" Date: Tue, 5 Feb 2013 23:30:25 +0000 Subject: [PATCH 10/13] VIF/VU: Removed all the everblue crap, found another way of doing it. As the savestate bummp wasn't needed anymore, i've put it back again. savestate users rejoyce? git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5546 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/SaveState.h | 2 +- pcsx2/Vif.cpp | 2 -- pcsx2/Vif_Codes.cpp | 19 +------------------ pcsx2/Vif_Dma.h | 3 --- pcsx2/Vif_Unpack.cpp | 21 +-------------------- 5 files changed, 3 insertions(+), 44 deletions(-) diff --git a/pcsx2/SaveState.h b/pcsx2/SaveState.h index 747708bbd6..45684b16e1 100644 --- a/pcsx2/SaveState.h +++ b/pcsx2/SaveState.h @@ -24,7 +24,7 @@ // the lower 16 bit value. IF the change is breaking of all compatibility with old // states, increment the upper 16 bit value, and clear the lower 16 bits to 0. -static const u32 g_SaveVersion = (0x9A0B << 16) | 0x0000; +static const u32 g_SaveVersion = (0x9A0A << 16) | 0x0000; // this function is meant to be used in the place of GSfreeze, and provides a safe layer // between the GS saving function and the MTGS's needs. :) diff --git a/pcsx2/Vif.cpp b/pcsx2/Vif.cpp index 13db69cf63..7df6e56924 100644 --- a/pcsx2/Vif.cpp +++ b/pcsx2/Vif.cpp @@ -103,7 +103,6 @@ __fi void vif0FBRST(u32 value) { vif0.cmd = 0; vif0.done = true; vif0ch.chcr.STR = false; - vif0.LoadedMicroProgs = 0; vif0Regs.err.reset(); vif0Regs.stat.clear_flags(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0 } @@ -178,7 +177,6 @@ __fi void vif1FBRST(u32 value) { psHu64(VIF1_FIFO) = 0; psHu64(VIF1_FIFO + 8) = 0; vif1.done = true; - vif1.LoadedMicroProgs = 0; vif1ch.chcr.STR = false; #if USE_OLD_GIF == 1 // ... diff --git a/pcsx2/Vif_Codes.cpp b/pcsx2/Vif_Codes.cpp index 000a3a11b0..38d2ee55a4 100644 --- a/pcsx2/Vif_Codes.cpp +++ b/pcsx2/Vif_Codes.cpp @@ -312,24 +312,6 @@ vifOp(vifCode_MPG) { vifX.tag.size = vifNum ? (vifNum*2) : 512; vifFlush(idx); - //Make a note of the VU programs we're loading, checked in VIF Unpacks - for( u32 i = 0; i < vifX.LoadedMicroProgs; i++ ) - { - if(vifX.MicroProgAddrS[i] == vifX.tag.addr) - { - bProgramExists = true; - vifX.MicroProgAddrS[i] = vifX.tag.addr; - vifX.MicroProgAddrE[i] = vifX.tag.addr + (vifX.tag.size * 4); - break; - } - } - if(bProgramExists == false) - { - vifX.MicroProgAddrS[vifX.LoadedMicroProgs] = vifX.tag.addr; - vifX.MicroProgAddrE[vifX.LoadedMicroProgs] = vifX.tag.addr + (vifX.tag.size * 4); - vifX.LoadedMicroProgs++; - } - if(vifX.vifstalled.enabled == true) return 0; else { @@ -439,6 +421,7 @@ vifOp(vifCode_Nop) { pass1 { GetVifX.cmd = 0; GetVifX.pass = 0; + vifExecQueue(idx); } pass3 { VifCodeLog("Nop"); } return 1; diff --git a/pcsx2/Vif_Dma.h b/pcsx2/Vif_Dma.h index ac2e6ea25e..14d20a1d1d 100644 --- a/pcsx2/Vif_Dma.h +++ b/pcsx2/Vif_Dma.h @@ -93,9 +93,6 @@ struct vifStruct { bool queued_program; u32 queued_pc; - u32 LoadedMicroProgs; //Note how many microprograms we have on the VU. - u32 MicroProgAddrS[100]; //Start Addresses - u32 MicroProgAddrE[100]; //End Addresses }; extern __aligned16 vifStruct vif0, vif1; diff --git a/pcsx2/Vif_Unpack.cpp b/pcsx2/Vif_Unpack.cpp index f6ff281674..bf76364cc7 100644 --- a/pcsx2/Vif_Unpack.cpp +++ b/pcsx2/Vif_Unpack.cpp @@ -185,7 +185,7 @@ __aligned16 const UNPACKFUNCTYPE VIFfuncTable[2][3][4 * 4 * 2 * 2] = //---------------------------------------------------------------------------- _vifT void vifUnpackSetup(const u32 *data) { - bool bModifyingVUProg = false; + vifStruct& vifX = GetVifX; if ((vifXRegs.cycle.wl == 0) && (vifXRegs.cycle.wl < vifXRegs.cycle.cl)) { @@ -226,25 +226,6 @@ _vifT void vifUnpackSetup(const u32 *data) { if (idx && ((addr>>15)&1)) addr += vif1Regs.tops; vifX.tag.addr = (addr<<4) & (idx ? 0x3ff0 : 0xff0); - //The Snowblind Engine modifies VU programs with unpacks (seemingly), - //however some games (like everblue) don't like the vu waiting until the - //last minute, so as long as the unpack isn't editing a microprogram, we're safe. - if(vifX.queued_program == true && vifX.LoadedMicroProgs > 0) - { - for(u32 i = 0; i < vifX.LoadedMicroProgs; i++) - { - if(vifX.MicroProgAddrS[i] <= vifX.tag.addr && vifX.MicroProgAddrE[i] > vifX.tag.addr) - { - bModifyingVUProg = true; - break; - } - } - if(bModifyingVUProg == false) - vifExecQueue(idx); - } - - - VIF_LOG("Unpack VIF%x, QWC %x tagsize %x", idx, vifNum, vif0.tag.size); vifX.cl = 0; From 5988c708229a4bf71e8d164dd255e625469d8f46 Mon Sep 17 00:00:00 2001 From: "sudonim1@gmail.com" Date: Thu, 7 Feb 2013 17:32:34 +0000 Subject: [PATCH 11/13] GSDX: Mask off high bits of calculated GS memory addresses, untested but probably what happens with real hardware. Fixes crash/memory corruption on starting Fatal Fury Battle Archives Volume 2, hopefully some other games too. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5547 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/GSLocalMemory.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/plugins/GSdx/GSLocalMemory.h b/plugins/GSdx/GSLocalMemory.h index 2a7e16426b..578a06fe5f 100644 --- a/plugins/GSdx/GSLocalMemory.h +++ b/plugins/GSdx/GSLocalMemory.h @@ -186,46 +186,46 @@ public: static uint32 BlockNumber32(int x, int y, uint32 bp, uint32 bw) { - return bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable32[(y >> 3) & 3][(x >> 3) & 7]; + return bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable32[(y >> 3) & 3][(x >> 3) & 7] & 16383; } static uint32 BlockNumber16(int x, int y, uint32 bp, uint32 bw) { - return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16[(y >> 3) & 7][(x >> 4) & 3]; + return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16[(y >> 3) & 7][(x >> 4) & 3] & 16383; } static uint32 BlockNumber16S(int x, int y, uint32 bp, uint32 bw) { - return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16S[(y >> 3) & 7][(x >> 4) & 3]; + return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16S[(y >> 3) & 7][(x >> 4) & 3] & 16383; } static uint32 BlockNumber8(int x, int y, uint32 bp, uint32 bw) { // ASSERT((bw & 1) == 0); // allowed for mipmap levels - return bp + ((y >> 1) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f) + blockTable8[(y >> 4) & 3][(x >> 4) & 7]; + return bp + ((y >> 1) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f) + blockTable8[(y >> 4) & 3][(x >> 4) & 7] & 16383; } static uint32 BlockNumber4(int x, int y, uint32 bp, uint32 bw) { // ASSERT((bw & 1) == 0); // allowed for mipmap levels - return bp + ((y >> 2) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f) + blockTable4[(y >> 4) & 7][(x >> 5) & 3]; + return bp + ((y >> 2) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f) + blockTable4[(y >> 4) & 7][(x >> 5) & 3] & 16383; } static uint32 BlockNumber32Z(int x, int y, uint32 bp, uint32 bw) { - return bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable32Z[(y >> 3) & 3][(x >> 3) & 7]; + return bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable32Z[(y >> 3) & 3][(x >> 3) & 7] & 16383; } static uint32 BlockNumber16Z(int x, int y, uint32 bp, uint32 bw) { - return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16Z[(y >> 3) & 7][(x >> 4) & 3]; + return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16Z[(y >> 3) & 7][(x >> 4) & 3] & 16383; } static uint32 BlockNumber16SZ(int x, int y, uint32 bp, uint32 bw) { - return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16SZ[(y >> 3) & 7][(x >> 4) & 3]; + return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16SZ[(y >> 3) & 7][(x >> 4) & 3] & 16383; } uint8* BlockPtr(uint32 bp) const @@ -317,7 +317,7 @@ public: static __forceinline uint32 PixelAddress32(int x, int y, uint32 bp, uint32 bw) { - uint32 page = (bp >> 5) + (y >> 5) * bw + (x >> 6); + uint32 page = (bp >> 5) + (y >> 5) * bw + (x >> 6) & 511; uint32 word = (page << 11) + pageOffset32[bp & 0x1f][y & 0x1f][x & 0x3f]; return word; @@ -325,7 +325,7 @@ public: static __forceinline uint32 PixelAddress16(int x, int y, uint32 bp, uint32 bw) { - uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6); + uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6) & 511; uint32 word = (page << 12) + pageOffset16[bp & 0x1f][y & 0x3f][x & 0x3f]; return word; @@ -333,7 +333,7 @@ public: static __forceinline uint32 PixelAddress16S(int x, int y, uint32 bp, uint32 bw) { - uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6); + uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6) & 511; uint32 word = (page << 12) + pageOffset16S[bp & 0x1f][y & 0x3f][x & 0x3f]; return word; @@ -343,7 +343,7 @@ public: { // ASSERT((bw & 1) == 0); // allowed for mipmap levels - uint32 page = (bp >> 5) + (y >> 6) * (bw >> 1) + (x >> 7); + uint32 page = (bp >> 5) + (y >> 6) * (bw >> 1) + (x >> 7) & 511; uint32 word = (page << 13) + pageOffset8[bp & 0x1f][y & 0x3f][x & 0x7f]; return word; @@ -353,7 +353,7 @@ public: { // ASSERT((bw & 1) == 0); // allowed for mipmap levels - uint32 page = (bp >> 5) + (y >> 7) * (bw >> 1) + (x >> 7); + uint32 page = (bp >> 5) + (y >> 7) * (bw >> 1) + (x >> 7) & 511; uint32 word = (page << 14) + pageOffset4[bp & 0x1f][y & 0x7f][x & 0x7f]; return word; @@ -361,7 +361,7 @@ public: static __forceinline uint32 PixelAddress32Z(int x, int y, uint32 bp, uint32 bw) { - uint32 page = (bp >> 5) + (y >> 5) * bw + (x >> 6); + uint32 page = (bp >> 5) + (y >> 5) * bw + (x >> 6) & 511; uint32 word = (page << 11) + pageOffset32Z[bp & 0x1f][y & 0x1f][x & 0x3f]; return word; @@ -369,7 +369,7 @@ public: static __forceinline uint32 PixelAddress16Z(int x, int y, uint32 bp, uint32 bw) { - uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6); + uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6) & 511; uint32 word = (page << 12) + pageOffset16Z[bp & 0x1f][y & 0x3f][x & 0x3f]; return word; @@ -377,7 +377,7 @@ public: static __forceinline uint32 PixelAddress16SZ(int x, int y, uint32 bp, uint32 bw) { - uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6); + uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6) & 511; uint32 word = (page << 12) + pageOffset16SZ[bp & 0x1f][y & 0x3f][x & 0x3f]; return word; From 23cd8fd6410a905531c121e3bc4671364e7adac1 Mon Sep 17 00:00:00 2001 From: "sudonim1@gmail.com" Date: Fri, 8 Feb 2013 15:35:28 +0000 Subject: [PATCH 12/13] GSDX: Committing pointless extra work for the record before reverting. Everything is terrible. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5548 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/GSClut.cpp | 12 ++--- plugins/GSdx/GSLocalMemory.cpp | 74 +++++++++++++++---------------- plugins/GSdx/GSLocalMemory.h | 62 +++++++++++++------------- plugins/GSdx/GSRendererDX.cpp | 2 +- plugins/GSdx/GSState.cpp | 48 ++++++++++---------- plugins/GSdx/GSTextureCache.cpp | 7 +-- plugins/GSdx/GSTextureCacheSW.cpp | 4 +- 7 files changed, 102 insertions(+), 107 deletions(-) diff --git a/plugins/GSdx/GSClut.cpp b/plugins/GSdx/GSClut.cpp index f61dabcfe6..bfe6274fdb 100644 --- a/plugins/GSdx/GSClut.cpp +++ b/plugins/GSdx/GSClut.cpp @@ -172,14 +172,14 @@ template void GSClut::WriteCLUT32_CSM2(const GIFRegTEX0& TEX0, const GIFR { GSOffset* o = m_mem->GetOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT32); - uint32* RESTRICT s = &m_mem->m_vm32[o->pixel.row[TEXCLUT.COV]]; + uint32 addr = o->pixel.row[TEXCLUT.COV]; int* RESTRICT col = &o->pixel.col[0][TEXCLUT.COU << 4]; uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4); for(int i = 0; i < n; i++) { - uint32 c = s[col[i]]; + uint32 c = m_mem->ReadPixel32(addr + col[i]); clut[i] = (uint16)(c & 0xffff); clut[i + 256] = (uint16)(c >> 16); @@ -190,14 +190,14 @@ template void GSClut::WriteCLUT16_CSM2(const GIFRegTEX0& TEX0, const GIFR { GSOffset* o = m_mem->GetOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16); - uint16* RESTRICT s = &m_mem->m_vm16[o->pixel.row[TEXCLUT.COV]]; + uint32 addr = o->pixel.row[TEXCLUT.COV]; int* RESTRICT col = &o->pixel.col[0][TEXCLUT.COU << 4]; uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4); for(int i = 0; i < n; i++) { - clut[i] = s[col[i]]; + clut[i] = (uint16)m_mem->ReadPixel16(addr + col[i]); } } @@ -205,14 +205,14 @@ template void GSClut::WriteCLUT16S_CSM2(const GIFRegTEX0& TEX0, const GIF { GSOffset* o = m_mem->GetOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16S); - uint16* RESTRICT s = &m_mem->m_vm16[o->pixel.row[TEXCLUT.COV]]; + uint32 addr = o->pixel.row[TEXCLUT.COV]; int* RESTRICT col = &o->pixel.col[0][TEXCLUT.COU << 4]; uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4); for(int i = 0; i < n; i++) { - clut[i] = s[col[i]]; + clut[i] = (uint16)m_mem->ReadPixel16(addr + col[i]); } } diff --git a/plugins/GSdx/GSLocalMemory.cpp b/plugins/GSdx/GSLocalMemory.cpp index dac52f6d95..990ee3c12b 100644 --- a/plugins/GSdx/GSLocalMemory.cpp +++ b/plugins/GSdx/GSLocalMemory.cpp @@ -83,9 +83,11 @@ GSLocalMemory::psm_t GSLocalMemory::m_psm[64]; GSLocalMemory::GSLocalMemory() : m_clut(this) { - m_vm8 = (uint8*)vmalloc(m_vmsize * 2, false); + m_vm8 = (uint8*)vmalloc(m_vmsize * 16, false); m_vm16 = (uint16*)m_vm8; m_vm32 = (uint32*)m_vm8; + DWORD oldprotect; + VirtualProtect(m_vm8 + m_vmsize, m_vmsize * 15, PAGE_NOACCESS, &oldprotect); memset(m_vm8, 0, m_vmsize); @@ -621,7 +623,7 @@ vector* GSLocalMemory::GetPage2TileMap(const GIFRegTEX0& TEX0) for(int x = 0, i = y << 7; x < tw; x += bs.x, i += bs.x) { - uint32 page = (base + o->block.col[x >> 3]) >> 5; + uint32 page = (base + o->block.col[x >> 3]) >> 5 & 511; if(page < MAX_PAGES) { @@ -1383,6 +1385,8 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB int sx = (int)TRXPOS.SSAX; int ex = sx + (int)TRXREG.RRW; + uint32 addr = psm->pa(0, y, bp, bw); + switch(BITBLTBUF.SPSM) { case PSM_PSMCT32: @@ -1395,19 +1399,18 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* RESTRICT offset = psm->rowOffset[y & 7]; - uint32* RESTRICT ps = &m_vm32[psm->pa(0, y, bp, bw)]; for(int ex4 = ex - 4; len >= 4 && x <= ex4; len -= 4, x += 4, pd += 4) { - pd[0] = ps[offset[x + 0]]; - pd[1] = ps[offset[x + 1]]; - pd[2] = ps[offset[x + 2]]; - pd[3] = ps[offset[x + 3]]; + pd[0] = ReadPixel32(addr + offset[x + 0]); + pd[1] = ReadPixel32(addr + offset[x + 1]); + pd[2] = ReadPixel32(addr + offset[x + 2]); + pd[3] = ReadPixel32(addr + offset[x + 3]); } for(; len > 0 && x < ex; len--, x++, pd++) { - *pd = ps[offset[x]]; + *pd = ReadPixel32(addr + offset[x]); } if(x == ex) {x = sx; y++;} @@ -1423,11 +1426,10 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* RESTRICT offset = psm->rowOffset[y & 7]; - uint32* RESTRICT ps = &m_vm32[psm->pa(0, y, bp, bw)]; for(; len > 0 && x < ex; len--, x++, pb += 3) { - uint32 c = ps[offset[x]]; + uint32 c = ReadPixel32(addr + offset[x]); pb[0] = (uint8)(c); pb[1] = (uint8)(c >> 8); @@ -1449,19 +1451,18 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* RESTRICT offset = psm->rowOffset[y & 7]; - uint16* RESTRICT ps = &m_vm16[psm->pa(0, y, bp, bw)]; for(int ex4 = ex - 4; len >= 4 && x <= ex4; len -= 4, x += 4, pw += 4) { - pw[0] = ps[offset[x + 0]]; - pw[1] = ps[offset[x + 1]]; - pw[2] = ps[offset[x + 2]]; - pw[3] = ps[offset[x + 3]]; + pw[0] = (uint16)ReadPixel16(addr + offset[x + 0]); + pw[1] = (uint16)ReadPixel16(addr + offset[x + 1]); + pw[2] = (uint16)ReadPixel16(addr + offset[x + 2]); + pw[3] = (uint16)ReadPixel16(addr + offset[x + 3]); } for(; len > 0 && x < ex; len--, x++, pw++) { - *pw = ps[offset[x]]; + *pw = (uint16)ReadPixel16(addr + offset[x]); } if(x == ex) {x = sx; y++;} @@ -1474,19 +1475,18 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* RESTRICT offset = psm->rowOffset[y & 7]; - uint8* RESTRICT ps = &m_vm8[psm->pa(0, y, bp, bw)]; for(int ex4 = ex - 4; len >= 4 && x <= ex4; len -= 4, x += 4, pb += 4) { - pb[0] = ps[offset[x + 0]]; - pb[1] = ps[offset[x + 1]]; - pb[2] = ps[offset[x + 2]]; - pb[3] = ps[offset[x + 3]]; + pb[0] = (uint8)ReadPixel8(addr + offset[x + 0]); + pb[1] = (uint8)ReadPixel8(addr + offset[x + 1]); + pb[2] = (uint8)ReadPixel8(addr + offset[x + 2]); + pb[3] = (uint8)ReadPixel8(addr + offset[x + 3]); } for(; len > 0 && x < ex; len--, x++, pb++) { - *pb = ps[offset[x]]; + *pb = (uint8)ReadPixel8(addr + offset[x]); } if(x == ex) {x = sx; y++;} @@ -1498,12 +1498,11 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { - uint32 addr = psm->pa(0, y, bp, bw); int* RESTRICT offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x += 2, pb++) { - *pb = ReadPixel4(addr + offset[x + 0]) | (ReadPixel4(addr + offset[x + 1]) << 4); + *pb = (uint8)(ReadPixel4(addr + offset[x + 0]) | (ReadPixel4(addr + offset[x + 1]) << 4)); } if(x == ex) {x = sx; y++;} @@ -1516,19 +1515,18 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* RESTRICT offset = psm->rowOffset[y & 7]; - uint32* RESTRICT ps = &m_vm32[psm->pa(0, y, bp, bw)]; for(int ex4 = ex - 4; len >= 4 && x <= ex4; len -= 4, x += 4, pb += 4) { - pb[0] = (uint8)(ps[offset[x + 0]] >> 24); - pb[1] = (uint8)(ps[offset[x + 1]] >> 24); - pb[2] = (uint8)(ps[offset[x + 2]] >> 24); - pb[3] = (uint8)(ps[offset[x + 3]] >> 24); + pb[0] = (uint8)ReadPixel8H(addr + offset[x + 0]); + pb[1] = (uint8)ReadPixel8H(addr + offset[x + 1]); + pb[2] = (uint8)ReadPixel8H(addr + offset[x + 2]); + pb[3] = (uint8)ReadPixel8H(addr + offset[x + 3]); } for(; len > 0 && x < ex; len--, x++, pb++) { - *pb = (uint8)(ps[offset[x]] >> 24); + *pb = (uint8)ReadPixel8H(addr + offset[x]); } if(x == ex) {x = sx; y++;} @@ -1541,14 +1539,13 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* offset = psm->rowOffset[y & 7]; - uint32* RESTRICT ps = &m_vm32[psm->pa(0, y, bp, bw)]; for(; len > 0 && x < ex; len--, x += 2, pb++) { - uint32 c0 = (ps[offset[x + 0]] >> 24) & 0x0f; - uint32 c1 = (ps[offset[x + 1]] >> 20) & 0xf0; + uint32 c0 = ReadPixel4HL(addr + offset[x + 0]); + uint32 c1 = ReadPixel4HL(addr + offset[x + 1]); - *pb = (uint8)(c0 | c1); + *pb = (uint8)(c0 | c1 << 4); } if(x == ex) {x = sx; y++;} @@ -1561,14 +1558,13 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* RESTRICT offset = psm->rowOffset[y & 7]; - uint32* RESTRICT ps = &m_vm32[psm->pa(0, y, bp, bw)]; for(; len > 0 && x < ex; len--, x += 2, pb++) { - uint32 c0 = (ps[offset[x + 0]] >> 28) & 0x0f; - uint32 c1 = (ps[offset[x + 1]] >> 24) & 0xf0; + uint32 c0 = ReadPixel4HH(addr + offset[x + 0]); + uint32 c1 = ReadPixel4HH(addr + offset[x + 1]); - *pb = (uint8)(c0 | c1); + *pb = (uint8)(c0 | c1 << 4); } if(x == ex) {x = sx; y++;} @@ -2040,7 +2036,7 @@ uint32* GSOffset::GetPages(const GSVector4i& rect, uint32* pages, GSVector4i* bb for(int x = r.left; x < r.right; x += bs.x) { - uint32 n = (base + block.col[x]) >> 5; + uint32 n = (base + block.col[x]) >> 5 & (MAX_PAGES-1); if(n < MAX_PAGES) { diff --git a/plugins/GSdx/GSLocalMemory.h b/plugins/GSdx/GSLocalMemory.h index 578a06fe5f..ee3c8da939 100644 --- a/plugins/GSdx/GSLocalMemory.h +++ b/plugins/GSdx/GSLocalMemory.h @@ -230,9 +230,7 @@ public: uint8* BlockPtr(uint32 bp) const { - ASSERT(bp < 16384); - - return &m_vm8[bp << 8]; + return &m_vm8[(bp & MAX_BLOCKS-1) << 8]; } uint8* BlockPtr32(int x, int y, uint32 bp, uint32 bw) const @@ -387,52 +385,52 @@ public: __forceinline uint32 ReadPixel32(uint32 addr) const { - return m_vm32[addr]; + return m_vm32[addr & 0xFFFFF]; } __forceinline uint32 ReadPixel24(uint32 addr) const { - return m_vm32[addr] & 0x00ffffff; + return m_vm32[addr & 0xFFFFF] & 0x00ffffff; } __forceinline uint32 ReadPixel16(uint32 addr) const { - return (uint32)m_vm16[addr]; + return (uint32)m_vm16[addr & 0x1FFFFF]; } __forceinline uint32 ReadPixel8(uint32 addr) const { - return (uint32)m_vm8[addr]; + return (uint32)m_vm8[addr & 0x3FFFFF]; } __forceinline uint32 ReadPixel4(uint32 addr) const { - return (m_vm8[addr >> 1] >> ((addr & 1) << 2)) & 0x0f; + return (m_vm8[addr >> 1 & 0x3FFFFF] >> ((addr & 1) << 2)) & 0x0f; } __forceinline uint32 ReadPixel8H(uint32 addr) const { - return m_vm32[addr] >> 24; + return m_vm32[addr & 0xFFFFF] >> 24; } __forceinline uint32 ReadPixel4HL(uint32 addr) const { - return (m_vm32[addr] >> 24) & 0x0f; + return (m_vm32[addr & 0xFFFFF] >> 24) & 0x0f; } __forceinline uint32 ReadPixel4HH(uint32 addr) const { - return (m_vm32[addr] >> 28) & 0x0f; + return (m_vm32[addr & 0xFFFFF] >> 28) & 0x0f; } __forceinline uint32 ReadFrame24(uint32 addr) const { - return 0x80000000 | (m_vm32[addr] & 0xffffff); + return 0x80000000 | (m_vm32[addr & 0xFFFFF] & 0xffffff); } __forceinline uint32 ReadFrame16(uint32 addr) const { - uint32 c = (uint32)m_vm16[addr]; + uint32 c = (uint32)m_vm16[addr & 0x1FFFFF]; return ((c & 0x8000) << 16) | ((c & 0x7c00) << 9) | ((c & 0x03e0) << 6) | ((c & 0x001f) << 3); } @@ -534,44 +532,44 @@ public: __forceinline void WritePixel32(uint32 addr, uint32 c) { - m_vm32[addr] = c; + m_vm32[addr & 0xFFFFF] = c; } __forceinline void WritePixel24(uint32 addr, uint32 c) { - m_vm32[addr] = (m_vm32[addr] & 0xff000000) | (c & 0x00ffffff); + m_vm32[addr & 0xFFFFF] = (m_vm32[addr & 0xFFFFF] & 0xff000000) | (c & 0x00ffffff); } __forceinline void WritePixel16(uint32 addr, uint32 c) { - m_vm16[addr] = (uint16)c; + m_vm16[addr & 0x1FFFFF] = (uint16)c; } __forceinline void WritePixel8(uint32 addr, uint32 c) { - m_vm8[addr] = (uint8)c; + m_vm8[addr & 0x3FFFFF] = (uint8)c; } __forceinline void WritePixel4(uint32 addr, uint32 c) { int shift = (addr & 1) << 2; addr >>= 1; - m_vm8[addr] = (uint8)((m_vm8[addr] & (0xf0 >> shift)) | ((c & 0x0f) << shift)); + m_vm8[addr & 0x3FFFFF] = (uint8)((m_vm8[addr & 0x3FFFFF] & (0xf0 >> shift)) | ((c & 0x0f) << shift)); } __forceinline void WritePixel8H(uint32 addr, uint32 c) { - m_vm32[addr] = (m_vm32[addr] & 0x00ffffff) | (c << 24); + m_vm32[addr & 0xFFFFF] = (m_vm32[addr & 0xFFFFF] & 0x00ffffff) | (c << 24); } __forceinline void WritePixel4HL(uint32 addr, uint32 c) { - m_vm32[addr] = (m_vm32[addr] & 0xf0ffffff) | ((c & 0x0f) << 24); + m_vm32[addr & 0xFFFFF] = (m_vm32[addr & 0xFFFFF] & 0xf0ffffff) | ((c & 0x0f) << 24); } __forceinline void WritePixel4HH(uint32 addr, uint32 c) { - m_vm32[addr] = (m_vm32[addr] & 0x0fffffff) | ((c & 0x0f) << 28); + m_vm32[addr & 0xFFFFF] = (m_vm32[addr & 0xFFFFF] & 0x0fffffff) | ((c & 0x0f) << 28); } __forceinline void WriteFrame16(uint32 addr, uint32 c) @@ -674,12 +672,12 @@ public: for(int y = r.top; y < r.bottom; y++, src += pitch) { uint32* RESTRICT s = (uint32*)src; - uint32* RESTRICT d = &m_vm32[o->pixel.row[y]]; + int d = o->pixel.row[y]; int* RESTRICT col = o->pixel.col[0]; for(int x = r.left; x < r.right; x++) { - d[col[x]] = s[x]; + m_vm32[d + col[x] & 0xFFFFF] = s[x]; } } } @@ -691,12 +689,12 @@ public: for(int y = r.top; y < r.bottom; y++, src += pitch) { uint32* RESTRICT s = (uint32*)src; - uint32* RESTRICT d = &m_vm32[o->pixel.row[y]]; + int d = o->pixel.row[y]; int* RESTRICT col = o->pixel.col[0]; for(int x = r.left; x < r.right; x++) { - d[col[x]] = (d[col[x]] & 0xff000000) | (s[x] & 0x00ffffff); + m_vm32[d + col[x] & 0xFFFFF] = (m_vm32[d + col[x] & 0xFFFFF] & 0xff000000) | (s[x] & 0x00ffffff); } } } @@ -708,12 +706,12 @@ public: for(int y = r.top; y < r.bottom; y++, src += pitch) { uint16* RESTRICT s = (uint16*)src; - uint16* RESTRICT d = &m_vm16[o->pixel.row[y]]; + int d = o->pixel.row[y]; int* RESTRICT col = o->pixel.col[0]; for(int x = r.left; x < r.right; x++) { - d[col[x]] = s[x]; + m_vm16[d + col[x] & 0x1FFFFF] = s[x]; } } } @@ -725,7 +723,7 @@ public: for(int y = r.top; y < r.bottom; y++, src += pitch) { uint32* RESTRICT s = (uint32*)src; - uint16* RESTRICT d = &m_vm16[o->pixel.row[y]]; + int d = o->pixel.row[y]; int* RESTRICT col = o->pixel.col[0]; for(int x = r.left; x < r.right; x++) @@ -733,24 +731,24 @@ public: uint32 rb = s[x] & 0x00f800f8; uint32 ga = s[x] & 0x8000f800; - d[col[x]] = (uint16)((ga >> 16) | (rb >> 9) | (ga >> 6) | (rb >> 3)); + m_vm16[d + col[x] & 0x1FFFFF] = (uint16)((ga >> 16) | (rb >> 9) | (ga >> 6) | (rb >> 3)); } } } __forceinline uint32 ReadTexel32(uint32 addr, const GIFRegTEXA& TEXA) const { - return m_vm32[addr]; + return m_vm32[addr & 0xFFFFF]; } __forceinline uint32 ReadTexel24(uint32 addr, const GIFRegTEXA& TEXA) const { - return Expand24To32(m_vm32[addr], TEXA); + return Expand24To32(m_vm32[addr & 0xFFFFF], TEXA); } __forceinline uint32 ReadTexel16(uint32 addr, const GIFRegTEXA& TEXA) const { - return Expand16To32(m_vm16[addr], TEXA); + return Expand16To32(m_vm16[addr & 0x1FFFFF], TEXA); } __forceinline uint32 ReadTexel8(uint32 addr, const GIFRegTEXA& TEXA) const diff --git a/plugins/GSdx/GSRendererDX.cpp b/plugins/GSdx/GSRendererDX.cpp index 1349e76c41..eab387828a 100644 --- a/plugins/GSdx/GSRendererDX.cpp +++ b/plugins/GSdx/GSRendererDX.cpp @@ -170,7 +170,7 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc { if(m_vt.m_max.p.z > 0xffff) { - ASSERT(m_vt.m_min.p.z > 0xffff); // sfex capcom logo + //ASSERT(m_vt.m_min.p.z > 0xffff); // sfex capcom logo // Fixme : Same as above, I guess. if (m_vt.m_min.p.z > 0xffff) { diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 6a58518031..2cb5d12a9b 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -1572,20 +1572,20 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32* RESTRICT s = &m_mem.m_vm32[spo->pixel.row[sy]]; - uint32* RESTRICT d = &m_mem.m_vm32[dpo->pixel.row[dy]]; + uint32 s = spo->pixel.row[sy]; + uint32 d = dpo->pixel.row[dy]; - for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]]; + for(int x = 0; x < w; x++) m_mem.WritePixel32(d + dcol[x], m_mem.ReadPixel32(s + scol[x])); } } else { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32* RESTRICT s = &m_mem.m_vm32[spo->pixel.row[sy]]; - uint32* RESTRICT d = &m_mem.m_vm32[dpo->pixel.row[dy]]; + uint32 s = spo->pixel.row[sy]; + uint32 d = dpo->pixel.row[dy]; - for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]]; + for(int x = 0; x > -w; x--) m_mem.WritePixel32(d + dcol[x], m_mem.ReadPixel32(s + scol[x])); } } } @@ -1595,20 +1595,20 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32* RESTRICT s = &m_mem.m_vm32[spo->pixel.row[sy]]; - uint32* RESTRICT d = &m_mem.m_vm32[dpo->pixel.row[dy]]; + uint32 s = spo->pixel.row[sy]; + uint32 d = dpo->pixel.row[dy]; - for(int x = 0; x < w; x++) d[dcol[x]] = (d[dcol[x]] & 0xff000000) | (s[scol[x]] & 0x00ffffff); + for(int x = 0; x < w; x++) m_mem.WritePixel24(d + dcol[x], m_mem.ReadPixel24(s + scol[x])); } } else { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32* RESTRICT s = &m_mem.m_vm32[spo->pixel.row[sy]]; - uint32* RESTRICT d = &m_mem.m_vm32[dpo->pixel.row[dy]]; + uint32 s = spo->pixel.row[sy]; + uint32 d = dpo->pixel.row[dy]; - for(int x = 0; x > -w; x--) d[dcol[x]] = (d[dcol[x]] & 0xff000000) | (s[scol[x]] & 0x00ffffff); + for(int x = 0; x > -w; x--) m_mem.WritePixel24(d + dcol[x], m_mem.ReadPixel24(s + scol[x])); } } } @@ -1618,20 +1618,20 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint16* RESTRICT s = &m_mem.m_vm16[spo->pixel.row[sy]]; - uint16* RESTRICT d = &m_mem.m_vm16[dpo->pixel.row[dy]]; + uint32 s = spo->pixel.row[sy]; + uint32 d = dpo->pixel.row[dy]; - for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]]; + for(int x = 0; x < w; x++) m_mem.WritePixel16(d + dcol[x], m_mem.ReadPixel16(s + scol[x])); } } else { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint16* RESTRICT s = &m_mem.m_vm16[spo->pixel.row[sy]]; - uint16* RESTRICT d = &m_mem.m_vm16[dpo->pixel.row[dy]]; + uint32 s = spo->pixel.row[sy]; + uint32 d = dpo->pixel.row[dy]; - for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]]; + for(int x = 0; x > -w; x--) m_mem.WritePixel16(d + dcol[x], m_mem.ReadPixel16(s + scol[x])); } } } @@ -1642,26 +1642,26 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint8* RESTRICT s = &m_mem.m_vm8[spo->pixel.row[sy]]; - uint8* RESTRICT d = &m_mem.m_vm8[dpo->pixel.row[dy]]; + uint32 s = spo->pixel.row[sy]; + uint32 d = dpo->pixel.row[dy]; int* RESTRICT scol = &spo->pixel.col[sy & 7][sx]; int* RESTRICT dcol = &dpo->pixel.col[dy & 7][dx]; - for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]]; + for(int x = 0; x < w; x++) m_mem.WritePixel8(d + dcol[x], m_mem.ReadPixel8(s + scol[x])); } } else { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint8* RESTRICT s = &m_mem.m_vm8[spo->pixel.row[sy]]; - uint8* RESTRICT d = &m_mem.m_vm8[dpo->pixel.row[dy]]; + uint32 s = spo->pixel.row[sy]; + uint32 d = dpo->pixel.row[dy]; int* RESTRICT scol = &spo->pixel.col[sy & 7][sx]; int* RESTRICT dcol = &dpo->pixel.col[dy & 7][dx]; - for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]]; + for(int x = 0; x > -w; x--) m_mem.WritePixel8(d + dcol[x], m_mem.ReadPixel8(s + scol[x])); } } } diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index d82ed1242f..5f273c5f13 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -409,6 +409,7 @@ void GSTextureCache::InvalidateVideoMem(GSOffset* o, const GSVector4i& rect, boo if(GSUtil::HasSharedBits(psm, t->m_TEX0.PSM) && bp < t->m_TEX0.TBP0) { uint32 rowsize = bw * 8192; + // FIXME: what if TBP0 < bp? uint32 offset = (uint32)((t->m_TEX0.TBP0 - bp) * 256); if(rowsize > 0 && offset % rowsize == 0) @@ -922,7 +923,7 @@ void GSTextureCache::Source::Update(const GSVector4i& rect) for(int x = r.left, i = (y << 7) + x; x < r.right; x += bs.x, i += bs.x) { - uint32 block = base + o->block.col[x >> 3]; + uint32 block = base + o->block.col[x >> 3] & (MAX_BLOCKS-1); if(block < MAX_BLOCKS) { @@ -951,7 +952,7 @@ void GSTextureCache::Source::Update(const GSVector4i& rect) for(int x = r.left; x < r.right; x += bs.x) { - uint32 block = base + o->block.col[x >> 3]; + uint32 block = base + o->block.col[x >> 3] & (MAX_BLOCKS-1); if(block < MAX_BLOCKS) { @@ -1185,7 +1186,7 @@ void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, const GSO for(int x = 0; x < tw; x += bs.x) { - uint32 page = (base + o->block.col[x >> 3]) >> 5; + uint32 page = (base + o->block.col[x >> 3]) >> 5 & (MAX_PAGES-1); if(page < MAX_PAGES) { diff --git a/plugins/GSdx/GSTextureCacheSW.cpp b/plugins/GSdx/GSTextureCacheSW.cpp index 3700e52795..8127cb6c2e 100644 --- a/plugins/GSdx/GSTextureCacheSW.cpp +++ b/plugins/GSdx/GSTextureCacheSW.cpp @@ -278,7 +278,7 @@ bool GSTextureCacheSW::Texture::Update(const GSVector4i& rect) for(int x = r.left, i = (y << 7) + x; x < r.right; x += bs.x, i += bs.x) { - uint32 block = base + o->block.col[x]; + uint32 block = base + o->block.col[x] & (MAX_BLOCKS-1); if(block < MAX_BLOCKS) { @@ -305,7 +305,7 @@ bool GSTextureCacheSW::Texture::Update(const GSVector4i& rect) for(int x = r.left; x < r.right; x += bs.x) { - uint32 block = base + o->block.col[x]; + uint32 block = base + o->block.col[x] & (MAX_BLOCKS-1); if(block < MAX_BLOCKS) { From b1536a755f5327035aecd1d931d0fa1e6994f20a Mon Sep 17 00:00:00 2001 From: "sudonim1@gmail.com" Date: Fri, 8 Feb 2013 15:36:54 +0000 Subject: [PATCH 13/13] GSDX: Nothing is fixed, the last two revisions did not happen. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5549 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/GSClut.cpp | 12 ++-- plugins/GSdx/GSLocalMemory.cpp | 74 ++++++++++++------------ plugins/GSdx/GSLocalMemory.h | 94 ++++++++++++++++--------------- plugins/GSdx/GSRendererDX.cpp | 2 +- plugins/GSdx/GSState.cpp | 48 ++++++++-------- plugins/GSdx/GSTextureCache.cpp | 7 +-- plugins/GSdx/GSTextureCacheSW.cpp | 4 +- 7 files changed, 123 insertions(+), 118 deletions(-) diff --git a/plugins/GSdx/GSClut.cpp b/plugins/GSdx/GSClut.cpp index bfe6274fdb..f61dabcfe6 100644 --- a/plugins/GSdx/GSClut.cpp +++ b/plugins/GSdx/GSClut.cpp @@ -172,14 +172,14 @@ template void GSClut::WriteCLUT32_CSM2(const GIFRegTEX0& TEX0, const GIFR { GSOffset* o = m_mem->GetOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT32); - uint32 addr = o->pixel.row[TEXCLUT.COV]; + uint32* RESTRICT s = &m_mem->m_vm32[o->pixel.row[TEXCLUT.COV]]; int* RESTRICT col = &o->pixel.col[0][TEXCLUT.COU << 4]; uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4); for(int i = 0; i < n; i++) { - uint32 c = m_mem->ReadPixel32(addr + col[i]); + uint32 c = s[col[i]]; clut[i] = (uint16)(c & 0xffff); clut[i + 256] = (uint16)(c >> 16); @@ -190,14 +190,14 @@ template void GSClut::WriteCLUT16_CSM2(const GIFRegTEX0& TEX0, const GIFR { GSOffset* o = m_mem->GetOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16); - uint32 addr = o->pixel.row[TEXCLUT.COV]; + uint16* RESTRICT s = &m_mem->m_vm16[o->pixel.row[TEXCLUT.COV]]; int* RESTRICT col = &o->pixel.col[0][TEXCLUT.COU << 4]; uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4); for(int i = 0; i < n; i++) { - clut[i] = (uint16)m_mem->ReadPixel16(addr + col[i]); + clut[i] = s[col[i]]; } } @@ -205,14 +205,14 @@ template void GSClut::WriteCLUT16S_CSM2(const GIFRegTEX0& TEX0, const GIF { GSOffset* o = m_mem->GetOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16S); - uint32 addr = o->pixel.row[TEXCLUT.COV]; + uint16* RESTRICT s = &m_mem->m_vm16[o->pixel.row[TEXCLUT.COV]]; int* RESTRICT col = &o->pixel.col[0][TEXCLUT.COU << 4]; uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4); for(int i = 0; i < n; i++) { - clut[i] = (uint16)m_mem->ReadPixel16(addr + col[i]); + clut[i] = s[col[i]]; } } diff --git a/plugins/GSdx/GSLocalMemory.cpp b/plugins/GSdx/GSLocalMemory.cpp index 990ee3c12b..dac52f6d95 100644 --- a/plugins/GSdx/GSLocalMemory.cpp +++ b/plugins/GSdx/GSLocalMemory.cpp @@ -83,11 +83,9 @@ GSLocalMemory::psm_t GSLocalMemory::m_psm[64]; GSLocalMemory::GSLocalMemory() : m_clut(this) { - m_vm8 = (uint8*)vmalloc(m_vmsize * 16, false); + m_vm8 = (uint8*)vmalloc(m_vmsize * 2, false); m_vm16 = (uint16*)m_vm8; m_vm32 = (uint32*)m_vm8; - DWORD oldprotect; - VirtualProtect(m_vm8 + m_vmsize, m_vmsize * 15, PAGE_NOACCESS, &oldprotect); memset(m_vm8, 0, m_vmsize); @@ -623,7 +621,7 @@ vector* GSLocalMemory::GetPage2TileMap(const GIFRegTEX0& TEX0) for(int x = 0, i = y << 7; x < tw; x += bs.x, i += bs.x) { - uint32 page = (base + o->block.col[x >> 3]) >> 5 & 511; + uint32 page = (base + o->block.col[x >> 3]) >> 5; if(page < MAX_PAGES) { @@ -1385,8 +1383,6 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB int sx = (int)TRXPOS.SSAX; int ex = sx + (int)TRXREG.RRW; - uint32 addr = psm->pa(0, y, bp, bw); - switch(BITBLTBUF.SPSM) { case PSM_PSMCT32: @@ -1399,18 +1395,19 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* RESTRICT offset = psm->rowOffset[y & 7]; + uint32* RESTRICT ps = &m_vm32[psm->pa(0, y, bp, bw)]; for(int ex4 = ex - 4; len >= 4 && x <= ex4; len -= 4, x += 4, pd += 4) { - pd[0] = ReadPixel32(addr + offset[x + 0]); - pd[1] = ReadPixel32(addr + offset[x + 1]); - pd[2] = ReadPixel32(addr + offset[x + 2]); - pd[3] = ReadPixel32(addr + offset[x + 3]); + pd[0] = ps[offset[x + 0]]; + pd[1] = ps[offset[x + 1]]; + pd[2] = ps[offset[x + 2]]; + pd[3] = ps[offset[x + 3]]; } for(; len > 0 && x < ex; len--, x++, pd++) { - *pd = ReadPixel32(addr + offset[x]); + *pd = ps[offset[x]]; } if(x == ex) {x = sx; y++;} @@ -1426,10 +1423,11 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* RESTRICT offset = psm->rowOffset[y & 7]; + uint32* RESTRICT ps = &m_vm32[psm->pa(0, y, bp, bw)]; for(; len > 0 && x < ex; len--, x++, pb += 3) { - uint32 c = ReadPixel32(addr + offset[x]); + uint32 c = ps[offset[x]]; pb[0] = (uint8)(c); pb[1] = (uint8)(c >> 8); @@ -1451,18 +1449,19 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* RESTRICT offset = psm->rowOffset[y & 7]; + uint16* RESTRICT ps = &m_vm16[psm->pa(0, y, bp, bw)]; for(int ex4 = ex - 4; len >= 4 && x <= ex4; len -= 4, x += 4, pw += 4) { - pw[0] = (uint16)ReadPixel16(addr + offset[x + 0]); - pw[1] = (uint16)ReadPixel16(addr + offset[x + 1]); - pw[2] = (uint16)ReadPixel16(addr + offset[x + 2]); - pw[3] = (uint16)ReadPixel16(addr + offset[x + 3]); + pw[0] = ps[offset[x + 0]]; + pw[1] = ps[offset[x + 1]]; + pw[2] = ps[offset[x + 2]]; + pw[3] = ps[offset[x + 3]]; } for(; len > 0 && x < ex; len--, x++, pw++) { - *pw = (uint16)ReadPixel16(addr + offset[x]); + *pw = ps[offset[x]]; } if(x == ex) {x = sx; y++;} @@ -1475,18 +1474,19 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* RESTRICT offset = psm->rowOffset[y & 7]; + uint8* RESTRICT ps = &m_vm8[psm->pa(0, y, bp, bw)]; for(int ex4 = ex - 4; len >= 4 && x <= ex4; len -= 4, x += 4, pb += 4) { - pb[0] = (uint8)ReadPixel8(addr + offset[x + 0]); - pb[1] = (uint8)ReadPixel8(addr + offset[x + 1]); - pb[2] = (uint8)ReadPixel8(addr + offset[x + 2]); - pb[3] = (uint8)ReadPixel8(addr + offset[x + 3]); + pb[0] = ps[offset[x + 0]]; + pb[1] = ps[offset[x + 1]]; + pb[2] = ps[offset[x + 2]]; + pb[3] = ps[offset[x + 3]]; } for(; len > 0 && x < ex; len--, x++, pb++) { - *pb = (uint8)ReadPixel8(addr + offset[x]); + *pb = ps[offset[x]]; } if(x == ex) {x = sx; y++;} @@ -1498,11 +1498,12 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { + uint32 addr = psm->pa(0, y, bp, bw); int* RESTRICT offset = psm->rowOffset[y & 7]; for(; len > 0 && x < ex; len--, x += 2, pb++) { - *pb = (uint8)(ReadPixel4(addr + offset[x + 0]) | (ReadPixel4(addr + offset[x + 1]) << 4)); + *pb = ReadPixel4(addr + offset[x + 0]) | (ReadPixel4(addr + offset[x + 1]) << 4); } if(x == ex) {x = sx; y++;} @@ -1515,18 +1516,19 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* RESTRICT offset = psm->rowOffset[y & 7]; + uint32* RESTRICT ps = &m_vm32[psm->pa(0, y, bp, bw)]; for(int ex4 = ex - 4; len >= 4 && x <= ex4; len -= 4, x += 4, pb += 4) { - pb[0] = (uint8)ReadPixel8H(addr + offset[x + 0]); - pb[1] = (uint8)ReadPixel8H(addr + offset[x + 1]); - pb[2] = (uint8)ReadPixel8H(addr + offset[x + 2]); - pb[3] = (uint8)ReadPixel8H(addr + offset[x + 3]); + pb[0] = (uint8)(ps[offset[x + 0]] >> 24); + pb[1] = (uint8)(ps[offset[x + 1]] >> 24); + pb[2] = (uint8)(ps[offset[x + 2]] >> 24); + pb[3] = (uint8)(ps[offset[x + 3]] >> 24); } for(; len > 0 && x < ex; len--, x++, pb++) { - *pb = (uint8)ReadPixel8H(addr + offset[x]); + *pb = (uint8)(ps[offset[x]] >> 24); } if(x == ex) {x = sx; y++;} @@ -1539,13 +1541,14 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* offset = psm->rowOffset[y & 7]; + uint32* RESTRICT ps = &m_vm32[psm->pa(0, y, bp, bw)]; for(; len > 0 && x < ex; len--, x += 2, pb++) { - uint32 c0 = ReadPixel4HL(addr + offset[x + 0]); - uint32 c1 = ReadPixel4HL(addr + offset[x + 1]); + uint32 c0 = (ps[offset[x + 0]] >> 24) & 0x0f; + uint32 c1 = (ps[offset[x + 1]] >> 20) & 0xf0; - *pb = (uint8)(c0 | c1 << 4); + *pb = (uint8)(c0 | c1); } if(x == ex) {x = sx; y++;} @@ -1558,13 +1561,14 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB while(len > 0) { int* RESTRICT offset = psm->rowOffset[y & 7]; + uint32* RESTRICT ps = &m_vm32[psm->pa(0, y, bp, bw)]; for(; len > 0 && x < ex; len--, x += 2, pb++) { - uint32 c0 = ReadPixel4HH(addr + offset[x + 0]); - uint32 c1 = ReadPixel4HH(addr + offset[x + 1]); + uint32 c0 = (ps[offset[x + 0]] >> 28) & 0x0f; + uint32 c1 = (ps[offset[x + 1]] >> 24) & 0xf0; - *pb = (uint8)(c0 | c1 << 4); + *pb = (uint8)(c0 | c1); } if(x == ex) {x = sx; y++;} @@ -2036,7 +2040,7 @@ uint32* GSOffset::GetPages(const GSVector4i& rect, uint32* pages, GSVector4i* bb for(int x = r.left; x < r.right; x += bs.x) { - uint32 n = (base + block.col[x]) >> 5 & (MAX_PAGES-1); + uint32 n = (base + block.col[x]) >> 5; if(n < MAX_PAGES) { diff --git a/plugins/GSdx/GSLocalMemory.h b/plugins/GSdx/GSLocalMemory.h index ee3c8da939..2a7e16426b 100644 --- a/plugins/GSdx/GSLocalMemory.h +++ b/plugins/GSdx/GSLocalMemory.h @@ -186,51 +186,53 @@ public: static uint32 BlockNumber32(int x, int y, uint32 bp, uint32 bw) { - return bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable32[(y >> 3) & 3][(x >> 3) & 7] & 16383; + return bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable32[(y >> 3) & 3][(x >> 3) & 7]; } static uint32 BlockNumber16(int x, int y, uint32 bp, uint32 bw) { - return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16[(y >> 3) & 7][(x >> 4) & 3] & 16383; + return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16[(y >> 3) & 7][(x >> 4) & 3]; } static uint32 BlockNumber16S(int x, int y, uint32 bp, uint32 bw) { - return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16S[(y >> 3) & 7][(x >> 4) & 3] & 16383; + return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16S[(y >> 3) & 7][(x >> 4) & 3]; } static uint32 BlockNumber8(int x, int y, uint32 bp, uint32 bw) { // ASSERT((bw & 1) == 0); // allowed for mipmap levels - return bp + ((y >> 1) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f) + blockTable8[(y >> 4) & 3][(x >> 4) & 7] & 16383; + return bp + ((y >> 1) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f) + blockTable8[(y >> 4) & 3][(x >> 4) & 7]; } static uint32 BlockNumber4(int x, int y, uint32 bp, uint32 bw) { // ASSERT((bw & 1) == 0); // allowed for mipmap levels - return bp + ((y >> 2) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f) + blockTable4[(y >> 4) & 7][(x >> 5) & 3] & 16383; + return bp + ((y >> 2) & ~0x1f) * (bw >> 1) + ((x >> 2) & ~0x1f) + blockTable4[(y >> 4) & 7][(x >> 5) & 3]; } static uint32 BlockNumber32Z(int x, int y, uint32 bp, uint32 bw) { - return bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable32Z[(y >> 3) & 3][(x >> 3) & 7] & 16383; + return bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable32Z[(y >> 3) & 3][(x >> 3) & 7]; } static uint32 BlockNumber16Z(int x, int y, uint32 bp, uint32 bw) { - return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16Z[(y >> 3) & 7][(x >> 4) & 3] & 16383; + return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16Z[(y >> 3) & 7][(x >> 4) & 3]; } static uint32 BlockNumber16SZ(int x, int y, uint32 bp, uint32 bw) { - return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16SZ[(y >> 3) & 7][(x >> 4) & 3] & 16383; + return bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f) + blockTable16SZ[(y >> 3) & 7][(x >> 4) & 3]; } uint8* BlockPtr(uint32 bp) const { - return &m_vm8[(bp & MAX_BLOCKS-1) << 8]; + ASSERT(bp < 16384); + + return &m_vm8[bp << 8]; } uint8* BlockPtr32(int x, int y, uint32 bp, uint32 bw) const @@ -315,7 +317,7 @@ public: static __forceinline uint32 PixelAddress32(int x, int y, uint32 bp, uint32 bw) { - uint32 page = (bp >> 5) + (y >> 5) * bw + (x >> 6) & 511; + uint32 page = (bp >> 5) + (y >> 5) * bw + (x >> 6); uint32 word = (page << 11) + pageOffset32[bp & 0x1f][y & 0x1f][x & 0x3f]; return word; @@ -323,7 +325,7 @@ public: static __forceinline uint32 PixelAddress16(int x, int y, uint32 bp, uint32 bw) { - uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6) & 511; + uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6); uint32 word = (page << 12) + pageOffset16[bp & 0x1f][y & 0x3f][x & 0x3f]; return word; @@ -331,7 +333,7 @@ public: static __forceinline uint32 PixelAddress16S(int x, int y, uint32 bp, uint32 bw) { - uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6) & 511; + uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6); uint32 word = (page << 12) + pageOffset16S[bp & 0x1f][y & 0x3f][x & 0x3f]; return word; @@ -341,7 +343,7 @@ public: { // ASSERT((bw & 1) == 0); // allowed for mipmap levels - uint32 page = (bp >> 5) + (y >> 6) * (bw >> 1) + (x >> 7) & 511; + uint32 page = (bp >> 5) + (y >> 6) * (bw >> 1) + (x >> 7); uint32 word = (page << 13) + pageOffset8[bp & 0x1f][y & 0x3f][x & 0x7f]; return word; @@ -351,7 +353,7 @@ public: { // ASSERT((bw & 1) == 0); // allowed for mipmap levels - uint32 page = (bp >> 5) + (y >> 7) * (bw >> 1) + (x >> 7) & 511; + uint32 page = (bp >> 5) + (y >> 7) * (bw >> 1) + (x >> 7); uint32 word = (page << 14) + pageOffset4[bp & 0x1f][y & 0x7f][x & 0x7f]; return word; @@ -359,7 +361,7 @@ public: static __forceinline uint32 PixelAddress32Z(int x, int y, uint32 bp, uint32 bw) { - uint32 page = (bp >> 5) + (y >> 5) * bw + (x >> 6) & 511; + uint32 page = (bp >> 5) + (y >> 5) * bw + (x >> 6); uint32 word = (page << 11) + pageOffset32Z[bp & 0x1f][y & 0x1f][x & 0x3f]; return word; @@ -367,7 +369,7 @@ public: static __forceinline uint32 PixelAddress16Z(int x, int y, uint32 bp, uint32 bw) { - uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6) & 511; + uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6); uint32 word = (page << 12) + pageOffset16Z[bp & 0x1f][y & 0x3f][x & 0x3f]; return word; @@ -375,7 +377,7 @@ public: static __forceinline uint32 PixelAddress16SZ(int x, int y, uint32 bp, uint32 bw) { - uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6) & 511; + uint32 page = (bp >> 5) + (y >> 6) * bw + (x >> 6); uint32 word = (page << 12) + pageOffset16SZ[bp & 0x1f][y & 0x3f][x & 0x3f]; return word; @@ -385,52 +387,52 @@ public: __forceinline uint32 ReadPixel32(uint32 addr) const { - return m_vm32[addr & 0xFFFFF]; + return m_vm32[addr]; } __forceinline uint32 ReadPixel24(uint32 addr) const { - return m_vm32[addr & 0xFFFFF] & 0x00ffffff; + return m_vm32[addr] & 0x00ffffff; } __forceinline uint32 ReadPixel16(uint32 addr) const { - return (uint32)m_vm16[addr & 0x1FFFFF]; + return (uint32)m_vm16[addr]; } __forceinline uint32 ReadPixel8(uint32 addr) const { - return (uint32)m_vm8[addr & 0x3FFFFF]; + return (uint32)m_vm8[addr]; } __forceinline uint32 ReadPixel4(uint32 addr) const { - return (m_vm8[addr >> 1 & 0x3FFFFF] >> ((addr & 1) << 2)) & 0x0f; + return (m_vm8[addr >> 1] >> ((addr & 1) << 2)) & 0x0f; } __forceinline uint32 ReadPixel8H(uint32 addr) const { - return m_vm32[addr & 0xFFFFF] >> 24; + return m_vm32[addr] >> 24; } __forceinline uint32 ReadPixel4HL(uint32 addr) const { - return (m_vm32[addr & 0xFFFFF] >> 24) & 0x0f; + return (m_vm32[addr] >> 24) & 0x0f; } __forceinline uint32 ReadPixel4HH(uint32 addr) const { - return (m_vm32[addr & 0xFFFFF] >> 28) & 0x0f; + return (m_vm32[addr] >> 28) & 0x0f; } __forceinline uint32 ReadFrame24(uint32 addr) const { - return 0x80000000 | (m_vm32[addr & 0xFFFFF] & 0xffffff); + return 0x80000000 | (m_vm32[addr] & 0xffffff); } __forceinline uint32 ReadFrame16(uint32 addr) const { - uint32 c = (uint32)m_vm16[addr & 0x1FFFFF]; + uint32 c = (uint32)m_vm16[addr]; return ((c & 0x8000) << 16) | ((c & 0x7c00) << 9) | ((c & 0x03e0) << 6) | ((c & 0x001f) << 3); } @@ -532,44 +534,44 @@ public: __forceinline void WritePixel32(uint32 addr, uint32 c) { - m_vm32[addr & 0xFFFFF] = c; + m_vm32[addr] = c; } __forceinline void WritePixel24(uint32 addr, uint32 c) { - m_vm32[addr & 0xFFFFF] = (m_vm32[addr & 0xFFFFF] & 0xff000000) | (c & 0x00ffffff); + m_vm32[addr] = (m_vm32[addr] & 0xff000000) | (c & 0x00ffffff); } __forceinline void WritePixel16(uint32 addr, uint32 c) { - m_vm16[addr & 0x1FFFFF] = (uint16)c; + m_vm16[addr] = (uint16)c; } __forceinline void WritePixel8(uint32 addr, uint32 c) { - m_vm8[addr & 0x3FFFFF] = (uint8)c; + m_vm8[addr] = (uint8)c; } __forceinline void WritePixel4(uint32 addr, uint32 c) { int shift = (addr & 1) << 2; addr >>= 1; - m_vm8[addr & 0x3FFFFF] = (uint8)((m_vm8[addr & 0x3FFFFF] & (0xf0 >> shift)) | ((c & 0x0f) << shift)); + m_vm8[addr] = (uint8)((m_vm8[addr] & (0xf0 >> shift)) | ((c & 0x0f) << shift)); } __forceinline void WritePixel8H(uint32 addr, uint32 c) { - m_vm32[addr & 0xFFFFF] = (m_vm32[addr & 0xFFFFF] & 0x00ffffff) | (c << 24); + m_vm32[addr] = (m_vm32[addr] & 0x00ffffff) | (c << 24); } __forceinline void WritePixel4HL(uint32 addr, uint32 c) { - m_vm32[addr & 0xFFFFF] = (m_vm32[addr & 0xFFFFF] & 0xf0ffffff) | ((c & 0x0f) << 24); + m_vm32[addr] = (m_vm32[addr] & 0xf0ffffff) | ((c & 0x0f) << 24); } __forceinline void WritePixel4HH(uint32 addr, uint32 c) { - m_vm32[addr & 0xFFFFF] = (m_vm32[addr & 0xFFFFF] & 0x0fffffff) | ((c & 0x0f) << 28); + m_vm32[addr] = (m_vm32[addr] & 0x0fffffff) | ((c & 0x0f) << 28); } __forceinline void WriteFrame16(uint32 addr, uint32 c) @@ -672,12 +674,12 @@ public: for(int y = r.top; y < r.bottom; y++, src += pitch) { uint32* RESTRICT s = (uint32*)src; - int d = o->pixel.row[y]; + uint32* RESTRICT d = &m_vm32[o->pixel.row[y]]; int* RESTRICT col = o->pixel.col[0]; for(int x = r.left; x < r.right; x++) { - m_vm32[d + col[x] & 0xFFFFF] = s[x]; + d[col[x]] = s[x]; } } } @@ -689,12 +691,12 @@ public: for(int y = r.top; y < r.bottom; y++, src += pitch) { uint32* RESTRICT s = (uint32*)src; - int d = o->pixel.row[y]; + uint32* RESTRICT d = &m_vm32[o->pixel.row[y]]; int* RESTRICT col = o->pixel.col[0]; for(int x = r.left; x < r.right; x++) { - m_vm32[d + col[x] & 0xFFFFF] = (m_vm32[d + col[x] & 0xFFFFF] & 0xff000000) | (s[x] & 0x00ffffff); + d[col[x]] = (d[col[x]] & 0xff000000) | (s[x] & 0x00ffffff); } } } @@ -706,12 +708,12 @@ public: for(int y = r.top; y < r.bottom; y++, src += pitch) { uint16* RESTRICT s = (uint16*)src; - int d = o->pixel.row[y]; + uint16* RESTRICT d = &m_vm16[o->pixel.row[y]]; int* RESTRICT col = o->pixel.col[0]; for(int x = r.left; x < r.right; x++) { - m_vm16[d + col[x] & 0x1FFFFF] = s[x]; + d[col[x]] = s[x]; } } } @@ -723,7 +725,7 @@ public: for(int y = r.top; y < r.bottom; y++, src += pitch) { uint32* RESTRICT s = (uint32*)src; - int d = o->pixel.row[y]; + uint16* RESTRICT d = &m_vm16[o->pixel.row[y]]; int* RESTRICT col = o->pixel.col[0]; for(int x = r.left; x < r.right; x++) @@ -731,24 +733,24 @@ public: uint32 rb = s[x] & 0x00f800f8; uint32 ga = s[x] & 0x8000f800; - m_vm16[d + col[x] & 0x1FFFFF] = (uint16)((ga >> 16) | (rb >> 9) | (ga >> 6) | (rb >> 3)); + d[col[x]] = (uint16)((ga >> 16) | (rb >> 9) | (ga >> 6) | (rb >> 3)); } } } __forceinline uint32 ReadTexel32(uint32 addr, const GIFRegTEXA& TEXA) const { - return m_vm32[addr & 0xFFFFF]; + return m_vm32[addr]; } __forceinline uint32 ReadTexel24(uint32 addr, const GIFRegTEXA& TEXA) const { - return Expand24To32(m_vm32[addr & 0xFFFFF], TEXA); + return Expand24To32(m_vm32[addr], TEXA); } __forceinline uint32 ReadTexel16(uint32 addr, const GIFRegTEXA& TEXA) const { - return Expand16To32(m_vm16[addr & 0x1FFFFF], TEXA); + return Expand16To32(m_vm16[addr], TEXA); } __forceinline uint32 ReadTexel8(uint32 addr, const GIFRegTEXA& TEXA) const diff --git a/plugins/GSdx/GSRendererDX.cpp b/plugins/GSdx/GSRendererDX.cpp index eab387828a..1349e76c41 100644 --- a/plugins/GSdx/GSRendererDX.cpp +++ b/plugins/GSdx/GSRendererDX.cpp @@ -170,7 +170,7 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc { if(m_vt.m_max.p.z > 0xffff) { - //ASSERT(m_vt.m_min.p.z > 0xffff); // sfex capcom logo + ASSERT(m_vt.m_min.p.z > 0xffff); // sfex capcom logo // Fixme : Same as above, I guess. if (m_vt.m_min.p.z > 0xffff) { diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 2cb5d12a9b..6a58518031 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -1572,20 +1572,20 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32 s = spo->pixel.row[sy]; - uint32 d = dpo->pixel.row[dy]; + uint32* RESTRICT s = &m_mem.m_vm32[spo->pixel.row[sy]]; + uint32* RESTRICT d = &m_mem.m_vm32[dpo->pixel.row[dy]]; - for(int x = 0; x < w; x++) m_mem.WritePixel32(d + dcol[x], m_mem.ReadPixel32(s + scol[x])); + for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]]; } } else { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32 s = spo->pixel.row[sy]; - uint32 d = dpo->pixel.row[dy]; + uint32* RESTRICT s = &m_mem.m_vm32[spo->pixel.row[sy]]; + uint32* RESTRICT d = &m_mem.m_vm32[dpo->pixel.row[dy]]; - for(int x = 0; x > -w; x--) m_mem.WritePixel32(d + dcol[x], m_mem.ReadPixel32(s + scol[x])); + for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]]; } } } @@ -1595,20 +1595,20 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32 s = spo->pixel.row[sy]; - uint32 d = dpo->pixel.row[dy]; + uint32* RESTRICT s = &m_mem.m_vm32[spo->pixel.row[sy]]; + uint32* RESTRICT d = &m_mem.m_vm32[dpo->pixel.row[dy]]; - for(int x = 0; x < w; x++) m_mem.WritePixel24(d + dcol[x], m_mem.ReadPixel24(s + scol[x])); + for(int x = 0; x < w; x++) d[dcol[x]] = (d[dcol[x]] & 0xff000000) | (s[scol[x]] & 0x00ffffff); } } else { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32 s = spo->pixel.row[sy]; - uint32 d = dpo->pixel.row[dy]; + uint32* RESTRICT s = &m_mem.m_vm32[spo->pixel.row[sy]]; + uint32* RESTRICT d = &m_mem.m_vm32[dpo->pixel.row[dy]]; - for(int x = 0; x > -w; x--) m_mem.WritePixel24(d + dcol[x], m_mem.ReadPixel24(s + scol[x])); + for(int x = 0; x > -w; x--) d[dcol[x]] = (d[dcol[x]] & 0xff000000) | (s[scol[x]] & 0x00ffffff); } } } @@ -1618,20 +1618,20 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32 s = spo->pixel.row[sy]; - uint32 d = dpo->pixel.row[dy]; + uint16* RESTRICT s = &m_mem.m_vm16[spo->pixel.row[sy]]; + uint16* RESTRICT d = &m_mem.m_vm16[dpo->pixel.row[dy]]; - for(int x = 0; x < w; x++) m_mem.WritePixel16(d + dcol[x], m_mem.ReadPixel16(s + scol[x])); + for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]]; } } else { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32 s = spo->pixel.row[sy]; - uint32 d = dpo->pixel.row[dy]; + uint16* RESTRICT s = &m_mem.m_vm16[spo->pixel.row[sy]]; + uint16* RESTRICT d = &m_mem.m_vm16[dpo->pixel.row[dy]]; - for(int x = 0; x > -w; x--) m_mem.WritePixel16(d + dcol[x], m_mem.ReadPixel16(s + scol[x])); + for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]]; } } } @@ -1642,26 +1642,26 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32 s = spo->pixel.row[sy]; - uint32 d = dpo->pixel.row[dy]; + uint8* RESTRICT s = &m_mem.m_vm8[spo->pixel.row[sy]]; + uint8* RESTRICT d = &m_mem.m_vm8[dpo->pixel.row[dy]]; int* RESTRICT scol = &spo->pixel.col[sy & 7][sx]; int* RESTRICT dcol = &dpo->pixel.col[dy & 7][dx]; - for(int x = 0; x < w; x++) m_mem.WritePixel8(d + dcol[x], m_mem.ReadPixel8(s + scol[x])); + for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]]; } } else { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32 s = spo->pixel.row[sy]; - uint32 d = dpo->pixel.row[dy]; + uint8* RESTRICT s = &m_mem.m_vm8[spo->pixel.row[sy]]; + uint8* RESTRICT d = &m_mem.m_vm8[dpo->pixel.row[dy]]; int* RESTRICT scol = &spo->pixel.col[sy & 7][sx]; int* RESTRICT dcol = &dpo->pixel.col[dy & 7][dx]; - for(int x = 0; x > -w; x--) m_mem.WritePixel8(d + dcol[x], m_mem.ReadPixel8(s + scol[x])); + for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]]; } } } diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index 5f273c5f13..d82ed1242f 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -409,7 +409,6 @@ void GSTextureCache::InvalidateVideoMem(GSOffset* o, const GSVector4i& rect, boo if(GSUtil::HasSharedBits(psm, t->m_TEX0.PSM) && bp < t->m_TEX0.TBP0) { uint32 rowsize = bw * 8192; - // FIXME: what if TBP0 < bp? uint32 offset = (uint32)((t->m_TEX0.TBP0 - bp) * 256); if(rowsize > 0 && offset % rowsize == 0) @@ -923,7 +922,7 @@ void GSTextureCache::Source::Update(const GSVector4i& rect) for(int x = r.left, i = (y << 7) + x; x < r.right; x += bs.x, i += bs.x) { - uint32 block = base + o->block.col[x >> 3] & (MAX_BLOCKS-1); + uint32 block = base + o->block.col[x >> 3]; if(block < MAX_BLOCKS) { @@ -952,7 +951,7 @@ void GSTextureCache::Source::Update(const GSVector4i& rect) for(int x = r.left; x < r.right; x += bs.x) { - uint32 block = base + o->block.col[x >> 3] & (MAX_BLOCKS-1); + uint32 block = base + o->block.col[x >> 3]; if(block < MAX_BLOCKS) { @@ -1186,7 +1185,7 @@ void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, const GSO for(int x = 0; x < tw; x += bs.x) { - uint32 page = (base + o->block.col[x >> 3]) >> 5 & (MAX_PAGES-1); + uint32 page = (base + o->block.col[x >> 3]) >> 5; if(page < MAX_PAGES) { diff --git a/plugins/GSdx/GSTextureCacheSW.cpp b/plugins/GSdx/GSTextureCacheSW.cpp index 8127cb6c2e..3700e52795 100644 --- a/plugins/GSdx/GSTextureCacheSW.cpp +++ b/plugins/GSdx/GSTextureCacheSW.cpp @@ -278,7 +278,7 @@ bool GSTextureCacheSW::Texture::Update(const GSVector4i& rect) for(int x = r.left, i = (y << 7) + x; x < r.right; x += bs.x, i += bs.x) { - uint32 block = base + o->block.col[x] & (MAX_BLOCKS-1); + uint32 block = base + o->block.col[x]; if(block < MAX_BLOCKS) { @@ -305,7 +305,7 @@ bool GSTextureCacheSW::Texture::Update(const GSVector4i& rect) for(int x = r.left; x < r.right; x += bs.x) { - uint32 block = base + o->block.col[x] & (MAX_BLOCKS-1); + uint32 block = base + o->block.col[x]; if(block < MAX_BLOCKS) {