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 FFPsyWindowInfo ff_psy_suggest_window(FFPsyContext *ctx,
00049 const int16_t *audio, const int16_t *la,
00050 int channel, int prev_type)
00051 {
00052 return ctx->model->window(ctx, audio, la, channel, prev_type);
00053 }
00054
00055 void ff_psy_set_band_info(FFPsyContext *ctx, int channel,
00056 const float *coeffs, FFPsyWindowInfo *wi)
00057 {
00058 ctx->model->analyze(ctx, channel, coeffs, wi);
00059 }
00060
00061 av_cold void ff_psy_end(FFPsyContext *ctx)
00062 {
00063 if (ctx->model->end)
00064 ctx->model->end(ctx);
00065 av_freep(&ctx->bands);
00066 av_freep(&ctx->num_bands);
00067 av_freep(&ctx->psy_bands);
00068 }
00069
00070 typedef struct FFPsyPreprocessContext{
00071 AVCodecContext *avctx;
00072 float stereo_att;
00073 struct FFIIRFilterCoeffs *fcoeffs;
00074 struct FFIIRFilterState **fstate;
00075 }FFPsyPreprocessContext;
00076
00077 #define FILT_ORDER 4
00078
00079 av_cold struct FFPsyPreprocessContext* ff_psy_preprocess_init(AVCodecContext *avctx)
00080 {
00081 FFPsyPreprocessContext *ctx;
00082 int i;
00083 float cutoff_coeff = 0;
00084 ctx = av_mallocz(sizeof(FFPsyPreprocessContext));
00085 ctx->avctx = avctx;
00086
00087 if (avctx->cutoff > 0)
00088 cutoff_coeff = 2.0 * avctx->cutoff / avctx->sample_rate;
00089
00090 if (cutoff_coeff)
00091 ctx->fcoeffs = ff_iir_filter_init_coeffs(FF_FILTER_TYPE_BUTTERWORTH, FF_FILTER_MODE_LOWPASS,
00092 FILT_ORDER, cutoff_coeff, 0.0, 0.0);
00093 if (ctx->fcoeffs) {
00094 ctx->fstate = av_mallocz(sizeof(ctx->fstate[0]) * avctx->channels);
00095 for (i = 0; i < avctx->channels; i++)
00096 ctx->fstate[i] = ff_iir_filter_init_state(FILT_ORDER);
00097 }
00098 return ctx;
00099 }
00100
00101 void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx,
00102 const int16_t *audio, int16_t *dest,
00103 int tag, int channels)
00104 {
00105 int ch, i;
00106 if (ctx->fstate) {
00107 for (ch = 0; ch < channels; ch++)
00108 ff_iir_filter(ctx->fcoeffs, ctx->fstate[tag+ch], ctx->avctx->frame_size,
00109 audio + ch, ctx->avctx->channels,
00110 dest + ch, ctx->avctx->channels);
00111 } else {
00112 for (ch = 0; ch < channels; ch++)
00113 for (i = 0; i < ctx->avctx->frame_size; i++)
00114 dest[i*ctx->avctx->channels + ch] = audio[i*ctx->avctx->channels + ch];
00115 }
00116 }
00117
00118 av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx)
00119 {
00120 int i;
00121 ff_iir_filter_free_coeffs(ctx->fcoeffs);
00122 if (ctx->fstate)
00123 for (i = 0; i < ctx->avctx->channels; i++)
00124 ff_iir_filter_free_state(ctx->fstate[i]);
00125 av_freep(&ctx->fstate);
00126 }
00127