2
0

bformatdec.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. #include "config.h"
  2. #include "bformatdec.h"
  3. #include "ambdec.h"
  4. #include "mixer_defs.h"
  5. #include "alu.h"
  6. #include "threads.h"
  7. #include "almalloc.h"
  8. void bandsplit_init(BandSplitter *splitter, ALfloat freq_mult)
  9. {
  10. ALfloat w = freq_mult * 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, ALuint count)
  28. {
  29. ALfloat coeff, d, x;
  30. ALfloat z1, z2;
  31. ALuint i;
  32. coeff = splitter->coeff*0.5f + 0.5f;
  33. z1 = splitter->lp_z1;
  34. z2 = splitter->lp_z2;
  35. for(i = 0;i < count;i++)
  36. {
  37. x = input[i];
  38. d = (x - z1) * coeff;
  39. x = z1 + d;
  40. z1 = x + d;
  41. d = (x - z2) * coeff;
  42. x = z2 + d;
  43. z2 = x + d;
  44. lpout[i] = x;
  45. }
  46. splitter->lp_z1 = z1;
  47. splitter->lp_z2 = z2;
  48. coeff = splitter->coeff;
  49. z1 = splitter->hp_z1;
  50. for(i = 0;i < count;i++)
  51. {
  52. x = input[i];
  53. d = x - coeff*z1;
  54. x = z1 + coeff*d;
  55. z1 = d;
  56. hpout[i] = x - lpout[i];
  57. }
  58. splitter->hp_z1 = z1;
  59. }
  60. static const ALfloat UnitScale[MAX_AMBI_COEFFS] = {
  61. 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
  62. 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f
  63. };
  64. static const ALfloat SN3D2N3DScale[MAX_AMBI_COEFFS] = {
  65. 1.000000000f, /* ACN 0 (W), sqrt(1) */
  66. 1.732050808f, /* ACN 1 (Y), sqrt(3) */
  67. 1.732050808f, /* ACN 2 (Z), sqrt(3) */
  68. 1.732050808f, /* ACN 3 (X), sqrt(3) */
  69. 2.236067978f, /* ACN 4 (V), sqrt(5) */
  70. 2.236067978f, /* ACN 5 (T), sqrt(5) */
  71. 2.236067978f, /* ACN 6 (R), sqrt(5) */
  72. 2.236067978f, /* ACN 7 (S), sqrt(5) */
  73. 2.236067978f, /* ACN 8 (U), sqrt(5) */
  74. 2.645751311f, /* ACN 9 (Q), sqrt(7) */
  75. 2.645751311f, /* ACN 10 (O), sqrt(7) */
  76. 2.645751311f, /* ACN 11 (M), sqrt(7) */
  77. 2.645751311f, /* ACN 12 (K), sqrt(7) */
  78. 2.645751311f, /* ACN 13 (L), sqrt(7) */
  79. 2.645751311f, /* ACN 14 (N), sqrt(7) */
  80. 2.645751311f, /* ACN 15 (P), sqrt(7) */
  81. };
  82. static const ALfloat FuMa2N3DScale[MAX_AMBI_COEFFS] = {
  83. 1.414213562f, /* ACN 0 (W), sqrt(2) */
  84. 1.732050808f, /* ACN 1 (Y), sqrt(3) */
  85. 1.732050808f, /* ACN 2 (Z), sqrt(3) */
  86. 1.732050808f, /* ACN 3 (X), sqrt(3) */
  87. 1.936491673f, /* ACN 4 (V), sqrt(15)/2 */
  88. 1.936491673f, /* ACN 5 (T), sqrt(15)/2 */
  89. 2.236067978f, /* ACN 6 (R), sqrt(5) */
  90. 1.936491673f, /* ACN 7 (S), sqrt(15)/2 */
  91. 1.936491673f, /* ACN 8 (U), sqrt(15)/2 */
  92. 2.091650066f, /* ACN 9 (Q), sqrt(35/8) */
  93. 1.972026594f, /* ACN 10 (O), sqrt(35)/3 */
  94. 2.231093404f, /* ACN 11 (M), sqrt(224/45) */
  95. 2.645751311f, /* ACN 12 (K), sqrt(7) */
  96. 2.231093404f, /* ACN 13 (L), sqrt(224/45) */
  97. 1.972026594f, /* ACN 14 (N), sqrt(35)/3 */
  98. 2.091650066f, /* ACN 15 (P), sqrt(35/8) */
  99. };
  100. enum FreqBand {
  101. FB_HighFreq,
  102. FB_LowFreq,
  103. FB_Max
  104. };
  105. /* These points are in AL coordinates! */
  106. static const ALfloat Ambi2DPoints[4][3] = {
  107. { -0.707106781f, 0.0f, -0.707106781f },
  108. { 0.707106781f, 0.0f, -0.707106781f },
  109. { -0.707106781f, 0.0f, 0.707106781f },
  110. { 0.707106781f, 0.0f, 0.707106781f },
  111. };
  112. static const ALfloat Ambi2DDecoder[4][FB_Max][MAX_AMBI_COEFFS] = {
  113. { { 0.353553f, 0.204094f, 0.0f, 0.204094f }, { 0.25f, 0.204094f, 0.0f, 0.204094f } },
  114. { { 0.353553f, -0.204094f, 0.0f, 0.204094f }, { 0.25f, -0.204094f, 0.0f, 0.204094f } },
  115. { { 0.353553f, 0.204094f, 0.0f, -0.204094f }, { 0.25f, 0.204094f, 0.0f, -0.204094f } },
  116. { { 0.353553f, -0.204094f, 0.0f, -0.204094f }, { 0.25f, -0.204094f, 0.0f, -0.204094f } },
  117. };
  118. static ALfloat Ambi2DEncoder[4][MAX_AMBI_COEFFS];
  119. /* These points are in AL coordinates! */
  120. static const ALfloat Ambi3DPoints[8][3] = {
  121. { -0.577350269f, 0.577350269f, -0.577350269f },
  122. { 0.577350269f, 0.577350269f, -0.577350269f },
  123. { -0.577350269f, 0.577350269f, 0.577350269f },
  124. { 0.577350269f, 0.577350269f, 0.577350269f },
  125. { -0.577350269f, -0.577350269f, -0.577350269f },
  126. { 0.577350269f, -0.577350269f, -0.577350269f },
  127. { -0.577350269f, -0.577350269f, 0.577350269f },
  128. { 0.577350269f, -0.577350269f, 0.577350269f },
  129. };
  130. static const ALfloat Ambi3DDecoder[8][FB_Max][MAX_AMBI_COEFFS] = {
  131. { { 0.25f, 0.1443375672f, 0.1443375672f, 0.1443375672f }, { 0.125f, 0.125f, 0.125f, 0.125f } },
  132. { { 0.25f, -0.1443375672f, 0.1443375672f, 0.1443375672f }, { 0.125f, -0.125f, 0.125f, 0.125f } },
  133. { { 0.25f, 0.1443375672f, 0.1443375672f, -0.1443375672f }, { 0.125f, 0.125f, 0.125f, -0.125f } },
  134. { { 0.25f, -0.1443375672f, 0.1443375672f, -0.1443375672f }, { 0.125f, -0.125f, 0.125f, -0.125f } },
  135. { { 0.25f, 0.1443375672f, -0.1443375672f, 0.1443375672f }, { 0.125f, 0.125f, -0.125f, 0.125f } },
  136. { { 0.25f, -0.1443375672f, -0.1443375672f, 0.1443375672f }, { 0.125f, -0.125f, -0.125f, 0.125f } },
  137. { { 0.25f, 0.1443375672f, -0.1443375672f, -0.1443375672f }, { 0.125f, 0.125f, -0.125f, -0.125f } },
  138. { { 0.25f, -0.1443375672f, -0.1443375672f, -0.1443375672f }, { 0.125f, -0.125f, -0.125f, -0.125f } },
  139. };
  140. static ALfloat Ambi3DEncoder[8][MAX_AMBI_COEFFS];
  141. static RowMixerFunc MixMatrixRow = MixRow_C;
  142. static alonce_flag bformatdec_inited = AL_ONCE_FLAG_INIT;
  143. static void init_bformatdec(void)
  144. {
  145. ALuint i, j;
  146. MixMatrixRow = SelectRowMixer();
  147. for(i = 0;i < COUNTOF(Ambi3DPoints);i++)
  148. CalcDirectionCoeffs(Ambi3DPoints[i], 0.0f, Ambi3DEncoder[i]);
  149. for(i = 0;i < COUNTOF(Ambi2DPoints);i++)
  150. {
  151. CalcDirectionCoeffs(Ambi2DPoints[i], 0.0f, Ambi2DEncoder[i]);
  152. /* Remove the skipped height-related coefficients for 2D rendering. */
  153. Ambi2DEncoder[i][2] = Ambi2DEncoder[i][3];
  154. Ambi2DEncoder[i][3] = Ambi2DEncoder[i][4];
  155. Ambi2DEncoder[i][4] = Ambi2DEncoder[i][8];
  156. Ambi2DEncoder[i][5] = Ambi2DEncoder[i][9];
  157. Ambi2DEncoder[i][6] = Ambi2DEncoder[i][15];
  158. for(j = 7;j < MAX_AMBI_COEFFS;j++)
  159. Ambi2DEncoder[i][j] = 0.0f;
  160. }
  161. }
  162. #define MAX_DELAY_LENGTH 128
  163. /* NOTE: BandSplitter filters are unused with single-band decoding */
  164. typedef struct BFormatDec {
  165. ALboolean Enabled[MAX_OUTPUT_CHANNELS];
  166. union {
  167. alignas(16) ALfloat Dual[MAX_OUTPUT_CHANNELS][FB_Max][MAX_AMBI_COEFFS];
  168. alignas(16) ALfloat Single[MAX_OUTPUT_CHANNELS][MAX_AMBI_COEFFS];
  169. } Matrix;
  170. BandSplitter XOver[MAX_AMBI_COEFFS];
  171. ALfloat (*Samples)[BUFFERSIZE];
  172. /* These two alias into Samples */
  173. ALfloat (*SamplesHF)[BUFFERSIZE];
  174. ALfloat (*SamplesLF)[BUFFERSIZE];
  175. alignas(16) ALfloat ChannelMix[BUFFERSIZE];
  176. struct {
  177. alignas(16) ALfloat Buffer[MAX_DELAY_LENGTH];
  178. ALuint Length; /* Valid range is [0...MAX_DELAY_LENGTH). */
  179. } Delay[MAX_OUTPUT_CHANNELS];
  180. struct {
  181. BandSplitter XOver[4];
  182. ALfloat Gains[4][MAX_OUTPUT_CHANNELS][FB_Max];
  183. } UpSampler;
  184. ALuint NumChannels;
  185. ALboolean DualBand;
  186. ALboolean Periphonic;
  187. } BFormatDec;
  188. BFormatDec *bformatdec_alloc()
  189. {
  190. alcall_once(&bformatdec_inited, init_bformatdec);
  191. return al_calloc(16, sizeof(BFormatDec));
  192. }
  193. void bformatdec_free(BFormatDec *dec)
  194. {
  195. if(dec)
  196. {
  197. al_free(dec->Samples);
  198. dec->Samples = NULL;
  199. dec->SamplesHF = NULL;
  200. dec->SamplesLF = NULL;
  201. memset(dec, 0, sizeof(*dec));
  202. al_free(dec);
  203. }
  204. }
  205. int bformatdec_getOrder(const struct BFormatDec *dec)
  206. {
  207. if(dec->Periphonic)
  208. {
  209. if(dec->NumChannels > 9) return 3;
  210. if(dec->NumChannels > 4) return 2;
  211. if(dec->NumChannels > 1) return 1;
  212. }
  213. else
  214. {
  215. if(dec->NumChannels > 5) return 3;
  216. if(dec->NumChannels > 3) return 2;
  217. if(dec->NumChannels > 1) return 1;
  218. }
  219. return 0;
  220. }
  221. void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALuint chancount, ALuint srate, const ALuint chanmap[MAX_OUTPUT_CHANNELS], int flags)
  222. {
  223. static const ALuint map2DTo3D[MAX_AMBI2D_COEFFS] = {
  224. 0, 1, 3, 4, 8, 9, 15
  225. };
  226. const ALfloat *coeff_scale = UnitScale;
  227. ALfloat distgain[MAX_OUTPUT_CHANNELS];
  228. ALfloat maxdist, ratio;
  229. ALuint i, j, k;
  230. al_free(dec->Samples);
  231. dec->Samples = NULL;
  232. dec->SamplesHF = NULL;
  233. dec->SamplesLF = NULL;
  234. dec->NumChannels = chancount;
  235. dec->Samples = al_calloc(16, dec->NumChannels*2 * sizeof(dec->Samples[0]));
  236. dec->SamplesHF = dec->Samples;
  237. dec->SamplesLF = dec->SamplesHF + dec->NumChannels;
  238. for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
  239. dec->Enabled[i] = AL_FALSE;
  240. for(i = 0;i < conf->NumSpeakers;i++)
  241. dec->Enabled[chanmap[i]] = AL_TRUE;
  242. if(conf->CoeffScale == ADS_SN3D)
  243. coeff_scale = SN3D2N3DScale;
  244. else if(conf->CoeffScale == ADS_FuMa)
  245. coeff_scale = FuMa2N3DScale;
  246. ratio = 400.0f / (ALfloat)srate;
  247. for(i = 0;i < 4;i++)
  248. bandsplit_init(&dec->UpSampler.XOver[i], ratio);
  249. memset(dec->UpSampler.Gains, 0, sizeof(dec->UpSampler.Gains));
  250. if((conf->ChanMask&AMBI_PERIPHONIC_MASK))
  251. {
  252. /* Combine the matrices that do the in->virt and virt->out conversions
  253. * so we get a single in->out conversion.
  254. */
  255. for(i = 0;i < 4;i++)
  256. {
  257. for(j = 0;j < dec->NumChannels;j++)
  258. {
  259. ALfloat *gains = dec->UpSampler.Gains[i][j];
  260. for(k = 0;k < COUNTOF(Ambi3DDecoder);k++)
  261. {
  262. gains[FB_HighFreq] += Ambi3DDecoder[k][FB_HighFreq][i]*Ambi3DEncoder[k][j];
  263. gains[FB_LowFreq] += Ambi3DDecoder[k][FB_LowFreq][i]*Ambi3DEncoder[k][j];
  264. }
  265. }
  266. }
  267. dec->Periphonic = AL_TRUE;
  268. }
  269. else
  270. {
  271. for(i = 0;i < 4;i++)
  272. {
  273. for(j = 0;j < dec->NumChannels;j++)
  274. {
  275. ALfloat *gains = dec->UpSampler.Gains[i][j];
  276. for(k = 0;k < COUNTOF(Ambi2DDecoder);k++)
  277. {
  278. gains[FB_HighFreq] += Ambi2DDecoder[k][FB_HighFreq][i]*Ambi2DEncoder[k][j];
  279. gains[FB_LowFreq] += Ambi2DDecoder[k][FB_LowFreq][i]*Ambi2DEncoder[k][j];
  280. }
  281. }
  282. }
  283. dec->Periphonic = AL_FALSE;
  284. }
  285. maxdist = 0.0f;
  286. for(i = 0;i < conf->NumSpeakers;i++)
  287. {
  288. maxdist = maxf(maxdist, conf->Speakers[i].Distance);
  289. distgain[i] = 1.0f;
  290. }
  291. memset(dec->Delay, 0, sizeof(dec->Delay));
  292. if((flags&BFDF_DistanceComp) && maxdist > 0.0f)
  293. {
  294. for(i = 0;i < conf->NumSpeakers;i++)
  295. {
  296. ALuint chan = chanmap[i];
  297. ALfloat delay;
  298. /* Distance compensation only delays in steps of the sample rate.
  299. * This is a bit less accurate since the delay time falls to the
  300. * nearest sample time, but it's far simpler as it doesn't have to
  301. * deal with phase offsets. This means at 48khz, for instance, the
  302. * distance delay will be in steps of about 7 millimeters.
  303. */
  304. delay = floorf((maxdist-conf->Speakers[i].Distance) / SPEEDOFSOUNDMETRESPERSEC *
  305. (ALfloat)srate + 0.5f);
  306. if(delay >= (ALfloat)MAX_DELAY_LENGTH)
  307. ERR("Delay for speaker \"%s\" exceeds buffer length (%f >= %u)\n",
  308. al_string_get_cstr(conf->Speakers[i].Name), delay, MAX_DELAY_LENGTH);
  309. dec->Delay[chan].Length = (ALuint)clampf(delay, 0.0f, (ALfloat)(MAX_DELAY_LENGTH-1));
  310. distgain[i] = conf->Speakers[i].Distance / maxdist;
  311. TRACE("Channel %u \"%s\" distance compensation: %u samples, %f gain\n", chan,
  312. al_string_get_cstr(conf->Speakers[i].Name), dec->Delay[chan].Length, distgain[i]
  313. );
  314. }
  315. }
  316. memset(&dec->Matrix, 0, sizeof(dec->Matrix));
  317. if(conf->FreqBands == 1)
  318. {
  319. dec->DualBand = AL_FALSE;
  320. for(i = 0;i < conf->NumSpeakers;i++)
  321. {
  322. ALuint chan = chanmap[i];
  323. ALfloat gain;
  324. ALuint j, k;
  325. if(!dec->Periphonic)
  326. {
  327. for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
  328. {
  329. ALuint l = map2DTo3D[j];
  330. if(j == 0) gain = conf->HFOrderGain[0];
  331. else if(j == 1) gain = conf->HFOrderGain[1];
  332. else if(j == 3) gain = conf->HFOrderGain[2];
  333. else if(j == 5) gain = conf->HFOrderGain[3];
  334. if((conf->ChanMask&(1<<l)))
  335. dec->Matrix.Single[chan][j] = conf->HFMatrix[i][k++] / coeff_scale[l] *
  336. gain * distgain[i];
  337. }
  338. }
  339. else
  340. {
  341. for(j = 0,k = 0;j < MAX_AMBI_COEFFS;j++)
  342. {
  343. if(j == 0) gain = conf->HFOrderGain[0];
  344. else if(j == 1) gain = conf->HFOrderGain[1];
  345. else if(j == 4) gain = conf->HFOrderGain[2];
  346. else if(j == 9) gain = conf->HFOrderGain[3];
  347. if((conf->ChanMask&(1<<j)))
  348. dec->Matrix.Single[chan][j] = conf->HFMatrix[i][k++] / coeff_scale[j] *
  349. gain * distgain[i];
  350. }
  351. }
  352. }
  353. }
  354. else
  355. {
  356. dec->DualBand = AL_TRUE;
  357. ratio = conf->XOverFreq / (ALfloat)srate;
  358. for(i = 0;i < MAX_AMBI_COEFFS;i++)
  359. bandsplit_init(&dec->XOver[i], ratio);
  360. ratio = powf(10.0f, conf->XOverRatio / 40.0f);
  361. for(i = 0;i < conf->NumSpeakers;i++)
  362. {
  363. ALuint chan = chanmap[i];
  364. ALfloat gain;
  365. ALuint j, k;
  366. if(!dec->Periphonic)
  367. {
  368. for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
  369. {
  370. ALuint l = map2DTo3D[j];
  371. if(j == 0) gain = conf->HFOrderGain[0] * ratio;
  372. else if(j == 1) gain = conf->HFOrderGain[1] * ratio;
  373. else if(j == 3) gain = conf->HFOrderGain[2] * ratio;
  374. else if(j == 5) gain = conf->HFOrderGain[3] * ratio;
  375. if((conf->ChanMask&(1<<l)))
  376. dec->Matrix.Dual[chan][FB_HighFreq][j] = conf->HFMatrix[i][k++] /
  377. coeff_scale[l] * gain *
  378. distgain[i];
  379. }
  380. for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
  381. {
  382. ALuint l = map2DTo3D[j];
  383. if(j == 0) gain = conf->LFOrderGain[0] / ratio;
  384. else if(j == 1) gain = conf->LFOrderGain[1] / ratio;
  385. else if(j == 3) gain = conf->LFOrderGain[2] / ratio;
  386. else if(j == 5) gain = conf->LFOrderGain[3] / ratio;
  387. if((conf->ChanMask&(1<<l)))
  388. dec->Matrix.Dual[chan][FB_LowFreq][j] = conf->LFMatrix[i][k++] /
  389. coeff_scale[l] * gain *
  390. distgain[i];
  391. }
  392. }
  393. else
  394. {
  395. for(j = 0,k = 0;j < MAX_AMBI_COEFFS;j++)
  396. {
  397. if(j == 0) gain = conf->HFOrderGain[0] * ratio;
  398. else if(j == 1) gain = conf->HFOrderGain[1] * ratio;
  399. else if(j == 4) gain = conf->HFOrderGain[2] * ratio;
  400. else if(j == 9) gain = conf->HFOrderGain[3] * ratio;
  401. if((conf->ChanMask&(1<<j)))
  402. dec->Matrix.Dual[chan][FB_HighFreq][j] = conf->HFMatrix[i][k++] /
  403. coeff_scale[j] * gain *
  404. distgain[i];
  405. }
  406. for(j = 0,k = 0;j < MAX_AMBI_COEFFS;j++)
  407. {
  408. if(j == 0) gain = conf->LFOrderGain[0] / ratio;
  409. else if(j == 1) gain = conf->LFOrderGain[1] / ratio;
  410. else if(j == 4) gain = conf->LFOrderGain[2] / ratio;
  411. else if(j == 9) gain = conf->LFOrderGain[3] / ratio;
  412. if((conf->ChanMask&(1<<j)))
  413. dec->Matrix.Dual[chan][FB_LowFreq][j] = conf->LFMatrix[i][k++] /
  414. coeff_scale[j] * gain *
  415. distgain[i];
  416. }
  417. }
  418. }
  419. }
  420. }
  421. void bformatdec_process(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint OutChannels, const ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint SamplesToDo)
  422. {
  423. ALuint chan, i;
  424. if(dec->DualBand)
  425. {
  426. for(i = 0;i < dec->NumChannels;i++)
  427. bandsplit_process(&dec->XOver[i], dec->SamplesHF[i], dec->SamplesLF[i],
  428. InSamples[i], SamplesToDo);
  429. for(chan = 0;chan < OutChannels;chan++)
  430. {
  431. if(!dec->Enabled[chan])
  432. continue;
  433. memset(dec->ChannelMix, 0, SamplesToDo*sizeof(ALfloat));
  434. MixMatrixRow(dec->ChannelMix, dec->Matrix.Dual[chan][FB_HighFreq],
  435. SAFE_CONST(ALfloatBUFFERSIZE*,dec->SamplesHF), dec->NumChannels, 0,
  436. SamplesToDo
  437. );
  438. MixMatrixRow(dec->ChannelMix, dec->Matrix.Dual[chan][FB_LowFreq],
  439. SAFE_CONST(ALfloatBUFFERSIZE*,dec->SamplesLF), dec->NumChannels, 0,
  440. SamplesToDo
  441. );
  442. if(dec->Delay[chan].Length > 0)
  443. {
  444. const ALuint base = dec->Delay[chan].Length;
  445. if(SamplesToDo >= base)
  446. {
  447. for(i = 0;i < base;i++)
  448. OutBuffer[chan][i] += dec->Delay[chan].Buffer[i];
  449. for(;i < SamplesToDo;i++)
  450. OutBuffer[chan][i] += dec->ChannelMix[i-base];
  451. memcpy(dec->Delay[chan].Buffer, &dec->ChannelMix[SamplesToDo-base],
  452. base*sizeof(ALfloat));
  453. }
  454. else
  455. {
  456. for(i = 0;i < SamplesToDo;i++)
  457. OutBuffer[chan][i] += dec->Delay[chan].Buffer[i];
  458. memmove(dec->Delay[chan].Buffer, dec->Delay[chan].Buffer+SamplesToDo,
  459. base - SamplesToDo);
  460. memcpy(dec->Delay[chan].Buffer+base-SamplesToDo, dec->ChannelMix,
  461. SamplesToDo*sizeof(ALfloat));
  462. }
  463. }
  464. else for(i = 0;i < SamplesToDo;i++)
  465. OutBuffer[chan][i] += dec->ChannelMix[i];
  466. }
  467. }
  468. else
  469. {
  470. for(chan = 0;chan < OutChannels;chan++)
  471. {
  472. if(!dec->Enabled[chan])
  473. continue;
  474. memset(dec->ChannelMix, 0, SamplesToDo*sizeof(ALfloat));
  475. MixMatrixRow(dec->ChannelMix, dec->Matrix.Single[chan], InSamples,
  476. dec->NumChannels, 0, SamplesToDo);
  477. if(dec->Delay[chan].Length > 0)
  478. {
  479. const ALuint base = dec->Delay[chan].Length;
  480. if(SamplesToDo >= base)
  481. {
  482. for(i = 0;i < base;i++)
  483. OutBuffer[chan][i] += dec->Delay[chan].Buffer[i];
  484. for(;i < SamplesToDo;i++)
  485. OutBuffer[chan][i] += dec->ChannelMix[i-base];
  486. memcpy(dec->Delay[chan].Buffer, &dec->ChannelMix[SamplesToDo-base],
  487. base*sizeof(ALfloat));
  488. }
  489. else
  490. {
  491. for(i = 0;i < SamplesToDo;i++)
  492. OutBuffer[chan][i] += dec->Delay[chan].Buffer[i];
  493. memmove(dec->Delay[chan].Buffer, dec->Delay[chan].Buffer+SamplesToDo,
  494. base - SamplesToDo);
  495. memcpy(dec->Delay[chan].Buffer+base-SamplesToDo, dec->ChannelMix,
  496. SamplesToDo*sizeof(ALfloat));
  497. }
  498. }
  499. else for(i = 0;i < SamplesToDo;i++)
  500. OutBuffer[chan][i] += dec->ChannelMix[i];
  501. }
  502. }
  503. }
  504. void bformatdec_upSample(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint InChannels, ALuint SamplesToDo)
  505. {
  506. ALuint i, j;
  507. /* This up-sampler is very simplistic. It essentially decodes the first-
  508. * order content to a square channel array (or cube if height is desired),
  509. * then encodes those points onto the higher order soundfield. The decoder
  510. * and encoder matrices have been combined to directly convert each input
  511. * channel to the output, without the need for storing the virtual channel
  512. * array.
  513. */
  514. for(i = 0;i < InChannels;i++)
  515. {
  516. /* First, split the first-order components into low and high frequency
  517. * bands.
  518. */
  519. bandsplit_process(&dec->UpSampler.XOver[i],
  520. dec->Samples[FB_HighFreq], dec->Samples[FB_LowFreq],
  521. InSamples[i], SamplesToDo
  522. );
  523. /* Now write each band to the output. */
  524. for(j = 0;j < dec->NumChannels;j++)
  525. MixMatrixRow(OutBuffer[j], dec->UpSampler.Gains[i][j],
  526. SAFE_CONST(ALfloatBUFFERSIZE*,dec->Samples), FB_Max, 0,
  527. SamplesToDo
  528. );
  529. }
  530. }
  531. typedef struct AmbiUpsampler {
  532. alignas(16) ALfloat Samples[FB_Max][BUFFERSIZE];
  533. BandSplitter XOver[4];
  534. ALfloat Gains[4][MAX_OUTPUT_CHANNELS][FB_Max];
  535. } AmbiUpsampler;
  536. AmbiUpsampler *ambiup_alloc()
  537. {
  538. alcall_once(&bformatdec_inited, init_bformatdec);
  539. return al_calloc(16, sizeof(AmbiUpsampler));
  540. }
  541. void ambiup_free(struct AmbiUpsampler *ambiup)
  542. {
  543. al_free(ambiup);
  544. }
  545. void ambiup_reset(struct AmbiUpsampler *ambiup, const ALCdevice *device)
  546. {
  547. ALfloat gains[8][MAX_OUTPUT_CHANNELS];
  548. ALfloat ratio;
  549. ALuint i, j, k;
  550. ratio = 400.0f / (ALfloat)device->Frequency;
  551. for(i = 0;i < 4;i++)
  552. bandsplit_init(&ambiup->XOver[i], ratio);
  553. for(i = 0;i < COUNTOF(Ambi3DEncoder);i++)
  554. ComputePanningGains(device->Dry, Ambi3DEncoder[i], 1.0f, gains[i]);
  555. memset(ambiup->Gains, 0, sizeof(ambiup->Gains));
  556. for(i = 0;i < 4;i++)
  557. {
  558. for(j = 0;j < device->Dry.NumChannels;j++)
  559. {
  560. for(k = 0;k < COUNTOF(Ambi3DDecoder);k++)
  561. {
  562. ambiup->Gains[i][j][FB_HighFreq] += Ambi3DDecoder[k][FB_HighFreq][i]*gains[k][j];
  563. ambiup->Gains[i][j][FB_LowFreq] += Ambi3DDecoder[k][FB_LowFreq][i]*gains[k][j];
  564. }
  565. }
  566. }
  567. }
  568. void ambiup_process(struct AmbiUpsampler *ambiup, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint OutChannels, const ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint SamplesToDo)
  569. {
  570. ALuint i, j;
  571. for(i = 0;i < 4;i++)
  572. {
  573. bandsplit_process(&ambiup->XOver[i],
  574. ambiup->Samples[FB_HighFreq], ambiup->Samples[FB_LowFreq],
  575. InSamples[i], SamplesToDo
  576. );
  577. for(j = 0;j < OutChannels;j++)
  578. MixMatrixRow(OutBuffer[j], ambiup->Gains[i][j],
  579. SAFE_CONST(ALfloatBUFFERSIZE*,ambiup->Samples), FB_Max, 0,
  580. SamplesToDo
  581. );
  582. }
  583. }