bformatdec.c 20 KB

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