Commit 73826094 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

Refactoring and adding support for rendering and reproduction module detectors and recordings

parent fd39a1f0
......@@ -68,11 +68,13 @@ ProjectName = MyVirtualAcousticsProject
[Debug]
# Dump the audio device input streams into file
#DumpDeviceInput = $(ProjectName)_in.wav
# Record device input and store to hard drive (will record every input channel)
OutputRecordEnabled = false
OutputRecordFilePath = $(ProjectName)_in.wav
# Dump the final output audio streams into file
#DumpFinalOutput = $(ProjectName)_out.wav
# Record device output and store to hard drive (will record every output channel)
InputRecordEnabled = false
OutputRecordFilePath = $(ProjectName)_out.wav
# Set log level: 0 = quiet; 1 = errors; 2 = warnings (default); 3 = info; 4 = verbose; 5 = trace;
LogLevel = @ITA_VACORE_DEFAULT_DEBUG_LEVEL@
......@@ -115,9 +117,13 @@ Buffersize = AUTO
[Renderer:MyBinauralFreeField]
Class = BinauralFreeField
Enabled = true
Class = BinauralFreeField
Outputs = MyTalkthroughHeadphones
OutputDetectorEnabled = true
RecordOutputEnabled = false
RecordOutputFilePath = $(ProjectName)_Renderer_MyBinauralFreeField_Output.wav
HRIRFilterLength = 256
MotionModelNumHistoryKeys = 10000
MotionModelWindowSize = 0.1
......@@ -248,6 +254,12 @@ Class = Talkthrough
Enabled = true
Name = Generic talkthrough to output group
Outputs = MyDesktopHP
InputDetectorEnabled = true
OutputDetectorEnabled = true
RecordInputEnabled = false
RecordInputFilePath = $(ProjectName)_Reproduction_MyTalkthroughHeadphones_Input.wav
RecordOutputEnabled = false
RecordOutputFilePath = $(ProjectName)_Reproduction_MyTalkthroughHeadphones_Output.wav
[Reproduction:MySubwooferMixer]
Class = LowFrequencyMixer
......
......@@ -27,7 +27,7 @@ CVAAudioDriverConfig::~CVAAudioDriverConfig()
{
}
void CVAAudioDriverConfig::init( const CVAStruct& oArgs )
void CVAAudioDriverConfig::Init( const CVAStruct& oArgs )
{
CVALiterals< int > lits;
lits.Add( "AUTO", AUTO );
......
......@@ -41,7 +41,7 @@ public:
virtual ~CVAAudioDriverConfig();
// Einstellungen aus einem Struct lesen
void init( const CVAStruct& oArgs );
void Init( const CVAStruct& oArgs );
};
#endif // IW_VACORE_AUDIODRIVERCONFIG
......@@ -1363,21 +1363,6 @@ int CVABinauralFreeFieldAudioRenderer::CallObject( const CVAStruct& oArgs, CVASt
return 1;
}
if( ( pStruct = oArgs.GetValue( "DIFFRACTION" ) ) != nullptr )
{
if( pStruct->GetDatatype() != CVAStructValue::STRING )
VA_EXCEPT2( INVALID_PARAMETER, "Configuration command must be a string" );
std::string sDiffractionCommand = toUppercase( *pStruct );
if( sDiffractionCommand == "SETPOS" )
{
VAVec3 vPos( oArgs["X"], oArgs["Y"], oArgs["Z"] );
return 0;
}
}
CVAConfigInterpreter oConfig( oArgs );
std::string sCommandOrg;
oConfig.ReqNonEmptyString( "Command", sCommandOrg );
......
......@@ -35,6 +35,9 @@ public:
CVACoreImpl* pCore; //!< Parent core
const CVAStruct* pConfig; //!< Renderer configuration
std::vector< std::string > vsOutputs; //!< Renderer outputs (e.g. Output:HP, Reproduction:CTC4)
bool bRecordOutputEnabled; //!< Renderer output recording and storing flag
std::string sRecordOutputFilePath; //!< Renderer output recording and storing file path
bool bOutputLevelMeterEnabled; //!< Renderer output level meter will be used (uses a little bit CPU resources)
};
//! Audio renderer interface
......
......@@ -24,13 +24,20 @@ class CVASceneState;
class CVAStruct;
class ITADatasource;
class CVAAudioReproductionModuleInitParams {
class CVAAudioReproductionModuleInitParams
{
public:
std::string sID; //!< ID (right-hand side of declaration CLASS:ID)
std::string sClass; //!< Module class
CVACoreImpl* pCore; //!< Core configuration
const CVAStruct* pConfig; //!< Module configuration (direct link)
std::vector<const CVAHardwareOutput*> vpOutputs; //!< Designated hardware outputs
bool bInputDetectorEnabled;
bool bOutputDetectorEnabled;
bool bRecordInputEnabled;
bool bRecordOutputEnabled;
std::string sRecordInputInputFilePath;
std::string sRecordOutputInputFilePath;
};
/**
......
......@@ -18,6 +18,7 @@
#include "Audiosignals/VAAudioSignalSourceManager.h"
#include "Utils/VADebug.h"
#include "VALog.h"
#include <ITAClock.h>
#include <ITADataSource.h>
......@@ -50,84 +51,79 @@ public:
class CVAAudiostreamTracker : public ITADatasource
{
public:
inline CVAAudiostreamTracker(ITADatasource* pSource,
ITAClock* pClock,
ITAAtomicFloat* pfClockOffset,
ITAAtomicLong* plSyncModOwner,
CVAAudioSignalSourceManager* pSignalSourceMan)
: m_pSource(pSource),
m_pClock(pClock),
m_pfClockOffset(pfClockOffset),
m_plSyncModOwner(plSyncModOwner),
m_pSignalSourceMan(pSignalSourceMan)
inline CVAAudiostreamTracker( ITADatasource* pSource, ITAClock* pClock, ITAAtomicFloat* pfClockOffset, ITAAtomicLong* plSyncModOwner, CVAAudioSignalSourceManager* pSignalSourceMan )
: m_pSource( pSource )
, m_pClock( pClock )
, m_pfClockOffset( pfClockOffset )
, m_plSyncModOwner( plSyncModOwner )
, m_pSignalSourceMan( pSignalSourceMan )
{
m_oState.i64Sample = -1;
m_dSamplerate = pSource->GetSampleRate();
m_uiBlocklength = pSource->GetBlocklength();
m_bGBPFirst = true;
}
inline ~CVAAudiostreamTracker()
{
VA_DEBUG_PRINTF("* Stream processing time: min=%0.3fms, avg=%0.3fms, max=%0.3fms, std=%0.3fms, avg DSP load = %0.1f%%\n",
m_swProcessingTime.minimum()*1e3,
m_swProcessingTime.mean()*1e3,
m_swProcessingTime.maximum()*1e3,
m_swProcessingTime.std_deviation()*1e3,
m_swProcessingTime.mean() * m_dSamplerate / m_uiBlocklength * 1e2);
VA_VERBOSE( "AudioStreaming", "Processing time: " << m_swProcessingTime.ToString() << " avg DSP load = " << m_swProcessingTime.mean() * m_dSamplerate / m_uiBlocklength * 1e2 );
}
// Wichtig: Diese Funktion darf nicht parallel zum Stream aufgerufen werden.
// Not thread safe, not reentrant safe
inline const CVAAudiostreamState& GetStreamState() const
{
return m_oState;
}
// --= Schnittstelle "ITADatasource" =--
inline unsigned int GetBlocklength() const
{
return m_pSource->GetBlocklength();
}
inline unsigned int GetNumberOfChannels() const
{
return m_pSource->GetNumberOfChannels();
}
inline unsigned int GetBlocklength() const { return m_pSource->GetBlocklength(); }
inline unsigned int GetNumberOfChannels() const { return m_pSource->GetNumberOfChannels(); }
inline double GetSampleRate() const { return m_pSource->GetSampleRate(); }
inline double GetSampleRate() const
{
return m_pSource->GetSampleRate();
}
inline const float* GetBlockPointer(unsigned int uiChannel, const ITAStreamInfo* pStreamInfo)
inline const float* GetBlockPointer( unsigned int uiChannel, const ITAStreamInfo* pStreamInfo )
{
// [fwe] Werte der ITAStreamInfo kopieren
m_oState = *pStreamInfo;
if (m_bGBPFirst) {
if( m_bGBPFirst )
{
m_swProcessingTime.start();
float fNewClockOffset = *m_pfClockOffset;
// Informationen aktualisieren
if (m_oState.i64Sample == 0)
if( m_oState.i64Sample == 0 )
{
// Stream-Startzeit holen
// Start
m_dStreamStartTime = m_pClock->getTime();
m_fCurrentClockOffset = fNewClockOffset;
m_oState.bTimeReset = false;
}
else
{
m_oState.bTimeReset = (m_fCurrentClockOffset != fNewClockOffset);
m_oState.bTimeReset = ( m_fCurrentClockOffset != fNewClockOffset );
m_fCurrentClockOffset = fNewClockOffset;
}
//m_oState.dSysTime = m_dStreamStartTime + (double) m_oState.i64Sample / m_dSamplerate;
// Clock drift compensation factor for RME Hammerfall - Handgemessen
m_oState.dSysTime = m_dStreamStartTime + (double) (m_oState.i64Sample + m_uiBlocklength) / m_dSamplerate * 0.999978;
m_oState.dCoreTime = m_oState.dSysTime - (double) m_fCurrentClockOffset;
m_oState.bSyncMod = ((*m_plSyncModOwner) != -1);
// Clock drift compensation factor for RME Hammerfall - via manual measurement @todo remove
m_oState.dSysTime = m_dStreamStartTime + ( double ) ( m_oState.i64Sample + m_uiBlocklength ) / m_dSamplerate * 0.999978;
m_oState.dCoreTime = m_oState.dSysTime - ( double ) m_fCurrentClockOffset;
m_oState.bSyncMod = ( ( *m_plSyncModOwner ) != -1 );
m_bGBPFirst = false;
// Audiosignaldatenquellen holen
m_pSignalSourceMan->FetchInputData(&m_oState);
m_pSignalSourceMan->FetchInputData( &m_oState );
}
return m_pSource->GetBlockPointer(uiChannel, &m_oState);
return m_pSource->GetBlockPointer( uiChannel, &m_oState );
}
inline void IncrementBlockPointer()
......@@ -152,4 +148,4 @@ private:
ITAStopWatch m_swProcessingTime;
};
#endif // IW_VACORE_CORECONFIG
#endif // IW_VACORE_AUDIOSTREAMTRACKER
......@@ -36,16 +36,15 @@ void CVACoreConfig::Init( const CVAStruct& oData )
CVAConfigInterpreter conf( oData );
// Get debug level first
// Get debug level first, will affect further config parsing outputs
int iVALogLevel;
conf.OptInteger( "Debug/LogLevel", iVALogLevel, VACORE_DEFAULT_LOG_LEVEL );
VALog_SetLogLevel( iVALogLevel );
VA_TRACE( "Config", oData );
// --= Macros =--
conf.OptInteger( "Debug/TriggerUpdateMilliseconds", iTriggerUpdateMilliseconds, 100 );
VA_TRACE( "Config", oData );
CVAStruct oMacroStruct( conf.OptStruct( "Macros" ) );
CVAStruct::const_iterator cit = oMacroStruct.Begin();
while( cit != oMacroStruct.End() )
......@@ -61,9 +60,6 @@ void CVACoreConfig::Init( const CVAStruct& oData )
cit++;
}
// --= Paths =--
CVAStruct oPathsStruct( conf.OptStruct( "Paths" ) );
cit = oPathsStruct.Begin();
while( cit != oPathsStruct.End() )
......@@ -78,11 +74,11 @@ void CVACoreConfig::Init( const CVAStruct& oData )
{
vsSearchPaths.push_back( sPath );
mMacros.AddMacro( "$(" + sPathName + ")", sPath );
VA_INFO( "Config", "Added path '" + sPath + "' to search path list and made it available as $(" + sPathName + ") macro." );
VA_INFO( "Config", "Added search path '" + sPath + "'" );
}
else
{
VA_VERBOSE( "Config", "Could not find path '" + sPath + "', removed from search path list. Macro $(" + sPathName + ") is NOT available." );
VA_VERBOSE( "Config", "Could not find path '" + sPath + "', removed from search path list." );
}
}
else
......@@ -91,24 +87,17 @@ void CVACoreConfig::Init( const CVAStruct& oData )
}
}
// --= Audio interface =--
oAudioDriverConfig.init( conf.OptStruct("Audio driver") );
// --= Hardware setup =--
oAudioDriverConfig.Init( conf.OptStruct("Audio driver") );
oHardwareSetup.Init( oData );
// --= Debug =--
conf.OptString( "Debug/DumpDeviceInput", sDumpDeviceInputFilename );
sDumpDeviceInputFilename = mMacros.SubstituteMacros( sDumpDeviceInputFilename );
conf.OptString( "Debug/DumpFinalOutput", sDumpFinalOutputFilename );
sDumpFinalOutputFilename = mMacros.SubstituteMacros( sDumpFinalOutputFilename );
// --= Substitute Macros =--
conf.OptBool( "Debug/InputRecordEnabled", bRecordDeviceInputEnabled, false );
conf.OptString( "Debug/InputRecordFilePath", sRecordDeviceInputFilePath );
sRecordDeviceInputFilePath = mMacros.SubstituteMacros( sRecordDeviceInputFilePath );
// TODO ...
conf.OptBool( "Debug/OutputRecordEnabled", bRecordDeviceOutputEnabled, false );
conf.OptString( "Debug/OutputRecordFilePath", sRecordFinalOutputFilePath );
sRecordFinalOutputFilePath = mMacros.SubstituteMacros( sRecordFinalOutputFilePath );
}
const CVAStruct& CVACoreConfig::GetStruct() const
......
......@@ -37,8 +37,13 @@ public:
CVAMacroMap mMacros; //!< Macros used in configuration file
std::vector< std::string > vsSearchPaths; //!< Search paths (existing directories only)
std::string sDumpDeviceInputFilename; //!< File name fr input channel dump
std::string sDumpFinalOutputFilename; //!< File name fr output channel dump
bool bRecordDeviceInputEnabled; //!< Switch to store entire device input stream record to hard drive
std::string sRecordDeviceInputFilePath; //!< File path where to store the input stream record to hard drive
bool bRecordDeviceOutputEnabled; //!< Switch to store entire device output stream record to hard drive
std::string sRecordFinalOutputFilePath; //!< File path where to store the output stream record to hard drive
int iTriggerUpdateMilliseconds;
//! Initialize the configuration with a struct
/**
......
This diff is collapsed.
......@@ -331,11 +331,13 @@ private:
void InitializeAudioDriver();
void FinalizeAudioDriver();
void FinalizeRenderingModules();
void FinalizeReproductionModules();
IVAAudioDriverBackend* m_pAudioDriverBackend;
ITAStreamAmplifier* m_pInputAmp;
ITAStreamPatchbay* m_pR2RPatchbay; // Patchbay linking audio renderers to audio reproduction modules
ITAStreamPatchbay* m_pOutputPatchbay; // Patchbay linking audio reproduction modules to hardware outputs
ITAStreamPatchbay* m_pR2RPatchbay; //!< Patchbay linking audio renderers to audio reproduction modules
ITAStreamPatchbay* m_pOutputPatchbay; //!< Patchbay linking audio reproduction modules to hardware outputs
ITAPeakDetector* m_pInputPeakDetector;
ITAPeakDetector* m_pOutputPeakDetector;
CVAAudiostreamTracker* m_pOutputTracker;
......@@ -356,31 +358,59 @@ private:
class CVAAudioRendererDesc : public CVAAudioRendererInfo
{
public:
std::shared_ptr< IVAAudioRenderer > pInstance;
IVAAudioRenderer* pInstance;
int iR2RPatchBayInput; //!< Input on the renderer-reproduction patch bay
std::vector< std::string > vsOutputs; //!< Target reproduction modules
ITAStreamProbe* pRecorder; //!< If a non-nullptr recorder is set, it will be deleted on destruction
ITAPeakDetector* pOutputDetector; //!< If a non-nullptr detector is set, it will be deleted on destruction
inline CVAAudioRendererDesc( IVAAudioRenderer* pInstance )
: pInstance( pInstance )
, pRecorder( NULL )
, pOutputDetector( NULL )
{
};
inline void Finalize()
{
delete pInstance;
delete pRecorder;
delete pOutputDetector;
};
};
std::vector< CVAAudioRendererDesc > m_vRenderers;
std::vector< CVAAudioRendererDesc > m_voRenderers;
class CVAAudioReproductionModuleDesc : public CVAAudioRendererInfo
{
public:
std::shared_ptr< IVAAudioReproductionModule > pInstance;
IVAAudioReproductionModule* pInstance;
int iR2RPatchBayOutput; //! Output channel on the renderer-reproduction patch bay
int iOutputPatchBayInput; //! Input channel on the output patchbay
std::vector< const CVAHardwareOutput* > vpOutputs;
ITAPeakDetector* pInputDetector; //!< If a non-nullptr detector is set, it will be deleted on destruction
ITAPeakDetector* pOutputDetector; //!< If a non-nullptr detector is set, it will be deleted on destruction
ITAStreamProbe* pInputRecorder; //!< If a non-nullptr recorder is set, it will be deleted on destruction
ITAStreamProbe* pOutputRecorder; //!< If a non-nullptr recorder is set, it will be deleted on destruction
inline CVAAudioReproductionModuleDesc( IVAAudioReproductionModule* pInstance )
inline CVAAudioReproductionModuleDesc( IVAAudioReproductionModule* pInstance )
: pInstance( pInstance )
, pInputDetector( NULL )
, pOutputDetector( NULL )
, pInputRecorder( NULL )
, pOutputRecorder( NULL )
{
};
inline void Finalize()
{
delete pInstance;
delete pInputDetector;
delete pOutputDetector;
delete pInputRecorder;
delete pOutputRecorder;
};
};
std::vector< CVAAudioReproductionModuleDesc > m_vReproductionModules;
std::vector< CVAAudioReproductionModuleDesc > m_voReproductionModules;
// --= Scene =------------------------------------------------------
......@@ -451,8 +481,14 @@ private:
// Schleifen-Funktion des Kern-Threads
void CoreThreadLoop();
// Aktualisierte Messwerte (Peaks, Last) als Event senden
void SendMeasuresUpdateEvent();
//!< Sends detector values to clients
void SendAudioDeviceDetectorUpdateEvent();
//!< Sends rendering detector values to clients
void SendRenderingModuleOutputDetectorsUpdateEvents();
//!< Sends reproduction detector values to clients
void SendReproductionModuleOIDetectorsUpdateEvents();
//! Initialize rendering modules
void InitializeAudioRenderers();
......
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