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;
57 DECLARE_ALIGNED(32, float, mdct_out)[NELLY_SAMPLES];
58 DECLARE_ALIGNED(32, float, in_buff)[NELLY_SAMPLES];
59 DECLARE_ALIGNED(32, float, buf)[3 * NELLY_BUF_LEN]; ///< sample buffer
60 float (*opt )[NELLY_BANDS];
61 uint8_t (*path)[NELLY_BANDS];
62 } NellyMoserEncodeContext;
64 static float pow_table[POW_TABLE_SIZE]; ///< -pow(2, -i / 2048.0 - 3.0);
66 static const uint8_t sf_lut[96] = {
67 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
68 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 12, 13, 13, 14,
69 15, 15, 16, 17, 17, 18, 19, 19, 20, 21, 22, 22, 23, 24, 25, 26,
70 27, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40,
71 41, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53,
72 54, 55, 55, 56, 57, 57, 58, 59, 59, 60, 60, 60, 61, 61, 61, 62,
75 static const uint8_t sf_delta_lut[78] = {
76 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
77 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 12,
78 13, 13, 14, 15, 16, 17, 17, 18, 19, 19, 20, 21, 21, 22, 22, 23,
79 23, 24, 24, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 27, 28,
80 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30,
83 static const uint8_t quant_lut[230] = {
90 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11,
93 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8,
94 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
95 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 29,
98 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3,
99 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9,
100 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
101 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20,
102 21, 21, 22, 22, 23, 23, 24, 25, 26, 26, 27, 28, 29, 30, 31, 32,
103 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 42, 43, 44, 44, 45, 45,
104 46, 47, 47, 48, 48, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52,
105 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, 57,
106 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 60, 61, 61, 61,
110 static const float quant_lut_mul[7] = { 0.0, 0.0, 2.0, 2.0, 5.0, 12.0, 36.6 };
111 static const float quant_lut_add[7] = { 0.0, 0.0, 2.0, 7.0, 21.0, 56.0, 157.0 };
112 static const uint8_t quant_lut_offset[8] = { 0, 0, 1, 4, 11, 32, 81, 230 };
114 static void apply_mdct(NellyMoserEncodeContext *s)
117 float *in1 = s->buf + NELLY_BUF_LEN;
118 float *in2 = s->buf + 2 * NELLY_BUF_LEN;
120 s->dsp.vector_fmul (s->in_buff, in0, ff_sine_128, NELLY_BUF_LEN);
121 s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in1, ff_sine_128, NELLY_BUF_LEN);
122 s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out, s->in_buff);
124 s->dsp.vector_fmul (s->in_buff, in1, ff_sine_128, NELLY_BUF_LEN);
125 s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in2, ff_sine_128, NELLY_BUF_LEN);
126 s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out + NELLY_BUF_LEN, s->in_buff);
129 static av_cold int encode_end(AVCodecContext *avctx)
131 NellyMoserEncodeContext *s = avctx->priv_data;
133 ff_mdct_end(&s->mdct_ctx);
135 if (s->avctx->trellis) {
139 av_freep(&avctx->coded_frame);
144 static av_cold int encode_init(AVCodecContext *avctx)
146 NellyMoserEncodeContext *s = avctx->priv_data;
149 if (avctx->channels != 1) {
150 av_log(avctx, AV_LOG_ERROR, "Nellymoser supports only 1 channel\n");
151 return AVERROR(EINVAL);
154 if (avctx->sample_rate != 8000 && avctx->sample_rate != 16000 &&
155 avctx->sample_rate != 11025 &&
156 avctx->sample_rate != 22050 && avctx->sample_rate != 44100 &&
157 avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
158 av_log(avctx, AV_LOG_ERROR, "Nellymoser works only with 8000, 16000, 11025, 22050 and 44100 sample rate\n");
159 return AVERROR(EINVAL);
162 avctx->frame_size = NELLY_SAMPLES;
163 avctx->delay = NELLY_BUF_LEN;
165 if ((ret = ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0)) < 0)
167 ff_dsputil_init(&s->dsp, avctx);
169 /* Generate overlap window */
170 ff_sine_window_init(ff_sine_128, 128);
171 for (i = 0; i < POW_TABLE_SIZE; i++)
172 pow_table[i] = -pow(2, -i / 2048.0 - 3.0 + POW_TABLE_OFFSET);
174 if (s->avctx->trellis) {
175 s->opt = av_malloc(NELLY_BANDS * OPT_SIZE * sizeof(float ));
176 s->path = av_malloc(NELLY_BANDS * OPT_SIZE * sizeof(uint8_t));
177 if (!s->opt || !s->path) {
178 ret = AVERROR(ENOMEM);
183 avctx->coded_frame = avcodec_alloc_frame();
184 if (!avctx->coded_frame) {
185 ret = AVERROR(ENOMEM);
195 #define find_best(val, table, LUT, LUT_add, LUT_size) \
197 LUT[av_clip ((lrintf(val) >> 8) + LUT_add, 0, LUT_size - 1)]; \
198 if (fabs(val - table[best_idx]) > fabs(val - table[best_idx + 1])) \
201 static void get_exponent_greedy(NellyMoserEncodeContext *s, float *cand, int *idx_table)
203 int band, best_idx, power_idx = 0;
204 float power_candidate;
207 find_best(cand[0], ff_nelly_init_table, sf_lut, -20, 96);
208 idx_table[0] = best_idx;
209 power_idx = ff_nelly_init_table[best_idx];
211 for (band = 1; band < NELLY_BANDS; band++) {
212 power_candidate = cand[band] - power_idx;
213 find_best(power_candidate, ff_nelly_delta_table, sf_delta_lut, 37, 78);
214 idx_table[band] = best_idx;
215 power_idx += ff_nelly_delta_table[best_idx];
219 static inline float distance(float x, float y, int band)
221 //return pow(fabs(x-y), 2.0);
226 static void get_exponent_dynamic(NellyMoserEncodeContext *s, float *cand, int *idx_table)
228 int i, j, band, best_idx;
229 float power_candidate, best_val;
231 float (*opt )[NELLY_BANDS] = s->opt ;
232 uint8_t(*path)[NELLY_BANDS] = s->path;
234 for (i = 0; i < NELLY_BANDS * OPT_SIZE; i++) {
235 opt[0][i] = INFINITY;
238 for (i = 0; i < 64; i++) {
239 opt[0][ff_nelly_init_table[i]] = distance(cand[0], ff_nelly_init_table[i], 0);
240 path[0][ff_nelly_init_table[i]] = i;
243 for (band = 1; band < NELLY_BANDS; band++) {
246 int idx_min, idx_max, idx;
247 power_candidate = cand[band];
248 for (q = 1000; !c && q < OPT_SIZE; q <<= 2) {
249 idx_min = FFMAX(0, cand[band] - q);
250 idx_max = FFMIN(OPT_SIZE, cand[band - 1] + q);
251 for (i = FFMAX(0, cand[band - 1] - q); i < FFMIN(OPT_SIZE, cand[band - 1] + q); i++) {
252 if ( isinf(opt[band - 1][i]) )
254 for (j = 0; j < 32; j++) {
255 idx = i + ff_nelly_delta_table[j];
258 if (idx >= idx_min) {
259 tmp = opt[band - 1][i] + distance(idx, power_candidate, band);
260 if (opt[band][idx] > tmp) {
261 opt[band][idx] = tmp;
274 band = NELLY_BANDS - 1;
275 for (i = 0; i < OPT_SIZE; i++) {
276 if (best_val > opt[band][i]) {
277 best_val = opt[band][i];
281 for (band = NELLY_BANDS - 1; band >= 0; band--) {
282 idx_table[band] = path[band][best_idx];
284 best_idx -= ff_nelly_delta_table[path[band][best_idx]];
290 * Encode NELLY_SAMPLES samples. It assumes, that samples contains 3 * NELLY_BUF_LEN values
291 * @param s encoder context
292 * @param output output buffer
293 * @param output_size size of output buffer
295 static void encode_block(NellyMoserEncodeContext *s, unsigned char *output, int output_size)
298 int i, j, band, block, best_idx, power_idx = 0;
299 float power_val, coeff, coeff_sum;
300 float pows[NELLY_FILL_LEN];
301 int bits[NELLY_BUF_LEN], idx_table[NELLY_BANDS];
302 float cand[NELLY_BANDS];
306 init_put_bits(&pb, output, output_size * 8);
309 for (band = 0; band < NELLY_BANDS; band++) {
311 for (j = 0; j < ff_nelly_band_sizes_table[band]; i++, j++) {
312 coeff_sum += s->mdct_out[i ] * s->mdct_out[i ]
313 + s->mdct_out[i + NELLY_BUF_LEN] * s->mdct_out[i + NELLY_BUF_LEN];
316 log(FFMAX(1.0, coeff_sum / (ff_nelly_band_sizes_table[band] << 7))) * 1024.0 / M_LN2;
319 if (s->avctx->trellis) {
320 get_exponent_dynamic(s, cand, idx_table);
322 get_exponent_greedy(s, cand, idx_table);
326 for (band = 0; band < NELLY_BANDS; band++) {
328 power_idx += ff_nelly_delta_table[idx_table[band]];
329 put_bits(&pb, 5, idx_table[band]);
331 power_idx = ff_nelly_init_table[idx_table[0]];
332 put_bits(&pb, 6, idx_table[0]);
334 power_val = pow_table[power_idx & 0x7FF] / (1 << ((power_idx >> 11) + POW_TABLE_OFFSET));
335 for (j = 0; j < ff_nelly_band_sizes_table[band]; i++, j++) {
336 s->mdct_out[i] *= power_val;
337 s->mdct_out[i + NELLY_BUF_LEN] *= power_val;
342 ff_nelly_get_sample_bits(pows, bits);
344 for (block = 0; block < 2; block++) {
345 for (i = 0; i < NELLY_FILL_LEN; i++) {
347 const float *table = ff_nelly_dequantization_table + (1 << bits[i]) - 1;
348 coeff = s->mdct_out[block * NELLY_BUF_LEN + i];
351 coeff * quant_lut_mul[bits[i]] + quant_lut_add[bits[i]],
352 quant_lut_offset[bits[i]],
353 quant_lut_offset[bits[i]+1] - 1
355 if (fabs(coeff - table[best_idx]) > fabs(coeff - table[best_idx + 1]))
358 put_bits(&pb, bits[i], best_idx);
362 put_bits(&pb, NELLY_HEADER_BITS + NELLY_DETAIL_BITS - put_bits_count(&pb), 0);
366 memset(put_bits_ptr(&pb), 0, output + output_size - put_bits_ptr(&pb));
369 static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, void *data)
371 NellyMoserEncodeContext *s = avctx->priv_data;
372 const float *samples = data;
377 memcpy(s->buf, s->buf + NELLY_SAMPLES, NELLY_BUF_LEN * sizeof(*s->buf));
379 memcpy(s->buf + NELLY_BUF_LEN, samples, avctx->frame_size * sizeof(*s->buf));
380 if (avctx->frame_size < NELLY_SAMPLES) {
381 memset(s->buf + NELLY_BUF_LEN + avctx->frame_size, 0,
382 (NELLY_SAMPLES - avctx->frame_size) * sizeof(*s->buf));
383 if (avctx->frame_size >= NELLY_BUF_LEN)
387 memset(s->buf + NELLY_BUF_LEN, 0, NELLY_SAMPLES * sizeof(*s->buf));
391 encode_block(s, frame, buf_size);
392 return NELLY_BLOCK_LEN;
395 AVCodec ff_nellymoser_encoder = {
396 .name = "nellymoser",
397 .type = AVMEDIA_TYPE_AUDIO,
398 .id = CODEC_ID_NELLYMOSER,
399 .priv_data_size = sizeof(NellyMoserEncodeContext),
401 .encode = encode_frame,
403 .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
404 .long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"),
405 .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE},