Band-split the HRIRs when building the ambisonic decoder filters
[openal-soft.git] / Alc / bformatdec.c
blob356423ce67e94e655c8757b51e834413bc0c649f
2 #include "config.h"
4 #include "bformatdec.h"
5 #include "ambdec.h"
6 #include "mixer_defs.h"
7 #include "alu.h"
9 #include "threads.h"
10 #include "almalloc.h"
13 void bandsplit_init(BandSplitter *splitter, ALfloat freq_mult)
15 ALfloat w = freq_mult * F_TAU;
16 ALfloat cw = cosf(w);
17 if(cw > FLT_EPSILON)
18 splitter->coeff = (sinf(w) - 1.0f) / cw;
19 else
20 splitter->coeff = cw * -0.5f;
22 splitter->lp_z1 = 0.0f;
23 splitter->lp_z2 = 0.0f;
24 splitter->hp_z1 = 0.0f;
27 void bandsplit_clear(BandSplitter *splitter)
29 splitter->lp_z1 = 0.0f;
30 splitter->lp_z2 = 0.0f;
31 splitter->hp_z1 = 0.0f;
34 void bandsplit_process(BandSplitter *splitter, ALfloat *restrict hpout, ALfloat *restrict lpout,
35 const ALfloat *input, ALuint count)
37 ALfloat coeff, d, x;
38 ALfloat z1, z2;
39 ALuint i;
41 coeff = splitter->coeff*0.5f + 0.5f;
42 z1 = splitter->lp_z1;
43 z2 = splitter->lp_z2;
44 for(i = 0;i < count;i++)
46 x = input[i];
48 d = (x - z1) * coeff;
49 x = z1 + d;
50 z1 = x + d;
52 d = (x - z2) * coeff;
53 x = z2 + d;
54 z2 = x + d;
56 lpout[i] = x;
58 splitter->lp_z1 = z1;
59 splitter->lp_z2 = z2;
61 coeff = splitter->coeff;
62 z1 = splitter->hp_z1;
63 for(i = 0;i < count;i++)
65 x = input[i];
67 d = x - coeff*z1;
68 x = z1 + coeff*d;
69 z1 = d;
71 hpout[i] = x - lpout[i];
73 splitter->hp_z1 = z1;
77 static const ALfloat UnitScale[MAX_AMBI_COEFFS] = {
78 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
79 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f
81 static const ALfloat SN3D2N3DScale[MAX_AMBI_COEFFS] = {
82 1.000000000f, /* ACN 0 (W), sqrt(1) */
83 1.732050808f, /* ACN 1 (Y), sqrt(3) */
84 1.732050808f, /* ACN 2 (Z), sqrt(3) */
85 1.732050808f, /* ACN 3 (X), sqrt(3) */
86 2.236067978f, /* ACN 4 (V), sqrt(5) */
87 2.236067978f, /* ACN 5 (T), sqrt(5) */
88 2.236067978f, /* ACN 6 (R), sqrt(5) */
89 2.236067978f, /* ACN 7 (S), sqrt(5) */
90 2.236067978f, /* ACN 8 (U), sqrt(5) */
91 2.645751311f, /* ACN 9 (Q), sqrt(7) */
92 2.645751311f, /* ACN 10 (O), sqrt(7) */
93 2.645751311f, /* ACN 11 (M), sqrt(7) */
94 2.645751311f, /* ACN 12 (K), sqrt(7) */
95 2.645751311f, /* ACN 13 (L), sqrt(7) */
96 2.645751311f, /* ACN 14 (N), sqrt(7) */
97 2.645751311f, /* ACN 15 (P), sqrt(7) */
99 static const ALfloat FuMa2N3DScale[MAX_AMBI_COEFFS] = {
100 1.414213562f, /* ACN 0 (W), sqrt(2) */
101 1.732050808f, /* ACN 1 (Y), sqrt(3) */
102 1.732050808f, /* ACN 2 (Z), sqrt(3) */
103 1.732050808f, /* ACN 3 (X), sqrt(3) */
104 1.936491673f, /* ACN 4 (V), sqrt(15)/2 */
105 1.936491673f, /* ACN 5 (T), sqrt(15)/2 */
106 2.236067978f, /* ACN 6 (R), sqrt(5) */
107 1.936491673f, /* ACN 7 (S), sqrt(15)/2 */
108 1.936491673f, /* ACN 8 (U), sqrt(15)/2 */
109 2.091650066f, /* ACN 9 (Q), sqrt(35/8) */
110 1.972026594f, /* ACN 10 (O), sqrt(35)/3 */
111 2.231093404f, /* ACN 11 (M), sqrt(224/45) */
112 2.645751311f, /* ACN 12 (K), sqrt(7) */
113 2.231093404f, /* ACN 13 (L), sqrt(224/45) */
114 1.972026594f, /* ACN 14 (N), sqrt(35)/3 */
115 2.091650066f, /* ACN 15 (P), sqrt(35/8) */
119 enum FreqBand {
120 FB_HighFreq,
121 FB_LowFreq,
122 FB_Max
125 static const ALfloat SquareMatrix[4][FB_Max][MAX_AMBI_COEFFS] = {
126 { { 0.353553f, 0.204094f, 0.0f, 0.204094f }, { 0.25f, 0.204094f, 0.0f, 0.204094f } },
127 { { 0.353553f, -0.204094f, 0.0f, 0.204094f }, { 0.25f, -0.204094f, 0.0f, 0.204094f } },
128 { { 0.353553f, 0.204094f, 0.0f, -0.204094f }, { 0.25f, 0.204094f, 0.0f, -0.204094f } },
129 { { 0.353553f, -0.204094f, 0.0f, -0.204094f }, { 0.25f, -0.204094f, 0.0f, -0.204094f } },
131 static ALfloat SquareEncoder[4][MAX_AMBI_COEFFS];
133 static const ALfloat CubePoints[8][3] = {
134 { -0.577350269f, 0.577350269f, -0.577350269f },
135 { 0.577350269f, 0.577350269f, -0.577350269f },
136 { -0.577350269f, 0.577350269f, 0.577350269f },
137 { 0.577350269f, 0.577350269f, 0.577350269f },
138 { -0.577350269f, -0.577350269f, -0.577350269f },
139 { 0.577350269f, -0.577350269f, -0.577350269f },
140 { -0.577350269f, -0.577350269f, 0.577350269f },
141 { 0.577350269f, -0.577350269f, 0.577350269f },
143 static const ALfloat CubeMatrix[8][FB_Max][MAX_AMBI_COEFFS] = {
144 { { 0.25f, 0.14425f, 0.14425f, 0.14425f }, { 0.125f, 0.125f, 0.125f, 0.125f } },
145 { { 0.25f, -0.14425f, 0.14425f, 0.14425f }, { 0.125f, -0.125f, 0.125f, 0.125f } },
146 { { 0.25f, 0.14425f, 0.14425f, -0.14425f }, { 0.125f, 0.125f, 0.125f, -0.125f } },
147 { { 0.25f, -0.14425f, 0.14425f, -0.14425f }, { 0.125f, -0.125f, 0.125f, -0.125f } },
148 { { 0.25f, 0.14425f, -0.14425f, 0.14425f }, { 0.125f, 0.125f, -0.125f, 0.125f } },
149 { { 0.25f, -0.14425f, -0.14425f, 0.14425f }, { 0.125f, -0.125f, -0.125f, 0.125f } },
150 { { 0.25f, 0.14425f, -0.14425f, -0.14425f }, { 0.125f, 0.125f, -0.125f, -0.125f } },
151 { { 0.25f, -0.14425f, -0.14425f, -0.14425f }, { 0.125f, -0.125f, -0.125f, -0.125f } },
153 static ALfloat CubeEncoder[8][MAX_AMBI_COEFFS];
156 static inline MatrixMixerFunc SelectMixer(void)
158 #ifdef HAVE_SSE
159 if((CPUCapFlags&CPU_CAP_SSE))
160 return MixRow_SSE;
161 #endif
162 #ifdef HAVE_NEON
163 if((CPUCapFlags&CPU_CAP_NEON))
164 return MixRow_Neon;
165 #endif
166 return MixRow_C;
169 static MatrixMixerFunc MixMatrixRow = MixRow_C;
172 static alonce_flag bformatdec_inited = AL_ONCE_FLAG_INIT;
174 static void init_bformatdec(void)
176 ALuint i, j;
178 MixMatrixRow = SelectMixer();
180 for(i = 0;i < COUNTOF(CubePoints);i++)
181 CalcDirectionCoeffs(CubePoints[i], 0.0f, CubeEncoder[i]);
183 CalcXYZCoeffs(-0.707106781f, 0.0f, -0.707106781f, 0.0f, SquareEncoder[0]);
184 CalcXYZCoeffs( 0.707106781f, 0.0f, -0.707106781f, 0.0f, SquareEncoder[1]);
185 CalcXYZCoeffs(-0.707106781f, 0.0f, 0.707106781f, 0.0f, SquareEncoder[2]);
186 CalcXYZCoeffs( 0.707106781f, 0.0f, 0.707106781f, 0.0f, SquareEncoder[3]);
188 for(i = 0;i < 4;i++)
190 /* Remove the skipped height-related coefficients for 2D rendering. */
191 SquareEncoder[i][2] = SquareEncoder[i][3];
192 SquareEncoder[i][3] = SquareEncoder[i][4];
193 SquareEncoder[i][4] = SquareEncoder[i][8];
194 SquareEncoder[i][5] = SquareEncoder[i][9];
195 SquareEncoder[i][6] = SquareEncoder[i][15];
196 for(j = 7;j < MAX_AMBI_COEFFS;j++)
197 SquareEncoder[i][j] = 0.0f;
202 #define MAX_DELAY_LENGTH 128
204 /* NOTE: BandSplitter filters are unused with single-band decoding */
205 typedef struct BFormatDec {
206 ALboolean Enabled[MAX_OUTPUT_CHANNELS];
208 union {
209 alignas(16) ALfloat Dual[MAX_OUTPUT_CHANNELS][FB_Max][MAX_AMBI_COEFFS];
210 alignas(16) ALfloat Single[MAX_OUTPUT_CHANNELS][MAX_AMBI_COEFFS];
211 } Matrix;
213 BandSplitter XOver[MAX_AMBI_COEFFS];
215 ALfloat (*Samples)[BUFFERSIZE];
216 /* These two alias into Samples */
217 ALfloat (*SamplesHF)[BUFFERSIZE];
218 ALfloat (*SamplesLF)[BUFFERSIZE];
220 alignas(16) ALfloat ChannelMix[BUFFERSIZE];
222 struct {
223 alignas(16) ALfloat Buffer[MAX_DELAY_LENGTH];
224 ALuint Length; /* Valid range is [0...MAX_DELAY_LENGTH). */
225 } Delay[MAX_OUTPUT_CHANNELS];
227 struct {
228 BandSplitter XOver[4];
230 const ALfloat (*restrict Matrix)[FB_Max][MAX_AMBI_COEFFS];
231 const ALfloat (*restrict Encoder)[MAX_AMBI_COEFFS];
232 ALuint NumChannels;
233 } UpSampler;
235 ALuint NumChannels;
236 ALboolean DualBand;
237 ALboolean Periphonic;
238 } BFormatDec;
240 BFormatDec *bformatdec_alloc()
242 alcall_once(&bformatdec_inited, init_bformatdec);
243 return al_calloc(16, sizeof(BFormatDec));
246 void bformatdec_free(BFormatDec *dec)
248 if(dec)
250 al_free(dec->Samples);
251 dec->Samples = NULL;
252 dec->SamplesHF = NULL;
253 dec->SamplesLF = NULL;
255 memset(dec, 0, sizeof(*dec));
256 al_free(dec);
260 int bformatdec_getOrder(const struct BFormatDec *dec)
262 if(dec->Periphonic)
264 if(dec->NumChannels > 9) return 3;
265 if(dec->NumChannels > 4) return 2;
266 if(dec->NumChannels > 1) return 1;
268 else
270 if(dec->NumChannels > 5) return 3;
271 if(dec->NumChannels > 3) return 2;
272 if(dec->NumChannels > 1) return 1;
274 return 0;
277 void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALuint chancount, ALuint srate, const ALuint chanmap[MAX_OUTPUT_CHANNELS], int flags)
279 static const ALuint map2DTo3D[MAX_AMBI2D_COEFFS] = {
280 0, 1, 3, 4, 8, 9, 15
282 const ALfloat *coeff_scale = UnitScale;
283 ALfloat distgain[MAX_OUTPUT_CHANNELS];
284 ALfloat maxdist, ratio;
285 ALuint i;
287 al_free(dec->Samples);
288 dec->Samples = NULL;
289 dec->SamplesHF = NULL;
290 dec->SamplesLF = NULL;
292 dec->NumChannels = chancount;
293 dec->Samples = al_calloc(16, dec->NumChannels*2 * sizeof(dec->Samples[0]));
294 dec->SamplesHF = dec->Samples;
295 dec->SamplesLF = dec->SamplesHF + dec->NumChannels;
297 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
298 dec->Enabled[i] = AL_FALSE;
299 for(i = 0;i < conf->NumSpeakers;i++)
300 dec->Enabled[chanmap[i]] = AL_TRUE;
302 if(conf->CoeffScale == ADS_SN3D)
303 coeff_scale = SN3D2N3DScale;
304 else if(conf->CoeffScale == ADS_FuMa)
305 coeff_scale = FuMa2N3DScale;
307 ratio = 400.0f / (ALfloat)srate;
308 for(i = 0;i < 4;i++)
309 bandsplit_init(&dec->UpSampler.XOver[i], ratio);
310 if((conf->ChanMask&AMBI_PERIPHONIC_MASK))
312 dec->UpSampler.Matrix = CubeMatrix;
313 dec->UpSampler.Encoder = (const ALfloat(*)[MAX_AMBI_COEFFS])CubeEncoder;
314 dec->UpSampler.NumChannels = 8;
315 dec->Periphonic = AL_TRUE;
317 else
319 dec->UpSampler.Matrix = SquareMatrix;
320 dec->UpSampler.Encoder = (const ALfloat(*)[MAX_AMBI_COEFFS])SquareEncoder;
321 dec->UpSampler.NumChannels = 4;
322 dec->Periphonic = AL_FALSE;
325 maxdist = 0.0f;
326 for(i = 0;i < conf->NumSpeakers;i++)
328 maxdist = maxf(maxdist, conf->Speakers[i].Distance);
329 distgain[i] = 1.0f;
332 memset(dec->Delay, 0, sizeof(dec->Delay));
333 if((flags&BFDF_DistanceComp) && maxdist > 0.0f)
335 for(i = 0;i < conf->NumSpeakers;i++)
337 ALuint chan = chanmap[i];
338 ALfloat delay;
340 /* Distance compensation only delays in steps of the sample rate.
341 * This is a bit less accurate since the delay time falls to the
342 * nearest sample time, but it's far simpler as it doesn't have to
343 * deal with phase offsets. This means at 48khz, for instance, the
344 * distance delay will be in steps of about 7 millimeters.
346 delay = floorf((maxdist-conf->Speakers[i].Distance) / SPEEDOFSOUNDMETRESPERSEC *
347 (ALfloat)srate + 0.5f);
348 if(delay >= (ALfloat)MAX_DELAY_LENGTH)
349 ERR("Delay for speaker \"%s\" exceeds buffer length (%f >= %u)\n",
350 al_string_get_cstr(conf->Speakers[i].Name), delay, MAX_DELAY_LENGTH);
352 dec->Delay[chan].Length = (ALuint)clampf(delay, 0.0f, (ALfloat)(MAX_DELAY_LENGTH-1));
353 distgain[i] = conf->Speakers[i].Distance / maxdist;
354 TRACE("Channel %u \"%s\" distance compensation: %u samples, %f gain\n", chan,
355 al_string_get_cstr(conf->Speakers[i].Name), dec->Delay[chan].Length, distgain[i]
360 memset(&dec->Matrix, 0, sizeof(dec->Matrix));
361 if(conf->FreqBands == 1)
363 dec->DualBand = AL_FALSE;
364 for(i = 0;i < conf->NumSpeakers;i++)
366 ALuint chan = chanmap[i];
367 ALfloat gain;
368 ALuint j, k;
370 if(!dec->Periphonic)
372 for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
374 ALuint l = map2DTo3D[j];
375 if(j == 0) gain = conf->HFOrderGain[0];
376 else if(j == 1) gain = conf->HFOrderGain[1];
377 else if(j == 3) gain = conf->HFOrderGain[2];
378 else if(j == 5) gain = conf->HFOrderGain[3];
379 if((conf->ChanMask&(1<<l)))
380 dec->Matrix.Single[chan][j] = conf->HFMatrix[i][k++] / coeff_scale[l] *
381 gain * distgain[i];
384 else
386 for(j = 0,k = 0;j < MAX_AMBI_COEFFS;j++)
388 if(j == 0) gain = conf->HFOrderGain[0];
389 else if(j == 1) gain = conf->HFOrderGain[1];
390 else if(j == 4) gain = conf->HFOrderGain[2];
391 else if(j == 9) gain = conf->HFOrderGain[3];
392 if((conf->ChanMask&(1<<j)))
393 dec->Matrix.Single[chan][j] = conf->HFMatrix[i][k++] / coeff_scale[j] *
394 gain * distgain[i];
399 else
401 dec->DualBand = AL_TRUE;
403 ratio = conf->XOverFreq / (ALfloat)srate;
404 for(i = 0;i < MAX_AMBI_COEFFS;i++)
405 bandsplit_init(&dec->XOver[i], ratio);
407 ratio = powf(10.0f, conf->XOverRatio / 40.0f);
408 for(i = 0;i < conf->NumSpeakers;i++)
410 ALuint chan = chanmap[i];
411 ALfloat gain;
412 ALuint j, k;
414 if(!dec->Periphonic)
416 for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
418 ALuint l = map2DTo3D[j];
419 if(j == 0) gain = conf->HFOrderGain[0] * ratio;
420 else if(j == 1) gain = conf->HFOrderGain[1] * ratio;
421 else if(j == 3) gain = conf->HFOrderGain[2] * ratio;
422 else if(j == 5) gain = conf->HFOrderGain[3] * ratio;
423 if((conf->ChanMask&(1<<l)))
424 dec->Matrix.Dual[chan][FB_HighFreq][j] = conf->HFMatrix[i][k++] /
425 coeff_scale[l] * gain *
426 distgain[i];
428 for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
430 ALuint l = map2DTo3D[j];
431 if(j == 0) gain = conf->LFOrderGain[0] / ratio;
432 else if(j == 1) gain = conf->LFOrderGain[1] / ratio;
433 else if(j == 3) gain = conf->LFOrderGain[2] / ratio;
434 else if(j == 5) gain = conf->LFOrderGain[3] / ratio;
435 if((conf->ChanMask&(1<<l)))
436 dec->Matrix.Dual[chan][FB_LowFreq][j] = conf->LFMatrix[i][k++] /
437 coeff_scale[l] * gain *
438 distgain[i];
441 else
443 for(j = 0,k = 0;j < MAX_AMBI_COEFFS;j++)
445 if(j == 0) gain = conf->HFOrderGain[0] * ratio;
446 else if(j == 1) gain = conf->HFOrderGain[1] * ratio;
447 else if(j == 4) gain = conf->HFOrderGain[2] * ratio;
448 else if(j == 9) gain = conf->HFOrderGain[3] * ratio;
449 if((conf->ChanMask&(1<<j)))
450 dec->Matrix.Dual[chan][FB_HighFreq][j] = conf->HFMatrix[i][k++] /
451 coeff_scale[j] * gain *
452 distgain[i];
454 for(j = 0,k = 0;j < MAX_AMBI_COEFFS;j++)
456 if(j == 0) gain = conf->LFOrderGain[0] / ratio;
457 else if(j == 1) gain = conf->LFOrderGain[1] / ratio;
458 else if(j == 4) gain = conf->LFOrderGain[2] / ratio;
459 else if(j == 9) gain = conf->LFOrderGain[3] / ratio;
460 if((conf->ChanMask&(1<<j)))
461 dec->Matrix.Dual[chan][FB_LowFreq][j] = conf->LFMatrix[i][k++] /
462 coeff_scale[j] * gain *
463 distgain[i];
471 void bformatdec_process(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint OutChannels, ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint SamplesToDo)
473 ALuint chan, i;
475 if(dec->DualBand)
477 for(i = 0;i < dec->NumChannels;i++)
478 bandsplit_process(&dec->XOver[i], dec->SamplesHF[i], dec->SamplesLF[i],
479 InSamples[i], SamplesToDo);
481 for(chan = 0;chan < OutChannels;chan++)
483 if(!dec->Enabled[chan])
484 continue;
486 memset(dec->ChannelMix, 0, SamplesToDo*sizeof(ALfloat));
487 MixMatrixRow(dec->ChannelMix, dec->Matrix.Dual[chan][FB_HighFreq],
488 dec->SamplesHF, dec->NumChannels, SamplesToDo
490 MixMatrixRow(dec->ChannelMix, dec->Matrix.Dual[chan][FB_LowFreq],
491 dec->SamplesLF, dec->NumChannels, SamplesToDo
494 if(dec->Delay[chan].Length > 0)
496 const ALuint base = dec->Delay[chan].Length;
497 if(SamplesToDo >= base)
499 for(i = 0;i < base;i++)
500 OutBuffer[chan][i] += dec->Delay[chan].Buffer[i];
501 for(;i < SamplesToDo;i++)
502 OutBuffer[chan][i] += dec->ChannelMix[i-base];
503 memcpy(dec->Delay[chan].Buffer, &dec->ChannelMix[SamplesToDo-base],
504 base*sizeof(ALfloat));
506 else
508 for(i = 0;i < SamplesToDo;i++)
509 OutBuffer[chan][i] += dec->Delay[chan].Buffer[i];
510 memmove(dec->Delay[chan].Buffer, dec->Delay[chan].Buffer+SamplesToDo,
511 base - SamplesToDo);
512 memcpy(dec->Delay[chan].Buffer+base-SamplesToDo, dec->ChannelMix,
513 SamplesToDo*sizeof(ALfloat));
516 else for(i = 0;i < SamplesToDo;i++)
517 OutBuffer[chan][i] += dec->ChannelMix[i];
520 else
522 for(chan = 0;chan < OutChannels;chan++)
524 if(!dec->Enabled[chan])
525 continue;
527 memset(dec->ChannelMix, 0, SamplesToDo*sizeof(ALfloat));
528 MixMatrixRow(dec->ChannelMix, dec->Matrix.Single[chan], InSamples,
529 dec->NumChannels, SamplesToDo);
531 if(dec->Delay[chan].Length > 0)
533 const ALuint base = dec->Delay[chan].Length;
534 if(SamplesToDo >= base)
536 for(i = 0;i < base;i++)
537 OutBuffer[chan][i] += dec->Delay[chan].Buffer[i];
538 for(;i < SamplesToDo;i++)
539 OutBuffer[chan][i] += dec->ChannelMix[i-base];
540 memcpy(dec->Delay[chan].Buffer, &dec->ChannelMix[SamplesToDo-base],
541 base*sizeof(ALfloat));
543 else
545 for(i = 0;i < SamplesToDo;i++)
546 OutBuffer[chan][i] += dec->Delay[chan].Buffer[i];
547 memmove(dec->Delay[chan].Buffer, dec->Delay[chan].Buffer+SamplesToDo,
548 base - SamplesToDo);
549 memcpy(dec->Delay[chan].Buffer+base-SamplesToDo, dec->ChannelMix,
550 SamplesToDo*sizeof(ALfloat));
553 else for(i = 0;i < SamplesToDo;i++)
554 OutBuffer[chan][i] += dec->ChannelMix[i];
560 void bformatdec_upSample(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint InChannels, ALuint SamplesToDo)
562 ALuint i, j, k;
564 /* First, split the first-order components into low and high frequency
565 * bands. This assumes SamplesHF and SamplesLF have enough space for first-
566 * order content (to which, this up-sampler is only used with second-order
567 * or higher decoding, so it will).
569 for(i = 0;i < InChannels;i++)
570 bandsplit_process(&dec->UpSampler.XOver[i], dec->SamplesHF[i], dec->SamplesLF[i],
571 InSamples[i], SamplesToDo);
573 /* This up-sampler is very simplistic. It essentially decodes the first-
574 * order content to a square channel array (or cube if height is desired),
575 * then encodes those points onto the higher order soundfield.
577 for(k = 0;k < dec->UpSampler.NumChannels;k++)
579 memset(dec->ChannelMix, 0, SamplesToDo*sizeof(ALfloat));
580 MixMatrixRow(dec->ChannelMix, dec->UpSampler.Matrix[k][FB_HighFreq],
581 dec->SamplesHF, InChannels, SamplesToDo);
582 MixMatrixRow(dec->ChannelMix, dec->UpSampler.Matrix[k][FB_LowFreq],
583 dec->SamplesLF, InChannels, SamplesToDo);
585 for(j = 0;j < dec->NumChannels;j++)
587 ALfloat gain = dec->UpSampler.Encoder[k][j];
588 if(!(fabsf(gain) > GAIN_SILENCE_THRESHOLD))
589 continue;
590 for(i = 0;i < SamplesToDo;i++)
591 OutBuffer[j][i] += dec->ChannelMix[i] * gain;
597 typedef struct AmbiUpsampler {
598 alignas(16) ALfloat SamplesHF[4][BUFFERSIZE];
599 alignas(16) ALfloat SamplesLF[4][BUFFERSIZE];
601 alignas(16) ALfloat ChannelMix[BUFFERSIZE];
603 BandSplitter XOver[4];
605 ALfloat Gains[8][MAX_OUTPUT_CHANNELS];
606 ALuint NumChannels;
607 } AmbiUpsampler;
609 AmbiUpsampler *ambiup_alloc()
611 alcall_once(&bformatdec_inited, init_bformatdec);
612 return al_calloc(16, sizeof(AmbiUpsampler));
615 void ambiup_free(struct AmbiUpsampler *ambiup)
617 al_free(ambiup);
620 void ambiup_reset(struct AmbiUpsampler *ambiup, const ALCdevice *device)
622 ALfloat ratio;
623 ALuint i;
625 ratio = 400.0f / (ALfloat)device->Frequency;
626 for(i = 0;i < 4;i++)
627 bandsplit_init(&ambiup->XOver[i], ratio);
629 ambiup->NumChannels = COUNTOF(CubePoints);
630 for(i = 0;i < ambiup->NumChannels;i++)
631 ComputePanningGains(device->Dry, CubeEncoder[i], 1.0f, ambiup->Gains[i]);
634 void ambiup_process(struct AmbiUpsampler *ambiup, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint OutChannels, ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint SamplesToDo)
636 ALuint i, j, k;
638 for(i = 0;i < 4;i++)
639 bandsplit_process(&ambiup->XOver[i], ambiup->SamplesHF[i], ambiup->SamplesLF[i],
640 InSamples[i], SamplesToDo);
642 for(k = 0;k < ambiup->NumChannels;k++)
644 memset(ambiup->ChannelMix, 0, SamplesToDo*sizeof(ALfloat));
645 MixMatrixRow(ambiup->ChannelMix, CubeMatrix[k][FB_HighFreq],
646 ambiup->SamplesHF, 4, SamplesToDo);
647 MixMatrixRow(ambiup->ChannelMix, CubeMatrix[k][FB_LowFreq],
648 ambiup->SamplesLF, 4, SamplesToDo);
650 for(j = 0;j < OutChannels;j++)
652 ALfloat gain = ambiup->Gains[k][j];
653 if(!(fabsf(gain) > GAIN_SILENCE_THRESHOLD))
654 continue;
655 for(i = 0;i < SamplesToDo;i++)
656 OutBuffer[j][i] += ambiup->ChannelMix[i] * gain;