Mercurial > libavcodec.hg
annotate g726.c @ 3990:746a60ba3177 libavcodec
enable CMOV_IS_FAST as its faster or equal speed on every cpu (duron, athlon, PM, P3) from which ive seen benchmarks, it might be slower on P4 but noone has posted benchmarks ...
author | michael |
---|---|
date | Wed, 11 Oct 2006 12:23:40 +0000 |
parents | c8c591fe26f8 |
children | 85438e10d72d |
rev | line source |
---|---|
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
1 /* |
2967 | 2 * G.726 ADPCM audio codec |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
3 * Copyright (c) 2004 Roman Shaposhnik. |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
4 * |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
5 * This is a very straightforward rendition of the G.726 |
2967 | 6 * Section 4 "Computational Details". |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
7 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
8 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
9 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
10 * FFmpeg is free software; you can redistribute it and/or |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
11 * modify it under the terms of the GNU Lesser General Public |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
12 * License as published by the Free Software Foundation; either |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
13 * version 2.1 of the License, or (at your option) any later version. |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
14 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
15 * FFmpeg is distributed in the hope that it will be useful, |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
18 * Lesser General Public License for more details. |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
19 * |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
20 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
21 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
23 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
24 #include <limits.h> |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
25 #include "avcodec.h" |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
26 #include "common.h" |
2398
582e635cfa08
common.c -> bitstream.c (and the single non bitstream func -> utils.c)
michael
parents:
2135
diff
changeset
|
27 #include "bitstream.h" |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
28 |
2135 | 29 /** |
30 * G.726 11bit float. | |
2967 | 31 * G.726 Standard uses rather odd 11bit floating point arithmentic for |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
32 * numerous occasions. It's a mistery to me why they did it this way |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
33 * instead of simply using 32bit integer arithmetic. |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
34 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
35 typedef struct Float11 { |
2979 | 36 int sign; /**< 1bit sign */ |
37 int exp; /**< 4bit exponent */ | |
38 int mant; /**< 6bit mantissa */ | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
39 } Float11; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
40 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
41 static inline Float11* i2f(int16_t i, Float11* f) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
42 { |
2979 | 43 f->sign = (i < 0); |
44 if (f->sign) | |
45 i = -i; | |
46 f->exp = av_log2_16bit(i) + !!i; | |
47 f->mant = i? (i<<6) >> f->exp : | |
48 1<<5; | |
49 return f; | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
50 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
51 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
52 static inline int16_t mult(Float11* f1, Float11* f2) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
53 { |
2979 | 54 int res, exp; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
55 |
2979 | 56 exp = f1->exp + f2->exp; |
57 res = (((f1->mant * f2->mant) + 0x30) >> 4) << 7; | |
58 res = exp > 26 ? res << (exp - 26) : res >> (26 - exp); | |
59 return (f1->sign ^ f2->sign) ? -res : res; | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
60 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
61 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
62 static inline int sgn(int value) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
63 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
64 return (value < 0) ? -1 : 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
65 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
66 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
67 typedef struct G726Tables { |
2979 | 68 int bits; /**< bits per sample */ |
69 int* quant; /**< quantization table */ | |
70 int* iquant; /**< inverse quantization table */ | |
71 int* W; /**< special table #1 ;-) */ | |
72 int* F; /**< special table #2 */ | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
73 } G726Tables; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
74 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
75 typedef struct G726Context { |
2979 | 76 G726Tables* tbls; /**< static tables needed for computation */ |
2967 | 77 |
2979 | 78 Float11 sr[2]; /**< prev. reconstructed samples */ |
79 Float11 dq[6]; /**< prev. difference */ | |
80 int a[2]; /**< second order predictor coeffs */ | |
81 int b[6]; /**< sixth order predictor coeffs */ | |
82 int pk[2]; /**< signs of prev. 2 sez + dq */ | |
2967 | 83 |
2979 | 84 int ap; /**< scale factor control */ |
85 int yu; /**< fast scale factor */ | |
86 int yl; /**< slow scale factor */ | |
87 int dms; /**< short average magnitude of F[i] */ | |
88 int dml; /**< long average magnitude of F[i] */ | |
89 int td; /**< tone detect */ | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
90 |
2979 | 91 int se; /**< estimated signal for the next iteration */ |
92 int sez; /**< estimated second order prediction */ | |
93 int y; /**< quantizer scaling factor for the next iteration */ | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
94 } G726Context; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
95 |
2135 | 96 static int quant_tbl16[] = /**< 16kbit/s 2bits per sample */ |
2967 | 97 { 260, INT_MAX }; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
98 static int iquant_tbl16[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
99 { 116, 365, 365, 116 }; |
2967 | 100 static int W_tbl16[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
101 { -22, 439, 439, -22 }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
102 static int F_tbl16[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
103 { 0, 7, 7, 0 }; |
2967 | 104 |
2135 | 105 static int quant_tbl24[] = /**< 24kbit/s 3bits per sample */ |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
106 { 7, 217, 330, INT_MAX }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
107 static int iquant_tbl24[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
108 { INT_MIN, 135, 273, 373, 373, 273, 135, INT_MIN }; |
2967 | 109 static int W_tbl24[] = |
110 { -4, 30, 137, 582, 582, 137, 30, -4 }; | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
111 static int F_tbl24[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
112 { 0, 1, 2, 7, 7, 2, 1, 0 }; |
2967 | 113 |
2135 | 114 static int quant_tbl32[] = /**< 32kbit/s 4bits per sample */ |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
115 { -125, 79, 177, 245, 299, 348, 399, INT_MAX }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
116 static int iquant_tbl32[] = |
2967 | 117 { INT_MIN, 4, 135, 213, 273, 323, 373, 425, |
2979 | 118 425, 373, 323, 273, 213, 135, 4, INT_MIN }; |
2967 | 119 static int W_tbl32[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
120 { -12, 18, 41, 64, 112, 198, 355, 1122, |
2979 | 121 1122, 355, 198, 112, 64, 41, 18, -12}; |
2967 | 122 static int F_tbl32[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
123 { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 }; |
2967 | 124 |
2135 | 125 static int quant_tbl40[] = /**< 40kbit/s 5bits per sample */ |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
126 { -122, -16, 67, 138, 197, 249, 297, 338, |
2979 | 127 377, 412, 444, 474, 501, 527, 552, INT_MAX }; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
128 static int iquant_tbl40[] = |
2967 | 129 { INT_MIN, -66, 28, 104, 169, 224, 274, 318, |
2979 | 130 358, 395, 429, 459, 488, 514, 539, 566, |
131 566, 539, 514, 488, 459, 429, 395, 358, | |
132 318, 274, 224, 169, 104, 28, -66, INT_MIN }; | |
2967 | 133 static int W_tbl40[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
134 { 14, 14, 24, 39, 40, 41, 58, 100, |
2979 | 135 141, 179, 219, 280, 358, 440, 529, 696, |
136 696, 529, 440, 358, 280, 219, 179, 141, | |
137 100, 58, 41, 40, 39, 24, 14, 14 }; | |
2967 | 138 static int F_tbl40[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
139 { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6, |
2979 | 140 6, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
141 |
2967 | 142 static G726Tables G726Tables_pool[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
143 {{ 2, quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 }, |
2979 | 144 { 3, quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 }, |
145 { 4, quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 }, | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
146 { 5, quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }}; |
2967 | 147 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
148 |
2135 | 149 /** |
2967 | 150 * Para 4.2.2 page 18: Adaptive quantizer. |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
151 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
152 static inline uint8_t quant(G726Context* c, int d) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
153 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
154 int sign, exp, i, dln; |
2967 | 155 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
156 sign = i = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
157 if (d < 0) { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
158 sign = 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
159 d = -d; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
160 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
161 exp = av_log2_16bit(d); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
162 dln = ((exp<<7) + (((d<<7)>>exp)&0x7f)) - (c->y>>2); |
2967 | 163 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
164 while (c->tbls->quant[i] < INT_MAX && c->tbls->quant[i] < dln) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
165 ++i; |
2967 | 166 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
167 if (sign) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
168 i = ~i; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
169 if (c->tbls->bits != 2 && i == 0) /* I'm not sure this is a good idea */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
170 i = 0xff; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
171 |
2967 | 172 return i; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
173 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
174 |
2135 | 175 /** |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
176 * Para 4.2.3 page 22: Inverse adaptive quantizer. |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
177 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
178 static inline int16_t inverse_quant(G726Context* c, int i) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
179 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
180 int dql, dex, dqt; |
2967 | 181 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
182 dql = c->tbls->iquant[i] + (c->y >> 2); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
183 dex = (dql>>7) & 0xf; /* 4bit exponent */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
184 dqt = (1<<7) + (dql & 0x7f); /* log2 -> linear */ |
2967 | 185 return (dql < 0) ? 0 : ((dqt<<7) >> (14-dex)); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
186 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
187 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
188 static inline int16_t g726_iterate(G726Context* c, int16_t I) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
189 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
190 int dq, re_signal, pk0, fa1, i, tr, ylint, ylfrac, thr2, al, dq0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
191 Float11 f; |
2967 | 192 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
193 dq = inverse_quant(c, I); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
194 if (I >> (c->tbls->bits - 1)) /* get the sign */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
195 dq = -dq; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
196 re_signal = c->se + dq; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
197 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
198 /* Transition detect */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
199 ylint = (c->yl >> 15); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
200 ylfrac = (c->yl >> 10) & 0x1f; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
201 thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
202 if (c->td == 1 && abs(dq) > ((thr2+(thr2>>1))>>1)) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
203 tr = 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
204 else |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
205 tr = 0; |
2967 | 206 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
207 /* Update second order predictor coefficient A2 and A1 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
208 pk0 = (c->sez + dq) ? sgn(c->sez + dq) : 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
209 dq0 = dq ? sgn(dq) : 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
210 if (tr) { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
211 c->a[0] = 0; |
2979 | 212 c->a[1] = 0; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
213 for (i=0; i<6; i++) |
2979 | 214 c->b[i] = 0; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
215 } else { |
2979 | 216 /* This is a bit crazy, but it really is +255 not +256 */ |
217 fa1 = clip((-c->a[0]*c->pk[0]*pk0)>>5, -256, 255); | |
2967 | 218 |
2979 | 219 c->a[1] += 128*pk0*c->pk[1] + fa1 - (c->a[1]>>7); |
220 c->a[1] = clip(c->a[1], -12288, 12288); | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
221 c->a[0] += 64*3*pk0*c->pk[0] - (c->a[0] >> 8); |
2979 | 222 c->a[0] = clip(c->a[0], -(15360 - c->a[1]), 15360 - c->a[1]); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
223 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
224 for (i=0; i<6; i++) |
2979 | 225 c->b[i] += 128*dq0*sgn(-c->dq[i].sign) - (c->b[i]>>8); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
226 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
227 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
228 /* Update Dq and Sr and Pk */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
229 c->pk[1] = c->pk[0]; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
230 c->pk[0] = pk0 ? pk0 : 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
231 c->sr[1] = c->sr[0]; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
232 i2f(re_signal, &c->sr[0]); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
233 for (i=5; i>0; i--) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
234 c->dq[i] = c->dq[i-1]; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
235 i2f(dq, &c->dq[0]); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
236 c->dq[0].sign = I >> (c->tbls->bits - 1); /* Isn't it crazy ?!?! */ |
2967 | 237 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
238 /* Update tone detect [I'm not sure 'tr == 0' is really needed] */ |
2967 | 239 c->td = (tr == 0 && c->a[1] < -11776); |
240 | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
241 /* Update Ap */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
242 c->dms += ((c->tbls->F[I]<<9) - c->dms) >> 5; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
243 c->dml += ((c->tbls->F[I]<<11) - c->dml) >> 7; |
2967 | 244 if (tr) |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
245 c->ap = 256; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
246 else if (c->y > 1535 && !c->td && (abs((c->dms << 2) - c->dml) < (c->dml >> 3))) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
247 c->ap += (-c->ap) >> 4; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
248 else |
2967 | 249 c->ap += (0x200 - c->ap) >> 4; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
250 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
251 /* Update Yu and Yl */ |
1792 | 252 c->yu = clip(c->y + (((c->tbls->W[I] << 5) - c->y) >> 5), 544, 5120); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
253 c->yl += c->yu + ((-c->yl)>>6); |
2967 | 254 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
255 /* Next iteration for Y */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
256 al = (c->ap >= 256) ? 1<<6 : c->ap >> 2; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
257 c->y = (c->yl + (c->yu - (c->yl>>6))*al) >> 6; |
2967 | 258 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
259 /* Next iteration for SE and SEZ */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
260 c->se = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
261 for (i=0; i<6; i++) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
262 c->se += mult(i2f(c->b[i] >> 2, &f), &c->dq[i]); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
263 c->sez = c->se >> 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
264 for (i=0; i<2; i++) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
265 c->se += mult(i2f(c->a[i] >> 2, &f), &c->sr[i]); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
266 c->se >>= 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
267 |
1792 | 268 return clip(re_signal << 2, -0xffff, 0xffff); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
269 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
270 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
271 static int g726_reset(G726Context* c, int bit_rate) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
272 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
273 int i; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
274 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
275 c->tbls = &G726Tables_pool[bit_rate/8000 - 2]; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
276 for (i=0; i<2; i++) { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
277 i2f(0, &c->sr[i]); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
278 c->a[i] = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
279 c->pk[i] = 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
280 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
281 for (i=0; i<6; i++) { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
282 i2f(0, &c->dq[i]); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
283 c->b[i] = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
284 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
285 c->ap = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
286 c->dms = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
287 c->dml = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
288 c->yu = 544; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
289 c->yl = 34816; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
290 c->td = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
291 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
292 c->se = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
293 c->sez = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
294 c->y = 544; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
295 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
296 return 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
297 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
298 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
299 static int16_t g726_decode(G726Context* c, int16_t i) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
300 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
301 return g726_iterate(c, i); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
302 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
303 |
3777 | 304 #ifdef CONFIG_ENCODERS |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
305 static int16_t g726_encode(G726Context* c, int16_t sig) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
306 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
307 uint8_t i; |
2967 | 308 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
309 i = quant(c, sig/4 - c->se) & ((1<<c->tbls->bits) - 1); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
310 g726_iterate(c, i); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
311 return i; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
312 } |
3777 | 313 #endif |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
314 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
315 /* Interfacing to the libavcodec */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
316 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
317 typedef struct AVG726Context { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
318 G726Context c; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
319 int bits_left; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
320 int bit_buffer; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
321 int code_size; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
322 } AVG726Context; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
323 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
324 static int g726_init(AVCodecContext * avctx) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
325 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
326 AVG726Context* c = (AVG726Context*)avctx->priv_data; |
2967 | 327 |
1792 | 328 if (avctx->channels != 1 || |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
329 (avctx->bit_rate != 16000 && avctx->bit_rate != 24000 && |
2979 | 330 avctx->bit_rate != 32000 && avctx->bit_rate != 40000)) { |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
331 av_log(avctx, AV_LOG_ERROR, "G726: unsupported audio format\n"); |
2979 | 332 return -1; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
333 } |
2658
d1609cfeb1d0
#defines for strict_std_compliance and split between inofficial extensions and non standarized things
michael
parents:
2398
diff
changeset
|
334 if (avctx->sample_rate != 8000 && avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL) { |
1792 | 335 av_log(avctx, AV_LOG_ERROR, "G726: unsupported audio format\n"); |
2979 | 336 return -1; |
1792 | 337 } |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
338 g726_reset(&c->c, avctx->bit_rate); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
339 c->code_size = c->c.tbls->bits; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
340 c->bit_buffer = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
341 c->bits_left = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
342 |
1797
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
343 avctx->coded_frame = avcodec_alloc_frame(); |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
344 if (!avctx->coded_frame) |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
345 return -ENOMEM; |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
346 avctx->coded_frame->key_frame = 1; |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
347 |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
348 return 0; |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
349 } |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
350 |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
351 static int g726_close(AVCodecContext *avctx) |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
352 { |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
353 av_freep(&avctx->coded_frame); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
354 return 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
355 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
356 |
3777 | 357 #ifdef CONFIG_ENCODERS |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
358 static int g726_encode_frame(AVCodecContext *avctx, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
359 uint8_t *dst, int buf_size, void *data) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
360 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
361 AVG726Context *c = avctx->priv_data; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
362 short *samples = data; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
363 PutBitContext pb; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
364 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
365 init_put_bits(&pb, dst, 1024*1024); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
366 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
367 for (; buf_size; buf_size--) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
368 put_bits(&pb, c->code_size, g726_encode(&c->c, *samples++)); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
369 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
370 flush_put_bits(&pb); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
371 |
2967 | 372 return put_bits_count(&pb)>>3; |
373 } | |
3777 | 374 #endif |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
375 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
376 static int g726_decode_frame(AVCodecContext *avctx, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
377 void *data, int *data_size, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
378 uint8_t *buf, int buf_size) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
379 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
380 AVG726Context *c = avctx->priv_data; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
381 short *samples = data; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
382 uint8_t code; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
383 uint8_t mask; |
2967 | 384 GetBitContext gb; |
385 | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
386 if (!buf_size) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
387 goto out; |
2967 | 388 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
389 mask = (1<<c->code_size) - 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
390 init_get_bits(&gb, buf, buf_size * 8); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
391 if (c->bits_left) { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
392 int s = c->code_size - c->bits_left;; |
2979 | 393 code = (c->bit_buffer << s) | get_bits(&gb, s); |
394 *samples++ = g726_decode(&c->c, code & mask); | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
395 } |
2967 | 396 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
397 while (get_bits_count(&gb) + c->code_size <= buf_size*8) |
2979 | 398 *samples++ = g726_decode(&c->c, get_bits(&gb, c->code_size) & mask); |
2967 | 399 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
400 c->bits_left = buf_size*8 - get_bits_count(&gb); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
401 c->bit_buffer = get_bits(&gb, c->bits_left); |
2967 | 402 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
403 out: |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
404 *data_size = (uint8_t*)samples - (uint8_t*)data; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
405 return buf_size; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
406 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
407 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
408 #ifdef CONFIG_ENCODERS |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
409 AVCodec adpcm_g726_encoder = { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
410 "g726", |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
411 CODEC_TYPE_AUDIO, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
412 CODEC_ID_ADPCM_G726, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
413 sizeof(AVG726Context), |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
414 g726_init, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
415 g726_encode_frame, |
1797
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
416 g726_close, |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
417 NULL, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
418 }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
419 #endif //CONFIG_ENCODERS |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
420 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
421 AVCodec adpcm_g726_decoder = { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
422 "g726", |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
423 CODEC_TYPE_AUDIO, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
424 CODEC_ID_ADPCM_G726, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
425 sizeof(AVG726Context), |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
426 g726_init, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
427 NULL, |
1797
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
428 g726_close, |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
429 g726_decode_frame, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
430 }; |