00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "get_bits.h"
00028 #include "gsm.h"
00029 #include "gsmdec_data.h"
00030
00031 static void apcm_dequant_add(GetBitContext *gb, int16_t *dst)
00032 {
00033 int i;
00034 int maxidx = get_bits(gb, 6);
00035 const int16_t *tab = ff_gsm_dequant_tab[maxidx];
00036 for (i = 0; i < 13; i++)
00037 dst[3*i] += tab[get_bits(gb, 3)];
00038 }
00039
00040 static inline int gsm_mult(int a, int b)
00041 {
00042 return (a * b + (1 << 14)) >> 15;
00043 }
00044
00045 static void long_term_synth(int16_t *dst, int lag, int gain_idx)
00046 {
00047 int i;
00048 const int16_t *src = dst - lag;
00049 uint16_t gain = ff_gsm_long_term_gain_tab[gain_idx];
00050 for (i = 0; i < 40; i++)
00051 dst[i] = gsm_mult(gain, src[i]);
00052 }
00053
00054 static inline int decode_log_area(int coded, int factor, int offset)
00055 {
00056 coded <<= 10;
00057 coded -= offset;
00058 return gsm_mult(coded, factor) << 1;
00059 }
00060
00061 static av_noinline int get_rrp(int filtered)
00062 {
00063 int abs = FFABS(filtered);
00064 if (abs < 11059) abs <<= 1;
00065 else if (abs < 20070) abs += 11059;
00066 else abs = (abs >> 2) + 26112;
00067 return filtered < 0 ? -abs : abs;
00068 }
00069
00070 static int filter_value(int in, int rrp[8], int v[9])
00071 {
00072 int i;
00073 for (i = 7; i >= 0; i--) {
00074 in -= gsm_mult(rrp[i], v[i]);
00075 v[i + 1] = v[i] + gsm_mult(rrp[i], in);
00076 }
00077 v[0] = in;
00078 return in;
00079 }
00080
00081 static void short_term_synth(GSMContext *ctx, int16_t *dst, const int16_t *src)
00082 {
00083 int i;
00084 int rrp[8];
00085 int *lar = ctx->lar[ctx->lar_idx];
00086 int *lar_prev = ctx->lar[ctx->lar_idx ^ 1];
00087 for (i = 0; i < 8; i++)
00088 rrp[i] = get_rrp((lar_prev[i] >> 2) + (lar_prev[i] >> 1) + (lar[i] >> 2));
00089 for (i = 0; i < 13; i++)
00090 dst[i] = filter_value(src[i], rrp, ctx->v);
00091
00092 for (i = 0; i < 8; i++)
00093 rrp[i] = get_rrp((lar_prev[i] >> 1) + (lar [i] >> 1));
00094 for (i = 13; i < 27; i++)
00095 dst[i] = filter_value(src[i], rrp, ctx->v);
00096
00097 for (i = 0; i < 8; i++)
00098 rrp[i] = get_rrp((lar_prev[i] >> 2) + (lar [i] >> 1) + (lar[i] >> 2));
00099 for (i = 27; i < 40; i++)
00100 dst[i] = filter_value(src[i], rrp, ctx->v);
00101
00102 for (i = 0; i < 8; i++)
00103 rrp[i] = get_rrp(lar[i]);
00104 for (i = 40; i < 160; i++)
00105 dst[i] = filter_value(src[i], rrp, ctx->v);
00106
00107 ctx->lar_idx ^= 1;
00108 }
00109
00110 static int postprocess(int16_t *data, int msr)
00111 {
00112 int i;
00113 for (i = 0; i < 160; i++) {
00114 msr = av_clip_int16(data[i] + gsm_mult(msr, 28180));
00115 data[i] = av_clip_int16(msr << 1) & ~7;
00116 }
00117 return msr;
00118 }
00119
00120 static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples,
00121 GetBitContext *gb)
00122 {
00123 GSMContext *ctx = avctx->priv_data;
00124 int i;
00125 int16_t *ref_dst = ctx->ref_buf + 120;
00126 int *lar = ctx->lar[ctx->lar_idx];
00127 lar[0] = decode_log_area(get_bits(gb, 6), 13107, 1 << 15);
00128 lar[1] = decode_log_area(get_bits(gb, 6), 13107, 1 << 15);
00129 lar[2] = decode_log_area(get_bits(gb, 5), 13107, (1 << 14) + 2048*2);
00130 lar[3] = decode_log_area(get_bits(gb, 5), 13107, (1 << 14) - 2560*2);
00131 lar[4] = decode_log_area(get_bits(gb, 4), 19223, (1 << 13) + 94*2);
00132 lar[5] = decode_log_area(get_bits(gb, 4), 17476, (1 << 13) - 1792*2);
00133 lar[6] = decode_log_area(get_bits(gb, 3), 31454, (1 << 12) - 341*2);
00134 lar[7] = decode_log_area(get_bits(gb, 3), 29708, (1 << 12) - 1144*2);
00135
00136 for (i = 0; i < 4; i++) {
00137 int lag = get_bits(gb, 7);
00138 int gain_idx = get_bits(gb, 2);
00139 int offset = get_bits(gb, 2);
00140 lag = av_clip(lag, 40, 120);
00141 long_term_synth(ref_dst, lag, gain_idx);
00142 apcm_dequant_add(gb, ref_dst + offset);
00143 ref_dst += 40;
00144 }
00145 memcpy(ctx->ref_buf, ctx->ref_buf + 160, 120 * sizeof(*ctx->ref_buf));
00146 short_term_synth(ctx, samples, ctx->ref_buf + 120);
00147
00148
00149 ctx->msr = postprocess(samples, ctx->msr);
00150 return 0;
00151 }