annotate g726.c @ 5775:38f220befc32 libavcodec

Replace "signed short" typecast with "int16_t" as suggested by Mans Rullgard. Value at the right side is 16 bit length signed. We can not know for sure that short is in fact 16 bits, even if this virtually always is the case.
author voroshil
date Thu, 04 Oct 2007 15:13:42 +0000
parents f99e40a7155b
children 9dd54c009d47
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
1 /*
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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"
2398
582e635cfa08 common.c -> bitstream.c (and the single non bitstream func -> utils.c)
michael
parents: 2135
diff changeset
26 #include "bitstream.h"
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
27
2135
9a481659d7cb make comments doxygen compatible
michael
parents: 1797
diff changeset
28 /**
9a481659d7cb make comments doxygen compatible
michael
parents: 1797
diff changeset
29 * G.726 11bit float.
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
30 * 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
31 * 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
32 * instead of simply using 32bit integer arithmetic.
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
33 */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
34 typedef struct Float11 {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
35 int sign; /**< 1bit sign */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
36 int exp; /**< 4bit exponent */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
37 int mant; /**< 6bit mantissa */
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
38 } Float11;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
39
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
40 static inline Float11* i2f(int16_t i, Float11* f)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
41 {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
42 f->sign = (i < 0);
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
43 if (f->sign)
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
44 i = -i;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
45 f->exp = av_log2_16bit(i) + !!i;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
46 f->mant = i? (i<<6) >> f->exp : 1<<5;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
47 return f;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
48 }
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 static inline int16_t mult(Float11* f1, Float11* f2)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
51 {
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
52 int res, exp;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
53
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
54 exp = f1->exp + f2->exp;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
55 res = (((f1->mant * f2->mant) + 0x30) >> 4) << 7;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
56 res = exp > 26 ? res << (exp - 26) : res >> (26 - exp);
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
57 return (f1->sign ^ f2->sign) ? -res : res;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
58 }
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 static inline int sgn(int value)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
61 {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
62 return (value < 0) ? -1 : 1;
1791
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
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
65 typedef struct G726Tables {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
66 int bits; /**< bits per sample */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
67 int* quant; /**< quantization table */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
68 int* iquant; /**< inverse quantization table */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
69 int* W; /**< special table #1 ;-) */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
70 int* F; /**< special table #2 */
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
71 } G726Tables;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
72
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
73 typedef struct G726Context {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
74 G726Tables* tbls; /**< static tables needed for computation */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
75
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
76 Float11 sr[2]; /**< prev. reconstructed samples */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
77 Float11 dq[6]; /**< prev. difference */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
78 int a[2]; /**< second order predictor coeffs */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
79 int b[6]; /**< sixth order predictor coeffs */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
80 int pk[2]; /**< signs of prev. 2 sez + dq */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
81
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
82 int ap; /**< scale factor control */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
83 int yu; /**< fast scale factor */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
84 int yl; /**< slow scale factor */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
85 int dms; /**< short average magnitude of F[i] */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
86 int dml; /**< long average magnitude of F[i] */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
87 int td; /**< tone detect */
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
88
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
89 int se; /**< estimated signal for the next iteration */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
90 int sez; /**< estimated second order prediction */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
91 int y; /**< quantizer scaling factor for the next iteration */
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
92 } G726Context;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
93
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
94 static int quant_tbl16[] = /**< 16kbit/s 2bits per sample */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
95 { 260, INT_MAX };
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
96 static int iquant_tbl16[] =
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
97 { 116, 365, 365, 116 };
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
98 static int W_tbl16[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
99 { -22, 439, 439, -22 };
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
100 static int F_tbl16[] =
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
101 { 0, 7, 7, 0 };
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
102
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
103 static int quant_tbl24[] = /**< 24kbit/s 3bits per sample */
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
104 { 7, 217, 330, INT_MAX };
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
105 static int iquant_tbl24[] =
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
106 { INT_MIN, 135, 273, 373, 373, 273, 135, INT_MIN };
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
107 static int W_tbl24[] =
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
108 { -4, 30, 137, 582, 582, 137, 30, -4 };
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
109 static int F_tbl24[] =
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
110 { 0, 1, 2, 7, 7, 2, 1, 0 };
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
111
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
112 static int quant_tbl32[] = /**< 32kbit/s 4bits per sample */
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
113 { -125, 79, 177, 245, 299, 348, 399, INT_MAX };
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
114 static int iquant_tbl32[] =
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
115 { INT_MIN, 4, 135, 213, 273, 323, 373, 425,
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
116 425, 373, 323, 273, 213, 135, 4, INT_MIN };
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
117 static int W_tbl32[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
118 { -12, 18, 41, 64, 112, 198, 355, 1122,
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
119 1122, 355, 198, 112, 64, 41, 18, -12};
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
120 static int F_tbl32[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
121 { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 };
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
122
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
123 static int quant_tbl40[] = /**< 40kbit/s 5bits per sample */
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
124 { -122, -16, 67, 138, 197, 249, 297, 338,
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
125 377, 412, 444, 474, 501, 527, 552, INT_MAX };
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
126 static int iquant_tbl40[] =
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
127 { INT_MIN, -66, 28, 104, 169, 224, 274, 318,
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
128 358, 395, 429, 459, 488, 514, 539, 566,
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
129 566, 539, 514, 488, 459, 429, 395, 358,
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
130 318, 274, 224, 169, 104, 28, -66, INT_MIN };
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
131 static int W_tbl40[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
132 { 14, 14, 24, 39, 40, 41, 58, 100,
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
133 141, 179, 219, 280, 358, 440, 529, 696,
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
134 696, 529, 440, 358, 280, 219, 179, 141,
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
135 100, 58, 41, 40, 39, 24, 14, 14 };
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
136 static int F_tbl40[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
137 { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6,
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
138 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
139
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
140 static G726Tables G726Tables_pool[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
141 {{ 2, quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 },
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
142 { 3, quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 },
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
143 { 4, quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 },
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
144 { 5, quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }};
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
145
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
146
2135
9a481659d7cb make comments doxygen compatible
michael
parents: 1797
diff changeset
147 /**
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
148 * Para 4.2.2 page 18: Adaptive quantizer.
1791
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 static inline uint8_t quant(G726Context* c, int d)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
151 {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
152 int sign, exp, i, dln;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
153
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
154 sign = i = 0;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
155 if (d < 0) {
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
156 sign = 1;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
157 d = -d;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
158 }
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
159 exp = av_log2_16bit(d);
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
160 dln = ((exp<<7) + (((d<<7)>>exp)&0x7f)) - (c->y>>2);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
161
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
162 while (c->tbls->quant[i] < INT_MAX && c->tbls->quant[i] < dln)
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
163 ++i;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
164
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
165 if (sign)
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
166 i = ~i;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
167 if (c->tbls->bits != 2 && i == 0) /* I'm not sure this is a good idea */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
168 i = 0xff;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
169
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
170 return i;
1791
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
2135
9a481659d7cb make comments doxygen compatible
michael
parents: 1797
diff changeset
173 /**
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
174 * Para 4.2.3 page 22: Inverse adaptive quantizer.
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 static inline int16_t inverse_quant(G726Context* c, int i)
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 int dql, dex, dqt;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
179
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
180 dql = c->tbls->iquant[i] + (c->y >> 2);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
181 dex = (dql>>7) & 0xf; /* 4bit exponent */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
182 dqt = (1<<7) + (dql & 0x7f); /* log2 -> linear */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
183 return (dql < 0) ? 0 : ((dqt<<7) >> (14-dex));
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
184 }
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 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
187 {
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
188 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
189 Float11 f;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
190
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
191 dq = inverse_quant(c, I);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
192 if (I >> (c->tbls->bits - 1)) /* get the sign */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
193 dq = -dq;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
194 re_signal = c->se + dq;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
195
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
196 /* Transition detect */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
197 ylint = (c->yl >> 15);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
198 ylfrac = (c->yl >> 10) & 0x1f;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
199 thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
200 if (c->td == 1 && abs(dq) > ((thr2+(thr2>>1))>>1))
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
201 tr = 1;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
202 else
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
203 tr = 0;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
204
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
205 /* Update second order predictor coefficient A2 and A1 */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
206 pk0 = (c->sez + dq) ? sgn(c->sez + dq) : 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
207 dq0 = dq ? sgn(dq) : 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
208 if (tr) {
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
209 c->a[0] = 0;
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
210 c->a[1] = 0;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
211 for (i=0; i<6; i++)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
212 c->b[i] = 0;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
213 } else {
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
214 /* This is a bit crazy, but it really is +255 not +256 */
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4520
diff changeset
215 fa1 = av_clip((-c->a[0]*c->pk[0]*pk0)>>5, -256, 255);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
216
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
217 c->a[1] += 128*pk0*c->pk[1] + fa1 - (c->a[1]>>7);
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4520
diff changeset
218 c->a[1] = av_clip(c->a[1], -12288, 12288);
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
219 c->a[0] += 64*3*pk0*c->pk[0] - (c->a[0] >> 8);
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4520
diff changeset
220 c->a[0] = av_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
221
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
222 for (i=0; i<6; i++)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
223 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
224 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
225
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
226 /* Update Dq and Sr and Pk */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
227 c->pk[1] = c->pk[0];
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
228 c->pk[0] = pk0 ? pk0 : 1;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
229 c->sr[1] = c->sr[0];
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
230 i2f(re_signal, &c->sr[0]);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
231 for (i=5; i>0; i--)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
232 c->dq[i] = c->dq[i-1];
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
233 i2f(dq, &c->dq[0]);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
234 c->dq[0].sign = I >> (c->tbls->bits - 1); /* Isn't it crazy ?!?! */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
235
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
236 /* Update tone detect [I'm not sure 'tr == 0' is really needed] */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
237 c->td = (tr == 0 && c->a[1] < -11776);
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
238
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
239 /* Update Ap */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
240 c->dms += ((c->tbls->F[I]<<9) - c->dms) >> 5;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
241 c->dml += ((c->tbls->F[I]<<11) - c->dml) >> 7;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
242 if (tr)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
243 c->ap = 256;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
244 else if (c->y > 1535 && !c->td && (abs((c->dms << 2) - c->dml) < (c->dml >> 3)))
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
245 c->ap += (-c->ap) >> 4;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
246 else
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
247 c->ap += (0x200 - c->ap) >> 4;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
248
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
249 /* Update Yu and Yl */
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4520
diff changeset
250 c->yu = av_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
251 c->yl += c->yu + ((-c->yl)>>6);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
252
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
253 /* Next iteration for Y */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
254 al = (c->ap >= 256) ? 1<<6 : c->ap >> 2;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
255 c->y = (c->yl + (c->yu - (c->yl>>6))*al) >> 6;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
256
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
257 /* Next iteration for SE and SEZ */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
258 c->se = 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
259 for (i=0; i<6; i++)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
260 c->se += mult(i2f(c->b[i] >> 2, &f), &c->dq[i]);
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
261 c->sez = c->se >> 1;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
262 for (i=0; i<2; i++)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
263 c->se += mult(i2f(c->a[i] >> 2, &f), &c->sr[i]);
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
264 c->se >>= 1;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
265
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4520
diff changeset
266 return av_clip(re_signal << 2, -0xffff, 0xffff);
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
267 }
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 static int g726_reset(G726Context* c, int bit_rate)
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 int i;
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 c->tbls = &G726Tables_pool[bit_rate/8000 - 2];
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
274 for (i=0; i<2; i++) {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
275 i2f(0, &c->sr[i]);
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
276 c->a[i] = 0;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
277 c->pk[i] = 1;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
278 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
279 for (i=0; i<6; i++) {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
280 i2f(0, &c->dq[i]);
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
281 c->b[i] = 0;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
282 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
283 c->ap = 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
284 c->dms = 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
285 c->dml = 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
286 c->yu = 544;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
287 c->yl = 34816;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
288 c->td = 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
289
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
290 c->se = 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
291 c->sez = 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
292 c->y = 544;
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 return 0;
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
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
297 static int16_t g726_decode(G726Context* c, int16_t 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 return g726_iterate(c, 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
3777
20545fbb6f7c add some #ifdef CONFIG_ENCODERS/DECODERS
mru
parents: 3036
diff changeset
302 #ifdef CONFIG_ENCODERS
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
303 static int16_t g726_encode(G726Context* c, int16_t sig)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
304 {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
305 uint8_t i;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
306
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
307 i = quant(c, sig/4 - c->se) & ((1<<c->tbls->bits) - 1);
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
308 g726_iterate(c, i);
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
309 return i;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
310 }
3777
20545fbb6f7c add some #ifdef CONFIG_ENCODERS/DECODERS
mru
parents: 3036
diff changeset
311 #endif
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
312
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
313 /* Interfacing to the libavcodec */
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 typedef struct AVG726Context {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
316 G726Context c;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
317 int bits_left;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
318 int bit_buffer;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
319 int code_size;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
320 } AVG726Context;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
321
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
322 static int g726_init(AVCodecContext * avctx)
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 AVG726Context* c = (AVG726Context*)avctx->priv_data;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
325
1792
7da4bdafe42e use clip() from common.h
michael
parents: 1791
diff changeset
326 if (avctx->channels != 1 ||
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
327 (avctx->bit_rate != 16000 && avctx->bit_rate != 24000 &&
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
328 avctx->bit_rate != 32000 && avctx->bit_rate != 40000)) {
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
329 av_log(avctx, AV_LOG_ERROR, "G726: unsupported audio format\n");
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
330 return -1;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
331 }
2658
d1609cfeb1d0 #defines for strict_std_compliance and split between inofficial extensions and non standarized things
michael
parents: 2398
diff changeset
332 if (avctx->sample_rate != 8000 && avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL) {
1792
7da4bdafe42e use clip() from common.h
michael
parents: 1791
diff changeset
333 av_log(avctx, AV_LOG_ERROR, "G726: unsupported audio format\n");
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
334 return -1;
1792
7da4bdafe42e use clip() from common.h
michael
parents: 1791
diff changeset
335 }
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
336 g726_reset(&c->c, avctx->bit_rate);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
337 c->code_size = c->c.tbls->bits;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
338 c->bit_buffer = 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
339 c->bits_left = 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
340
1797
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
341 avctx->coded_frame = avcodec_alloc_frame();
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
342 if (!avctx->coded_frame)
4520
9bf957e669f0 This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents: 4119
diff changeset
343 return AVERROR(ENOMEM);
1797
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
344 avctx->coded_frame->key_frame = 1;
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
345
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
346 return 0;
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
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
349 static int g726_close(AVCodecContext *avctx)
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 av_freep(&avctx->coded_frame);
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
352 return 0;
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
3777
20545fbb6f7c add some #ifdef CONFIG_ENCODERS/DECODERS
mru
parents: 3036
diff changeset
355 #ifdef CONFIG_ENCODERS
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
356 static int g726_encode_frame(AVCodecContext *avctx,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
357 uint8_t *dst, int buf_size, void *data)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
358 {
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
359 AVG726Context *c = avctx->priv_data;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
360 short *samples = data;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
361 PutBitContext pb;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
362
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
363 init_put_bits(&pb, dst, 1024*1024);
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 for (; buf_size; buf_size--)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
366 put_bits(&pb, c->code_size, g726_encode(&c->c, *samples++));
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
367
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
368 flush_put_bits(&pb);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
369
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
370 return put_bits_count(&pb)>>3;
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
371 }
3777
20545fbb6f7c add some #ifdef CONFIG_ENCODERS/DECODERS
mru
parents: 3036
diff changeset
372 #endif
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
373
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
374 static int g726_decode_frame(AVCodecContext *avctx,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
375 void *data, int *data_size,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
376 uint8_t *buf, int buf_size)
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 AVG726Context *c = avctx->priv_data;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
379 short *samples = data;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
380 uint8_t code;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
381 uint8_t mask;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
382 GetBitContext gb;
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
383
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
384 if (!buf_size)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
385 goto out;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
386
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
387 mask = (1<<c->code_size) - 1;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
388 init_get_bits(&gb, buf, buf_size * 8);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
389 if (c->bits_left) {
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
390 int s = c->code_size - c->bits_left;;
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
391 code = (c->bit_buffer << s) | get_bits(&gb, s);
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
392 *samples++ = g726_decode(&c->c, code & mask);
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
393 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
394
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
395 while (get_bits_count(&gb) + c->code_size <= buf_size*8)
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
396 *samples++ = g726_decode(&c->c, get_bits(&gb, c->code_size) & mask);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
397
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
398 c->bits_left = buf_size*8 - get_bits_count(&gb);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
399 c->bit_buffer = get_bits(&gb, c->bits_left);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
400
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
401 out:
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
402 *data_size = (uint8_t*)samples - (uint8_t*)data;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
403 return buf_size;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
404 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
405
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
406 #ifdef CONFIG_ENCODERS
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
407 AVCodec adpcm_g726_encoder = {
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
408 "g726",
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
409 CODEC_TYPE_AUDIO,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
410 CODEC_ID_ADPCM_G726,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
411 sizeof(AVG726Context),
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
412 g726_init,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
413 g726_encode_frame,
1797
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
414 g726_close,
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
415 NULL,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
416 };
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
417 #endif //CONFIG_ENCODERS
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 AVCodec adpcm_g726_decoder = {
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
420 "g726",
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
421 CODEC_TYPE_AUDIO,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
422 CODEC_ID_ADPCM_G726,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
423 sizeof(AVG726Context),
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
424 g726_init,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
425 NULL,
1797
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
426 g726_close,
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
427 g726_decode_frame,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
428 };