]> git.sesse.net Git - ffmpeg/blob - libavcodec/wavpack.h
Merge commit '310cc4bf82824f09bdd0b9147ed725cdbeaf9bdd'
[ffmpeg] / libavcodec / wavpack.h
1 /*
2  * WavPack decoder/encoder common code
3  * Copyright (c) 2006,2011 Konstantin Shishkov
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #ifndef AVCODEC_WAVPACK_H
23 #define AVCODEC_WAVPACK_H
24
25 #define MAX_TERMS      16
26 #define MAX_TERM        8
27
28 #define WV_HEADER_SIZE    32
29
30 #define WV_MONO           0x00000004
31 #define WV_JOINT_STEREO   0x00000010
32 #define WV_CROSS_DECORR   0x00000020
33 #define WV_FLOAT_DATA     0x00000080
34 #define WV_INT32_DATA     0x00000100
35 #define WV_FALSE_STEREO   0x40000000
36
37 #define WV_HYBRID_MODE    0x00000008
38 #define WV_HYBRID_SHAPE   0x00000008
39 #define WV_HYBRID_BITRATE 0x00000200
40 #define WV_HYBRID_BALANCE 0x00000400
41 #define WV_INITIAL_BLOCK  0x00000800
42 #define WV_FINAL_BLOCK    0x00001000
43
44 #define WV_MONO_DATA    (WV_MONO | WV_FALSE_STEREO)
45
46 #define WV_SINGLE_BLOCK (WV_INITIAL_BLOCK | WV_FINAL_BLOCK)
47
48 #define WV_FLT_SHIFT_ONES 0x01
49 #define WV_FLT_SHIFT_SAME 0x02
50 #define WV_FLT_SHIFT_SENT 0x04
51 #define WV_FLT_ZERO_SENT  0x08
52 #define WV_FLT_ZERO_SIGN  0x10
53
54 #define WV_MAX_SAMPLES    131072
55
56 enum WP_ID_Flags {
57     WP_IDF_MASK   = 0x3F,
58     WP_IDF_IGNORE = 0x20,
59     WP_IDF_ODD    = 0x40,
60     WP_IDF_LONG   = 0x80
61 };
62
63 enum WP_ID {
64     WP_ID_DUMMY = 0,
65     WP_ID_ENCINFO,
66     WP_ID_DECTERMS,
67     WP_ID_DECWEIGHTS,
68     WP_ID_DECSAMPLES,
69     WP_ID_ENTROPY,
70     WP_ID_HYBRID,
71     WP_ID_SHAPING,
72     WP_ID_FLOATINFO,
73     WP_ID_INT32INFO,
74     WP_ID_DATA,
75     WP_ID_CORR,
76     WP_ID_EXTRABITS,
77     WP_ID_CHANINFO,
78     WP_ID_SAMPLE_RATE = 0x27,
79 };
80
81 typedef struct Decorr {
82     int delta;
83     int value;
84     int weightA;
85     int weightB;
86     int samplesA[MAX_TERM];
87     int samplesB[MAX_TERM];
88     int sumA;
89     int sumB;
90 } Decorr;
91
92 typedef struct WvChannel {
93     int median[3];
94     int slow_level, error_limit;
95     int bitrate_acc, bitrate_delta;
96 } WvChannel;
97
98 // macros for manipulating median values
99 #define GET_MED(n) ((c->median[n] >> 4) + 1)
100 #define DEC_MED(n) c->median[n] -= ((c->median[n] + (128 >> n) - 2) / (128 >> n)) * 2
101 #define INC_MED(n) c->median[n] += ((c->median[n] + (128 >> n)    ) / (128 >> n)) * 5
102
103 // macros for applying weight
104 #define UPDATE_WEIGHT_CLIP(weight, delta, samples, in) \
105     if (samples && in) { \
106         if ((samples ^ in) < 0) { \
107             weight -= delta; \
108             if (weight < -1024) \
109                 weight = -1024; \
110         } else { \
111             weight += delta; \
112             if (weight > 1024) \
113                 weight = 1024; \
114         } \
115     }
116
117 static const int wv_rates[16] = {
118      6000,  8000,  9600, 11025, 12000, 16000,  22050, 24000,
119     32000, 44100, 48000, 64000, 88200, 96000, 192000,     0
120 };
121
122 // exponent table copied from WavPack source
123 static const uint8_t wp_exp2_table[256] = {
124     0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b,
125     0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16,
126     0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23,
127     0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
128     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d,
129     0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b,
130     0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
131     0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
132     0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
133     0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a,
134     0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
135     0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad,
136     0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
137     0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4,
138     0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9,
139     0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff
140 };
141
142 static const uint8_t wp_log2_table [] = {
143     0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15,
144     0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a,
145     0x2c, 0x2d, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e,
146     0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
147     0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
148     0x64, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75,
149     0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85,
150     0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95,
151     0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4,
152     0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb2,
153     0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc0,
154     0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xce,
155     0xcf, 0xd0, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xdb,
156     0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe4, 0xe5, 0xe6, 0xe7, 0xe7,
157     0xe8, 0xe9, 0xea, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xee, 0xef, 0xf0, 0xf1, 0xf1, 0xf2, 0xf3, 0xf4,
158     0xf4, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0xff
159 };
160
161 static av_always_inline int wp_exp2(int16_t val)
162 {
163     int res, neg = 0;
164
165     if (val < 0) {
166         val = -val;
167         neg = 1;
168     }
169
170     res   = wp_exp2_table[val & 0xFF] | 0x100;
171     val >>= 8;
172     res   = (val > 9) ? (res << (val - 9)) : (res >> (9 - val));
173     return neg ? -res : res;
174 }
175
176 static av_always_inline int wp_log2(int32_t val)
177 {
178     int bits;
179
180     if (!val)
181         return 0;
182     if (val == 1)
183         return 256;
184     val += val >> 9;
185     bits = av_log2(val) + 1;
186     if (bits < 9)
187         return (bits << 8) + wp_log2_table[(val << (9 - bits)) & 0xFF];
188     else
189         return (bits << 8) + wp_log2_table[(val >> (bits - 9)) & 0xFF];
190 }
191
192 #endif /* AVCODEC_WAVPACK_H */