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.
Files changed (62) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +148 -0
  3. package/android/build.gradle +112 -0
  4. package/android/generated/java/com/tinywavpackdecoder/NativeTinyWavPackDecoderSpec.java +47 -0
  5. package/android/generated/jni/CMakeLists.txt +36 -0
  6. package/android/generated/jni/RNTinyWavPackDecoderSpec-generated.cpp +44 -0
  7. package/android/generated/jni/RNTinyWavPackDecoderSpec.h +31 -0
  8. package/android/generated/jni/react/renderer/components/RNTinyWavPackDecoderSpec/RNTinyWavPackDecoderSpecJSI-generated.cpp +46 -0
  9. package/android/generated/jni/react/renderer/components/RNTinyWavPackDecoderSpec/RNTinyWavPackDecoderSpecJSI.h +89 -0
  10. package/android/gradle.properties +5 -0
  11. package/android/src/main/AndroidManifest.xml +3 -0
  12. package/android/src/main/AndroidManifestNew.xml +2 -0
  13. package/android/src/main/cpp/CMakeLists.txt +54 -0
  14. package/android/src/main/cpp/TinyWavPackDecoderModule.cpp +118 -0
  15. package/android/src/main/java/com/tinywavpackdecoder/TinyWavPackDecoderModule.kt +114 -0
  16. package/android/src/main/java/com/tinywavpackdecoder/TinyWavPackDecoderPackage.kt +18 -0
  17. package/ios/TinyWavPackDecoder.h +8 -0
  18. package/ios/TinyWavPackDecoder.mm +83 -0
  19. package/ios/generated/RNTinyWavPackDecoderSpec/RNTinyWavPackDecoderSpec-generated.mm +53 -0
  20. package/ios/generated/RNTinyWavPackDecoderSpec/RNTinyWavPackDecoderSpec.h +69 -0
  21. package/ios/generated/RNTinyWavPackDecoderSpecJSI-generated.cpp +46 -0
  22. package/ios/generated/RNTinyWavPackDecoderSpecJSI.h +89 -0
  23. package/lib/module/NativeTinyWavPackDecoder.ts +19 -0
  24. package/lib/module/index.js +38 -0
  25. package/lib/module/index.js.map +1 -0
  26. package/lib/module/package.json +1 -0
  27. package/lib/module/tiny-wavpack/common/TinyWavPackDecoderInterface.c +414 -0
  28. package/lib/module/tiny-wavpack/common/TinyWavPackDecoderInterface.h +52 -0
  29. package/lib/module/tiny-wavpack/common/test.c +45 -0
  30. package/lib/module/tiny-wavpack/common/wv2wav +0 -0
  31. package/lib/module/tiny-wavpack/lib/bits.c +140 -0
  32. package/lib/module/tiny-wavpack/lib/float.c +50 -0
  33. package/lib/module/tiny-wavpack/lib/license.txt +25 -0
  34. package/lib/module/tiny-wavpack/lib/metadata.c +105 -0
  35. package/lib/module/tiny-wavpack/lib/readme.txt +68 -0
  36. package/lib/module/tiny-wavpack/lib/unpack.c +785 -0
  37. package/lib/module/tiny-wavpack/lib/wavpack.h +384 -0
  38. package/lib/module/tiny-wavpack/lib/words.c +560 -0
  39. package/lib/module/tiny-wavpack/lib/wputils.c +351 -0
  40. package/lib/typescript/package.json +1 -0
  41. package/lib/typescript/src/NativeTinyWavPackDecoder.d.ts +9 -0
  42. package/lib/typescript/src/NativeTinyWavPackDecoder.d.ts.map +1 -0
  43. package/lib/typescript/src/index.d.ts +18 -0
  44. package/lib/typescript/src/index.d.ts.map +1 -0
  45. package/package.json +195 -0
  46. package/react-native-wavpack-decoder.podspec +35 -0
  47. package/react-native.config.js +12 -0
  48. package/src/NativeTinyWavPackDecoder.ts +19 -0
  49. package/src/index.tsx +57 -0
  50. package/src/tiny-wavpack/common/TinyWavPackDecoderInterface.c +414 -0
  51. package/src/tiny-wavpack/common/TinyWavPackDecoderInterface.h +52 -0
  52. package/src/tiny-wavpack/common/test.c +45 -0
  53. package/src/tiny-wavpack/common/wv2wav +0 -0
  54. package/src/tiny-wavpack/lib/bits.c +140 -0
  55. package/src/tiny-wavpack/lib/float.c +50 -0
  56. package/src/tiny-wavpack/lib/license.txt +25 -0
  57. package/src/tiny-wavpack/lib/metadata.c +105 -0
  58. package/src/tiny-wavpack/lib/readme.txt +68 -0
  59. package/src/tiny-wavpack/lib/unpack.c +785 -0
  60. package/src/tiny-wavpack/lib/wavpack.h +384 -0
  61. package/src/tiny-wavpack/lib/words.c +560 -0
  62. 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
+ }