annotate wmaprodec.c @ 10097:9b608d9428ae libavcodec

add decode_coeffs()
author faust3
date Wed, 26 Aug 2009 21:23:21 +0000
parents 071d6d272a77
children 254f8c7d5e4d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10073
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
1 /*
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
2 * Wmapro compatible decoder
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
3 * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
4 * Copyright (c) 2008 - 2009 Sascha Sommer, Benjamin Larsson
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
5 *
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
6 * This file is part of FFmpeg.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
7 *
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
10 * License as published by the Free Software Foundation; either
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
12 *
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
16 * Lesser General Public License for more details.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
17 *
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
21 */
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
22
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
23 /**
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
24 * @file libavcodec/wmaprodec.c
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
25 * @brief wmapro decoder implementation
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
26 * Wmapro is an MDCT based codec comparable to wma standard or AAC.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
27 * The decoding therefore consists of the following steps:
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
28 * - bitstream decoding
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
29 * - reconstruction of per-channel data
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
30 * - rescaling and inverse quantization
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
31 * - IMDCT
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
32 * - windowing and overlapp-add
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
33 *
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
34 * The compressed wmapro bitstream is split into individual packets.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
35 * Every such packet contains one or more wma frames.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
36 * The compressed frames may have a variable length and frames may
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
37 * cross packet boundaries.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
38 * Common to all wmapro frames is the number of samples that are stored in
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
39 * a frame.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
40 * The number of samples and a few other decode flags are stored
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
41 * as extradata that has to be passed to the decoder.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
42 *
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
43 * The wmapro frames themselves are again split into a variable number of
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
44 * subframes. Every subframe contains the data for 2^N time domain samples
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
45 * where N varies between 7 and 12.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
46 *
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
47 * Example wmapro bitstream (in samples):
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
48 *
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
49 * || packet 0 || packet 1 || packet 2 packets
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
50 * ---------------------------------------------------
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
51 * || frame 0 || frame 1 || frame 2 || frames
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
52 * ---------------------------------------------------
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
53 * || | | || | | | || || subframes of channel 0
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
54 * ---------------------------------------------------
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
55 * || | | || | | | || || subframes of channel 1
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
56 * ---------------------------------------------------
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
57 *
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
58 * The frame layouts for the individual channels of a wma frame does not need
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
59 * to be the same.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
60 *
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
61 * However, if the offsets and lengths of several subframes of a frame are the
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
62 * same, the subframes of the channels can be grouped.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
63 * Every group may then use special coding techniques like M/S stereo coding
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
64 * to improve the compression ratio. These channel transformations do not
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
65 * need to be applied to a whole subframe. Instead, they can also work on
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
66 * individual scale factor bands (see below).
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
67 * The coefficients that carry the audio signal in the frequency domain
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
68 * are transmitted as huffman-coded vectors with 4, 2 and 1 elements.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
69 * In addition to that, the encoder can switch to a runlevel coding scheme
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
70 * by transmitting subframe_length / 128 zero coefficients.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
71 *
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
72 * Before the audio signal can be converted to the time domain, the
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
73 * coefficients have to be rescaled and inverse quantized.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
74 * A subframe is therefore split into several scale factor bands that get
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
75 * scaled individually.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
76 * Scale factors are submitted for every frame but they might be shared
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
77 * between the subframes of a channel. Scale factors are initially DPCM-coded.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
78 * Once scale factors are shared, the differences are transmitted as runlevel
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
79 * codes.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
80 * Every subframe length and offset combination in the frame layout shares a
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
81 * common quantization factor that can be adjusted for every channel by a
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
82 * modifier.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
83 * After the inverse quantization, the coefficients get processed by an IMDCT.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
84 * The resulting values are then windowed with a sine window and the first half
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
85 * of the values are added to the second half of the output from the previous
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
86 * subframe in order to reconstruct the output samples.
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
87 */
57d76996ccb8 Add some more wmapro decoder hunks
faust3
parents: 10006
diff changeset
88
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
89 /**
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
90 *@brief Uninitialize the decoder and free all resources.
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
91 *@param avctx codec context
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
92 *@return 0 on success, < 0 otherwise
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
93 */
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
94 static av_cold int decode_end(AVCodecContext *avctx)
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
95 {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
96 WMA3DecodeContext *s = avctx->priv_data;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
97 int i;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
98
10084
bf63f070fbf7 whitespace cosmetics
diego
parents: 10073
diff changeset
99 for (i = 0; i < WMAPRO_BLOCK_SIZES; i++)
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
100 ff_mdct_end(&s->mdct_ctx[i]);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
101
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
102 return 0;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
103 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
104
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
105 /**
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
106 *@brief Calculate a decorrelation matrix from the bitstream parameters.
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
107 *@param s codec context
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
108 *@param chgroup channel group for which the matrix needs to be calculated
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
109 */
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
110 static void decode_decorrelation_matrix(WMA3DecodeContext *s,
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
111 WMA3ChannelGroup *chgroup)
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
112 {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
113 int i;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
114 int offset = 0;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
115 int8_t rotation_offset[WMAPRO_MAX_CHANNELS * WMAPRO_MAX_CHANNELS];
10084
bf63f070fbf7 whitespace cosmetics
diego
parents: 10073
diff changeset
116 memset(chgroup->decorrelation_matrix, 0,
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
117 sizeof(float) *s->num_channels * s->num_channels);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
118
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
119 for (i = 0; i < chgroup->num_channels * (chgroup->num_channels - 1) >> 1; i++)
10084
bf63f070fbf7 whitespace cosmetics
diego
parents: 10073
diff changeset
120 rotation_offset[i] = get_bits(&s->gb, 6);
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
121
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
122 for (i = 0; i < chgroup->num_channels; i++)
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
123 chgroup->decorrelation_matrix[chgroup->num_channels * i + i] =
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
124 get_bits1(&s->gb) ? 1.0 : -1.0;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
125
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
126 for (i = 1; i < chgroup->num_channels; i++) {
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
127 int x;
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
128 for (x = 0; x < i; x++) {
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
129 int y;
10084
bf63f070fbf7 whitespace cosmetics
diego
parents: 10073
diff changeset
130 for (y = 0; y < i + 1; y++) {
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
131 float v1 = chgroup->decorrelation_matrix[x * chgroup->num_channels + y];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
132 float v2 = chgroup->decorrelation_matrix[i * chgroup->num_channels + y];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
133 int n = rotation_offset[offset + x];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
134 float sinv;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
135 float cosv;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
136
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
137 if (n < 32) {
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
138 sinv = sin64[n];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
139 cosv = sin64[32-n];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
140 } else {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
141 sinv = sin64[64-n];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
142 cosv = -sin64[n-32];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
143 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
144
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
145 chgroup->decorrelation_matrix[y + x * chgroup->num_channels] =
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
146 (v1 * sinv) - (v2 * cosv);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
147 chgroup->decorrelation_matrix[y + i * chgroup->num_channels] =
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
148 (v1 * cosv) + (v2 * sinv);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
149 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
150 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
151 offset += i;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
152 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
153 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
154
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
155 /**
10097
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
156 *@brief Extract the coefficients from the bitstream.
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
157 *@param s codec context
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
158 *@param c current channel number
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
159 *@return 0 on success, < 0 in case of bitstream errors
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
160 */
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
161 static int decode_coeffs(WMA3DecodeContext *s, int c)
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
162 {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
163 int vlctable;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
164 VLC* vlc;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
165 WMA3ChannelCtx* ci = &s->channel[c];
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
166 int rl_mode = 0;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
167 int cur_coeff = 0;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
168 int num_zeros = 0;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
169 const uint16_t* run;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
170 const uint16_t* level;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
171
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
172 dprintf(s->avctx, "decode coefficients for channel %i\n", c);
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
173
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
174 vlctable = get_bits1(&s->gb);
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
175 vlc = &coef_vlc[vlctable];
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
176
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
177 if (vlctable) {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
178 run = coef1_run;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
179 level = coef1_level;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
180 } else {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
181 run = coef0_run;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
182 level = coef0_level;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
183 }
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
184
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
185 /** decode vector coefficients (consumes up to 167 bits per iteration for
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
186 4 vector coded large values) */
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
187 while (!rl_mode && cur_coeff + 3 < s->subframe_len) {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
188 int vals[4];
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
189 int i;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
190 unsigned int idx;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
191
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
192 idx = get_vlc2(&s->gb, vec4_vlc.table, VLCBITS, VEC4MAXDEPTH);
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
193
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
194 if ( idx == HUFF_VEC4_SIZE - 1 ) {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
195 for (i = 0; i < 4; i += 2) {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
196 idx = get_vlc2(&s->gb, vec2_vlc.table, VLCBITS, VEC2MAXDEPTH);
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
197 if ( idx == HUFF_VEC2_SIZE - 1 ) {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
198 vals[i] = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH);
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
199 if (vals[i] == HUFF_VEC1_SIZE - 1)
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
200 vals[i] += ff_wma_get_large_val(&s->gb);
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
201 vals[i+1] = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH);
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
202 if (vals[i+1] == HUFF_VEC1_SIZE - 1)
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
203 vals[i+1] += ff_wma_get_large_val(&s->gb);
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
204 } else {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
205 vals[i] = symbol_to_vec2[idx] >> 4;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
206 vals[i+1] = symbol_to_vec2[idx] & 0xF;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
207 }
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
208 }
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
209 } else {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
210 vals[0] = symbol_to_vec4[idx] >> 12;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
211 vals[1] = (symbol_to_vec4[idx] >> 8) & 0xF;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
212 vals[2] = (symbol_to_vec4[idx] >> 4) & 0xF;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
213 vals[3] = symbol_to_vec4[idx] & 0xF;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
214 }
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
215
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
216 /** decode sign */
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
217 for (i = 0; i < 4; i++) {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
218 if (vals[i]) {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
219 int sign = get_bits1(&s->gb) - 1;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
220 ci->coeffs[cur_coeff] = (vals[i]^sign) - sign;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
221 num_zeros = 0;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
222 } else {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
223 /** switch to run level mode when subframe_len / 128 zeros
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
224 were found in a row */
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
225 rl_mode |= (++num_zeros > s->subframe_len>>8);
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
226 }
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
227 ++cur_coeff;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
228 }
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
229 }
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
230
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
231 /** decode run level coded coefficients */
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
232 if (rl_mode) {
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
233 if(ff_wma_run_level_decode(s->avctx, &s->gb, vlc,
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
234 level, run, 1, ci->coeffs,
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
235 cur_coeff, s->subframe_len, s->subframe_len,
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
236 s->esc_len, 0))
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
237 return AVERROR_INVALIDDATA;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
238 }
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
239
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
240 return 0;
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
241 }
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
242
9b608d9428ae add decode_coeffs()
faust3
parents: 10096
diff changeset
243 /**
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
244 *@brief Reconstruct the individual channel data.
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
245 *@param s codec context
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
246 */
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
247 static void inverse_channel_transform(WMA3DecodeContext *s)
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
248 {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
249 int i;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
250
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
251 for (i = 0; i < s->num_chgroups; i++) {
10096
071d6d272a77 merge 2-channel M/S stereo decoding code with the multichannel version
faust3
parents: 10084
diff changeset
252 if (s->chgroup[i].transform) {
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
253 float data[WMAPRO_MAX_CHANNELS];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
254 const int num_channels = s->chgroup[i].num_channels;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
255 float** ch_data = s->chgroup[i].channel_data;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
256 float** ch_end = ch_data + num_channels;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
257 const int8_t* tb = s->chgroup[i].transform_band;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
258 int16_t* sfb;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
259
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
260 /** multichannel decorrelation */
10084
bf63f070fbf7 whitespace cosmetics
diego
parents: 10073
diff changeset
261 for (sfb = s->cur_sfb_offsets;
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
262 sfb < s->cur_sfb_offsets + s->num_bands;sfb++) {
10096
071d6d272a77 merge 2-channel M/S stereo decoding code with the multichannel version
faust3
parents: 10084
diff changeset
263 int y;
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
264 if (*tb++ == 1) {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
265 /** multiply values with the decorrelation_matrix */
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
266 for (y = sfb[0]; y < FFMIN(sfb[1], s->subframe_len); y++) {
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
267 const float* mat = s->chgroup[i].decorrelation_matrix;
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
268 const float* data_end = data + num_channels;
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
269 float* data_ptr = data;
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
270 float** ch;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
271
10084
bf63f070fbf7 whitespace cosmetics
diego
parents: 10073
diff changeset
272 for (ch = ch_data; ch < ch_end; ch++)
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
273 *data_ptr++ = (*ch)[y];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
274
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
275 for (ch = ch_data; ch < ch_end; ch++) {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
276 float sum = 0;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
277 data_ptr = data;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
278 while (data_ptr < data_end)
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
279 sum += *data_ptr++ * *mat++;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
280
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
281 (*ch)[y] = sum;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
282 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
283 }
10096
071d6d272a77 merge 2-channel M/S stereo decoding code with the multichannel version
faust3
parents: 10084
diff changeset
284 } else if (s->num_channels == 2) {
071d6d272a77 merge 2-channel M/S stereo decoding code with the multichannel version
faust3
parents: 10084
diff changeset
285 for (y = sfb[0]; y < FFMIN(sfb[1], s->subframe_len); y++) {
071d6d272a77 merge 2-channel M/S stereo decoding code with the multichannel version
faust3
parents: 10084
diff changeset
286 ch_data[0][y] *= 181.0 / 128;
071d6d272a77 merge 2-channel M/S stereo decoding code with the multichannel version
faust3
parents: 10084
diff changeset
287 ch_data[1][y] *= 181.0 / 128;
071d6d272a77 merge 2-channel M/S stereo decoding code with the multichannel version
faust3
parents: 10084
diff changeset
288 }
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
289 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
290 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
291 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
292 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
293 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
294