introduce GetInOutLatencyMs to query the actual latency from the sound interface
This commit is contained in:
parent
d089e7d308
commit
3fc6ccc8aa
4 changed files with 50 additions and 9 deletions
|
@ -1229,15 +1229,32 @@ int CClient::EstimatedOverallDelay ( const int iPingTimeMs )
|
||||||
static_cast<double> ( GetSockBufNumFrames() +
|
static_cast<double> ( GetSockBufNumFrames() +
|
||||||
GetServerSockBufNumFrames() ) / 2;
|
GetServerSockBufNumFrames() ) / 2;
|
||||||
|
|
||||||
|
// consider delay introduced by the sound card conversion buffer by using
|
||||||
|
// "GetSndCrdConvBufAdditionalDelayMonoBlSize()"
|
||||||
|
double dTotalSoundCardDelayMs = GetSndCrdConvBufAdditionalDelayMonoBlSize() *
|
||||||
|
1000 / SYSTEM_SAMPLE_RATE_HZ;
|
||||||
|
|
||||||
|
// try to get the actual input/output sound card delay from the audio
|
||||||
|
// interface, per definition it is not available if a 0 is returned
|
||||||
|
const double dSoundCardInputOutputLatencyMs = Sound.GetInOutLatencyMs();
|
||||||
|
|
||||||
|
if ( dSoundCardInputOutputLatencyMs == 0.0 )
|
||||||
|
{
|
||||||
|
// use an alternative aproach for estimating the sound card delay:
|
||||||
|
//
|
||||||
// we assume that we have two period sizes for the input and one for the
|
// we assume that we have two period sizes for the input and one for the
|
||||||
// output, therefore we have "3 *" instead of "2 *" (for input and output)
|
// output, therefore we have "3 *" instead of "2 *" (for input and output)
|
||||||
// the actual sound card buffer size, also consider delay introduced by
|
// the actual sound card buffer size
|
||||||
// sound card conversion buffer by using
|
|
||||||
// "GetSndCrdConvBufAdditionalDelayMonoBlSize"
|
// "GetSndCrdConvBufAdditionalDelayMonoBlSize"
|
||||||
const double dTotalSoundCardDelayMs =
|
dTotalSoundCardDelayMs +=
|
||||||
( 3 * GetSndCrdActualMonoBlSize() +
|
( 3 * GetSndCrdActualMonoBlSize() ) *
|
||||||
GetSndCrdConvBufAdditionalDelayMonoBlSize() ) *
|
|
||||||
1000 / SYSTEM_SAMPLE_RATE_HZ;
|
1000 / SYSTEM_SAMPLE_RATE_HZ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// add the actual sound card latency in ms
|
||||||
|
dTotalSoundCardDelayMs += dSoundCardInputOutputLatencyMs;
|
||||||
|
}
|
||||||
|
|
||||||
// network packets are of the same size as the audio packets per definition
|
// network packets are of the same size as the audio packets per definition
|
||||||
// if no sound card conversion buffer is used
|
// if no sound card conversion buffer is used
|
||||||
|
|
|
@ -77,6 +77,8 @@ public:
|
||||||
virtual int GetLeftOutputChannel() { return 0; }
|
virtual int GetLeftOutputChannel() { return 0; }
|
||||||
virtual int GetRightOutputChannel() { return 1; }
|
virtual int GetRightOutputChannel() { return 1; }
|
||||||
|
|
||||||
|
virtual double GetInOutLatencyMs() { return 0.0; } // "0.0" means no latency is available
|
||||||
|
|
||||||
virtual void OpenDriverSetup() {}
|
virtual void OpenDriverSetup() {}
|
||||||
|
|
||||||
bool IsRunning() const { return bRun; }
|
bool IsRunning() const { return bRun; }
|
||||||
|
|
|
@ -363,6 +363,24 @@ int CSound::Init ( const int iNewPrefMonoBufferSize )
|
||||||
2 /* in/out */ * NUM_IN_OUT_CHANNELS /* stereo */,
|
2 /* in/out */ * NUM_IN_OUT_CHANNELS /* stereo */,
|
||||||
iASIOBufferSizeMono, &asioCallbacks );
|
iASIOBufferSizeMono, &asioCallbacks );
|
||||||
|
|
||||||
|
// query the latency of the driver
|
||||||
|
long lInputLatency = 0;
|
||||||
|
long lOutputLatency = 0;
|
||||||
|
|
||||||
|
if ( ASIOGetLatencies ( &lInputLatency, &lOutputLatency ) != ASE_NotPresent )
|
||||||
|
{
|
||||||
|
// add the input and output latencies (returned in number of
|
||||||
|
// samples) and calculate the time in ms
|
||||||
|
dInOutLatencyMs =
|
||||||
|
( static_cast<double> ( lInputLatency ) + lOutputLatency ) /
|
||||||
|
SYSTEM_SAMPLE_RATE_HZ * 1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no latency available
|
||||||
|
dInOutLatencyMs = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
// check wether the driver requires the ASIOOutputReady() optimization
|
// check wether the driver requires the ASIOOutputReady() optimization
|
||||||
// (can be used by the driver to reduce output latency by one block)
|
// (can be used by the driver to reduce output latency by one block)
|
||||||
bASIOPostOutput = ( ASIOOutputReady() == ASE_OK );
|
bASIOPostOutput = ( ASIOOutputReady() == ASE_OK );
|
||||||
|
@ -402,7 +420,8 @@ CSound::CSound ( void (*fpNewCallback) ( CVector<int16_t>& psData, void* arg ),
|
||||||
vSelectedInputChannels ( NUM_IN_OUT_CHANNELS ),
|
vSelectedInputChannels ( NUM_IN_OUT_CHANNELS ),
|
||||||
vSelectedOutputChannels ( NUM_IN_OUT_CHANNELS ),
|
vSelectedOutputChannels ( NUM_IN_OUT_CHANNELS ),
|
||||||
lNumInChan ( 0 ),
|
lNumInChan ( 0 ),
|
||||||
lNumOutChan ( 0 )
|
lNumOutChan ( 0 ),
|
||||||
|
dInOutLatencyMs ( 0.0 ) // "0.0" means that no latency value is available
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,8 @@ public:
|
||||||
virtual int GetLeftOutputChannel() { return vSelectedOutputChannels[0]; }
|
virtual int GetLeftOutputChannel() { return vSelectedOutputChannels[0]; }
|
||||||
virtual int GetRightOutputChannel() { return vSelectedOutputChannels[1]; }
|
virtual int GetRightOutputChannel() { return vSelectedOutputChannels[1]; }
|
||||||
|
|
||||||
|
virtual double GetInOutLatencyMs() { return dInOutLatencyMs; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QString LoadAndInitializeDriver ( int iIdx );
|
virtual QString LoadAndInitializeDriver ( int iIdx );
|
||||||
virtual void UnloadCurrentDriver();
|
virtual void UnloadCurrentDriver();
|
||||||
|
@ -85,6 +87,7 @@ protected:
|
||||||
|
|
||||||
long lNumInChan;
|
long lNumInChan;
|
||||||
long lNumOutChan;
|
long lNumOutChan;
|
||||||
|
double dInOutLatencyMs;
|
||||||
CVector<int> vSelectedInputChannels;
|
CVector<int> vSelectedInputChannels;
|
||||||
CVector<int> vSelectedOutputChannels;
|
CVector<int> vSelectedOutputChannels;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue