00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00135
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
00159
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
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
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 }