Commit 01397e5e authored by henryjandrew's avatar henryjandrew

changed wavefront to so that TOA difference calculations are done outside the...

changed wavefront to so that TOA difference calculations are done outside the class, and added some checks to OutdoorRenderer
parent 32057179
......@@ -171,9 +171,15 @@ void CVABinauralOutdoorNoiseRenderer::SetParameters(const CVAStruct& oInArgs)
m_mPaths[path_ID]->hasValidTrajectory = true; //TODO: check if this should be checked in some fn rather than just alway set
int path_source_ID = path["source"]; //get source ID from incoming data
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[path_ID]->setSource(m_mSources[path_source_ID]); //set the source for this path
int path_receiver_ID = 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[path_ID]->setReceiver( m_mBinauralReceivers[path_receiver_ID] ); //set the sound receiver for this path
//m_pClusterEngine->AddWaveFront(path_ID, m_mPaths[path_ID]); //add new wave front to the clustering engine
......@@ -195,7 +201,7 @@ void CVABinauralOutdoorNoiseRenderer::SetParameters(const CVAStruct& oInArgs)
double delay = path["delay"];
int idelay = (int)round(delay * m_oDefaultWaveFrontConf.sampleRate);
unsigned int idelay = (int)round(delay * m_oDefaultWaveFrontConf.sampleRate); //unsigned as can not have negative delay (causality)
m_mPaths[path_ID]->setDelay(idelay);
......
......@@ -11,8 +11,10 @@
#include <ITASIMOVariableDelayLineBase.h>
#include <ITASampleBuffer.h>
#include <ITAException.h>
#include <ITAThirdOctaveFIRFilterGenerator.h>
#include <math.h>
#define MIN_RESAMPLING_FACTOR 0.0f // [0, inf) ... aber sinnvoll z.B. 0, 0.1, 0.5 (< 1)
#define MAX_RESAMPLING_FACTOR 2.5f // [0, inf) ... aber sinnvoll z.B. 1, 1.5, 2, 3 (> 1)
......@@ -78,52 +80,36 @@ void CVABinauralOutdoorWaveFront::GetOutput( ITASampleBuffer* pfLeftChannel, ITA
//Then interpolate delay
//Then split into two channels and adjust for ITD to nearest sample
// Determine ToA difference
VARelationMetrics clusterMetrics; //get metrics about the clustering direction
clusterMetrics.calc( m_v3PredictedClusteringPos, m_v3PredictedClusteringView, m_v3PredictedClusteringUp, v3ReceiverPos );
int toaClusterLeft = (int)round( sound_receiver->pTimeOfArrivalEstimator->getTOALeft(clusterMetrics.phi, clusterMetrics.theta) ); //the TOA difference for a signal coming from the specified angles for the left ear
int toaClusterRight = (int)round(sound_receiver->pTimeOfArrivalEstimator->getTOARight(clusterMetrics.phi, clusterMetrics.theta)); //TODO: test if this works/ how accurate
VARelationMetrics pathMetrics; //get metrics about the current path
pathMetrics.calc(v3PredictedPos, m_v3PredictedClusteringView, m_v3PredictedClusteringUp, v3ReceiverPos); //TODO: add these variables in setMotion NOTE: uses same view and up vectors as for cluster, I THINK this is ok
int toaPathLeft = (int)round(sound_receiver->pTimeOfArrivalEstimator->getTOALeft(pathMetrics.phi, pathMetrics.theta)); //the TOA difference for a signal coming from the specified angles for the left ear
int toaPathRight = (int)round(sound_receiver->pTimeOfArrivalEstimator->getTOARight(pathMetrics.phi, pathMetrics.theta)); //TODO: test if this works/ how accurate
int ITD_diff_margin_left, ITD_diff_margin_right; //calculate the difference in the TOA from cluster to path
ITD_diff_margin_left = toaPathLeft - toaClusterLeft;
ITD_diff_margin_right = toaPathRight - toaClusterRight;
float test = sound_receiver->pTimeOfArrivalEstimator->getTOALeft(clusterMetrics.phi, clusterMetrics.theta) * oConf.sampleRate;
float test1 = sound_receiver->pTimeOfArrivalEstimator->getTOALeft(pathMetrics.phi, pathMetrics.theta) * oConf.sampleRate;
if (toaClusterLeft > 0) {
int test = 1;
}
int iCurrentDelay = VDL->GetCurrentDelaySamples(iCursorID); //get current and new delay in samples
int iNewDelay = VDL->GetNewDelaySamples(iCursorID);
if (iNewDelay == iCurrentDelay) {
//Directly read from VDL -> IIR to L/R channels, no interp needed, as no change in delay, so no Doppler
VDL->SetOverlapSamples(iCursorID, ITD_diff_margin_left, ITD_diff_margin_right); //no interp
VDL->SetOverlapSamples(iCursorID, itdDifference, 0); //no interp
int buffer_size = VDL->GetEffectiveReadLength(iCursorID, oConf.blockLength);
VDL->Read(iCursorID, oConf.blockLength, tempBuffer.GetData()); //read VDL data to tempary buffer
oIIRFilterEngine.Process(tempBuffer.GetData(), tempBuffer.GetData(), buffer_size); //apply the IIR filter to the data taken from the VDL
pfLeftChannel->write(tempBuffer, oConf.blockLength);
pfRightChannel->write(tempBuffer, oConf.blockLength, ITD_diff_margin_left + ITD_diff_margin_right);
if (itdDifference <= 0) { //adjust where data is read from the buffer depending on whether ITD diff is positive or negative
pfLeftChannel->write(tempBuffer, oConf.blockLength );
pfRightChannel->write(tempBuffer, oConf.blockLength, itdDifference);
}
else {
pfLeftChannel->write(tempBuffer, oConf.blockLength, itdDifference);
pfRightChannel->write(tempBuffer, oConf.blockLength);
}
return;
}
int interpolate_left, interpolate_right;
m_pInterpolationRoutine->GetOverlapSamples(interpolate_left, interpolate_right); //get number of overlap samples needed for the interpolation
VDL->SetOverlapSamples(iCursorID, interpolate_left + ITD_diff_margin_left, interpolate_right + ITD_diff_margin_right); //set the overlap to be read from the VDL
VDL->SetOverlapSamples(iCursorID, interpolate_left + itdDifference, interpolate_right ); //set the overlap to be read from the VDL
int buffer_size = VDL->GetEffectiveReadLength(iCursorID,oConf.blockLength);
int interpolated_signal_size = oConf.blockLength + ITD_diff_margin_left + ITD_diff_margin_right;
int interpolated_signal_size = oConf.blockLength + abs(itdDifference);
//***************************************************Read data from VDL******************************************************
VDL->Read(iCursorID,oConf.blockLength,tempBuffer.GetData());
......@@ -152,62 +138,38 @@ void CVABinauralOutdoorWaveFront::GetOutput( ITASampleBuffer* pfLeftChannel, ITA
case SWITCH:
{
//Directly switch from new to old delay: no interpolation skip to end
interpolatedSignal.write(tempBuffer.GetData(), interpolated_signal_size, interpolate_left+ITD_diff_margin_left);
//Directly switch from new to old delay: no interpolation skip to end
interpolatedSignal.write(tempBuffer.GetData(), interpolated_signal_size, interpolate_left, 0 );
break;
}
case CROSSFADE:
{
//Think for this that we need to store the previous buffer (or atleast the read cursor) either here or in the VDL base (probably better in base)
/*
assert(m_iFadeLength <= m_psbTemp->length()); //fade between old buffer and new one
m_psbTemp->cyclic_write(m_psbVDLBuffer, m_iFadeLength, iReadCursorCurrent, 0);
psbOutput->cyclic_write(m_psbVDLBuffer, m_iBlockLength, iReadCursorNew, 0);
psbOutput->Crossfade(m_psbTemp, 0, m_iFadeLength, ITABase::CrossfadeDirection::FROM_SOURCE, ITABase::FadingFunction::COSINE_SQUARE);
*/
VA_EXCEPT1("CROSSFADE not yet implememnted in VABinauralOutdoorWaveFront GetOutput");
break;
}
default: //Interpolate
{
//assert(iLeft < oConf.blockLength);
//assert(iRight < oConf.blockLength);
//assert(m_iVDLBufferSize > iNewIntDelay + iRight);
//assert(iLeft + iSize + iRight <= m_psbTemp->length());
m_pInterpolationRoutine->Interpolate(&tempBuffer, buffer_size, interpolate_left, &interpolatedSignal, interpolated_signal_size);
//output size increased to be blocklength + left/right margin for ITD difference offset
//output size decreased to be blocklength + left/right margin for ITD difference offset
break;
}
} // end case switch
//m_lUserCursors[iCursorID].iOldReadCursorSamples = iNewDelayLocalCopy; //This should be done in VDL base?
//***************************************Apply ITD correction*************************************************
//write from the interpolated buffer to left/right channels with different offset depending on the ITD correction needed
pfLeftChannel->write(interpolatedSignal, oConf.blockLength);
pfRightChannel->write(interpolatedSignal, oConf.blockLength, ITD_diff_margin_left + ITD_diff_margin_right);
//double toaDistance = sourceMetrics.dist / 343; // TODO: get sound speed from core homogeneous medium
//double toaSourceChL = _listener->toaEstimator->getTOALeft(sourceMetrics.phi, sourceMetrics.theta);
//double toSourceaChR = _listener->toaEstimator->getTOARight(sourceMetrics.phi, sourceMetrics.theta);
// @todo finalize and use TOA estimation
//vdlChL->SetDelayTime(std::max(0., toaDistance + toaSourceChL - toaHRTFChL));
//vdlChR->SetDelayTime(std::max(0., toaDistance + toaSourceChR - toaHRTFChR)); //
//@todo jst: there is something wrong with the following two lines ... toaDistance seems to jump
//vdlChL->SetDelayTime( toaDistance );
//vdlChR->SetDelayTime( toaDistance ); //taken from simulation instead
if (itdDifference <= 0) { //adjust where data is read from the buffer depending on whether ITD diff is positive or negative
pfLeftChannel->write(interpolatedSignal, oConf.blockLength);
pfRightChannel->write(interpolatedSignal, oConf.blockLength, itdDifference);
}
else {
pfLeftChannel->write(interpolatedSignal, oConf.blockLength, itdDifference);
pfRightChannel->write(interpolatedSignal, oConf.blockLength);
}
//float gain = float( ( 1 / sourceMetrics.dist ) * pState->GetVolume( VAConfig::amplitudeCalibration ) );
//pfLeftChannel->mul_scalar( gain ); //gain should be taken care of in simulation and IIR?
//pfRightChannel->mul_scalar( gain );
}
void CVABinauralOutdoorWaveFront::SetClusteringPose( const VAVec3& v3Pos, const VAVec3& v3View, const VAVec3& v3Up )
......@@ -273,3 +235,10 @@ void CVABinauralOutdoorWaveFront::setReceiver(CVABinauralClusteringDirectionRece
sound_receiver = receiver;
v3ReceiverPos = receiver->v3PredictedPosition; //set the position of the sound receiver
}
void CVABinauralOutdoorWaveFront::setITDDifference(const float itdDiff)
{
itdDifference = (int)round(itdDiff * oConf.sampleRate); //convert the ITD difference in seconds to samples
if (abs(itdDifference) + oConf.blockLength > oConf.BufferSize)
VA_EXCEPT1("ITD Differnce set is too large, increase the maximum buffersize for the outdoor renderer in the config file");
}
......@@ -119,6 +119,8 @@ public:
void setReceiver(CVABinauralClusteringDirectionReceiver* sound_receiver);
void setITDDifference(const float itdDiff);
virtual bool GetValidTrajectory() const
{
......@@ -161,6 +163,8 @@ private:
ITASampleBuffer tempBuffer;
ITASampleBuffer interpolatedSignal;
int itdDifference;
};
#endif // IW_VACORE_BINAURAL_OUTDOOR_WAVE_FRONT
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