Starting test-driven development of offline simulation feature using a virtual...

Starting test-driven development of offline simulation feature using a virtual user-triggered audio device
parent 5663a6d7
......@@ -36,9 +36,7 @@
#include <sstream>
CVAAudioSignalSourceManager::CVAAudioSignalSourceManager( CVACoreImpl* pParentCore,
const CVAAudioDriverConfig& oAudioDriverConfig,
ITADatasource* pDeviceInputSource )
CVAAudioSignalSourceManager::CVAAudioSignalSourceManager( CVACoreImpl* pParentCore, const CVAAudioDriverConfig& oAudioDriverConfig, ITADatasource* pDeviceInputSource )
: m_pParentCore( pParentCore ),
m_dSamplerate( oAudioDriverConfig.dSampleRate ),
m_iBlocklength( oAudioDriverConfig.iBuffersize ),
......
......@@ -35,8 +35,8 @@ void CVAAudioDriverConfig::Init( const CVAStruct& oArgs )
CVAConfigInterpreter conf( oArgs );
conf.OptNonEmptyString( "Driver", sDriver );
conf.OptString( "Device", sDevice, "AUTO" );
conf.OptNumber( "Samplerate", dSampleRate, DEFAULT_SAMPLERATE );
conf.OptInteger( "Buffersize", iBuffersize, AUTO, &lits );
conf.OptNumber( "SampleRate", dSampleRate, DEFAULT_SAMPLERATE );
conf.OptInteger( "BufferSize", iBuffersize, AUTO, &lits );
conf.OptInteger( "InputChannels", iInputChannels, AUTO, &lits );
conf.OptInteger( "OutputChannels", iOutputChannels, AUTO, &lits );
......@@ -48,9 +48,8 @@ void CVAAudioDriverConfig::Init( const CVAStruct& oArgs )
VA_EXCEPT1( "Invalid buffersize specified" );
if( ( iInputChannels < 0 ) && ( iInputChannels != AUTO ) )
VA_EXCEPT1( "Invalid number of input channels specified" );
VA_EXCEPT1( "Invalid number of input channels specified (autodetect = -1 or AUTO)" );
// @todo: really?! I don't see a point why single channel output shouldn't be supported.
if( ( iOutputChannels < 2 ) && ( iOutputChannels != AUTO ) )
VA_EXCEPT1( "Invalid number of output channels specified (at least two)" );
if( ( iOutputChannels < 1 ) && ( iOutputChannels != AUTO ) )
VA_EXCEPT1( "Invalid number of output channels specified (at least one required, if not using autodetect ... -1 or AUTO)" );
}
......@@ -494,6 +494,7 @@ void CVACoreImpl::Initialize() {
SetProgress( "Setting up resource managers", "", 2 );
assert( m_oCoreConfig.oAudioDriverConfig.iInputChannels >= 0 );
m_pSignalSourceManager = new CVAAudioSignalSourceManager( this, m_oCoreConfig.oAudioDriverConfig, pInputTail );
m_pGlobalSamplePool = ITASoundSamplePool::Create( 1, m_oCoreConfig.oAudioDriverConfig.dSampleRate );
m_pGlobalSampler = ITASoundSampler::Create( 1, m_oCoreConfig.oAudioDriverConfig.dSampleRate, m_oCoreConfig.oAudioDriverConfig.iBuffersize, m_pGlobalSamplePool );
......@@ -4328,8 +4329,9 @@ void CVACoreImpl::InitializeAudioDriver()
m_pAudioDriverBackend = new CVAPortaudioBackend( &m_oCoreConfig.oAudioDriverConfig );
#endif
#ifdef VACORE_WITH_AUDIO_BACKEND_DUMMY
if( m_oCoreConfig.oAudioDriverConfig.sDriver == "Dummy" )
if( m_oCoreConfig.oAudioDriverConfig.sDriver == "Virtual" )
{
m_oCoreConfig.oAudioDriverConfig.iInputChannels = 0; // not allowed
CVADummyAudioDriverBackend* pAudioDriverBackend = new CVADummyAudioDriverBackend( &m_oCoreConfig.oAudioDriverConfig );
RegisterModule( pAudioDriverBackend );
m_pAudioDriverBackend = pAudioDriverBackend;
......@@ -4337,7 +4339,7 @@ void CVACoreImpl::InitializeAudioDriver()
#endif
if( m_pAudioDriverBackend == nullptr )
VA_ERROR( "Core", "Unkown or unsupported audio driver backend '" << m_oCoreConfig.oAudioDriverConfig.sDriver << "'" );
VA_EXCEPT2( INVALID_PARAMETER, "Unkown, uninitializable or unsupported audio driver backend '" + m_oCoreConfig.oAudioDriverConfig.sDriver + "'" );
try
{
......
......@@ -61,4 +61,14 @@ vista_configure_app( NetworkStreamAudioSignalSourceTest )
vista_install( NetworkStreamAudioSignalSourceTest )
vista_create_default_info_file( NetworkStreamAudioSignalSourceTest )
set_property( TARGET NetworkStreamAudioSignalSourceTest PROPERTY FOLDER "VA/Tests/VABase" )
set_property( TARGET NetworkStreamAudioSignalSourceTest PROPERTY FOLDER "VA/Tests/VACore" )
add_executable( OfflineSimulationVirtualDeviceTest OfflineSimulationVirtualDeviceTest.cpp )
target_link_libraries( OfflineSimulationVirtualDeviceTest ${VISTA_USE_PACKAGE_LIBRARIES} ${VISTAINTERPROCCOMM_ADDITIONAL_DEPENDENCIES} )
vista_configure_app( OfflineSimulationVirtualDeviceTest )
#vista_install( OfflineSimulationVirtualDeviceTest )
#vista_create_default_info_file( OfflineSimulationVirtualDeviceTest )
set_property( TARGET OfflineSimulationVirtualDeviceTest PROPERTY FOLDER "VA/Tests/VACore" )
......@@ -132,13 +132,13 @@ CVAStruct GetCoreConfig()
CVAStruct oRenderer1;
oRenderer1[ "class" ] = "BinauralFreeField";
oRenderer1[ "outputs" ] = "MyTalkthroughHeadphones";
oRenderer1[ "Reproductions" ] = "MyTalkthroughHeadphones";
oConfig[ "Renderer:BFF_CoreTest" ] = oRenderer1;
CVAStruct oRenderer2;
oRenderer2[ "class" ] = "PrototypeGenericPath";
oRenderer2[ "numchannels" ] = 2;
oRenderer2[ "outputs" ] = "MyTalkthroughHeadphones";
oRenderer2[ "Reproductions" ] = "MyTalkthroughHeadphones";
oConfig[ "Renderer:PTGP_CoreTest" ] = oRenderer2;
return oConfig;
......
#include <VA.h>
#include <VACore.h>
#include <iostream>
#include <VistaBase/VistaTimeUtils.h>
using namespace std;
IVAInterface* pCore = NULL;
//! Trigger virtual audio device block increment in audio processing thread
/**
* A special prototype call to control the virtual audio device and increment a block
* of the audio processing by user. Produces one more block of audio samples and increments
* the pCore time by user-defined time steps.
*/
void TriggerVirtualAudioDeviceBlockIncrement();
//! Manually update the core clock
/**
* ... used for scene modification time stamps. This lets the user control the
* asynchronous update beaviour independent from the audio processing thread.
*/
void ManualCoreClockUpdate( const float );
void TestOfflineSimulationVirtualAudioDevice()
{
// Load directivity
int iHRTFID = pCore->CreateDirectivityFromFile( "ITA_Artificial_Head_5x5_44kHz_128.v17.ir.daff" );
// Set up scene
int iListenerID = pCore->CreateSoundReceiver( "Listener with HRTF" );
pCore->SetSoundReceiverPosition( iListenerID, VAVec3( 0, 1.7, 0 ) );
pCore->SetActiveSoundReceiver( iListenerID );
pCore->SetSoundReceiverDirectivity( iListenerID, iHRTFID );
int iSourceID = pCore->CreateSoundSource( "Source" );
// Load input data & start playback
string sFileSignalID = pCore->CreateSignalSourceBufferFromFile( "WelcomeToVA.wav" );
pCore->SetSignalSourceBufferPlaybackAction( sFileSignalID, IVAInterface::VA_PLAYBACK_ACTION_PLAY );
pCore->SetSignalSourceBufferLooping( sFileSignalID, true );
pCore->SetSoundSourceSignalSource( iSourceID, sFileSignalID );
// --- Simulation loop using time steps and locked scene/audio updates --- //
const int iNumSteps = 300;
const float fTimeStepIncrement = 0.02f; // 20 ms between updates (do not confuse with virtual audio device updates)
float fManualCoreTime = 0.0f;
// Motion
float fXPos = -100.0f;
const float fXPosIncrement = 1.0f;
for( int n = 0; n < iNumSteps; n++ )
{
pCore->SetSoundSourcePosition( iSourceID, VAVec3( fXPos, 1.7f, -2.0f ) );
fXPos -= fXPosIncrement;
fManualCoreTime += fTimeStepIncrement;
ManualCoreClockUpdate( fManualCoreTime );
TriggerVirtualAudioDeviceBlockIncrement();
}
}
//! Creates an example configuration for two-channel offline simulation and recording
CVAStruct CreateOfflineSimulationVirtualDeviceConfig()
{
CVAStruct oConfig, oAudioDevice;
CVAStruct oSectionDebug;
oSectionDebug[ "loglevel" ] = 5;
oConfig[ "debug" ] = oSectionDebug;
CVAStruct oSectionDriver;
oSectionDriver[ "driver" ] = "Virtual";
// Default user-triggered settings
oSectionDriver[ "Device" ] = "Trigger";
oSectionDriver[ "BufferSize" ] = 128;
oSectionDriver[ "SampleRate" ] = 44100.0f;
oSectionDriver[ "OutputChannels" ] = 2;
// Timeout settings
//oSectionDriver[ "Device" ] = "Timout";
//oSectionDriver[ "UpdateRate" ] = 300;
oConfig[ "audio driver" ] = oSectionDriver;
CVAStruct oDevice1;
oDevice1[ "type" ] = "HP";
oDevice1[ "channels" ] = "1,2";
oConfig[ "OutputDevice:MyHP" ] = oDevice1;
CVAStruct oOutput1;
oOutput1[ "devices" ] = "MyHP";
oConfig[ "Output:MyDesktopHP" ] = oOutput1;
CVAStruct oReproduction1;
oReproduction1[ "class" ] = "Talkthrough";
oReproduction1[ "outputs" ] = "MyDesktopHP";
oConfig[ "Reproduction:MyTalkthroughHeadphones" ] = oReproduction1;
CVAStruct oRenderer1;
oRenderer1[ "class" ] = "BinauralFreeField";
oRenderer1[ "Reproductions" ] = "MyTalkthroughHeadphones";
oRenderer1[ "RecordOutputEnabled" ] = true;
oRenderer1[ "RecordOutputFilePath" ] = "OfflineSimulationVirtualDeviceTest.wav";
oConfig[ "Renderer:BFF_OfflineSimulationTest" ] = oRenderer1;
return oConfig;
}
void TriggerVirtualAudioDeviceBlockIncrement()
{
CVAStruct oTriggerMessage;
oTriggerMessage[ "trigger" ] = true;
CVAStruct oAnswer = pCore->CallModule( "VirtualAudioDevice", oTriggerMessage );
}
void TriggerVirtualAudioDeviceBlockIncrement( const float fNewCoreClockTimeSeconds )
{
CVAStruct opCoreClockIncrement;
opCoreClockIncrement[ "clock" ] = fNewCoreClockTimeSeconds;
CVAStruct oAnswer = pCore->CallModule( "core", opCoreClockIncrement );
}
int main()
{
try
{
CVAStruct opCoreConfig = CreateOfflineSimulationVirtualDeviceConfig();
pCore = VACore::CreateCoreInstance( opCoreConfig );
pCore->Initialize();
pCore->AddSearchPath( "../data" );
TestOfflineSimulationVirtualAudioDevice();
pCore->Finalize();
}
catch( CVAException& e )
{
cerr << "Error: " << e << endl;
int iErrorCode = e.GetErrorCode();
delete pCore;
return iErrorCode;
}
delete pCore;
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment