aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/bformatdec.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-04-09 08:04:56 -0700
committerChris Robinson <[email protected]>2016-04-09 13:10:52 -0700
commit7bdd68ddbe896bc7d50a8a43ba093d66e1c0216e (patch)
tree1bb119b80ae71914712ac5378395ceebd0c7ac84 /Alc/bformatdec.c
parenta8101da95676f2f9541cb3fcdbcf66ddb16e913c (diff)
Use frequency-dependent processing for the ambisonic up-sampler
Diffstat (limited to 'Alc/bformatdec.c')
-rw-r--r--Alc/bformatdec.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/Alc/bformatdec.c b/Alc/bformatdec.c
index e4c6da49..dd0561d0 100644
--- a/Alc/bformatdec.c
+++ b/Alc/bformatdec.c
@@ -114,6 +114,12 @@ static const ALfloat SquareMatrixHF[4][MAX_AMBI_COEFFS] = {
{ 0.353553f, 0.204094f, 0.0f, -0.204094f },
{ 0.353553f, -0.204094f, 0.0f, -0.204094f },
};
+static const ALfloat SquareMatrixLF[4][MAX_AMBI_COEFFS] = {
+ { 0.25f, 0.204094f, 0.0f, 0.204094f },
+ { 0.25f, -0.204094f, 0.0f, 0.204094f },
+ { 0.25f, 0.204094f, 0.0f, -0.204094f },
+ { 0.25f, -0.204094f, 0.0f, -0.204094f },
+};
static ALfloat SquareEncoder[4][MAX_AMBI_COEFFS];
static const ALfloat CubeMatrixHF[8][MAX_AMBI_COEFFS] = {
@@ -126,6 +132,16 @@ static const ALfloat CubeMatrixHF[8][MAX_AMBI_COEFFS] = {
{ 0.25f, 0.14425f, -0.14425f, -0.14425f },
{ 0.25f, -0.14425f, -0.14425f, -0.14425f },
};
+static const ALfloat CubeMatrixLF[8][MAX_AMBI_COEFFS] = {
+ { 0.125f, 0.125f, 0.125f, 0.125f },
+ { 0.125f, -0.125f, 0.125f, 0.125f },
+ { 0.125f, 0.125f, 0.125f, -0.125f },
+ { 0.125f, -0.125f, 0.125f, -0.125f },
+ { 0.125f, 0.125f, -0.125f, 0.125f },
+ { 0.125f, -0.125f, -0.125f, 0.125f },
+ { 0.125f, 0.125f, -0.125f, -0.125f },
+ { 0.125f, -0.125f, -0.125f, -0.125f },
+};
static ALfloat CubeEncoder[8][MAX_AMBI_COEFFS];
static alonce_flag encoder_inited = AL_ONCE_FLAG_INIT;
@@ -188,7 +204,10 @@ typedef struct BFormatDec {
} Delay[MAX_OUTPUT_CHANNELS];
struct {
+ BandSplitter XOver[4];
+
const ALfloat (*restrict MatrixHF)[MAX_AMBI_COEFFS];
+ const ALfloat (*restrict MatrixLF)[MAX_AMBI_COEFFS];
const ALfloat (*restrict Encoder)[MAX_AMBI_COEFFS];
ALuint NumChannels;
} UpSampler;
@@ -251,8 +270,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALuint chancount,
dec->SamplesLF = NULL;
dec->NumChannels = chancount;
- dec->Samples = al_calloc(16, dec->NumChannels * conf->FreqBands *
- sizeof(dec->Samples[0]));
+ dec->Samples = al_calloc(16, dec->NumChannels*2 * sizeof(dec->Samples[0]));
dec->SamplesHF = dec->Samples;
dec->SamplesLF = dec->SamplesHF + dec->NumChannels;
@@ -266,9 +284,13 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALuint chancount,
else if(conf->CoeffScale == ADS_FuMa)
coeff_scale = FuMa2N3DScale;
+ ratio = 400.0f / (ALfloat)srate;
+ for(i = 0;i < 4;i++)
+ bandsplit_init(&dec->UpSampler.XOver[i], ratio);
if((conf->ChanMask & ~0x831b))
{
dec->UpSampler.MatrixHF = CubeMatrixHF;
+ dec->UpSampler.MatrixLF = CubeMatrixLF;
dec->UpSampler.Encoder = (const ALfloat(*)[MAX_AMBI_COEFFS])CubeEncoder;
dec->UpSampler.NumChannels = 8;
dec->Periphonic = AL_TRUE;
@@ -276,6 +298,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALuint chancount,
else
{
dec->UpSampler.MatrixHF = SquareMatrixHF;
+ dec->UpSampler.MatrixLF = SquareMatrixLF;
dec->UpSampler.Encoder = (const ALfloat(*)[MAX_AMBI_COEFFS])SquareEncoder;
dec->UpSampler.NumChannels = 4;
dec->Periphonic = AL_FALSE;
@@ -510,6 +533,15 @@ void bformatdec_upSample(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[B
{
ALuint i, j, k;
+ /* First, split the first-order components into low and high frequency
+ * bands. This assumes SamplesHF and SamplesLF have enough space for first-
+ * order content (to which, this up-sampler is only used with second-order
+ * or higher decoding, so it will).
+ */
+ for(i = 0;i < InChannels;i++)
+ bandsplit_process(&dec->UpSampler.XOver[i], dec->SamplesHF[i], dec->SamplesLF[i],
+ InSamples[i], SamplesToDo);
+
/* This up-sampler is very simplistic. It essentially decodes the first-
* order content to a square channel array (or cube if height is desired),
* then encodes those points onto the higher order soundfield.
@@ -517,7 +549,9 @@ void bformatdec_upSample(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[B
for(k = 0;k < dec->UpSampler.NumChannels;k++)
{
memset(dec->ChannelMix, 0, SamplesToDo*sizeof(ALfloat));
- apply_row(dec->ChannelMix, dec->UpSampler.MatrixHF[k], InSamples,
+ apply_row(dec->ChannelMix, dec->UpSampler.MatrixHF[k], dec->SamplesHF,
+ InChannels, SamplesToDo);
+ apply_row(dec->ChannelMix, dec->UpSampler.MatrixLF[k], dec->SamplesLF,
InChannels, SamplesToDo);
for(j = 0;j < dec->NumChannels;j++)