bformatdec.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. #include "config.h"
  2. #include "bformatdec.h"
  3. #include "ambdec.h"
  4. #include "alu.h"
  5. #include "bool.h"
  6. #include "threads.h"
  7. #include "almalloc.h"
  8. void bandsplit_init(BandSplitter *splitter, ALfloat f0norm)
  9. {
  10. ALfloat w = f0norm * F_TAU;
  11. ALfloat cw = cosf(w);
  12. if(cw > FLT_EPSILON)
  13. splitter->coeff = (sinf(w) - 1.0f) / cw;
  14. else
  15. splitter->coeff = cw * -0.5f;
  16. splitter->lp_z1 = 0.0f;
  17. splitter->lp_z2 = 0.0f;
  18. splitter->hp_z1 = 0.0f;
  19. }
  20. void bandsplit_clear(BandSplitter *splitter)
  21. {
  22. splitter->lp_z1 = 0.0f;
  23. splitter->lp_z2 = 0.0f;
  24. splitter->hp_z1 = 0.0f;
  25. }
  26. void bandsplit_process(BandSplitter *splitter, ALfloat *restrict hpout, ALfloat *restrict lpout,
  27. const ALfloat *input, ALsizei count)
  28. {
  29. ALfloat lp_coeff, hp_coeff, lp_y, hp_y, d;
  30. ALfloat lp_z1, lp_z2, hp_z1;
  31. ALsizei i;
  32. hp_coeff = splitter->coeff;
  33. lp_coeff = splitter->coeff*0.5f + 0.5f;
  34. lp_z1 = splitter->lp_z1;
  35. lp_z2 = splitter->lp_z2;
  36. hp_z1 = splitter->hp_z1;
  37. for(i = 0;i < count;i++)
  38. {
  39. ALfloat in = input[i];
  40. /* Low-pass sample processing. */
  41. d = (in - lp_z1) * lp_coeff;
  42. lp_y = lp_z1 + d;
  43. lp_z1 = lp_y + d;
  44. d = (lp_y - lp_z2) * lp_coeff;
  45. lp_y = lp_z2 + d;
  46. lp_z2 = lp_y + d;
  47. lpout[i] = lp_y;
  48. /* All-pass sample processing. */
  49. d = in - hp_coeff*hp_z1;
  50. hp_y = hp_z1 + hp_coeff*d;
  51. hp_z1 = d;
  52. /* High-pass generated from removing low-passed output. */
  53. hpout[i] = hp_y - lp_y;
  54. }
  55. splitter->lp_z1 = lp_z1;
  56. splitter->lp_z2 = lp_z2;
  57. splitter->hp_z1 = hp_z1;
  58. }
  59. void splitterap_init(SplitterAllpass *splitter, ALfloat f0norm)
  60. {
  61. ALfloat w = f0norm * F_TAU;
  62. ALfloat cw = cosf(w);
  63. if(cw > FLT_EPSILON)
  64. splitter->coeff = (sinf(w) - 1.0f) / cw;
  65. else
  66. splitter->coeff = cw * -0.5f;
  67. splitter->z1 = 0.0f;
  68. }
  69. void splitterap_clear(SplitterAllpass *splitter)
  70. {
  71. splitter->z1 = 0.0f;
  72. }
  73. void splitterap_process(SplitterAllpass *splitter, ALfloat *restrict samples, ALsizei count)
  74. {
  75. ALfloat coeff, d, x;
  76. ALfloat z1;
  77. ALsizei i;
  78. coeff = splitter->coeff;
  79. z1 = splitter->z1;
  80. for(i = 0;i < count;i++)
  81. {
  82. x = samples[i];
  83. d = x - coeff*z1;
  84. x = z1 + coeff*d;
  85. z1 = d;
  86. samples[i] = x;
  87. }
  88. splitter->z1 = z1;
  89. }
  90. /* NOTE: These are scale factors as applied to Ambisonics content. Decoder
  91. * coefficients should be divided by these values to get proper N3D scalings.
  92. */
  93. const ALfloat N3D2N3DScale[MAX_AMBI_COEFFS] = {
  94. 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
  95. 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f
  96. };
  97. const ALfloat SN3D2N3DScale[MAX_AMBI_COEFFS] = {
  98. 1.000000000f, /* ACN 0 (W), sqrt(1) */
  99. 1.732050808f, /* ACN 1 (Y), sqrt(3) */
  100. 1.732050808f, /* ACN 2 (Z), sqrt(3) */
  101. 1.732050808f, /* ACN 3 (X), sqrt(3) */
  102. 2.236067978f, /* ACN 4 (V), sqrt(5) */
  103. 2.236067978f, /* ACN 5 (T), sqrt(5) */
  104. 2.236067978f, /* ACN 6 (R), sqrt(5) */
  105. 2.236067978f, /* ACN 7 (S), sqrt(5) */
  106. 2.236067978f, /* ACN 8 (U), sqrt(5) */
  107. 2.645751311f, /* ACN 9 (Q), sqrt(7) */
  108. 2.645751311f, /* ACN 10 (O), sqrt(7) */
  109. 2.645751311f, /* ACN 11 (M), sqrt(7) */
  110. 2.645751311f, /* ACN 12 (K), sqrt(7) */
  111. 2.645751311f, /* ACN 13 (L), sqrt(7) */
  112. 2.645751311f, /* ACN 14 (N), sqrt(7) */
  113. 2.645751311f, /* ACN 15 (P), sqrt(7) */
  114. };
  115. const ALfloat FuMa2N3DScale[MAX_AMBI_COEFFS] = {
  116. 1.414213562f, /* ACN 0 (W), sqrt(2) */
  117. 1.732050808f, /* ACN 1 (Y), sqrt(3) */
  118. 1.732050808f, /* ACN 2 (Z), sqrt(3) */
  119. 1.732050808f, /* ACN 3 (X), sqrt(3) */
  120. 1.936491673f, /* ACN 4 (V), sqrt(15)/2 */
  121. 1.936491673f, /* ACN 5 (T), sqrt(15)/2 */
  122. 2.236067978f, /* ACN 6 (R), sqrt(5) */
  123. 1.936491673f, /* ACN 7 (S), sqrt(15)/2 */
  124. 1.936491673f, /* ACN 8 (U), sqrt(15)/2 */
  125. 2.091650066f, /* ACN 9 (Q), sqrt(35/8) */
  126. 1.972026594f, /* ACN 10 (O), sqrt(35)/3 */
  127. 2.231093404f, /* ACN 11 (M), sqrt(224/45) */
  128. 2.645751311f, /* ACN 12 (K), sqrt(7) */
  129. 2.231093404f, /* ACN 13 (L), sqrt(224/45) */
  130. 1.972026594f, /* ACN 14 (N), sqrt(35)/3 */
  131. 2.091650066f, /* ACN 15 (P), sqrt(35/8) */
  132. };
  133. #define HF_BAND 0
  134. #define LF_BAND 1
  135. #define NUM_BANDS 2
  136. /* These points are in AL coordinates! */
  137. static const ALfloat Ambi3DPoints[8][3] = {
  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 },
  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. };
  147. static const ALfloat Ambi3DDecoder[8][MAX_AMBI_COEFFS] = {
  148. { 0.125f, 0.125f, 0.125f, 0.125f },
  149. { 0.125f, -0.125f, 0.125f, 0.125f },
  150. { 0.125f, 0.125f, 0.125f, -0.125f },
  151. { 0.125f, -0.125f, 0.125f, -0.125f },
  152. { 0.125f, 0.125f, -0.125f, 0.125f },
  153. { 0.125f, -0.125f, -0.125f, 0.125f },
  154. { 0.125f, 0.125f, -0.125f, -0.125f },
  155. { 0.125f, -0.125f, -0.125f, -0.125f },
  156. };
  157. static const ALfloat Ambi3DDecoderHFScale[MAX_AMBI_COEFFS] = {
  158. 2.0f,
  159. 1.15470054f, 1.15470054f, 1.15470054f
  160. };
  161. /* NOTE: BandSplitter filters are unused with single-band decoding */
  162. typedef struct BFormatDec {
  163. ALuint Enabled; /* Bitfield of enabled channels. */
  164. union {
  165. alignas(16) ALfloat Dual[MAX_OUTPUT_CHANNELS][NUM_BANDS][MAX_AMBI_COEFFS];
  166. alignas(16) ALfloat Single[MAX_OUTPUT_CHANNELS][MAX_AMBI_COEFFS];
  167. } Matrix;
  168. BandSplitter XOver[MAX_AMBI_COEFFS];
  169. ALfloat (*Samples)[BUFFERSIZE];
  170. /* These two alias into Samples */
  171. ALfloat (*SamplesHF)[BUFFERSIZE];
  172. ALfloat (*SamplesLF)[BUFFERSIZE];
  173. alignas(16) ALfloat ChannelMix[BUFFERSIZE];
  174. struct {
  175. BandSplitter XOver;
  176. ALfloat Gains[NUM_BANDS];
  177. } UpSampler[4];
  178. ALsizei NumChannels;
  179. ALboolean DualBand;
  180. } BFormatDec;
  181. BFormatDec *bformatdec_alloc()
  182. {
  183. return al_calloc(16, sizeof(BFormatDec));
  184. }
  185. void bformatdec_free(BFormatDec **dec)
  186. {
  187. if(dec && *dec)
  188. {
  189. al_free((*dec)->Samples);
  190. (*dec)->Samples = NULL;
  191. (*dec)->SamplesHF = NULL;
  192. (*dec)->SamplesLF = NULL;
  193. al_free(*dec);
  194. *dec = NULL;
  195. }
  196. }
  197. void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount, ALuint srate, const ALsizei chanmap[MAX_OUTPUT_CHANNELS])
  198. {
  199. static const ALsizei map2DTo3D[MAX_AMBI2D_COEFFS] = {
  200. 0, 1, 3, 4, 8, 9, 15
  201. };
  202. const ALfloat *coeff_scale = N3D2N3DScale;
  203. bool periphonic;
  204. ALfloat ratio;
  205. ALsizei i;
  206. al_free(dec->Samples);
  207. dec->Samples = NULL;
  208. dec->SamplesHF = NULL;
  209. dec->SamplesLF = NULL;
  210. dec->NumChannels = chancount;
  211. dec->Samples = al_calloc(16, dec->NumChannels*2 * sizeof(dec->Samples[0]));
  212. dec->SamplesHF = dec->Samples;
  213. dec->SamplesLF = dec->SamplesHF + dec->NumChannels;
  214. dec->Enabled = 0;
  215. for(i = 0;i < conf->NumSpeakers;i++)
  216. dec->Enabled |= 1 << chanmap[i];
  217. if(conf->CoeffScale == ADS_SN3D)
  218. coeff_scale = SN3D2N3DScale;
  219. else if(conf->CoeffScale == ADS_FuMa)
  220. coeff_scale = FuMa2N3DScale;
  221. memset(dec->UpSampler, 0, sizeof(dec->UpSampler));
  222. ratio = 400.0f / (ALfloat)srate;
  223. for(i = 0;i < 4;i++)
  224. bandsplit_init(&dec->UpSampler[i].XOver, ratio);
  225. if((conf->ChanMask&AMBI_PERIPHONIC_MASK))
  226. {
  227. periphonic = true;
  228. dec->UpSampler[0].Gains[HF_BAND] = (conf->ChanMask > 0x1ff) ? W_SCALE_3H3P :
  229. (conf->ChanMask > 0xf) ? W_SCALE_2H2P : 1.0f;
  230. dec->UpSampler[0].Gains[LF_BAND] = 1.0f;
  231. for(i = 1;i < 4;i++)
  232. {
  233. dec->UpSampler[i].Gains[HF_BAND] = (conf->ChanMask > 0x1ff) ? XYZ_SCALE_3H3P :
  234. (conf->ChanMask > 0xf) ? XYZ_SCALE_2H2P : 1.0f;
  235. dec->UpSampler[i].Gains[LF_BAND] = 1.0f;
  236. }
  237. }
  238. else
  239. {
  240. periphonic = false;
  241. dec->UpSampler[0].Gains[HF_BAND] = (conf->ChanMask > 0x1ff) ? W_SCALE_3H0P :
  242. (conf->ChanMask > 0xf) ? W_SCALE_2H0P : 1.0f;
  243. dec->UpSampler[0].Gains[LF_BAND] = 1.0f;
  244. for(i = 1;i < 3;i++)
  245. {
  246. dec->UpSampler[i].Gains[HF_BAND] = (conf->ChanMask > 0x1ff) ? XYZ_SCALE_3H0P :
  247. (conf->ChanMask > 0xf) ? XYZ_SCALE_2H0P : 1.0f;
  248. dec->UpSampler[i].Gains[LF_BAND] = 1.0f;
  249. }
  250. dec->UpSampler[3].Gains[HF_BAND] = 0.0f;
  251. dec->UpSampler[3].Gains[LF_BAND] = 0.0f;
  252. }
  253. memset(&dec->Matrix, 0, sizeof(dec->Matrix));
  254. if(conf->FreqBands == 1)
  255. {
  256. dec->DualBand = AL_FALSE;
  257. for(i = 0;i < conf->NumSpeakers;i++)
  258. {
  259. ALsizei chan = chanmap[i];
  260. ALfloat gain;
  261. ALsizei j, k;
  262. if(!periphonic)
  263. {
  264. for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
  265. {
  266. ALsizei l = map2DTo3D[j];
  267. if(j == 0) gain = conf->HFOrderGain[0];
  268. else if(j == 1) gain = conf->HFOrderGain[1];
  269. else if(j == 3) gain = conf->HFOrderGain[2];
  270. else if(j == 5) gain = conf->HFOrderGain[3];
  271. if((conf->ChanMask&(1<<l)))
  272. dec->Matrix.Single[chan][j] = conf->HFMatrix[i][k++] / coeff_scale[l] *
  273. gain;
  274. }
  275. }
  276. else
  277. {
  278. for(j = 0,k = 0;j < MAX_AMBI_COEFFS;j++)
  279. {
  280. if(j == 0) gain = conf->HFOrderGain[0];
  281. else if(j == 1) gain = conf->HFOrderGain[1];
  282. else if(j == 4) gain = conf->HFOrderGain[2];
  283. else if(j == 9) gain = conf->HFOrderGain[3];
  284. if((conf->ChanMask&(1<<j)))
  285. dec->Matrix.Single[chan][j] = conf->HFMatrix[i][k++] / coeff_scale[j] *
  286. gain;
  287. }
  288. }
  289. }
  290. }
  291. else
  292. {
  293. dec->DualBand = AL_TRUE;
  294. ratio = conf->XOverFreq / (ALfloat)srate;
  295. for(i = 0;i < MAX_AMBI_COEFFS;i++)
  296. bandsplit_init(&dec->XOver[i], ratio);
  297. ratio = powf(10.0f, conf->XOverRatio / 40.0f);
  298. for(i = 0;i < conf->NumSpeakers;i++)
  299. {
  300. ALsizei chan = chanmap[i];
  301. ALfloat gain;
  302. ALsizei j, k;
  303. if(!periphonic)
  304. {
  305. for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
  306. {
  307. ALsizei l = map2DTo3D[j];
  308. if(j == 0) gain = conf->HFOrderGain[0] * ratio;
  309. else if(j == 1) gain = conf->HFOrderGain[1] * ratio;
  310. else if(j == 3) gain = conf->HFOrderGain[2] * ratio;
  311. else if(j == 5) gain = conf->HFOrderGain[3] * ratio;
  312. if((conf->ChanMask&(1<<l)))
  313. dec->Matrix.Dual[chan][HF_BAND][j] = conf->HFMatrix[i][k++] /
  314. coeff_scale[l] * gain;
  315. }
  316. for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
  317. {
  318. ALsizei l = map2DTo3D[j];
  319. if(j == 0) gain = conf->LFOrderGain[0] / ratio;
  320. else if(j == 1) gain = conf->LFOrderGain[1] / ratio;
  321. else if(j == 3) gain = conf->LFOrderGain[2] / ratio;
  322. else if(j == 5) gain = conf->LFOrderGain[3] / ratio;
  323. if((conf->ChanMask&(1<<l)))
  324. dec->Matrix.Dual[chan][LF_BAND][j] = conf->LFMatrix[i][k++] /
  325. coeff_scale[l] * gain;
  326. }
  327. }
  328. else
  329. {
  330. for(j = 0,k = 0;j < MAX_AMBI_COEFFS;j++)
  331. {
  332. if(j == 0) gain = conf->HFOrderGain[0] * ratio;
  333. else if(j == 1) gain = conf->HFOrderGain[1] * ratio;
  334. else if(j == 4) gain = conf->HFOrderGain[2] * ratio;
  335. else if(j == 9) gain = conf->HFOrderGain[3] * ratio;
  336. if((conf->ChanMask&(1<<j)))
  337. dec->Matrix.Dual[chan][HF_BAND][j] = conf->HFMatrix[i][k++] /
  338. coeff_scale[j] * gain;
  339. }
  340. for(j = 0,k = 0;j < MAX_AMBI_COEFFS;j++)
  341. {
  342. if(j == 0) gain = conf->LFOrderGain[0] / ratio;
  343. else if(j == 1) gain = conf->LFOrderGain[1] / ratio;
  344. else if(j == 4) gain = conf->LFOrderGain[2] / ratio;
  345. else if(j == 9) gain = conf->LFOrderGain[3] / ratio;
  346. if((conf->ChanMask&(1<<j)))
  347. dec->Matrix.Dual[chan][LF_BAND][j] = conf->LFMatrix[i][k++] /
  348. coeff_scale[j] * gain;
  349. }
  350. }
  351. }
  352. }
  353. }
  354. void bformatdec_process(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALsizei OutChannels, const ALfloat (*restrict InSamples)[BUFFERSIZE], ALsizei SamplesToDo)
  355. {
  356. ALsizei chan, i;
  357. OutBuffer = ASSUME_ALIGNED(OutBuffer, 16);
  358. if(dec->DualBand)
  359. {
  360. for(i = 0;i < dec->NumChannels;i++)
  361. bandsplit_process(&dec->XOver[i], dec->SamplesHF[i], dec->SamplesLF[i],
  362. InSamples[i], SamplesToDo);
  363. for(chan = 0;chan < OutChannels;chan++)
  364. {
  365. if(!(dec->Enabled&(1<<chan)))
  366. continue;
  367. memset(dec->ChannelMix, 0, SamplesToDo*sizeof(ALfloat));
  368. MixRowSamples(dec->ChannelMix, dec->Matrix.Dual[chan][HF_BAND],
  369. dec->SamplesHF, dec->NumChannels, 0, SamplesToDo
  370. );
  371. MixRowSamples(dec->ChannelMix, dec->Matrix.Dual[chan][LF_BAND],
  372. dec->SamplesLF, dec->NumChannels, 0, SamplesToDo
  373. );
  374. for(i = 0;i < SamplesToDo;i++)
  375. OutBuffer[chan][i] += dec->ChannelMix[i];
  376. }
  377. }
  378. else
  379. {
  380. for(chan = 0;chan < OutChannels;chan++)
  381. {
  382. if(!(dec->Enabled&(1<<chan)))
  383. continue;
  384. memset(dec->ChannelMix, 0, SamplesToDo*sizeof(ALfloat));
  385. MixRowSamples(dec->ChannelMix, dec->Matrix.Single[chan], InSamples,
  386. dec->NumChannels, 0, SamplesToDo);
  387. for(i = 0;i < SamplesToDo;i++)
  388. OutBuffer[chan][i] += dec->ChannelMix[i];
  389. }
  390. }
  391. }
  392. void bformatdec_upSample(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat (*restrict InSamples)[BUFFERSIZE], ALsizei InChannels, ALsizei SamplesToDo)
  393. {
  394. ALsizei i;
  395. /* This up-sampler leverages the differences observed in dual-band second-
  396. * and third-order decoder matrices compared to first-order. For the same
  397. * output channel configuration, the low-frequency matrix has identical
  398. * coefficients in the shared input channels, while the high-frequency
  399. * matrix has extra scalars applied to the W channel and X/Y/Z channels.
  400. * Mixing the first-order content into the higher-order stream with the
  401. * appropriate counter-scales applied to the HF response results in the
  402. * subsequent higher-order decode generating the same response as a first-
  403. * order decode.
  404. */
  405. for(i = 0;i < InChannels;i++)
  406. {
  407. /* First, split the first-order components into low and high frequency
  408. * bands.
  409. */
  410. bandsplit_process(&dec->UpSampler[i].XOver,
  411. dec->Samples[HF_BAND], dec->Samples[LF_BAND],
  412. InSamples[i], SamplesToDo
  413. );
  414. /* Now write each band to the output. */
  415. MixRowSamples(OutBuffer[i], dec->UpSampler[i].Gains,
  416. dec->Samples, NUM_BANDS, 0, SamplesToDo
  417. );
  418. }
  419. }
  420. #define INVALID_UPSAMPLE_INDEX INT_MAX
  421. static ALsizei GetACNIndex(const BFChannelConfig *chans, ALsizei numchans, ALsizei acn)
  422. {
  423. ALsizei i;
  424. for(i = 0;i < numchans;i++)
  425. {
  426. if(chans[i].Index == acn)
  427. return i;
  428. }
  429. return INVALID_UPSAMPLE_INDEX;
  430. }
  431. #define GetChannelForACN(b, a) GetACNIndex((b).Ambi.Map, (b).NumChannels, (a))
  432. typedef struct AmbiUpsampler {
  433. alignas(16) ALfloat Samples[NUM_BANDS][BUFFERSIZE];
  434. BandSplitter XOver[4];
  435. ALfloat Gains[4][MAX_OUTPUT_CHANNELS][NUM_BANDS];
  436. } AmbiUpsampler;
  437. AmbiUpsampler *ambiup_alloc()
  438. {
  439. return al_calloc(16, sizeof(AmbiUpsampler));
  440. }
  441. void ambiup_free(struct AmbiUpsampler **ambiup)
  442. {
  443. if(ambiup)
  444. {
  445. al_free(*ambiup);
  446. *ambiup = NULL;
  447. }
  448. }
  449. void ambiup_reset(struct AmbiUpsampler *ambiup, const ALCdevice *device, ALfloat w_scale, ALfloat xyz_scale)
  450. {
  451. ALfloat ratio;
  452. ALsizei i;
  453. ratio = 400.0f / (ALfloat)device->Frequency;
  454. for(i = 0;i < 4;i++)
  455. bandsplit_init(&ambiup->XOver[i], ratio);
  456. memset(ambiup->Gains, 0, sizeof(ambiup->Gains));
  457. if(device->Dry.CoeffCount > 0)
  458. {
  459. ALfloat encgains[8][MAX_OUTPUT_CHANNELS];
  460. ALsizei j;
  461. size_t k;
  462. for(k = 0;k < COUNTOF(Ambi3DPoints);k++)
  463. {
  464. ALfloat coeffs[MAX_AMBI_COEFFS] = { 0.0f };
  465. CalcDirectionCoeffs(Ambi3DPoints[k], 0.0f, coeffs);
  466. ComputeDryPanGains(&device->Dry, coeffs, 1.0f, encgains[k]);
  467. }
  468. /* Combine the matrices that do the in->virt and virt->out conversions
  469. * so we get a single in->out conversion. NOTE: the Encoder matrix
  470. * (encgains) and output are transposed, so the input channels line up
  471. * with the rows and the output channels line up with the columns.
  472. */
  473. for(i = 0;i < 4;i++)
  474. {
  475. for(j = 0;j < device->Dry.NumChannels;j++)
  476. {
  477. ALfloat gain=0.0f;
  478. for(k = 0;k < COUNTOF(Ambi3DDecoder);k++)
  479. gain += Ambi3DDecoder[k][i] * encgains[k][j];
  480. ambiup->Gains[i][j][HF_BAND] = gain * Ambi3DDecoderHFScale[i];
  481. ambiup->Gains[i][j][LF_BAND] = gain;
  482. }
  483. }
  484. }
  485. else
  486. {
  487. for(i = 0;i < 4;i++)
  488. {
  489. ALsizei index = GetChannelForACN(device->Dry, i);
  490. if(index != INVALID_UPSAMPLE_INDEX)
  491. {
  492. ALfloat scale = device->Dry.Ambi.Map[index].Scale;
  493. ambiup->Gains[i][index][HF_BAND] = scale * ((i==0) ? w_scale : xyz_scale);
  494. ambiup->Gains[i][index][LF_BAND] = scale;
  495. }
  496. }
  497. }
  498. }
  499. void ambiup_process(struct AmbiUpsampler *ambiup, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALsizei OutChannels, const ALfloat (*restrict InSamples)[BUFFERSIZE], ALsizei SamplesToDo)
  500. {
  501. ALsizei i, j;
  502. for(i = 0;i < 4;i++)
  503. {
  504. bandsplit_process(&ambiup->XOver[i],
  505. ambiup->Samples[HF_BAND], ambiup->Samples[LF_BAND],
  506. InSamples[i], SamplesToDo
  507. );
  508. for(j = 0;j < OutChannels;j++)
  509. MixRowSamples(OutBuffer[j], ambiup->Gains[i][j],
  510. ambiup->Samples, NUM_BANDS, 0, SamplesToDo
  511. );
  512. }
  513. }