some more ASIO implementation, audio in is nearly ready
This commit is contained in:
parent
3e3deac163
commit
5eb8694134
3 changed files with 187 additions and 319 deletions
|
@ -30,11 +30,19 @@
|
||||||
|
|
||||||
/* Implementation *************************************************************/
|
/* Implementation *************************************************************/
|
||||||
#ifdef USE_ASIO_SND_INTERFACE
|
#ifdef USE_ASIO_SND_INTERFACE
|
||||||
|
#include <qmutex.h>
|
||||||
|
|
||||||
// external references
|
// external references
|
||||||
extern AsioDrivers* asioDrivers;
|
extern AsioDrivers* asioDrivers;
|
||||||
bool loadAsioDriver ( char *name );
|
bool loadAsioDriver ( char *name );
|
||||||
|
|
||||||
|
// mutex
|
||||||
|
QMutex ASIOMutex;
|
||||||
|
|
||||||
|
// TODO the following variables should be in the class definition but we cannot
|
||||||
|
// do it here since we have static callback functions which cannot access the
|
||||||
|
// class members :-(((
|
||||||
|
|
||||||
// ASIO stuff
|
// ASIO stuff
|
||||||
ASIODriverInfo driverInfo;
|
ASIODriverInfo driverInfo;
|
||||||
ASIOBufferInfo bufferInfos[2 * NUM_IN_OUT_CHANNELS]; // for input and output buffers -> "2 *"
|
ASIOBufferInfo bufferInfos[2 * NUM_IN_OUT_CHANNELS]; // for input and output buffers -> "2 *"
|
||||||
|
@ -43,13 +51,30 @@ bool bASIOPostOutput;
|
||||||
ASIOCallbacks asioCallbacks;
|
ASIOCallbacks asioCallbacks;
|
||||||
int iBufferSize;
|
int iBufferSize;
|
||||||
|
|
||||||
|
// event
|
||||||
|
HANDLE m_ASIOEvent;
|
||||||
|
|
||||||
|
// wave in
|
||||||
|
int iCurBlockToWrite;
|
||||||
|
short* psSoundcardBuffer[MAX_SND_BUF_IN];
|
||||||
|
|
||||||
|
// wave out
|
||||||
|
short* psPlaybackBuffer[MAX_SND_BUF_OUT];
|
||||||
|
|
||||||
|
int iCurNumSndBufIn;
|
||||||
|
int iCurNumSndBufOut;
|
||||||
|
|
||||||
|
// we must implement these functions here to get access to global variables
|
||||||
|
int CSound::GetOutNumBuf() { return iCurNumSndBufOut; }
|
||||||
|
int CSound::GetInNumBuf() { return iCurNumSndBufIn; }
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
* Wave in *
|
* Wave in *
|
||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
bool CSound::Read ( CVector<short>& psData )
|
bool CSound::Read ( CVector<short>& psData )
|
||||||
{
|
{
|
||||||
int i;
|
int i, j;
|
||||||
bool bError = false;
|
bool bError = false;
|
||||||
|
|
||||||
// check if device must be opened or reinitialized
|
// check if device must be opened or reinitialized
|
||||||
|
@ -62,100 +87,51 @@ bool CSound::Read ( CVector<short>& psData )
|
||||||
bChangParamIn = false;
|
bChangParamIn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
// wait until data is available
|
// wait until data is available
|
||||||
if ( ! ( m_WaveInHeader[iWhichBufferIn].dwFlags & WHDR_DONE ) )
|
if ( iCurBlockToWrite == 0 )
|
||||||
{
|
{
|
||||||
if ( bBlockingRec )
|
if ( bBlockingRec )
|
||||||
{
|
{
|
||||||
WaitForSingleObject ( m_WaveInEvent, INFINITE );
|
WaitForSingleObject ( m_ASIOEvent, INFINITE );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
// check if buffers got lost
|
|
||||||
int iNumInBufDone = 0;
|
|
||||||
for ( i = 0; i < iCurNumSndBufIn; i++ )
|
|
||||||
{
|
|
||||||
if ( m_WaveInHeader[i].dwFlags & WHDR_DONE )
|
|
||||||
{
|
|
||||||
iNumInBufDone++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
// 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
|
||||||
if ( iNumInBufDone == iCurNumSndBufIn )
|
bError = ( iCurBlockToWrite == iCurNumSndBufIn );
|
||||||
{
|
|
||||||
bError = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bError = false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
ASIOMutex.lock(); // get mutex lock
|
||||||
/*
|
{
|
||||||
// copy data from sound card in output buffer
|
// copy data from sound card in output buffer
|
||||||
for ( i = 0; i < iBufferSize; i++ )
|
for ( i = 0; i < iBufferSize; i++ )
|
||||||
{
|
{
|
||||||
psData[i] = psSoundcardBuffer[iWhichBufferIn][i];
|
psData[i] = psSoundcardBuffer[0][i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the buffer so that it can be filled with new samples
|
// move all other data in buffer
|
||||||
AddInBuffer();
|
for ( j = 0; j < iCurBlockToWrite - 1; j++ )
|
||||||
|
{
|
||||||
|
for ( i = 0; i < iBufferSize; i++ )
|
||||||
|
{
|
||||||
|
psSoundcardBuffer[j][i] = psSoundcardBuffer[j + 1][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust "current block to write" pointer
|
||||||
|
iCurBlockToWrite--;
|
||||||
|
}
|
||||||
|
ASIOMutex.unlock();
|
||||||
|
|
||||||
// in case more than one buffer was ready, reset event
|
// in case more than one buffer was ready, reset event
|
||||||
ResetEvent ( m_WaveInEvent );
|
ResetEvent ( m_ASIOEvent );
|
||||||
*/
|
|
||||||
|
|
||||||
return bError;
|
return bError;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSound::AddInBuffer()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
// unprepare old wave-header
|
|
||||||
waveInUnprepareHeader (
|
|
||||||
m_WaveIn, &m_WaveInHeader[iWhichBufferIn], sizeof ( WAVEHDR ) );
|
|
||||||
|
|
||||||
// prepare buffers for sending to sound interface
|
|
||||||
PrepareInBuffer ( iWhichBufferIn );
|
|
||||||
|
|
||||||
// send buffer to driver for filling with new data
|
|
||||||
waveInAddBuffer ( m_WaveIn, &m_WaveInHeader[iWhichBufferIn], sizeof ( WAVEHDR ) );
|
|
||||||
*/
|
|
||||||
|
|
||||||
// toggle buffers
|
|
||||||
iWhichBufferIn++;
|
|
||||||
if ( iWhichBufferIn == iCurNumSndBufIn )
|
|
||||||
{
|
|
||||||
iWhichBufferIn = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::PrepareInBuffer ( int iBufNum )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
// set struct entries
|
|
||||||
m_WaveInHeader[iBufNum].lpData = (LPSTR) &psSoundcardBuffer[iBufNum][0];
|
|
||||||
m_WaveInHeader[iBufNum].dwBufferLength = iBufferSizeIn * BYTES_PER_SAMPLE;
|
|
||||||
m_WaveInHeader[iBufNum].dwFlags = 0;
|
|
||||||
|
|
||||||
// prepare wave-header
|
|
||||||
waveInPrepareHeader ( m_WaveIn, &m_WaveInHeader[iBufNum], sizeof ( WAVEHDR ) );
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::SetInNumBuf ( int iNewNum )
|
void CSound::SetInNumBuf ( int iNewNum )
|
||||||
{
|
{
|
||||||
// check new parameter
|
// check new parameter
|
||||||
|
@ -264,50 +240,6 @@ return true;
|
||||||
return bError;
|
return bError;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSound::GetDoneBuffer ( int& iCntPrepBuf, int& iIndexDoneBuf )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
// get number of "done"-buffers and position of one of them
|
|
||||||
iCntPrepBuf = 0;
|
|
||||||
for ( int i = 0; i < iCurNumSndBufOut; i++ )
|
|
||||||
{
|
|
||||||
if ( m_WaveOutHeader[i].dwFlags & WHDR_DONE )
|
|
||||||
{
|
|
||||||
iCntPrepBuf++;
|
|
||||||
iIndexDoneBuf = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::AddOutBuffer ( int iBufNum )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
// Unprepare old wave-header
|
|
||||||
waveOutUnprepareHeader (
|
|
||||||
m_WaveOut, &m_WaveOutHeader[iBufNum], sizeof ( WAVEHDR ) );
|
|
||||||
|
|
||||||
// Prepare buffers for sending to sound interface
|
|
||||||
PrepareOutBuffer ( iBufNum );
|
|
||||||
|
|
||||||
// Send buffer to driver for filling with new data
|
|
||||||
waveOutWrite ( m_WaveOut, &m_WaveOutHeader[iBufNum], sizeof ( WAVEHDR ) );
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::PrepareOutBuffer ( int iBufNum )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
// Set Header data
|
|
||||||
m_WaveOutHeader[iBufNum].lpData = (LPSTR) &psPlaybackBuffer[iBufNum][0];
|
|
||||||
m_WaveOutHeader[iBufNum].dwBufferLength = iBufferSizeOut * BYTES_PER_SAMPLE;
|
|
||||||
m_WaveOutHeader[iBufNum].dwFlags = 0;
|
|
||||||
|
|
||||||
// Prepare wave-header
|
|
||||||
waveOutPrepareHeader ( m_WaveOut, &m_WaveOutHeader[iBufNum], sizeof ( WAVEHDR ) );
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::SetOutNumBuf ( int iNewNum )
|
void CSound::SetOutNumBuf ( int iNewNum )
|
||||||
{
|
{
|
||||||
// check new parameter
|
// check new parameter
|
||||||
|
@ -335,6 +267,8 @@ void CSound::InitRecordingAndPlayback ( int iNewBufferSize )
|
||||||
// first, stop audio
|
// first, stop audio
|
||||||
ASIOStop();
|
ASIOStop();
|
||||||
|
|
||||||
|
ASIOMutex.lock(); // get mutex lock
|
||||||
|
{
|
||||||
// calculate "nearest" buffer size and set internal parameter accordingly
|
// calculate "nearest" buffer size and set internal parameter accordingly
|
||||||
// first check minimum and maximum values
|
// first check minimum and maximum values
|
||||||
if ( iNewBufferSize < HWBufferInfo.lMinSize )
|
if ( iNewBufferSize < HWBufferInfo.lMinSize )
|
||||||
|
@ -391,12 +325,8 @@ void CSound::InitRecordingAndPlayback ( int iNewBufferSize )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create and activate buffers
|
// create and activate ASIO buffers
|
||||||
|
ASIOCreateBuffers ( bufferInfos, 2 * NUM_IN_OUT_CHANNELS,
|
||||||
|
|
||||||
int test2;
|
|
||||||
int test = ASE_OK;
|
|
||||||
int test1 = ASIOCreateBuffers ( bufferInfos, 2 * NUM_IN_OUT_CHANNELS,
|
|
||||||
iBufferSize * BYTES_PER_SAMPLE, &asioCallbacks );
|
iBufferSize * BYTES_PER_SAMPLE, &asioCallbacks );
|
||||||
|
|
||||||
// now set all the buffer details
|
// now set all the buffer details
|
||||||
|
@ -409,57 +339,26 @@ int test = ASE_OK;
|
||||||
// only 16 bit is supported
|
// only 16 bit is supported
|
||||||
if ( channelInfos[i].type != ASIOSTInt16LSB )
|
if ( channelInfos[i].type != ASIOSTInt16LSB )
|
||||||
{
|
{
|
||||||
// TODO fire error
|
throw CGenErr ( "Required audio sample format not available (16 bit LSB)." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// our buffer management -----------------------------------------------
|
||||||
|
// initialize write block pointer
|
||||||
/*
|
iCurBlockToWrite = 0;
|
||||||
// reset interface so that all buffers are returned from the interface
|
|
||||||
waveInReset ( m_WaveIn );
|
|
||||||
waveInStop ( m_WaveIn );
|
|
||||||
*/
|
|
||||||
|
|
||||||
// reset current buffer ID (it is important to do this BEFORE calling
|
|
||||||
// "AddInBuffer()"
|
|
||||||
iWhichBufferIn = 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++ )
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
// Unprepare old wave-header in case that we "re-initialized" this
|
|
||||||
// module. Calling "waveInUnprepareHeader()" with an unprepared
|
|
||||||
// buffer (when the module is initialized for the first time) has
|
|
||||||
// simply no effect
|
|
||||||
waveInUnprepareHeader ( m_WaveIn, &m_WaveInHeader[i], sizeof ( WAVEHDR ) );
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( psSoundcardBuffer[i] != NULL )
|
if ( psSoundcardBuffer[i] != NULL )
|
||||||
{
|
{
|
||||||
delete[] psSoundcardBuffer[i];
|
delete[] psSoundcardBuffer[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
psSoundcardBuffer[i] = new short[iBufferSize];
|
psSoundcardBuffer[i] = new short[iBufferSize];
|
||||||
|
|
||||||
|
|
||||||
/* Send all buffers to driver for filling the queue ----------------- */
|
|
||||||
// prepare buffers before sending them to the sound interface
|
|
||||||
PrepareInBuffer ( i );
|
|
||||||
|
|
||||||
AddInBuffer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// notify that sound capturing can start now
|
|
||||||
waveInStart ( m_WaveIn );
|
|
||||||
*/
|
|
||||||
|
|
||||||
// This reset event is very important for initialization, otherwise we will
|
|
||||||
// get errors!
|
|
||||||
ResetEvent ( m_WaveInEvent );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -467,15 +366,9 @@ int test = ASE_OK;
|
||||||
// reset interface
|
// reset interface
|
||||||
waveOutReset ( m_WaveOut );
|
waveOutReset ( m_WaveOut );
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
for ( j = 0; j < iCurNumSndBufOut; j++ )
|
for ( j = 0; j < iCurNumSndBufOut; j++ )
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
// Unprepare old wave-header (in case header was not prepared before,
|
|
||||||
// simply nothing happens with this function call
|
|
||||||
waveOutUnprepareHeader ( m_WaveOut, &m_WaveOutHeader[j], sizeof ( WAVEHDR ) );
|
|
||||||
*/
|
|
||||||
|
|
||||||
// create memory for playback buffer
|
// create memory for playback buffer
|
||||||
if ( psPlaybackBuffer[j] != NULL )
|
if ( psPlaybackBuffer[j] != NULL )
|
||||||
{
|
{
|
||||||
|
@ -496,7 +389,12 @@ int test = ASE_OK;
|
||||||
// initially, send all buffers to the interface
|
// initially, send all buffers to the interface
|
||||||
AddOutBuffer ( j );
|
AddOutBuffer ( j );
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// reset event
|
||||||
|
ResetEvent ( m_ASIOEvent );
|
||||||
|
}
|
||||||
|
ASIOMutex.unlock();
|
||||||
|
|
||||||
// initialization is done, (re)start audio
|
// initialization is done, (re)start audio
|
||||||
ASIOStart();
|
ASIOStart();
|
||||||
|
@ -505,9 +403,9 @@ int test = ASE_OK;
|
||||||
void CSound::Close()
|
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_WaveInEvent != NULL )
|
if ( m_ASIOEvent != NULL )
|
||||||
{
|
{
|
||||||
SetEvent(m_WaveInEvent);
|
SetEvent(m_ASIOEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for the thread to terminate
|
// wait for the thread to terminate
|
||||||
|
@ -527,8 +425,7 @@ CSound::CSound()
|
||||||
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
|
||||||
m_WaveInEvent = NULL;
|
m_ASIOEvent = NULL;
|
||||||
m_WaveOutEvent = NULL;
|
|
||||||
|
|
||||||
// get available ASIO driver names in system
|
// get available ASIO driver names in system
|
||||||
char* cDriverNames[MAX_NUMBER_SOUND_CARDS];
|
char* cDriverNames[MAX_NUMBER_SOUND_CARDS];
|
||||||
|
@ -641,10 +538,9 @@ pstrDevices[0] = driverInfo.name;
|
||||||
psPlaybackBuffer[i] = NULL;
|
psPlaybackBuffer[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we use an event controlled wave-in (wave-out) structure
|
// we use an event controlled structure
|
||||||
// create events
|
// create event
|
||||||
m_WaveInEvent = CreateEvent ( NULL, FALSE, FALSE, NULL );
|
m_ASIOEvent = CreateEvent ( NULL, FALSE, FALSE, NULL );
|
||||||
m_WaveOutEvent = CreateEvent ( NULL, FALSE, FALSE, NULL );
|
|
||||||
|
|
||||||
// set flag to open devices
|
// set flag to open devices
|
||||||
bChangParamIn = true;
|
bChangParamIn = true;
|
||||||
|
@ -678,18 +574,11 @@ CSound::~CSound()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// close the handle for the event
|
||||||
// close the handle for the events
|
if ( m_ASIOEvent != NULL )
|
||||||
if ( m_WaveInEvent != NULL )
|
|
||||||
{
|
{
|
||||||
CloseHandle ( m_WaveInEvent );
|
CloseHandle ( m_ASIOEvent );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_WaveOutEvent != NULL )
|
|
||||||
{
|
|
||||||
CloseHandle ( m_WaveOutEvent );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ASIO callbacks -------------------------------------------------------------
|
// ASIO callbacks -------------------------------------------------------------
|
||||||
|
@ -701,11 +590,8 @@ ASIOTime* CSound::bufferSwitchTimeInfo ( ASIOTime *timeInfo, long index, ASIOBoo
|
||||||
|
|
||||||
void CSound::bufferSwitch ( long index, ASIOBool processNow )
|
void CSound::bufferSwitch ( long index, ASIOBool processNow )
|
||||||
{
|
{
|
||||||
static long processedSamples = 0;
|
ASIOMutex.lock(); // get mutex lock
|
||||||
|
{
|
||||||
// buffer size in samples
|
|
||||||
long buffSize = iBufferSize * BYTES_PER_SAMPLE;
|
|
||||||
|
|
||||||
// perform the processing for input and output
|
// perform the processing for input and output
|
||||||
for ( int i = 0; i < 2 * NUM_IN_OUT_CHANNELS; i++ )
|
for ( int i = 0; i < 2 * NUM_IN_OUT_CHANNELS; i++ )
|
||||||
{
|
{
|
||||||
|
@ -718,33 +604,23 @@ void CSound::bufferSwitch ( long index, ASIOBool processNow )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// CAPTURE ---------------------------------------------------------
|
// CAPTURE ---------------------------------------------------------
|
||||||
/*
|
// first check if buffer is available
|
||||||
// TEST
|
if ( iCurBlockToWrite < iCurNumSndBufIn )
|
||||||
static FILE* pFile = fopen ( "test.dat", "w" );
|
|
||||||
for ( int iIdx = 0; iIdx < buffSize * 2; iIdx++ )
|
|
||||||
{
|
{
|
||||||
fprintf ( pFile, "%d\n", ((short*) bufferInfos[i].buffers[index])[iIdx] );
|
// copy new captured block in thread transfer buffer
|
||||||
}
|
for ( int iCurSample = 0; iCurSample < iBufferSize; iCurSample++ )
|
||||||
fflush ( pFile );
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TEST
|
|
||||||
channelInfos[i];
|
|
||||||
|
|
||||||
short* test;
|
|
||||||
test = (short*) bufferInfos[i].buffers[index];
|
|
||||||
/*
|
|
||||||
// TEST
|
|
||||||
static FILE* pFile = fopen ( "test.dat", "w" );
|
|
||||||
for ( int iIdx = 0; iIdx < buffSize; iIdx++ )
|
|
||||||
{
|
{
|
||||||
fprintf ( pFile, "%d\n", test[iIdx] );
|
psSoundcardBuffer[iCurBlockToWrite][iCurSample] =
|
||||||
|
((short*) bufferInfos[i].buffers[index])[iCurSample];
|
||||||
}
|
}
|
||||||
fflush ( pFile );
|
|
||||||
*/
|
|
||||||
|
|
||||||
int test2 = 0;
|
iCurBlockToWrite++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
// buffer overrun, inform user somehow...?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -754,6 +630,11 @@ int test2 = 0;
|
||||||
{
|
{
|
||||||
ASIOOutputReady();
|
ASIOOutputReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set event
|
||||||
|
SetEvent ( m_ASIOEvent );
|
||||||
|
}
|
||||||
|
ASIOMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
long CSound::asioMessages ( long selector, long value, void* message, double* opt )
|
long CSound::asioMessages ( long selector, long value, void* message, double* opt )
|
||||||
|
|
|
@ -71,8 +71,8 @@ public:
|
||||||
CSound();
|
CSound();
|
||||||
virtual ~CSound();
|
virtual ~CSound();
|
||||||
|
|
||||||
void InitRecording ( int iNewBufferSize, bool bNewBlocking = true ) { InitRecordingAndPlayback ( iNewBufferSize ); }
|
void InitRecording ( int iNewBufferSize, bool bNewBlocking = true ) { bBlockingRec = bNewBlocking; InitRecordingAndPlayback ( iNewBufferSize ); }
|
||||||
void InitPlayback ( int iNewBufferSize, bool bNewBlocking = false ) { InitRecordingAndPlayback ( iNewBufferSize ); }
|
void InitPlayback ( int iNewBufferSize, bool bNewBlocking = false ) { bBlockingPlay = bNewBlocking; InitRecordingAndPlayback ( iNewBufferSize ); }
|
||||||
bool Read ( CVector<short>& psData );
|
bool Read ( CVector<short>& psData );
|
||||||
bool Write ( CVector<short>& psData );
|
bool Write ( CVector<short>& psData );
|
||||||
|
|
||||||
|
@ -83,19 +83,14 @@ public:
|
||||||
void SetInDev ( int iNewDev ) {} // not supported
|
void SetInDev ( int iNewDev ) {} // not supported
|
||||||
int GetInDev() { return 0; } // not supported
|
int GetInDev() { return 0; } // not supported
|
||||||
void SetOutNumBuf ( int iNewNum );
|
void SetOutNumBuf ( int iNewNum );
|
||||||
int GetOutNumBuf() { return iCurNumSndBufOut; }
|
int GetOutNumBuf();
|
||||||
void SetInNumBuf ( int iNewNum );
|
void SetInNumBuf ( int iNewNum );
|
||||||
int GetInNumBuf() { return iCurNumSndBufIn; }
|
int GetInNumBuf();
|
||||||
|
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void InitRecordingAndPlayback ( int iNewBufferSize );
|
void InitRecordingAndPlayback ( int iNewBufferSize );
|
||||||
void PrepareInBuffer ( int iBufNum );
|
|
||||||
void PrepareOutBuffer ( int iBufNum );
|
|
||||||
void AddInBuffer();
|
|
||||||
void AddOutBuffer ( int iBufNum );
|
|
||||||
void GetDoneBuffer ( int& iCntPrepBuf, int& iIndexDoneBuf );
|
|
||||||
|
|
||||||
// audio hardware buffer info
|
// audio hardware buffer info
|
||||||
struct sHWBufferInfo
|
struct sHWBufferInfo
|
||||||
|
@ -116,17 +111,9 @@ protected:
|
||||||
std::string pstrDevices[MAX_NUMBER_SOUND_CARDS];
|
std::string pstrDevices[MAX_NUMBER_SOUND_CARDS];
|
||||||
bool bChangParamIn;
|
bool bChangParamIn;
|
||||||
bool bChangParamOut;
|
bool bChangParamOut;
|
||||||
int iCurNumSndBufIn;
|
|
||||||
int iCurNumSndBufOut;
|
|
||||||
|
|
||||||
// wave in
|
bool bBlockingRec;
|
||||||
HANDLE m_WaveInEvent;
|
bool bBlockingPlay;
|
||||||
int iWhichBufferIn;
|
|
||||||
short* psSoundcardBuffer[MAX_SND_BUF_IN];
|
|
||||||
|
|
||||||
// wave out
|
|
||||||
HANDLE m_WaveOutEvent;
|
|
||||||
short* psPlaybackBuffer[MAX_SND_BUF_OUT];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // USE_ASIO_SND_INTERFACE
|
#else // USE_ASIO_SND_INTERFACE
|
||||||
|
|
Loading…
Reference in a new issue