annotate g726.c @ 4166:eced83504436 libavcodec

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