Mercurial > libavcodec.hg
comparison ra288.c @ 7853:21ab545aed8b libavcodec
Simplify: use a single history buffer for gain and a single one for
speech instead of having two for each in the context.
author | vitor |
---|---|
date | Sat, 13 Sep 2008 16:49:05 +0000 |
parents | 2bfde5b45e01 |
children | e5e3c56c358c |
comparison
equal
deleted
inserted
replaced
7852:0d60b8b7f30b | 7853:21ab545aed8b |
---|---|
27 | 27 |
28 typedef struct { | 28 typedef struct { |
29 float sp_lpc[36]; ///< LPC coefficients for speech data (spec: A) | 29 float sp_lpc[36]; ///< LPC coefficients for speech data (spec: A) |
30 float gain_lpc[10]; ///< LPC coefficients for gain (spec: GB) | 30 float gain_lpc[10]; ///< LPC coefficients for gain (spec: GB) |
31 | 31 |
32 float sp_hist[111]; ///< speech data history (spec: SB) | 32 /** speech data history (spec: SB). |
33 * Its first 70 coefficients are updated only at backward filtering. | |
34 */ | |
35 float sp_hist[111]; | |
33 | 36 |
34 /// speech part of the gain autocorrelation (spec: REXP) | 37 /// speech part of the gain autocorrelation (spec: REXP) |
35 float sp_rec[37]; | 38 float sp_rec[37]; |
36 | 39 |
37 float gain_hist[38]; ///< log-gain history (spec: SBLG) | 40 /** log-gain history (spec: SBLG). |
41 * Its first 28 coefficients are updated only at backward filtering. | |
42 */ | |
43 float gain_hist[38]; | |
38 | 44 |
39 /// recursive part of the gain autocorrelation (spec: REXPLG) | 45 /// recursive part of the gain autocorrelation (spec: REXPLG) |
40 float gain_rec[11]; | 46 float gain_rec[11]; |
41 | |
42 float sp_block[41]; ///< four blocks of speech data (spec: STTMP) | |
43 float gain_block[10]; ///< four blocks of gain data (spec: GSTATE) | |
44 } RA288Context; | 47 } RA288Context; |
45 | 48 |
46 static av_cold int ra288_decode_init(AVCodecContext *avctx) | 49 static av_cold int ra288_decode_init(AVCodecContext *avctx) |
47 { | 50 { |
48 avctx->sample_fmt = SAMPLE_FMT_S16; | 51 avctx->sample_fmt = SAMPLE_FMT_S16; |
69 static void decode(RA288Context *ractx, float gain, int cb_coef) | 72 static void decode(RA288Context *ractx, float gain, int cb_coef) |
70 { | 73 { |
71 int i, j; | 74 int i, j; |
72 double sumsum; | 75 double sumsum; |
73 float sum, buffer[5]; | 76 float sum, buffer[5]; |
74 float *block = ractx->sp_block + 36; // current block | 77 float *block = ractx->sp_hist + 70 + 36; // current block |
75 | 78 float *gain_block = ractx->gain_hist + 28; |
76 memmove(ractx->sp_block, ractx->sp_block + 5, 36*sizeof(*ractx->sp_block)); | 79 |
80 memmove(ractx->sp_hist + 70, ractx->sp_hist + 75, 36*sizeof(*block)); | |
77 | 81 |
78 for (i=0; i < 5; i++) { | 82 for (i=0; i < 5; i++) { |
79 block[i] = 0.; | 83 block[i] = 0.; |
80 for (j=0; j < 36; j++) | 84 for (j=0; j < 36; j++) |
81 block[i] -= block[i-1-j]*ractx->sp_lpc[j]; | 85 block[i] -= block[i-1-j]*ractx->sp_lpc[j]; |
82 } | 86 } |
83 | 87 |
84 /* block 46 of G.728 spec */ | 88 /* block 46 of G.728 spec */ |
85 sum = 32.; | 89 sum = 32.; |
86 for (i=0; i < 10; i++) | 90 for (i=0; i < 10; i++) |
87 sum -= ractx->gain_block[9-i] * ractx->gain_lpc[i]; | 91 sum -= gain_block[9-i] * ractx->gain_lpc[i]; |
88 | 92 |
89 /* block 47 of G.728 spec */ | 93 /* block 47 of G.728 spec */ |
90 sum = av_clipf(sum, 0, 60); | 94 sum = av_clipf(sum, 0, 60); |
91 | 95 |
92 /* block 48 of G.728 spec */ | 96 /* block 48 of G.728 spec */ |
98 sum = scalar_product_float(buffer, buffer, 5) / 5; | 102 sum = scalar_product_float(buffer, buffer, 5) / 5; |
99 | 103 |
100 sum = FFMAX(sum, 1); | 104 sum = FFMAX(sum, 1); |
101 | 105 |
102 /* shift and store */ | 106 /* shift and store */ |
103 memmove(ractx->gain_block, ractx->gain_block + 1, | 107 memmove(gain_block, gain_block + 1, 9 * sizeof(*gain_block)); |
104 9 * sizeof(*ractx->gain_block)); | 108 |
105 | 109 gain_block[9] = 10 * log10(sum) - 32; |
106 ractx->gain_block[9] = 10 * log10(sum) - 32; | |
107 | 110 |
108 for (i=1; i < 5; i++) | 111 for (i=1; i < 5; i++) |
109 for (j=i-1; j >= 0; j--) | 112 for (j=i-1; j >= 0; j--) |
110 buffer[i] -= ractx->sp_lpc[i-j-1] * buffer[j]; | 113 buffer[i] -= ractx->sp_lpc[i-j-1] * buffer[j]; |
111 | 114 |
126 * | 129 * |
127 * @param order filter order | 130 * @param order filter order |
128 * @param n input length | 131 * @param n input length |
129 * @param non_rec number of non-recursive samples | 132 * @param non_rec number of non-recursive samples |
130 * @param out filter output | 133 * @param out filter output |
131 * @param in pointer to the input of the filter | 134 * @param hist pointer to the input history of the filter |
132 * @param hist Pointer to the input history of the filter, it is updated by | |
133 * this function. | |
134 * @param out pointer to the non-recursive part of the output | 135 * @param out pointer to the non-recursive part of the output |
135 * @param out2 pointer to the recursive part of the output | 136 * @param out2 pointer to the recursive part of the output |
136 * @param window pointer to the windowing function table | 137 * @param window pointer to the windowing function table |
137 */ | 138 */ |
138 static void do_hybrid_window(int order, int n, int non_rec, const float *in, | 139 static void do_hybrid_window(int order, int n, int non_rec, |
139 float *out, float *hist, float *out2, | 140 float *out, float *hist, float *out2, |
140 const float *window) | 141 const float *window) |
141 { | 142 { |
142 int i; | 143 int i; |
143 float buffer1[order + 1]; | 144 float buffer1[order + 1]; |
144 float buffer2[order + 1]; | 145 float buffer2[order + 1]; |
145 float work[order + n + non_rec]; | 146 float work[order + n + non_rec]; |
146 | 147 |
147 /* update history */ | |
148 memmove(hist , hist + n, (order + non_rec)*sizeof(*hist)); | |
149 memcpy (hist + order + non_rec, in , n *sizeof(*hist)); | |
150 | |
151 apply_window(work, window, hist, order + n + non_rec); | 148 apply_window(work, window, hist, order + n + non_rec); |
152 | 149 |
153 convolve(buffer1, work + order , n , order); | 150 convolve(buffer1, work + order , n , order); |
154 convolve(buffer2, work + order + n, non_rec, order); | 151 convolve(buffer2, work + order + n, non_rec, order); |
155 | 152 |
168 static void backward_filter(RA288Context *ractx) | 165 static void backward_filter(RA288Context *ractx) |
169 { | 166 { |
170 float temp1[37]; // RTMP in the spec | 167 float temp1[37]; // RTMP in the spec |
171 float temp2[11]; // GPTPMP in the spec | 168 float temp2[11]; // GPTPMP in the spec |
172 | 169 |
173 do_hybrid_window(36, 40, 35, ractx->sp_block+1, temp1, ractx->sp_hist, | 170 do_hybrid_window(36, 40, 35, temp1, ractx->sp_hist, |
174 ractx->sp_rec, syn_window); | 171 ractx->sp_rec, syn_window); |
175 | 172 |
176 if (!compute_lpc_coefs(temp1, 36, ractx->sp_lpc, 0, 1, 1)) | 173 if (!compute_lpc_coefs(temp1, 36, ractx->sp_lpc, 0, 1, 1)) |
177 apply_window(ractx->sp_lpc, ractx->sp_lpc, syn_bw_tab, 36); | 174 apply_window(ractx->sp_lpc, ractx->sp_lpc, syn_bw_tab, 36); |
178 | 175 |
179 do_hybrid_window(10, 8, 20, ractx->gain_block+2, temp2, ractx->gain_hist, | 176 do_hybrid_window(10, 8, 20, temp2, ractx->gain_hist, |
180 ractx->gain_rec, gain_window); | 177 ractx->gain_rec, gain_window); |
181 | 178 |
182 if (!compute_lpc_coefs(temp2, 10, ractx->gain_lpc, 0, 1, 1)) | 179 if (!compute_lpc_coefs(temp2, 10, ractx->gain_lpc, 0, 1, 1)) |
183 apply_window(ractx->gain_lpc, ractx->gain_lpc, gain_bw_tab, 10); | 180 apply_window(ractx->gain_lpc, ractx->gain_lpc, gain_bw_tab, 10); |
181 | |
182 memmove(ractx->gain_hist, ractx->gain_hist + 8, | |
183 28*sizeof(*ractx->gain_hist)); | |
184 | |
185 memmove(ractx->sp_hist , ractx->sp_hist + 40, | |
186 70*sizeof(*ractx->sp_hist )); | |
184 } | 187 } |
185 | 188 |
186 static int ra288_decode_frame(AVCodecContext * avctx, void *data, | 189 static int ra288_decode_frame(AVCodecContext * avctx, void *data, |
187 int *data_size, const uint8_t * buf, | 190 int *data_size, const uint8_t * buf, |
188 int buf_size) | 191 int buf_size) |
209 int cb_coef = get_bits(&gb, 6 + (i&1)); | 212 int cb_coef = get_bits(&gb, 6 + (i&1)); |
210 | 213 |
211 decode(ractx, gain, cb_coef); | 214 decode(ractx, gain, cb_coef); |
212 | 215 |
213 for (j=0; j < 5; j++) | 216 for (j=0; j < 5; j++) |
214 *(out++) = 8 * ractx->sp_block[36 + j]; | 217 *(out++) = 8 * ractx->sp_hist[70 + 36 + j]; |
215 | 218 |
216 if ((i & 7) == 3) | 219 if ((i & 7) == 3) |
217 backward_filter(ractx); | 220 backward_filter(ractx); |
218 } | 221 } |
219 | 222 |