3 * This code is developed as part of Google Summer of Code 2008 Program.
5 * Copyright (c) 2008 Bartlomiej Wolowiec
7 * This file is part of Libav.
9 * Libav 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.
14 * Libav 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.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with Libav; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 * by Bartlomiej Wolowiec
29 * Generic codec information: libavcodec/nellymoserdec.c
31 * Some information also from: http://samples.libav.org/A-codecs/Nelly_Moser/ASAO/ASAO.zip
32 * (Copyright Joseph Artsimovich and UAB "DKD")
34 * for more information about nellymoser format, visit:
35 * http://wiki.multimedia.cx/index.php?title=Nellymoser
38 #include "libavutil/mathematics.h"
39 #include "nellymoser.h"
45 #define BITSTREAM_WRITER_LE
48 #define POW_TABLE_SIZE (1<<11)
49 #define POW_TABLE_OFFSET 3
50 #define OPT_SIZE ((1<<15) + 3000)
52 typedef struct NellyMoserEncodeContext {
53 AVCodecContext *avctx;
59 DECLARE_ALIGNED(32, float, mdct_out)[NELLY_SAMPLES];
60 DECLARE_ALIGNED(32, float, in_buff)[NELLY_SAMPLES];
61 DECLARE_ALIGNED(32, float, buf)[2][3 * NELLY_BUF_LEN]; ///< sample buffer
62 float (*opt )[NELLY_BANDS];
63 uint8_t (*path)[NELLY_BANDS];
64 } NellyMoserEncodeContext;
66 static float pow_table[POW_TABLE_SIZE]; ///< -pow(2, -i / 2048.0 - 3.0);
68 static const uint8_t sf_lut[96] = {
69 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
70 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 12, 13, 13, 14,
71 15, 15, 16, 17, 17, 18, 19, 19, 20, 21, 22, 22, 23, 24, 25, 26,
72 27, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40,
73 41, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53,
74 54, 55, 55, 56, 57, 57, 58, 59, 59, 60, 60, 60, 61, 61, 61, 62,
77 static const uint8_t sf_delta_lut[78] = {
78 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
79 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 12,
80 13, 13, 14, 15, 16, 17, 17, 18, 19, 19, 20, 21, 21, 22, 22, 23,
81 23, 24, 24, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 27, 28,
82 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30,
85 static const uint8_t quant_lut[230] = {
92 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11,
95 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8,
96 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
97 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 29,
100 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3,
101 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9,
102 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
103 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20,
104 21, 21, 22, 22, 23, 23, 24, 25, 26, 26, 27, 28, 29, 30, 31, 32,
105 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 42, 43, 44, 44, 45, 45,
106 46, 47, 47, 48, 48, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52,
107 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, 57,
108 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 60, 61, 61, 61,
112 static const float quant_lut_mul[7] = { 0.0, 0.0, 2.0, 2.0, 5.0, 12.0, 36.6 };
113 static const float quant_lut_add[7] = { 0.0, 0.0, 2.0, 7.0, 21.0, 56.0, 157.0 };
114 static const uint8_t quant_lut_offset[8] = { 0, 0, 1, 4, 11, 32, 81, 230 };
116 static void apply_mdct(NellyMoserEncodeContext *s)
118 s->dsp.vector_fmul(s->in_buff, s->buf[s->bufsel], ff_sine_128, NELLY_BUF_LEN);
119 s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, s->buf[s->bufsel] + NELLY_BUF_LEN, ff_sine_128,
121 s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out, s->in_buff);
123 s->dsp.vector_fmul(s->buf[s->bufsel] + NELLY_BUF_LEN, s->buf[s->bufsel] + NELLY_BUF_LEN,
124 ff_sine_128, NELLY_BUF_LEN);
125 s->dsp.vector_fmul_reverse(s->buf[s->bufsel] + 2 * NELLY_BUF_LEN, s->buf[1 - s->bufsel], ff_sine_128,
127 s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out + NELLY_BUF_LEN, s->buf[s->bufsel] + NELLY_BUF_LEN);
130 static av_cold int encode_init(AVCodecContext *avctx)
132 NellyMoserEncodeContext *s = avctx->priv_data;
135 if (avctx->channels != 1) {
136 av_log(avctx, AV_LOG_ERROR, "Nellymoser supports only 1 channel\n");
140 if (avctx->sample_rate != 8000 && avctx->sample_rate != 16000 &&
141 avctx->sample_rate != 11025 &&
142 avctx->sample_rate != 22050 && avctx->sample_rate != 44100 &&
143 avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
144 av_log(avctx, AV_LOG_ERROR, "Nellymoser works only with 8000, 16000, 11025, 22050 and 44100 sample rate\n");
148 avctx->frame_size = NELLY_SAMPLES;
150 ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0);
151 dsputil_init(&s->dsp, avctx);
153 /* Generate overlap window */
154 ff_sine_window_init(ff_sine_128, 128);
155 for (i = 0; i < POW_TABLE_SIZE; i++)
156 pow_table[i] = -pow(2, -i / 2048.0 - 3.0 + POW_TABLE_OFFSET);
158 if (s->avctx->trellis) {
159 s->opt = av_malloc(NELLY_BANDS * OPT_SIZE * sizeof(float ));
160 s->path = av_malloc(NELLY_BANDS * OPT_SIZE * sizeof(uint8_t));
166 static av_cold int encode_end(AVCodecContext *avctx)
168 NellyMoserEncodeContext *s = avctx->priv_data;
170 ff_mdct_end(&s->mdct_ctx);
172 if (s->avctx->trellis) {
180 #define find_best(val, table, LUT, LUT_add, LUT_size) \
182 LUT[av_clip ((lrintf(val) >> 8) + LUT_add, 0, LUT_size - 1)]; \
183 if (fabs(val - table[best_idx]) > fabs(val - table[best_idx + 1])) \
186 static void get_exponent_greedy(NellyMoserEncodeContext *s, float *cand, int *idx_table)
188 int band, best_idx, power_idx = 0;
189 float power_candidate;
192 find_best(cand[0], ff_nelly_init_table, sf_lut, -20, 96);
193 idx_table[0] = best_idx;
194 power_idx = ff_nelly_init_table[best_idx];
196 for (band = 1; band < NELLY_BANDS; band++) {
197 power_candidate = cand[band] - power_idx;
198 find_best(power_candidate, ff_nelly_delta_table, sf_delta_lut, 37, 78);
199 idx_table[band] = best_idx;
200 power_idx += ff_nelly_delta_table[best_idx];
204 static inline float distance(float x, float y, int band)
206 //return pow(fabs(x-y), 2.0);
211 static void get_exponent_dynamic(NellyMoserEncodeContext *s, float *cand, int *idx_table)
213 int i, j, band, best_idx;
214 float power_candidate, best_val;
216 float (*opt )[NELLY_BANDS] = s->opt ;
217 uint8_t(*path)[NELLY_BANDS] = s->path;
219 for (i = 0; i < NELLY_BANDS * OPT_SIZE; i++) {
220 opt[0][i] = INFINITY;
223 for (i = 0; i < 64; i++) {
224 opt[0][ff_nelly_init_table[i]] = distance(cand[0], ff_nelly_init_table[i], 0);
225 path[0][ff_nelly_init_table[i]] = i;
228 for (band = 1; band < NELLY_BANDS; band++) {
231 int idx_min, idx_max, idx;
232 power_candidate = cand[band];
233 for (q = 1000; !c && q < OPT_SIZE; q <<= 2) {
234 idx_min = FFMAX(0, cand[band] - q);
235 idx_max = FFMIN(OPT_SIZE, cand[band - 1] + q);
236 for (i = FFMAX(0, cand[band - 1] - q); i < FFMIN(OPT_SIZE, cand[band - 1] + q); i++) {
237 if ( isinf(opt[band - 1][i]) )
239 for (j = 0; j < 32; j++) {
240 idx = i + ff_nelly_delta_table[j];
243 if (idx >= idx_min) {
244 tmp = opt[band - 1][i] + distance(idx, power_candidate, band);
245 if (opt[band][idx] > tmp) {
246 opt[band][idx] = tmp;
259 band = NELLY_BANDS - 1;
260 for (i = 0; i < OPT_SIZE; i++) {
261 if (best_val > opt[band][i]) {
262 best_val = opt[band][i];
266 for (band = NELLY_BANDS - 1; band >= 0; band--) {
267 idx_table[band] = path[band][best_idx];
269 best_idx -= ff_nelly_delta_table[path[band][best_idx]];
275 * Encode NELLY_SAMPLES samples. It assumes, that samples contains 3 * NELLY_BUF_LEN values
276 * @param s encoder context
277 * @param output output buffer
278 * @param output_size size of output buffer
280 static void encode_block(NellyMoserEncodeContext *s, unsigned char *output, int output_size)
283 int i, j, band, block, best_idx, power_idx = 0;
284 float power_val, coeff, coeff_sum;
285 float pows[NELLY_FILL_LEN];
286 int bits[NELLY_BUF_LEN], idx_table[NELLY_BANDS];
287 float cand[NELLY_BANDS];
291 init_put_bits(&pb, output, output_size * 8);
294 for (band = 0; band < NELLY_BANDS; band++) {
296 for (j = 0; j < ff_nelly_band_sizes_table[band]; i++, j++) {
297 coeff_sum += s->mdct_out[i ] * s->mdct_out[i ]
298 + s->mdct_out[i + NELLY_BUF_LEN] * s->mdct_out[i + NELLY_BUF_LEN];
301 log(FFMAX(1.0, coeff_sum / (ff_nelly_band_sizes_table[band] << 7))) * 1024.0 / M_LN2;
304 if (s->avctx->trellis) {
305 get_exponent_dynamic(s, cand, idx_table);
307 get_exponent_greedy(s, cand, idx_table);
311 for (band = 0; band < NELLY_BANDS; band++) {
313 power_idx += ff_nelly_delta_table[idx_table[band]];
314 put_bits(&pb, 5, idx_table[band]);
316 power_idx = ff_nelly_init_table[idx_table[0]];
317 put_bits(&pb, 6, idx_table[0]);
319 power_val = pow_table[power_idx & 0x7FF] / (1 << ((power_idx >> 11) + POW_TABLE_OFFSET));
320 for (j = 0; j < ff_nelly_band_sizes_table[band]; i++, j++) {
321 s->mdct_out[i] *= power_val;
322 s->mdct_out[i + NELLY_BUF_LEN] *= power_val;
327 ff_nelly_get_sample_bits(pows, bits);
329 for (block = 0; block < 2; block++) {
330 for (i = 0; i < NELLY_FILL_LEN; i++) {
332 const float *table = ff_nelly_dequantization_table + (1 << bits[i]) - 1;
333 coeff = s->mdct_out[block * NELLY_BUF_LEN + i];
336 coeff * quant_lut_mul[bits[i]] + quant_lut_add[bits[i]],
337 quant_lut_offset[bits[i]],
338 quant_lut_offset[bits[i]+1] - 1
340 if (fabs(coeff - table[best_idx]) > fabs(coeff - table[best_idx + 1]))
343 put_bits(&pb, bits[i], best_idx);
347 put_bits(&pb, NELLY_HEADER_BITS + NELLY_DETAIL_BITS - put_bits_count(&pb), 0);
353 static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, void *data)
355 NellyMoserEncodeContext *s = avctx->priv_data;
356 const float *samples = data;
363 memcpy(s->buf[s->bufsel], samples, avctx->frame_size * sizeof(*samples));
364 for (i = avctx->frame_size; i < NELLY_SAMPLES; i++) {
365 s->buf[s->bufsel][i] = 0;
367 s->bufsel = 1 - s->bufsel;
368 if (!s->have_saved) {
373 memset(s->buf[s->bufsel], 0, sizeof(s->buf[0][0]) * NELLY_BUF_LEN);
374 s->bufsel = 1 - s->bufsel;
379 encode_block(s, frame, buf_size);
380 return NELLY_BLOCK_LEN;
385 AVCodec ff_nellymoser_encoder = {
386 .name = "nellymoser",
387 .type = AVMEDIA_TYPE_AUDIO,
388 .id = CODEC_ID_NELLYMOSER,
389 .priv_data_size = sizeof(NellyMoserEncodeContext),
391 .encode = encode_frame,
393 .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
394 .long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"),
395 .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE},