Mercurial > libavcodec.hg
annotate g726.c @ 1795:920e6381e1fe libavcodec
2 byte shorter userdata for mpeg4
in the past it was startcode,string,00,7F,startcode
now it is startcode,string,stratcode
both are mpeg4 compliant, as according to the standard the userdata lasts until the next 00 00 01 (startcode prefix) but some very primitive decoders which simply skip until the first 00 byte and then expect the next valid startcode might fail with the old variant, just a theory though (didnt test if quicktime can decode it now)
author | michael |
---|---|
date | Sun, 08 Feb 2004 22:52:35 +0000 |
parents | 7da4bdafe42e |
children | fac680cf3008 |
rev | line source |
---|---|
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
1 /* |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
2 * G.726 ADPCM audio codec |
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 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
6 * Section 4 "Computational Details". |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
7 * |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
8 * This library is free software; you can redistribute it and/or |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
9 * 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
|
10 * License as published by the Free Software Foundation; either |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
11 * version 2 of the License, or (at your option) any later version. |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
12 * |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
13 * This library is distributed in the hope that it will be useful, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
16 * Lesser General Public License for more details. |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
17 * |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
18 * You should have received a copy of the GNU Lesser General Public |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
19 * License along with this library; if not, write to the Free Software |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
21 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
22 #include <limits.h> |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
23 #include "avcodec.h" |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
24 #include "common.h" |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
25 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
26 /* |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
27 * G.726 Standard uses rather odd 11bit floating point arithmentic for |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
28 * 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
|
29 * instead of simply using 32bit integer arithmetic. |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
30 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
31 typedef struct Float11 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
32 int sign; /* 1bit sign */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
33 int exp; /* 4bit exponent */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
34 int mant; /* 6bit mantissa */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
35 } Float11; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
36 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
37 static inline Float11* i2f(int16_t i, Float11* f) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
38 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
39 f->sign = (i < 0); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
40 if (f->sign) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
41 i = -i; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
42 f->exp = av_log2_16bit(i) + !!i; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
43 f->mant = i? (i<<6) >> f->exp : |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
44 1<<5; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
45 return f; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
46 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
47 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
48 static inline int16_t mult(Float11* f1, Float11* f2) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
49 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
50 int res, exp; |
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 exp = f1->exp + f2->exp; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
53 res = (((f1->mant * f2->mant) + 0x30) >> 4) << 7; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
54 res = exp > 26 ? res << (exp - 26) : res >> (26 - exp); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
55 return (f1->sign ^ f2->sign) ? -res : res; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
56 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
57 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
58 static inline int sgn(int value) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
59 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
60 return (value < 0) ? -1 : 1; |
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 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
63 typedef struct G726Tables { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
64 int bits; /* bits per sample */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
65 int* quant; /* quantization table */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
66 int* iquant; /* inverse quantization table */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
67 int* W; /* special table #1 ;-) */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
68 int* F; /* special table #2 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
69 } G726Tables; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
70 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
71 typedef struct G726Context { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
72 G726Tables* tbls; /* static tables needed for computation */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
73 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
74 Float11 sr[2]; /* prev. reconstructed samples */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
75 Float11 dq[6]; /* prev. difference */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
76 int a[2]; /* second order predictor coeffs */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
77 int b[6]; /* sixth order predictor coeffs */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
78 int pk[2]; /* signs of prev. 2 sez + dq */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
79 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
80 int ap; /* scale factor control */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
81 int yu; /* fast scale factor */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
82 int yl; /* slow scale factor */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
83 int dms; /* short average magnitude of F[i] */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
84 int dml; /* long average magnitude of F[i] */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
85 int td; /* tone detect */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
86 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
87 int se; /* estimated signal for the next iteration */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
88 int sez; /* estimated second order prediction */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
89 int y; /* quantizer scaling factor for the next iteration */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
90 } G726Context; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
91 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
92 static int quant_tbl16[] = /* 16kbit/s 2bits per sample */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
93 { 260, INT_MAX }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
94 static int iquant_tbl16[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
95 { 116, 365, 365, 116 }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
96 static int W_tbl16[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
97 { -22, 439, 439, -22 }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
98 static int F_tbl16[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
99 { 0, 7, 7, 0 }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
100 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
101 static int quant_tbl24[] = /* 24kbit/s 3bits per sample */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
102 { 7, 217, 330, INT_MAX }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
103 static int iquant_tbl24[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
104 { INT_MIN, 135, 273, 373, 373, 273, 135, INT_MIN }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
105 static int W_tbl24[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
106 { -4, 30, 137, 582, 582, 137, 30, -4 }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
107 static int F_tbl24[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
108 { 0, 1, 2, 7, 7, 2, 1, 0 }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
109 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
110 static int quant_tbl32[] = /* 32kbit/s 4bits per sample */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
111 { -125, 79, 177, 245, 299, 348, 399, INT_MAX }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
112 static int iquant_tbl32[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
113 { INT_MIN, 4, 135, 213, 273, 323, 373, 425, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
114 425, 373, 323, 273, 213, 135, 4, INT_MIN }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
115 static int W_tbl32[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
116 { -12, 18, 41, 64, 112, 198, 355, 1122, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
117 1122, 355, 198, 112, 64, 41, 18, -12}; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
118 static int F_tbl32[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
119 { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
120 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
121 static int quant_tbl40[] = /* 40kbit/s 5bits per sample */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
122 { -122, -16, 67, 138, 197, 249, 297, 338, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
123 377, 412, 444, 474, 501, 527, 552, INT_MAX }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
124 static int iquant_tbl40[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
125 { INT_MIN, -66, 28, 104, 169, 224, 274, 318, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
126 358, 395, 429, 459, 488, 514, 539, 566, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
127 566, 539, 514, 488, 459, 429, 395, 358, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
128 318, 274, 224, 169, 104, 28, -66, INT_MIN }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
129 static int W_tbl40[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
130 { 14, 14, 24, 39, 40, 41, 58, 100, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
131 141, 179, 219, 280, 358, 440, 529, 696, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
132 696, 529, 440, 358, 280, 219, 179, 141, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
133 100, 58, 41, 40, 39, 24, 14, 14 }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
134 static int F_tbl40[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
135 { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
136 6, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
137 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
138 static G726Tables G726Tables_pool[] = |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
139 {{ 2, quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 }, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
140 { 3, quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 }, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
141 { 4, quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 }, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
142 { 5, quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }}; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
143 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
144 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
145 /* |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
146 * Para 4.2.2 page 18: Adaptive quantizer. |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
147 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
148 static inline uint8_t quant(G726Context* c, int d) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
149 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
150 int sign, exp, i, dln; |
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 sign = i = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
153 if (d < 0) { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
154 sign = 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
155 d = -d; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
156 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
157 exp = av_log2_16bit(d); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
158 dln = ((exp<<7) + (((d<<7)>>exp)&0x7f)) - (c->y>>2); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
159 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
160 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
|
161 ++i; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
162 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
163 if (sign) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
164 i = ~i; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
165 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
|
166 i = 0xff; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
167 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
168 return i; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
169 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
170 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
171 /* |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
172 * Para 4.2.3 page 22: Inverse adaptive quantizer. |
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 static inline int16_t inverse_quant(G726Context* c, int i) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
175 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
176 int dql, dex, dqt; |
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 dql = c->tbls->iquant[i] + (c->y >> 2); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
179 dex = (dql>>7) & 0xf; /* 4bit exponent */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
180 dqt = (1<<7) + (dql & 0x7f); /* log2 -> linear */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
181 return (dql < 0) ? 0 : ((dqt<<7) >> (14-dex)); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
182 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
183 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
184 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
|
185 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
186 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
|
187 Float11 f; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
188 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
189 dq = inverse_quant(c, I); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
190 if (I >> (c->tbls->bits - 1)) /* get the sign */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
191 dq = -dq; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
192 re_signal = c->se + dq; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
193 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
194 /* Transition detect */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
195 ylint = (c->yl >> 15); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
196 ylfrac = (c->yl >> 10) & 0x1f; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
197 thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
198 if (c->td == 1 && abs(dq) > ((thr2+(thr2>>1))>>1)) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
199 tr = 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
200 else |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
201 tr = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
202 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
203 /* Update second order predictor coefficient A2 and A1 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
204 pk0 = (c->sez + dq) ? sgn(c->sez + dq) : 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
205 dq0 = dq ? sgn(dq) : 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
206 if (tr) { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
207 c->a[0] = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
208 c->a[1] = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
209 for (i=0; i<6; i++) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
210 c->b[i] = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
211 } else { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
212 /* This is a bit crazy, but it really is +255 not +256 */ |
1792 | 213 fa1 = clip((-c->a[0]*c->pk[0]*pk0)>>5, -256, 255); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
214 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
215 c->a[1] += 128*pk0*c->pk[1] + fa1 - (c->a[1]>>7); |
1792 | 216 c->a[1] = clip(c->a[1], -12288, 12288); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
217 c->a[0] += 64*3*pk0*c->pk[0] - (c->a[0] >> 8); |
1792 | 218 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
|
219 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
220 for (i=0; i<6; i++) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
221 c->b[i] += 128*dq0*sgn(-c->dq[i].sign) - (c->b[i]>>8); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
222 } |
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 /* Update Dq and Sr and Pk */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
225 c->pk[1] = c->pk[0]; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
226 c->pk[0] = pk0 ? pk0 : 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
227 c->sr[1] = c->sr[0]; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
228 i2f(re_signal, &c->sr[0]); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
229 for (i=5; i>0; i--) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
230 c->dq[i] = c->dq[i-1]; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
231 i2f(dq, &c->dq[0]); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
232 c->dq[0].sign = I >> (c->tbls->bits - 1); /* Isn't it crazy ?!?! */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
233 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
234 /* Update tone detect [I'm not sure 'tr == 0' is really needed] */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
235 c->td = (tr == 0 && c->a[1] < -11776); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
236 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
237 /* Update Ap */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
238 c->dms += ((c->tbls->F[I]<<9) - c->dms) >> 5; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
239 c->dml += ((c->tbls->F[I]<<11) - c->dml) >> 7; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
240 if (tr) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
241 c->ap = 256; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
242 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
|
243 c->ap += (-c->ap) >> 4; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
244 else |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
245 c->ap += (0x200 - c->ap) >> 4; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
246 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
247 /* Update Yu and Yl */ |
1792 | 248 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
|
249 c->yl += c->yu + ((-c->yl)>>6); |
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 /* Next iteration for Y */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
252 al = (c->ap >= 256) ? 1<<6 : c->ap >> 2; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
253 c->y = (c->yl + (c->yu - (c->yl>>6))*al) >> 6; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
254 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
255 /* Next iteration for SE and SEZ */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
256 c->se = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
257 for (i=0; i<6; i++) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
258 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
|
259 c->sez = c->se >> 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
260 for (i=0; i<2; i++) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
261 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
|
262 c->se >>= 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
263 |
1792 | 264 return clip(re_signal << 2, -0xffff, 0xffff); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
265 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
266 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
267 static int g726_reset(G726Context* c, int bit_rate) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
268 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
269 int i; |
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 c->tbls = &G726Tables_pool[bit_rate/8000 - 2]; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
272 for (i=0; i<2; i++) { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
273 i2f(0, &c->sr[i]); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
274 c->a[i] = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
275 c->pk[i] = 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
276 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
277 for (i=0; i<6; i++) { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
278 i2f(0, &c->dq[i]); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
279 c->b[i] = 0; |
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 c->ap = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
282 c->dms = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
283 c->dml = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
284 c->yu = 544; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
285 c->yl = 34816; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
286 c->td = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
287 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
288 c->se = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
289 c->sez = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
290 c->y = 544; |
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 return 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
293 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
294 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
295 static int16_t g726_decode(G726Context* c, int16_t i) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
296 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
297 return g726_iterate(c, i); |
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 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
300 static int16_t g726_encode(G726Context* c, int16_t sig) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
301 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
302 uint8_t i; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
303 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
304 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
|
305 g726_iterate(c, i); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
306 return i; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
307 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
308 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
309 /* Interfacing to the libavcodec */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
310 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
311 typedef struct AVG726Context { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
312 G726Context c; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
313 int bits_left; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
314 int bit_buffer; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
315 int code_size; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
316 } AVG726Context; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
317 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
318 static int g726_init(AVCodecContext * avctx) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
319 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
320 AVG726Context* c = (AVG726Context*)avctx->priv_data; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
321 |
1792 | 322 if (avctx->channels != 1 || |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
323 (avctx->bit_rate != 16000 && avctx->bit_rate != 24000 && |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
324 avctx->bit_rate != 32000 && avctx->bit_rate != 40000)) { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
325 av_log(avctx, AV_LOG_ERROR, "G726: unsupported audio format\n"); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
326 return -1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
327 } |
1792 | 328 if (avctx->sample_rate != 8000 && avctx->strict_std_compliance>=0) { |
329 av_log(avctx, AV_LOG_ERROR, "G726: unsupported audio format\n"); | |
330 return -1; | |
331 } | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
332 g726_reset(&c->c, avctx->bit_rate); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
333 c->code_size = c->c.tbls->bits; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
334 c->bit_buffer = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
335 c->bits_left = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
336 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
337 return 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
338 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
339 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
340 static int g726_encode_frame(AVCodecContext *avctx, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
341 uint8_t *dst, int buf_size, void *data) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
342 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
343 AVG726Context *c = avctx->priv_data; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
344 short *samples = data; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
345 PutBitContext pb; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
346 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
347 init_put_bits(&pb, dst, 1024*1024); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
348 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
349 for (; buf_size; buf_size--) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
350 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
|
351 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
352 flush_put_bits(&pb); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
353 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
354 return put_bits_count(&pb)>>3; |
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 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
357 static int g726_decode_frame(AVCodecContext *avctx, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
358 void *data, int *data_size, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
359 uint8_t *buf, int buf_size) |
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 uint8_t code; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
364 uint8_t mask; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
365 GetBitContext gb; |
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 if (!buf_size) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
368 goto out; |
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 mask = (1<<c->code_size) - 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
371 init_get_bits(&gb, buf, buf_size * 8); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
372 if (c->bits_left) { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
373 int s = c->code_size - c->bits_left;; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
374 code = (c->bit_buffer << s) | get_bits(&gb, s); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
375 *samples++ = g726_decode(&c->c, code & mask); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
376 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
377 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
378 while (get_bits_count(&gb) + c->code_size <= buf_size*8) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
379 *samples++ = g726_decode(&c->c, get_bits(&gb, c->code_size) & mask); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
380 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
381 c->bits_left = buf_size*8 - get_bits_count(&gb); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
382 c->bit_buffer = get_bits(&gb, c->bits_left); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
383 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
384 out: |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
385 *data_size = (uint8_t*)samples - (uint8_t*)data; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
386 return buf_size; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
387 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
388 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
389 #ifdef CONFIG_ENCODERS |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
390 AVCodec adpcm_g726_encoder = { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
391 "g726", |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
392 CODEC_TYPE_AUDIO, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
393 CODEC_ID_ADPCM_G726, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
394 sizeof(AVG726Context), |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
395 g726_init, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
396 g726_encode_frame, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
397 NULL, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
398 NULL, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
399 }; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
400 #endif //CONFIG_ENCODERS |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
401 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
402 AVCodec adpcm_g726_decoder = { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
403 "g726", |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
404 CODEC_TYPE_AUDIO, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
405 CODEC_ID_ADPCM_G726, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
406 sizeof(AVG726Context), |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
407 g726_init, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
408 NULL, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
409 NULL, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
410 g726_decode_frame, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
411 }; |