Refactoring binaural outdoor noise renderer

parent 97fe602a
......@@ -156,6 +156,9 @@ if( NOT DEFINED ITA_VACORE_WITH_RENDERER_BINAURAL_AIR_TRAFFIC_NOISE )
endif( )
if( NOT DEFINED ITA_VACORE_WITH_RENDERER_BINAURAL_OUTDOOR_NOISE )
set( ITA_VACORE_WITH_RENDERER_BINAURAL_OUTDOOR_NOISE OFF CACHE BOOL "Build VACore with rendering module: outdoor noise" )
if( NOT DEFINED ITA_VACORE_BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS )
set( ITA_VACORE_BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS OFF CACHE BOOL "Enable in-source benchmarking for binaural outdoor noise renderer" )
endif( )
endif( )
if( NOT DEFINED ITA_VACORE_WITH_RENDERER_BINAURAL_CLUSTERING )
set( ITA_VACORE_WITH_RENDERER_BINAURAL_CLUSTERING ON CACHE BOOL "Build VACore with rendering module: clustering renderer" )
......@@ -349,6 +352,11 @@ if( ITA_VACORE_WITH_TTS_SIGNAL_SOURCE )
endif( )
endif( )
if( ITA_VACORE_BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS )
add_definitions( "-DBINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS" )
endif( )
# Dev switches
if( ITA_VACORE_REPRODUCTION_NCTC_WITH_SWEET_SPOT_WIDENING )
add_definitions( "-DVACORE_REPRODUCTION_NCTC_WITH_SWEET_SPOT_WIDENING" )
......
......@@ -82,29 +82,27 @@ void CVABinauralOutdoorNoiseRenderer::Init( const CVAStruct& oArgs )
CVAConfigInterpreter oConf( oArgs );
// set interpolation algorithm
std::string vldInterpolationAlgorithm;
oConf.OptString( "SwitchingAlgorithm", vldInterpolationAlgorithm, "linear" );
vldInterpolationAlgorithm = toLowercase( vldInterpolationAlgorithm );
std::string sVDLInterpolationAlgorithm;
oConf.OptString( "SwitchingAlgorithm", sVDLInterpolationAlgorithm, "linear" );
sVDLInterpolationAlgorithm = toLowercase( sVDLInterpolationAlgorithm );
if( vldInterpolationAlgorithm == "none" )
if( sVDLInterpolationAlgorithm == "none" )
m_iDefaultVDLSwitchingAlgorithm = ITABase::InterpolationFunctions::NONE;
else if( vldInterpolationAlgorithm == "linear" )
else if( sVDLInterpolationAlgorithm == "linear" )
m_iDefaultVDLSwitchingAlgorithm = ITABase::InterpolationFunctions::LINEAR;
else if( vldInterpolationAlgorithm == "cubicspline" )
else if( sVDLInterpolationAlgorithm == "cubicspline" )
m_iDefaultVDLSwitchingAlgorithm = ITABase::InterpolationFunctions::CUBIC_SPLINE;
else
ITA_EXCEPT1( INVALID_PARAMETER, "Unrecognized interpolation algorithm '" + vldInterpolationAlgorithm + "' in BinauralFreefieldAudioRendererConfig" );
ITA_EXCEPT1( INVALID_PARAMETER, "Unrecognized interpolation algorithm '" + sVDLInterpolationAlgorithm + "' in BinauralOutdoorAudioRendererConfig" );
m_oDefaultWaveFrontConf.iSwitchingAlgorithm = m_iDefaultVDLSwitchingAlgorithm;
oConf.OptInteger( "MaxDelaySamples", m_iMaxDelaySamples, 3 * 44100 );
// HRTF filter length
oConf.OptInteger( "HRIRFilterLength", m_iHRIRFilterLength, 256 );
// additional static delay
oConf.OptNumber( "AdditionalStaticDelaySeconds", m_dAdditionalStaticDelaySeconds, 0.0f );
// default listener config, @todo rest
// Default listener config, @todo rest
m_oDefaultReceiverConf.bMotionModelLogEstimated = false;
m_oDefaultReceiverConf.bMotionModelLogInput = false;
oConf.OptInteger( "MotionModelNumHistoryKeys", m_oDefaultReceiverConf.iMotionModelNumHistoryKeys, 1000 );
......@@ -134,15 +132,15 @@ void CVABinauralOutdoorNoiseRenderer::Init( const CVAStruct& oArgs )
m_oDefaultWaveFrontConf.dSampleRate = GetSampleRate();
oConf.OptInteger( "IIRFilterOrder", m_oDefaultWaveFrontConf.iIIRFilterOrder, 4 );
oConf.OptInteger( "BurgFIRLength", m_oDefaultWaveFrontConf.FIRFilterLength, 1024 );
oConf.OptInteger( "BurgFIRLength", m_oDefaultWaveFrontConf.iFIRFilterLength, 1024 );
oConf.OptInteger( "InterpolationBufferSize", m_oDefaultWaveFrontConf.iBufferSize, GetBlocklength() * 10 );
m_oDefaultWaveFrontConf.FilterDesignAlgorithm = ITADSP::BURG; //no other algorthms currently implemented
m_oDefaultWaveFrontConf.iFilterDesignAlgorithm = ITADSP::BURG; // No other algorthms currently implemented
oConf.OptInteger( "NumClusters", m_iNumClusters, 12 );
oConf.OptNumber( "AngularDistanceThreshold", m_dAngularDistanceThreshold, 4.0f / float( m_iNumClusters ) );
// initialize after config
// Initialize after config
m_pClusterEngine = new CVABinauralClusteringEngine( GetBlocklength(), m_iHRIRFilterLength );
}
......@@ -210,13 +208,13 @@ void CVABinauralOutdoorNoiseRenderer::SetParameters( const CVAStruct& oInArgs )
auto checksrc = m_mSources.find( path_source_ID );
if( checksrc == m_mSources.end() )
VA_EXCEPT1( "Source ID not found, make sure the source associated with each path exists." );
m_mPaths[ iPathID ]->setSource( m_mSources[ path_source_ID ] ); //set the source for this path
m_mPaths[ iPathID ]->SetSource( m_mSources[ path_source_ID ] ); //set the source for this path
int path_receiver_ID = 1; // = path[ "receiver" ];
auto checkrec = m_mBinauralReceivers.find( path_receiver_ID );
if( checkrec == m_mBinauralReceivers.end() )
VA_EXCEPT1( "Receiver ID not found, make sure the Receiver associated with each path exists." );
m_mPaths[ iPathID ]->setReceiver( m_mBinauralReceivers[ path_receiver_ID ] ); //set the sound receiver for this path
m_mPaths[ iPathID ]->SetReceiver( m_mBinauralReceivers[ path_receiver_ID ] ); //set the sound receiver for this path
}
bool audible_ok = false; //if this is the first time this path is used, and it does not have the right keys,needs to be set inaudible
......@@ -226,7 +224,7 @@ void CVABinauralOutdoorNoiseRenderer::SetParameters( const CVAStruct& oInArgs )
/*
if( oPath.HasKey( "valid" ) )
m_mPaths[ iPathID ]->SetValid( oPath[ "valid" ] );
m_mPaths[ iPathID ]->SetValid( oPath[ "valid" ] );
*/
if( oPath.HasKey( "frequency_magnitudes" ) )
......@@ -241,7 +239,7 @@ void CVABinauralOutdoorNoiseRenderer::SetParameters( const CVAStruct& oInArgs )
for( int i = 0; i < 31; i++ )
oMagsTemp.SetMagnitude( i, pfMags[ i ] );
m_mPaths[ iPathID ]->setFilterCoefficients( oMagsTemp ); //update the filter coefficients internal to the path based on the target frequency magnitudes
m_mPaths[ iPathID ]->SetFilterCoefficients( oMagsTemp ); //update the filter coefficients internal to the path based on the target frequency magnitudes
audible_ok = true;
}
......@@ -249,7 +247,7 @@ void CVABinauralOutdoorNoiseRenderer::SetParameters( const CVAStruct& oInArgs )
{
double delay = oPath[ "delay" ];
unsigned int idelay = ( int ) round( delay * m_oDefaultWaveFrontConf.dSampleRate ); //unsigned as can not have negative delay (causality)
m_mPaths[ iPathID ]->setDelay( idelay );
m_mPaths[ iPathID ]->SetDelay( idelay );
}
if( oPath.HasKey( "gain" ) )
......@@ -292,38 +290,21 @@ CVAStruct CVABinauralOutdoorNoiseRenderer::GetParameters( const CVAStruct& ) con
void CVABinauralOutdoorNoiseRenderer::UpdateGlobalAuralizationMode( int iGlobalAuralizationMode )
{
if( m_iCurGlobalAuralizationMode == iGlobalAuralizationMode )
return;
m_iCurGlobalAuralizationMode = iGlobalAuralizationMode;
return;
if( m_iCurGlobalAuralizationMode != iGlobalAuralizationMode )
m_iCurGlobalAuralizationMode = iGlobalAuralizationMode;
}
void
CVABinauralOutdoorNoiseRenderer::ProcessStream( const ITAStreamInfo* streamInfo )
void CVABinauralOutdoorNoiseRenderer::ProcessStream( const ITAStreamInfo* streamInfo )
{
#ifdef BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
auto start = std::chrono::high_resolution_clock::now();
LARGE_INTEGER frequency; // ticks per second
LARGE_INTEGER t1, t2; // ticks
double elapsedTime;
// get ticks per second
QueryPerformanceFrequency(&frequency);
// start timer
QueryPerformanceCounter( &t1 );
#endif // BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
m_swProcessStream.start();
#endif
float* pfOutputL = GetWritePointer( 0 );
float* pOutputR = GetWritePointer( 1 );
float* pfOutputR = GetWritePointer( 1 );
fm_zero( pfOutputL, GetBlocklength() );
fm_zero( pOutputR, GetBlocklength() );
fm_zero( pfOutputR, GetBlocklength() );
/* @todo jst: why is this outcommented? Trajectories must be updated here for Doppler shifts ...
const CVAAudiostreamState* streamState = dynamic_cast< const CVAAudiostreamState* >( streamInfo );
......@@ -350,34 +331,22 @@ CVABinauralOutdoorNoiseRenderer::ProcessStream( const ITAStreamInfo* streamInfo
ITASampleFrame* sfOutput = pReceiverInstance->GetOutput();
fm_copy( pfOutputL, ( *sfOutput )[ 0 ].GetData(), GetBlocklength() );
fm_copy( pOutputR, ( *sfOutput )[ 1 ].GetData(), GetBlocklength() );
fm_copy( pfOutputR, ( *sfOutput )[ 1 ].GetData(), GetBlocklength() );
}
// -- Increment source's SIMO VDLs
for( auto oSource : m_mSources )
{
CVABinauralOutdoorSource* pSource( oSource.second );
pSource->pVDL->Increment( GetBlocklength() );
}
#ifdef BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
// stop timer
QueryPerformanceCounter(&t2);
// compute and print the elapsed time in millisec
elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
std::ofstream outfile("X:/Sciebo/master-thesis/data/benchmarks/Stream_128.txt", std::fstream::app);
outfile << elapsedTime << std::endl;
outfile.close();
#endif // BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
IncrementWritePointer();
return;
}
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
m_swProcessStream.stop();
#endif
}
void CVABinauralOutdoorNoiseRenderer::UpdateScene( CVASceneState* pNewSceneState )
{
......@@ -394,20 +363,6 @@ void CVABinauralOutdoorNoiseRenderer::UpdateScene( CVASceneState* pNewSceneState
CVASceneStateDiff diff;
m_pNewSceneState->Diff( m_pCurSceneState, &diff );
#ifdef BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
LARGE_INTEGER frequency; // ticks per second
LARGE_INTEGER t1, t2; // ticks
double elapsedTime;
// get ticks per second
QueryPerformanceFrequency(&frequency);
// start timer
QueryPerformanceCounter( &t1 );
#endif // BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
// Update receivers
UpdateSoundReceivers( &diff );
......@@ -416,20 +371,6 @@ void CVABinauralOutdoorNoiseRenderer::UpdateScene( CVASceneState* pNewSceneState
m_pClusterEngine->Update();
#ifdef BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
// stop timer
QueryPerformanceCounter(&t2);
// compute and print the elapsed time in millisec
elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
std::ofstream outfile("X:/Sciebo/master-thesis/data/benchmarks/UpdateScene_128.txt", std::fstream::app);
outfile << elapsedTime << std::endl;
outfile.close();
#endif // BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
// Alte Szene freigeben (dereferenzieren)
if( m_pCurSceneState )
m_pCurSceneState->RemoveReference();
......@@ -459,7 +400,7 @@ void CVABinauralOutdoorNoiseRenderer::UpdateSoundSources( CVASceneStateDiff* dif
{
const int& iID( *it++ );
CreateSoundSource( iID, m_pNewSceneState->GetSoundSourceState( iID ) );
}
}
// Update wave front trajectories
std::map< int, CVABinauralOutdoorSource* >::iterator it;
......@@ -557,7 +498,7 @@ void CVABinauralOutdoorNoiseRenderer::UpdateSoundReceivers( CVASceneStateDiff* p
void CVABinauralOutdoorNoiseRenderer::CreateSoundSource( const int iSourceID, const CVASoundSourceState* pSourceState )
{
auto pSource = new CVABinauralOutdoorSource();
auto pSource = new CVABinauralOutdoorSource( m_iMaxDelaySamples );
// set state
pSource->pState = ( CVASoundSourceState* ) pSourceState;
......
......@@ -88,10 +88,10 @@ private:
CVABinauralClusteringReceiver::Config m_oDefaultReceiverConf; //!< Default listener config for factory object creation
CVABinauralOutdoorWaveFront::Config m_oDefaultWaveFrontConf;
int m_iMaxDelaySamples;
int m_iDefaultVDLSwitchingAlgorithm;
int m_iHRIRFilterLength;
int m_iCurGlobalAuralizationMode; // @todo use in UpdateScene
double m_dAdditionalStaticDelaySeconds;
void Init( const CVAStruct& oArgs );
......@@ -107,13 +107,12 @@ private:
void UpdateMotionStates();
void UpdateTrajectories( double dTime );
int mNumberofPaths;
std::vector<ITABase::CThirdOctaveGainMagnitudeSpectrum> mMags; //internal vector of target magnitude spectrums for IIR filter design
//vector elements correspond to the path number *****************PROBABLY NOT NEEDED ANY MORE**********************************
double m_dAngularDistanceThreshold;
int m_iNumClusters;
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
ITAStopWatch m_swProcessStream;
#endif
};
#endif // VACORE_WITH_RENDERER_BINAURAL_OUTDOOR_NOISE
......
#include "VABinauralOutdoorSource.h"
CVABinauralOutdoorSource::CVABinauralOutdoorSource()
CVABinauralOutdoorSource::CVABinauralOutdoorSource( int iMaxDelaySamples )
{
const int max_delay_samples = 1024; //TODO: take this number from ini file instead
pVDL = new CITASIMOVariableDelayLineBase(max_delay_samples);
pVDL = new CITASIMOVariableDelayLineBase( iMaxDelaySamples );
}
CVABinauralOutdoorSource::~CVABinauralOutdoorSource()
{
delete pVDL;
}
......@@ -27,7 +27,7 @@
class CVABinauralOutdoorSource
{
public:
CVABinauralOutdoorSource();
CVABinauralOutdoorSource( int iMaxDelaySamples );
~CVABinauralOutdoorSource();
CVASoundSourceState* pState;
......
......@@ -24,8 +24,7 @@ CVABinauralOutdoorWaveFront::CVABinauralOutdoorWaveFront( const CVABinauralOutdo
, m_bClusteringPoseSet( false )
, m_bWaveFrontOriginSet( false )
{
if( conf.FilterDesignAlgorithm == ITADSP::BURG )
if( conf.iFilterDesignAlgorithm == ITADSP::BURG )
{
m_iIIRFilterCoeffs.Initialise( conf.iIIRFilterOrder, false );
m_iIIRFilterCoeffs.iDesignAlgorithm = ITADSP::BURG;
......@@ -69,33 +68,48 @@ void CVABinauralOutdoorWaveFront::PreRelease()
void CVABinauralOutdoorWaveFront::GetOutput( ITASampleBuffer* pfLeftChannel, ITASampleBuffer* pfRightChannel )
{
//This fn is called from the clustering direction, and outputs the left and right audio channels for a path.
//First get the data from the VDL
//Then apply the IIR filter to the single channel
//Then interpolate delay
//Then split into two channels and adjust for ITD to nearest sample
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
m_swGetOutput.start();
#endif
/*
* This fn is called from the clustering direction, and outputs the left and right audio channels for a path.
* First get the data from the VDL
* Then apply the IIR filter to the single channel
* Then interpolate delay
* Then split into two channels and adjust for ITD to nearest sample
*/
float fGainOld = m_fGainCur;
float fGainNew = m_bAudible ? m_fGainNew : 0.0f; // Switch to new gain or fade out
int iCurrentDelay = m_pSIMOVDL->GetCurrentDelaySamples( iCursorID ); //get current and new delay in samples
int iNewDelay = m_pSIMOVDL->GetNewDelaySamples( iCursorID );
int iCurrentDelay = m_pSIMOVDL->GetCurrentDelaySamples( m_iCursorID ); // Get current and new delay in samples
int iNewDelay = m_pSIMOVDL->GetNewDelaySamples( m_iCursorID );
if( iNewDelay == iCurrentDelay )
{
//Directly read from VDL -> IIR to L/R channels, no interp needed, as no change in delay, so no Doppler
m_pSIMOVDL->SetOverlapSamples( iCursorID, m_iITDDifference, 0 ); //no interp
unsigned int buffer_size = m_pSIMOVDL->GetEffectiveReadLength( iCursorID, oConf.iBlockLength );
m_pSIMOVDL->Read( iCursorID, oConf.iBlockLength, m_sbTemp.GetData() ); //read VDL data to tempary buffer
//tempBuffer.Store("test_vdl_data.wav"); //TEST
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
m_swVDL.start();
#endif
// Directly read from VDL -> IIR to L/R channels, no interp needed, as no change in delay, so no Doppler
m_pSIMOVDL->SetOverlapSamples( m_iCursorID, m_iITDDifference, 0 ); // No interp
unsigned int buffer_size = m_pSIMOVDL->GetEffectiveReadLength( m_iCursorID, oConf.iBlockLength );
m_pSIMOVDL->Read( m_iCursorID, oConf.iBlockLength, m_sbTemp.GetData() ); // Read VDL data to tempary buffer
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
m_swVDL.stop();
m_swIIRFilter.start();
#endif
m_oIIRFilterEngine.Process( m_sbTemp.GetData(), m_sbTemp.GetData(), buffer_size, fGainOld, fGainNew, ITABase::MixingMethod::OVERWRITE ); //apply the IIR filter to the data taken from the VDL
//tempBuffer.Store("test_filtered_signal.wav"); //TEST
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
m_swIIRFilter.stop();
m_swInterpolation.start();
#endif
if( m_iITDDifference <= 0 )
{ //adjust where data is read from the buffer depending on whether ITD diff is positive or negative
{
// Adjust where data is read from the buffer depending on whether ITD diff is positive or negative
pfLeftChannel->write( m_sbTemp, oConf.iBlockLength );
pfRightChannel->write( m_sbTemp, oConf.iBlockLength, m_iITDDifference );
}
......@@ -104,56 +118,63 @@ void CVABinauralOutdoorWaveFront::GetOutput( ITASampleBuffer* pfLeftChannel, ITA
pfLeftChannel->write( m_sbTemp, oConf.iBlockLength, m_iITDDifference );
pfRightChannel->write( m_sbTemp, oConf.iBlockLength );
}
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
m_swInterpolation.stop();
#endif
}
else
{
int interpolate_left, interpolate_right;
m_pInterpolationRoutine->GetOverlapSamples( interpolate_left, interpolate_right ); //get number of overlap samples needed for the interpolation
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
m_swVDL.start();
#endif
int iInterpolateLeft, iInterpolateRight;
m_pInterpolationRoutine->GetOverlapSamples( iInterpolateLeft, iInterpolateRight ); // Get number of overlap samples needed for the interpolation
m_pSIMOVDL->SetOverlapSamples( iCursorID, interpolate_left + m_iITDDifference, interpolate_right ); //set the overlap to be read from the VDL
m_pSIMOVDL->SetOverlapSamples( m_iCursorID, iInterpolateLeft + m_iITDDifference, iInterpolateRight ); // Set the overlap to be read from the VDL
int buffer_size = m_pSIMOVDL->GetEffectiveReadLength( iCursorID, oConf.iBlockLength );
unsigned int interpolated_signal_size = oConf.iBlockLength + abs( m_iITDDifference );
int iBufferSize = m_pSIMOVDL->GetEffectiveReadLength( m_iCursorID, oConf.iBlockLength );
unsigned int iInterpolatedSignalSize = oConf.iBlockLength + abs( m_iITDDifference );
if( m_sbTemp.GetLength() < buffer_size )
m_sbTemp.Init( buffer_size * 2 ); // Init should be avoided, so extend to twice the size in hope to avoid this call
if( m_sbTemp.GetLength() < iBufferSize )
m_sbTemp.Init( iBufferSize * 2 ); // Init should be avoided, so extend to twice the size in hope to avoid this call
//***************************************************Read data from VDL******************************************************
m_pSIMOVDL->Read( iCursorID, oConf.iBlockLength, m_sbTemp.GetData() );
m_pSIMOVDL->Read( m_iCursorID, oConf.iBlockLength, m_sbTemp.GetData() ); // Take out variable-sized block from VDL (not interpolated yet!)
//tempBuffer.Store("test_vdl_data.wav"); //TEST
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
m_swVDL.stop();
m_swIIRFilter.start();
#endif
//*****************************************************Apply IIR Filter******************************************************
m_oIIRFilterEngine.Process( m_sbTemp.GetData(), m_sbTemp.GetData(), buffer_size, fGainOld, fGainNew, ITABase::MixingMethod::OVERWRITE ); //apply the IIR filter to the data taken from the VDL
m_oIIRFilterEngine.Process( m_sbTemp.GetData(), m_sbTemp.GetData(), iBufferSize, fGainOld, fGainNew, ITABase::MixingMethod::OVERWRITE ); //apply the IIR filter to the data taken from the VDL
//tempBuffer.Store("test_filtered_signal.wav"); //TEST
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
m_swIIRFilter.stop();
m_swInterpolation.start();
#endif
//*****************************************************Interpolate***********************************************************
int input_length = buffer_size - interpolate_left;
bool bSkipInterpoltionOnCorruptBlockLength = (input_length < 1);
if (oConf.iSwitchingAlgorithm == ITABase::InterpolationFunctions::LINEAR && !bSkipInterpoltionOnCorruptBlockLength )
const int iInputLength = iBufferSize - iInterpolateLeft;
bool bSkipInterpoltionOnCorruptBlockLength = bool( iInputLength < 1 );
if( oConf.iSwitchingAlgorithm == ITABase::InterpolationFunctions::LINEAR && !bSkipInterpoltionOnCorruptBlockLength )
{
m_pInterpolationRoutine->Interpolate(&m_sbTemp, input_length, interpolate_left, &m_sbInterpolated, interpolated_signal_size);
//output size decreased to be blocklength + left/right margin for ITD difference offset
m_pInterpolationRoutine->Interpolate( &m_sbTemp, iInputLength, iInterpolateLeft, &m_sbInterpolated, iInterpolatedSignalSize );
// Output size decreased to be blocklength + left/right margin for ITD difference offset
}
else if(oConf.iSwitchingAlgorithm == ITABase::InterpolationFunctions::NONE || bSkipInterpoltionOnCorruptBlockLength)
else if( oConf.iSwitchingAlgorithm == ITABase::InterpolationFunctions::NONE || bSkipInterpoltionOnCorruptBlockLength )
{
//Directly switch from new to old delay: no interpolation skip to end
m_sbInterpolated.write( m_sbTemp, interpolated_signal_size, interpolate_left, 0 );
// Directly switch from new to old delay: no interpolation skip to end
m_sbInterpolated.write( m_sbTemp, iInterpolatedSignalSize, iInterpolateLeft, 0 );
if( bSkipInterpoltionOnCorruptBlockLength )
VA_WARN( "BinauralOutdoorNoiseRenderer", "Had to skip a path update due to invalid buffer size to write to" );
}
else
{
VA_EXCEPT1("Unknown interpolation type forwarded to VABinaurlWaveFront, please use either 'LINEAR_INTERPOLATION' or 'SWITCH'.");
VA_EXCEPT1( "Unknown interpolation type forwarded to VABinaurlWaveFront, please use either 'LINEAR_INTERPOLATION' or 'SWITCH'." );
}
//tempBuffer.Store("test_interpolated_signal.wav"); //TEST
//***************************************Apply ITD correction*************************************************
//write from the interpolated buffer to left/right channels with different offset depending on the ITD correction needed
// Apply ITD correction
if( m_iITDDifference <= 0 )
{ //adjust where data is read from the buffer depending on whether ITD diff is positive or negative
{
// Adjust where data is read from the buffer depending on whether ITD diff is positive or negative
pfLeftChannel->write( m_sbInterpolated, oConf.iBlockLength );
pfRightChannel->write( m_sbInterpolated, oConf.iBlockLength, m_iITDDifference );
}
......@@ -162,23 +183,30 @@ void CVABinauralOutdoorWaveFront::GetOutput( ITASampleBuffer* pfLeftChannel, ITA
pfLeftChannel->write( m_sbInterpolated, oConf.iBlockLength, m_iITDDifference );
pfRightChannel->write( m_sbInterpolated, oConf.iBlockLength );
}
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
m_swInterpolation.stop();
#endif
}
m_fGainCur = fGainNew;
#ifdef BINAURAL_OUTDOOR_NOISE_INSOURCE_BENCHMARKS
m_swGetOutput.stop();
#endif
}
void CVABinauralOutdoorWaveFront::setParameters( const CVAStruct &oInArgs )
void CVABinauralOutdoorWaveFront::SetParameters( const CVAStruct &oInArgs )
{
VA_EXCEPT_NOT_IMPLEMENTED;
}
void CVABinauralOutdoorWaveFront::setFilterCoefficients( const ITABase::CThirdOctaveGainMagnitudeSpectrum &oMags )
void CVABinauralOutdoorWaveFront::SetFilterCoefficients( const ITABase::CThirdOctaveGainMagnitudeSpectrum &oMags )
{
ITABase::CFiniteImpulseResponse oIR( oConf.FIRFilterLength, float( oConf.dSampleRate ) ); //create an empty impulse response
ITABase::CFiniteImpulseResponse oIR( oConf.iFIRFilterLength, float( oConf.dSampleRate ) ); //create an empty impulse response
CITAThirdOctaveFIRFilterGenerator oIRGenerator( oConf.dSampleRate, oConf.FIRFilterLength ); //convert the given third ctave frequency magnitudes to an impulse response
CITAThirdOctaveFIRFilterGenerator oIRGenerator( oConf.dSampleRate, oConf.iFIRFilterLength ); //convert the given third ctave frequency magnitudes to an impulse response
if( oConf.FilterDesignAlgorithm == ITADSP::BURG )
if( oConf.iFilterDesignAlgorithm == ITADSP::BURG )
{
oIRGenerator.GenerateFilter( oMags, oIR.GetData(), false ); //set to false for normal, true for minimum phase needed for yulewalk
ITADSP::IIRFilterGenerator::Burg( oIR, m_iIIRFilterCoeffs ); //using the impulse response as input, calculate the IIR filter coefficients.
......@@ -191,9 +219,9 @@ void CVABinauralOutdoorWaveFront::setFilterCoefficients( const ITABase::CThirdOc
}
void CVABinauralOutdoorWaveFront::setDelay( const int iDelaySamples )
void CVABinauralOutdoorWaveFront::SetDelay( const int iDelaySamples )
{
m_pSIMOVDL->SetDelaySamples( iCursorID, iDelaySamples );
m_pSIMOVDL->SetDelaySamples( m_iCursorID, iDelaySamples );
}
void CVABinauralOutdoorWaveFront::SetGain( float fGain )
......@@ -201,21 +229,21 @@ void CVABinauralOutdoorWaveFront::SetGain( float fGain )
m_fGainNew = fGain;
}
void CVABinauralOutdoorWaveFront::setMotion()
void CVABinauralOutdoorWaveFront::SetMotion()
{
ITA_EXCEPT_NOT_IMPLEMENTED;
}
void CVABinauralOutdoorWaveFront::setSource( CVABinauralOutdoorSource* source )
void CVABinauralOutdoorWaveFront::SetSource( CVABinauralOutdoorSource* pSource )
{
m_pSIMOVDL = source->pVDL; //The variable delay line from the source this path originated from
m_pSIMOVDL = pSource->pVDL; //The variable delay line from the source this path originated from
iCursorID = m_pSIMOVDL->AddCursor();
m_iCursorID = m_pSIMOVDL->AddCursor();
m_pSource = source;
m_pSource = pSource;
}
void CVABinauralOutdoorWaveFront::setReceiver( CVABinauralClusteringReceiver* receiver )
void CVABinauralOutdoorWaveFront::SetReceiver( CVABinauralClusteringReceiver* receiver )
{
m_pReceiver = receiver;
}
......@@ -224,7 +252,7 @@ void CVABinauralOutdoorWaveFront::setITDDifference( const float fITDDiff )
{
m_iITDDifference = ( int ) round( fITDDiff * oConf.dSampleRate ); //convert the ITD difference in seconds to samples
if( abs( m_iITDDifference ) + oConf.iBlockLength > oConf.iBufferSize )
VA_EXCEPT1( "ITD Differnce set is too large, increase the maximum buffersize for the outdoor renderer in the config file" );
VA_EXCEPT1( "ITD Difference set is too large, increase the maximum buffersize for the outdoor renderer in the config file" );
}
void CVABinauralOutdoorWaveFront::SetClusteringMetrics( const VAVec3& v3Pos, const VAVec3& v3View, const VAVec3& v3Up, const VAVec3& v3PrincipleDirectionOrigin )
......
......@@ -58,14 +58,12 @@ public:
int iBlockLength;
int iIIRFilterOrder;
int FIRFilterLength;
int FilterDesignAlgorithm;
int iFIRFilterLength;
int iFilterDesignAlgorithm;
int iBufferSize;