Refactoring NCTC

parent 74a0c562
......@@ -88,7 +88,7 @@ public:
/**
* \note All angles in degrees [°]
*/
void SetOrientationYPRdeg( double fYaw, double fPitch, double fRoll );
void SetOrientationYPRdeg( const float fYaw, const float fPitch, const float fRoll );
//! Get YPR angles
void GetOrientationYPRdeg( float& fYaw, float& fPitch, float& fRoll ) const;
......@@ -122,6 +122,7 @@ public:
int iOptimization; //!< Optimization algorithm (future work, see features/room_compensation)
float fCrossTalkCancellationFactor; //!< Factor for cross-talk cancellation (none = 0.0, full = 1.0)
float fWaveIncidenceAngleCompensationFactor; //!< Factor for cross-talk cancellation (none = 0.0, full = 1.0)
float fRegularizationFactor; //!< Regularization factor (beta)
class ITA_CTC_API Loudspeaker
{
......@@ -149,9 +150,9 @@ public:
* through the configuration's SelectedSpeakers list. The configuration may have more
* loudspeakers defined than are selected in the end.
*
* \note Throws ITAException errors
* @note Throws ITAException errors
*
* \param oNCTCConfig The configuration, see \Config
* @param[in] oNCTCConfig The configuration, see @Config
*
*/
ITANCTC( const Config& oNCTCConfig );
......@@ -159,12 +160,12 @@ public:
//! Destructor
~ITANCTC();
//! Get the number of loudspeaker for this CTC enginge
//! Get the number of loudspeakers/channels for this CTC engine
/**
* \return number of channels (N)
* @return Number of channels (N)
*
*/
int GetN() const;
int GetNumChannels() const;
//! Configuration getter
/**
......@@ -173,47 +174,47 @@ public:
const Config& GetConfig() const;
//! Get beta parameter
//! Get regularization factor (beta)
/**
* \return Beta parameter
*/
float GetBeta();
* @return Regularization factor
*/
float GetRegularizationFactor() const;
//! Set beta parameter
//! Set regularization factor
/**
* \param fBeta Set the beta regularization parameter
*/
void SetBeta( float fBeta );
* @param fRegularizationFator Set the regularization factor (beta)
*/
void SetRegularizationFactor( const float fRegularizationFator );
//! Get cross-talk cancellation factor
/**
* \return Factor [0..1]
*/
float GetCrossTalkCancellationFactor();
float GetCrossTalkCancellationFactor() const;
//! Set cross-talk cancellation factor
/**
* \param fFactor number between [0..1] (none: 0, max range = 1.0)
*/
void SetCrossTalkCancellationFactor( float fFactor );
void SetCrossTalkCancellationFactor( const float fFactor );
//! Get cross-talk cancellation factor
/**
* \return Factor [0..1]
*/
float GetWaveIncidenceAngleCompensation();
float GetWaveIncidenceAngleCompensation() const;
//! Set cross-talk cancellation factor
/**
* \param fFactor number between [0..1] (none: 0, max range = 1.0)
*/
void SetWaveIncidenceAngleCompensationFactor( float fFactor );
void SetWaveIncidenceAngleCompensationFactor( const float fFactor );
//! Get additional delay parameter
/**
* \return Delay in seconds
*/
std::vector< float > GetDelayTime();
std::vector< float > GetDelayTime() const;
//! Set additional delay parameter in seconds (affects all channels)
/**
......@@ -223,7 +224,7 @@ public:
*
* @param fDelayTime Set the time delay (all channels)
*/
void SetDelayTime( float fDelayTime );
void SetDelayTime( const float fDelayTime );
//! Set delay parameter in seconds for each loudspeaker channel individually
/**
......@@ -234,13 +235,13 @@ public:
*
* \param vfDelayTime Set the time delay (each channel/loudspeaker individually)
*/
void SetDelayTime( std::vector< float > vfDelayTime );
void SetDelayTime( const std::vector< float >& vfDelayTime );
//! Sets the optimization
/**
* Optimization setter, i.e. early reflection compensation for aixCAVE (see enum of Config)
*/
void SetOptimization( int iOptimization );
void SetOptimization( const int iOptimization );
//! Optimization getter
/**
......@@ -254,7 +255,7 @@ public:
* \return Returns the pose of a loudspeaker
*/
const Pose& GetLoudspeakerPose( int iLoudspeakerID ) const;
const Pose& GetLoudspeakerPose( const int iLoudspeakerID ) const;
//! Set HRIR dataset
/**
......@@ -302,18 +303,18 @@ public:
void CalculateFilter( std::vector< ITAHDFTSpectra* >& vpSpectra ) const;
//! Calculate the Wiener-Hopf factorization
void WienerHopfFactorization( ITAHDFTSpectrum* voSpecIn, ITAHDFTSpectrum* voSpecOutPlus, ITAHDFTSpectrum* voSpecOutMinus );
void WienerHopfFactorization( const ITAHDFTSpectrum* voSpecIn, ITAHDFTSpectrum* voSpecOutPlus, ITAHDFTSpectrum* voSpecOutMinus );
protected:
private:
const Config m_oConfig; //!< CTC Configuration
std::atomic< float > m_fBeta; //!< Beta parameter (regularization)
std::vector< float > m_vfDelayTime; //!< Add a delay [seconds] to the resulting CTC filter (individual channels)
std::atomic <int > m_iOptimization; //!< Optimization (see Config enum)
std::atomic< float > m_fCrossTalkCancellationFactor; //!< Factor for cross-talk cancellation (none = 0.0, full = 1.0)
std::atomic< float > m_fWaveIncidenceAngleCompensationFactor; //!< Factor for cross-talk cancellation (none = 0.0, full = 1.0)
mutable std::atomic< float > m_fRegularizationFactor; //!< Beta parameter (regularization)
mutable std::vector< float > m_vfDelayTime; //!< Add a delay [seconds] to the resulting CTC filter (individual channels)
std::atomic< int > m_iOptimization; //!< Optimization (see Config enum)
mutable std::atomic< float > m_fCrossTalkCancellationFactor; //!< Factor for cross-talk cancellation (none = 0.0, full = 1.0)
mutable std::atomic< float > m_fWaveIncidenceAngleCompensationFactor; //!< Factor for cross-talk cancellation (none = 0.0, full = 1.0)
const DAFFContentIR* m_pHRIR; //!< HRIR dataset pointer
Pose m_oHeadPose; //!< Current head Pose data
......@@ -321,13 +322,13 @@ private:
mutable ITAFFT m_fft, m_ifft; //!< Internal FFT and IFFT transformations
mutable ITASampleFrame m_sfCTC_temp; //!< Internal CTC helper
std::vector< double > m_vdWeights; //!< Diagonal values for the weighting matrix (W or Z), only non-zero entries allowed
std::vector< float > m_vfWeights; //!< Diagonal values for the weighting matrix (W or Z), only non-zero entries allowed
std::vector< ITAHDFTSpectra* > m_vpHRTFs; //!< N-dim vector with two-channel HRTF sets for each LS direction
std::vector< ITAHDFTSpectra* > m_vpHelper2x2; //!< Two-by-two helper matrix
ITAHDFTSpectrum* t; //!< Helper
ITAHDFTSpectrum* det; //!< Helper
int GetLoudspeakerSide( int ) const;
int GetLoudspeakerSide( const int ) const;
//! Adds a HRIR into the target filter
/**
......
......@@ -18,26 +18,25 @@ ITANCTC::ITANCTC( const Config& oNCTCConfig )
: m_oConfig( oNCTCConfig )
, m_pHRIR( NULL )
{
m_fBeta = float( 1e-4 );
if( oNCTCConfig.N <= 0 )
ITA_EXCEPT1( INVALID_PARAMETER, "Wrong configuration, N-CTC requires a valid number of loudspeakers" );
m_iOptimization = m_oConfig.iOptimization;
m_fCrossTalkCancellationFactor = m_oConfig.fCrossTalkCancellationFactor;
m_fWaveIncidenceAngleCompensationFactor = m_oConfig.fWaveIncidenceAngleCompensationFactor;
m_fRegularizationFactor = oNCTCConfig.fRegularizationFactor;
m_oHeadPose.vPos.SetToZeroVector();
m_oHeadPose.vView.SetValues( 0, 0, -1.0f );
m_oHeadPose.vUp.SetValues( 0, 1.0f, 0 );
//m_oHeadPose.qOrient.SetToNeutralQuaternion();
m_sfCTC_temp.init( 2, m_oConfig.iCTCFilterLength, true );
m_sfCTC_temp.Init( 2, m_oConfig.iCTCFilterLength, true );
int iDFTSize = m_oConfig.iCTCFilterLength + 1;
for( int n = 0; n < GetN(); n++ )
for( int n = 0; n < GetNumChannels(); n++ )
{
m_vdWeights.push_back( 1.0f );
m_vfWeights.push_back( 1.0f );
m_vpHRTFs.push_back( new ITAHDFTSpectra( m_oConfig.fSampleRate, 2, iDFTSize, true ) );
m_vfDelayTime.push_back( float( m_oConfig.iCTCFilterLength ) / m_oConfig.fSampleRate / 2.0f );
}
......@@ -48,15 +47,14 @@ ITANCTC::ITANCTC( const Config& oNCTCConfig )
t = new ITAHDFTSpectrum( m_oConfig.fSampleRate, iDFTSize, true );
det = new ITAHDFTSpectrum( m_oConfig.fSampleRate, 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() );
m_fft.plan( ITAFFT::FFT_R2C, m_oConfig.iCTCFilterLength, m_sfCTC_temp[ 0 ].GetData(), ( *m_vpHRTFs[ 0 ] )[ 0 ]->data() );
m_ifft.plan( ITAFFT::IFFT_C2R, m_oConfig.iCTCFilterLength, ( *m_vpHRTFs[ 0 ] )[ 0 ]->data(), m_sfCTC_temp[ 0 ].GetData() );
}
ITANCTC::~ITANCTC()
{
for( int n = 0; n < GetN(); n++ )
for( int n = 0; n < GetNumChannels(); n++ )
delete m_vpHRTFs[ n ];
for( int i = 0; i < 2; i++ )
......@@ -72,7 +70,7 @@ const ITANCTC::Config& ITANCTC::GetConfig() const
return m_oConfig;
}
int ITANCTC::GetN() const
int ITANCTC::GetNumChannels() const
{
return m_oConfig.N;
}
......@@ -84,7 +82,7 @@ void ITANCTC::UpdateHeadPose( const Pose& oHead )
return;
}
int ITANCTC::GetLoudspeakerSide( int iNumLoudspeaker ) const
int ITANCTC::GetLoudspeakerSide( const int iNumLoudspeaker ) const
{
Pose oDest = GetLoudspeakerPose( iNumLoudspeaker );
......@@ -105,7 +103,6 @@ int ITANCTC::GetLoudspeakerSide( int iNumLoudspeaker ) const
{
return Config::Loudspeaker::RIGHT_SIDE;
}
}
void ITANCTC::AddHRIR( const Pose& oDest, ITASampleFrame& sfDestHRIR, bool& bOutOfRange, const double dReflectionFactor/* = 1.0f */, const int iDistanceCompensationSamples /* = 0 */ ) const
......@@ -114,7 +111,7 @@ void ITANCTC::AddHRIR( const Pose& oDest, ITASampleFrame& sfDestHRIR, bool& bOut
ITA_EXCEPT1( INVALID_PARAMETER, "Two channel HRIR expected" );
if( !m_pHRIR )
ITA_EXCEPT1( MODAL_EXCEPTION, "HRIR missing" );
// Calculate sample delay of HRIR insertion position
VistaVector3D v3Conn = oDest.vPos - m_oHeadPose.vPos;
double dDistanceMeters = double( v3Conn.GetLength() );
......@@ -150,9 +147,9 @@ void ITANCTC::AddHRIR( const Pose& oDest, ITASampleFrame& sfDestHRIR, bool& bOut
return;
}
const ITANCTC::Pose& ITANCTC::GetLoudspeakerPose( int iLoudspeakerID ) const
const ITANCTC::Pose& ITANCTC::GetLoudspeakerPose( const int iLoudspeakerID ) const
{
if( iLoudspeakerID > GetN() )
if( iLoudspeakerID > GetNumChannels() )
ITA_EXCEPT1( INVALID_PARAMETER, "Loudspeaker ID (starting from 1) out of range." );
return m_oConfig.voLoudspeaker[ iLoudspeakerID - 1 ].oPose;
......@@ -163,11 +160,11 @@ void ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter ) con
if( !m_pHRIR )
ITA_EXCEPT1( MODAL_EXCEPTION, "CTC filters could not be created because HRIR is not set" );
float fMinDistance = GetMinimumDistanceHead2LS();
int iMinDistanceCompensationSamples = int( fMinDistance / m_oConfig.fSpeedOfSound * m_oConfig.fSampleRate );
const float fMinDistance = GetMinimumDistanceHead2LS();
const int iMinDistanceCompensationSamples = int( fMinDistance / m_oConfig.fSpeedOfSound * m_oConfig.fSampleRate );
bool bOutOfRange = false;
for( int n = 0; n < GetN(); n++ )
for( int n = 0; n < GetNumChannels(); n++ )
{
m_sfCTC_temp.zero();
......@@ -186,8 +183,8 @@ void ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter ) con
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 ].GetData(), ( *pHRTF )[ 0 ]->data() );
m_fft.execute( m_sfCTC_temp[ 1 ].GetData(), ( *pHRTF )[ 1 ]->data() );
#ifdef NCTC_EXPORT_FILTER_TO_HARDDRIVE
ITAFFTUtils::Export(pHRTF, "HRIR_LS" + IntToString(n + 1) + "_RAW");
......@@ -214,7 +211,7 @@ void ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter ) con
// Prepare HRTF spectra
for( int n = 0; n < GetN(); n++ )
for( int n = 0; n < GetNumChannels(); n++ )
{
ITAHDFTSpectra* pHRTF( m_vpHRTFs[ n ] ); // two-channel
......@@ -222,7 +219,7 @@ void ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter ) con
// --- WICK factor ---
// First, store original energy of HRTF (left channel)
float fEnergy = ( *pHRTF )[ 0 ]->getEnergy();
const float fEnergyLeftChannel = ( *pHRTF )[ 0 ]->getEnergy();
// Apply WICK factor only on magnitudes (left channel)
for( int i = 0; i < ( *pHRTF )[ 0 ]->getSize(); i++ )
......@@ -232,13 +229,13 @@ void ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter ) con
}
// Compensate initial HRTF energy when WICK is used (left channel)
assert( fEnergy > 0 );
float fEnergyCompensation = std::pow( fEnergy, ( 1 - m_fWaveIncidenceAngleCompensationFactor ) );
( *pHRTF )[ 0 ]->mul( fEnergyCompensation );
assert( fEnergyLeftChannel > 0 );
const float fEnergyCompensationLeftChannel = std::pow( fEnergyLeftChannel, ( 1 - m_fWaveIncidenceAngleCompensationFactor ) );
( *pHRTF )[ 0 ]->mul( fEnergyCompensationLeftChannel );
// First, store original energy of HRTF only on magnitudes (right channel)
fEnergy = ( *pHRTF )[ 1 ]->getEnergy();
const float fEnergyRightChannel = ( *pHRTF )[ 1 ]->getEnergy();
// Apply WICK factor only on magnitude (right channel)
for( int i = 0; i < ( *pHRTF )[ 1 ]->getSize(); i++ )
......@@ -248,9 +245,9 @@ void ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter ) con
}
// Compensate initial HRTF energy when WICK is used (right channel)
assert( fEnergy > 0 );
fEnergyCompensation = std::pow( fEnergy, ( 1 - m_fWaveIncidenceAngleCompensationFactor ) );
( *pHRTF )[ 1 ]->mul( fEnergyCompensation );
assert( fEnergyRightChannel > 0 );
const float fEnergyCompensationRightChannel = std::pow( fEnergyRightChannel, ( 1 - m_fWaveIncidenceAngleCompensationFactor ) );
( *pHRTF )[ 1 ]->mul( fEnergyCompensationRightChannel );
#ifdef NCTC_EXPORT_FILTER_TO_HARDDRIVE
......@@ -259,7 +256,7 @@ void ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter ) con
// --- CTC compensation factor ---
// CTC compensation factors
int iLSSide = GetLoudspeakerSide( n + 1 );
const int iLSSide = GetLoudspeakerSide( n + 1 );
float fRightChannelCTC = 1.0f;
if( iLSSide == Config::Loudspeaker::LEFT_SIDE )
......@@ -277,7 +274,7 @@ void ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter ) con
#endif // NCTC_EXPORT_FILTER_TO_HARDDRIVE
// --- Weighting ---
float fWeight = float( m_vdWeights[ n ] ); // diag element
const float& fWeight( m_vfWeights[ n ] ); // diag element
// Element wise (a and d): HWH* -> 2x2
t->copy( ( *pHRTF )[ 0 ] );
......@@ -309,8 +306,8 @@ void ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter ) con
// Regularize
a->add( m_fBeta );
d->add( m_fBeta );
a->add( m_fRegularizationFactor );
d->add( m_fRegularizationFactor );
ITAHDFTSpectra abcd( m_oConfig.fSampleRate, 4, m_oConfig.iCTCFilterLength );
abcd[ 0 ]->copyFrom( *a );
......@@ -343,13 +340,13 @@ void ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter ) con
// Calculate CTC filter WH*Inv (Nx2)
ITASampleFrame sfTargetData_shift( m_sfCTC_temp.channels(), m_sfCTC_temp.length(), true );
ITASampleFrame sfTargetData_shift( m_sfCTC_temp.GetNumChannels(), m_sfCTC_temp.GetLength(), true );
for( int n = 0; n < GetN(); n++ )
for( int n = 0; n < GetNumChannels(); n++ )
{
ITAHDFTSpectra* pHRTF( m_vpHRTFs[ n ] ); // two-channel, already WICKed
ITAHDFTSpectra* pCTCFilter( vpCTCFilter[ n ] ); // two-channel
float fWeight = float( m_vdWeights[ n ] ); // diag element
const float& fWeight( m_vfWeights[ n ] ); // diag element
t->copy( a );
t->mul_conj( ( *pHRTF )[ 0 ] );
......@@ -376,20 +373,20 @@ void ITANCTC::CalculateFilter( std::vector< ITAHDFTSpectra* >& vpCTCFilter ) con
// 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 ].GetData() );
m_ifft.execute( ( *pCTCFilter )[ 1 ]->data(), m_sfCTC_temp[ 1 ].GetData() );
// Normalize after IFFT
m_sfCTC_temp.div_scalar( float( m_sfCTC_temp.length() ) );
m_sfCTC_temp.div_scalar( float( m_sfCTC_temp.GetLength() ) );
// Shift the CTC filter according to desired delay
int iShiftSamples = int( m_oConfig.fSampleRate * m_vfDelayTime[ n ] );
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 );
iShiftSamples = m_sfCTC_temp.GetLength() / 2; // if invalid, shift by half length
sfTargetData_shift.cyclic_write( m_sfCTC_temp, m_sfCTC_temp.GetLength(), 0, iShiftSamples );
m_fft.execute( sfTargetData_shift[ 0 ].data(), ( *pCTCFilter )[ 0 ]->data() );
m_fft.execute( sfTargetData_shift[ 1 ].data(), ( *pCTCFilter )[ 1 ]->data() );
m_fft.execute( sfTargetData_shift[ 0 ].GetData(), ( *pCTCFilter )[ 0 ]->data() );
m_fft.execute( sfTargetData_shift[ 1 ].GetData(), ( *pCTCFilter )[ 1 ]->data() );
#ifdef NCTC_EXPORT_FILTER_TO_HARDDRIVE
ITAFFTUtils::Export(pCTCFilter, "CTCFilter_shift_" + IntToString(n + 1));
......@@ -437,65 +434,63 @@ void ITANCTC::SetHRIR( const DAFFContentIR* pHRIR )
ITA_EXCEPT1( INVALID_PARAMETER,
std::string( "The metadata tag \"DELAY_SAMPLES\" in HRIR database \"" ) + m_pHRIR->getParent()->getFilename() +
std::string( "\" must not be negative" ) );
}
}
void ITANCTC::SetBeta( float fBeta )
void ITANCTC::SetRegularizationFactor( const float fRegularizationFactor )
{
m_fBeta = fBeta;
m_fRegularizationFactor = fRegularizationFactor;
}
float ITANCTC::GetBeta()
float ITANCTC::GetRegularizationFactor() const
{
return m_fBeta;
return m_fRegularizationFactor;
}
void ITANCTC::SetCrossTalkCancellationFactor( float fFactor )
void ITANCTC::SetCrossTalkCancellationFactor( const float fFactor )
{
m_fCrossTalkCancellationFactor = fFactor;
}
float ITANCTC::GetCrossTalkCancellationFactor()
float ITANCTC::GetCrossTalkCancellationFactor() const
{
return m_fCrossTalkCancellationFactor;
}
void ITANCTC::SetWaveIncidenceAngleCompensationFactor( float fFactor )
void ITANCTC::SetWaveIncidenceAngleCompensationFactor( const float fFactor )
{
m_fWaveIncidenceAngleCompensationFactor = fFactor;
}
float ITANCTC::GetWaveIncidenceAngleCompensation()
float ITANCTC::GetWaveIncidenceAngleCompensation() const
{
return m_fWaveIncidenceAngleCompensationFactor;
}
void ITANCTC::SetDelayTime( float fDelayTime )
void ITANCTC::SetDelayTime( const float fDelayTime )
{
for( int n = 0; n < GetN(); n++ )
for( int n = 0; n < GetNumChannels(); n++ )
m_vfDelayTime[ n ] = fDelayTime;
}
void ITANCTC::SetDelayTime( std::vector< float > vfDelayTime )
void ITANCTC::SetDelayTime( const std::vector< float >& vfDelayTime )
{
if( int( vfDelayTime.size() ) != GetN() )
if( int( vfDelayTime.size() ) != GetNumChannels() )
ITA_EXCEPT1( INVALID_PARAMETER, "Provide as many delay values as channels for NCTC" );
for( int n = 0; n < GetN(); n++ )
for( int n = 0; n < GetNumChannels(); n++ )
m_vfDelayTime[ n ] = vfDelayTime[ n ];
}
std::vector< float > ITANCTC::GetDelayTime()
std::vector< float > ITANCTC::GetDelayTime() const
{
std::vector< float > vfDelayTime( GetN() );
for( int n = 0; n < GetN(); n++ )
std::vector< float > vfDelayTime( GetNumChannels() );
for( int n = 0; n < GetNumChannels(); n++ )
vfDelayTime[ n ] = m_vfDelayTime[ n ];
return vfDelayTime;
}
void ITANCTC::SetOptimization( int iOptimization )
void ITANCTC::SetOptimization( const int iOptimization )
{
m_iOptimization = iOptimization;
}
......@@ -519,16 +514,16 @@ ITANCTC::Pose ITANCTC::GetHeadPose() const
return m_oHeadPose;
}
float ITANCTC::GetMinimumDistanceHead2LS() const
{
assert( GetN() > 0 );
float fMinDistance = ( m_oHeadPose.vPos - GetLoudspeakerPose( 0 ).vPos ).GetLength();
for( int n = 1; n < GetN(); n++ )
assert( GetNumChannels() > 0 );
float fMinDistance = ( m_oHeadPose.vPos - GetLoudspeakerPose( 1 ).vPos ).GetLength();
for( int n = 1; n < GetNumChannels(); n++ )
{
if( ( m_oHeadPose.vPos - GetLoudspeakerPose( n ).vPos ).GetLength() < fMinDistance )
fMinDistance = ( m_oHeadPose.vPos - GetLoudspeakerPose( n ).vPos ).GetLength();
if( ( m_oHeadPose.vPos - GetLoudspeakerPose( n + 1 ).vPos ).GetLength() < fMinDistance )
fMinDistance = ( m_oHeadPose.vPos - GetLoudspeakerPose( n + 1 ).vPos ).GetLength();
}
return fMinDistance;
}
......@@ -560,15 +555,15 @@ ITANCTC::Pose& ITANCTC::Pose::operator=( const ITANCTC::Pose& oPoseRHS )
return *this;
}
void ITANCTC::Pose::SetOrientationYPRdeg( double fYaw, double fPitch, double fRoll )
void ITANCTC::Pose::SetOrientationYPRdeg( const float fYaw, const float fPitch, const float fRoll )
{
double yaw = grad2rad( fYaw );
double pitch = grad2rad( fPitch );
double roll = grad2rad( fRoll );
const double yaw = grad2rad( fYaw );
const double pitch = grad2rad( fPitch );
const 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 );
const double sy = sin( yaw ), cy = cos( yaw );
const double sp = sin( pitch ), cp = cos( pitch );
const 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 );
......@@ -585,4 +580,5 @@ ITANCTC::Config::Config()
iOptimization = OPTIMIZATION_NONE;
fCrossTalkCancellationFactor = 1.0f;
fWaveIncidenceAngleCompensationFactor = 1.0f;
fRegularizationFactor = 0.0001f;
}
......@@ -90,14 +90,14 @@ int main( int, char** )
ITANCTC ctc( oNCTCConfig );
// Settings
ctc.SetBeta( 0.001f );
ctc.SetRegularizationFactor( 0.001f );
// Update and calculate filter
ctc.SetHRIR( pHRIR );
ctc.UpdateHeadPose( oHead );
std::vector< ITAHDFTSpectra* > vpCTCFilter;
for( int n=0; n<ctc.GetN(); n++ )
for( int n=0; n<ctc.GetNumChannels(); n++ )
vpCTCFilter.push_back( new ITAHDFTSpectra( oNCTCConfig.fSampleRate, 2, oNCTCConfig.iCTCFilterLength+1, true ) );
try
......@@ -109,7 +109,7 @@ int main( int, char** )
std::cout << e << std::endl;
}
for( int i=0; i<ctc.GetN(); i++ )
for( int i=0; i<ctc.GetNumChannels(); i++ )
ITAFFTUtils::Export( vpCTCFilter[i], "CTCFilter_" + IntToString( i ) );
ITAStopWatch sw;
......@@ -133,7 +133,7 @@ int main( int, char** )
// Export resulting filter set to WAV file
for( int n=0; n<ctc.GetN(); n++ )
for( int n=0; n<ctc.GetNumChannels(); n++ )
{
ITAFFTUtils::Export( vpCTCFilter[ n ], "CTCFilter_LS" + IntToString( int( n + 1 ) ) );
ITAFFTUtils::Export( vpHRTF[ n ], "HRTFs_LS" + IntToString( int( n + 1 ) ) );
......
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