bformatdec.c 17 KB

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