Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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