1/* 2 * The simplest AC-3 encoder 3 * Copyright (c) 2000 Fabrice Bellard 4 * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com> 5 * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de> 6 * 7 * This file is part of Libav. 8 * 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. 13 * 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. 18 * 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 22 */ 23 24/** 25 * @file 26 * floating-point AC-3 encoder. 27 */ 28 29#define CONFIG_AC3ENC_FLOAT 1 30#include "ac3enc.h" 31#include "eac3enc.h" 32#include "kbdwin.h" 33 34 35#if CONFIG_AC3_ENCODER 36#define AC3ENC_TYPE AC3ENC_TYPE_AC3 37#include "ac3enc_opts_template.c" 38static const AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name, 39 ac3_options, LIBAVUTIL_VERSION_INT }; 40#endif 41 42#include "ac3enc_template.c" 43 44 45/** 46 * Finalize MDCT and free allocated memory. 47 * 48 * @param s AC-3 encoder private context 49 */ 50av_cold void ff_ac3_float_mdct_end(AC3EncodeContext *s) 51{ 52 ff_mdct_end(&s->mdct); 53 av_freep(&s->mdct_window); 54} 55 56 57/** 58 * Initialize MDCT tables. 59 * 60 * @param s AC-3 encoder private context 61 * @return 0 on success, negative error code on failure 62 */ 63av_cold int ff_ac3_float_mdct_init(AC3EncodeContext *s) 64{ 65 float *window; 66 int i, n, n2; 67 68 n = 1 << 9; 69 n2 = n >> 1; 70 71 window = av_malloc(n * sizeof(*window)); 72 if (!window) { 73 av_log(s->avctx, AV_LOG_ERROR, "Cannot allocate memory.\n"); 74 return AVERROR(ENOMEM); 75 } 76 ff_kbd_window_init(window, 5.0, n2); 77 for (i = 0; i < n2; i++) 78 window[n-1-i] = window[i]; 79 s->mdct_window = window; 80 81 return ff_mdct_init(&s->mdct, 9, 0, -2.0 / n); 82} 83 84 85/* 86 * Apply KBD window to input samples prior to MDCT. 87 */ 88static void apply_window(DSPContext *dsp, float *output, const float *input, 89 const float *window, unsigned int len) 90{ 91 dsp->vector_fmul(output, input, window, len); 92} 93 94 95/* 96 * Normalize the input samples. 97 * Not needed for the floating-point encoder. 98 */ 99static int normalize_samples(AC3EncodeContext *s) 100{ 101 return 0; 102} 103 104 105/* 106 * Scale MDCT coefficients from float to 24-bit fixed-point. 107 */ 108static void scale_coefficients(AC3EncodeContext *s) 109{ 110 int chan_size = AC3_MAX_COEFS * s->num_blocks; 111 int cpl = s->cpl_on; 112 s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer + (chan_size * !cpl), 113 s->mdct_coef_buffer + (chan_size * !cpl), 114 chan_size * (s->channels + cpl)); 115} 116 117 118/* 119 * Clip MDCT coefficients to allowable range. 120 */ 121static void clip_coefficients(DSPContext *dsp, float *coef, unsigned int len) 122{ 123 dsp->vector_clipf(coef, coef, COEF_MIN, COEF_MAX, len); 124} 125 126 127/* 128 * Calculate a single coupling coordinate. 129 */ 130static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) 131{ 132 float coord = 0.125; 133 if (energy_cpl > 0) 134 coord *= sqrtf(energy_ch / energy_cpl); 135 return FFMIN(coord, COEF_MAX); 136} 137 138 139#if CONFIG_AC3_ENCODER 140AVCodec ff_ac3_encoder = { 141 .name = "ac3", 142 .type = AVMEDIA_TYPE_AUDIO, 143 .id = CODEC_ID_AC3, 144 .priv_data_size = sizeof(AC3EncodeContext), 145 .init = ff_ac3_encode_init, 146 .encode = ff_ac3_float_encode_frame, 147 .close = ff_ac3_encode_close, 148 .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE}, 149 .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), 150 .priv_class = &ac3enc_class, 151 .channel_layouts = ff_ac3_channel_layouts, 152}; 153#endif 154