Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Institute of Technical Acoustics (ITA)
ITACTC
Commits
ab4ad111
Commit
ab4ad111
authored
Jun 15, 2017
by
Dipl.-Ing. Jonas Stienen
Browse files
Refactoring NCTC
parent
74a0c562
Changes
3
Hide whitespace changes
Inline
Side-by-side
include/ITANCTC.h
View file @
ab4ad111
...
...
@@ -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 engin
g
e
//! Get the number of loudspeaker
s/channels
for this CTC engine
/**
*
\
return
n
umber of channels (N)
*
@
return
N
umber of channels (N)
*
*/
int
GetN
()
const
;
int
GetN
umChannels
()
const
;
//! Configuration getter
/**
...
...
@@ -173,47 +174,47 @@ public:
const
Config
&
GetConfig
()
const
;
//! Get
beta parameter
//! Get
regularization factor (beta)
/**
*
\
return
Beta paramete
r
*/
float
Get
Beta
()
;
*
@
return
Regularization facto
r
*/
float
Get
RegularizationFactor
()
const
;
//! Set
beta paramete
r
//! Set
regularization facto
r
/**
*
\
param f
Beta
Set the
beta
regularization
parameter
*/
void
Set
Beta
(
float
fBeta
);
*
@
param f
RegularizationFator
Set the regularization
factor (beta)
*/
void
Set
RegularizationFactor
(
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_f
Beta
;
//!< 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_f
RegularizationFactor
;
//!< 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_v
d
Weights
;
//!< Diagonal values for the weighting matrix (W or Z), only non-zero entries allowed
std
::
vector
<
float
>
m_v
f
Weights
;
//!< 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
/**
...
...
src/ITANCTC.cpp
View file @
ab4ad111
...
...
@@ -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.0
f
);
m_oHeadPose
.
vUp
.
SetValues
(
0
,
1.0
f
,
0
);
//m_oHeadPose.qOrient.SetToNeutralQuaternion();
m_sfCTC_temp
.
i
nit
(
2
,
m_oConfig
.
iCTCFilterLength
,
true
);
m_sfCTC_temp
.
I
nit
(
2
,
m_oConfig
.
iCTCFilterLength
,
true
);
int
iDFTSize
=
m_oConfig
.
iCTCFilterLength
+
1
;
for
(
int
n
=
0
;
n
<
GetN
();
n
++
)
for
(
int
n
=
0
;
n
<
GetN
umChannels
();
n
++
)
{
m_v
d
Weights
.
push_back
(
1.0
f
);
m_v
f
Weights
.
push_back
(
1.0
f
);
m_vpHRTFs
.
push_back
(
new
ITAHDFTSpectra
(
m_oConfig
.
fSampleRate
,
2
,
iDFTSize
,
true
)
);
m_vfDelayTime
.
push_back
(
float
(
m_oConfig
.
iCTCFilterLength
)
/
m_oConfig
.
fSampleRate
/
2.0
f
);
}
...
...
@@ -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
<
GetN
umChannels
();
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
::
GetN
umChannels
()
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
>
GetN
umChannels
()
)
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
<
GetN
umChannels
();
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
].
d
ata
(),
(
*
pHRTF
)[
0
]
->
data
()
);
m_fft
.
execute
(
m_sfCTC_temp
[
1
].
d
ata
(),
(
*
pHRTF
)[
1
]
->
data
()
);
m_fft
.
execute
(
m_sfCTC_temp
[
0
].
GetD
ata
(),
(
*
pHRTF
)[
0
]
->
data
()
);
m_fft
.
execute
(
m_sfCTC_temp
[
1
].
GetD
ata
(),
(
*
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
<
GetN
umChannels
();
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
fEnergy
LeftChannel
=
(
*
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
(
fEnergy
LeftChannel
>
0
);
const
float
fEnergyCompensation
LeftChannel
=
std
::
pow
(
fEnergy
LeftChannel
,
(
1
-
m_fWaveIncidenceAngleCompensationFactor
)
);
(
*
pHRTF
)[
0
]
->
mul
(
fEnergyCompensation
LeftChannel
);
// 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
(
fEnergy
RightChannel
>
0
);
const
float
fEnergyCompensation
RightChannel
=
std
::
pow
(
fEnergy
RightChannel
,
(
1
-
m_fWaveIncidenceAngleCompensationFactor
)
);
(
*
pHRTF
)[
1
]
->
mul
(
fEnergyCompensation
RightChannel
);
#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.0
f
;
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_v
d
Weights
[
n
]
);
// diag element
const
float
&
fWeight
(
m_v
f
Weights
[
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_f
Beta
);
d
->
add
(
m_f
Beta
);
a
->
add
(
m_f
RegularizationFactor
);
d
->
add
(
m_f
RegularizationFactor
);
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
.
c
hannels
(),
m_sfCTC_temp
.
l
ength
(),
true
);
ITASampleFrame
sfTargetData_shift
(
m_sfCTC_temp
.
GetNumC
hannels
(),
m_sfCTC_temp
.
GetL
ength
(),
true
);
for
(
int
n
=
0
;
n
<
GetN
();
n
++
)
for
(
int
n
=
0
;
n
<
GetN
umChannels
();
n
++
)
{
ITAHDFTSpectra
*
pHRTF
(
m_vpHRTFs
[
n
]
);
// two-channel, already WICKed
ITAHDFTSpectra
*
pCTCFilter
(
vpCTCFilter
[
n
]
);
// two-channel
float
fWeight
=
float
(
m_v
d
Weights
[
n
]
);
// diag element
const
float
&
fWeight
(
m_v
f
Weights
[
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
].
d
ata
()
);
m_ifft
.
execute
(
(
*
pCTCFilter
)[
1
]
->
data
(),
m_sfCTC_temp
[
1
].
d
ata
()
);
m_ifft
.
execute
(
(
*
pCTCFilter
)[
0
]
->
data
(),
m_sfCTC_temp
[
0
].
GetD
ata
()
);
m_ifft
.
execute
(
(
*
pCTCFilter
)[
1
]
->
data
(),
m_sfCTC_temp
[
1
].
GetD
ata
()
);
// Normalize after IFFT
m_sfCTC_temp
.
div_scalar
(
float
(
m_sfCTC_temp
.
l
ength
()
)
);
m_sfCTC_temp
.
div_scalar
(
float
(
m_sfCTC_temp
.
GetL
ength
()
)
);
// Shift the CTC filter according to desired delay
int
iShiftSamples
=
int
(
m_oConfig
.
fSampleRate
*
m_vfDelayTime
[
n
]
);
if
(
m_vfDelayTime
[
n
]
<
0.0
f
)
iShiftSamples
=
m_sfCTC_temp
.
l
ength
()
/
2
;
// if invalid, shift by half length
sfTargetData_shift
.
cyclic_write
(
m_sfCTC_temp
,
m_sfCTC_temp
.
l
ength
(),
0
,
iShiftSamples
);
iShiftSamples
=
m_sfCTC_temp
.
GetL
ength
()
/
2
;
// if invalid, shift by half length
sfTargetData_shift
.
cyclic_write
(
m_sfCTC_temp
,
m_sfCTC_temp
.
GetL
ength
(),
0
,
iShiftSamples
);
m_fft
.
execute
(
sfTargetData_shift
[
0
].
d
ata
(),
(
*
pCTCFilter
)[
0
]
->
data
()
);
m_fft
.
execute
(
sfTargetData_shift
[
1
].
d
ata
(),
(
*
pCTCFilter
)[
1
]
->
data
()
);
m_fft
.
execute
(
sfTargetData_shift
[
0
].
GetD
ata
(),
(
*
pCTCFilter
)[
0
]
->
data
()
);
m_fft
.
execute
(
sfTargetData_shift
[
1
].
GetD
ata
(),
(
*
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
::
Set
Beta
(
float
fBeta
)
void
ITANCTC
::
Set
RegularizationFactor
(
const
float
fRegularizationFactor
)
{
m_f
Beta
=
fBeta
;
m_f
RegularizationFactor
=
fRegularizationFactor
;
}
float
ITANCTC
::
Get
Beta
()
float
ITANCTC
::
Get
RegularizationFactor
()
const
{
return
m_f
Beta
;
return
m_f
RegularizationFactor
;
}
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
<
GetN
umChannels
();
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
()
)
!=
GetN
umChannels
()
)
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
<
GetN
umChannels
();
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
(
GetN
umChannels
()
);
for
(
int
n
=
0
;
n
<
GetN
umChannels
();
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
(
GetN
umChannels
()
>
0
);
float
fMinDistance
=
(
m_oHeadPose
.
vPos
-
GetLoudspeakerPose
(
1
).
vPos
).
GetLength
();
for
(
int
n
=
1
;
n
<
GetN
umChannels
();
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.0
f
;
fWaveIncidenceAngleCompensationFactor
=
1.0
f
;
fRegularizationFactor
=
0.0001
f
;
}
tests/NCTC_CTCFilterTest.cpp
View file @
ab4ad111
...
...
@@ -90,14 +90,14 @@ int main( int, char** )
ITANCTC
ctc
(
oNCTCConfig
);
// Settings
ctc
.
Set
Beta
(
0.001
f
);
ctc
.
Set
RegularizationFactor
(
0.001
f
);
// 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
.
GetN
umChannels
();
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
.
GetN
umChannels
();
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
.
GetN
umChannels
();
n
++
)
{
ITAFFTUtils
::
Export
(
vpCTCFilter
[
n
],
"CTCFilter_LS"
+
IntToString
(
int
(
n
+
1
)
)
);
ITAFFTUtils
::
Export
(
vpHRTF
[
n
],
"HRTFs_LS"
+
IntToString
(
int
(
n
+
1
)
)
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment