Originally committed as revision 20450 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -22,6 +22,7 @@ |
| 22 | 22 |
|
| 23 | 23 |
#include <inttypes.h> |
| 24 | 24 |
#include "avcodec.h" |
| 25 |
+#include "celp_math.h" |
|
| 25 | 26 |
#include "acelp_vectors.h" |
| 26 | 27 |
#include "celp_math.h" |
| 27 | 28 |
|
| ... | ... |
@@ -177,3 +178,14 @@ void ff_adaptative_gain_control(float *buf_out, float speech_energ, |
| 177 | 177 |
|
| 178 | 178 |
*gain_mem = mem; |
| 179 | 179 |
} |
| 180 |
+ |
|
| 181 |
+void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in, |
|
| 182 |
+ float sum_of_squares, const int n) |
|
| 183 |
+{
|
|
| 184 |
+ int i; |
|
| 185 |
+ float scalefactor = ff_dot_productf(in, in, n); |
|
| 186 |
+ if (scalefactor) |
|
| 187 |
+ scalefactor = sqrt(sum_of_squares / scalefactor); |
|
| 188 |
+ for (i = 0; i < n; i++) |
|
| 189 |
+ out[i] = in[i] * scalefactor; |
|
| 190 |
+} |
| ... | ... |
@@ -176,4 +176,22 @@ void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b, |
| 176 | 176 |
void ff_adaptative_gain_control(float *buf_out, float speech_energ, |
| 177 | 177 |
int size, float alpha, float *gain_mem); |
| 178 | 178 |
|
| 179 |
+/** |
|
| 180 |
+ * Set the sum of squares of a signal by scaling |
|
| 181 |
+ * |
|
| 182 |
+ * @param out output samples |
|
| 183 |
+ * @param in input samples |
|
| 184 |
+ * @param sum_of_squares new sum of squares |
|
| 185 |
+ * @param n number of samples |
|
| 186 |
+ * |
|
| 187 |
+ * @note If the input is zero (or its energy underflows), the output is zero. |
|
| 188 |
+ * This is the behavior of AGC in the AMR reference decoder. The QCELP |
|
| 189 |
+ * reference decoder seems to have undefined behavior. |
|
| 190 |
+ * |
|
| 191 |
+ * TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6 |
|
| 192 |
+ * 3GPP TS 26.090 6.1 (6) |
|
| 193 |
+ */ |
|
| 194 |
+void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in, |
|
| 195 |
+ float sum_of_squares, const int n); |
|
| 196 |
+ |
|
| 179 | 197 |
#endif /* AVCODEC_ACELP_VECTORS_H */ |
| ... | ... |
@@ -406,31 +406,6 @@ static void compute_svector(QCELPContext *q, const float *gain, |
| 406 | 406 |
} |
| 407 | 407 |
|
| 408 | 408 |
/** |
| 409 |
- * Compute the gain control |
|
| 410 |
- * |
|
| 411 |
- * @param v_in gain-controlled vector |
|
| 412 |
- * @param v_ref vector to control gain of |
|
| 413 |
- * |
|
| 414 |
- * @return gain control |
|
| 415 |
- * |
|
| 416 |
- * FIXME: If v_ref is a zero vector, it energy is zero |
|
| 417 |
- * and the behavior of the gain control is |
|
| 418 |
- * undefined in the specs. |
|
| 419 |
- * |
|
| 420 |
- * TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6 |
|
| 421 |
- */ |
|
| 422 |
-static float compute_gain_ctrl(const float *v_ref, const float *v_in, const int len) |
|
| 423 |
-{
|
|
| 424 |
- float scalefactor = ff_dot_productf(v_in, v_in, len); |
|
| 425 |
- |
|
| 426 |
- if(scalefactor) |
|
| 427 |
- scalefactor = sqrt(ff_dot_productf(v_ref, v_ref, len) / scalefactor); |
|
| 428 |
- else |
|
| 429 |
- av_log_missing_feature(NULL, "Zero energy for gain control", 1); |
|
| 430 |
- return scalefactor; |
|
| 431 |
-} |
|
| 432 |
- |
|
| 433 |
-/** |
|
| 434 | 409 |
* Apply generic gain control. |
| 435 | 410 |
* |
| 436 | 411 |
* @param v_out output vector |
| ... | ... |
@@ -442,15 +417,13 @@ static float compute_gain_ctrl(const float *v_ref, const float *v_in, const int |
| 442 | 442 |
static void apply_gain_ctrl(float *v_out, const float *v_ref, |
| 443 | 443 |
const float *v_in) |
| 444 | 444 |
{
|
| 445 |
- int i, j, len; |
|
| 446 |
- float scalefactor; |
|
| 445 |
+ int i; |
|
| 447 | 446 |
|
| 448 |
- for(i=0, j=0; i<4; i++) |
|
| 449 |
- {
|
|
| 450 |
- scalefactor = compute_gain_ctrl(v_ref + j, v_in + j, 40); |
|
| 451 |
- for(len=j+40; j<len; j++) |
|
| 452 |
- v_out[j] = scalefactor * v_in[j]; |
|
| 453 |
- } |
|
| 447 |
+ for (i = 0; i < 160; i += 40) |
|
| 448 |
+ ff_scale_vector_to_given_sum_of_squares(v_out + i, v_in + i, |
|
| 449 |
+ ff_dot_productf(v_ref + i, |
|
| 450 |
+ v_ref + i, 40), |
|
| 451 |
+ 40); |
|
| 454 | 452 |
} |
| 455 | 453 |
|
| 456 | 454 |
/** |