From c1f366cdf5d60cf61f2bdbda56ae2b7a4e44a1e1 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Sun, 16 Mar 2008 13:10:46 +0000 Subject: [PATCH] some work on ASIO --- windows/sound.cpp | 98 +++++++++++++++++------------------------------ windows/sound.h | 44 ++++++++++----------- 2 files changed, 58 insertions(+), 84 deletions(-) diff --git a/windows/sound.cpp b/windows/sound.cpp index 2ae48989..4772b3e1 100755 --- a/windows/sound.cpp +++ b/windows/sound.cpp @@ -549,9 +549,9 @@ pstrDevices[0] = driverInfo.name; bASIOPostOutput = ( ASIOOutputReady() == ASE_OK ); // set up the asioCallback structure and create the ASIO data buffer - asioCallbacks.bufferSwitch = &bufferSwitch; - asioCallbacks.sampleRateDidChange = &sampleRateChanged; - asioCallbacks.asioMessage = &asioMessages; + asioCallbacks.bufferSwitch = &bufferSwitch; + asioCallbacks.sampleRateDidChange = &sampleRateChanged; + asioCallbacks.asioMessage = &asioMessages; asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo; // prepare input channels @@ -637,70 +637,43 @@ CSound::~CSound() // ASIO callbacks ------------------------------------------------------------- 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 - long buffSize = asioDriverInfo.preferredSize; +// long buffSize = asioDriverInfo.preferredSize; // 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 - switch (asioDriverInfo.channelInfos[i].type) + switch ( asioDriverInfo.channelInfos[i].type ) { case ASIOSTInt16LSB: - memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 2); + memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 2 ); break; 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; case ASIOSTInt32LSB: - memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4); + memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4 ); break; 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; 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; // 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 ASIOSTInt32LSB20: // 32 bit data with 20 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; case ASIOSTInt16MSB: - memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 2); + memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 2 ); break; 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; case ASIOSTInt32MSB: - memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4); + memset ( asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4 ); break; 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; 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; // 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 ASIOSTInt32MSB20: // 32 bit data with 20 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; } } } // finally if the driver supports the ASIOOutputReady() optimization, do it here, all data are in place - if (asioDriverInfo.postOutput) + if ( asioDriverInfo.postOutput ) + { ASIOOutputReady(); + } - if (processedSamples >= asioDriverInfo.sampleRate * TEST_RUN_TIME) // roughly measured + if ( processedSamples >= asioDriverInfo.sampleRate * TEST_RUN_TIME ) // roughly measured + { asioDriverInfo.stopped = true; + } else + { processedSamples += buffSize; + } */ - return 0L; -} - -void CSound::bufferSwitch( long index, ASIOBool processNow ) -{ } diff --git a/windows/sound.h b/windows/sound.h index c054c581..6e13f744 100755 --- a/windows/sound.h +++ b/windows/sound.h @@ -35,8 +35,8 @@ /* Definitions ****************************************************************/ // switch here between ASIO (Steinberg) or native Windows(TM) sound interface -#undef USE_ASIO_SND_INTERFACE -//#define USE_ASIO_SND_INTERFACE +//#undef USE_ASIO_SND_INTERFACE +#define USE_ASIO_SND_INTERFACE #define NUM_IN_OUT_CHANNELS 2 /* Stereo recording (but we only @@ -98,35 +98,35 @@ protected: void GetDoneBuffer ( int& iCntPrepBuf, int& iIndexDoneBuf ); // ASIO stuff - ASIODriverInfo driverInfo; - ASIOBufferInfo bufferInfos[2 * NUM_IN_OUT_CHANNELS]; // for input and output buffers -> "2 *" - ASIOChannelInfo channelInfos[2 * NUM_IN_OUT_CHANNELS]; - bool bASIOPostOutput; - ASIOCallbacks asioCallbacks; + ASIODriverInfo driverInfo; + ASIOBufferInfo bufferInfos[2 * NUM_IN_OUT_CHANNELS]; // for input and output buffers -> "2 *" + ASIOChannelInfo channelInfos[2 * NUM_IN_OUT_CHANNELS]; + bool bASIOPostOutput; + ASIOCallbacks asioCallbacks; // 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 void sampleRateChanged ( ASIOSampleRate sRate ) {} - static long asioMessages ( long selector, long value, void* message, double* opt ); + static void sampleRateChanged ( ASIOSampleRate sRate ) {} + static long asioMessages ( long selector, long value, void* message, double* opt ); - int iNumDevs; - std::string pstrDevices[MAX_NUMBER_SOUND_CARDS]; - bool bChangParamIn; - bool bChangParamOut; - int iCurNumSndBufIn; - int iCurNumSndBufOut; + int iNumDevs; + std::string pstrDevices[MAX_NUMBER_SOUND_CARDS]; + bool bChangParamIn; + bool bChangParamOut; + int iCurNumSndBufIn; + int iCurNumSndBufOut; - int iBufferSize; + int iBufferSize; // wave in - HANDLE m_WaveInEvent; - int iWhichBufferIn; - short* psSoundcardBuffer[MAX_SND_BUF_IN]; + HANDLE m_WaveInEvent; + int iWhichBufferIn; + short* psSoundcardBuffer[MAX_SND_BUF_IN]; // wave out - short* psPlaybackBuffer[MAX_SND_BUF_OUT]; - HANDLE m_WaveOutEvent; + short* psPlaybackBuffer[MAX_SND_BUF_OUT]; + HANDLE m_WaveOutEvent; }; #else // USE_ASIO_SND_INTERFACE