react-native-tiny-wavpack-decoder 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +148 -0
- package/android/build.gradle +112 -0
- package/android/generated/java/com/tinywavpackdecoder/NativeTinyWavPackDecoderSpec.java +47 -0
- package/android/generated/jni/CMakeLists.txt +36 -0
- package/android/generated/jni/RNTinyWavPackDecoderSpec-generated.cpp +44 -0
- package/android/generated/jni/RNTinyWavPackDecoderSpec.h +31 -0
- package/android/generated/jni/react/renderer/components/RNTinyWavPackDecoderSpec/RNTinyWavPackDecoderSpecJSI-generated.cpp +46 -0
- package/android/generated/jni/react/renderer/components/RNTinyWavPackDecoderSpec/RNTinyWavPackDecoderSpecJSI.h +89 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/cpp/CMakeLists.txt +54 -0
- package/android/src/main/cpp/TinyWavPackDecoderModule.cpp +118 -0
- package/android/src/main/java/com/tinywavpackdecoder/TinyWavPackDecoderModule.kt +114 -0
- package/android/src/main/java/com/tinywavpackdecoder/TinyWavPackDecoderPackage.kt +18 -0
- package/ios/TinyWavPackDecoder.h +8 -0
- package/ios/TinyWavPackDecoder.mm +83 -0
- package/ios/generated/RNTinyWavPackDecoderSpec/RNTinyWavPackDecoderSpec-generated.mm +53 -0
- package/ios/generated/RNTinyWavPackDecoderSpec/RNTinyWavPackDecoderSpec.h +69 -0
- package/ios/generated/RNTinyWavPackDecoderSpecJSI-generated.cpp +46 -0
- package/ios/generated/RNTinyWavPackDecoderSpecJSI.h +89 -0
- package/lib/module/NativeTinyWavPackDecoder.ts +19 -0
- package/lib/module/index.js +38 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/tiny-wavpack/common/TinyWavPackDecoderInterface.c +414 -0
- package/lib/module/tiny-wavpack/common/TinyWavPackDecoderInterface.h +52 -0
- package/lib/module/tiny-wavpack/common/test.c +45 -0
- package/lib/module/tiny-wavpack/common/wv2wav +0 -0
- package/lib/module/tiny-wavpack/lib/bits.c +140 -0
- package/lib/module/tiny-wavpack/lib/float.c +50 -0
- package/lib/module/tiny-wavpack/lib/license.txt +25 -0
- package/lib/module/tiny-wavpack/lib/metadata.c +105 -0
- package/lib/module/tiny-wavpack/lib/readme.txt +68 -0
- package/lib/module/tiny-wavpack/lib/unpack.c +785 -0
- package/lib/module/tiny-wavpack/lib/wavpack.h +384 -0
- package/lib/module/tiny-wavpack/lib/words.c +560 -0
- package/lib/module/tiny-wavpack/lib/wputils.c +351 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeTinyWavPackDecoder.d.ts +9 -0
- package/lib/typescript/src/NativeTinyWavPackDecoder.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +18 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +195 -0
- package/react-native-wavpack-decoder.podspec +35 -0
- package/react-native.config.js +12 -0
- package/src/NativeTinyWavPackDecoder.ts +19 -0
- package/src/index.tsx +57 -0
- package/src/tiny-wavpack/common/TinyWavPackDecoderInterface.c +414 -0
- package/src/tiny-wavpack/common/TinyWavPackDecoderInterface.h +52 -0
- package/src/tiny-wavpack/common/test.c +45 -0
- package/src/tiny-wavpack/common/wv2wav +0 -0
- package/src/tiny-wavpack/lib/bits.c +140 -0
- package/src/tiny-wavpack/lib/float.c +50 -0
- package/src/tiny-wavpack/lib/license.txt +25 -0
- package/src/tiny-wavpack/lib/metadata.c +105 -0
- package/src/tiny-wavpack/lib/readme.txt +68 -0
- package/src/tiny-wavpack/lib/unpack.c +785 -0
- package/src/tiny-wavpack/lib/wavpack.h +384 -0
- package/src/tiny-wavpack/lib/words.c +560 -0
- package/src/tiny-wavpack/lib/wputils.c +351 -0
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// **** WAVPACK **** //
|
|
3
|
+
// Hybrid Lossless Wavefile Compressor //
|
|
4
|
+
// Copyright (c) 1998 - 2006 Conifer Software. //
|
|
5
|
+
// All Rights Reserved. //
|
|
6
|
+
// Distributed under the BSD Software License (see license.txt) //
|
|
7
|
+
////////////////////////////////////////////////////////////////////////////
|
|
8
|
+
|
|
9
|
+
// words.c
|
|
10
|
+
|
|
11
|
+
// This module provides entropy word encoding and decoding functions using
|
|
12
|
+
// a variation on the Rice method. This was introduced in version 3.93
|
|
13
|
+
// because it allows splitting the data into a "lossy" stream and a
|
|
14
|
+
// "correction" stream in a very efficient manner and is therefore ideal
|
|
15
|
+
// for the "hybrid" mode. For 4.0, the efficiency of this method was
|
|
16
|
+
// significantly improved by moving away from the normal Rice restriction of
|
|
17
|
+
// using powers of two for the modulus divisions and now the method can be
|
|
18
|
+
// used for both hybrid and pure lossless encoding.
|
|
19
|
+
|
|
20
|
+
// Samples are divided by median probabilities at 5/7 (71.43%), 10/49 (20.41%),
|
|
21
|
+
// and 20/343 (5.83%). Each zone has 3.5 times fewer samples than the
|
|
22
|
+
// previous. Using standard Rice coding on this data would result in 1.4
|
|
23
|
+
// bits per sample average (not counting sign bit). However, there is a
|
|
24
|
+
// very simple encoding that is over 99% efficient with this data and
|
|
25
|
+
// results in about 1.22 bits per sample.
|
|
26
|
+
|
|
27
|
+
#include "wavpack.h"
|
|
28
|
+
|
|
29
|
+
#include <string.h>
|
|
30
|
+
|
|
31
|
+
//////////////////////////////// local macros /////////////////////////////////
|
|
32
|
+
|
|
33
|
+
#define LIMIT_ONES 16 // maximum consecutive 1s sent for "div" data
|
|
34
|
+
|
|
35
|
+
// these control the time constant "slow_level" which is used for hybrid mode
|
|
36
|
+
// that controls bitrate as a function of residual level (HYBRID_BITRATE).
|
|
37
|
+
#define SLS 8
|
|
38
|
+
#define SLO ((1 << (SLS - 1)))
|
|
39
|
+
|
|
40
|
+
// these control the time constant of the 3 median level breakpoints
|
|
41
|
+
#define DIV0 128 // 5/7 of samples
|
|
42
|
+
#define DIV1 64 // 10/49 of samples
|
|
43
|
+
#define DIV2 32 // 20/343 of samples
|
|
44
|
+
|
|
45
|
+
// this macro retrieves the specified median breakpoint (without frac; min = 1)
|
|
46
|
+
#define GET_MED(med) (((c->median [med]) >> 4) + 1)
|
|
47
|
+
|
|
48
|
+
// These macros update the specified median breakpoints. Note that the median
|
|
49
|
+
// is incremented when the sample is higher than the median, else decremented.
|
|
50
|
+
// They are designed so that the median will never drop below 1 and the value
|
|
51
|
+
// is essentially stationary if there are 2 increments for every 5 decrements.
|
|
52
|
+
|
|
53
|
+
#define INC_MED0() (c->median [0] += ((c->median [0] + DIV0) / DIV0) * 5)
|
|
54
|
+
#define DEC_MED0() (c->median [0] -= ((c->median [0] + (DIV0-2)) / DIV0) * 2)
|
|
55
|
+
#define INC_MED1() (c->median [1] += ((c->median [1] + DIV1) / DIV1) * 5)
|
|
56
|
+
#define DEC_MED1() (c->median [1] -= ((c->median [1] + (DIV1-2)) / DIV1) * 2)
|
|
57
|
+
#define INC_MED2() (c->median [2] += ((c->median [2] + DIV2) / DIV2) * 5)
|
|
58
|
+
#define DEC_MED2() (c->median [2] -= ((c->median [2] + (DIV2-2)) / DIV2) * 2)
|
|
59
|
+
|
|
60
|
+
#define count_bits(av) ( \
|
|
61
|
+
(av) < (1 << 8) ? nbits_table [av] : \
|
|
62
|
+
( \
|
|
63
|
+
(av) < (1L << 16) ? nbits_table [(av) >> 8] + 8 : \
|
|
64
|
+
((av) < (1L << 24) ? nbits_table [(av) >> 16] + 16 : nbits_table [(av) >> 24] + 24) \
|
|
65
|
+
) \
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
///////////////////////////// local table storage ////////////////////////////
|
|
69
|
+
|
|
70
|
+
const char nbits_table [] = {
|
|
71
|
+
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, // 0 - 15
|
|
72
|
+
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 16 - 31
|
|
73
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 32 - 47
|
|
74
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 48 - 63
|
|
75
|
+
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 64 - 79
|
|
76
|
+
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 80 - 95
|
|
77
|
+
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 96 - 111
|
|
78
|
+
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 112 - 127
|
|
79
|
+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 128 - 143
|
|
80
|
+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 144 - 159
|
|
81
|
+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 160 - 175
|
|
82
|
+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 176 - 191
|
|
83
|
+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 192 - 207
|
|
84
|
+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 208 - 223
|
|
85
|
+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 224 - 239
|
|
86
|
+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 // 240 - 255
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
static const uchar log2_table [] = {
|
|
90
|
+
0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15,
|
|
91
|
+
0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a,
|
|
92
|
+
0x2c, 0x2d, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e,
|
|
93
|
+
0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
|
|
94
|
+
0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
|
|
95
|
+
0x64, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75,
|
|
96
|
+
0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85,
|
|
97
|
+
0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95,
|
|
98
|
+
0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4,
|
|
99
|
+
0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb2,
|
|
100
|
+
0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc0,
|
|
101
|
+
0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xce,
|
|
102
|
+
0xcf, 0xd0, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xdb,
|
|
103
|
+
0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe4, 0xe5, 0xe6, 0xe7, 0xe7,
|
|
104
|
+
0xe8, 0xe9, 0xea, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xee, 0xef, 0xf0, 0xf1, 0xf1, 0xf2, 0xf3, 0xf4,
|
|
105
|
+
0xf4, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0xff
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
static const uchar exp2_table [] = {
|
|
109
|
+
0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b,
|
|
110
|
+
0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16,
|
|
111
|
+
0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23,
|
|
112
|
+
0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
|
|
113
|
+
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d,
|
|
114
|
+
0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b,
|
|
115
|
+
0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
|
|
116
|
+
0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
|
|
117
|
+
0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
|
|
118
|
+
0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a,
|
|
119
|
+
0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
|
|
120
|
+
0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad,
|
|
121
|
+
0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
|
|
122
|
+
0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4,
|
|
123
|
+
0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9,
|
|
124
|
+
0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
static const char ones_count_table [] = {
|
|
128
|
+
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
|
|
129
|
+
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
|
|
130
|
+
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
|
|
131
|
+
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,
|
|
132
|
+
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
|
|
133
|
+
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
|
|
134
|
+
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
|
|
135
|
+
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
///////////////////////////// executable code ////////////////////////////////
|
|
139
|
+
|
|
140
|
+
void init_words (WavpackStream *wps)
|
|
141
|
+
{
|
|
142
|
+
CLEAR (wps->w);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
static int mylog2 (uint32_t avalue);
|
|
146
|
+
|
|
147
|
+
// Read the median log2 values from the specifed metadata structure, convert
|
|
148
|
+
// them back to 32-bit unsigned values and store them. If length is not
|
|
149
|
+
// exactly correct then we flag and return an error.
|
|
150
|
+
|
|
151
|
+
int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd)
|
|
152
|
+
{
|
|
153
|
+
uchar *byteptr = wpmd->data;
|
|
154
|
+
|
|
155
|
+
if (wpmd->byte_length != ((wps->wphdr.flags & MONO_DATA) ? 6 : 12))
|
|
156
|
+
return FALSE;
|
|
157
|
+
|
|
158
|
+
wps->w.c [0].median [0] = exp2s (byteptr [0] + (byteptr [1] << 8));
|
|
159
|
+
wps->w.c [0].median [1] = exp2s (byteptr [2] + (byteptr [3] << 8));
|
|
160
|
+
wps->w.c [0].median [2] = exp2s (byteptr [4] + (byteptr [5] << 8));
|
|
161
|
+
|
|
162
|
+
if (!(wps->wphdr.flags & MONO_DATA)) {
|
|
163
|
+
wps->w.c [1].median [0] = exp2s (byteptr [6] + (byteptr [7] << 8));
|
|
164
|
+
wps->w.c [1].median [1] = exp2s (byteptr [8] + (byteptr [9] << 8));
|
|
165
|
+
wps->w.c [1].median [2] = exp2s (byteptr [10] + (byteptr [11] << 8));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return TRUE;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Read the hybrid related values from the specifed metadata structure, convert
|
|
172
|
+
// them back to their internal formats and store them. The extended profile
|
|
173
|
+
// stuff is not implemented yet, so return an error if we get more data than
|
|
174
|
+
// we know what to do with.
|
|
175
|
+
|
|
176
|
+
int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd)
|
|
177
|
+
{
|
|
178
|
+
uchar *byteptr = wpmd->data;
|
|
179
|
+
uchar *endptr = byteptr + wpmd->byte_length;
|
|
180
|
+
|
|
181
|
+
if (wps->wphdr.flags & HYBRID_BITRATE) {
|
|
182
|
+
wps->w.c [0].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8));
|
|
183
|
+
byteptr += 2;
|
|
184
|
+
|
|
185
|
+
if (!(wps->wphdr.flags & MONO_DATA)) {
|
|
186
|
+
wps->w.c [1].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8));
|
|
187
|
+
byteptr += 2;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
wps->w.bitrate_acc [0] = (int32_t)(byteptr [0] + (byteptr [1] << 8)) << 16;
|
|
192
|
+
byteptr += 2;
|
|
193
|
+
|
|
194
|
+
if (!(wps->wphdr.flags & MONO_DATA)) {
|
|
195
|
+
wps->w.bitrate_acc [1] = (int32_t)(byteptr [0] + (byteptr [1] << 8)) << 16;
|
|
196
|
+
byteptr += 2;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (byteptr < endptr) {
|
|
200
|
+
wps->w.bitrate_delta [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
|
201
|
+
byteptr += 2;
|
|
202
|
+
|
|
203
|
+
if (!(wps->wphdr.flags & MONO_DATA)) {
|
|
204
|
+
wps->w.bitrate_delta [1] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
|
205
|
+
byteptr += 2;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (byteptr < endptr)
|
|
209
|
+
return FALSE;
|
|
210
|
+
}
|
|
211
|
+
else
|
|
212
|
+
wps->w.bitrate_delta [0] = wps->w.bitrate_delta [1] = 0;
|
|
213
|
+
|
|
214
|
+
return TRUE;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// This function is called during both encoding and decoding of hybrid data to
|
|
218
|
+
// update the "error_limit" variable which determines the maximum sample error
|
|
219
|
+
// allowed in the main bitstream. In the HYBRID_BITRATE mode (which is the only
|
|
220
|
+
// currently implemented) this is calculated from the slow_level values and the
|
|
221
|
+
// bitrate accumulators. Note that the bitrate accumulators can be changing.
|
|
222
|
+
|
|
223
|
+
void update_error_limit (struct words_data *w, uint32_t flags)
|
|
224
|
+
{
|
|
225
|
+
int bitrate_0 = (w->bitrate_acc [0] += w->bitrate_delta [0]) >> 16;
|
|
226
|
+
|
|
227
|
+
if (flags & MONO_DATA) {
|
|
228
|
+
if (flags & HYBRID_BITRATE) {
|
|
229
|
+
int slow_log_0 = (w->c [0].slow_level + SLO) >> SLS;
|
|
230
|
+
|
|
231
|
+
if (slow_log_0 - bitrate_0 > -0x100)
|
|
232
|
+
w->c [0].error_limit = exp2s (slow_log_0 - bitrate_0 + 0x100);
|
|
233
|
+
else
|
|
234
|
+
w->c [0].error_limit = 0;
|
|
235
|
+
}
|
|
236
|
+
else
|
|
237
|
+
w->c [0].error_limit = exp2s (bitrate_0);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
int bitrate_1 = (w->bitrate_acc [1] += w->bitrate_delta [1]) >> 16;
|
|
241
|
+
|
|
242
|
+
if (flags & HYBRID_BITRATE) {
|
|
243
|
+
int slow_log_0 = (w->c [0].slow_level + SLO) >> SLS;
|
|
244
|
+
int slow_log_1 = (w->c [1].slow_level + SLO) >> SLS;
|
|
245
|
+
|
|
246
|
+
if (flags & HYBRID_BALANCE) {
|
|
247
|
+
int balance = (slow_log_1 - slow_log_0 + bitrate_1 + 1) >> 1;
|
|
248
|
+
|
|
249
|
+
if (balance > bitrate_0) {
|
|
250
|
+
bitrate_1 = bitrate_0 * 2;
|
|
251
|
+
bitrate_0 = 0;
|
|
252
|
+
}
|
|
253
|
+
else if (-balance > bitrate_0) {
|
|
254
|
+
bitrate_0 = bitrate_0 * 2;
|
|
255
|
+
bitrate_1 = 0;
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
bitrate_1 = bitrate_0 + balance;
|
|
259
|
+
bitrate_0 = bitrate_0 - balance;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (slow_log_0 - bitrate_0 > -0x100)
|
|
264
|
+
w->c [0].error_limit = exp2s (slow_log_0 - bitrate_0 + 0x100);
|
|
265
|
+
else
|
|
266
|
+
w->c [0].error_limit = 0;
|
|
267
|
+
|
|
268
|
+
if (slow_log_1 - bitrate_1 > -0x100)
|
|
269
|
+
w->c [1].error_limit = exp2s (slow_log_1 - bitrate_1 + 0x100);
|
|
270
|
+
else
|
|
271
|
+
w->c [1].error_limit = 0;
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
w->c [0].error_limit = exp2s (bitrate_0);
|
|
275
|
+
w->c [1].error_limit = exp2s (bitrate_1);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
static uint32_t read_code (Bitstream *bs, uint32_t maxcode);
|
|
281
|
+
|
|
282
|
+
// Read the next word from the bitstream "wvbits" and return the value. This
|
|
283
|
+
// function can be used for hybrid or lossless streams, but since an
|
|
284
|
+
// optimized version is available for lossless this function would normally
|
|
285
|
+
// be used for hybrid only. If a hybrid lossless stream is being read then
|
|
286
|
+
// the "correction" offset is written at the specified pointer. A return value
|
|
287
|
+
// of WORD_EOF indicates that the end of the bitstream was reached (all 1s) or
|
|
288
|
+
// some other error occurred.
|
|
289
|
+
|
|
290
|
+
int32_t get_words (int32_t *buffer, int nsamples, uint32_t flags,
|
|
291
|
+
struct words_data *w, Bitstream *bs)
|
|
292
|
+
{
|
|
293
|
+
register struct entropy_data *c = w->c;
|
|
294
|
+
int csamples;
|
|
295
|
+
|
|
296
|
+
if (!(flags & MONO_DATA))
|
|
297
|
+
nsamples *= 2;
|
|
298
|
+
|
|
299
|
+
for (csamples = 0; csamples < nsamples; ++csamples) {
|
|
300
|
+
uint32_t ones_count, low, mid, high;
|
|
301
|
+
|
|
302
|
+
if (!(flags & MONO_DATA))
|
|
303
|
+
c = w->c + (csamples & 1);
|
|
304
|
+
|
|
305
|
+
if (!(w->c [0].median [0] & ~1) && !w->holding_zero && !w->holding_one && !(w->c [1].median [0] & ~1)) {
|
|
306
|
+
uint32_t mask;
|
|
307
|
+
int cbits;
|
|
308
|
+
|
|
309
|
+
if (w->zeros_acc) {
|
|
310
|
+
if (--w->zeros_acc) {
|
|
311
|
+
c->slow_level -= (c->slow_level + SLO) >> SLS;
|
|
312
|
+
*buffer++ = 0;
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
for (cbits = 0; cbits < 33 && getbit (bs); ++cbits);
|
|
318
|
+
|
|
319
|
+
if (cbits == 33)
|
|
320
|
+
break;
|
|
321
|
+
|
|
322
|
+
if (cbits < 2)
|
|
323
|
+
w->zeros_acc = cbits;
|
|
324
|
+
else {
|
|
325
|
+
for (mask = 1, w->zeros_acc = 0; --cbits; mask <<= 1)
|
|
326
|
+
if (getbit (bs))
|
|
327
|
+
w->zeros_acc |= mask;
|
|
328
|
+
|
|
329
|
+
w->zeros_acc |= mask;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (w->zeros_acc) {
|
|
333
|
+
c->slow_level -= (c->slow_level + SLO) >> SLS;
|
|
334
|
+
CLEAR (w->c [0].median);
|
|
335
|
+
CLEAR (w->c [1].median);
|
|
336
|
+
*buffer++ = 0;
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (w->holding_zero)
|
|
343
|
+
ones_count = w->holding_zero = 0;
|
|
344
|
+
else {
|
|
345
|
+
int next8;
|
|
346
|
+
|
|
347
|
+
if (bs->bc < 8) {
|
|
348
|
+
if (++(bs->ptr) == bs->end)
|
|
349
|
+
bs->wrap (bs);
|
|
350
|
+
|
|
351
|
+
next8 = (bs->sr |= *(bs->ptr) << bs->bc) & 0xff;
|
|
352
|
+
bs->bc += 8;
|
|
353
|
+
}
|
|
354
|
+
else
|
|
355
|
+
next8 = bs->sr & 0xff;
|
|
356
|
+
|
|
357
|
+
if (next8 == 0xff) {
|
|
358
|
+
bs->bc -= 8;
|
|
359
|
+
bs->sr >>= 8;
|
|
360
|
+
|
|
361
|
+
for (ones_count = 8; ones_count < (LIMIT_ONES + 1) && getbit (bs); ++ones_count);
|
|
362
|
+
|
|
363
|
+
if (ones_count == (LIMIT_ONES + 1))
|
|
364
|
+
break;
|
|
365
|
+
|
|
366
|
+
if (ones_count == LIMIT_ONES) {
|
|
367
|
+
uint32_t mask;
|
|
368
|
+
int cbits;
|
|
369
|
+
|
|
370
|
+
for (cbits = 0; cbits < 33 && getbit (bs); ++cbits);
|
|
371
|
+
|
|
372
|
+
if (cbits == 33)
|
|
373
|
+
break;
|
|
374
|
+
|
|
375
|
+
if (cbits < 2)
|
|
376
|
+
ones_count = cbits;
|
|
377
|
+
else {
|
|
378
|
+
for (mask = 1, ones_count = 0; --cbits; mask <<= 1)
|
|
379
|
+
if (getbit (bs))
|
|
380
|
+
ones_count |= mask;
|
|
381
|
+
|
|
382
|
+
ones_count |= mask;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
ones_count += LIMIT_ONES;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
bs->bc -= (ones_count = ones_count_table [next8]) + 1;
|
|
390
|
+
bs->sr >>= ones_count + 1;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (w->holding_one) {
|
|
394
|
+
w->holding_one = ones_count & 1;
|
|
395
|
+
ones_count = (ones_count >> 1) + 1;
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
w->holding_one = ones_count & 1;
|
|
399
|
+
ones_count >>= 1;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
w->holding_zero = ~w->holding_one & 1;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if ((flags & HYBRID_FLAG) && ((flags & MONO_DATA) || !(csamples & 1)))
|
|
406
|
+
update_error_limit (w, flags);
|
|
407
|
+
|
|
408
|
+
if (ones_count == 0) {
|
|
409
|
+
low = 0;
|
|
410
|
+
high = GET_MED (0) - 1;
|
|
411
|
+
DEC_MED0 ();
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
low = GET_MED (0);
|
|
415
|
+
INC_MED0 ();
|
|
416
|
+
|
|
417
|
+
if (ones_count == 1) {
|
|
418
|
+
high = low + GET_MED (1) - 1;
|
|
419
|
+
DEC_MED1 ();
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
low += GET_MED (1);
|
|
423
|
+
INC_MED1 ();
|
|
424
|
+
|
|
425
|
+
if (ones_count == 2) {
|
|
426
|
+
high = low + GET_MED (2) - 1;
|
|
427
|
+
DEC_MED2 ();
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
low += (ones_count - 2) * GET_MED (2);
|
|
431
|
+
high = low + GET_MED (2) - 1;
|
|
432
|
+
INC_MED2 ();
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
mid = (high + low + 1) >> 1;
|
|
438
|
+
|
|
439
|
+
if (!c->error_limit)
|
|
440
|
+
mid = read_code (bs, high - low) + low;
|
|
441
|
+
else while (high - low > c->error_limit) {
|
|
442
|
+
if (getbit (bs))
|
|
443
|
+
mid = (high + (low = mid) + 1) >> 1;
|
|
444
|
+
else
|
|
445
|
+
mid = ((high = mid - 1) + low + 1) >> 1;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
*buffer++ = getbit (bs) ? ~mid : mid;
|
|
449
|
+
|
|
450
|
+
if (flags & HYBRID_BITRATE)
|
|
451
|
+
c->slow_level = c->slow_level - ((c->slow_level + SLO) >> SLS) + mylog2 (mid);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
return (flags & MONO_DATA) ? csamples : (csamples / 2);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Read a single unsigned value from the specified bitstream with a value
|
|
458
|
+
// from 0 to maxcode. If there are exactly a power of two number of possible
|
|
459
|
+
// codes then this will read a fixed number of bits; otherwise it reads the
|
|
460
|
+
// minimum number of bits and then determines whether another bit is needed
|
|
461
|
+
// to define the code.
|
|
462
|
+
|
|
463
|
+
static uint32_t read_code (Bitstream *bs, uint32_t maxcode)
|
|
464
|
+
{
|
|
465
|
+
int bitcount = count_bits (maxcode);
|
|
466
|
+
uint32_t extras = (1L << bitcount) - maxcode - 1, code;
|
|
467
|
+
|
|
468
|
+
if (!bitcount)
|
|
469
|
+
return 0;
|
|
470
|
+
|
|
471
|
+
getbits (&code, bitcount - 1, bs);
|
|
472
|
+
code &= (1L << (bitcount - 1)) - 1;
|
|
473
|
+
|
|
474
|
+
if (code >= extras) {
|
|
475
|
+
code = (code << 1) - extras;
|
|
476
|
+
|
|
477
|
+
if (getbit (bs))
|
|
478
|
+
++code;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return code;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// The concept of a base 2 logarithm is used in many parts of WavPack. It is
|
|
485
|
+
// a way of sufficiently accurately representing 32-bit signed and unsigned
|
|
486
|
+
// values storing only 16 bits (actually fewer). It is also used in the hybrid
|
|
487
|
+
// mode for quickly comparing the relative magnitude of large values (i.e.
|
|
488
|
+
// division) and providing smooth exponentials using only addition.
|
|
489
|
+
|
|
490
|
+
// These are not strict logarithms in that they become linear around zero and
|
|
491
|
+
// can therefore represent both zero and negative values. They have 8 bits
|
|
492
|
+
// of precision and in "roundtrip" conversions the total error never exceeds 1
|
|
493
|
+
// part in 225 except for the cases of +/-115 and +/-195 (which error by 1).
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
// This function returns the log2 for the specified 32-bit unsigned value.
|
|
497
|
+
// The maximum value allowed is about 0xff800000 and returns 8447.
|
|
498
|
+
|
|
499
|
+
static int mylog2 (uint32_t avalue)
|
|
500
|
+
{
|
|
501
|
+
int dbits;
|
|
502
|
+
|
|
503
|
+
if ((avalue += avalue >> 9) < (1 << 8)) {
|
|
504
|
+
dbits = nbits_table [avalue];
|
|
505
|
+
return (dbits << 8) + log2_table [(avalue << (9 - dbits)) & 0xff];
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
if (avalue < (1L << 16))
|
|
509
|
+
dbits = nbits_table [avalue >> 8] + 8;
|
|
510
|
+
else if (avalue < (1L << 24))
|
|
511
|
+
dbits = nbits_table [avalue >> 16] + 16;
|
|
512
|
+
else
|
|
513
|
+
dbits = nbits_table [avalue >> 24] + 24;
|
|
514
|
+
|
|
515
|
+
return (dbits << 8) + log2_table [(avalue >> (dbits - 9)) & 0xff];
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// This function returns the log2 for the specified 32-bit signed value.
|
|
520
|
+
// All input values are valid and the return values are in the range of
|
|
521
|
+
// +/- 8192.
|
|
522
|
+
|
|
523
|
+
int log2s (int32_t value)
|
|
524
|
+
{
|
|
525
|
+
return (value < 0) ? -mylog2 (-value) : mylog2 (value);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// This function returns the original integer represented by the supplied
|
|
529
|
+
// logarithm (at least within the provided accuracy). The log is signed,
|
|
530
|
+
// but since a full 32-bit value is returned this can be used for unsigned
|
|
531
|
+
// conversions as well (i.e. the input range is -8192 to +8447).
|
|
532
|
+
|
|
533
|
+
int32_t exp2s (int log)
|
|
534
|
+
{
|
|
535
|
+
uint32_t value;
|
|
536
|
+
|
|
537
|
+
if (log < 0)
|
|
538
|
+
return -exp2s (-log);
|
|
539
|
+
|
|
540
|
+
value = exp2_table [log & 0xff] | 0x100;
|
|
541
|
+
|
|
542
|
+
if ((log >>= 8) <= 9)
|
|
543
|
+
return value >> (9 - log);
|
|
544
|
+
else
|
|
545
|
+
return value << (log - 9);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// These two functions convert internal weights (which are normally +/-1024)
|
|
549
|
+
// to and from an 8-bit signed character version for storage in metadata. The
|
|
550
|
+
// weights are clipped here in the case that they are outside that range.
|
|
551
|
+
|
|
552
|
+
int restore_weight (signed char weight)
|
|
553
|
+
{
|
|
554
|
+
int result;
|
|
555
|
+
|
|
556
|
+
if ((result = (int) weight << 3) > 0)
|
|
557
|
+
result += (result + 64) >> 7;
|
|
558
|
+
|
|
559
|
+
return result;
|
|
560
|
+
}
|