ffmpeg / libavcodec / nellymoserenc.c @ f2e57867
History  View  Annotate  Download (12.7 KB)
1 
/*


2 
* Nellymoser encoder

3 
* This code is developed as part of Google Summer of Code 2008 Program.

4 
*

5 
* Copyright (c) 2008 Bartlomiej Wolowiec

6 
*

7 
* This file is part of FFmpeg.

8 
*

9 
* FFmpeg is free software; you can redistribute it and/or

10 
* modify it under the terms of the GNU Lesser General Public

11 
* License as published by the Free Software Foundation; either

12 
* version 2.1 of the License, or (at your option) any later version.

13 
*

14 
* FFmpeg is distributed in the hope that it will be useful,

15 
* but WITHOUT ANY WARRANTY; without even the implied warranty of

16 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

17 
* Lesser General Public License for more details.

18 
*

19 
* You should have received a copy of the GNU Lesser General Public

20 
* License along with FFmpeg; if not, write to the Free Software

21 
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 021101301 USA

22 
*/

23  
24 
/**

25 
* @file nellymoserenc.c

26 
* Nellymoser encoder

27 
* by Bartlomiej Wolowiec

28 
*

29 
* Generic codec information: libavcodec/nellymoserdec.c

30 
*

31 
* Some information also from: http://www1.mplayerhq.hu/ASAO/ASAO.zip

32 
* (Copyright Joseph Artsimovich and UAB "DKD")

33 
*

34 
* for more information about nellymoser format, visit:

35 
* http://wiki.multimedia.cx/index.php?title=Nellymoser

36 
*/

37  
38 
#include "nellymoser.h" 
39 
#include "avcodec.h" 
40 
#include "dsputil.h" 
41  
42 
#define BITSTREAM_WRITER_LE

43 
#include "bitstream.h" 
44  
45 
#define POW_TABLE_SIZE (1<<11) 
46 
#define POW_TABLE_OFFSET 3 
47  
48 
typedef struct NellyMoserEncodeContext { 
49 
AVCodecContext *avctx; 
50 
int last_frame;

51 
int bufsel;

52 
int have_saved;

53 
DSPContext dsp; 
54 
MDCTContext mdct_ctx; 
55 
DECLARE_ALIGNED_16(float, mdct_out[NELLY_SAMPLES]);

56 
DECLARE_ALIGNED_16(float, buf[2][3 * NELLY_BUF_LEN]); ///< sample buffer 
57 
} NellyMoserEncodeContext; 
58  
59 
static float pow_table[POW_TABLE_SIZE]; ///< pow(2, i / 2048.0  3.0); 
60  
61 
static const uint8_t sf_lut[96] = { 
62 
0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 
63 
5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 12, 13, 13, 14, 
64 
15, 15, 16, 17, 17, 18, 19, 19, 20, 21, 22, 22, 23, 24, 25, 26, 
65 
27, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 
66 
41, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, 
67 
54, 55, 55, 56, 57, 57, 58, 59, 59, 60, 60, 60, 61, 61, 61, 62, 
68 
}; 
69  
70 
static const uint8_t sf_delta_lut[78] = { 
71 
0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 
72 
4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 12, 
73 
13, 13, 14, 15, 16, 17, 17, 18, 19, 19, 20, 21, 21, 22, 22, 23, 
74 
23, 24, 24, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 27, 28, 
75 
28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, 
76 
}; 
77  
78 
static const uint8_t quant_lut[230] = { 
79 
0,

80  
81 
0, 1, 2, 
82  
83 
0, 1, 2, 3, 4, 5, 6, 
84  
85 
0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 
86 
12, 13, 13, 13, 14, 
87  
88 
0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 
89 
8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 
90 
22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 29, 
91 
30,

92  
93 
0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 
94 
4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 
95 
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, 
96 
15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 
97 
21, 21, 22, 22, 23, 23, 24, 25, 26, 26, 27, 28, 29, 30, 31, 32, 
98 
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 42, 43, 44, 44, 45, 45, 
99 
46, 47, 47, 48, 48, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, 
100 
53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, 57, 
101 
58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 60, 61, 61, 61, 
102 
61, 61, 61, 61, 62, 
103 
}; 
104  
105 
static const float quant_lut_mul[7] = { 0.0, 0.0, 2.0, 2.0, 5.0, 12.0, 36.6 }; 
106 
static const float quant_lut_add[7] = { 0.0, 0.0, 2.0, 7.0, 21.0, 56.0, 157.0 }; 
107 
static const uint8_t quant_lut_offset[8] = { 0, 0, 1, 4, 11, 32, 81, 230 }; 
108  
109 
void apply_mdct(NellyMoserEncodeContext *s)

110 
{ 
111 
DECLARE_ALIGNED_16(float, in_buff[NELLY_SAMPLES]);

112  
113 
memcpy(in_buff, s>buf[s>bufsel], NELLY_BUF_LEN * sizeof(float)); 
114 
s>dsp.vector_fmul(in_buff, ff_sine_128, NELLY_BUF_LEN); 
115 
s>dsp.vector_fmul_reverse(in_buff + NELLY_BUF_LEN, s>buf[s>bufsel] + NELLY_BUF_LEN, ff_sine_128, 
116 
NELLY_BUF_LEN); 
117 
ff_mdct_calc(&s>mdct_ctx, s>mdct_out, in_buff); 
118  
119 
s>dsp.vector_fmul(s>buf[s>bufsel] + NELLY_BUF_LEN, ff_sine_128, NELLY_BUF_LEN); 
120 
s>dsp.vector_fmul_reverse(s>buf[s>bufsel] + 2 * NELLY_BUF_LEN, s>buf[1  s>bufsel], ff_sine_128, 
121 
NELLY_BUF_LEN); 
122 
ff_mdct_calc(&s>mdct_ctx, s>mdct_out + NELLY_BUF_LEN, s>buf[s>bufsel] + NELLY_BUF_LEN); 
123 
} 
124  
125 
static av_cold int encode_init(AVCodecContext *avctx) 
126 
{ 
127 
NellyMoserEncodeContext *s = avctx>priv_data; 
128 
int i;

129  
130 
if (avctx>channels != 1) { 
131 
av_log(avctx, AV_LOG_ERROR, "Nellymoser supports only 1 channel\n");

132 
return 1; 
133 
} 
134  
135 
if (avctx>sample_rate != 8000 && avctx>sample_rate != 11025 && 
136 
avctx>sample_rate != 22050 && avctx>sample_rate != 44100 && 
137 
avctx>strict_std_compliance >= FF_COMPLIANCE_NORMAL) { 
138 
av_log(avctx, AV_LOG_ERROR, "Nellymoser works only with 8000, 11025, 22050 and 44100 sample rate\n");

139 
return 1; 
140 
} 
141  
142 
avctx>frame_size = NELLY_SAMPLES; 
143 
s>avctx = avctx; 
144 
ff_mdct_init(&s>mdct_ctx, 8, 0); 
145 
dsputil_init(&s>dsp, avctx); 
146  
147 
/* Generate overlap window */

148 
ff_sine_window_init(ff_sine_128, 128);

149 
for (i = 0; i < POW_TABLE_SIZE; i++) 
150 
pow_table[i] = pow(2, i / 2048.0  3.0 + POW_TABLE_OFFSET); 
151  
152 
return 0; 
153 
} 
154  
155 
static av_cold int encode_end(AVCodecContext *avctx) 
156 
{ 
157 
NellyMoserEncodeContext *s = avctx>priv_data; 
158  
159 
ff_mdct_end(&s>mdct_ctx); 
160 
return 0; 
161 
} 
162  
163 
#define find_best(val, table, LUT, LUT_add, LUT_size) \

164 
best_idx = \ 
165 
LUT[av_clip ((lrintf(val) >> 8) + LUT_add, 0, LUT_size  1)]; \ 
166 
if (fabs(val  table[best_idx]) > fabs(val  table[best_idx + 1])) \ 
167 
best_idx++; 
168  
169 
static void get_exponent_greedy(NellyMoserEncodeContext *s, float *cand, int *idx_table) 
170 
{ 
171 
int band, best_idx, power_idx = 0; 
172 
float power_candidate;

173  
174 
//base exponent

175 
find_best(cand[0], ff_nelly_init_table, sf_lut, 20, 96); 
176 
idx_table[0] = best_idx;

177 
power_idx = ff_nelly_init_table[best_idx]; 
178  
179 
for (band = 1; band < NELLY_BANDS; band++) { 
180 
power_candidate = cand[band]  power_idx; 
181 
find_best(power_candidate, ff_nelly_delta_table, sf_delta_lut, 37, 78); 
182 
idx_table[band] = best_idx; 
183 
power_idx += ff_nelly_delta_table[best_idx]; 
184 
} 
185 
} 
186  
187 
#define OPT_SIZE ((1<<15) + 3000) 
188  
189 
static inline float distance(float x, float y, int band) 
190 
{ 
191 
//return pow(fabs(xy), 2.0);

192 
float tmp = x  y;

193 
return tmp * tmp;

194 
} 
195  
196 
static void get_exponent_dynamic(NellyMoserEncodeContext *s, float *cand, int *idx_table) 
197 
{ 
198 
int i, j, band, best_idx;

199 
float power_candidate, best_val;

200  
201 
float opt[NELLY_BANDS][OPT_SIZE];

202 
int path[NELLY_BANDS][OPT_SIZE];

203  
204 
for (i = 0; i < NELLY_BANDS * OPT_SIZE; i++) { 
205 
opt[0][i] = INFINITY;

206 
} 
207  
208 
for (i = 0; i < 64; i++) { 
209 
opt[0][ff_nelly_init_table[i]] = distance(cand[0], ff_nelly_init_table[i], 0); 
210 
path[0][ff_nelly_init_table[i]] = i;

211 
} 
212  
213 
for (band = 1; band < NELLY_BANDS; band++) { 
214 
int q, c = 0; 
215 
float tmp;

216 
int idx_min, idx_max, idx;

217 
power_candidate = cand[band]; 
218 
for (q = 1000; !c && q < OPT_SIZE; q <<= 2) { 
219 
idx_min = FFMAX(0, cand[band]  q);

220 
idx_max = FFMIN(OPT_SIZE, cand[band  1] + q);

221 
for (i = FFMAX(0, cand[band  1]  q); i < FFMIN(OPT_SIZE, cand[band  1] + q); i++) { 
222 
if ( isinf(opt[band  1][i]) ) 
223 
continue;

224 
for (j = 0; j < 32; j++) { 
225 
idx = i + ff_nelly_delta_table[j]; 
226 
if (idx > idx_max)

227 
break;

228 
if (idx >= idx_min) {

229 
tmp = opt[band  1][i] + distance(idx, power_candidate, band);

230 
if (opt[band][idx] > tmp) {

231 
opt[band][idx] = tmp; 
232 
path[band][idx] = j; 
233 
c = 1;

234 
} 
235 
} 
236 
} 
237 
} 
238 
} 
239 
assert(c); //FIXME

240 
} 
241  
242 
best_val = INFINITY; 
243 
best_idx = 1;

244 
band = NELLY_BANDS  1;

245 
for (i = 0; i < OPT_SIZE; i++) { 
246 
if (best_val > opt[band][i]) {

247 
best_val = opt[band][i]; 
248 
best_idx = i; 
249 
} 
250 
} 
251 
for (band = NELLY_BANDS  1; band >= 0; band) { 
252 
idx_table[band] = path[band][best_idx]; 
253 
if (band) {

254 
best_idx = ff_nelly_delta_table[path[band][best_idx]]; 
255 
} 
256 
} 
257 
} 
258  
259 
/**

260 
* Encodes NELLY_SAMPLES samples. It assumes, that samples contains 3 * NELLY_BUF_LEN values

261 
* @param s encoder context

262 
* @param output output buffer

263 
* @param output_size size of output buffer

264 
*/

265 
static void encode_block(NellyMoserEncodeContext *s, unsigned char *output, int output_size) 
266 
{ 
267 
PutBitContext pb; 
268 
int i, j, band, block, best_idx, power_idx = 0; 
269 
float power_val, coeff, coeff_sum;

270 
float pows[NELLY_FILL_LEN];

271 
int bits[NELLY_BUF_LEN], idx_table[NELLY_BANDS];

272 
float cand[NELLY_BANDS];

273  
274 
apply_mdct(s); 
275  
276 
init_put_bits(&pb, output, output_size * 8);

277  
278 
i = 0;

279 
for (band = 0; band < NELLY_BANDS; band++) { 
280 
coeff_sum = 0;

281 
for (j = 0; j < ff_nelly_band_sizes_table[band]; i++, j++) { 
282 
coeff_sum += s>mdct_out[i ] * s>mdct_out[i ] 
283 
+ s>mdct_out[i + NELLY_BUF_LEN] * s>mdct_out[i + NELLY_BUF_LEN]; 
284 
} 
285 
cand[band] = 
286 
log(FFMAX(1.0, coeff_sum / (ff_nelly_band_sizes_table[band] << 7))) * 1024.0 / M_LN2; 
287 
} 
288  
289 
if (s>avctx>trellis) {

290 
get_exponent_dynamic(s, cand, idx_table); 
291 
} else {

292 
get_exponent_greedy(s, cand, idx_table); 
293 
} 
294  
295 
i = 0;

296 
for (band = 0; band < NELLY_BANDS; band++) { 
297 
if (band) {

298 
power_idx += ff_nelly_delta_table[idx_table[band]]; 
299 
put_bits(&pb, 5, idx_table[band]);

300 
} else {

301 
power_idx = ff_nelly_init_table[idx_table[0]];

302 
put_bits(&pb, 6, idx_table[0]); 
303 
} 
304 
power_val = pow_table[power_idx & 0x7FF] / (1 << ((power_idx >> 11) + POW_TABLE_OFFSET)); 
305 
for (j = 0; j < ff_nelly_band_sizes_table[band]; i++, j++) { 
306 
s>mdct_out[i] *= power_val; 
307 
s>mdct_out[i + NELLY_BUF_LEN] *= power_val; 
308 
pows[i] = power_idx; 
309 
} 
310 
} 
311  
312 
ff_nelly_get_sample_bits(pows, bits); 
313  
314 
for (block = 0; block < 2; block++) { 
315 
for (i = 0; i < NELLY_FILL_LEN; i++) { 
316 
if (bits[i] > 0) { 
317 
const float *table = ff_nelly_dequantization_table + (1 << bits[i])  1; 
318 
coeff = s>mdct_out[block * NELLY_BUF_LEN + i]; 
319 
best_idx = 
320 
quant_lut[av_clip ( 
321 
coeff * quant_lut_mul[bits[i]] + quant_lut_add[bits[i]], 
322 
quant_lut_offset[bits[i]], 
323 
quant_lut_offset[bits[i]+1]  1 
324 
)]; 
325 
if (fabs(coeff  table[best_idx]) > fabs(coeff  table[best_idx + 1])) 
326 
best_idx++; 
327  
328 
put_bits(&pb, bits[i], best_idx); 
329 
} 
330 
} 
331 
if (!block)

332 
put_bits(&pb, NELLY_HEADER_BITS + NELLY_DETAIL_BITS  put_bits_count(&pb), 0);

333 
} 
334  
335 
flush_put_bits(&pb); 
336 
} 
337  
338 
static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, void *data) 
339 
{ 
340 
NellyMoserEncodeContext *s = avctx>priv_data; 
341 
int16_t *samples = data; 
342 
int i;

343  
344 
if (s>last_frame)

345 
return 0; 
346  
347 
if (data) {

348 
for (i = 0; i < avctx>frame_size; i++) { 
349 
s>buf[s>bufsel][i] = samples[i]; 
350 
} 
351 
for (; i < NELLY_SAMPLES; i++) {

352 
s>buf[s>bufsel][i] = 0;

353 
} 
354 
s>bufsel = 1  s>bufsel;

355 
if (!s>have_saved) {

356 
s>have_saved = 1;

357 
return 0; 
358 
} 
359 
} else {

360 
memset(s>buf[s>bufsel], 0, sizeof(s>buf[0][0]) * NELLY_BUF_LEN); 
361 
s>bufsel = 1  s>bufsel;

362 
s>last_frame = 1;

363 
} 
364  
365 
if (s>have_saved) {

366 
encode_block(s, frame, buf_size); 
367 
return NELLY_BLOCK_LEN;

368 
} 
369 
return 0; 
370 
} 
371  
372 
AVCodec nellymoser_encoder = { 
373 
.name = "nellymoser",

374 
.type = CODEC_TYPE_AUDIO, 
375 
.id = CODEC_ID_NELLYMOSER, 
376 
.priv_data_size = sizeof(NellyMoserEncodeContext),

377 
.init = encode_init, 
378 
.encode = encode_frame, 
379 
.close = encode_end, 
380 
.capabilities = CODEC_CAP_SMALL_LAST_FRAME  CODEC_CAP_DELAY, 
381 
.long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao Codec"),

382 
}; 