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,785 @@
|
|
|
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
|
+
// unpack.c
|
|
10
|
+
|
|
11
|
+
// This module actually handles the decompression of the audio data, except
|
|
12
|
+
// for the entropy decoding which is handled by the words.c module. For
|
|
13
|
+
// maximum efficiency, the conversion is isolated to tight loops that handle
|
|
14
|
+
// an entire buffer.
|
|
15
|
+
|
|
16
|
+
#include "wavpack.h"
|
|
17
|
+
|
|
18
|
+
#include <stdlib.h>
|
|
19
|
+
#include <string.h>
|
|
20
|
+
|
|
21
|
+
#define LOSSY_MUTE
|
|
22
|
+
|
|
23
|
+
///////////////////////////// executable code ////////////////////////////////
|
|
24
|
+
|
|
25
|
+
// This function initializes everything required to unpack a WavPack block
|
|
26
|
+
// and must be called before unpack_samples() is called to obtain audio data.
|
|
27
|
+
// It is assumed that the WavpackHeader has been read into the wps->wphdr
|
|
28
|
+
// (in the current WavpackStream). This is where all the metadata blocks are
|
|
29
|
+
// scanned up to the one containing the audio bitstream.
|
|
30
|
+
|
|
31
|
+
int unpack_init (WavpackContext *wpc)
|
|
32
|
+
{
|
|
33
|
+
WavpackStream *wps = &wpc->stream;
|
|
34
|
+
WavpackMetadata wpmd;
|
|
35
|
+
|
|
36
|
+
if (wps->wphdr.block_samples && wps->wphdr.block_index != (uint32_t) -1)
|
|
37
|
+
wps->sample_index = wps->wphdr.block_index;
|
|
38
|
+
|
|
39
|
+
wps->mute_error = FALSE;
|
|
40
|
+
wps->crc = 0xffffffff;
|
|
41
|
+
CLEAR (wps->wvbits);
|
|
42
|
+
CLEAR (wps->decorr_passes);
|
|
43
|
+
CLEAR (wps->w);
|
|
44
|
+
|
|
45
|
+
while (read_metadata_buff (wpc, &wpmd)) {
|
|
46
|
+
if (!process_metadata (wpc, &wpmd)) {
|
|
47
|
+
strcpy (wpc->error_message, "invalid metadata!");
|
|
48
|
+
return FALSE;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (wpmd.id == ID_WV_BITSTREAM)
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (wps->wphdr.block_samples && !bs_is_open (&wps->wvbits)) {
|
|
56
|
+
strcpy (wpc->error_message, "invalid WavPack file!");
|
|
57
|
+
return FALSE;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (wps->wphdr.block_samples) {
|
|
61
|
+
if ((wps->wphdr.flags & INT32_DATA) && wps->int32_sent_bits)
|
|
62
|
+
wpc->lossy_blocks = TRUE;
|
|
63
|
+
|
|
64
|
+
if ((wps->wphdr.flags & FLOAT_DATA) &&
|
|
65
|
+
wps->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT | FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME))
|
|
66
|
+
wpc->lossy_blocks = TRUE;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return TRUE;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// This function initialzes the main bitstream for audio samples, which must
|
|
73
|
+
// be in the "wv" file.
|
|
74
|
+
|
|
75
|
+
int init_wv_bitstream (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|
76
|
+
{
|
|
77
|
+
WavpackStream *wps = &wpc->stream;
|
|
78
|
+
|
|
79
|
+
if (wpmd->data)
|
|
80
|
+
bs_open_read (&wps->wvbits, wpmd->data, (unsigned char *) wpmd->data + wpmd->byte_length, NULL, 0);
|
|
81
|
+
else if (wpmd->byte_length)
|
|
82
|
+
bs_open_read (&wps->wvbits, wpc->read_buffer, wpc->read_buffer + sizeof (wpc->read_buffer),
|
|
83
|
+
wpc->infile, wpmd->byte_length + (wpmd->byte_length & 1));
|
|
84
|
+
|
|
85
|
+
return TRUE;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Read decorrelation terms from specified metadata block into the
|
|
89
|
+
// decorr_passes array. The terms range from -3 to 8, plus 17 & 18;
|
|
90
|
+
// other values are reserved and generate errors for now. The delta
|
|
91
|
+
// ranges from 0 to 7 with all values valid. Note that the terms are
|
|
92
|
+
// stored in the opposite order in the decorr_passes array compared
|
|
93
|
+
// to packing.
|
|
94
|
+
|
|
95
|
+
int read_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd)
|
|
96
|
+
{
|
|
97
|
+
int termcnt = wpmd->byte_length;
|
|
98
|
+
uchar *byteptr = wpmd->data;
|
|
99
|
+
struct decorr_pass *dpp;
|
|
100
|
+
|
|
101
|
+
if (termcnt > MAX_NTERMS)
|
|
102
|
+
return FALSE;
|
|
103
|
+
|
|
104
|
+
wps->num_terms = termcnt;
|
|
105
|
+
|
|
106
|
+
for (dpp = wps->decorr_passes + termcnt - 1; termcnt--; dpp--) {
|
|
107
|
+
dpp->term = (int)(*byteptr & 0x1f) - 5;
|
|
108
|
+
dpp->delta = (*byteptr++ >> 5) & 0x7;
|
|
109
|
+
|
|
110
|
+
if (!dpp->term || dpp->term < -3 || (dpp->term > MAX_TERM && dpp->term < 17) || dpp->term > 18)
|
|
111
|
+
return FALSE;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return TRUE;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Read decorrelation weights from specified metadata block into the
|
|
118
|
+
// decorr_passes array. The weights range +/-1024, but are rounded and
|
|
119
|
+
// truncated to fit in signed chars for metadata storage. Weights are
|
|
120
|
+
// separate for the two channels and are specified from the "last" term
|
|
121
|
+
// (first during encode). Unspecified weights are set to zero.
|
|
122
|
+
|
|
123
|
+
int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd)
|
|
124
|
+
{
|
|
125
|
+
int termcnt = wpmd->byte_length, tcount;
|
|
126
|
+
signed char *byteptr = wpmd->data;
|
|
127
|
+
struct decorr_pass *dpp;
|
|
128
|
+
|
|
129
|
+
if (!(wps->wphdr.flags & MONO_DATA))
|
|
130
|
+
termcnt /= 2;
|
|
131
|
+
|
|
132
|
+
if (termcnt > wps->num_terms)
|
|
133
|
+
return FALSE;
|
|
134
|
+
|
|
135
|
+
for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
|
|
136
|
+
dpp->weight_A = dpp->weight_B = 0;
|
|
137
|
+
|
|
138
|
+
while (--dpp >= wps->decorr_passes && termcnt--) {
|
|
139
|
+
dpp->weight_A = restore_weight (*byteptr++);
|
|
140
|
+
|
|
141
|
+
if (!(wps->wphdr.flags & MONO_DATA))
|
|
142
|
+
dpp->weight_B = restore_weight (*byteptr++);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return TRUE;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Read decorrelation samples from specified metadata block into the
|
|
149
|
+
// decorr_passes array. The samples are signed 32-bit values, but are
|
|
150
|
+
// converted to signed log2 values for storage in metadata. Values are
|
|
151
|
+
// stored for both channels and are specified from the "last" term
|
|
152
|
+
// (first during encode) with unspecified samples set to zero. The
|
|
153
|
+
// number of samples stored varies with the actual term value, so
|
|
154
|
+
// those must obviously come first in the metadata.
|
|
155
|
+
|
|
156
|
+
int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd)
|
|
157
|
+
{
|
|
158
|
+
uchar *byteptr = wpmd->data;
|
|
159
|
+
uchar *endptr = byteptr + wpmd->byte_length;
|
|
160
|
+
struct decorr_pass *dpp;
|
|
161
|
+
int tcount;
|
|
162
|
+
|
|
163
|
+
for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) {
|
|
164
|
+
CLEAR (dpp->samples_A);
|
|
165
|
+
CLEAR (dpp->samples_B);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (wps->wphdr.version == 0x402 && (wps->wphdr.flags & HYBRID_FLAG)) {
|
|
169
|
+
byteptr += 2;
|
|
170
|
+
|
|
171
|
+
if (!(wps->wphdr.flags & MONO_DATA))
|
|
172
|
+
byteptr += 2;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
while (dpp-- > wps->decorr_passes && byteptr < endptr)
|
|
176
|
+
if (dpp->term > MAX_TERM) {
|
|
177
|
+
dpp->samples_A [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
|
178
|
+
dpp->samples_A [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
|
|
179
|
+
byteptr += 4;
|
|
180
|
+
|
|
181
|
+
if (!(wps->wphdr.flags & MONO_DATA)) {
|
|
182
|
+
dpp->samples_B [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
|
183
|
+
dpp->samples_B [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
|
|
184
|
+
byteptr += 4;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else if (dpp->term < 0) {
|
|
188
|
+
dpp->samples_A [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
|
189
|
+
dpp->samples_B [0] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
|
|
190
|
+
byteptr += 4;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
int m = 0, cnt = dpp->term;
|
|
194
|
+
|
|
195
|
+
while (cnt--) {
|
|
196
|
+
dpp->samples_A [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
|
197
|
+
byteptr += 2;
|
|
198
|
+
|
|
199
|
+
if (!(wps->wphdr.flags & MONO_DATA)) {
|
|
200
|
+
dpp->samples_B [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
|
201
|
+
byteptr += 2;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
m++;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return byteptr == endptr;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Read the int32 data from the specified metadata into the specified stream.
|
|
212
|
+
// This data is used for integer data that has more than 24 bits of magnitude
|
|
213
|
+
// or, in some cases, used to eliminate redundant bits from any audio stream.
|
|
214
|
+
|
|
215
|
+
int read_int32_info (WavpackStream *wps, WavpackMetadata *wpmd)
|
|
216
|
+
{
|
|
217
|
+
int bytecnt = wpmd->byte_length;
|
|
218
|
+
char *byteptr = wpmd->data;
|
|
219
|
+
|
|
220
|
+
if (bytecnt != 4)
|
|
221
|
+
return FALSE;
|
|
222
|
+
|
|
223
|
+
wps->int32_sent_bits = *byteptr++;
|
|
224
|
+
wps->int32_zeros = *byteptr++;
|
|
225
|
+
wps->int32_ones = *byteptr++;
|
|
226
|
+
wps->int32_dups = *byteptr;
|
|
227
|
+
return TRUE;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Read multichannel information from metadata. The first byte is the total
|
|
231
|
+
// number of channels and the following bytes represent the channel_mask
|
|
232
|
+
// as described for Microsoft WAVEFORMATEX.
|
|
233
|
+
|
|
234
|
+
int read_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|
235
|
+
{
|
|
236
|
+
int bytecnt = wpmd->byte_length, shift = 0;
|
|
237
|
+
char *byteptr = wpmd->data;
|
|
238
|
+
uint32_t mask = 0;
|
|
239
|
+
|
|
240
|
+
if (!bytecnt || bytecnt > 5)
|
|
241
|
+
return FALSE;
|
|
242
|
+
|
|
243
|
+
wpc->config.num_channels = *byteptr++;
|
|
244
|
+
|
|
245
|
+
while (--bytecnt) {
|
|
246
|
+
mask |= (uint32_t) *byteptr++ << shift;
|
|
247
|
+
shift += 8;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
wpc->config.channel_mask = mask;
|
|
251
|
+
return TRUE;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Read configuration information from metadata.
|
|
255
|
+
|
|
256
|
+
int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|
257
|
+
{
|
|
258
|
+
int bytecnt = wpmd->byte_length;
|
|
259
|
+
uchar *byteptr = wpmd->data;
|
|
260
|
+
|
|
261
|
+
if (bytecnt >= 3) {
|
|
262
|
+
wpc->config.flags &= 0xff;
|
|
263
|
+
wpc->config.flags |= (int32_t) *byteptr++ << 8;
|
|
264
|
+
wpc->config.flags |= (int32_t) *byteptr++ << 16;
|
|
265
|
+
wpc->config.flags |= (int32_t) *byteptr << 24;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return TRUE;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// This monster actually unpacks the WavPack bitstream(s) into the specified
|
|
272
|
+
// buffer as 32-bit integers or floats (depending on orignal data). Lossy
|
|
273
|
+
// samples will be clipped to their original limits (i.e. 8-bit samples are
|
|
274
|
+
// clipped to -128/+127) but are still returned in int32_ts. It is up to the
|
|
275
|
+
// caller to potentially reformat this for the final output including any
|
|
276
|
+
// multichannel distribution, block alignment or endian compensation. The
|
|
277
|
+
// function unpack_init() must have been called and the entire WavPack block
|
|
278
|
+
// must still be visible (although wps->blockbuff will not be accessed again).
|
|
279
|
+
// For maximum clarity, the function is broken up into segments that handle
|
|
280
|
+
// various modes. This makes for a few extra infrequent flag checks, but
|
|
281
|
+
// makes the code easier to follow because the nesting does not become so
|
|
282
|
+
// deep. For maximum efficiency, the conversion is isolated to tight loops
|
|
283
|
+
// that handle an entire buffer. The function returns the total number of
|
|
284
|
+
// samples unpacked, which can be less than the number requested if an error
|
|
285
|
+
// occurs or the end of the block is reached.
|
|
286
|
+
|
|
287
|
+
#if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
|
|
288
|
+
extern void decorr_stereo_pass_cont_mcf5249 (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count);
|
|
289
|
+
#elif defined(CPU_ARM) && !defined(SIMULATOR)
|
|
290
|
+
extern void decorr_stereo_pass_cont_arm (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count);
|
|
291
|
+
extern void decorr_stereo_pass_cont_arml (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count);
|
|
292
|
+
#else
|
|
293
|
+
static void decorr_stereo_pass_cont (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count);
|
|
294
|
+
#endif
|
|
295
|
+
|
|
296
|
+
static void decorr_mono_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count);
|
|
297
|
+
static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count);
|
|
298
|
+
static void fixup_samples (WavpackStream *wps, int32_t *buffer, uint32_t sample_count);
|
|
299
|
+
|
|
300
|
+
int32_t unpack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count)
|
|
301
|
+
{
|
|
302
|
+
WavpackStream *wps = &wpc->stream;
|
|
303
|
+
uint32_t flags = wps->wphdr.flags, crc = wps->crc, i;
|
|
304
|
+
int32_t mute_limit = (1L << ((flags & MAG_MASK) >> MAG_LSB)) + 2;
|
|
305
|
+
struct decorr_pass *dpp;
|
|
306
|
+
int32_t *bptr, *eptr;
|
|
307
|
+
int tcount;
|
|
308
|
+
|
|
309
|
+
if (wps->sample_index + sample_count > wps->wphdr.block_index + wps->wphdr.block_samples)
|
|
310
|
+
sample_count = wps->wphdr.block_index + wps->wphdr.block_samples - wps->sample_index;
|
|
311
|
+
|
|
312
|
+
if (wps->mute_error) {
|
|
313
|
+
memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8));
|
|
314
|
+
wps->sample_index += sample_count;
|
|
315
|
+
return sample_count;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (flags & HYBRID_FLAG)
|
|
319
|
+
mute_limit *= 2;
|
|
320
|
+
|
|
321
|
+
///////////////////// handle version 4 mono data /////////////////////////
|
|
322
|
+
|
|
323
|
+
if (flags & MONO_DATA) {
|
|
324
|
+
eptr = buffer + sample_count;
|
|
325
|
+
i = get_words (buffer, sample_count, flags, &wps->w, &wps->wvbits);
|
|
326
|
+
|
|
327
|
+
for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
|
|
328
|
+
decorr_mono_pass (dpp, buffer, sample_count);
|
|
329
|
+
|
|
330
|
+
for (bptr = buffer; bptr < eptr; ++bptr) {
|
|
331
|
+
if (labs (bptr [0]) > mute_limit) {
|
|
332
|
+
i = bptr - buffer;
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
crc = crc * 3 + bptr [0];
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
//////////////////// handle version 4 stereo data ////////////////////////
|
|
341
|
+
|
|
342
|
+
else {
|
|
343
|
+
eptr = buffer + (sample_count * 2);
|
|
344
|
+
i = get_words (buffer, sample_count, flags, &wps->w, &wps->wvbits);
|
|
345
|
+
|
|
346
|
+
if (sample_count < 16)
|
|
347
|
+
for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
|
|
348
|
+
decorr_stereo_pass (dpp, buffer, sample_count);
|
|
349
|
+
else
|
|
350
|
+
for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) {
|
|
351
|
+
decorr_stereo_pass (dpp, buffer, 8);
|
|
352
|
+
#if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
|
|
353
|
+
decorr_stereo_pass_cont_mcf5249 (dpp, buffer + 16, sample_count - 8);
|
|
354
|
+
#elif defined(CPU_ARM) && !defined(SIMULATOR)
|
|
355
|
+
if (((flags & MAG_MASK) >> MAG_LSB) > 15)
|
|
356
|
+
decorr_stereo_pass_cont_arml (dpp, buffer + 16, sample_count - 8);
|
|
357
|
+
else
|
|
358
|
+
decorr_stereo_pass_cont_arm (dpp, buffer + 16, sample_count - 8);
|
|
359
|
+
#else
|
|
360
|
+
decorr_stereo_pass_cont (dpp, buffer + 16, sample_count - 8);
|
|
361
|
+
#endif
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if (flags & JOINT_STEREO)
|
|
365
|
+
for (bptr = buffer; bptr < eptr; bptr += 2) {
|
|
366
|
+
bptr [0] += (bptr [1] -= (bptr [0] >> 1));
|
|
367
|
+
|
|
368
|
+
if (labs (bptr [0]) > mute_limit || labs (bptr [1]) > mute_limit) {
|
|
369
|
+
i = (bptr - buffer) / 2;
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
crc = (crc * 3 + bptr [0]) * 3 + bptr [1];
|
|
374
|
+
}
|
|
375
|
+
else
|
|
376
|
+
for (bptr = buffer; bptr < eptr; bptr += 2) {
|
|
377
|
+
if (labs (bptr [0]) > mute_limit || labs (bptr [1]) > mute_limit) {
|
|
378
|
+
i = (bptr - buffer) / 2;
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
crc = (crc * 3 + bptr [0]) * 3 + bptr [1];
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (i != sample_count) {
|
|
387
|
+
memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8));
|
|
388
|
+
wps->mute_error = TRUE;
|
|
389
|
+
i = sample_count;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
fixup_samples (wps, buffer, i);
|
|
393
|
+
|
|
394
|
+
if (flags & FALSE_STEREO) {
|
|
395
|
+
int32_t *dptr = buffer + i * 2;
|
|
396
|
+
int32_t *sptr = buffer + i;
|
|
397
|
+
int32_t c = i;
|
|
398
|
+
|
|
399
|
+
while (c--) {
|
|
400
|
+
*--dptr = *--sptr;
|
|
401
|
+
*--dptr = *sptr;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
wps->sample_index += i;
|
|
406
|
+
wps->crc = crc;
|
|
407
|
+
|
|
408
|
+
return i;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count)
|
|
412
|
+
{
|
|
413
|
+
int32_t delta = dpp->delta, weight_A = dpp->weight_A, weight_B = dpp->weight_B;
|
|
414
|
+
int32_t *bptr, *eptr = buffer + (sample_count * 2), sam_A, sam_B;
|
|
415
|
+
int m, k;
|
|
416
|
+
|
|
417
|
+
switch (dpp->term) {
|
|
418
|
+
|
|
419
|
+
case 17:
|
|
420
|
+
for (bptr = buffer; bptr < eptr; bptr += 2) {
|
|
421
|
+
sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
|
|
422
|
+
dpp->samples_A [1] = dpp->samples_A [0];
|
|
423
|
+
dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0];
|
|
424
|
+
update_weight (weight_A, delta, sam_A, bptr [0]);
|
|
425
|
+
bptr [0] = dpp->samples_A [0];
|
|
426
|
+
|
|
427
|
+
sam_A = 2 * dpp->samples_B [0] - dpp->samples_B [1];
|
|
428
|
+
dpp->samples_B [1] = dpp->samples_B [0];
|
|
429
|
+
dpp->samples_B [0] = apply_weight (weight_B, sam_A) + bptr [1];
|
|
430
|
+
update_weight (weight_B, delta, sam_A, bptr [1]);
|
|
431
|
+
bptr [1] = dpp->samples_B [0];
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
break;
|
|
435
|
+
|
|
436
|
+
case 18:
|
|
437
|
+
for (bptr = buffer; bptr < eptr; bptr += 2) {
|
|
438
|
+
sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
|
|
439
|
+
dpp->samples_A [1] = dpp->samples_A [0];
|
|
440
|
+
dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0];
|
|
441
|
+
update_weight (weight_A, delta, sam_A, bptr [0]);
|
|
442
|
+
bptr [0] = dpp->samples_A [0];
|
|
443
|
+
|
|
444
|
+
sam_A = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1;
|
|
445
|
+
dpp->samples_B [1] = dpp->samples_B [0];
|
|
446
|
+
dpp->samples_B [0] = apply_weight (weight_B, sam_A) + bptr [1];
|
|
447
|
+
update_weight (weight_B, delta, sam_A, bptr [1]);
|
|
448
|
+
bptr [1] = dpp->samples_B [0];
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
break;
|
|
452
|
+
|
|
453
|
+
default:
|
|
454
|
+
for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr += 2) {
|
|
455
|
+
sam_A = dpp->samples_A [m];
|
|
456
|
+
dpp->samples_A [k] = apply_weight (weight_A, sam_A) + bptr [0];
|
|
457
|
+
update_weight (weight_A, delta, sam_A, bptr [0]);
|
|
458
|
+
bptr [0] = dpp->samples_A [k];
|
|
459
|
+
|
|
460
|
+
sam_A = dpp->samples_B [m];
|
|
461
|
+
dpp->samples_B [k] = apply_weight (weight_B, sam_A) + bptr [1];
|
|
462
|
+
update_weight (weight_B, delta, sam_A, bptr [1]);
|
|
463
|
+
bptr [1] = dpp->samples_B [k];
|
|
464
|
+
|
|
465
|
+
m = (m + 1) & (MAX_TERM - 1);
|
|
466
|
+
k = (k + 1) & (MAX_TERM - 1);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
if (m) {
|
|
470
|
+
int32_t temp_samples [MAX_TERM];
|
|
471
|
+
|
|
472
|
+
memcpy (temp_samples, dpp->samples_A, sizeof (dpp->samples_A));
|
|
473
|
+
|
|
474
|
+
for (k = 0; k < MAX_TERM; k++, m++)
|
|
475
|
+
dpp->samples_A [k] = temp_samples [m & (MAX_TERM - 1)];
|
|
476
|
+
|
|
477
|
+
memcpy (temp_samples, dpp->samples_B, sizeof (dpp->samples_B));
|
|
478
|
+
|
|
479
|
+
for (k = 0; k < MAX_TERM; k++, m++)
|
|
480
|
+
dpp->samples_B [k] = temp_samples [m & (MAX_TERM - 1)];
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
break;
|
|
484
|
+
|
|
485
|
+
case -1:
|
|
486
|
+
for (bptr = buffer; bptr < eptr; bptr += 2) {
|
|
487
|
+
sam_A = bptr [0] + apply_weight (weight_A, dpp->samples_A [0]);
|
|
488
|
+
update_weight_clip (weight_A, delta, dpp->samples_A [0], bptr [0]);
|
|
489
|
+
bptr [0] = sam_A;
|
|
490
|
+
dpp->samples_A [0] = bptr [1] + apply_weight (weight_B, sam_A);
|
|
491
|
+
update_weight_clip (weight_B, delta, sam_A, bptr [1]);
|
|
492
|
+
bptr [1] = dpp->samples_A [0];
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
break;
|
|
496
|
+
|
|
497
|
+
case -2:
|
|
498
|
+
for (bptr = buffer; bptr < eptr; bptr += 2) {
|
|
499
|
+
sam_B = bptr [1] + apply_weight (weight_B, dpp->samples_B [0]);
|
|
500
|
+
update_weight_clip (weight_B, delta, dpp->samples_B [0], bptr [1]);
|
|
501
|
+
bptr [1] = sam_B;
|
|
502
|
+
dpp->samples_B [0] = bptr [0] + apply_weight (weight_A, sam_B);
|
|
503
|
+
update_weight_clip (weight_A, delta, sam_B, bptr [0]);
|
|
504
|
+
bptr [0] = dpp->samples_B [0];
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
break;
|
|
508
|
+
|
|
509
|
+
case -3:
|
|
510
|
+
for (bptr = buffer; bptr < eptr; bptr += 2) {
|
|
511
|
+
sam_A = bptr [0] + apply_weight (weight_A, dpp->samples_A [0]);
|
|
512
|
+
update_weight_clip (weight_A, delta, dpp->samples_A [0], bptr [0]);
|
|
513
|
+
sam_B = bptr [1] + apply_weight (weight_B, dpp->samples_B [0]);
|
|
514
|
+
update_weight_clip (weight_B, delta, dpp->samples_B [0], bptr [1]);
|
|
515
|
+
bptr [0] = dpp->samples_B [0] = sam_A;
|
|
516
|
+
bptr [1] = dpp->samples_A [0] = sam_B;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
break;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
dpp->weight_A = weight_A;
|
|
523
|
+
dpp->weight_B = weight_B;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
#if (!defined(CPU_COLDFIRE) && !defined(CPU_ARM)) || defined(SIMULATOR)
|
|
527
|
+
|
|
528
|
+
static void decorr_stereo_pass_cont (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count)
|
|
529
|
+
{
|
|
530
|
+
int32_t delta = dpp->delta, weight_A = dpp->weight_A, weight_B = dpp->weight_B;
|
|
531
|
+
int32_t *bptr, *tptr, *eptr = buffer + (sample_count * 2), sam_A, sam_B;
|
|
532
|
+
int k, i;
|
|
533
|
+
|
|
534
|
+
switch (dpp->term) {
|
|
535
|
+
|
|
536
|
+
case 17:
|
|
537
|
+
for (bptr = buffer; bptr < eptr; bptr += 2) {
|
|
538
|
+
sam_A = 2 * bptr [-2] - bptr [-4];
|
|
539
|
+
bptr [0] = apply_weight (weight_A, sam_A) + (sam_B = bptr [0]);
|
|
540
|
+
update_weight (weight_A, delta, sam_A, sam_B);
|
|
541
|
+
|
|
542
|
+
sam_A = 2 * bptr [-1] - bptr [-3];
|
|
543
|
+
bptr [1] = apply_weight (weight_B, sam_A) + (sam_B = bptr [1]);
|
|
544
|
+
update_weight (weight_B, delta, sam_A, sam_B);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
dpp->samples_B [0] = bptr [-1];
|
|
548
|
+
dpp->samples_A [0] = bptr [-2];
|
|
549
|
+
dpp->samples_B [1] = bptr [-3];
|
|
550
|
+
dpp->samples_A [1] = bptr [-4];
|
|
551
|
+
break;
|
|
552
|
+
|
|
553
|
+
case 18:
|
|
554
|
+
for (bptr = buffer; bptr < eptr; bptr += 2) {
|
|
555
|
+
sam_A = (3 * bptr [-2] - bptr [-4]) >> 1;
|
|
556
|
+
bptr [0] = apply_weight (weight_A, sam_A) + (sam_B = bptr [0]);
|
|
557
|
+
update_weight (weight_A, delta, sam_A, sam_B);
|
|
558
|
+
|
|
559
|
+
sam_A = (3 * bptr [-1] - bptr [-3]) >> 1;
|
|
560
|
+
bptr [1] = apply_weight (weight_B, sam_A) + (sam_B = bptr [1]);
|
|
561
|
+
update_weight (weight_B, delta, sam_A, sam_B);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
dpp->samples_B [0] = bptr [-1];
|
|
565
|
+
dpp->samples_A [0] = bptr [-2];
|
|
566
|
+
dpp->samples_B [1] = bptr [-3];
|
|
567
|
+
dpp->samples_A [1] = bptr [-4];
|
|
568
|
+
break;
|
|
569
|
+
|
|
570
|
+
default:
|
|
571
|
+
for (bptr = buffer, tptr = buffer - (dpp->term * 2); bptr < eptr; bptr += 2, tptr += 2) {
|
|
572
|
+
bptr [0] = apply_weight (weight_A, tptr [0]) + (sam_A = bptr [0]);
|
|
573
|
+
update_weight (weight_A, delta, tptr [0], sam_A);
|
|
574
|
+
|
|
575
|
+
bptr [1] = apply_weight (weight_B, tptr [1]) + (sam_A = bptr [1]);
|
|
576
|
+
update_weight (weight_B, delta, tptr [1], sam_A);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
for (k = dpp->term - 1, i = 8; i--; k--) {
|
|
580
|
+
dpp->samples_B [k & (MAX_TERM - 1)] = *--bptr;
|
|
581
|
+
dpp->samples_A [k & (MAX_TERM - 1)] = *--bptr;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
break;
|
|
585
|
+
|
|
586
|
+
case -1:
|
|
587
|
+
for (bptr = buffer; bptr < eptr; bptr += 2) {
|
|
588
|
+
bptr [0] = apply_weight (weight_A, bptr [-1]) + (sam_A = bptr [0]);
|
|
589
|
+
update_weight_clip (weight_A, delta, bptr [-1], sam_A);
|
|
590
|
+
bptr [1] = apply_weight (weight_B, bptr [0]) + (sam_A = bptr [1]);
|
|
591
|
+
update_weight_clip (weight_B, delta, bptr [0], sam_A);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
dpp->samples_A [0] = bptr [-1];
|
|
595
|
+
break;
|
|
596
|
+
|
|
597
|
+
case -2:
|
|
598
|
+
for (bptr = buffer; bptr < eptr; bptr += 2) {
|
|
599
|
+
bptr [1] = apply_weight (weight_B, bptr [-2]) + (sam_A = bptr [1]);
|
|
600
|
+
update_weight_clip (weight_B, delta, bptr [-2], sam_A);
|
|
601
|
+
bptr [0] = apply_weight (weight_A, bptr [1]) + (sam_A = bptr [0]);
|
|
602
|
+
update_weight_clip (weight_A, delta, bptr [1], sam_A);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
dpp->samples_B [0] = bptr [-2];
|
|
606
|
+
break;
|
|
607
|
+
|
|
608
|
+
case -3:
|
|
609
|
+
for (bptr = buffer; bptr < eptr; bptr += 2) {
|
|
610
|
+
bptr [0] = apply_weight (weight_A, bptr [-1]) + (sam_A = bptr [0]);
|
|
611
|
+
update_weight_clip (weight_A, delta, bptr [-1], sam_A);
|
|
612
|
+
bptr [1] = apply_weight (weight_B, bptr [-2]) + (sam_A = bptr [1]);
|
|
613
|
+
update_weight_clip (weight_B, delta, bptr [-2], sam_A);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
dpp->samples_A [0] = bptr [-1];
|
|
617
|
+
dpp->samples_B [0] = bptr [-2];
|
|
618
|
+
break;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
dpp->weight_A = weight_A;
|
|
622
|
+
dpp->weight_B = weight_B;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
#endif
|
|
626
|
+
|
|
627
|
+
static void decorr_mono_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count)
|
|
628
|
+
{
|
|
629
|
+
int32_t delta = dpp->delta, weight_A = dpp->weight_A;
|
|
630
|
+
int32_t *bptr, *eptr = buffer + sample_count, sam_A;
|
|
631
|
+
int m, k;
|
|
632
|
+
|
|
633
|
+
switch (dpp->term) {
|
|
634
|
+
|
|
635
|
+
case 17:
|
|
636
|
+
for (bptr = buffer; bptr < eptr; bptr++) {
|
|
637
|
+
sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
|
|
638
|
+
dpp->samples_A [1] = dpp->samples_A [0];
|
|
639
|
+
dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0];
|
|
640
|
+
update_weight (weight_A, delta, sam_A, bptr [0]);
|
|
641
|
+
bptr [0] = dpp->samples_A [0];
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
break;
|
|
645
|
+
|
|
646
|
+
case 18:
|
|
647
|
+
for (bptr = buffer; bptr < eptr; bptr++) {
|
|
648
|
+
sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
|
|
649
|
+
dpp->samples_A [1] = dpp->samples_A [0];
|
|
650
|
+
dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0];
|
|
651
|
+
update_weight (weight_A, delta, sam_A, bptr [0]);
|
|
652
|
+
bptr [0] = dpp->samples_A [0];
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
break;
|
|
656
|
+
|
|
657
|
+
default:
|
|
658
|
+
for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr++) {
|
|
659
|
+
sam_A = dpp->samples_A [m];
|
|
660
|
+
dpp->samples_A [k] = apply_weight (weight_A, sam_A) + bptr [0];
|
|
661
|
+
update_weight (weight_A, delta, sam_A, bptr [0]);
|
|
662
|
+
bptr [0] = dpp->samples_A [k];
|
|
663
|
+
m = (m + 1) & (MAX_TERM - 1);
|
|
664
|
+
k = (k + 1) & (MAX_TERM - 1);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
if (m) {
|
|
668
|
+
int32_t temp_samples [MAX_TERM];
|
|
669
|
+
|
|
670
|
+
memcpy (temp_samples, dpp->samples_A, sizeof (dpp->samples_A));
|
|
671
|
+
|
|
672
|
+
for (k = 0; k < MAX_TERM; k++, m++)
|
|
673
|
+
dpp->samples_A [k] = temp_samples [m & (MAX_TERM - 1)];
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
break;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
dpp->weight_A = weight_A;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
// This is a helper function for unpack_samples() that applies several final
|
|
684
|
+
// operations. First, if the data is 32-bit float data, then that conversion
|
|
685
|
+
// is done in the float.c module (whether lossy or lossless) and we return.
|
|
686
|
+
// Otherwise, if the extended integer data applies, then that operation is
|
|
687
|
+
// executed first. If the unpacked data is lossy (and not corrected) then
|
|
688
|
+
// it is clipped and shifted in a single operation. Otherwise, if it's
|
|
689
|
+
// lossless then the last step is to apply the final shift (if any).
|
|
690
|
+
|
|
691
|
+
static void fixup_samples (WavpackStream *wps, int32_t *buffer, uint32_t sample_count)
|
|
692
|
+
{
|
|
693
|
+
uint32_t flags = wps->wphdr.flags;
|
|
694
|
+
int shift = (flags & SHIFT_MASK) >> SHIFT_LSB;
|
|
695
|
+
|
|
696
|
+
if (flags & FLOAT_DATA) {
|
|
697
|
+
float_values (wps, buffer, (flags & MONO_FLAG) ? sample_count : sample_count * 2);
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
if (flags & INT32_DATA) {
|
|
702
|
+
uint32_t count = (flags & MONO_FLAG) ? sample_count : sample_count * 2;
|
|
703
|
+
int sent_bits = wps->int32_sent_bits, zeros = wps->int32_zeros;
|
|
704
|
+
int ones = wps->int32_ones, dups = wps->int32_dups;
|
|
705
|
+
int32_t *dptr = buffer;
|
|
706
|
+
|
|
707
|
+
if (!(flags & HYBRID_FLAG) && !sent_bits && (zeros + ones + dups))
|
|
708
|
+
while (count--) {
|
|
709
|
+
if (zeros)
|
|
710
|
+
*dptr <<= zeros;
|
|
711
|
+
else if (ones)
|
|
712
|
+
*dptr = ((*dptr + 1) << ones) - 1;
|
|
713
|
+
else if (dups)
|
|
714
|
+
*dptr = ((*dptr + (*dptr & 1)) << dups) - (*dptr & 1);
|
|
715
|
+
|
|
716
|
+
dptr++;
|
|
717
|
+
}
|
|
718
|
+
else
|
|
719
|
+
shift += zeros + sent_bits + ones + dups;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
if (flags & HYBRID_FLAG) {
|
|
723
|
+
int32_t min_value, max_value, min_shifted, max_shifted;
|
|
724
|
+
|
|
725
|
+
switch (flags & BYTES_STORED) {
|
|
726
|
+
case 0:
|
|
727
|
+
min_shifted = (min_value = -128 >> shift) << shift;
|
|
728
|
+
max_shifted = (max_value = 127 >> shift) << shift;
|
|
729
|
+
break;
|
|
730
|
+
|
|
731
|
+
case 1:
|
|
732
|
+
min_shifted = (min_value = -32768 >> shift) << shift;
|
|
733
|
+
max_shifted = (max_value = 32767 >> shift) << shift;
|
|
734
|
+
break;
|
|
735
|
+
|
|
736
|
+
case 2:
|
|
737
|
+
min_shifted = (min_value = -8388608 >> shift) << shift;
|
|
738
|
+
max_shifted = (max_value = 8388607 >> shift) << shift;
|
|
739
|
+
break;
|
|
740
|
+
|
|
741
|
+
case 3:
|
|
742
|
+
default:
|
|
743
|
+
min_shifted = (min_value = (int32_t) 0x80000000 >> shift) << shift;
|
|
744
|
+
max_shifted = (max_value = (int32_t) 0x7FFFFFFF >> shift) << shift;
|
|
745
|
+
break;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
if (!(flags & MONO_FLAG))
|
|
749
|
+
sample_count *= 2;
|
|
750
|
+
|
|
751
|
+
while (sample_count--) {
|
|
752
|
+
if (*buffer < min_value)
|
|
753
|
+
*buffer++ = min_shifted;
|
|
754
|
+
else if (*buffer > max_value)
|
|
755
|
+
*buffer++ = max_shifted;
|
|
756
|
+
else
|
|
757
|
+
*buffer++ <<= shift;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
else if (shift) {
|
|
761
|
+
if (!(flags & MONO_FLAG))
|
|
762
|
+
sample_count *= 2;
|
|
763
|
+
|
|
764
|
+
while (sample_count--)
|
|
765
|
+
*buffer++ <<= shift;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// This function checks the crc value(s) for an unpacked block, returning the
|
|
770
|
+
// number of actual crc errors detected for the block. The block must be
|
|
771
|
+
// completely unpacked before this test is valid. For losslessly unpacked
|
|
772
|
+
// blocks of float or extended integer data the extended crc is also checked.
|
|
773
|
+
// Note that WavPack's crc is not a CCITT approved polynomial algorithm, but
|
|
774
|
+
// is a much simpler method that is virtually as robust for real world data.
|
|
775
|
+
|
|
776
|
+
int check_crc_error (WavpackContext *wpc)
|
|
777
|
+
{
|
|
778
|
+
WavpackStream *wps = &wpc->stream;
|
|
779
|
+
int result = 0;
|
|
780
|
+
|
|
781
|
+
if (wps->crc != wps->wphdr.crc)
|
|
782
|
+
++result;
|
|
783
|
+
|
|
784
|
+
return result;
|
|
785
|
+
}
|