yading@10: /* yading@10: * The simplest AC-3 encoder yading@10: * Copyright (c) 2000 Fabrice Bellard yading@10: * Copyright (c) 2006-2010 Justin Ruggles yading@10: * Copyright (c) 2006-2010 Prakash Punnoor yading@10: * yading@10: * This file is part of FFmpeg. yading@10: * yading@10: * FFmpeg is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * FFmpeg is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with FFmpeg; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: /** yading@10: * @file yading@10: * floating-point AC-3 encoder. yading@10: */ yading@10: yading@10: #define CONFIG_AC3ENC_FLOAT 1 yading@10: #include "internal.h" yading@10: #include "ac3enc.h" yading@10: #include "eac3enc.h" yading@10: #include "kbdwin.h" yading@10: yading@10: yading@10: #if CONFIG_AC3_ENCODER yading@10: #define AC3ENC_TYPE AC3ENC_TYPE_AC3 yading@10: #include "ac3enc_opts_template.c" yading@10: static const AVClass ac3enc_class = { yading@10: .class_name = "AC-3 Encoder", yading@10: .item_name = av_default_item_name, yading@10: .option = ac3_options, yading@10: .version = LIBAVUTIL_VERSION_INT, yading@10: }; yading@10: #endif yading@10: yading@10: #include "ac3enc_template.c" yading@10: yading@10: yading@10: /** yading@10: * Finalize MDCT and free allocated memory. yading@10: * yading@10: * @param s AC-3 encoder private context yading@10: */ yading@10: av_cold void ff_ac3_float_mdct_end(AC3EncodeContext *s) yading@10: { yading@10: ff_mdct_end(&s->mdct); yading@10: av_freep(&s->mdct_window); yading@10: } yading@10: yading@10: yading@10: /** yading@10: * Initialize MDCT tables. yading@10: * yading@10: * @param s AC-3 encoder private context yading@10: * @return 0 on success, negative error code on failure yading@10: */ yading@10: av_cold int ff_ac3_float_mdct_init(AC3EncodeContext *s) yading@10: { yading@10: float *window; yading@10: int i, n, n2; yading@10: yading@10: n = 1 << 9; yading@10: n2 = n >> 1; yading@10: yading@10: window = av_malloc(n * sizeof(*window)); yading@10: if (!window) { yading@10: av_log(s->avctx, AV_LOG_ERROR, "Cannot allocate memory.\n"); yading@10: return AVERROR(ENOMEM); yading@10: } yading@10: ff_kbd_window_init(window, 5.0, n2); yading@10: for (i = 0; i < n2; i++) yading@10: window[n-1-i] = window[i]; yading@10: s->mdct_window = window; yading@10: yading@10: return ff_mdct_init(&s->mdct, 9, 0, -2.0 / n); yading@10: } yading@10: yading@10: yading@10: /* yading@10: * Apply KBD window to input samples prior to MDCT. yading@10: */ yading@10: static void apply_window(void *dsp, float *output, yading@10: const float *input, const float *window, yading@10: unsigned int len) yading@10: { yading@10: AVFloatDSPContext *fdsp = dsp; yading@10: fdsp->vector_fmul(output, input, window, len); yading@10: } yading@10: yading@10: yading@10: /* yading@10: * Normalize the input samples. yading@10: * Not needed for the floating-point encoder. yading@10: */ yading@10: static int normalize_samples(AC3EncodeContext *s) yading@10: { yading@10: return 0; yading@10: } yading@10: yading@10: yading@10: /* yading@10: * Scale MDCT coefficients from float to 24-bit fixed-point. yading@10: */ yading@10: static void scale_coefficients(AC3EncodeContext *s) yading@10: { yading@10: int chan_size = AC3_MAX_COEFS * s->num_blocks; yading@10: int cpl = s->cpl_on; yading@10: s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer + (chan_size * !cpl), yading@10: s->mdct_coef_buffer + (chan_size * !cpl), yading@10: chan_size * (s->channels + cpl)); yading@10: } yading@10: yading@10: static void sum_square_butterfly(AC3EncodeContext *s, float sum[4], yading@10: const float *coef0, const float *coef1, yading@10: int len) yading@10: { yading@10: s->ac3dsp.sum_square_butterfly_float(sum, coef0, coef1, len); yading@10: } yading@10: yading@10: /* yading@10: * Clip MDCT coefficients to allowable range. yading@10: */ yading@10: static void clip_coefficients(DSPContext *dsp, float *coef, unsigned int len) yading@10: { yading@10: dsp->vector_clipf(coef, coef, COEF_MIN, COEF_MAX, len); yading@10: } yading@10: yading@10: yading@10: /* yading@10: * Calculate a single coupling coordinate. yading@10: */ yading@10: static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) yading@10: { yading@10: float coord = 0.125; yading@10: if (energy_cpl > 0) yading@10: coord *= sqrtf(energy_ch / energy_cpl); yading@10: return FFMIN(coord, COEF_MAX); yading@10: } yading@10: yading@10: yading@10: #if CONFIG_AC3_ENCODER yading@10: AVCodec ff_ac3_encoder = { yading@10: .name = "ac3", yading@10: .type = AVMEDIA_TYPE_AUDIO, yading@10: .id = AV_CODEC_ID_AC3, yading@10: .priv_data_size = sizeof(AC3EncodeContext), yading@10: .init = ff_ac3_encode_init, yading@10: .encode2 = ff_ac3_float_encode_frame, yading@10: .close = ff_ac3_encode_close, yading@10: .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, yading@10: AV_SAMPLE_FMT_NONE }, yading@10: .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), yading@10: .priv_class = &ac3enc_class, yading@10: .channel_layouts = ff_ac3_channel_layouts, yading@10: .defaults = ac3_defaults, yading@10: }; yading@10: #endif