00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <string.h>
00023
00024 #include "avcodec.h"
00025 #include "psymodel.h"
00026 #include "iirfilter.h"
00027 #include "libavutil/mem.h"
00028
00029 extern const FFPsyModel ff_aac_psy_model;
00030
00031 av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens,
00032 const uint8_t **bands, const int* num_bands,
00033 int num_groups, const uint8_t *group_map)
00034 {
00035 int i, j, k = 0;
00036
00037 ctx->avctx = avctx;
00038 ctx->ch = av_mallocz(sizeof(ctx->ch[0]) * avctx->channels * 2);
00039 ctx->group = av_mallocz(sizeof(ctx->group[0]) * num_groups);
00040 ctx->bands = av_malloc (sizeof(ctx->bands[0]) * num_lens);
00041 ctx->num_bands = av_malloc (sizeof(ctx->num_bands[0]) * num_lens);
00042 memcpy(ctx->bands, bands, sizeof(ctx->bands[0]) * num_lens);
00043 memcpy(ctx->num_bands, num_bands, sizeof(ctx->num_bands[0]) * num_lens);
00044
00045
00046 for (i = 0; i < num_groups; i++) {
00047
00048
00049
00050
00051 ctx->group[i].num_ch = group_map[i] + 1;
00052 for (j = 0; j < ctx->group[i].num_ch * 2; j++)
00053 ctx->group[i].ch[j] = &ctx->ch[k++];
00054 }
00055
00056 switch (ctx->avctx->codec_id) {
00057 case AV_CODEC_ID_AAC:
00058 ctx->model = &ff_aac_psy_model;
00059 break;
00060 }
00061 if (ctx->model->init)
00062 return ctx->model->init(ctx);
00063 return 0;
00064 }
00065
00066 FFPsyChannelGroup *ff_psy_find_group(FFPsyContext *ctx, int channel)
00067 {
00068 int i = 0, ch = 0;
00069
00070 while (ch <= channel)
00071 ch += ctx->group[i++].num_ch;
00072
00073 return &ctx->group[i-1];
00074 }
00075
00076 av_cold void ff_psy_end(FFPsyContext *ctx)
00077 {
00078 if (ctx->model->end)
00079 ctx->model->end(ctx);
00080 av_freep(&ctx->bands);
00081 av_freep(&ctx->num_bands);
00082 av_freep(&ctx->group);
00083 av_freep(&ctx->ch);
00084 }
00085
00086 typedef struct FFPsyPreprocessContext{
00087 AVCodecContext *avctx;
00088 float stereo_att;
00089 struct FFIIRFilterCoeffs *fcoeffs;
00090 struct FFIIRFilterState **fstate;
00091 }FFPsyPreprocessContext;
00092
00093 #define FILT_ORDER 4
00094
00095 av_cold struct FFPsyPreprocessContext* ff_psy_preprocess_init(AVCodecContext *avctx)
00096 {
00097 FFPsyPreprocessContext *ctx;
00098 int i;
00099 float cutoff_coeff = 0;
00100 ctx = av_mallocz(sizeof(FFPsyPreprocessContext));
00101 ctx->avctx = avctx;
00102
00103 if (avctx->cutoff > 0)
00104 cutoff_coeff = 2.0 * avctx->cutoff / avctx->sample_rate;
00105
00106 if (!cutoff_coeff && avctx->codec_id == AV_CODEC_ID_AAC)
00107 cutoff_coeff = 2.0 * AAC_CUTOFF(avctx) / avctx->sample_rate;
00108
00109 if (cutoff_coeff)
00110 ctx->fcoeffs = ff_iir_filter_init_coeffs(avctx, FF_FILTER_TYPE_BUTTERWORTH,
00111 FF_FILTER_MODE_LOWPASS, FILT_ORDER,
00112 cutoff_coeff, 0.0, 0.0);
00113 if (ctx->fcoeffs) {
00114 ctx->fstate = av_mallocz(sizeof(ctx->fstate[0]) * avctx->channels);
00115 for (i = 0; i < avctx->channels; i++)
00116 ctx->fstate[i] = ff_iir_filter_init_state(FILT_ORDER);
00117 }
00118 return ctx;
00119 }
00120
00121 void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx, float **audio, int channels)
00122 {
00123 int ch;
00124 int frame_size = ctx->avctx->frame_size;
00125
00126 if (ctx->fstate) {
00127 for (ch = 0; ch < channels; ch++)
00128 ff_iir_filter_flt(ctx->fcoeffs, ctx->fstate[ch], frame_size,
00129 &audio[ch][frame_size], 1, &audio[ch][frame_size], 1);
00130 }
00131 }
00132
00133 av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx)
00134 {
00135 int i;
00136 ff_iir_filter_free_coeffs(ctx->fcoeffs);
00137 if (ctx->fstate)
00138 for (i = 0; i < ctx->avctx->channels; i++)
00139 ff_iir_filter_free_state(ctx->fstate[i]);
00140 av_freep(&ctx->fstate);
00141 av_free(ctx);
00142 }