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