summaryrefslogtreecommitdiff
path: root/apps/codecs/libwavpack/unpack.c
diff options
context:
space:
mode:
authorChristian Gmeiner <christian.gmeiner@gmail.com>2005-02-25 17:05:30 +0000
committerChristian Gmeiner <christian.gmeiner@gmail.com>2005-02-25 17:05:30 +0000
commite449d88b3e6b584998f8f38ed61467c35ca74466 (patch)
tree307e87242fd5fbf45d7424bb5afad17b9dd34429 /apps/codecs/libwavpack/unpack.c
parent234489a449e13d99b76daff61ff7774226d21a5b (diff)
downloadrockbox-e449d88b3e6b584998f8f38ed61467c35ca74466.tar.gz
rockbox-e449d88b3e6b584998f8f38ed61467c35ca74466.zip
Initial import of libwavpack
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6056 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libwavpack/unpack.c')
-rw-r--r--apps/codecs/libwavpack/unpack.c576
1 files changed, 576 insertions, 0 deletions
diff --git a/apps/codecs/libwavpack/unpack.c b/apps/codecs/libwavpack/unpack.c
new file mode 100644
index 0000000000..e2e27b4999
--- /dev/null
+++ b/apps/codecs/libwavpack/unpack.c
@@ -0,0 +1,576 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 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 <string.h>
19#include <math.h>
20
21#define LOSSY_MUTE
22
23//////////////////////////////// local macros /////////////////////////////////
24
25#define apply_weight_i(weight, sample) ((weight * sample + 512) >> 10)
26
27#define apply_weight_f(weight, sample) (((((sample & 0xffff) * weight) >> 9) + \
28 (((sample & ~0xffff) >> 9) * weight) + 1) >> 1)
29
30#define apply_weight(weight, sample) (sample != (short) sample ? \
31 apply_weight_f (weight, sample) : apply_weight_i (weight, sample))
32
33#define update_weight(weight, delta, source, result) \
34 if (source && result) weight -= ((((source ^ result) >> 30) & 2) - 1) * delta;
35
36#define update_weight_clip(weight, delta, source, result) \
37 if (source && result && ((source ^ result) < 0 ? (weight -= delta) < -1024 : (weight += delta) > 1024)) \
38 weight = weight < 0 ? -1024 : 1024;
39
40///////////////////////////// executable code ////////////////////////////////
41
42// This function initializes everything required to unpack a WavPack block
43// and must be called before unpack_samples() is called to obtain audio data.
44// It is assumed that the WavpackHeader has been read into the wps->wphdr
45// (in the current WavpackStream). This is where all the metadata blocks are
46// scanned up to the one containing the audio bitstream.
47
48int unpack_init (WavpackContext *wpc)
49{
50 WavpackStream *wps = &wpc->stream;
51 WavpackMetadata wpmd;
52
53 if (wps->wphdr.block_samples && wps->wphdr.block_index != (ulong) -1)
54 wps->sample_index = wps->wphdr.block_index;
55
56 wps->mute_error = FALSE;
57 wps->crc = 0xffffffff;
58 CLEAR (wps->wvbits);
59 CLEAR (wps->decorr_passes);
60 CLEAR (wps->w);
61
62 while (read_metadata_buff (wpc, &wpmd)) {
63 if (!process_metadata (wpc, &wpmd)) {
64 strcpy (wpc->error_message, "invalid metadata!");
65 return FALSE;
66 }
67
68 if (wpmd.id == ID_WV_BITSTREAM)
69 break;
70 }
71
72 if (wps->wphdr.block_samples && !bs_is_open (&wps->wvbits)) {
73 strcpy (wpc->error_message, "invalid WavPack file!");
74 return FALSE;
75 }
76
77 if (wps->wphdr.block_samples) {
78 if ((wps->wphdr.flags & INT32_DATA) && wps->int32_sent_bits)
79 wpc->lossy_blocks = TRUE;
80
81 if ((wps->wphdr.flags & FLOAT_DATA) &&
82 wps->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT | FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME))
83 wpc->lossy_blocks = TRUE;
84 }
85
86 return TRUE;
87}
88
89// This function initialzes the main bitstream for audio samples, which must
90// be in the "wv" file.
91
92int init_wv_bitstream (WavpackContext *wpc, WavpackMetadata *wpmd)
93{
94 WavpackStream *wps = &wpc->stream;
95
96 if (wpmd->data)
97 bs_open_read (&wps->wvbits, wpmd->data, (char *) wpmd->data + wpmd->byte_length, NULL, 0);
98 else if (wpmd->byte_length)
99 bs_open_read (&wps->wvbits, wpc->read_buffer, wpc->read_buffer + sizeof (wpc->read_buffer),
100 wpc->infile, wpmd->byte_length + (wpmd->byte_length & 1));
101
102 return TRUE;
103}
104
105// Read decorrelation terms from specified metadata block into the
106// decorr_passes array. The terms range from -3 to 8, plus 17 & 18;
107// other values are reserved and generate errors for now. The delta
108// ranges from 0 to 7 with all values valid. Note that the terms are
109// stored in the opposite order in the decorr_passes array compared
110// to packing.
111
112int read_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd)
113{
114 int termcnt = wpmd->byte_length;
115 uchar *byteptr = wpmd->data;
116 struct decorr_pass *dpp;
117
118 if (termcnt > MAX_NTERMS)
119 return FALSE;
120
121 wps->num_terms = termcnt;
122
123 for (dpp = wps->decorr_passes + termcnt - 1; termcnt--; dpp--) {
124 dpp->term = (int)(*byteptr & 0x1f) - 5;
125 dpp->delta = (*byteptr++ >> 5) & 0x7;
126
127 if (!dpp->term || dpp->term < -3 || (dpp->term > MAX_TERM && dpp->term < 17) || dpp->term > 18)
128 return FALSE;
129 }
130
131 return TRUE;
132}
133
134// Read decorrelation weights from specified metadata block into the
135// decorr_passes array. The weights range +/-1024, but are rounded and
136// truncated to fit in signed chars for metadata storage. Weights are
137// separate for the two channels and are specified from the "last" term
138// (first during encode). Unspecified weights are set to zero.
139
140int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd)
141{
142 int termcnt = wpmd->byte_length, tcount;
143 char *byteptr = wpmd->data;
144 struct decorr_pass *dpp;
145
146 if (!(wps->wphdr.flags & MONO_FLAG))
147 termcnt /= 2;
148
149 if (termcnt > wps->num_terms)
150 return FALSE;
151
152 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
153 dpp->weight_A = dpp->weight_B = 0;
154
155 while (--dpp >= wps->decorr_passes && termcnt--) {
156 dpp->weight_A = restore_weight (*byteptr++);
157
158 if (!(wps->wphdr.flags & MONO_FLAG))
159 dpp->weight_B = restore_weight (*byteptr++);
160 }
161
162 return TRUE;
163}
164
165// Read decorrelation samples from specified metadata block into the
166// decorr_passes array. The samples are signed 32-bit values, but are
167// converted to signed log2 values for storage in metadata. Values are
168// stored for both channels and are specified from the "last" term
169// (first during encode) with unspecified samples set to zero. The
170// number of samples stored varies with the actual term value, so
171// those must obviously come first in the metadata.
172
173int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd)
174{
175 uchar *byteptr = wpmd->data;
176 uchar *endptr = byteptr + wpmd->byte_length;
177 struct decorr_pass *dpp;
178 int tcount;
179
180 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) {
181 CLEAR (dpp->samples_A);
182 CLEAR (dpp->samples_B);
183 }
184
185 if (wps->wphdr.version == 0x402 && (wps->wphdr.flags & HYBRID_FLAG)) {
186 byteptr += 2;
187
188 if (!(wps->wphdr.flags & MONO_FLAG))
189 byteptr += 2;
190 }
191
192 while (dpp-- > wps->decorr_passes && byteptr < endptr)
193 if (dpp->term > MAX_TERM) {
194 dpp->samples_A [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
195 dpp->samples_A [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
196 byteptr += 4;
197
198 if (!(wps->wphdr.flags & MONO_FLAG)) {
199 dpp->samples_B [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
200 dpp->samples_B [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
201 byteptr += 4;
202 }
203 }
204 else if (dpp->term < 0) {
205 dpp->samples_A [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
206 dpp->samples_B [0] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
207 byteptr += 4;
208 }
209 else {
210 int m = 0, cnt = dpp->term;
211
212 while (cnt--) {
213 dpp->samples_A [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
214 byteptr += 2;
215
216 if (!(wps->wphdr.flags & MONO_FLAG)) {
217 dpp->samples_B [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
218 byteptr += 2;
219 }
220
221 m++;
222 }
223 }
224
225 return byteptr == endptr;
226}
227
228// Read the int32 data from the specified metadata into the specified stream.
229// This data is used for integer data that has more than 24 bits of magnitude
230// or, in some cases, used to eliminate redundant bits from any audio stream.
231
232int read_int32_info (WavpackStream *wps, WavpackMetadata *wpmd)
233{
234 int bytecnt = wpmd->byte_length;
235 char *byteptr = wpmd->data;
236
237 if (bytecnt != 4)
238 return FALSE;
239
240 wps->int32_sent_bits = *byteptr++;
241 wps->int32_zeros = *byteptr++;
242 wps->int32_ones = *byteptr++;
243 wps->int32_dups = *byteptr;
244 return TRUE;
245}
246
247// Read multichannel information from metadata. The first byte is the total
248// number of channels and the following bytes represent the channel_mask
249// as described for Microsoft WAVEFORMATEX.
250
251int read_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd)
252{
253 int bytecnt = wpmd->byte_length, shift = 0;
254 char *byteptr = wpmd->data;
255 ulong mask = 0;
256
257 if (!bytecnt || bytecnt > 5)
258 return FALSE;
259
260 wpc->config.num_channels = *byteptr++;
261
262 while (--bytecnt) {
263 mask |= (ulong) *byteptr++ << shift;
264 shift += 8;
265 }
266
267 wpc->config.channel_mask = mask;
268 return TRUE;
269}
270
271// Read configuration information from metadata.
272
273int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
274{
275 int bytecnt = wpmd->byte_length;
276 uchar *byteptr = wpmd->data;
277
278 if (bytecnt >= 3) {
279 wpc->config.flags &= 0xff;
280 wpc->config.flags |= (long) *byteptr++ << 8;
281 wpc->config.flags |= (long) *byteptr++ << 16;
282 wpc->config.flags |= (long) *byteptr << 24;
283 }
284
285 return TRUE;
286}
287
288// This monster actually unpacks the WavPack bitstream(s) into the specified
289// buffer as 32-bit integers or floats (depending on orignal data). Lossy
290// samples will be clipped to their original limits (i.e. 8-bit samples are
291// clipped to -128/+127) but are still returned in longs. It is up to the
292// caller to potentially reformat this for the final output including any
293// multichannel distribution, block alignment or endian compensation. The
294// function unpack_init() must have been called and the entire WavPack block
295// must still be visible (although wps->blockbuff will not be accessed again).
296// For maximum clarity, the function is broken up into segments that handle
297// various modes. This makes for a few extra infrequent flag checks, but
298// makes the code easier to follow because the nesting does not become so
299// deep. For maximum efficiency, the conversion is isolated to tight loops
300// that handle an entire buffer. The function returns the total number of
301// samples unpacked, which can be less than the number requested if an error
302// occurs or the end of the block is reached.
303
304static void fixup_samples (WavpackStream *wps, long *buffer, ulong sample_count);
305
306long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count)
307{
308 WavpackStream *wps = &wpc->stream;
309 ulong flags = wps->wphdr.flags, crc = wps->crc, i;
310 long mute_limit = (1L << ((flags & MAG_MASK) >> MAG_LSB)) + 2;
311 struct decorr_pass *dpp;
312 long read_word, *bptr;
313 int tcount, m = 0;
314
315 if (wps->sample_index + sample_count > wps->wphdr.block_index + wps->wphdr.block_samples)
316 sample_count = wps->wphdr.block_index + wps->wphdr.block_samples - wps->sample_index;
317
318 if (wps->mute_error) {
319 memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8));
320 wps->sample_index += sample_count;
321 return sample_count;
322 }
323
324 if (flags & HYBRID_FLAG)
325 mute_limit *= 2;
326
327 ///////////////////// handle version 4 mono data /////////////////////////
328
329 if (flags & MONO_FLAG)
330 for (bptr = buffer, i = 0; i < sample_count; ++i) {
331 if ((read_word = get_word (wps, 0)) == WORD_EOF)
332 break;
333
334 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) {
335 long sam, temp;
336 int k;
337
338 if (dpp->term > MAX_TERM) {
339 if (dpp->term & 1)
340 sam = 2 * dpp->samples_A [0] - dpp->samples_A [1];
341 else
342 sam = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
343
344 dpp->samples_A [1] = dpp->samples_A [0];
345 k = 0;
346 }
347 else {
348 sam = dpp->samples_A [m];
349 k = (m + dpp->term) & (MAX_TERM - 1);
350 }
351
352 temp = apply_weight (dpp->weight_A, sam) + read_word;
353 update_weight (dpp->weight_A, dpp->delta, sam, read_word);
354 dpp->samples_A [k] = read_word = temp;
355 }
356
357 if (labs (read_word) > mute_limit)
358 break;
359
360 m = (m + 1) & (MAX_TERM - 1);
361 crc = crc * 3 + read_word;
362 *bptr++ = read_word;
363 }
364
365 //////////////////// handle version 4 stereo data ////////////////////////
366
367 else
368 for (bptr = buffer, i = 0; i < sample_count; ++i) {
369 long left, right, left2, right2;
370
371 if ((left = get_word (wps, 0)) == WORD_EOF ||
372 (right = get_word (wps, 1)) == WORD_EOF)
373 break;
374
375 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
376 if (dpp->term > 0) {
377 long sam_A, sam_B;
378 int k;
379
380 if (dpp->term > MAX_TERM) {
381 if (dpp->term & 1) {
382 sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
383 sam_B = 2 * dpp->samples_B [0] - dpp->samples_B [1];
384 }
385 else {
386 sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
387 sam_B = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1;
388 }
389
390 dpp->samples_A [1] = dpp->samples_A [0];
391 dpp->samples_B [1] = dpp->samples_B [0];
392 k = 0;
393 }
394 else {
395 sam_A = dpp->samples_A [m];
396 sam_B = dpp->samples_B [m];
397 k = (m + dpp->term) & (MAX_TERM - 1);
398 }
399
400 left2 = apply_weight (dpp->weight_A, sam_A) + left;
401 right2 = apply_weight (dpp->weight_B, sam_B) + right;
402
403 update_weight (dpp->weight_A, dpp->delta, sam_A, left);
404 update_weight (dpp->weight_B, dpp->delta, sam_B, right);
405
406 dpp->samples_A [k] = left = left2;
407 dpp->samples_B [k] = right = right2;
408 }
409 else if (dpp->term == -1) {
410 left2 = left + apply_weight (dpp->weight_A, dpp->samples_A [0]);
411 update_weight_clip (dpp->weight_A, dpp->delta, dpp->samples_A [0], left);
412 left = left2;
413 right2 = right + apply_weight (dpp->weight_B, left2);
414 update_weight_clip (dpp->weight_B, dpp->delta, left2, right);
415 dpp->samples_A [0] = right = right2;
416 }
417 else {
418 right2 = right + apply_weight (dpp->weight_B, dpp->samples_B [0]);
419 update_weight_clip (dpp->weight_B, dpp->delta, dpp->samples_B [0], right);
420 right = right2;
421
422 if (dpp->term == -3) {
423 right2 = dpp->samples_A [0];
424 dpp->samples_A [0] = right;
425 }
426
427 left2 = left + apply_weight (dpp->weight_A, right2);
428 update_weight_clip (dpp->weight_A, dpp->delta, right2, left);
429 dpp->samples_B [0] = left = left2;
430 }
431
432 m = (m + 1) & (MAX_TERM - 1);
433
434 if (flags & JOINT_STEREO)
435 left += (right -= (left >> 1));
436
437 if (labs (left) > mute_limit || labs (right) > mute_limit)
438 break;
439
440 crc = (crc * 3 + left) * 3 + right;
441 *bptr++ = left;
442 *bptr++ = right;
443 }
444
445 if (i != sample_count) {
446 memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8));
447 wps->mute_error = TRUE;
448 i = sample_count;
449 }
450
451 while (m--)
452 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
453 if (dpp->term > 0 && dpp->term <= MAX_TERM) {
454 long temp = dpp->samples_A [0];
455 memcpy (dpp->samples_A, dpp->samples_A + 1, sizeof (dpp->samples_A) - sizeof (dpp->samples_A [0]));
456 dpp->samples_A [MAX_TERM - 1] = temp;
457 temp = dpp->samples_B [0];
458 memcpy (dpp->samples_B, dpp->samples_B + 1, sizeof (dpp->samples_B) - sizeof (dpp->samples_B [0]));
459 dpp->samples_B [MAX_TERM - 1] = temp;
460 }
461
462 fixup_samples (wps, buffer, i);
463
464 if (flags & FLOAT_DATA)
465 float_normalize (buffer, (flags & MONO_FLAG) ? i : i * 2,
466 127 - wps->float_norm_exp + wpc->norm_offset);
467
468 wps->sample_index += i;
469 wps->crc = crc;
470
471 return i;
472}
473
474// This is a helper function for unpack_samples() that applies several final
475// operations. First, if the data is 32-bit float data, then that conversion
476// is done in the float.c module (whether lossy or lossless) and we return.
477// Otherwise, if the extended integer data applies, then that operation is
478// executed first. If the unpacked data is lossy (and not corrected) then
479// it is clipped and shifted in a single operation. Otherwise, if it's
480// lossless then the last step is to apply the final shift (if any).
481
482static void fixup_samples (WavpackStream *wps, long *buffer, ulong sample_count)
483{
484 ulong flags = wps->wphdr.flags;
485 int shift = (flags & SHIFT_MASK) >> SHIFT_LSB;
486
487 if (flags & FLOAT_DATA) {
488 float_values (wps, buffer, (flags & MONO_FLAG) ? sample_count : sample_count * 2);
489 return;
490 }
491
492 if (flags & INT32_DATA) {
493 ulong count = (flags & MONO_FLAG) ? sample_count : sample_count * 2;
494 int sent_bits = wps->int32_sent_bits, zeros = wps->int32_zeros;
495 int ones = wps->int32_ones, dups = wps->int32_dups;
496// ulong mask = (1 << sent_bits) - 1;
497 long *dptr = buffer;
498
499 if (!(flags & HYBRID_FLAG) && !sent_bits && (zeros + ones + dups))
500 while (count--) {
501 if (zeros)
502 *dptr <<= zeros;
503 else if (ones)
504 *dptr = ((*dptr + 1) << ones) - 1;
505 else if (dups)
506 *dptr = ((*dptr + (*dptr & 1)) << dups) - (*dptr & 1);
507
508 dptr++;
509 }
510 else
511 shift += zeros + sent_bits + ones + dups;
512 }
513
514 if (flags & HYBRID_FLAG) {
515 long min_value, max_value, min_shifted, max_shifted;
516
517 switch (flags & BYTES_STORED) {
518 case 0:
519 min_shifted = (min_value = -128 >> shift) << shift;
520 max_shifted = (max_value = 127 >> shift) << shift;
521 break;
522
523 case 1:
524 min_shifted = (min_value = -32768 >> shift) << shift;
525 max_shifted = (max_value = 32767 >> shift) << shift;
526 break;
527
528 case 2:
529 min_shifted = (min_value = -8388608 >> shift) << shift;
530 max_shifted = (max_value = 8388607 >> shift) << shift;
531 break;
532
533 case 3:
534 min_shifted = (min_value = -(long)2147483648 >> shift) << shift;
535 max_shifted = (max_value = (long) 2147483647 >> shift) << shift;
536 break;
537 }
538
539 if (!(flags & MONO_FLAG))
540 sample_count *= 2;
541
542 while (sample_count--) {
543 if (*buffer < min_value)
544 *buffer++ = min_shifted;
545 else if (*buffer > max_value)
546 *buffer++ = max_shifted;
547 else
548 *buffer++ <<= shift;
549 }
550 }
551 else if (shift) {
552 if (!(flags & MONO_FLAG))
553 sample_count *= 2;
554
555 while (sample_count--)
556 *buffer++ <<= shift;
557 }
558}
559
560// This function checks the crc value(s) for an unpacked block, returning the
561// number of actual crc errors detected for the block. The block must be
562// completely unpacked before this test is valid. For losslessly unpacked
563// blocks of float or extended integer data the extended crc is also checked.
564// Note that WavPack's crc is not a CCITT approved polynomial algorithm, but
565// is a much simpler method that is virtually as robust for real world data.
566
567int check_crc_error (WavpackContext *wpc)
568{
569 WavpackStream *wps = &wpc->stream;
570 int result = 0;
571
572 if (wps->crc != wps->wphdr.crc)
573 ++result;
574
575 return result;
576}