Update some atomic memory ordering
[openal-soft.git] / Alc / bformatdec.c
blob2aab4ed8f4f3be841c87e352a7d1411e7a5e4622
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 /* These points are in AL coordinates! */
126 static const ALfloat Ambi2DPoints[4][3] = {
127 { -0.707106781f, 0.0f, -0.707106781f },
128 { 0.707106781f, 0.0f, -0.707106781f },
129 { -0.707106781f, 0.0f, 0.707106781f },
130 { 0.707106781f, 0.0f, 0.707106781f },
132 static const ALfloat Ambi2DDecoder[4][FB_Max][MAX_AMBI_COEFFS] = {
133 { { 0.353553f, 0.204094f, 0.0f, 0.204094f }, { 0.25f, 0.204094f, 0.0f, 0.204094f } },
134 { { 0.353553f, -0.204094f, 0.0f, 0.204094f }, { 0.25f, -0.204094f, 0.0f, 0.204094f } },
135 { { 0.353553f, 0.204094f, 0.0f, -0.204094f }, { 0.25f, 0.204094f, 0.0f, -0.204094f } },
136 { { 0.353553f, -0.204094f, 0.0f, -0.204094f }, { 0.25f, -0.204094f, 0.0f, -0.204094f } },
138 static ALfloat Ambi2DEncoder[4][MAX_AMBI_COEFFS];
140 /* These points are in AL coordinates! */
141 static const ALfloat Ambi3DPoints[8][3] = {
142 { -0.577350269f, 0.577350269f, -0.577350269f },
143 { 0.577350269f, 0.577350269f, -0.577350269f },
144 { -0.577350269f, 0.577350269f, 0.577350269f },
145 { 0.577350269f, 0.577350269f, 0.577350269f },
146 { -0.577350269f, -0.577350269f, -0.577350269f },
147 { 0.577350269f, -0.577350269f, -0.577350269f },
148 { -0.577350269f, -0.577350269f, 0.577350269f },
149 { 0.577350269f, -0.577350269f, 0.577350269f },
151 static const ALfloat Ambi3DDecoder[8][FB_Max][MAX_AMBI_COEFFS] = {
152 { { 0.25f, 0.1443375672f, 0.1443375672f, 0.1443375672f }, { 0.125f, 0.125f, 0.125f, 0.125f } },
153 { { 0.25f, -0.1443375672f, 0.1443375672f, 0.1443375672f }, { 0.125f, -0.125f, 0.125f, 0.125f } },
154 { { 0.25f, 0.1443375672f, 0.1443375672f, -0.1443375672f }, { 0.125f, 0.125f, 0.125f, -0.125f } },
155 { { 0.25f, -0.1443375672f, 0.1443375672f, -0.1443375672f }, { 0.125f, -0.125f, 0.125f, -0.125f } },
156 { { 0.25f, 0.1443375672f, -0.1443375672f, 0.1443375672f }, { 0.125f, 0.125f, -0.125f, 0.125f } },
157 { { 0.25f, -0.1443375672f, -0.1443375672f, 0.1443375672f }, { 0.125f, -0.125f, -0.125f, 0.125f } },
158 { { 0.25f, 0.1443375672f, -0.1443375672f, -0.1443375672f }, { 0.125f, 0.125f, -0.125f, -0.125f } },
159 { { 0.25f, -0.1443375672f, -0.1443375672f, -0.1443375672f }, { 0.125f, -0.125f, -0.125f, -0.125f } },
161 static ALfloat Ambi3DEncoder[8][MAX_AMBI_COEFFS];
164 static RowMixerFunc MixMatrixRow = MixRow_C;
167 static alonce_flag bformatdec_inited = AL_ONCE_FLAG_INIT;
169 static void init_bformatdec(void)
171 ALuint i, j;
173 MixMatrixRow = SelectRowMixer();
175 for(i = 0;i < COUNTOF(Ambi3DPoints);i++)
176 CalcDirectionCoeffs(Ambi3DPoints[i], 0.0f, Ambi3DEncoder[i]);
178 for(i = 0;i < COUNTOF(Ambi2DPoints);i++)
180 CalcDirectionCoeffs(Ambi2DPoints[i], 0.0f, Ambi2DEncoder[i]);
182 /* Remove the skipped height-related coefficients for 2D rendering. */
183 Ambi2DEncoder[i][2] = Ambi2DEncoder[i][3];
184 Ambi2DEncoder[i][3] = Ambi2DEncoder[i][4];
185 Ambi2DEncoder[i][4] = Ambi2DEncoder[i][8];
186 Ambi2DEncoder[i][5] = Ambi2DEncoder[i][9];
187 Ambi2DEncoder[i][6] = Ambi2DEncoder[i][15];
188 for(j = 7;j < MAX_AMBI_COEFFS;j++)
189 Ambi2DEncoder[i][j] = 0.0f;
194 #define MAX_DELAY_LENGTH 128
196 /* NOTE: BandSplitter filters are unused with single-band decoding */
197 typedef struct BFormatDec {
198 ALboolean Enabled[MAX_OUTPUT_CHANNELS];
200 union {
201 alignas(16) ALfloat Dual[MAX_OUTPUT_CHANNELS][FB_Max][MAX_AMBI_COEFFS];
202 alignas(16) ALfloat Single[MAX_OUTPUT_CHANNELS][MAX_AMBI_COEFFS];
203 } Matrix;
205 BandSplitter XOver[MAX_AMBI_COEFFS];
207 ALfloat (*Samples)[BUFFERSIZE];
208 /* These two alias into Samples */
209 ALfloat (*SamplesHF)[BUFFERSIZE];
210 ALfloat (*SamplesLF)[BUFFERSIZE];
212 alignas(16) ALfloat ChannelMix[BUFFERSIZE];
214 struct {
215 alignas(16) ALfloat Buffer[MAX_DELAY_LENGTH];
216 ALuint Length; /* Valid range is [0...MAX_DELAY_LENGTH). */
217 } Delay[MAX_OUTPUT_CHANNELS];
219 struct {
220 BandSplitter XOver[4];
222 ALfloat Gains[4][MAX_OUTPUT_CHANNELS][FB_Max];
223 } UpSampler;
225 ALuint NumChannels;
226 ALboolean DualBand;
227 ALboolean Periphonic;
228 } BFormatDec;
230 BFormatDec *bformatdec_alloc()
232 alcall_once(&bformatdec_inited, init_bformatdec);
233 return al_calloc(16, sizeof(BFormatDec));
236 void bformatdec_free(BFormatDec *dec)
238 if(dec)
240 al_free(dec->Samples);
241 dec->Samples = NULL;
242 dec->SamplesHF = NULL;
243 dec->SamplesLF = NULL;
245 memset(dec, 0, sizeof(*dec));
246 al_free(dec);
250 int bformatdec_getOrder(const struct BFormatDec *dec)
252 if(dec->Periphonic)
254 if(dec->NumChannels > 9) return 3;
255 if(dec->NumChannels > 4) return 2;
256 if(dec->NumChannels > 1) return 1;
258 else
260 if(dec->NumChannels > 5) return 3;
261 if(dec->NumChannels > 3) return 2;
262 if(dec->NumChannels > 1) return 1;
264 return 0;
267 void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALuint chancount, ALuint srate, const ALuint chanmap[MAX_OUTPUT_CHANNELS], int flags)
269 static const ALuint map2DTo3D[MAX_AMBI2D_COEFFS] = {
270 0, 1, 3, 4, 8, 9, 15
272 const ALfloat *coeff_scale = UnitScale;
273 ALfloat distgain[MAX_OUTPUT_CHANNELS];
274 ALfloat maxdist, ratio;
275 ALuint i, j, k;
277 al_free(dec->Samples);
278 dec->Samples = NULL;
279 dec->SamplesHF = NULL;
280 dec->SamplesLF = NULL;
282 dec->NumChannels = chancount;
283 dec->Samples = al_calloc(16, dec->NumChannels*2 * sizeof(dec->Samples[0]));
284 dec->SamplesHF = dec->Samples;
285 dec->SamplesLF = dec->SamplesHF + dec->NumChannels;
287 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
288 dec->Enabled[i] = AL_FALSE;
289 for(i = 0;i < conf->NumSpeakers;i++)
290 dec->Enabled[chanmap[i]] = AL_TRUE;
292 if(conf->CoeffScale == ADS_SN3D)
293 coeff_scale = SN3D2N3DScale;
294 else if(conf->CoeffScale == ADS_FuMa)
295 coeff_scale = FuMa2N3DScale;
297 ratio = 400.0f / (ALfloat)srate;
298 for(i = 0;i < 4;i++)
299 bandsplit_init(&dec->UpSampler.XOver[i], ratio);
300 memset(dec->UpSampler.Gains, 0, sizeof(dec->UpSampler.Gains));
301 if((conf->ChanMask&AMBI_PERIPHONIC_MASK))
303 /* Combine the matrices that do the in->virt and virt->out conversions
304 * so we get a single in->out conversion.
306 for(i = 0;i < 4;i++)
308 for(j = 0;j < dec->NumChannels;j++)
310 ALfloat *gains = dec->UpSampler.Gains[i][j];
311 for(k = 0;k < COUNTOF(Ambi3DDecoder);k++)
313 gains[FB_HighFreq] += Ambi3DDecoder[k][FB_HighFreq][i]*Ambi3DEncoder[k][j];
314 gains[FB_LowFreq] += Ambi3DDecoder[k][FB_LowFreq][i]*Ambi3DEncoder[k][j];
319 dec->Periphonic = AL_TRUE;
321 else
323 for(i = 0;i < 4;i++)
325 for(j = 0;j < dec->NumChannels;j++)
327 ALfloat *gains = dec->UpSampler.Gains[i][j];
328 for(k = 0;k < COUNTOF(Ambi2DDecoder);k++)
330 gains[FB_HighFreq] += Ambi2DDecoder[k][FB_HighFreq][i]*Ambi2DEncoder[k][j];
331 gains[FB_LowFreq] += Ambi2DDecoder[k][FB_LowFreq][i]*Ambi2DEncoder[k][j];
336 dec->Periphonic = AL_FALSE;
339 maxdist = 0.0f;
340 for(i = 0;i < conf->NumSpeakers;i++)
342 maxdist = maxf(maxdist, conf->Speakers[i].Distance);
343 distgain[i] = 1.0f;
346 memset(dec->Delay, 0, sizeof(dec->Delay));
347 if((flags&BFDF_DistanceComp) && maxdist > 0.0f)
349 for(i = 0;i < conf->NumSpeakers;i++)
351 ALuint chan = chanmap[i];
352 ALfloat delay;
354 /* Distance compensation only delays in steps of the sample rate.
355 * This is a bit less accurate since the delay time falls to the
356 * nearest sample time, but it's far simpler as it doesn't have to
357 * deal with phase offsets. This means at 48khz, for instance, the
358 * distance delay will be in steps of about 7 millimeters.
360 delay = floorf((maxdist-conf->Speakers[i].Distance) / SPEEDOFSOUNDMETRESPERSEC *
361 (ALfloat)srate + 0.5f);
362 if(delay >= (ALfloat)MAX_DELAY_LENGTH)
363 ERR("Delay for speaker \"%s\" exceeds buffer length (%f >= %u)\n",
364 al_string_get_cstr(conf->Speakers[i].Name), delay, MAX_DELAY_LENGTH);
366 dec->Delay[chan].Length = (ALuint)clampf(delay, 0.0f, (ALfloat)(MAX_DELAY_LENGTH-1));
367 distgain[i] = conf->Speakers[i].Distance / maxdist;
368 TRACE("Channel %u \"%s\" distance compensation: %u samples, %f gain\n", chan,
369 al_string_get_cstr(conf->Speakers[i].Name), dec->Delay[chan].Length, distgain[i]
374 memset(&dec->Matrix, 0, sizeof(dec->Matrix));
375 if(conf->FreqBands == 1)
377 dec->DualBand = AL_FALSE;
378 for(i = 0;i < conf->NumSpeakers;i++)
380 ALuint chan = chanmap[i];
381 ALfloat gain;
382 ALuint j, k;
384 if(!dec->Periphonic)
386 for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
388 ALuint l = map2DTo3D[j];
389 if(j == 0) gain = conf->HFOrderGain[0];
390 else if(j == 1) gain = conf->HFOrderGain[1];
391 else if(j == 3) gain = conf->HFOrderGain[2];
392 else if(j == 5) gain = conf->HFOrderGain[3];
393 if((conf->ChanMask&(1<<l)))
394 dec->Matrix.Single[chan][j] = conf->HFMatrix[i][k++] / coeff_scale[l] *
395 gain * distgain[i];
398 else
400 for(j = 0,k = 0;j < MAX_AMBI_COEFFS;j++)
402 if(j == 0) gain = conf->HFOrderGain[0];
403 else if(j == 1) gain = conf->HFOrderGain[1];
404 else if(j == 4) gain = conf->HFOrderGain[2];
405 else if(j == 9) gain = conf->HFOrderGain[3];
406 if((conf->ChanMask&(1<<j)))
407 dec->Matrix.Single[chan][j] = conf->HFMatrix[i][k++] / coeff_scale[j] *
408 gain * distgain[i];
413 else
415 dec->DualBand = AL_TRUE;
417 ratio = conf->XOverFreq / (ALfloat)srate;
418 for(i = 0;i < MAX_AMBI_COEFFS;i++)
419 bandsplit_init(&dec->XOver[i], ratio);
421 ratio = powf(10.0f, conf->XOverRatio / 40.0f);
422 for(i = 0;i < conf->NumSpeakers;i++)
424 ALuint chan = chanmap[i];
425 ALfloat gain;
426 ALuint j, k;
428 if(!dec->Periphonic)
430 for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
432 ALuint l = map2DTo3D[j];
433 if(j == 0) gain = conf->HFOrderGain[0] * ratio;
434 else if(j == 1) gain = conf->HFOrderGain[1] * ratio;
435 else if(j == 3) gain = conf->HFOrderGain[2] * ratio;
436 else if(j == 5) gain = conf->HFOrderGain[3] * ratio;
437 if((conf->ChanMask&(1<<l)))
438 dec->Matrix.Dual[chan][FB_HighFreq][j] = conf->HFMatrix[i][k++] /
439 coeff_scale[l] * gain *
440 distgain[i];
442 for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
444 ALuint l = map2DTo3D[j];
445 if(j == 0) gain = conf->LFOrderGain[0] / ratio;
446 else if(j == 1) gain = conf->LFOrderGain[1] / ratio;
447 else if(j == 3) gain = conf->LFOrderGain[2] / ratio;
448 else if(j == 5) gain = conf->LFOrderGain[3] / ratio;
449 if((conf->ChanMask&(1<<l)))
450 dec->Matrix.Dual[chan][FB_LowFreq][j] = conf->LFMatrix[i][k++] /
451 coeff_scale[l] * gain *
452 distgain[i];
455 else
457 for(j = 0,k = 0;j < MAX_AMBI_COEFFS;j++)
459 if(j == 0) gain = conf->HFOrderGain[0] * ratio;
460 else if(j == 1) gain = conf->HFOrderGain[1] * ratio;
461 else if(j == 4) gain = conf->HFOrderGain[2] * ratio;
462 else if(j == 9) gain = conf->HFOrderGain[3] * ratio;
463 if((conf->ChanMask&(1<<j)))
464 dec->Matrix.Dual[chan][FB_HighFreq][j] = conf->HFMatrix[i][k++] /
465 coeff_scale[j] * gain *
466 distgain[i];
468 for(j = 0,k = 0;j < MAX_AMBI_COEFFS;j++)
470 if(j == 0) gain = conf->LFOrderGain[0] / ratio;
471 else if(j == 1) gain = conf->LFOrderGain[1] / ratio;
472 else if(j == 4) gain = conf->LFOrderGain[2] / ratio;
473 else if(j == 9) gain = conf->LFOrderGain[3] / ratio;
474 if((conf->ChanMask&(1<<j)))
475 dec->Matrix.Dual[chan][FB_LowFreq][j] = conf->LFMatrix[i][k++] /
476 coeff_scale[j] * gain *
477 distgain[i];
485 void bformatdec_process(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint OutChannels, const ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint SamplesToDo)
487 ALuint chan, i;
489 if(dec->DualBand)
491 for(i = 0;i < dec->NumChannels;i++)
492 bandsplit_process(&dec->XOver[i], dec->SamplesHF[i], dec->SamplesLF[i],
493 InSamples[i], SamplesToDo);
495 for(chan = 0;chan < OutChannels;chan++)
497 if(!dec->Enabled[chan])
498 continue;
500 memset(dec->ChannelMix, 0, SamplesToDo*sizeof(ALfloat));
501 MixMatrixRow(dec->ChannelMix, dec->Matrix.Dual[chan][FB_HighFreq],
502 SAFE_CONST(ALfloatBUFFERSIZE*,dec->SamplesHF), dec->NumChannels, 0,
503 SamplesToDo
505 MixMatrixRow(dec->ChannelMix, dec->Matrix.Dual[chan][FB_LowFreq],
506 SAFE_CONST(ALfloatBUFFERSIZE*,dec->SamplesLF), dec->NumChannels, 0,
507 SamplesToDo
510 if(dec->Delay[chan].Length > 0)
512 const ALuint base = dec->Delay[chan].Length;
513 if(SamplesToDo >= base)
515 for(i = 0;i < base;i++)
516 OutBuffer[chan][i] += dec->Delay[chan].Buffer[i];
517 for(;i < SamplesToDo;i++)
518 OutBuffer[chan][i] += dec->ChannelMix[i-base];
519 memcpy(dec->Delay[chan].Buffer, &dec->ChannelMix[SamplesToDo-base],
520 base*sizeof(ALfloat));
522 else
524 for(i = 0;i < SamplesToDo;i++)
525 OutBuffer[chan][i] += dec->Delay[chan].Buffer[i];
526 memmove(dec->Delay[chan].Buffer, dec->Delay[chan].Buffer+SamplesToDo,
527 base - SamplesToDo);
528 memcpy(dec->Delay[chan].Buffer+base-SamplesToDo, dec->ChannelMix,
529 SamplesToDo*sizeof(ALfloat));
532 else for(i = 0;i < SamplesToDo;i++)
533 OutBuffer[chan][i] += dec->ChannelMix[i];
536 else
538 for(chan = 0;chan < OutChannels;chan++)
540 if(!dec->Enabled[chan])
541 continue;
543 memset(dec->ChannelMix, 0, SamplesToDo*sizeof(ALfloat));
544 MixMatrixRow(dec->ChannelMix, dec->Matrix.Single[chan], InSamples,
545 dec->NumChannels, 0, SamplesToDo);
547 if(dec->Delay[chan].Length > 0)
549 const ALuint base = dec->Delay[chan].Length;
550 if(SamplesToDo >= base)
552 for(i = 0;i < base;i++)
553 OutBuffer[chan][i] += dec->Delay[chan].Buffer[i];
554 for(;i < SamplesToDo;i++)
555 OutBuffer[chan][i] += dec->ChannelMix[i-base];
556 memcpy(dec->Delay[chan].Buffer, &dec->ChannelMix[SamplesToDo-base],
557 base*sizeof(ALfloat));
559 else
561 for(i = 0;i < SamplesToDo;i++)
562 OutBuffer[chan][i] += dec->Delay[chan].Buffer[i];
563 memmove(dec->Delay[chan].Buffer, dec->Delay[chan].Buffer+SamplesToDo,
564 base - SamplesToDo);
565 memcpy(dec->Delay[chan].Buffer+base-SamplesToDo, dec->ChannelMix,
566 SamplesToDo*sizeof(ALfloat));
569 else for(i = 0;i < SamplesToDo;i++)
570 OutBuffer[chan][i] += dec->ChannelMix[i];
576 void bformatdec_upSample(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint InChannels, ALuint SamplesToDo)
578 ALuint i, j;
580 /* This up-sampler is very simplistic. It essentially decodes the first-
581 * order content to a square channel array (or cube if height is desired),
582 * then encodes those points onto the higher order soundfield. The decoder
583 * and encoder matrices have been combined to directly convert each input
584 * channel to the output, without the need for storing the virtual channel
585 * array.
587 for(i = 0;i < InChannels;i++)
589 /* First, split the first-order components into low and high frequency
590 * bands.
592 bandsplit_process(&dec->UpSampler.XOver[i],
593 dec->Samples[FB_HighFreq], dec->Samples[FB_LowFreq],
594 InSamples[i], SamplesToDo
597 /* Now write each band to the output. */
598 for(j = 0;j < dec->NumChannels;j++)
599 MixMatrixRow(OutBuffer[j], dec->UpSampler.Gains[i][j],
600 SAFE_CONST(ALfloatBUFFERSIZE*,dec->Samples), FB_Max, 0,
601 SamplesToDo
607 typedef struct AmbiUpsampler {
608 alignas(16) ALfloat Samples[FB_Max][BUFFERSIZE];
610 BandSplitter XOver[4];
612 ALfloat Gains[4][MAX_OUTPUT_CHANNELS][FB_Max];
613 } AmbiUpsampler;
615 AmbiUpsampler *ambiup_alloc()
617 alcall_once(&bformatdec_inited, init_bformatdec);
618 return al_calloc(16, sizeof(AmbiUpsampler));
621 void ambiup_free(struct AmbiUpsampler *ambiup)
623 al_free(ambiup);
626 void ambiup_reset(struct AmbiUpsampler *ambiup, const ALCdevice *device)
628 ALfloat gains[8][MAX_OUTPUT_CHANNELS];
629 ALfloat ratio;
630 ALuint i, j, k;
632 ratio = 400.0f / (ALfloat)device->Frequency;
633 for(i = 0;i < 4;i++)
634 bandsplit_init(&ambiup->XOver[i], ratio);
636 for(i = 0;i < COUNTOF(Ambi3DEncoder);i++)
637 ComputePanningGains(device->Dry, Ambi3DEncoder[i], 1.0f, gains[i]);
639 memset(ambiup->Gains, 0, sizeof(ambiup->Gains));
640 for(i = 0;i < 4;i++)
642 for(j = 0;j < device->Dry.NumChannels;j++)
644 for(k = 0;k < COUNTOF(Ambi3DDecoder);k++)
646 ambiup->Gains[i][j][FB_HighFreq] += Ambi3DDecoder[k][FB_HighFreq][i]*gains[k][j];
647 ambiup->Gains[i][j][FB_LowFreq] += Ambi3DDecoder[k][FB_LowFreq][i]*gains[k][j];
653 void ambiup_process(struct AmbiUpsampler *ambiup, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint OutChannels, const ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint SamplesToDo)
655 ALuint i, j;
657 for(i = 0;i < 4;i++)
659 bandsplit_process(&ambiup->XOver[i],
660 ambiup->Samples[FB_HighFreq], ambiup->Samples[FB_LowFreq],
661 InSamples[i], SamplesToDo
664 for(j = 0;j < OutChannels;j++)
665 MixMatrixRow(OutBuffer[j], ambiup->Gains[i][j],
666 SAFE_CONST(ALfloatBUFFERSIZE*,ambiup->Samples), FB_Max, 0,
667 SamplesToDo