You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
5.0KB

  1. /**
  2. *@brief Uninitialize the decoder and free all resources.
  3. *@param avctx codec context
  4. *@return 0 on success, < 0 otherwise
  5. */
  6. static av_cold int decode_end(AVCodecContext *avctx)
  7. {
  8. WMA3DecodeContext *s = avctx->priv_data;
  9. int i;
  10. av_freep(&s->num_sfb);
  11. av_freep(&s->sfb_offsets);
  12. av_freep(&s->subwoofer_cutoffs);
  13. av_freep(&s->sf_offsets);
  14. for (i = 0 ; i < WMAPRO_BLOCK_SIZES ; i++)
  15. ff_mdct_end(&s->mdct_ctx[i]);
  16. return 0;
  17. }
  18. /**
  19. *@brief Calculate a decorrelation matrix from the bitstream parameters.
  20. *@param s codec context
  21. *@param chgroup channel group for which the matrix needs to be calculated
  22. */
  23. static void decode_decorrelation_matrix(WMA3DecodeContext *s,
  24. WMA3ChannelGroup *chgroup)
  25. {
  26. int i;
  27. int offset = 0;
  28. int8_t rotation_offset[WMAPRO_MAX_CHANNELS * WMAPRO_MAX_CHANNELS];
  29. memset(chgroup->decorrelation_matrix,0,
  30. sizeof(float) *s->num_channels * s->num_channels);
  31. for (i = 0; i < chgroup->num_channels * (chgroup->num_channels - 1) >> 1; i++)
  32. rotation_offset[i] = get_bits(&s->gb,6);
  33. for (i = 0; i < chgroup->num_channels; i++)
  34. chgroup->decorrelation_matrix[chgroup->num_channels * i + i] =
  35. get_bits1(&s->gb) ? 1.0 : -1.0;
  36. for (i = 1; i < chgroup->num_channels; i++) {
  37. int x;
  38. for (x = 0; x < i; x++) {
  39. int y;
  40. for (y = 0; y < i + 1 ; y++) {
  41. float v1 = chgroup->decorrelation_matrix[x * chgroup->num_channels + y];
  42. float v2 = chgroup->decorrelation_matrix[i * chgroup->num_channels + y];
  43. int n = rotation_offset[offset + x];
  44. float sinv;
  45. float cosv;
  46. if (n < 32) {
  47. sinv = sin64[n];
  48. cosv = sin64[32-n];
  49. } else {
  50. sinv = sin64[64-n];
  51. cosv = -sin64[n-32];
  52. }
  53. chgroup->decorrelation_matrix[y + x * chgroup->num_channels] =
  54. (v1 * sinv) - (v2 * cosv);
  55. chgroup->decorrelation_matrix[y + i * chgroup->num_channels] =
  56. (v1 * cosv) + (v2 * sinv);
  57. }
  58. }
  59. offset += i;
  60. }
  61. }
  62. /**
  63. *@brief Reconstruct the individual channel data.
  64. *@param s codec context
  65. */
  66. static void inverse_channel_transform(WMA3DecodeContext *s)
  67. {
  68. int i;
  69. for (i = 0; i < s->num_chgroups; i++) {
  70. if (s->chgroup[i].transform == 1) {
  71. /** M/S stereo decoding */
  72. int16_t* sfb_offsets = s->cur_sfb_offsets;
  73. float* ch0 = *sfb_offsets + s->channel[0].coeffs;
  74. float* ch1 = *sfb_offsets++ + s->channel[1].coeffs;
  75. const char* tb = s->chgroup[i].transform_band;
  76. const char* tb_end = tb + s->num_bands;
  77. while (tb < tb_end) {
  78. const float* ch0_end = s->channel[0].coeffs +
  79. FFMIN(*sfb_offsets,s->subframe_len);
  80. if (*tb++ == 1) {
  81. while (ch0 < ch0_end) {
  82. const float v1 = *ch0;
  83. const float v2 = *ch1;
  84. *ch0++ = v1 - v2;
  85. *ch1++ = v1 + v2;
  86. }
  87. } else {
  88. while (ch0 < ch0_end) {
  89. *ch0++ *= 181.0 / 128;
  90. *ch1++ *= 181.0 / 128;
  91. }
  92. }
  93. ++sfb_offsets;
  94. }
  95. } else if (s->chgroup[i].transform) {
  96. float data[WMAPRO_MAX_CHANNELS];
  97. const int num_channels = s->chgroup[i].num_channels;
  98. float** ch_data = s->chgroup[i].channel_data;
  99. float** ch_end = ch_data + num_channels;
  100. const int8_t* tb = s->chgroup[i].transform_band;
  101. int16_t* sfb;
  102. /** multichannel decorrelation */
  103. for (sfb = s->cur_sfb_offsets ;
  104. sfb < s->cur_sfb_offsets + s->num_bands;sfb++) {
  105. if (*tb++ == 1) {
  106. int y;
  107. /** multiply values with the decorrelation_matrix */
  108. for (y = sfb[0]; y < FFMIN(sfb[1], s->subframe_len); y++) {
  109. const float* mat = s->chgroup[i].decorrelation_matrix;
  110. const float* data_end = data + num_channels;
  111. float* data_ptr = data;
  112. float** ch;
  113. for (ch = ch_data;ch < ch_end; ch++)
  114. *data_ptr++ = (*ch)[y];
  115. for (ch = ch_data; ch < ch_end; ch++) {
  116. float sum = 0;
  117. data_ptr = data;
  118. while (data_ptr < data_end)
  119. sum += *data_ptr++ * *mat++;
  120. (*ch)[y] = sum;
  121. }
  122. }
  123. }
  124. }
  125. }
  126. }
  127. }