even more ASIO work, audio in and out in first version ready, at least some sound can be heard although it sounds a bit strange :-)

This commit is contained in:
Volker Fischer 2008-07-12 21:10:17 +00:00
parent 5eb8694134
commit 2cf4e4f285

View file

@ -55,10 +55,11 @@ int iBufferSize;
HANDLE m_ASIOEvent; HANDLE m_ASIOEvent;
// wave in // wave in
int iCurBlockToWrite; int iInCurBlockToWrite;
short* psSoundcardBuffer[MAX_SND_BUF_IN]; short* psSoundcardBuffer[MAX_SND_BUF_IN];
// wave out // wave out
int iOutCurBlockToWrite;
short* psPlaybackBuffer[MAX_SND_BUF_OUT]; short* psPlaybackBuffer[MAX_SND_BUF_OUT];
int iCurNumSndBufIn; int iCurNumSndBufIn;
@ -88,7 +89,7 @@ bool CSound::Read ( CVector<short>& psData )
} }
// wait until data is available // wait until data is available
if ( iCurBlockToWrite == 0 ) if ( iInCurBlockToWrite == 0 )
{ {
if ( bBlockingRec ) if ( bBlockingRec )
{ {
@ -102,7 +103,7 @@ bool CSound::Read ( CVector<short>& psData )
// If the number of done buffers equals the total number of buffers, it is // If the number of done buffers equals the total number of buffers, it is
// very likely that a buffer got lost -> set error flag // very likely that a buffer got lost -> set error flag
bError = ( iCurBlockToWrite == iCurNumSndBufIn ); bError = ( iInCurBlockToWrite == iCurNumSndBufIn );
ASIOMutex.lock(); // get mutex lock ASIOMutex.lock(); // get mutex lock
{ {
@ -113,7 +114,7 @@ bool CSound::Read ( CVector<short>& psData )
} }
// move all other data in buffer // move all other data in buffer
for ( j = 0; j < iCurBlockToWrite - 1; j++ ) for ( j = 0; j < iInCurBlockToWrite - 1; j++ )
{ {
for ( i = 0; i < iBufferSize; i++ ) for ( i = 0; i < iBufferSize; i++ )
{ {
@ -122,7 +123,7 @@ bool CSound::Read ( CVector<short>& psData )
} }
// adjust "current block to write" pointer // adjust "current block to write" pointer
iCurBlockToWrite--; iInCurBlockToWrite--;
} }
ASIOMutex.unlock(); ASIOMutex.unlock();
@ -154,10 +155,8 @@ void CSound::SetInNumBuf ( int iNewNum )
\******************************************************************************/ \******************************************************************************/
bool CSound::Write ( CVector<short>& psData ) bool CSound::Write ( CVector<short>& psData )
{ {
int i, j; // init return state
int iCntPrepBuf; bool bError = false;
int iIndexDoneBuf;
bool bError;
// check if device must be opened or reinitialized // check if device must be opened or reinitialized
if ( bChangParamOut ) if ( bChangParamOut )
@ -169,73 +168,26 @@ bool CSound::Write ( CVector<short>& psData )
bChangParamOut = false; bChangParamOut = false;
} }
/* ASIOMutex.lock(); // get mutex lock
// get number of "done"-buffers and position of one of them
GetDoneBuffer ( iCntPrepBuf, iIndexDoneBuf );
// now check special cases (Buffer is full or empty)
if ( iCntPrepBuf == 0 )
{ {
// Blocking wave out routine. Needed for transmitter. Always // first check if buffer is available
// ensure that the buffer is completely filled to avoid buffer if ( iOutCurBlockToWrite < iCurNumSndBufOut )
// underruns
while ( iCntPrepBuf == 0 )
{ {
WaitForSingleObject ( m_WaveOutEvent, INFINITE ); // copy stereo data from input in soundcard buffer
for ( int i = 0; i < iBufferSize; i++ )
{
psPlaybackBuffer[iOutCurBlockToWrite][i] = psData[i];
}
GetDoneBuffer ( iCntPrepBuf, iIndexDoneBuf ); iOutCurBlockToWrite++;
}
else
{
// buffer overrun, return error
bError = true;
} }
} }
else ASIOMutex.unlock();
{
if ( iCntPrepBuf == iCurNumSndBufOut )
{
// -----------------------------------------------------------------
// Buffer is empty -> send as many cleared blocks to the sound-
// interface until half of the buffer size is reached
// send half of the buffer size blocks to the sound-interface
for ( j = 0; j < iCurNumSndBufOut / 2; j++ )
{
// first, clear these buffers
for ( i = 0; i < iBufferSize; i++ )
{
psPlaybackBuffer[j][i] = 0;
}
// then send them to the interface
AddOutBuffer ( j );
}
// set index for done buffer
iIndexDoneBuf = iCurNumSndBufOut / 2;
bError = true;
}
else
{
bError = false;
}
}
*/
/*
// copy stereo data from input in soundcard buffer
for ( i = 0; i < iBufferSize; i++ )
{
psPlaybackBuffer[iIndexDoneBuf][i] = psData[i];
}
*/
/*
// now, send the current block
AddOutBuffer ( iIndexDoneBuf );
*/
// TEST
Sleep(10);
return true;
return bError; return bError;
} }
@ -264,8 +216,9 @@ void CSound::InitRecordingAndPlayback ( int iNewBufferSize )
{ {
int i, j; int i, j;
// first, stop audio // first, stop audio and dispose ASIO buffers
ASIOStop(); ASIOStop();
ASIODisposeBuffers();
ASIOMutex.lock(); // get mutex lock ASIOMutex.lock(); // get mutex lock
{ {
@ -345,8 +298,8 @@ void CSound::InitRecordingAndPlayback ( int iNewBufferSize )
// our buffer management ----------------------------------------------- // our buffer management -----------------------------------------------
// initialize write block pointer // initialize write block pointer in
iCurBlockToWrite = 0; iInCurBlockToWrite = 0;
// create memory for sound card buffer // create memory for sound card buffer
for ( i = 0; i < iCurNumSndBufIn; i++ ) for ( i = 0; i < iCurNumSndBufIn; i++ )
@ -359,37 +312,25 @@ void CSound::InitRecordingAndPlayback ( int iNewBufferSize )
psSoundcardBuffer[i] = new short[iBufferSize]; psSoundcardBuffer[i] = new short[iBufferSize];
} }
// initialize write block pointer out
iOutCurBlockToWrite = 0;
/*
// reset interface
waveOutReset ( m_WaveOut );
*/
/*
for ( j = 0; j < iCurNumSndBufOut; j++ )
{
// create memory for playback buffer // create memory for playback buffer
if ( psPlaybackBuffer[j] != NULL ) for ( j = 0; j < iCurNumSndBufOut; j++ )
{ {
delete[] psPlaybackBuffer[j]; if ( psPlaybackBuffer[j] != NULL )
} {
delete[] psPlaybackBuffer[j];
}
psPlaybackBuffer[j] = new short[iBufferSize]; psPlaybackBuffer[j] = new short[iBufferSize];
// clear new buffer // clear new buffer
for ( i = 0; i < iBufferSize; i++ ) for ( i = 0; i < iBufferSize; i++ )
{ {
psPlaybackBuffer[j][i] = 0; psPlaybackBuffer[j][i] = 0;
} }
}
// prepare buffer for sending to the sound interface
PrepareOutBuffer ( j );
// initially, send all buffers to the interface
AddOutBuffer ( j );
}
*/
// reset event // reset event
ResetEvent ( m_ASIOEvent ); ResetEvent ( m_ASIOEvent );
@ -405,7 +346,7 @@ void CSound::Close()
// set event to ensure that thread leaves the waiting function // set event to ensure that thread leaves the waiting function
if ( m_ASIOEvent != NULL ) if ( m_ASIOEvent != NULL )
{ {
SetEvent(m_ASIOEvent); SetEvent ( m_ASIOEvent );
} }
// wait for the thread to terminate // wait for the thread to terminate
@ -542,9 +483,9 @@ pstrDevices[0] = driverInfo.name;
// create event // create event
m_ASIOEvent = CreateEvent ( NULL, FALSE, FALSE, NULL ); m_ASIOEvent = CreateEvent ( NULL, FALSE, FALSE, NULL );
// set flag to open devices // init flag to open devices
bChangParamIn = true; bChangParamIn = false;
bChangParamOut = true; bChangParamOut = false;
} }
CSound::~CSound() CSound::~CSound()
@ -590,6 +531,8 @@ ASIOTime* CSound::bufferSwitchTimeInfo ( ASIOTime *timeInfo, long index, ASIOBoo
void CSound::bufferSwitch ( long index, ASIOBool processNow ) void CSound::bufferSwitch ( long index, ASIOBool processNow )
{ {
int iCurSample;
ASIOMutex.lock(); // get mutex lock ASIOMutex.lock(); // get mutex lock
{ {
// perform the processing for input and output // perform the processing for input and output
@ -598,43 +541,66 @@ void CSound::bufferSwitch ( long index, ASIOBool processNow )
if ( bufferInfos[i].isInput == false ) if ( bufferInfos[i].isInput == false )
{ {
// PLAYBACK -------------------------------------------------------- // PLAYBACK --------------------------------------------------------
// TODO the following is just a test code if ( iOutCurBlockToWrite > 0 )
//memset ( bufferInfos[i].buffers[index], 0, buffSize /** 2*/ ); {
// copy data from sound card in output buffer
for ( iCurSample = 0; iCurSample < iBufferSize; iCurSample++ )
{
((short*) bufferInfos[i].buffers[index])[iCurSample] =
psSoundcardBuffer[0][iCurSample];
}
// move all other data in buffer
for ( int j = 0; j < iOutCurBlockToWrite - 1; j++ )
{
for ( iCurSample = 0; iCurSample < iBufferSize; iCurSample++ )
{
psPlaybackBuffer[j][iCurSample] =
psPlaybackBuffer[j + 1][iCurSample];
}
}
// adjust "current block to write" pointer
iOutCurBlockToWrite--;
}
else
{
// TODO: buffer underrun, inform user somehow...?
}
} }
else else
{ {
// CAPTURE --------------------------------------------------------- // CAPTURE ---------------------------------------------------------
// first check if buffer is available // first check if buffer is available
if ( iCurBlockToWrite < iCurNumSndBufIn ) if ( iInCurBlockToWrite < iCurNumSndBufIn )
{ {
// copy new captured block in thread transfer buffer // copy new captured block in thread transfer buffer
for ( int iCurSample = 0; iCurSample < iBufferSize; iCurSample++ ) for ( iCurSample = 0; iCurSample < iBufferSize; iCurSample++ )
{ {
psSoundcardBuffer[iCurBlockToWrite][iCurSample] = psSoundcardBuffer[iInCurBlockToWrite][iCurSample] =
((short*) bufferInfos[i].buffers[index])[iCurSample]; ((short*) bufferInfos[i].buffers[index])[iCurSample];
} }
iCurBlockToWrite++; iInCurBlockToWrite++;
} }
else else
{ {
// TODO // TODO: buffer overrun, inform user somehow...?
// buffer overrun, inform user somehow...?
} }
} }
} }
// finally if the driver supports the ASIOOutputReady() optimization,
// do it here, all data are in place
if ( bASIOPostOutput )
{
ASIOOutputReady();
}
// set event
SetEvent ( m_ASIOEvent );
} }
ASIOMutex.unlock(); ASIOMutex.unlock();
// finally if the driver supports the ASIOOutputReady() optimization,
// do it here, all data are in place
if ( bASIOPostOutput )
{
ASIOOutputReady();
}
// set event
SetEvent ( m_ASIOEvent );
} }
long CSound::asioMessages ( long selector, long value, void* message, double* opt ) long CSound::asioMessages ( long selector, long value, void* message, double* opt )