00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avcodec.h"
00023 #include "psymodel.h"
00024 #include "iirfilter.h"
00025
00026 extern const FFPsyModel ff_aac_psy_model;
00027
00028 av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx,
00029 int num_lens,
00030 const uint8_t **bands, const int* num_bands)
00031 {
00032 ctx->avctx = avctx;
00033 ctx->psy_bands = av_mallocz(sizeof(FFPsyBand) * PSY_MAX_BANDS * avctx->channels);
00034 ctx->bands = av_malloc (sizeof(ctx->bands[0]) * num_lens);
00035 ctx->num_bands = av_malloc (sizeof(ctx->num_bands[0]) * num_lens);
00036 memcpy(ctx->bands, bands, sizeof(ctx->bands[0]) * num_lens);
00037 memcpy(ctx->num_bands, num_bands, sizeof(ctx->num_bands[0]) * num_lens);
00038 switch (ctx->avctx->codec_id) {
00039 case CODEC_ID_AAC:
00040 ctx->model = &ff_aac_psy_model;
00041 break;
00042 }
00043 if (ctx->model->init)
00044 return ctx->model->init(ctx);
00045 return 0;
00046 }
00047
00048 av_cold void ff_psy_end(FFPsyContext *ctx)
00049 {
00050 if (ctx->model->end)
00051 ctx->model->end(ctx);
00052 av_freep(&ctx->bands);
00053 av_freep(&ctx->num_bands);
00054 av_freep(&ctx->psy_bands);
00055 }
00056
00057 typedef struct FFPsyPreprocessContext{
00058 AVCodecContext *avctx;
00059 float stereo_att;
00060 struct FFIIRFilterCoeffs *fcoeffs;
00061 struct FFIIRFilterState **fstate;
00062 }FFPsyPreprocessContext;
00063
00064 #define FILT_ORDER 4
00065
00066 av_cold struct FFPsyPreprocessContext* ff_psy_preprocess_init(AVCodecContext *avctx)
00067 {
00068 FFPsyPreprocessContext *ctx;
00069 int i;
00070 float cutoff_coeff = 0;
00071 ctx = av_mallocz(sizeof(FFPsyPreprocessContext));
00072 ctx->avctx = avctx;
00073
00074 if (avctx->cutoff > 0)
00075 cutoff_coeff = 2.0 * avctx->cutoff / avctx->sample_rate;
00076
00077 if (cutoff_coeff)
00078 ctx->fcoeffs = ff_iir_filter_init_coeffs(avctx, FF_FILTER_TYPE_BUTTERWORTH,
00079 FF_FILTER_MODE_LOWPASS, FILT_ORDER,
00080 cutoff_coeff, 0.0, 0.0);
00081 if (ctx->fcoeffs) {
00082 ctx->fstate = av_mallocz(sizeof(ctx->fstate[0]) * avctx->channels);
00083 for (i = 0; i < avctx->channels; i++)
00084 ctx->fstate[i] = ff_iir_filter_init_state(FILT_ORDER);
00085 }
00086 return ctx;
00087 }
00088
00089 void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx,
00090 const int16_t *audio, int16_t *dest,
00091 int tag, int channels)
00092 {
00093 int ch, i;
00094 if (ctx->fstate) {
00095 for (ch = 0; ch < channels; ch++)
00096 ff_iir_filter(ctx->fcoeffs, ctx->fstate[tag+ch], ctx->avctx->frame_size,
00097 audio + ch, ctx->avctx->channels,
00098 dest + ch, ctx->avctx->channels);
00099 } else {
00100 for (ch = 0; ch < channels; ch++)
00101 for (i = 0; i < ctx->avctx->frame_size; i++)
00102 dest[i*ctx->avctx->channels + ch] = audio[i*ctx->avctx->channels + ch];
00103 }
00104 }
00105
00106 av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx)
00107 {
00108 int i;
00109 ff_iir_filter_free_coeffs(ctx->fcoeffs);
00110 if (ctx->fstate)
00111 for (i = 0; i < ctx->avctx->channels; i++)
00112 ff_iir_filter_free_state(ctx->fstate[i]);
00113 av_freep(&ctx->fstate);
00114 av_free(ctx);
00115 }
00116