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, int num_lens,
00029 const uint8_t **bands, const int* num_bands,
00030 int num_groups, const uint8_t *group_map)
00031 {
00032 int i, j, k = 0;
00033
00034 ctx->avctx = avctx;
00035 ctx->ch = av_mallocz(sizeof(ctx->ch[0]) * avctx->channels * 2);
00036 ctx->group = av_mallocz(sizeof(ctx->group[0]) * num_groups);
00037 ctx->bands = av_malloc (sizeof(ctx->bands[0]) * num_lens);
00038 ctx->num_bands = av_malloc (sizeof(ctx->num_bands[0]) * num_lens);
00039 memcpy(ctx->bands, bands, sizeof(ctx->bands[0]) * num_lens);
00040 memcpy(ctx->num_bands, num_bands, sizeof(ctx->num_bands[0]) * num_lens);
00041
00042
00043 for (i = 0; i < num_groups; i++) {
00044
00045
00046
00047
00048 ctx->group[i].num_ch = group_map[i] + 1;
00049 for (j = 0; j < ctx->group[i].num_ch * 2; j++)
00050 ctx->group[i].ch[j] = &ctx->ch[k++];
00051 }
00052
00053 switch (ctx->avctx->codec_id) {
00054 case CODEC_ID_AAC:
00055 ctx->model = &ff_aac_psy_model;
00056 break;
00057 }
00058 if (ctx->model->init)
00059 return ctx->model->init(ctx);
00060 return 0;
00061 }
00062
00063 FFPsyChannelGroup *ff_psy_find_group(FFPsyContext *ctx, int channel)
00064 {
00065 int i = 0, ch = 0;
00066
00067 while (ch <= channel)
00068 ch += ctx->group[i++].num_ch;
00069
00070 return &ctx->group[i-1];
00071 }
00072
00073 av_cold void ff_psy_end(FFPsyContext *ctx)
00074 {
00075 if (ctx->model->end)
00076 ctx->model->end(ctx);
00077 av_freep(&ctx->bands);
00078 av_freep(&ctx->num_bands);
00079 av_freep(&ctx->group);
00080 av_freep(&ctx->ch);
00081 }
00082
00083 typedef struct FFPsyPreprocessContext{
00084 AVCodecContext *avctx;
00085 float stereo_att;
00086 struct FFIIRFilterCoeffs *fcoeffs;
00087 struct FFIIRFilterState **fstate;
00088 }FFPsyPreprocessContext;
00089
00090 #define FILT_ORDER 4
00091
00092 av_cold struct FFPsyPreprocessContext* ff_psy_preprocess_init(AVCodecContext *avctx)
00093 {
00094 FFPsyPreprocessContext *ctx;
00095 int i;
00096 float cutoff_coeff = 0;
00097 ctx = av_mallocz(sizeof(FFPsyPreprocessContext));
00098 ctx->avctx = avctx;
00099
00100 if (avctx->cutoff > 0)
00101 cutoff_coeff = 2.0 * avctx->cutoff / avctx->sample_rate;
00102
00103 if (cutoff_coeff)
00104 ctx->fcoeffs = ff_iir_filter_init_coeffs(avctx, FF_FILTER_TYPE_BUTTERWORTH,
00105 FF_FILTER_MODE_LOWPASS, FILT_ORDER,
00106 cutoff_coeff, 0.0, 0.0);
00107 if (ctx->fcoeffs) {
00108 ctx->fstate = av_mallocz(sizeof(ctx->fstate[0]) * avctx->channels);
00109 for (i = 0; i < avctx->channels; i++)
00110 ctx->fstate[i] = ff_iir_filter_init_state(FILT_ORDER);
00111 }
00112 return ctx;
00113 }
00114
00115 void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx, float **audio, int channels)
00116 {
00117 int ch;
00118 int frame_size = ctx->avctx->frame_size;
00119
00120 if (ctx->fstate) {
00121 for (ch = 0; ch < channels; ch++)
00122 ff_iir_filter_flt(ctx->fcoeffs, ctx->fstate[ch], frame_size,
00123 &audio[ch][frame_size], 1, &audio[ch][frame_size], 1);
00124 }
00125 }
00126
00127 av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx)
00128 {
00129 int i;
00130 ff_iir_filter_free_coeffs(ctx->fcoeffs);
00131 if (ctx->fstate)
00132 for (i = 0; i < ctx->avctx->channels; i++)
00133 ff_iir_filter_free_state(ctx->fstate[i]);
00134 av_freep(&ctx->fstate);
00135 av_free(ctx);
00136 }