Style update. Re-arranging WICK and CTC factor implementation.

parent 504bbe6e
......@@ -31,41 +31,41 @@ ITANCTC::ITANCTC( const Config& oNCTCConfig )
m_oHeadPose.vPos.SetToZeroVector();
m_oHeadPose.vView.SetValues( 0, 0, -1.0f );
m_oHeadPose.vUp.SetValues( 0, 1.0f, 0);
m_oHeadPose.vUp.SetValues( 0, 1.0f, 0 );
//m_oHeadPose.qOrient.SetToNeutralQuaternion();
m_sfCTC_temp.init( 2, m_oConfig.iCTCFilterLength, true );
int iDFTSize = m_oConfig.iCTCFilterLength+1;
for( int n=0; n<GetN(); n++ )
int iDFTSize = m_oConfig.iCTCFilterLength + 1;
for( int n = 0; n < GetN(); n++ )
{
m_vdWeights.push_back( 1.0f );
m_vpHRTFs.push_back( new ITAHDFTSpectra( m_oConfig.dSampleRate, 2, iDFTSize, true ) );
m_vfDelayTime.push_back( float( m_oConfig.iCTCFilterLength / m_oConfig.dSampleRate / 2.0f ) );
}
for( int i=0; i<2; i++ )
for( int i = 0; i < 2; i++ )
m_vpHelper2x2.push_back( new ITAHDFTSpectra( m_oConfig.dSampleRate, 2, iDFTSize, true ) );
t = new ITAHDFTSpectrum( m_oConfig.dSampleRate, iDFTSize, true );
det = new ITAHDFTSpectrum( m_oConfig.dSampleRate, iDFTSize, true );
int l = m_oConfig.iCTCFilterLength;
m_fft.plan( ITAFFT::FFT_R2C, l, m_sfCTC_temp[0].data(), (*m_vpHRTFs[0])[0]->data() );
m_ifft.plan( ITAFFT::IFFT_C2R, l, (*m_vpHRTFs[0])[0]->data(), m_sfCTC_temp[0].data() );
int l = m_oConfig.iCTCFilterLength;
m_fft.plan( ITAFFT::FFT_R2C, l, m_sfCTC_temp[ 0 ].data(), ( *m_vpHRTFs[ 0 ] )[ 0 ]->data() );
m_ifft.plan( ITAFFT::IFFT_C2R, l, ( *m_vpHRTFs[ 0 ] )[ 0 ]->data(), m_sfCTC_temp[ 0 ].data() );
}
ITANCTC::~ITANCTC()
{
for( int n=0; n<GetN(); n++ )
delete m_vpHRTFs[n];
for( int n = 0; n < GetN(); n++ )
delete m_vpHRTFs[ n ];
for( int i=0; i<2; i++ )
delete m_vpHelper2x2[i];
for( int i = 0; i < 2; i++ )
delete m_vpHelper2x2[ i ];
delete t, det;
return;
}
......@@ -81,21 +81,21 @@ int ITANCTC::GetN() const
void ITANCTC::UpdateHeadPose( const Pose& oHead )
{
m_oHeadPose = oHead;
m_oHeadPose = oHead;
return;
}
int ITANCTC::GetLoudspeakerSide(int iNumLoudspeaker)
int ITANCTC::GetLoudspeakerSide( int iNumLoudspeaker )
{
Pose oDest = GetLoudspeakerPose(iNumLoudspeaker);
Pose oDest = GetLoudspeakerPose( iNumLoudspeaker );
VistaVector3D vConn = oDest.vPos - m_oHeadPose.vPos;
double dDistanceMeters = double(vConn.GetLength());
float fLS2HeadDelaySamples = (float)dDistanceMeters / m_oConfig.fSpeedOfSound * (float)m_oConfig.dSampleRate;
double dDistanceMeters = double( vConn.GetLength() );
float fLS2HeadDelaySamples = ( float ) dDistanceMeters / m_oConfig.fSpeedOfSound * ( float ) m_oConfig.dSampleRate;
// 1/r attenuation due to distance law
// Note: Gain of HRIR dataset is normalized to 1 m according to convention
float fDistanceGain = 1 / (float)dDistanceMeters;
float fDistanceGain = 1 / ( float ) dDistanceMeters;
// @todo jst: mit VistaQuaternion lsen
/*
......@@ -116,12 +116,12 @@ int ITANCTC::GetLoudspeakerSide(int iNumLoudspeaker)
VistaVector3D vDir = oDest.vPos - m_oHeadPose.vPos;
vDir.Normalize();
VistaVector3D vViewMinusZ = m_oHeadPose.vView * (-1.0f); // local z axis
const VistaVector3D vRight = vViewMinusZ.Cross(m_oHeadPose.vUp); // local x axis
const double dAzimuthAngleDeg = atan2(vDir.Dot(vRight), vDir.Dot(m_oHeadPose.vView)) * 180.0f / ITAConstants::PI_D;
dPhiDeg = ((dAzimuthAngleDeg < 0.0f) ? (dAzimuthAngleDeg + 360.0f) : dAzimuthAngleDeg);
dThetaDeg = asin(vDir.Dot(m_oHeadPose.vUp)) * 180.0f / ITAConstants::PI_D;
if (dPhiDeg < 180)
VistaVector3D vViewMinusZ = m_oHeadPose.vView * ( -1.0f ); // local z axis
const VistaVector3D vRight = vViewMinusZ.Cross( m_oHeadPose.vUp ); // local x axis
const double dAzimuthAngleDeg = atan2( vDir.Dot( vRight ), vDir.Dot( m_oHeadPose.vView ) ) * 180.0f / ITAConstants::PI_D;
dPhiDeg = ( ( dAzimuthAngleDeg < 0.0f ) ? ( dAzimuthAngleDeg + 360.0f ) : dAzimuthAngleDeg );
dThetaDeg = asin( vDir.Dot( m_oHeadPose.vUp ) ) * 180.0f / ITAConstants::PI_D;
if( dPhiDeg < 180 )
{
return Config::Loudspeaker::LEFT_SIDE;
}
......@@ -129,7 +129,7 @@ int ITANCTC::GetLoudspeakerSide(int iNumLoudspeaker)
{
return Config::Loudspeaker::RIGHT_SIDE;
}
}
bool ITANCTC::AddHRIR( const Pose& oDest, ITASampleFrame& sfDestHRIR, bool& bOutOfRange, double dReflectionFactor/* = 1.0f */ ) const
......@@ -140,11 +140,11 @@ bool ITANCTC::AddHRIR( const Pose& oDest, ITASampleFrame& sfDestHRIR, bool& bOut
// Calculate sample delay of HRIR insertion position
VistaVector3D vConn = oDest.vPos - m_oHeadPose.vPos;
double dDistanceMeters = double( vConn.GetLength() );
float fLS2HeadDelaySamples = (float) dDistanceMeters / m_oConfig.fSpeedOfSound * (float) m_oConfig.dSampleRate;
float fLS2HeadDelaySamples = ( float ) dDistanceMeters / m_oConfig.fSpeedOfSound * ( float ) m_oConfig.dSampleRate;
// 1/r attenuation due to distance law
// Note: Gain of HRIR dataset is normalized to 1 m according to convention
float fDistanceGain = 1 / (float) dDistanceMeters;
float fDistanceGain = 1 / ( float ) dDistanceMeters;
// @todo jst: mit VistaQuaternion lsen
/*
......@@ -165,16 +165,16 @@ bool ITANCTC::AddHRIR( const Pose& oDest, ITASampleFrame& sfDestHRIR, bool& bOut
VistaVector3D vDir = oDest.vPos - m_oHeadPose.vPos;
vDir.Normalize();
VistaVector3D vViewMinusZ = m_oHeadPose.vView * (-1.0f); // local z axis
VistaVector3D vViewMinusZ = m_oHeadPose.vView * ( -1.0f ); // local z axis
const VistaVector3D vRight = vViewMinusZ.Cross( m_oHeadPose.vUp ); // local x axis
const double dAzimuthAngleDeg = atan2( vDir.Dot( vRight ), vDir.Dot( m_oHeadPose.vView ) ) * 180.0f / ITAConstants::PI_D;
dPhiDeg = ( ( dAzimuthAngleDeg < 0.0f ) ? ( dAzimuthAngleDeg + 360.0f ) : dAzimuthAngleDeg );
dThetaDeg = asin( vDir.Dot( m_oHeadPose.vUp ) ) * 180.0f / ITAConstants::PI_D;
int iHRIRPreOffset = m_pHRIR->getMinEffectiveFilterOffset();
int iHRIRFilerTaps = m_pHRIR->getMaxEffectiveFilterLength();
int iOffset = (std::max)( 0, int( fLS2HeadDelaySamples - iHRIRPreOffset ) ); // remove starting zeros from HRIR
int iOffset = ( std::max )( 0, int( fLS2HeadDelaySamples - iHRIRPreOffset ) ); // remove starting zeros from HRIR
iOffset = int( fLS2HeadDelaySamples ) + iHRIRPreOffset;
// Check against buffer overrun, prevent if necessary (PROBLEM: LS too far away for target filter)
......@@ -183,9 +183,9 @@ bool ITANCTC::AddHRIR( const Pose& oDest, ITASampleFrame& sfDestHRIR, bool& bOut
int iRecordIndex;
m_pHRIR->getNearestNeighbour( DAFF_OBJECT_VIEW, float( dPhiDeg ), float( dThetaDeg ), iRecordIndex, bOutOfRange );
m_pHRIR->addFilterCoeffs( iRecordIndex, 0, sfDestHRIR[0].data() + iOffset, fDistanceGain * float( dReflectionFactor ) );
m_pHRIR->addFilterCoeffs( iRecordIndex, 1, sfDestHRIR[1].data() + iOffset, fDistanceGain * float( dReflectionFactor ) );
m_pHRIR->addFilterCoeffs( iRecordIndex, 0, sfDestHRIR[ 0 ].data() + iOffset, fDistanceGain * float( dReflectionFactor ) );
m_pHRIR->addFilterCoeffs( iRecordIndex, 1, sfDestHRIR[ 1 ].data() + iOffset, fDistanceGain * float( dReflectionFactor ) );
return true;
}
......@@ -194,16 +194,16 @@ const ITANCTC::Pose& ITANCTC::GetLoudspeakerPose( int iLoudspeakerID ) const
if( iLoudspeakerID > GetN() )
ITA_EXCEPT1( INVALID_PARAMETER, "Loudspeaker ID (starting from 1) out of range." );
return m_oConfig.voLoudspeaker[iLoudspeakerID-1].oPose;
return m_oConfig.voLoudspeaker[ iLoudspeakerID - 1 ].oPose;
}
bool ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter )
{
if( !m_pHRIR )
return false;
bool bOutOfRange = false;
for( int n=0; n<GetN(); n++ )
for( int n = 0; n < GetN(); n++ )
{
m_sfCTC_temp.zero();
......@@ -211,135 +211,137 @@ bool ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter )
{
// Here comes more if ready ... see feature/room_compensation branch
case Config::OPTIMIZATION_NONE:
default:
if( AddHRIR( GetLoudspeakerPose( n+1 ), m_sfCTC_temp, bOutOfRange ) == false )
return false;
break;
default:
if( AddHRIR( GetLoudspeakerPose( n + 1 ), m_sfCTC_temp, bOutOfRange ) == false )
return false;
break;
}
if( bOutOfRange )
return false;
ITAHDFTSpectra* pHRTF( m_vpHRTFs[n] );
ITAHDFTSpectra* pHRTF( m_vpHRTFs[ n ] );
// Convert HRIRs to HRTFs
m_fft.execute( m_sfCTC_temp[0].data(), (*pHRTF)[0]->data() );
m_fft.execute( m_sfCTC_temp[1].data(), (*pHRTF)[1]->data() );
m_fft.execute( m_sfCTC_temp[ 0 ].data(), ( *pHRTF )[ 0 ]->data() );
m_fft.execute( m_sfCTC_temp[ 1 ].data(), ( *pHRTF )[ 1 ]->data() );
//pHRTF->Export( "BRIR_CalculateFilter_LS" + IntToString( n+1 ) );
}
/* Matrix to be inverted (as two-by-two row vector)
* a c
* b d
*/
ITAHDFTSpectrum* a = (*m_vpHelper2x2[0])[0];
ITAHDFTSpectrum* b = (*m_vpHelper2x2[0])[1];
ITAHDFTSpectrum* c = (*m_vpHelper2x2[1])[0];
ITAHDFTSpectrum* d = (*m_vpHelper2x2[1])[1];
ITAHDFTSpectrum* a = ( *m_vpHelper2x2[ 0 ] )[ 0 ];
ITAHDFTSpectrum* b = ( *m_vpHelper2x2[ 0 ] )[ 1 ];
ITAHDFTSpectrum* c = ( *m_vpHelper2x2[ 1 ] )[ 0 ];
ITAHDFTSpectrum* d = ( *m_vpHelper2x2[ 1 ] )[ 1 ];
// Least-squares minimization: C = WH*(HWH*-\beta)^-1
// using H* as the hermitian (complex conjugated) transpose of H
// @todo: jst/mko sweet spot widening ...
/* Sweet spot optimization: modify input HRTFs
* 1. Crosstalk side will be lowered by CTC factor
* 2. HRTF will be flattened by WICK factor
*/
// Prepare HRTF spectra
int iDFTSize = m_oConfig.iCTCFilterLength+1;
for( int n=0; n<GetN(); n++ )
int iDFTSize = m_oConfig.iCTCFilterLength + 1;
for( int n = 0; n < GetN(); n++ )
{
ITAHDFTSpectra* pHRTF( m_vpHRTFs[n] ); // two-channel
ITAHDFTSpectra* pHRTF( m_vpHRTFs[ n ] ); // two-channel
// Apply WIACF in cepstrum domain
// --- WICK factor ---
// First, store original energy of HRTF (left channel)
float fEnergy = ( *pHRTF )[ 0 ]->getEnergy();
// Apply WICK factor in cepstrum domain (left channel)
( *pHRTF )[ 0 ]->log();
( *pHRTF )[ 0 ]->mul( m_fWaveIncidenceAngleCompensationFactor );
( *pHRTF )[ 0 ]->exp();
// Compensate initial HRTF energy when WIACF is used
float fEnergy = ( *pHRTF )[ 0 ]->getEnergy();
// Compensate initial HRTF energy when WICK is used (left channel)
assert( fEnergy > 0 );
float fEnergyCompensation = powf( fEnergy, ( 1 - m_fWaveIncidenceAngleCompensationFactor ) );
( *pHRTF )[ 0 ]->mul( fEnergyCompensation );
// Apply WIACF in cepstrum domain
(*pHRTF)[1]->log();
(*pHRTF)[1]->mul(m_fWaveIncidenceAngleCompensationFactor);
(*pHRTF)[1]->exp();
// Compensate initial HRTF energy when WIACF is used
// First, store original energy of HRTF (right channel)
fEnergy = ( *pHRTF )[ 1 ]->getEnergy();
// Apply WICK factor in cepstrum domain (right channel)
( *pHRTF )[ 1 ]->log();
( *pHRTF )[ 1 ]->mul( m_fWaveIncidenceAngleCompensationFactor );
( *pHRTF )[ 1 ]->exp();
// Compensate initial HRTF energy when WICK is used (right channel)
assert( fEnergy > 0 );
fEnergyCompensation = powf( fEnergy, ( 1 - m_fWaveIncidenceAngleCompensationFactor ) );
( *pHRTF )[ 1 ]->mul( fEnergyCompensation );
// Weighting
float fWeight = float( m_vdWeights[n] ); // diag element
// --- CTC compensation factor + weighting ---
float fLeftChannel = 1;
float fRightChannel = 1;
// Weighting
float fWeight = float( m_vdWeights[ n ] ); // diag element
float fLeftChannelWICK = 1;
float fRightChannelWICK = 1;
// CTC compensation factors
int iLSSide = GetLoudspeakerSide( n + 1 );
float fRightChannelCTC = 1.0f;
if( iLSSide == Config::Loudspeaker::LEFT_SIDE )
fRightChannelCTC *= m_fCrossTalkCancellationFactor; // only apply to left channel if LS is at left side
float fLeftChannelCTC = 1.0f;
if( iLSSide == Config::Loudspeaker::RIGHT_SIDE )
fLeftChannelCTC *= m_fCrossTalkCancellationFactor; // only apply to right channel if LS is at right side
if (GetLoudspeakerSide(n) == Config::Loudspeaker::LEFT_SIDE)
{
fRightChannel *= m_fCrossTalkCancellationFactor;
//fLeftChannelWICK *= m_fWaveIncidenceAngleCompensationFactor;
}
else if (GetLoudspeakerSide(n) == Config::Loudspeaker::RIGHT_SIDE)
{
fLeftChannel *= m_fCrossTalkCancellationFactor;
//fRightChannelWICK *= m_fWaveIncidenceAngleCompensationFactor;
}
// Element wise (a and d): HWH* -> 2x2
t->copy( (*pHRTF)[0] );
t->mul( fWeight*fLeftChannel );
//t->log();
//t->mul(m_fCrossTalkCancellationFactor);
//t->exp();
t->mul_conj( (*pHRTF)[0] );
t->copy( ( *pHRTF )[ 0 ] );
t->mul( fWeight * fLeftChannelCTC );
t->mul_conj( ( *pHRTF )[ 0 ] );
n == 0 ? a->copy( t ) : a->add( t );
t->copy( (*pHRTF)[1] );
t->mul( fWeight*fRightChannel );
/*t->log();
t->mul(m_fCrossTalkCancellationFactor);
t->exp();
*/
t->mul_conj( (*pHRTF)[1] );
t->copy( ( *pHRTF )[ 1 ] );
t->mul( fWeight * fRightChannelCTC );
t->mul_conj( ( *pHRTF )[ 1 ] );
n == 0 ? d->copy( t ) : d->add( t );
// Cross elements (b and c): HWH*
t->copy( (*pHRTF)[1] );
t->mul( fWeight*fRightChannel );
/*t->log();
t->mul(m_fCrossTalkCancellationFactor);
t->exp();*/
t->copy( ( *pHRTF )[ 1 ] );
t->mul( fWeight * fRightChannelCTC );
t->mul_conj( (*pHRTF)[0] );
t->mul_conj( ( *pHRTF )[ 0 ] );
n == 0 ? b->copy( t ) : b->add( t );
t->copy( (*pHRTF)[0] );
t->mul( fWeight*fLeftChannel );
/*t->log();
t->mul(m_fCrossTalkCancellationFactor);
t->exp();
*/
t->mul_conj( (*pHRTF)[1] );
t->copy( ( *pHRTF )[ 0 ] );
t->mul( fWeight * fLeftChannelCTC );
t->mul_conj( ( *pHRTF )[ 1 ] );
n == 0 ? c->copy( t ) : c->add( t );
}
// Regularize
a->add( m_fBeta );
d->add( m_fBeta );
ITAHDFTSpectra abcd( m_oConfig.dSampleRate, 4, m_oConfig.iCTCFilterLength );
abcd[0]->copyFrom( *a );
abcd[1]->copyFrom( *b );
abcd[2]->copyFrom( *c );
abcd[3]->copyFrom( *d );
abcd[ 0 ]->copyFrom( *a );
abcd[ 1 ]->copyFrom( *b );
abcd[ 2 ]->copyFrom( *c );
abcd[ 3 ]->copyFrom( *d );
// Invert via determinant
// Invert via determinant (simple 2x2 matrix inversion)
/*
* d/det -b/det
* -c/det a/det
......@@ -362,56 +364,51 @@ bool ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter )
// Calculate CTC filter WH*Inv (Nx2)
ITASampleFrame sfTargetData_shift( m_sfCTC_temp.channels(), m_sfCTC_temp.length(), true );
for( int n=0; n<GetN(); n++ )
for( int n = 0; n < GetN(); n++ )
{
float fLeftChannel = 1;
float fRightChannel = 1;
// Again, apply CTC compensation factors
int iLSSide = GetLoudspeakerSide( n + 1 );
float fLeftChannelWICK = 1;
float fRightChannelWICK = 1;
float fRightChannelCTC = 1.0f;
if( iLSSide == Config::Loudspeaker::LEFT_SIDE )
fRightChannelCTC *= m_fCrossTalkCancellationFactor;
if (GetLoudspeakerSide(n) == Config::Loudspeaker::LEFT_SIDE)
{
fRightChannel *= m_fCrossTalkCancellationFactor;
fLeftChannelWICK *= m_fWaveIncidenceAngleCompensationFactor;
}
else if (GetLoudspeakerSide(n) == Config::Loudspeaker::RIGHT_SIDE)
{
fLeftChannel *= m_fCrossTalkCancellationFactor;
fRightChannelWICK *= m_fWaveIncidenceAngleCompensationFactor;
}
float fLeftChannelCTC = 1.0f;
if( iLSSide == Config::Loudspeaker::RIGHT_SIDE )
fLeftChannelCTC *= m_fCrossTalkCancellationFactor;
ITAHDFTSpectra* pHRTF( m_vpHRTFs[n] ); // two-channel
ITAHDFTSpectra* pCTCFilter( vpCTCFilter[n] ); // two-channel
float fWeight = float( m_vdWeights[n] ); // diag element
ITAHDFTSpectra* pHRTF( m_vpHRTFs[ n ] ); // two-channel, already WICKed
ITAHDFTSpectra* pCTCFilter( vpCTCFilter[ n ] ); // two-channel
float fWeight = float( m_vdWeights[ n ] ); // diag element
t->copy( a );
t->mul_conj( (*pHRTF)[0] );
t->mul( fWeight*fLeftChannel );
(*pCTCFilter)[0]->copy( t );
t->mul_conj( ( *pHRTF )[ 0 ] );
t->mul( fWeight * fLeftChannelCTC );
( *pCTCFilter )[ 0 ]->copy( t );
t->copy( b );
t->mul_conj( (*pHRTF)[1] );
t->mul( fWeight*fRightChannel );
(*pCTCFilter)[0]->add( t );
t->mul_conj( ( *pHRTF )[ 1 ] );
t->mul( fWeight * fRightChannelCTC );
( *pCTCFilter )[ 0 ]->add( t );
t->copy( c );
t->mul_conj( (*pHRTF)[0] );
t->mul( fWeight*fLeftChannel );
(*pCTCFilter)[1]->copy( t );
t->mul_conj( ( *pHRTF )[ 0 ] );
t->mul( fWeight * fLeftChannelCTC );
( *pCTCFilter )[ 1 ]->copy( t );
t->copy( d );
t->mul_conj( (*pHRTF)[1] );
t->mul( fWeight*fRightChannel );
(*pCTCFilter)[1]->add( t );
t->mul_conj( ( *pHRTF )[ 1 ] );
t->mul( fWeight * fRightChannelCTC );
( *pCTCFilter )[ 1 ]->add( t );
//pCTCFilter->Export( "CTCFilter_noshift_" + IntToString( n+1 ) );
// Time-shift
m_ifft.execute( (*pCTCFilter)[0]->data(), m_sfCTC_temp[0].data() );
m_ifft.execute( (*pCTCFilter)[1]->data(), m_sfCTC_temp[1].data() );
m_ifft.execute( ( *pCTCFilter )[ 0 ]->data(), m_sfCTC_temp[ 0 ].data() );
m_ifft.execute( ( *pCTCFilter )[ 1 ]->data(), m_sfCTC_temp[ 1 ].data() );
// Normalize after IFFT
m_sfCTC_temp.div_scalar( float( m_sfCTC_temp.length() ) );
......@@ -421,7 +418,7 @@ bool ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter )
if( m_vfDelayTime[ n ] < 0.0f )
iShiftSamples = m_sfCTC_temp.length() / 2; // if invalid, shift by half length
sfTargetData_shift.cyclic_write( m_sfCTC_temp, m_sfCTC_temp.length(), 0, iShiftSamples );
m_fft.execute( sfTargetData_shift[ 0 ].data(), ( *pCTCFilter )[ 0 ]->data() );
m_fft.execute( sfTargetData_shift[ 1 ].data(), ( *pCTCFilter )[ 1 ]->data() );
......@@ -441,36 +438,36 @@ void ITANCTC::SetHRIR( const DAFFContentIR* pHRIR )
m_pHRIR = pHRIR;
// Return if HRIR is reset (NULL)
if (!m_pHRIR)
if( !m_pHRIR )
return;
if (m_pHRIR->getProperties()->getNumberOfChannels() != 2)
ITA_EXCEPT1(INVALID_PARAMETER, "HRIR dataset must have exactly two channels");
if( m_pHRIR->getProperties()->getNumberOfChannels() != 2 )
ITA_EXCEPT1( INVALID_PARAMETER, "HRIR dataset must have exactly two channels" );
// Get HRIR filter length
if( m_pHRIR->getFilterLength() > m_oConfig.iCTCFilterLength )
ITA_EXCEPT1(INVALID_PARAMETER,
std::string("The filter length of the HRIR database \"") + m_pHRIR->getParent()->getFilename() +
std::string("\" is larger than the CTC filters. This leads to buffer overruns."));
ITA_EXCEPT1( INVALID_PARAMETER,
std::string( "The filter length of the HRIR database \"" ) + m_pHRIR->getParent()->getFilename() +
std::string( "\" is larger than the CTC filters. This leads to buffer overruns." ) );
// Get HRIR delay samples
const DAFFMetadata* pHRIRMetadata = m_pHRIR->getParent()->getMetadata();
if (!pHRIRMetadata->hasKey("DELAY_SAMPLES"))
ITA_EXCEPT1(INVALID_PARAMETER,
std::string("HRIR database \"") + m_pHRIR->getParent()->getFilename() +
std::string("\" is missing a \"DELAY_SAMPLES\" metadata tag"));
if ((pHRIRMetadata->getKeyType("DELAY_SAMPLES") != DAFFMetadata::DAFF_INT) &&
(pHRIRMetadata->getKeyType("DELAY_SAMPLES") != DAFFMetadata::DAFF_FLOAT))
ITA_EXCEPT1(INVALID_PARAMETER,
std::string("The metadata tag \"DELAY_SAMPLES\" in HRIR database \"") + m_pHRIR->getParent()->getFilename() +
std::string("\" is not numeric"));
float fHRIRDelay = (float) pHRIRMetadata->getKeyFloat("DELAY_SAMPLES");
if( !pHRIRMetadata->hasKey( "DELAY_SAMPLES" ) )
ITA_EXCEPT1( INVALID_PARAMETER,
std::string( "HRIR database \"" ) + m_pHRIR->getParent()->getFilename() +
std::string( "\" is missing a \"DELAY_SAMPLES\" metadata tag" ) );
if( ( pHRIRMetadata->getKeyType( "DELAY_SAMPLES" ) != DAFFMetadata::DAFF_INT ) &&
( pHRIRMetadata->getKeyType( "DELAY_SAMPLES" ) != DAFFMetadata::DAFF_FLOAT ) )
ITA_EXCEPT1( INVALID_PARAMETER,
std::string( "The metadata tag \"DELAY_SAMPLES\" in HRIR database \"" ) + m_pHRIR->getParent()->getFilename() +
std::string( "\" is not numeric" ) );
float fHRIRDelay = ( float ) pHRIRMetadata->getKeyFloat( "DELAY_SAMPLES" );
if( fHRIRDelay < 0 )
ITA_EXCEPT1(INVALID_PARAMETER,
std::string("The metadata tag \"DELAY_SAMPLES\" in HRIR database \"") + m_pHRIR->getParent()->getFilename() +
std::string("\" must not be negative"));
ITA_EXCEPT1( INVALID_PARAMETER,
std::string( "The metadata tag \"DELAY_SAMPLES\" in HRIR database \"" ) + m_pHRIR->getParent()->getFilename() +
std::string( "\" must not be negative" ) );
}
......@@ -557,8 +554,8 @@ ITANCTC::Pose ITANCTC::GetHeadPose() const
// --- Loudspeaker ---
ITANCTC::Config::Loudspeaker::Loudspeaker()
: pDirectivity(NULL)
, iSide( SIDE_NOT_SPECIFIED )
: pDirectivity( NULL )
, iSide( SIDE_NOT_SPECIFIED )
{
}
......@@ -588,9 +585,9 @@ void ITANCTC::Pose::SetOrientationYPRdeg( double fYaw, double fPitch, double fRo
double pitch = grad2rad( fPitch );
double roll = grad2rad( fRoll );
double sy = sin(yaw), cy = cos(yaw);
double sp = sin(pitch), cp = cos(pitch);
double sr = sin(roll), cr = cos(roll);
double sy = sin( yaw ), cy = cos( yaw );
double sp = sin( pitch ), cp = cos( pitch );
double sr = sin( roll ), cr = cos( roll );
vView.SetValues( -sy*cp, sp, -cy*cp );
vUp.SetValues( cy*sr + sy*sp*cr, cp*cr, -sy*sr + cy*sp*cr );
......
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