Browse code

gain code, gain pitch and pitch delay decoding for ACELP based codecs

Originally committed as revision 14037 to svn://svn.ffmpeg.org/ffmpeg/trunk

Vladimir Voroshilov authored on 2008/07/01 03:03:38
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,119 @@
0
+/*
1
+ * gain code, gain pitch and pitch delay decoding
2
+ *
3
+ * Copyright (c) 2008 Vladimir Voroshilov
4
+ *
5
+ * This file is part of FFmpeg.
6
+ *
7
+ * FFmpeg is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU Lesser General Public
9
+ * License as published by the Free Software Foundation; either
10
+ * version 2.1 of the License, or (at your option) any later version.
11
+ *
12
+ * FFmpeg is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
+ * Lesser General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Lesser General Public
18
+ * License along with FFmpeg; if not, write to the Free Software
19
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
+ */
21
+
22
+#include "avcodec.h"
23
+#include "acelp_pitch_delay.h"
24
+#include "acelp_math.h"
25
+
26
+int ff_acelp_decode_8bit_to_1st_delay3(int ac_index)
27
+{
28
+    ac_index += 58;
29
+    if(ac_index > 254)
30
+        ac_index = 3 * ac_index - 510;
31
+    return ac_index;
32
+}
33
+
34
+int ff_acelp_decode_4bit_to_2nd_delay3(
35
+        int ac_index,
36
+        int pitch_delay_min)
37
+{
38
+    if(ac_index < 4)
39
+        return 3 * (ac_index + pitch_delay_min);
40
+    else if(ac_index < 12)
41
+        return 3 * pitch_delay_min + ac_index + 6;
42
+    else
43
+        return 3 * (ac_index + pitch_delay_min) - 18;
44
+}
45
+
46
+int ff_acelp_decode_5_6_bit_to_2nd_delay3(
47
+        int ac_index,
48
+        int pitch_delay_min)
49
+{
50
+        return 3 * pitch_delay_min + ac_index - 2;
51
+}
52
+
53
+int ff_acelp_decode_9bit_to_1st_delay6(int ac_index)
54
+{
55
+    if(ac_index < 463)
56
+        return ac_index + 105;
57
+    else
58
+        return 6 * (ac_index - 368);
59
+}
60
+int ff_acelp_decode_6bit_to_2nd_delay6(
61
+        int ac_index,
62
+        int pitch_delay_min)
63
+{
64
+    return 6 * pitch_delay_min + ac_index - 3;
65
+}
66
+
67
+void ff_acelp_update_past_gain(
68
+    int16_t* quant_energy,
69
+    int gain_corr_factor,
70
+    int log2_ma_pred_order,
71
+    int erasure)
72
+{
73
+    int i;
74
+    int avg_gain=quant_energy[(1 << log2_ma_pred_order) - 1]; // (5.10)
75
+
76
+    for(i=(1 << log2_ma_pred_order) - 1; i>0; i--)
77
+    {
78
+        avg_gain       += quant_energy[i-1];
79
+        quant_energy[i] = quant_energy[i-1];
80
+    }
81
+
82
+    if(erasure)
83
+        quant_energy[0] = FFMAX(avg_gain >> log2_ma_pred_order, -10240) - 4096; // -10 and -4 in (5.10)
84
+    else
85
+        quant_energy[0] = (6165 * ((ff_log2(gain_corr_factor) >> 2) - (13 << 13))) >> 13;
86
+}
87
+
88
+int16_t ff_acelp_decode_gain_code(
89
+    int gain_corr_factor,
90
+    const int16_t* fc_v,
91
+    int mr_energy,
92
+    const int16_t* quant_energy,
93
+    const int16_t* ma_prediction_coeff,
94
+    int subframe_size,
95
+    int ma_pred_order)
96
+{
97
+    int i;
98
+
99
+    mr_energy <<= 10;
100
+
101
+    for(i=0; i<ma_pred_order; i++)
102
+        mr_energy += quant_energy[i] * ma_prediction_coeff[i];
103
+
104
+#ifdef G729_BITEXACT
105
+    mr_energy += (((-6165LL * ff_log2(sum_of_squares(fc_v, subframe_size, 0, 0))) >> 3) & ~0x3ff);
106
+
107
+    mr_energy = (5439 * (mr_energy >> 15)) >> 8;           // (0.15) = (0.15) * (7.23)
108
+
109
+    return bidir_sal(
110
+               ((ff_exp2(mr_energy & 0x7fff) + 16) >> 5) * (gain_corr_factor >> 1),
111
+               (mr_energy >> 15) - 25
112
+           );
113
+#else
114
+    mr_energy = gain_corr_factor * exp(M_LN10 / (20 << 23) * mr_energy) /
115
+                sqrt(sum_of_squares(fc_v, subframe_size, 0, 0));
116
+    return mr_energy >> 12;
117
+#endif
118
+}
0 119
new file mode 100644
... ...
@@ -0,0 +1,220 @@
0
+/*
1
+ * gain code, gain pitch and pitch delay decoding
2
+ *
3
+ * Copyright (c) 2008 Vladimir Voroshilov
4
+ *
5
+ * This file is part of FFmpeg.
6
+ *
7
+ * FFmpeg is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU Lesser General Public
9
+ * License as published by the Free Software Foundation; either
10
+ * version 2.1 of the License, or (at your option) any later version.
11
+ *
12
+ * FFmpeg is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
+ * Lesser General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Lesser General Public
18
+ * License along with FFmpeg; if not, write to the Free Software
19
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
+ */
21
+
22
+#ifndef FFMPEG_ACELP_PITCH_DELAY_H
23
+#define FFMPEG_ACELP_PITCH_DELAY_H
24
+
25
+#include <stdint.h>
26
+
27
+#define PITCH_DELAY_MIN             20
28
+#define PITCH_DELAY_MAX             143
29
+
30
+/**
31
+ * \brief Decode pitch delay of the first subframe encoded by 8 bits with 1/3
32
+ *        resolution.
33
+ * \param ac_index adaptive codebook index (8 bits)
34
+ *
35
+ * \return pitch delay in 1/3 units
36
+ *
37
+ * Pitch delay is coded:
38
+ *    with 1/3 resolution, 19  < pitch_delay <  85
39
+ *    integers only,       85 <= pitch_delay <= 143
40
+ */
41
+int ff_acelp_decode_8bit_to_1st_delay3(int ac_index);
42
+
43
+/**
44
+ * \brief Decode pitch delay of the second subframe encoded by 5 or 6 bits
45
+ *        with 1/3 precision.
46
+ * \param ac_index adaptive codebook index (5 or 6 bits)
47
+ * \param pitch_delay_min lower bound (integer) of pitch delay interval
48
+ *                      for second subframe
49
+ *
50
+ * \return pitch delay in 1/3 units
51
+ *
52
+ * Pitch delay is coded:
53
+ *    with 1/3 resolution, -6 < pitch_delay - int(prev_pitch_delay) < 5
54
+ *
55
+ * \remark The routine is used in G.729 @8k, AMR @10.2k, AMR @7.95k,
56
+ *         AMR @7.4k for the second subframe.
57
+ */
58
+int ff_acelp_decode_5_6_bit_to_2nd_delay3(
59
+        int ac_index,
60
+        int pitch_delay_min);
61
+
62
+/**
63
+ * \brief Decode pitch delay with 1/3 precision.
64
+ * \param ac_index adaptive codebook index (4 bits)
65
+ * \param pitch_delay_min lower bound (integer) of pitch delay interval for
66
+ *                      second subframe
67
+ *
68
+ * \return pitch delay in 1/3 units
69
+ *
70
+ * Pitch delay is coded:
71
+ *    integers only,          -6  < pitch_delay - int(prev_pitch_delay) <= -2
72
+ *    with 1/3 resolution,    -2  < pitch_delay - int(prev_pitch_delay) <  1
73
+ *    integers only,           1 <= pitch_delay - int(prev_pitch_delay) <  5
74
+ *
75
+ * \remark The routine is used in G.729 @6.4k, AMR @6.7k, AMR @5.9k,
76
+ *         AMR @5.15k, AMR @4.75k for the second subframe.
77
+ */
78
+int ff_acelp_decode_4bit_to_2nd_delay3(
79
+        int ac_index,
80
+        int pitch_delay_min);
81
+
82
+/**
83
+ * \brief Decode pitch delay of the first subframe encoded by 9 bits
84
+ *        with 1/6 precision.
85
+ * \param ac_index adaptive codebook index (9 bits)
86
+ * \param pitch_delay_min lower bound (integer) of pitch delay interval for
87
+ *                      second subframe
88
+ *
89
+ * \return pitch delay in 1/6 units
90
+ *
91
+ * Pitch delay is coded:
92
+ *    with 1/6 resolution,  17  < pitch_delay <  95
93
+ *    integers only,        95 <= pitch_delay <= 143
94
+ *
95
+ * \remark The routine is used in AMR @12.2k for the first and third subframes.
96
+ */
97
+int ff_acelp_decode_9bit_to_1st_delay6(int ac_index);
98
+
99
+/**
100
+ * \brief Decode pitch delay of the second subframe encoded by 6 bits
101
+ *        with 1/6 precision.
102
+ * \param ac_index adaptive codebook index (6 bits)
103
+ * \param pitch_delay_min lower bound (integer) of pitch delay interval for
104
+ *                      second subframe
105
+ *
106
+ * \return pitch delay in 1/6 units
107
+ *
108
+ * Pitch delay is coded:
109
+ *    with 1/6 resolution, -6 < pitch_delay - int(prev_pitch_delay) < 5
110
+ *
111
+ * \remark The routine is used in AMR @12.2k for the second and fourth subframes.
112
+ */
113
+int ff_acelp_decode_6bit_to_2nd_delay6(
114
+        int ac_index,
115
+        int pitch_delay_min);
116
+
117
+/**
118
+ * \brief Update past quantized energies
119
+ * \param quant_energy [in/out] past quantized energies (5.10)
120
+ * \param gain_corr_factor gain correction factor
121
+ * \param log2_ma_pred_order log2() of MA prediction order
122
+ * \param erasure frame erasure flag
123
+ *
124
+ * If frame erasure flag is not equal to zero, memory is updated with
125
+ * averaged energy, attenuated by 4dB:
126
+ *     max(avg(quant_energy[i])-4, -14), i=0,ma_pred_order
127
+ *
128
+ * In normal mode memory is updated with
129
+ *     Er - Ep = 20 * log10(gain_corr_factor)
130
+ *
131
+ * \remark The routine is used in G.729 and AMR (all modes).
132
+ */
133
+void ff_acelp_update_past_gain(
134
+        int16_t* quant_energy,
135
+        int gain_corr_factor,
136
+        int log2_ma_pred_order,
137
+        int erasure);
138
+
139
+/**
140
+ * \brief Decode the adaptive codebook gain and add
141
+ *        correction (4.1.5 and 3.9.1 of G.729).
142
+ * \param gain_corr_factor gain correction factor (2.13)
143
+ * \param fc_v fixed-codebook vector (2.13)
144
+ * \param mr_energy mean innovation energy and fixed-point correction (7.13)
145
+ * \param quant_energy [in/out] past quantized energies (5.10)
146
+ * \param subframe_size length of subframe
147
+ * \param ma_pred_order MA prediction order
148
+ *
149
+ * \return quantized fixed-codebook gain (14.1)
150
+ *
151
+ * The routine implements equations 69, 66 and 71 of the G.729 specification (3.9.1)
152
+ *
153
+ *    Em   - mean innovation energy (dB, constant, depends on decoding algorithm)
154
+ *    Ep   - mean-removed predicted energy (dB)
155
+ *    Er   - mean-removed innovation energy (dB)
156
+ *    Ei   - mean energy of the fixed-codebook contribution (dB)
157
+ *    N    - subframe_size
158
+ *    M    - MA (Moving Average) prediction order
159
+ *    gc   - fixed-codebook gain
160
+ *    gc_p - predicted fixed-codebook gain
161
+ *
162
+ *    Fixed codebook gain is computed using predicted gain gc_p and
163
+ *    correction factor gain_corr_factor as shown below:
164
+ *
165
+ *        gc = gc_p * gain_corr_factor
166
+ *
167
+ *    The predicted fixed codebook gain gc_p is found by predicting
168
+ *    the energy of the fixed-codebook contribution from the energy
169
+ *    of previous fixed-codebook contributions.
170
+ *
171
+ *        mean = 1/N * sum(i,0,N){ fc_v[i] * fc_v[i] }
172
+ *
173
+ *        Ei = 10log(mean)
174
+ *
175
+ *        Er = 10log(1/N * gc^2 * mean) - Em = 20log(gc) + Ei - Em
176
+ *
177
+ *    Replacing Er with Ep and gc with gc_p we will receive:
178
+ *
179
+ *        Ep = 10log(1/N * gc_p^2 * mean) - Em = 20log(gc_p) + Ei - Em
180
+ *
181
+ *    and from above:
182
+ *
183
+ *        gc_p = 10^((Ep - Ei + Em) / 20)
184
+ *
185
+ *    Ep is predicted using past energies and prediction coefficients:
186
+ *
187
+ *        Ep = sum(i,0,M){ ma_prediction_coeff[i] * quant_energy[i] }
188
+ *
189
+ *    gc_p in fixed-point arithmetic is calculated as following:
190
+ *
191
+ *        mean = 1/N * sum(i,0,N){ (fc_v[i] / 2^13) * (fc_v[i] / 2^13) } =
192
+ *        = 1/N * sum(i,0,N) { fc_v[i] * fc_v[i] } / 2^26
193
+ *
194
+ *        Ei = 10log(mean) = -10log(N) - 10log(2^26) +
195
+ *        + 10log(sum(i,0,N) { fc_v[i] * fc_v[i] })
196
+ *
197
+ *        Ep - Ei + Em = Ep + Em + 10log(N) + 10log(2^26) -
198
+ *        - 10log(sum(i,0,N) { fc_v[i] * fc_v[i] }) =
199
+ *        = Ep + mr_energy - 10log(sum(i,0,N) { fc_v[i] * fc_v[i] })
200
+ *
201
+ *        gc_p = 10 ^ ((Ep - Ei + Em) / 20) =
202
+ *        = 2 ^ (3.3219 * (Ep - Ei + Em) / 20) = 2 ^ (0.166 * (Ep - Ei + Em))
203
+ *
204
+ *    where
205
+ *
206
+ *        mr_energy = Em + 10log(N) + 10log(2^26)
207
+ *
208
+ * \remark The routine is used in G.729 and AMR (all modes).
209
+ */
210
+int16_t ff_acelp_decode_gain_code(
211
+    int gain_corr_factor,
212
+    const int16_t* fc_v,
213
+    int mr_energy,
214
+    const int16_t* quant_energy,
215
+    const int16_t* ma_prediction_coeff,
216
+    int subframe_size,
217
+    int max_pred_order);
218
+
219
+#endif /* FFMPEG_ACELP_PITCH_DELAY_H */