From 86dcb0a1a9082f9fcde3092dd24a939cd91b292a Mon Sep 17 00:00:00 2001 From: ramapcsx2 Date: Fri, 19 Mar 2010 20:28:10 +0000 Subject: [PATCH] SPU2-X: Work on support for Wasapi's exclusive mode. Not enabled yet. Also lower (/8) sound out packet size. Helps the timestretcher responsiveness and quality. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2755 96395faa-99c1-11dd-bbfe-3dabce05a288 --- .../src/hostapi/wasapi/pa_win_wasapi.c | 4 + plugins/spu2-x/src/SndOut.h | 2 +- plugins/spu2-x/src/SndOut_Portaudio.cpp | 128 +++++++++--------- plugins/spu2-x/src/Timestretcher.cpp | 2 +- plugins/spu2-x/src/Windows/SndOut_DSound.cpp | 2 +- plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp | 2 +- 6 files changed, 75 insertions(+), 65 deletions(-) diff --git a/3rdparty/portaudio/src/hostapi/wasapi/pa_win_wasapi.c b/3rdparty/portaudio/src/hostapi/wasapi/pa_win_wasapi.c index b1974ddbcb..071326b3c2 100644 --- a/3rdparty/portaudio/src/hostapi/wasapi/pa_win_wasapi.c +++ b/3rdparty/portaudio/src/hostapi/wasapi/pa_win_wasapi.c @@ -1806,6 +1806,10 @@ static HRESULT CreateAudioClient(PaWasapiSubStream *pSubStream, PaWasapiDeviceIn if (pSubStream->period < info->DefaultDevicePeriod) pSubStream->period = info->DefaultDevicePeriod; } + // Issues with setting exclusive mode due to pSubStream->period beeing wrong somehow + // Most likely reason is that framesPerLatency is hardcoded to 0. + else if (pSubStream->shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE) + pSubStream->period = info->MinimumDevicePeriod; // Gives 3ms of latency // Open the stream and associate it with an audio session hr = IAudioClient_Initialize(pAudioClient, diff --git a/plugins/spu2-x/src/SndOut.h b/plugins/spu2-x/src/SndOut.h index 897f704b1b..02b96f615a 100644 --- a/plugins/spu2-x/src/SndOut.h +++ b/plugins/spu2-x/src/SndOut.h @@ -20,7 +20,7 @@ // Number of stereo samples per SndOut block. // All drivers must work in units of this size when communicating with // SndOut. -static const int SndOutPacketSize = 512; +static const int SndOutPacketSize = 64; // Overall master volume shift. // Converts the mixer's 32 bit value into a 16 bit value. diff --git a/plugins/spu2-x/src/SndOut_Portaudio.cpp b/plugins/spu2-x/src/SndOut_Portaudio.cpp index b1b6b5037f..a377b50473 100644 --- a/plugins/spu2-x/src/SndOut_Portaudio.cpp +++ b/plugins/spu2-x/src/SndOut_Portaudio.cpp @@ -21,22 +21,19 @@ #include "Dialogs.h" #include "portaudio/include/portaudio.h" - -#ifdef __LINUX__ -int PaLinuxCallback( const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void *userData ); -#endif +#include "portaudio/include/pa_win_wasapi.h" + +#ifdef __LINUX__ +int PaLinuxCallback( const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void *userData ); +#endif class Portaudio : public SndOutModule { private: - static const uint MAX_BUFFER_COUNT = 8; - static const int PacketsPerBuffer = 1; - static const int BufferSize = SndOutPacketSize * PacketsPerBuffer; - ////////////////////////////////////////////////////////////////////////////////////////// // Configuration Vars (unused still) @@ -54,7 +51,7 @@ private: bool started; PaStream* stream; - + #ifndef __LINUX__ static int PaCallback( const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, @@ -63,27 +60,27 @@ private: void *userData ) { return PA.ActualPaCallback(inputBuffer,outputBuffer,framesPerBuffer,timeInfo,statusFlags,userData); - } -#endif + } +#endif -public: - int ActualPaCallback( const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void *userData ) - { - StereoOut32* p1 = (StereoOut32*)outputBuffer; - - int packets = framesPerBuffer / SndOutPacketSize; - - for(int p=0; pname,strlen(info->name),buffer,999); buffer[999]=0; #else -//# error TODO - static wchar_t buffer [1000]; - //MultiByteToWideChar(CP_UTF8,0,info->name,strlen(info->name),buffer,999); +//# error TODO + static wchar_t buffer [1000]; + //MultiByteToWideChar(CP_UTF8,0,info->name,strlen(info->name),buffer,999); buffer[999]=0; #endif @@ -153,6 +150,13 @@ public: if(deviceIndex>=0) { + PaWasapiStreamInfo info = { + sizeof(PaWasapiStreamInfo), + paWASAPI, + 1, + paWinWasapiExclusive + }; + PaStreamParameters outParams = { // PaDeviceIndex device; @@ -165,29 +169,30 @@ public: paInt32, 0, //? NULL - }; - + //&info // Use this instead of the NULL above, to pass it the Exclusive mode enable flag + }; + err = Pa_OpenStream(&stream, NULL, &outParams, SampleRate, SndOutPacketSize, - paNoFlag, -#ifndef __LINUX__ - PaCallback, -#else - PaLinuxCallback, -#endif + paNoFlag, +#ifndef __LINUX__ + PaCallback, +#else + PaLinuxCallback, +#endif NULL); } else { err = Pa_OpenDefaultStream( &stream, 0, 2, paInt32, 48000, - SndOutPacketSize, -#ifndef __LINUX__ - PaCallback, -#else - PaLinuxCallback, -#endif + SndOutPacketSize, +#ifndef __LINUX__ + PaCallback, +#else + PaLinuxCallback, +#endif NULL ); } if( err != paNoError ) @@ -258,6 +263,7 @@ public: writtenLastTime = writtenSoFar; availableLastTime = availableNow; + // Lowest resolution here is the SndOutPacketSize we use. return playedSinceLastTime; } @@ -323,16 +329,16 @@ public: } } static PA; - -#ifdef __LINUX__ - int PaLinuxCallback( const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void *userData ) - { - return PA.ActualPaCallback(inputBuffer,outputBuffer,framesPerBuffer,timeInfo,statusFlags,userData); - } -#endif + +#ifdef __LINUX__ + int PaLinuxCallback( const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void *userData ) + { + return PA.ActualPaCallback(inputBuffer,outputBuffer,framesPerBuffer,timeInfo,statusFlags,userData); + } +#endif SndOutModule *PortaudioOut = &PA; diff --git a/plugins/spu2-x/src/Timestretcher.cpp b/plugins/spu2-x/src/Timestretcher.cpp index 41831ce9c9..b1d568ba5a 100644 --- a/plugins/spu2-x/src/Timestretcher.cpp +++ b/plugins/spu2-x/src/Timestretcher.cpp @@ -55,7 +55,7 @@ float SndBuffer::GetStatusPct() int drvempty = mods[OutputModule]->GetEmptySampleCount(); // / 2; - //ConLog( "Data %d >>> driver: %d predict: %d\n", data, drvempty, predictData ); + //ConLog( "Data %d >>> driver: %d predict: %d\n", m_data, drvempty, m_predictData ); float result = (float)(m_data + m_predictData - drvempty) - (m_size/2); result /= (m_size/2); diff --git a/plugins/spu2-x/src/Windows/SndOut_DSound.cpp b/plugins/spu2-x/src/Windows/SndOut_DSound.cpp index 800499d2ac..87bde40bda 100644 --- a/plugins/spu2-x/src/Windows/SndOut_DSound.cpp +++ b/plugins/spu2-x/src/Windows/SndOut_DSound.cpp @@ -27,7 +27,7 @@ class DSound : public SndOutModule { private: static const uint MAX_BUFFER_COUNT = 8; - static const int PacketsPerBuffer = 1; + static const int PacketsPerBuffer = 8; static const int BufferSize = SndOutPacketSize * PacketsPerBuffer; ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp b/plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp index f5b72b6885..c13447a2dc 100644 --- a/plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp +++ b/plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp @@ -68,7 +68,7 @@ static const double SndOutNormalizer = (double)(1UL<<(SndOutVolumeShift+16)); class XAudio2Mod: public SndOutModule { private: - static const int PacketsPerBuffer = 1; + static const int PacketsPerBuffer = 8; static const int MAX_BUFFER_COUNT = 3; class BaseStreamingVoice : public IXAudio2VoiceCallback