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