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
This commit is contained in:
ramapcsx2 2010-03-19 20:28:10 +00:00
parent 8c0fc49f61
commit 86dcb0a1a9
6 changed files with 75 additions and 65 deletions

View File

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

View File

@ -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.

View File

@ -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; p<packets; p++, p1+=SndOutPacketSize )
SndBuffer::ReadSamples( p1 );
writtenSoFar += packets * SndOutPacketSize;
return 0;
}
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; p<packets; p++, p1+=SndOutPacketSize )
SndBuffer::ReadSamples( p1 );
writtenSoFar += packets * SndOutPacketSize;
return 0;
}
Portaudio()
{
@ -123,9 +120,9 @@ public:
MultiByteToWideChar(CP_UTF8,0,info->name,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;

View File

@ -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);

View File

@ -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;
//////////////////////////////////////////////////////////////////////////////////////////

View File

@ -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