Skip to content

Commit

Permalink
replace generic xyzgain by diffusedecoder with detection of 2d/3d
Browse files Browse the repository at this point in the history
  • Loading branch information
gisogrimm committed Nov 15, 2024
1 parent c50ae39 commit 54d87b0
Show file tree
Hide file tree
Showing 22 changed files with 56 additions and 24 deletions.
5 changes: 2 additions & 3 deletions libtascar/include/speakerarray.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ namespace TASCAR {
spk_array_t(const spk_array_t&);

public:
enum dffusedecoder_t { basic, maxre, inphase };
double get_rmax() const { return rmax; };
double get_rmin() const { return rmin; };
class didx_t {
Expand All @@ -116,7 +117,7 @@ namespace TASCAR {
private:
double rmax;
double rmin;
float xyzgain;
dffusedecoder_t diffusedecoder_enum = maxre;
std::string onload;
std::string onunload;
std::vector<didx_t> didx;
Expand Down Expand Up @@ -212,8 +213,6 @@ namespace TASCAR {
// lowpass filters for subwoofer (24 dB/Oct):
std::vector<TASCAR::biquadf_t> flt_lowp1;
std::vector<TASCAR::biquadf_t> flt_lowp2;
// allpass filters for transition phase matching, broad band speakers:
//std::vector<TASCAR::biquad_t> flt_allp;
std::vector<std::vector<float>> subweight;
std::vector<std::string>
convolution_ir; //< file name of impulse response for convolution
Expand Down
37 changes: 35 additions & 2 deletions libtascar/src/speakerarray.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ spk_array_cfg_t::~spk_array_cfg_t()
spk_array_t::spk_array_t(tsccfg::node_t e, bool use_parent_xml,
const std::string& elementname_, bool allow_empty)
: spk_array_cfg_t(e, use_parent_xml), elayout(e_layout), rmax(0), rmin(0),
xyzgain(1.0), elementname(elementname_), mean_rotation(0)
elementname(elementname_), mean_rotation(0)
{
clear();
{
Expand Down Expand Up @@ -119,12 +119,23 @@ spk_array_t::spk_array_t(tsccfg::node_t e, bool use_parent_xml,
}
for(auto& sn : tsccfg::node_get_children(e_layout, elementname))
emplace_back(sn);
elayout.GET_ATTRIBUTE(xyzgain, "", "XYZ-gain for FOA decoding");
elayout.GET_ATTRIBUTE(name, "", "Name of layout, for documentation only");
elayout.GET_ATTRIBUTE(onload, "",
"system command to be executed when layout is loaded");
elayout.GET_ATTRIBUTE(
onunload, "", "system command to be executed when layout is unloaded");
std::string diffusedecoder = "maxre";
elayout.GET_ATTRIBUTE(diffusedecoder, "basic|maxre|inphase",
"Diffuse-decoder method");
if(diffusedecoder == "maxre")
diffusedecoder_enum = maxre;
else if(diffusedecoder == "basic")
diffusedecoder_enum = basic;
else if(diffusedecoder == "inphase")
diffusedecoder_enum = inphase;
else
throw TASCAR::ErrMsg("Invalid diffuse decoder type \"" + diffusedecoder +
"\". Valid values are basic, maxre or inphase.");
//
if(empty() && (!allow_empty))
throw TASCAR::ErrMsg("Invalid " + elementname_ + " array (no " +
Expand All @@ -141,13 +152,35 @@ spk_array_t::spk_array_t(tsccfg::node_t e, bool use_parent_xml,
rmin = r;
}
}
bool isflat = true;
std::complex<double> p_xy(0);
for(uint32_t k = 0; k < size(); k++) {
if(fabsf(operator[](k).unitvector.z) > 1e-6f)
isflat = false;
operator[](k).spkgain *= operator[](k).norm() / rmax;
operator[](k).dr = rmax - operator[](k).norm();
p_xy += std::exp(-(double)k * TASCAR_2PI * i / (double)(size())) *
(operator[](k).unitvector.x + i * operator[](k).unitvector.y);
}
// calculate xyzgain according to Daniel (2001), table 3.10:
double xyzgain = 1.0;
switch(diffusedecoder_enum) {
case basic:
xyzgain = 1.0;
break;
case maxre:
if(isflat)
xyzgain = sqrt(0.5);
else
xyzgain = 0.577;
break;
case inphase:
if(isflat)
xyzgain = 0.5;
else
xyzgain = 1.0/3.0;
break;
}
mean_rotation = std::arg(p_xy);
didx.resize(size());
for(uint32_t k = 0; k < size(); ++k) {
Expand Down
2 changes: 1 addition & 1 deletion manual/manual.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1181,7 +1181,7 @@ \subsection{The {\tt <receiver .../>} element}\label{sec:receiver}\index{receive
first order Ambisonics signal of the $l$-th diffuse sound field; $L$ is the
number of all diffuse sound fields, including diffuse reverberation inputs.

For all loudspeaker-based receiver types, $D$ is a first order Ambisonics decoder matrix, with optional loudspeaker density compensation and decorrelation filters. To get a $\max rE$-decoder, set the \indattr{xyzgain} attribute to 0.707 for regular horizontal loudspeaker layouts and to 0.577 for regular 3D loudspeaker layouts. For Ambisonics based receiver types, $D$ is a diagonal matrix. By default, the decoded output of the first order Ambisonics rendering is de-correlated using FIR all-pass filters to achieve diffuse sound fields and avoid coloration artifacts (see \indattr{decorr} and \indattr{decorr\_length} for details).
For all loudspeaker-based receiver types, $D$ is a first order Ambisonics decoder matrix, with optional loudspeaker density compensation and decorrelation filters. By default, a $\max rE$-decoder is used. The order gain $g_{xyz}$ is set according to Table 3.10 of \citet{Daniel2001}. A loudspeaker layout is assumed to reproduce in 3D when at least one loudspeaker has non-zero elevation. For Ambisonics based receiver types, $D$ is a diagonal matrix. By default, the decoded output of the first order Ambisonics rendering is de-correlated using FIR all-pass filters to achieve diffuse sound fields and avoid coloration artifacts (see \indattr{decorr} and \indattr{decorr\_length} for details).

Figure \ref{fig:renderer} presents the typical connections in \tascar{}
and may help to visualize the role of the receiver.
Expand Down
2 changes: 1 addition & 1 deletion test/36ch.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<layout xyzgain="0.70710678118654757274" >
<layout>
<speaker az="0"/>
<speaker az="10"/>
<speaker az="20"/>
Expand Down
2 changes: 1 addition & 1 deletion test/4ch.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
<layout xyzgain="0.70710678118654757274" decorr="false" densitycorr="false">
<layout decorr="false" densitycorr="false">
<speaker az="0"/>
<speaker az="90"/>
<speaker az="180"/>
Expand Down
2 changes: 1 addition & 1 deletion test/4ch_decorr.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
<layout xyzgain="0.70710678118654757274" diffusegain="6.45">
<layout diffusegain="6.45">
<speaker az="0"/>
<speaker az="90"/>
<speaker az="180"/>
Expand Down
2 changes: 1 addition & 1 deletion test/4ch_nodecorr.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
<layout xyzgain="0.70710678118654757274" decorr="false" diffusegain="-2.89">
<layout decorr="false" diffusegain="-2.89">
<speaker az="0"/>
<speaker az="90"/>
<speaker az="180"/>
Expand Down
2 changes: 1 addition & 1 deletion test/8ch.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<layout xyzgain="0.70710678118654757274" >
<layout>
<speaker az="0" connect="system:playback_1"/>
<speaker az="45" connect="system:playback_2"/>
<speaker az="90" connect="system:playback_3"/>
Expand Down
2 changes: 1 addition & 1 deletion test/8ch_calib.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<layout xyzgain="0.70710678118654757274" caliblevel="70">
<layout caliblevel="70">
<speaker az="0"/>
<speaker az="45"/>
<speaker az="90"/>
Expand Down
2 changes: 1 addition & 1 deletion test/8ch_diffuse.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<layout xyzgain="0.70710678118654757274" decorr="false" densitycorr="false">
<layout decorr="false" densitycorr="false">
<speaker az="0"/>
<speaker az="45"/>
<speaker az="90"/>
Expand Down
2 changes: 1 addition & 1 deletion test/8ch_diffuse_zero.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<layout xyzgain="0.70710678118654757274" decorr="true" decorr_length="0" densitycorr="false">
<layout decorr="true" decorr_length="0" densitycorr="false">
<speaker az="0"/>
<speaker az="45"/>
<speaker az="90"/>
Expand Down
2 changes: 1 addition & 1 deletion test/8ch_nodecorr.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<layout xyzgain="1" decorr="false">
<layout diffusedecoder="basic" decorr="false">
<speaker az="0" connect="system:playback_1"/>
<speaker az="45" connect="system:playback_2"/>
<speaker az="90" connect="system:playback_3"/>
Expand Down
2 changes: 1 addition & 1 deletion test/8ch_sub.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<layout xyzgain="0.70710678118654757274" fcsub="80">
<layout fcsub="80">
<speaker az="0" connect="system:playback_1"/>
<speaker az="45" connect="system:playback_2"/>
<speaker az="90" connect="system:playback_3"/>
Expand Down
Binary file modified test/expected_snd_diffuse_maxre.wav
Binary file not shown.
2 changes: 1 addition & 1 deletion test/irreg.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<layout xyzgain="0.70710678118654757274" >
<layout >
<speaker az="0" connect="system:playback_1"/>
<speaker az="37" connect="system:playback_2"/>
<speaker az="90" connect="system:playback_3"/>
Expand Down
2 changes: 1 addition & 1 deletion test/lidhan_3d.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<layout name="glab" xyzgain="0.577" decorr="false">
<layout name="glab" decorr="false">
<speaker az="11.25"/>
<speaker az="33.75"/>
<speaker az="56.25"/>
Expand Down
2 changes: 1 addition & 1 deletion test/lidhan_3d45.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<layout xyzgain="0.577" decorr="false">
<layout decorr="false">
<speaker az="11.25" el="0.0" label="B.1"/>
<speaker az="33.75" el="0.0" label="B.2"/>
<speaker az="56.25" el="0.0" label="B.3"/>
Expand Down
2 changes: 1 addition & 1 deletion test/lidhan_3d45_sub.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<layout xyzgain="0.577" decorr="false">
<layout decorr="false">
<speaker az="11.25" el="0.0" label="B.1"/>
<speaker az="33.75" el="0.0" label="B.2"/>
<speaker az="56.25" el="0.0" label="B.3"/>
Expand Down
2 changes: 1 addition & 1 deletion test/test_snd_diffuse_basic.tsc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</diffuse>
<receiver type="nsp">
<!-- basic decoding is achieved with g_m = 1.0 (Daniel, 2001) -->
<layout xyzgain="1.0" decorr="false">
<layout diffusedecoder="basic" decorr="false">
<speaker az="0" r="1"/>
</layout>
</receiver>
Expand Down
2 changes: 1 addition & 1 deletion test/test_snd_diffuse_inphase.tsc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</diffuse>
<receiver type="nsp">
<!-- inphase decoding is achieved with g_m = 0.5 (Daniel, 2001) -->
<layout xyzgain="0.5" decorr="false">
<layout diffusedecoder="inphase" decorr="false">
<speaker az="0" r="1"/>
</layout>
</receiver>
Expand Down
2 changes: 1 addition & 1 deletion test/test_snd_diffuse_maxre.tsc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</diffuse>
<receiver type="nsp">
<!-- maxre decoding is achieved with g_m = 0.7071 (Daniel, 2001) -->
<layout xyzgain="0.7071" decorr="false">
<layout diffusedecoder="maxre" decorr="false">
<speaker az="0" r="1"/>
</layout>
</receiver>
Expand Down
2 changes: 1 addition & 1 deletion test/vbap6.spk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
<layout>
<layout diffusedecoder="basic">
<speaker az="0"/>
<speaker az="90"/>
<speaker az="-90"/>
Expand Down

0 comments on commit 54d87b0

Please sign in to comment.