ASIO fixes

This commit is contained in:
Volker Fischer 2008-07-13 22:57:31 +00:00
parent 94d6d451bc
commit 11e8dc7b3d
5 changed files with 53 additions and 24 deletions

View file

@ -400,13 +400,6 @@ fflush(pFileDelay);
const double dCurAddVal = const double dCurAddVal =
( (double) TimeLastBlock.msecsTo ( CurTime ) - MIN_BLOCK_DURATION_MS ); ( (double) TimeLastBlock.msecsTo ( CurTime ) - MIN_BLOCK_DURATION_MS );
/*
// TEST
static FILE* pFileTest = fopen("sti.dat", "w");
fprintf(pFileTest, "%e\n", dCurAddVal);
fflush(pFileTest);
*/
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); // add squared value RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); // add squared value
// store old time value // store old time value
@ -416,6 +409,9 @@ fflush(pFileTest);
// disable channel // disable channel
Channel.SetEnable ( false ); Channel.SetEnable ( false );
// disable sound interface
Sound.Close();
// reset current signal level and LEDs // reset current signal level and LEDs
SignalLevelMeterL.Reset(); SignalLevelMeterL.Reset();
SignalLevelMeterR.Reset(); SignalLevelMeterR.Reset();

View file

@ -36,13 +36,21 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
// init slider controls --- // init slider controls ---
// sound buffer in // sound buffer in
#ifdef _WIN32
SliderSndBufIn->setRange ( 1, AUD_SLIDER_LENGTH ); // for ASIO we only need one buffer
#else
SliderSndBufIn->setRange ( 2, AUD_SLIDER_LENGTH ); SliderSndBufIn->setRange ( 2, AUD_SLIDER_LENGTH );
#endif
const int iCurNumInBuf = pClient->GetSndInterface()->GetInNumBuf(); const int iCurNumInBuf = pClient->GetSndInterface()->GetInNumBuf();
SliderSndBufIn->setValue ( iCurNumInBuf ); SliderSndBufIn->setValue ( iCurNumInBuf );
TextSndBufIn->setText ( "In: " + QString().setNum ( iCurNumInBuf ) ); TextSndBufIn->setText ( "In: " + QString().setNum ( iCurNumInBuf ) );
// sound buffer out // sound buffer out
#ifdef _WIN32
SliderSndBufOut->setRange ( 1, AUD_SLIDER_LENGTH ); // for ASIO we only need one buffer
#else
SliderSndBufOut->setRange ( 2, AUD_SLIDER_LENGTH ); SliderSndBufOut->setRange ( 2, AUD_SLIDER_LENGTH );
#endif
const int iCurNumOutBuf = pClient->GetSndInterface()->GetOutNumBuf(); const int iCurNumOutBuf = pClient->GetSndInterface()->GetOutNumBuf();
SliderSndBufOut->setValue ( iCurNumOutBuf ); SliderSndBufOut->setValue ( iCurNumOutBuf );
TextSndBufOut->setText ( "Out: " + QString().setNum ( iCurNumOutBuf ) ); TextSndBufOut->setText ( "Out: " + QString().setNum ( iCurNumOutBuf ) );

View file

@ -412,7 +412,7 @@
<item> <item>
<widget class="QGroupBox" name="GroupBoxSoundCardBuffers" > <widget class="QGroupBox" name="GroupBoxSoundCardBuffers" >
<property name="title" > <property name="title" >
<string>Sndcard Buffers</string> <string>Soundcard Buffers</string>
</property> </property>
<layout class="QVBoxLayout" > <layout class="QVBoxLayout" >
<property name="spacing" > <property name="spacing" >

View file

@ -59,13 +59,17 @@ HANDLE m_ASIOEvent;
// wave in // wave in
int iInCurBlockToWrite; int iInCurBlockToWrite;
short* psSoundcardBuffer[MAX_SND_BUF_IN]; short* psSoundcardBuffer[MAX_SND_BUF_IN];
bool bBufferOverrun;
// wave out // wave out
int iOutCurBlockToWrite; int iOutCurBlockToWrite;
short* psPlaybackBuffer[MAX_SND_BUF_OUT]; short* psPlaybackBuffer[MAX_SND_BUF_OUT];
bool bBufferUnderrun;
int iCurNumSndBufIn; int iCurNumSndBufIn;
int iCurNumSndBufOut; int iCurNumSndBufOut;
int iNewNumSndBufIn;
int iNewNumSndBufOut;
// we must implement these functions here to get access to global variables // we must implement these functions here to get access to global variables
int CSound::GetOutNumBuf() { return iCurNumSndBufOut; } int CSound::GetOutNumBuf() { return iCurNumSndBufOut; }
@ -78,7 +82,7 @@ int CSound::GetInNumBuf() { return iCurNumSndBufIn; }
bool CSound::Read ( CVector<short>& psData ) bool CSound::Read ( CVector<short>& psData )
{ {
int i, j; int i, j;
bool bError = false; bool bError;
// check if device must be opened or reinitialized // check if device must be opened or reinitialized
if ( bChangParamIn ) if ( bChangParamIn )
@ -103,12 +107,16 @@ bool CSound::Read ( CVector<short>& psData )
} }
} }
// if the number of done buffers equals the total number of buffers, it is
// very likely that a buffer got lost -> set error flag
bError = ( iInCurBlockToWrite == iCurNumSndBufIn );
ASIOMutex.lock(); // get mutex lock ASIOMutex.lock(); // get mutex lock
{ {
// check for buffer overrun in ASIO thread
bError = bBufferOverrun;
if ( bBufferOverrun )
{
// reset flag
bBufferOverrun = false;
}
// copy data from sound card in output buffer // copy data from sound card in output buffer
for ( i = 0; i < iBufferSizeStereo; i++ ) for ( i = 0; i < iBufferSizeStereo; i++ )
{ {
@ -146,7 +154,7 @@ void CSound::SetInNumBuf ( int iNewNum )
// change only if parameter is different // change only if parameter is different
if ( iNewNum != iCurNumSndBufIn ) if ( iNewNum != iCurNumSndBufIn )
{ {
iCurNumSndBufIn = iNewNum; iNewNumSndBufIn = iNewNum;
bChangParamIn = true; bChangParamIn = true;
} }
} }
@ -157,8 +165,7 @@ void CSound::SetInNumBuf ( int iNewNum )
\******************************************************************************/ \******************************************************************************/
bool CSound::Write ( CVector<short>& psData ) bool CSound::Write ( CVector<short>& psData )
{ {
// init return state bool bError;
bool bError = false;
// check if device must be opened or reinitialized // check if device must be opened or reinitialized
if ( bChangParamOut ) if ( bChangParamOut )
@ -172,6 +179,14 @@ bool CSound::Write ( CVector<short>& psData )
ASIOMutex.lock(); // get mutex lock ASIOMutex.lock(); // get mutex lock
{ {
// check for buffer underrun in ASIO thread
bError = bBufferUnderrun;
if ( bBufferUnderrun )
{
// reset flag
bBufferUnderrun = false;
}
// first check if buffer is available // first check if buffer is available
if ( iOutCurBlockToWrite < iCurNumSndBufOut ) if ( iOutCurBlockToWrite < iCurNumSndBufOut )
{ {
@ -205,7 +220,7 @@ void CSound::SetOutNumBuf ( int iNewNum )
// change only if parameter is different // change only if parameter is different
if ( iNewNum != iCurNumSndBufOut ) if ( iNewNum != iCurNumSndBufOut )
{ {
iCurNumSndBufOut = iNewNum; iNewNumSndBufOut = iNewNum;
bChangParamOut = true; bChangParamOut = true;
} }
} }
@ -334,9 +349,14 @@ if ( iASIOBufferSizeMono != iBufferSizeMono )
} }
// our buffer management ----------------------------------------------- // Our buffer management -----------------------------------------------
// initialize write block pointer in // store new buffer number values
iCurNumSndBufIn = iNewNumSndBufIn;
iCurNumSndBufOut = iNewNumSndBufOut;
// initialize write block pointer in and overrun flag
iInCurBlockToWrite = 0; iInCurBlockToWrite = 0;
bBufferOverrun = false;
// create memory for sound card buffer // create memory for sound card buffer
for ( i = 0; i < iCurNumSndBufIn; i++ ) for ( i = 0; i < iCurNumSndBufIn; i++ )
@ -349,8 +369,9 @@ if ( iASIOBufferSizeMono != iBufferSizeMono )
psSoundcardBuffer[i] = new short[iBufferSizeStereo]; psSoundcardBuffer[i] = new short[iBufferSizeStereo];
} }
// initialize write block pointer out // initialize write block pointer out and underrun flag
iOutCurBlockToWrite = 0; iOutCurBlockToWrite = 0;
bBufferUnderrun = false;
// create memory for playback buffer // create memory for playback buffer
for ( j = 0; j < iCurNumSndBufOut; j++ ) for ( j = 0; j < iCurNumSndBufOut; j++ )
@ -403,7 +424,9 @@ CSound::CSound()
int i; int i;
// init number of sound buffers // init number of sound buffers
iNewNumSndBufIn = NUM_SOUND_BUFFERS_IN;
iCurNumSndBufIn = NUM_SOUND_BUFFERS_IN; iCurNumSndBufIn = NUM_SOUND_BUFFERS_IN;
iNewNumSndBufOut = NUM_SOUND_BUFFERS_OUT;
iCurNumSndBufOut = NUM_SOUND_BUFFERS_OUT; iCurNumSndBufOut = NUM_SOUND_BUFFERS_OUT;
// should be initialized because an error can occur during init // should be initialized because an error can occur during init
@ -616,7 +639,8 @@ void CSound::bufferSwitch ( long index, ASIOBool processNow )
} }
else else
{ {
// TODO: buffer underrun, inform user somehow...? // set buffer underrun flag
bBufferUnderrun = true;
} }
// capture // capture
@ -626,7 +650,8 @@ void CSound::bufferSwitch ( long index, ASIOBool processNow )
} }
else else
{ {
// TODO: buffer overrun, inform user somehow...? // set buffer overrun flag
bBufferOverrun = true;
} }
// finally if the driver supports the ASIOOutputReady() optimization, // finally if the driver supports the ASIOOutputReady() optimization,

View file

@ -47,8 +47,8 @@
#define MAX_SND_BUF_IN 100 #define MAX_SND_BUF_IN 100
#define MAX_SND_BUF_OUT 100 #define MAX_SND_BUF_OUT 100
#define NUM_SOUND_BUFFERS_IN 2 #define NUM_SOUND_BUFFERS_IN 1
#define NUM_SOUND_BUFFERS_OUT 2 #define NUM_SOUND_BUFFERS_OUT 1
// maximum number of recognized sound cards installed in the system // maximum number of recognized sound cards installed in the system
#define MAX_NUMBER_SOUND_CARDS 10 #define MAX_NUMBER_SOUND_CARDS 10