1 /**
2 * Aften: A/52 audio encoder
3 * Copyright (c) 2006 Justin Ruggles
4 *
5 * Based on "The simplest AC3 encoder" from FFmpeg
6 * Copyright (c) 2000 Fabrice Bellard.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /**
24 * @file exponent_common.c
25 * A/52 common exponent functions
26 */
27
28 #include "common.h"
29
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33
34 #include "exponent.h"
35 #include "a52.h"
36
37 /**
38 * LUT for number of exponent groups present.
39 * expsizetab[exponent strategy][number of coefficients]
40 */
41 extern int nexpgrptab[3][256];
42
43 /**
44 * Pre-defined sets of exponent strategies. A strategy set is selected for
45 * each channel in a frame. All sets 1 to 5 use the same number of exponent
46 * bits. Set 0 is only used as the reference of optimal accuracy.
47 * TODO: more options and other sets which use greater or fewer bits
48 */
49 extern uint8_t str_predef[6][6];
50
51 /* set exp[i] to min(exp[i], exp1[i]) */
52 static void
53 exponent_min(uint8_t *exp, uint8_t *exp1, int n);
54
55 /**
56 * Update the exponents so that they are the ones the decoder will decode.
57 * Constrain DC exponent, group exponents based on strategy, constrain delta
58 * between adjacent exponents to +2/-2.
59 */
60 static void
61 encode_exp_blk_ch(uint8_t *exp, int ncoefs, int exp_strategy);
62
63 /**
64 * Determine a good exponent strategy for all blocks of a single channel.
65 * A pre-defined set of strategies is chosen based on the SSE between each set
66 * and the most accurate strategy set (all blocks EXP_D15).
67 */
68 static int
69 compute_expstr_ch(uint8_t *exp[A52_NUM_BLOCKS], int ncoefs);
70
71 /**
72 * Runs the per-channel exponent strategy decision function for all channels
73 */
74 static void
compute_exponent_strategy(A52ThreadContext * tctx)75 compute_exponent_strategy(A52ThreadContext *tctx)
76 {
77 A52Context *ctx = tctx->ctx;
78 A52Frame *frame = &tctx->frame;
79 A52Block *blocks = frame->blocks;
80 int *ncoefs = frame->ncoefs;
81 uint8_t *exp[A52_MAX_CHANNELS][A52_NUM_BLOCKS];
82 int ch, blk, str;
83
84 if(ctx->params.expstr_fast) {
85 for(ch=0; ch<ctx->n_channels; ch++) {
86 for(blk=0; blk<A52_NUM_BLOCKS; blk++) {
87 blocks[blk].exp_strategy[ch] = str_predef[4][blk];
88 }
89 frame->expstr_set[ch] = 4;
90 }
91 } else {
92 for(ch=0; ch<ctx->n_channels; ch++) {
93 for(blk=0; blk<A52_NUM_BLOCKS; blk++)
94 exp[ch][blk] = blocks[blk].exp[ch];
95
96 str = compute_expstr_ch(exp[ch], ncoefs[ch]);
97 for(blk=0; blk<A52_NUM_BLOCKS; blk++) {
98 blocks[blk].exp_strategy[ch] = str_predef[str][blk];
99 }
100 frame->expstr_set[ch] = str;
101 }
102 }
103
104 // lfe channel
105 if(ctx->lfe) {
106 for(blk=0; blk<A52_NUM_BLOCKS; blk++) {
107 blocks[blk].exp_strategy[ctx->lfe_channel] = str_predef[1][blk];
108 }
109 }
110 }
111
112 /**
113 * Encode exponent groups. 3 exponents are in per 7-bit group. The number of
114 * groups varies depending on exponent strategy and bandwidth
115 */
116 static void
group_exponents(A52ThreadContext * tctx)117 group_exponents(A52ThreadContext *tctx)
118 {
119 A52Context *ctx = tctx->ctx;
120 A52Frame *frame = &tctx->frame;
121 A52Block *block;
122 uint8_t *p;
123 int delta[3];
124 int blk, ch, i, gsize, bits;
125 int expstr;
126 int exp0, exp1, exp2, exp3;
127
128 bits = 0;
129 for(blk=0; blk<A52_NUM_BLOCKS; blk++) {
130 block = &frame->blocks[blk];
131 for(ch=0; ch<ctx->n_all_channels; ch++) {
132 expstr = block->exp_strategy[ch];
133 if(expstr == EXP_REUSE) {
134 block->nexpgrps[ch] = 0;
135 continue;
136 }
137 block->nexpgrps[ch] = nexpgrptab[expstr-1][frame->ncoefs[ch]];
138 bits += (4 + (block->nexpgrps[ch] * 7));
139 gsize = expstr + (expstr == EXP_D45);
140 p = block->exp[ch];
141
142 exp1 = *p++;
143 block->grp_exp[ch][0] = exp1;
144
145 for(i=1; i<=block->nexpgrps[ch]; i++) {
146 /* merge three delta into one code */
147 exp0 = exp1;
148 exp1 = p[0];
149 p += gsize;
150 delta[0] = exp1 - exp0 + 2;
151
152 exp2 = p[0];
153 p += gsize;
154 delta[1] = exp2 - exp1 + 2;
155
156 exp3 = p[0];
157 p += gsize;
158 delta[2] = exp3 - exp2 + 2;
159 exp1 = exp3;
160
161 block->grp_exp[ch][i] = ((delta[0]*5+delta[1])*5)+delta[2];
162 }
163 }
164 }
165 frame->exp_bits = bits;
166 }
167
168 /**
169 * Creates final exponents for the entire frame based on exponent strategies.
170 * If the strategy for a block & channel is EXP_REUSE, exponents are copied,
171 * otherwise they are encoded according to the specific exponent strategy.
172 */
173 static void
encode_exponents(A52ThreadContext * tctx)174 encode_exponents(A52ThreadContext *tctx)
175 {
176 A52Context *ctx = tctx->ctx;
177 A52Frame *frame = &tctx->frame;
178 A52Block *blocks = frame->blocks;
179 int *ncoefs = frame->ncoefs;
180 int ch, i, j, k;
181
182 for(ch=0; ch<ctx->n_all_channels; ch++) {
183 // compute the exponents as the decoder will see them. The
184 // EXP_REUSE case must be handled carefully : we select the
185 // min of the exponents
186 i = 0;
187 while(i < A52_NUM_BLOCKS) {
188 j = i + 1;
189 while(j < A52_NUM_BLOCKS && blocks[j].exp_strategy[ch]==EXP_REUSE) {
190 exponent_min(blocks[i].exp[ch], blocks[j].exp[ch], ncoefs[ch]);
191 j++;
192 }
193 encode_exp_blk_ch(blocks[i].exp[ch], ncoefs[ch],
194 blocks[i].exp_strategy[ch]);
195 // copy encoded exponents for reuse case
196 for(k=i+1; k<j; k++) {
197 memcpy(blocks[k].exp[ch], blocks[i].exp[ch], ncoefs[ch]);
198 }
199 i = j;
200 }
201 }
202 }
203
204 /**
205 * Extracts the optimal exponent portion of each MDCT coefficient.
206 */
207 static void
extract_exponents(A52ThreadContext * tctx)208 extract_exponents(A52ThreadContext *tctx)
209 {
210 A52Frame *frame = &tctx->frame;
211 A52Block *block;
212 int all_channels = tctx->ctx->n_all_channels;
213 int blk, ch, j;
214 uint32_t v1, v2;
215
216 for(ch=0; ch<all_channels; ch++) {
217 for(blk=0; blk<A52_NUM_BLOCKS; blk++) {
218 block = &frame->blocks[blk];
219 for(j=0; j<256; j+=2) {
220 v1 = (uint32_t)AFT_FABS(block->mdct_coef[ch][j ] * FCONST(16777216.0));
221 v2 = (uint32_t)AFT_FABS(block->mdct_coef[ch][j+1] * FCONST(16777216.0));
222 block->exp[ch][j ] = (v1 == 0)? 24 : 23 - log2i(v1);
223 block->exp[ch][j+1] = (v2 == 0)? 24 : 23 - log2i(v2);
224 }
225 }
226 }
227 }
228