Libav 0.7.1
libavcodec/mpegaudiodsp_template.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001, 2002 Fabrice Bellard
00003  *
00004  * This file is part of Libav.
00005  *
00006  * Libav is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * Libav is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with Libav; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00021 #include <stdint.h>
00022 
00023 #include "libavutil/mem.h"
00024 #include "dct32.h"
00025 #include "mathops.h"
00026 #include "mpegaudiodsp.h"
00027 #include "mpegaudio.h"
00028 #include "mpegaudiodata.h"
00029 
00030 #if CONFIG_FLOAT
00031 #define RENAME(n) n##_float
00032 
00033 static inline float round_sample(float *sum)
00034 {
00035     float sum1=*sum;
00036     *sum = 0;
00037     return sum1;
00038 }
00039 
00040 #define MACS(rt, ra, rb) rt+=(ra)*(rb)
00041 #define MULS(ra, rb) ((ra)*(rb))
00042 #define MLSS(rt, ra, rb) rt-=(ra)*(rb)
00043 
00044 #else
00045 
00046 #define RENAME(n) n##_fixed
00047 #define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 15)
00048 
00049 static inline int round_sample(int64_t *sum)
00050 {
00051     int sum1;
00052     sum1 = (int)((*sum) >> OUT_SHIFT);
00053     *sum &= (1<<OUT_SHIFT)-1;
00054     return av_clip_int16(sum1);
00055 }
00056 
00057 #   define MULS(ra, rb) MUL64(ra, rb)
00058 #   define MACS(rt, ra, rb) MAC64(rt, ra, rb)
00059 #   define MLSS(rt, ra, rb) MLS64(rt, ra, rb)
00060 #endif
00061 
00062 DECLARE_ALIGNED(16, MPA_INT, RENAME(ff_mpa_synth_window))[512+256];
00063 
00064 #define SUM8(op, sum, w, p)               \
00065 {                                         \
00066     op(sum, (w)[0 * 64], (p)[0 * 64]);    \
00067     op(sum, (w)[1 * 64], (p)[1 * 64]);    \
00068     op(sum, (w)[2 * 64], (p)[2 * 64]);    \
00069     op(sum, (w)[3 * 64], (p)[3 * 64]);    \
00070     op(sum, (w)[4 * 64], (p)[4 * 64]);    \
00071     op(sum, (w)[5 * 64], (p)[5 * 64]);    \
00072     op(sum, (w)[6 * 64], (p)[6 * 64]);    \
00073     op(sum, (w)[7 * 64], (p)[7 * 64]);    \
00074 }
00075 
00076 #define SUM8P2(sum1, op1, sum2, op2, w1, w2, p) \
00077 {                                               \
00078     INTFLOAT tmp;\
00079     tmp = p[0 * 64];\
00080     op1(sum1, (w1)[0 * 64], tmp);\
00081     op2(sum2, (w2)[0 * 64], tmp);\
00082     tmp = p[1 * 64];\
00083     op1(sum1, (w1)[1 * 64], tmp);\
00084     op2(sum2, (w2)[1 * 64], tmp);\
00085     tmp = p[2 * 64];\
00086     op1(sum1, (w1)[2 * 64], tmp);\
00087     op2(sum2, (w2)[2 * 64], tmp);\
00088     tmp = p[3 * 64];\
00089     op1(sum1, (w1)[3 * 64], tmp);\
00090     op2(sum2, (w2)[3 * 64], tmp);\
00091     tmp = p[4 * 64];\
00092     op1(sum1, (w1)[4 * 64], tmp);\
00093     op2(sum2, (w2)[4 * 64], tmp);\
00094     tmp = p[5 * 64];\
00095     op1(sum1, (w1)[5 * 64], tmp);\
00096     op2(sum2, (w2)[5 * 64], tmp);\
00097     tmp = p[6 * 64];\
00098     op1(sum1, (w1)[6 * 64], tmp);\
00099     op2(sum2, (w2)[6 * 64], tmp);\
00100     tmp = p[7 * 64];\
00101     op1(sum1, (w1)[7 * 64], tmp);\
00102     op2(sum2, (w2)[7 * 64], tmp);\
00103 }
00104 
00105 void RENAME(ff_mpadsp_apply_window)(MPA_INT *synth_buf, MPA_INT *window,
00106                                   int *dither_state, OUT_INT *samples,
00107                                   int incr)
00108 {
00109     register const MPA_INT *w, *w2, *p;
00110     int j;
00111     OUT_INT *samples2;
00112 #if CONFIG_FLOAT
00113     float sum, sum2;
00114 #else
00115     int64_t sum, sum2;
00116 #endif
00117 
00118     /* copy to avoid wrap */
00119     memcpy(synth_buf + 512, synth_buf, 32 * sizeof(*synth_buf));
00120 
00121     samples2 = samples + 31 * incr;
00122     w = window;
00123     w2 = window + 31;
00124 
00125     sum = *dither_state;
00126     p = synth_buf + 16;
00127     SUM8(MACS, sum, w, p);
00128     p = synth_buf + 48;
00129     SUM8(MLSS, sum, w + 32, p);
00130     *samples = round_sample(&sum);
00131     samples += incr;
00132     w++;
00133 
00134     /* we calculate two samples at the same time to avoid one memory
00135        access per two sample */
00136     for(j=1;j<16;j++) {
00137         sum2 = 0;
00138         p = synth_buf + 16 + j;
00139         SUM8P2(sum, MACS, sum2, MLSS, w, w2, p);
00140         p = synth_buf + 48 - j;
00141         SUM8P2(sum, MLSS, sum2, MLSS, w + 32, w2 + 32, p);
00142 
00143         *samples = round_sample(&sum);
00144         samples += incr;
00145         sum += sum2;
00146         *samples2 = round_sample(&sum);
00147         samples2 -= incr;
00148         w++;
00149         w2--;
00150     }
00151 
00152     p = synth_buf + 32;
00153     SUM8(MLSS, sum, w + 32, p);
00154     *samples = round_sample(&sum);
00155     *dither_state= sum;
00156 }
00157 
00158 /* 32 sub band synthesis filter. Input: 32 sub band samples, Output:
00159    32 samples. */
00160 void RENAME(ff_mpa_synth_filter)(MPADSPContext *s, MPA_INT *synth_buf_ptr,
00161                                  int *synth_buf_offset,
00162                                  MPA_INT *window, int *dither_state,
00163                                  OUT_INT *samples, int incr,
00164                                  MPA_INT *sb_samples)
00165 {
00166     MPA_INT *synth_buf;
00167     int offset;
00168 
00169     offset = *synth_buf_offset;
00170     synth_buf = synth_buf_ptr + offset;
00171 
00172     s->RENAME(dct32)(synth_buf, sb_samples);
00173     s->RENAME(apply_window)(synth_buf, window, dither_state, samples, incr);
00174 
00175     offset = (offset - 32) & 511;
00176     *synth_buf_offset = offset;
00177 }
00178 
00179 void av_cold RENAME(ff_mpa_synth_init)(MPA_INT *window)
00180 {
00181     int i, j;
00182 
00183     /* max = 18760, max sum over all 16 coefs : 44736 */
00184     for(i=0;i<257;i++) {
00185         INTFLOAT v;
00186         v = ff_mpa_enwindow[i];
00187 #if CONFIG_FLOAT
00188         v *= 1.0 / (1LL<<(16 + FRAC_BITS));
00189 #endif
00190         window[i] = v;
00191         if ((i & 63) != 0)
00192             v = -v;
00193         if (i != 0)
00194             window[512 - i] = v;
00195     }
00196 
00197     // Needed for avoiding shuffles in ASM implementations
00198     for(i=0; i < 8; i++)
00199         for(j=0; j < 16; j++)
00200             window[512+16*i+j] = window[64*i+32-j];
00201 
00202     for(i=0; i < 8; i++)
00203         for(j=0; j < 16; j++)
00204             window[512+128+16*i+j] = window[64*i+48-j];
00205 }