2 *@brief Uninitialize the decoder and free all resources.
3 *@param avctx codec context
4 *@return 0 on success, < 0 otherwise
6 static av_cold
int decode_end(AVCodecContext
*avctx
)
8 WMA3DecodeContext
*s
= avctx
->priv_data
;
11 av_freep(&s
->num_sfb
);
12 av_freep(&s
->sfb_offsets
);
13 av_freep(&s
->subwoofer_cutoffs
);
14 av_freep(&s
->sf_offsets
);
16 for (i
= 0 ; i
< WMAPRO_BLOCK_SIZES
; i
++)
17 ff_mdct_end(&s
->mdct_ctx
[i
]);
23 *@brief Calculate a decorrelation matrix from the bitstream parameters.
24 *@param s codec context
25 *@param chgroup channel group for which the matrix needs to be calculated
27 static void decode_decorrelation_matrix(WMA3DecodeContext
*s
,
28 WMA3ChannelGroup
*chgroup
)
32 int8_t rotation_offset
[WMAPRO_MAX_CHANNELS
* WMAPRO_MAX_CHANNELS
];
33 memset(chgroup
->decorrelation_matrix
,0,
34 sizeof(float) *s
->num_channels
* s
->num_channels
);
36 for (i
= 0; i
< chgroup
->num_channels
* (chgroup
->num_channels
- 1) >> 1; i
++)
37 rotation_offset
[i
] = get_bits(&s
->gb
,6);
39 for (i
= 0; i
< chgroup
->num_channels
; i
++)
40 chgroup
->decorrelation_matrix
[chgroup
->num_channels
* i
+ i
] =
41 get_bits1(&s
->gb
) ? 1.0 : -1.0;
43 for (i
= 1; i
< chgroup
->num_channels
; i
++) {
45 for (x
= 0; x
< i
; x
++) {
47 for (y
= 0; y
< i
+ 1 ; y
++) {
48 float v1
= chgroup
->decorrelation_matrix
[x
* chgroup
->num_channels
+ y
];
49 float v2
= chgroup
->decorrelation_matrix
[i
* chgroup
->num_channels
+ y
];
50 int n
= rotation_offset
[offset
+ x
];
62 chgroup
->decorrelation_matrix
[y
+ x
* chgroup
->num_channels
] =
63 (v1
* sinv
) - (v2
* cosv
);
64 chgroup
->decorrelation_matrix
[y
+ i
* chgroup
->num_channels
] =
65 (v1
* cosv
) + (v2
* sinv
);
73 *@brief Reconstruct the individual channel data.
74 *@param s codec context
76 static void inverse_channel_transform(WMA3DecodeContext
*s
)
80 for (i
= 0; i
< s
->num_chgroups
; i
++) {
82 if (s
->chgroup
[i
].transform
== 1) {
83 /** M/S stereo decoding */
84 int16_t* sfb_offsets
= s
->cur_sfb_offsets
;
85 float* ch0
= *sfb_offsets
+ s
->channel
[0].coeffs
;
86 float* ch1
= *sfb_offsets
++ + s
->channel
[1].coeffs
;
87 const char* tb
= s
->chgroup
[i
].transform_band
;
88 const char* tb_end
= tb
+ s
->num_bands
;
91 const float* ch0_end
= s
->channel
[0].coeffs
+
92 FFMIN(*sfb_offsets
,s
->subframe_len
);
94 while (ch0
< ch0_end
) {
95 const float v1
= *ch0
;
96 const float v2
= *ch1
;
101 while (ch0
< ch0_end
) {
102 *ch0
++ *= 181.0 / 128;
103 *ch1
++ *= 181.0 / 128;
108 } else if (s
->chgroup
[i
].transform
) {
109 float data
[WMAPRO_MAX_CHANNELS
];
110 const int num_channels
= s
->chgroup
[i
].num_channels
;
111 float** ch_data
= s
->chgroup
[i
].channel_data
;
112 float** ch_end
= ch_data
+ num_channels
;
113 const int8_t* tb
= s
->chgroup
[i
].transform_band
;
116 /** multichannel decorrelation */
117 for (sfb
= s
->cur_sfb_offsets
;
118 sfb
< s
->cur_sfb_offsets
+ s
->num_bands
;sfb
++) {
121 /** multiply values with the decorrelation_matrix */
122 for (y
= sfb
[0]; y
< FFMIN(sfb
[1], s
->subframe_len
); y
++) {
123 const float* mat
= s
->chgroup
[i
].decorrelation_matrix
;
124 const float* data_end
= data
+ num_channels
;
125 float* data_ptr
= data
;
128 for (ch
= ch_data
;ch
< ch_end
; ch
++)
129 *data_ptr
++ = (*ch
)[y
];
131 for (ch
= ch_data
; ch
< ch_end
; ch
++) {
134 while (data_ptr
< data_end
)
135 sum
+= *data_ptr
++ * *mat
++;