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, const 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(avctx, FF_FILTER_TYPE_BUTTERWORTH,
00092 FF_FILTER_MODE_LOWPASS, FILT_ORDER,
00093 cutoff_coeff, 0.0, 0.0);
00094 if (ctx->fcoeffs) {
00095 ctx->fstate = av_mallocz(sizeof(ctx->fstate[0]) * avctx->channels);
00096 for (i = 0; i < avctx->channels; i++)
00097 ctx->fstate[i] = ff_iir_filter_init_state(FILT_ORDER);
00098 }
00099 return ctx;
00100 }
00101
00102 void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx,
00103 const int16_t *audio, int16_t *dest,
00104 int tag, int channels)
00105 {
00106 int ch, i;
00107 if (ctx->fstate) {
00108 for (ch = 0; ch < channels; ch++)
00109 ff_iir_filter(ctx->fcoeffs, ctx->fstate[tag+ch], ctx->avctx->frame_size,
00110 audio + ch, ctx->avctx->channels,
00111 dest + ch, ctx->avctx->channels);
00112 } else {
00113 for (ch = 0; ch < channels; ch++)
00114 for (i = 0; i < ctx->avctx->frame_size; i++)
00115 dest[i*ctx->avctx->channels + ch] = audio[i*ctx->avctx->channels + ch];
00116 }
00117 }
00118
00119 av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx)
00120 {
00121 int i;
00122 ff_iir_filter_free_coeffs(ctx->fcoeffs);
00123 if (ctx->fstate)
00124 for (i = 0; i < ctx->avctx->channels; i++)
00125 ff_iir_filter_free_state(ctx->fstate[i]);
00126 av_freep(&ctx->fstate);
00127 av_free(ctx);
00128 }
00129