diff --git a/tests/AsioTests/CMakeLists.txt b/tests/AsioTests/CMakeLists.txt index 84d328a0bb2090b820167e6cde40392769e1b486..99b49c8dbe57c900fe08b85d483155b3c2be3029 100644 --- a/tests/AsioTests/CMakeLists.txt +++ b/tests/AsioTests/CMakeLists.txt @@ -26,3 +26,12 @@ vista_install( NativeAsioThreadedMultiInstanceTest ) vista_create_default_info_file( NativeAsioThreadedMultiInstanceTest ) set_property( TARGET NativeAsioThreadedMultiInstanceTest PROPERTY FOLDER "ITACoreLibs/Tests/ITADataSources/Asio" ) + +add_executable( ReciprocalDAADLatencyMeasurement ReciprocalDAADLatencyMeasurement.cpp ) +target_link_libraries( ReciprocalDAADLatencyMeasurement ${VISTA_USE_PACKAGE_LIBRARIES} ) + +vista_configure_app( ReciprocalDAADLatencyMeasurement ) +vista_install( ReciprocalDAADLatencyMeasurement ) +vista_create_default_info_file( ReciprocalDAADLatencyMeasurement ) + +set_property( TARGET ReciprocalDAADLatencyMeasurement PROPERTY FOLDER "ITACoreLibs/Tests/ITADataSources/Asio" ) diff --git a/tests/AsioTests/NativeAsioThreadedMultiInstanceTest.cpp b/tests/AsioTests/NativeAsioThreadedMultiInstanceTest.cpp index 9f06baab90f203348093d7239f938b8007083d4c..79c365de6e2df80a77662d916f906c80dde5d8d5 100644 --- a/tests/AsioTests/NativeAsioThreadedMultiInstanceTest.cpp +++ b/tests/AsioTests/NativeAsioThreadedMultiInstanceTest.cpp @@ -28,22 +28,28 @@ public: inline CThreadedASIO( const int iDriverIndex ) : m_iDriverIndex( iDriverIndex ) { - assert( iDriverIndex < g_oAsioDriverList.asioGetNumDev() && iDriverIndex > 0 ); + ASIOError ae; + + assert( m_iDriverIndex < g_oAsioDriverList.asioGetNumDev() && m_iDriverIndex >= 0 ); m_sDriverName.resize( 256 ); - m_oDriver.asioGetDriverName( iDriverIndex, &m_sDriverName[ 0 ], int( m_sDriverName.size() ) ); + m_oDriver.asioGetDriverName( m_iDriverIndex, &m_sDriverName[ 0 ], int( m_sDriverName.size() ) ); m_sDriverName = std::string( m_sDriverName.c_str() ); // Strip - cout << "New threaded ASIO instance with driver name: " << m_sDriverName << endl; + + cout << "[" << m_sDriverName << "] Initializing ASIO from thread " << VistaThread::GetThreadIdentity() << endl; + + VistaTimeUtils::Sleep( 1000 ); bool bLoadSuccess = m_oDriver.loadDriver( &m_sDriverName[ 0 ] ); + assert( bLoadSuccess ); + + VistaTimeUtils::Sleep( 1000 ); ASIODriverInfo oDriverInfo; oDriverInfo.asioVersion = 2; - assert( ASIOInit( &oDriverInfo ) == ASE_OK ); + assert( ( ae = ASIOInit( &oDriverInfo ) ) == ASE_OK ); ASIOCallbacks oAsioCallback; - //long AsioMessages( long selector, long value, void*, double* ) - - oAsioCallback.asioMessage = long( CThreadedASIO::* )( long, long, void*, double* ); + oAsioCallback.asioMessage = &( CThreadedASIO::AsioMessages ); oAsioCallback.bufferSwitch = &( CThreadedASIO::AsioBufferSwitch ); oAsioCallback.bufferSwitchTimeInfo = &( CThreadedASIO::AsioBufferSwitchTimeInfo ); oAsioCallback.sampleRateDidChange = &( CThreadedASIO::AsioSampleRateChanged ); @@ -72,22 +78,15 @@ public: assert( ASE_OK == ASIOCreateBuffers( &voBufferInfos.front(), 4, preferredSize, &oAsioCallback ) ); g_oRegistry[ VistaThread::GetThreadIdentity() ] = this; - }; - inline void StartStreaming() - { assert( ASE_OK == ASIOStart() ); + cout << "[" << m_sDriverName << "] Started ASIO from thread " << VistaThread::GetThreadIdentity() << endl; + VistaTimeUtils::Sleep( 10000 ); + assert( ASE_OK == ASIOStop() ); }; - + inline void ThreadBody() { - cout << "[" << m_sDriverName << "] Tic Toc" << endl; - VistaTimeUtils::Sleep( 1000 ); - }; - - inline void StopStreaming() - { - assert( ASE_OK == ASIOStop() ); }; inline static ASIOTime* AsioBufferSwitchTimeInfo( ASIOTime *timeInfo, long index, ASIOBool processNow ) @@ -104,9 +103,10 @@ public: timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid; AsioBufferSwitchTimeInfo( &timeInfo, index, processNow ); - - long iThreadID = VistaThread::GetThreadIdentity(); - g_oRegistry[ iThreadID ]; + + long iThreadID = VistaThread::GetCallingThreadIdentity(); + cout << "Buffer switch called from thread " << iThreadID << endl; + //g_oRegistry[ iThreadID ]; }; inline static void AsioSampleRateChanged( ASIOSampleRate fs ) @@ -115,7 +115,7 @@ public: return; }; - inline long AsioMessages( long selector, long value, void*, double* ) + inline static long AsioMessages( long selector, long value, void*, double* ) { return 0; }; @@ -129,16 +129,14 @@ private: int main( int, char[] ) { - CThreadedASIO oAsio1( 2 ); - CThreadedASIO oAsio2( 2 ); - - oAsio1.StartStreaming(); - oAsio2.StartStreaming(); + cout << "Main thread is called by " << VistaThread::GetCallingThreadIdentity() << endl; + CThreadedASIO oAsio1( 1 ); + //CThreadedASIO oAsio2( 1 ); - VistaTimeUtils::Sleep( 3000 ); + oAsio1.Run(); + //oAsio2.Run(); - oAsio1.StopStreaming(); - oAsio2.StopStreaming(); + VistaTimeUtils::Sleep( 10000 ); return 0; } diff --git a/tests/AsioTests/ReciprocalDAADLatencyMeasurement.cpp b/tests/AsioTests/ReciprocalDAADLatencyMeasurement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d9dba855ee5bd301521b8dcf27aed310c6fe81fa --- /dev/null +++ b/tests/AsioTests/ReciprocalDAADLatencyMeasurement.cpp @@ -0,0 +1,207 @@ +#include <cassert> +#include <conio.h> +#include <iostream> +#include <string> +#include <vector> +#include <algorithm> + +#include <host/asiodrivers.h> +#include <common/asio.h> + +#include <VistaBase/VistaTimeUtils.h> + +using namespace std; + +ASIOTime* AsioBufferSwitchTimeInfoA( ASIOTime *timeInfo, long, ASIOBool ) +{ + return timeInfo; +}; + +void AsioBufferSwitchA( long nIndex, ASIOBool processNow ) +{ + ASIOTime timeInfo; + memset( &timeInfo, 0, sizeof( timeInfo ) ); + + if( ASIOGetSamplePosition( &timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime ) == ASE_OK ) + timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid; + + AsioBufferSwitchTimeInfoA( &timeInfo, nIndex, processNow ); +}; + +void AsioSampleRateChangedA( ASIOSampleRate fs ) +{ + cout << "Sample rate changed to " << fs << endl; + return; +}; + +long AsioMessagesA( long, long, void*, double* ) +{ + return 0; +}; + +ASIOTime* AsioBufferSwitchTimeInfoB( ASIOTime *timeInfo, long, ASIOBool ) +{ + return timeInfo; +}; + +void AsioBufferSwitchB( long nIndex, ASIOBool processNow ) +{ + ASIOTime timeInfo; + memset( &timeInfo, 0, sizeof( timeInfo ) ); + + if( ASIOGetSamplePosition( &timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime ) == ASE_OK ) + timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid; + + AsioBufferSwitchTimeInfoB( &timeInfo, nIndex, processNow ); +}; + +void AsioSampleRateChangedB( ASIOSampleRate fs ) +{ + cout << "Sample rate changed to " << fs << endl; + return; +}; + +long AsioMessagesB( long, long, void*, double* ) +{ + return 0; +}; + + +int main( int, char[] ) +{ + ASIOError ae; + AsioDriverList* pDrivers = new AsioDriverList(); + long nNumDrivers = pDrivers->asioGetNumDev(); + cout << "Number of ASIO drivers: " << nNumDrivers << endl; + delete pDrivers; + + // Driver A + + int iDriverIndexA = 1; + AsioDrivers* pDriverA = new AsioDrivers(); + + string sDriverNameA; + sDriverNameA.resize( 256 ); + pDriverA->asioGetDriverName( iDriverIndexA, &sDriverNameA[ 0 ], int( sDriverNameA.size() ) ); + sDriverNameA = std::string( sDriverNameA.c_str() ); // Strip + cout << "Driver name: " << sDriverNameA << "." << endl; + + + int iDriverIndexB = 1; + //AsioDrivers* pDriverB = new AsioDrivers(); + string sDriverNameB; + sDriverNameB.resize( 256 ); + pDriverA->asioGetDriverName( iDriverIndexB, &sDriverNameB[ 0 ], int( sDriverNameB.size() ) ); + sDriverNameB = std::string( sDriverNameB.c_str() ); // Strip + cout << "Driver name: " << sDriverNameB << "." << endl; + + bool bLoadSuccessA = pDriverA->loadDriver( &sDriverNameA[ 0 ] ); + assert( bLoadSuccessA ); + + bool bLoadSuccessB = pDriverA->loadDriver( &sDriverNameB[ 0 ] ); + assert( bLoadSuccessB ); + + ASIODriverInfo oDriverInfo; + oDriverInfo.asioVersion = 2; + if( ASIOInit( &oDriverInfo ) != ASE_OK ) + { + cout << "Could not initialize " << sDriverNameA << ", skipping." << endl; + return 255; + } + + ASIOCallbacks oAsioCallbackA; + oAsioCallbackA.asioMessage = &AsioMessagesA; + oAsioCallbackA.bufferSwitch = &AsioBufferSwitchA; + oAsioCallbackA.bufferSwitchTimeInfo = &AsioBufferSwitchTimeInfoA; + oAsioCallbackA.sampleRateDidChange = &AsioSampleRateChangedA; + + vector< ASIOBufferInfo > voBufferInfosA( 4 ); + voBufferInfosA[ 0 ].buffers; + voBufferInfosA[ 0 ].channelNum = 0; + voBufferInfosA[ 0 ].isInput = ASIOTrue; + voBufferInfosA[ 1 ].buffers; + voBufferInfosA[ 1 ].channelNum = 1; + voBufferInfosA[ 1 ].isInput = ASIOTrue; + voBufferInfosA[ 2 ].buffers; + voBufferInfosA[ 2 ].channelNum = 0; + voBufferInfosA[ 2 ].isInput = ASIOFalse; + voBufferInfosA[ 3 ].buffers; + voBufferInfosA[ 3 ].channelNum = 1; + voBufferInfosA[ 3 ].isInput = ASIOFalse; + + ASIOSampleRate fs; + if( ASIOGetSampleRate( &fs ) == ASE_NotPresent ) + return 255; + + long minSize, maxSize, preferredSize, granularity; + ae = ASIOGetBufferSize( &minSize, &maxSize, &preferredSize, &granularity ); + preferredSize = ( preferredSize == 0 ? min( 1024, maxSize ) : preferredSize ); + + ae = ASIOCreateBuffers( &voBufferInfosA.front(), 4, preferredSize, &oAsioCallbackA ); + assert( ae == ASE_OK ); + + ae = ASIOStart(); + assert( ae == ASE_OK ); + + VistaTimeUtils::Sleep( int( 2e3 ) ); + + ae = ASIOStop(); + assert( ae == ASE_OK ); + + + // Driver B + + ASIODriverInfo oDriverInfoB; + oDriverInfoB.asioVersion = 2; + if( ASIOInit( &oDriverInfoB ) != ASE_OK ) + { + cout << "Could not initialize " << sDriverNameB << ", skipping." << endl; + return 255; + } + + ASIOCallbacks oAsioCallbackB; + oAsioCallbackB.asioMessage = &AsioMessagesB; + oAsioCallbackB.bufferSwitch = &AsioBufferSwitchB; + oAsioCallbackB.bufferSwitchTimeInfo = &AsioBufferSwitchTimeInfoB; + oAsioCallbackB.sampleRateDidChange = &AsioSampleRateChangedB; + + vector< ASIOBufferInfo > voBufferInfosB( 4 ); + voBufferInfosB[ 0 ].buffers; + voBufferInfosB[ 0 ].channelNum = 0; + voBufferInfosB[ 0 ].isInput = ASIOTrue; + voBufferInfosB[ 1 ].buffers; + voBufferInfosB[ 1 ].channelNum = 1; + voBufferInfosB[ 1 ].isInput = ASIOTrue; + voBufferInfosB[ 2 ].buffers; + voBufferInfosB[ 2 ].channelNum = 0; + voBufferInfosB[ 2 ].isInput = ASIOFalse; + voBufferInfosB[ 3 ].buffers; + voBufferInfosB[ 3 ].channelNum = 1; + voBufferInfosB[ 3 ].isInput = ASIOFalse; + + if( ASIOGetSampleRate( &fs ) == ASE_NotPresent ) + return 255; + + ae = ASIOGetBufferSize( &minSize, &maxSize, &preferredSize, &granularity ); + preferredSize = ( preferredSize == 0 ? min( 1024, maxSize ) : preferredSize ); + + + ae = ASIOCreateBuffers( &voBufferInfosB.front(), 4, preferredSize, &oAsioCallbackB ); + assert( ae == ASE_OK ); + + ae = ASIOStart(); + assert( ae == ASE_OK ); + + VistaTimeUtils::Sleep( int( 2e3 ) ); + + ae = ASIOStop(); + assert( ae == ASE_OK ); + + pDriverA->removeCurrentDriver(); + delete pDriverA; + +// pDriverB->removeCurrentDriver(); + //delete pDriverB; + + return 0; +}