some work on ASIO

This commit is contained in:
Volker Fischer 2008-03-16 13:10:46 +00:00
parent 7cd1c095f9
commit c1f366cdf5
2 changed files with 58 additions and 84 deletions

View file

@ -549,9 +549,9 @@ pstrDevices[0] = driverInfo.name;
bASIOPostOutput = ( ASIOOutputReady() == ASE_OK ); bASIOPostOutput = ( ASIOOutputReady() == ASE_OK );
// set up the asioCallback structure and create the ASIO data buffer // set up the asioCallback structure and create the ASIO data buffer
asioCallbacks.bufferSwitch = &bufferSwitch; asioCallbacks.bufferSwitch = &bufferSwitch;
asioCallbacks.sampleRateDidChange = &sampleRateChanged; asioCallbacks.sampleRateDidChange = &sampleRateChanged;
asioCallbacks.asioMessage = &asioMessages; asioCallbacks.asioMessage = &asioMessages;
asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo; asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo;
// prepare input channels // prepare input channels
@ -637,70 +637,43 @@ CSound::~CSound()
// ASIO callbacks ------------------------------------------------------------- // ASIO callbacks -------------------------------------------------------------
ASIOTime* CSound::bufferSwitchTimeInfo ( ASIOTime *timeInfo, long index, ASIOBool processNow ) ASIOTime* CSound::bufferSwitchTimeInfo ( ASIOTime *timeInfo, long index, ASIOBool processNow )
{ {
bufferSwitch ( index, processNow );
return 0L;
}
void CSound::bufferSwitch( long index, ASIOBool processNow )
{
static long processedSamples = 0;
/* /*
static long processedSamples = 0;
// store the timeInfo for later use
asioDriverInfo.tInfo = *timeInfo;
// get the time stamp of the buffer, not necessary if no
// synchronization to other media is required
if (timeInfo->timeInfo.flags & kSystemTimeValid)
asioDriverInfo.nanoSeconds = ASIO64toDouble(timeInfo->timeInfo.systemTime);
else
asioDriverInfo.nanoSeconds = 0;
if (timeInfo->timeInfo.flags & kSamplePositionValid)
asioDriverInfo.samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition);
else
asioDriverInfo.samples = 0;
if (timeInfo->timeCode.flags & kTcValid)
asioDriverInfo.tcSamples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples);
else
asioDriverInfo.tcSamples = 0;
// get the system reference time
asioDriverInfo.sysRefTime = get_sys_reference_time();
#if WINDOWS && _DEBUG
// a few debug messages for the Windows device driver developer
// tells you the time when driver got its interrupt and the delay until the app receives
// the event notification.
static double last_samples = 0;
char tmp[128];
sprintf (tmp, "diff: %d / %d ms / %d ms / %d samples \n", asioDriverInfo.sysRefTime - (long)(asioDriverInfo.nanoSeconds / 1000000.0), asioDriverInfo.sysRefTime, (long)(asioDriverInfo.nanoSeconds / 1000000.0), (long)(asioDriverInfo.samples - last_samples));
OutputDebugString (tmp);
last_samples = asioDriverInfo.samples;
#endif
// buffer size in samples // buffer size in samples
long buffSize = asioDriverInfo.preferredSize; // long buffSize = asioDriverInfo.preferredSize;
// perform the processing // perform the processing
for (int i = 0; i < asioDriverInfo.inputBuffers + asioDriverInfo.outputBuffers; i++) for ( int i = 0; i < asioDriverInfo.inputBuffers + asioDriverInfo.outputBuffers; i++ )
{ {
if (asioDriverInfo.bufferInfos[i].isInput == false) if ( asioDriverInfo.bufferInfos[i].isInput == false )
{ {
// OK do processing for the outputs only // OK do processing for the outputs only
switch (asioDriverInfo.channelInfos[i].type) switch ( asioDriverInfo.channelInfos[i].type )
{ {
case ASIOSTInt16LSB: case ASIOSTInt16LSB:
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 2); memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 2 );
break; break;
case ASIOSTInt24LSB: // used for 20 bits as well case ASIOSTInt24LSB: // used for 20 bits as well
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 3); memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 3 );
break; break;
case ASIOSTInt32LSB: case ASIOSTInt32LSB:
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4); memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4 );
break; break;
case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4); memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4 );
break; break;
case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 8); memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 8 );
break; break;
// these are used for 32 bit data buffer, with different alignment of the data inside // these are used for 32 bit data buffer, with different alignment of the data inside
@ -709,23 +682,23 @@ ASIOTime* CSound::bufferSwitchTimeInfo ( ASIOTime *timeInfo, long index, ASIOBoo
case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment
case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment
case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4); memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4 );
break; break;
case ASIOSTInt16MSB: case ASIOSTInt16MSB:
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 2); memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 2 );
break; break;
case ASIOSTInt24MSB: // used for 20 bits as well case ASIOSTInt24MSB: // used for 20 bits as well
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 3); memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 3 );
break; break;
case ASIOSTInt32MSB: case ASIOSTInt32MSB:
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4); memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4 );
break; break;
case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on Intel x86 architecture case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on Intel x86 architecture
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4); memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4 );
break; break;
case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 8); memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 8 );
break; break;
// these are used for 32 bit data buffer, with different alignment of the data inside // these are used for 32 bit data buffer, with different alignment of the data inside
@ -734,28 +707,29 @@ ASIOTime* CSound::bufferSwitchTimeInfo ( ASIOTime *timeInfo, long index, ASIOBoo
case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment
case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment
case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4); memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4 );
break; break;
} }
} }
} }
// finally if the driver supports the ASIOOutputReady() optimization, do it here, all data are in place // finally if the driver supports the ASIOOutputReady() optimization, do it here, all data are in place
if (asioDriverInfo.postOutput) if ( asioDriverInfo.postOutput )
{
ASIOOutputReady(); ASIOOutputReady();
}
if (processedSamples >= asioDriverInfo.sampleRate * TEST_RUN_TIME) // roughly measured if ( processedSamples >= asioDriverInfo.sampleRate * TEST_RUN_TIME ) // roughly measured
{
asioDriverInfo.stopped = true; asioDriverInfo.stopped = true;
}
else else
{
processedSamples += buffSize; processedSamples += buffSize;
}
*/ */
return 0L;
}
void CSound::bufferSwitch( long index, ASIOBool processNow )
{
} }

View file

@ -35,8 +35,8 @@
/* Definitions ****************************************************************/ /* Definitions ****************************************************************/
// switch here between ASIO (Steinberg) or native Windows(TM) sound interface // switch here between ASIO (Steinberg) or native Windows(TM) sound interface
#undef USE_ASIO_SND_INTERFACE //#undef USE_ASIO_SND_INTERFACE
//#define USE_ASIO_SND_INTERFACE #define USE_ASIO_SND_INTERFACE
#define NUM_IN_OUT_CHANNELS 2 /* Stereo recording (but we only #define NUM_IN_OUT_CHANNELS 2 /* Stereo recording (but we only
@ -98,35 +98,35 @@ protected:
void GetDoneBuffer ( int& iCntPrepBuf, int& iIndexDoneBuf ); void GetDoneBuffer ( int& iCntPrepBuf, int& iIndexDoneBuf );
// 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 *"
ASIOChannelInfo channelInfos[2 * NUM_IN_OUT_CHANNELS]; ASIOChannelInfo channelInfos[2 * NUM_IN_OUT_CHANNELS];
bool bASIOPostOutput; bool bASIOPostOutput;
ASIOCallbacks asioCallbacks; ASIOCallbacks asioCallbacks;
// callbacks // callbacks
static void bufferSwitch ( long index, ASIOBool processNow ); static void bufferSwitch ( long index, ASIOBool processNow );
static ASIOTime* bufferSwitchTimeInfo ( ASIOTime *timeInfo, long index, ASIOBool processNow ); static ASIOTime* bufferSwitchTimeInfo ( ASIOTime *timeInfo, long index, ASIOBool processNow );
static void sampleRateChanged ( ASIOSampleRate sRate ) {} static void sampleRateChanged ( ASIOSampleRate sRate ) {}
static long asioMessages ( long selector, long value, void* message, double* opt ); static long asioMessages ( long selector, long value, void* message, double* opt );
int iNumDevs; int iNumDevs;
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 iCurNumSndBufIn;
int iCurNumSndBufOut; int iCurNumSndBufOut;
int iBufferSize; int iBufferSize;
// wave in // wave in
HANDLE m_WaveInEvent; HANDLE m_WaveInEvent;
int iWhichBufferIn; int iWhichBufferIn;
short* psSoundcardBuffer[MAX_SND_BUF_IN]; short* psSoundcardBuffer[MAX_SND_BUF_IN];
// wave out // wave out
short* psPlaybackBuffer[MAX_SND_BUF_OUT]; short* psPlaybackBuffer[MAX_SND_BUF_OUT];
HANDLE m_WaveOutEvent; HANDLE m_WaveOutEvent;
}; };
#else // USE_ASIO_SND_INTERFACE #else // USE_ASIO_SND_INTERFACE