diff options
author | Christian Gmeiner <christian.gmeiner@gmail.com> | 2005-02-25 17:05:30 +0000 |
---|---|---|
committer | Christian Gmeiner <christian.gmeiner@gmail.com> | 2005-02-25 17:05:30 +0000 |
commit | e449d88b3e6b584998f8f38ed61467c35ca74466 (patch) | |
tree | 307e87242fd5fbf45d7424bb5afad17b9dd34429 /apps/codecs | |
parent | 234489a449e13d99b76daff61ff7774226d21a5b (diff) | |
download | rockbox-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')
-rw-r--r-- | apps/codecs/libwavpack/LICENSE | 25 | ||||
-rw-r--r-- | apps/codecs/libwavpack/README | 52 | ||||
-rw-r--r-- | apps/codecs/libwavpack/README.rockbox | 15 | ||||
-rw-r--r-- | apps/codecs/libwavpack/SOURCES | 6 | ||||
-rw-r--r-- | apps/codecs/libwavpack/bits.c | 140 | ||||
-rw-r--r-- | apps/codecs/libwavpack/float.c | 83 | ||||
-rw-r--r-- | apps/codecs/libwavpack/make.bat | 1 | ||||
-rw-r--r-- | apps/codecs/libwavpack/metadata.c | 105 | ||||
-rw-r--r-- | apps/codecs/libwavpack/unpack.c | 576 | ||||
-rw-r--r-- | apps/codecs/libwavpack/wavpack.h | 330 | ||||
-rw-r--r-- | apps/codecs/libwavpack/words.c | 503 | ||||
-rw-r--r-- | apps/codecs/libwavpack/wputils.c | 354 |
12 files changed, 2190 insertions, 0 deletions
diff --git a/apps/codecs/libwavpack/LICENSE b/apps/codecs/libwavpack/LICENSE new file mode 100644 index 0000000000..3ee485817d --- /dev/null +++ b/apps/codecs/libwavpack/LICENSE | |||
@@ -0,0 +1,25 @@ | |||
1 | Copyright (c) 1998 - 2004 Conifer Software | ||
2 | All rights reserved. | ||
3 | |||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions are met: | ||
6 | |||
7 | * Redistributions of source code must retain the above copyright notice, | ||
8 | this list of conditions and the following disclaimer. | ||
9 | * Redistributions in binary form must reproduce the above copyright notice, | ||
10 | this list of conditions and the following disclaimer in the | ||
11 | documentation and/or other materials provided with the distribution. | ||
12 | * Neither the name of Conifer Software nor the names of its contributors | ||
13 | may be used to endorse or promote products derived from this software | ||
14 | without specific prior written permission. | ||
15 | |||
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
19 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR | ||
20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
diff --git a/apps/codecs/libwavpack/README b/apps/codecs/libwavpack/README new file mode 100644 index 0000000000..b373235e1c --- /dev/null +++ b/apps/codecs/libwavpack/README | |||
@@ -0,0 +1,52 @@ | |||
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 | This package contains a tiny version of the WavPack 4.0 decoder that might | ||
10 | be used in a "resource limited" CPU environment or form the basis for a | ||
11 | hardware decoding implementation. It is packaged with a demo command-line | ||
12 | program that accepts a WavPack audio file on stdin and outputs a RIFF wav | ||
13 | file to stdout. The program is standard C, and a win32 executable is | ||
14 | included which was compiled under MS Visual C++ 6.0 using this command: | ||
15 | |||
16 | cl /O1 /DWIN32 wvfilter.c wputils.c unpack.c float.c metadata.c words.c bits.c | ||
17 | |||
18 | WavPack data is read with a stream reading callback. No direct seeking is | ||
19 | provided for, but it is possible to start decoding anywhere in a WavPack | ||
20 | stream. In this case, WavPack will be able to provide the sample-accurate | ||
21 | position when it synchs with the data and begins decoding. | ||
22 | |||
23 | For demonstration purposes this uses a single static copy of the | ||
24 | WavpackContext structure, so obviously it cannot be used for more than one | ||
25 | file at a time. Also, this decoder will not handle "correction" files, plays | ||
26 | only the first two channels of multi-channel files, and is limited in | ||
27 | resolution in some large integer or floating point files (but always | ||
28 | provides at least 24 bits of resolution). It also will not accept WavPack | ||
29 | files from before version 4.0. | ||
30 | |||
31 | To make this code viable on the greatest number of hardware platforms, the | ||
32 | following are true: | ||
33 | |||
34 | speed is about 4x realtime on an AMD K6 300 MHz | ||
35 | ("high" mode 16/44 stereo; normal mode is about twice that fast) | ||
36 | |||
37 | no floating-point math required; just 32b * 32b = 32b int multiply | ||
38 | |||
39 | large data areas are static and less than 4K total | ||
40 | executable code and tables are less than 32K | ||
41 | no malloc / free usage | ||
42 | |||
43 | To maintain compatibility on various platforms, the following conventions | ||
44 | are used: | ||
45 | |||
46 | a "short" must be 16-bits | ||
47 | a "long" must be 32-bits | ||
48 | an "int" must be at least 16-bits, but may be larger | ||
49 | a "char" must default to signed | ||
50 | |||
51 | |||
52 | Questions or comments should be directed to david@wavpack.com | ||
diff --git a/apps/codecs/libwavpack/README.rockbox b/apps/codecs/libwavpack/README.rockbox new file mode 100644 index 0000000000..a74b0c511c --- /dev/null +++ b/apps/codecs/libwavpack/README.rockbox | |||
@@ -0,0 +1,15 @@ | |||
1 | Library: wavpack - Release 4.1 - September 14, 2004 | ||
2 | Imported: 2005-02-25 by Christian Gmeiner | ||
3 | |||
4 | |||
5 | This directory contains a "tiny" decoder version of wavpack for version 4.x. | ||
6 | |||
7 | LICENSING INFORMATION | ||
8 | |||
9 | wavpack is released under the BSD License as described | ||
10 | in the LICENSE file in this directory. | ||
11 | |||
12 | |||
13 | IMPORT DETAILS | ||
14 | |||
15 | Excluded is wvfilter.c, because it is only a test programm. | ||
diff --git a/apps/codecs/libwavpack/SOURCES b/apps/codecs/libwavpack/SOURCES new file mode 100644 index 0000000000..9b79d70b22 --- /dev/null +++ b/apps/codecs/libwavpack/SOURCES | |||
@@ -0,0 +1,6 @@ | |||
1 | bits.c | ||
2 | float.c | ||
3 | metadata.c | ||
4 | unpack.c | ||
5 | words.c | ||
6 | wputils.c \ No newline at end of file | ||
diff --git a/apps/codecs/libwavpack/bits.c b/apps/codecs/libwavpack/bits.c new file mode 100644 index 0000000000..25a222780f --- /dev/null +++ b/apps/codecs/libwavpack/bits.c | |||
@@ -0,0 +1,140 @@ | |||
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 | // bits.c | ||
10 | |||
11 | // This module provides utilities to support the BitStream structure which is | ||
12 | // used to read and write all WavPack audio data streams. It also contains a | ||
13 | // wrapper for the stream I/O functions and a set of functions dealing with | ||
14 | // endian-ness, both for enhancing portability. Finally, a debug wrapper for | ||
15 | // the malloc() system is provided. | ||
16 | |||
17 | #include "wavpack.h" | ||
18 | |||
19 | #include <string.h> | ||
20 | #include <ctype.h> | ||
21 | |||
22 | ////////////////////////// Bitstream functions //////////////////////////////// | ||
23 | |||
24 | // Open the specified BitStream and associate with the specified buffer. | ||
25 | |||
26 | static void bs_read (Bitstream *bs); | ||
27 | |||
28 | void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end, read_stream file, ulong file_bytes) | ||
29 | { | ||
30 | CLEAR (*bs); | ||
31 | bs->buf = buffer_start; | ||
32 | bs->end = buffer_end; | ||
33 | |||
34 | if (file) { | ||
35 | bs->ptr = bs->end - 1; | ||
36 | bs->file_bytes = file_bytes; | ||
37 | bs->file = file; | ||
38 | } | ||
39 | else | ||
40 | bs->ptr = bs->buf - 1; | ||
41 | |||
42 | bs->wrap = bs_read; | ||
43 | } | ||
44 | |||
45 | // This function is only called from the getbit() and getbits() macros when | ||
46 | // the BitStream has been exhausted and more data is required. Sinve these | ||
47 | // bistreams no longer access files, this function simple sets an error and | ||
48 | // resets the buffer. | ||
49 | |||
50 | static void bs_read (Bitstream *bs) | ||
51 | { | ||
52 | if (bs->file && bs->file_bytes) { | ||
53 | ulong bytes_read, bytes_to_read = bs->end - bs->buf; | ||
54 | |||
55 | if (bytes_to_read > bs->file_bytes) | ||
56 | bytes_to_read = bs->file_bytes; | ||
57 | |||
58 | bytes_read = bs->file (bs->buf, bytes_to_read); | ||
59 | |||
60 | if (bytes_read) { | ||
61 | bs->end = bs->buf + bytes_read; | ||
62 | bs->file_bytes -= bytes_read; | ||
63 | } | ||
64 | else { | ||
65 | memset (bs->buf, -1, bs->end - bs->buf); | ||
66 | bs->error = 1; | ||
67 | } | ||
68 | } | ||
69 | else | ||
70 | bs->error = 1; | ||
71 | |||
72 | if (bs->error) | ||
73 | memset (bs->buf, -1, bs->end - bs->buf); | ||
74 | |||
75 | bs->ptr = bs->buf; | ||
76 | } | ||
77 | |||
78 | /////////////////////// Endian Correction Routines //////////////////////////// | ||
79 | |||
80 | void little_endian_to_native (void *data, char *format) | ||
81 | { | ||
82 | uchar *cp = (uchar *) data; | ||
83 | long temp; | ||
84 | |||
85 | while (*format) { | ||
86 | switch (*format) { | ||
87 | case 'L': | ||
88 | temp = cp [0] + ((long) cp [1] << 8) + ((long) cp [2] << 16) + ((long) cp [3] << 24); | ||
89 | * (long *) cp = temp; | ||
90 | cp += 4; | ||
91 | break; | ||
92 | |||
93 | case 'S': | ||
94 | temp = cp [0] + (cp [1] << 8); | ||
95 | * (short *) cp = (short) temp; | ||
96 | cp += 2; | ||
97 | break; | ||
98 | |||
99 | default: | ||
100 | if (isdigit (*format)) | ||
101 | cp += *format - '0'; | ||
102 | |||
103 | break; | ||
104 | } | ||
105 | |||
106 | format++; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | void native_to_little_endian (void *data, char *format) | ||
111 | { | ||
112 | uchar *cp = (uchar *) data; | ||
113 | long temp; | ||
114 | |||
115 | while (*format) { | ||
116 | switch (*format) { | ||
117 | case 'L': | ||
118 | temp = * (long *) cp; | ||
119 | *cp++ = (uchar) temp; | ||
120 | *cp++ = (uchar) (temp >> 8); | ||
121 | *cp++ = (uchar) (temp >> 16); | ||
122 | *cp++ = (uchar) (temp >> 24); | ||
123 | break; | ||
124 | |||
125 | case 'S': | ||
126 | temp = * (short *) cp; | ||
127 | *cp++ = (uchar) temp; | ||
128 | *cp++ = (uchar) (temp >> 8); | ||
129 | break; | ||
130 | |||
131 | default: | ||
132 | if (isdigit (*format)) | ||
133 | cp += *format - '0'; | ||
134 | |||
135 | break; | ||
136 | } | ||
137 | |||
138 | format++; | ||
139 | } | ||
140 | } | ||
diff --git a/apps/codecs/libwavpack/float.c b/apps/codecs/libwavpack/float.c new file mode 100644 index 0000000000..3e678e824d --- /dev/null +++ b/apps/codecs/libwavpack/float.c | |||
@@ -0,0 +1,83 @@ | |||
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 | // float.c | ||
10 | |||
11 | #include "wavpack.h" | ||
12 | |||
13 | int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd) | ||
14 | { | ||
15 | int bytecnt = wpmd->byte_length; | ||
16 | char *byteptr = wpmd->data; | ||
17 | |||
18 | if (bytecnt != 4) | ||
19 | return FALSE; | ||
20 | |||
21 | wps->float_flags = *byteptr++; | ||
22 | wps->float_shift = *byteptr++; | ||
23 | wps->float_max_exp = *byteptr++; | ||
24 | wps->float_norm_exp = *byteptr; | ||
25 | return TRUE; | ||
26 | } | ||
27 | |||
28 | void float_values (WavpackStream *wps, long *values, long num_values) | ||
29 | { | ||
30 | while (num_values--) { | ||
31 | int shift_count = 0, exp = wps->float_max_exp; | ||
32 | f32 outval = { 0, 0, 0 }; | ||
33 | |||
34 | if (*values) { | ||
35 | *values <<= wps->float_shift; | ||
36 | |||
37 | if (*values < 0) { | ||
38 | *values = -*values; | ||
39 | outval.sign = 1; | ||
40 | } | ||
41 | |||
42 | if (*values == 0x1000000) | ||
43 | outval.exponent = 255; | ||
44 | else { | ||
45 | if (exp) | ||
46 | while (!(*values & 0x800000) && --exp) { | ||
47 | shift_count++; | ||
48 | *values <<= 1; | ||
49 | } | ||
50 | |||
51 | if (shift_count && (wps->float_flags & FLOAT_SHIFT_ONES)) | ||
52 | *values |= ((1 << shift_count) - 1); | ||
53 | |||
54 | outval.mantissa = *values; | ||
55 | outval.exponent = exp; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | * (f32 *) values++ = outval; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | void float_normalize (long *values, long num_values, int delta_exp) | ||
64 | { | ||
65 | f32 *fvalues = (f32 *) values, fzero = { 0, 0, 0 }; | ||
66 | int exp; | ||
67 | |||
68 | if (!delta_exp) | ||
69 | return; | ||
70 | |||
71 | while (num_values--) { | ||
72 | if ((exp = fvalues->exponent) == 0 || exp + delta_exp <= 0) | ||
73 | *fvalues = fzero; | ||
74 | else if (exp == 255 || (exp += delta_exp) >= 255) { | ||
75 | fvalues->exponent = 255; | ||
76 | fvalues->mantissa = 0; | ||
77 | } | ||
78 | else | ||
79 | fvalues->exponent = exp; | ||
80 | |||
81 | fvalues++; | ||
82 | } | ||
83 | } | ||
diff --git a/apps/codecs/libwavpack/make.bat b/apps/codecs/libwavpack/make.bat new file mode 100644 index 0000000000..0ca72d7e55 --- /dev/null +++ b/apps/codecs/libwavpack/make.bat | |||
@@ -0,0 +1 @@ | |||
cl /O1 /DWIN32 wvfilter.c wputils.c unpack.c float.c metadata.c words.c bits.c | |||
diff --git a/apps/codecs/libwavpack/metadata.c b/apps/codecs/libwavpack/metadata.c new file mode 100644 index 0000000000..40ede99cd4 --- /dev/null +++ b/apps/codecs/libwavpack/metadata.c | |||
@@ -0,0 +1,105 @@ | |||
1 | //////////////////////////////////////////////////////////////////////////// | ||
2 | // **** WAVPACK **** // | ||
3 | // Hybrid Lossless Wavefile Compressor // | ||
4 | // Copyright (c) 1998 - 2003 Conifer Software. // | ||
5 | // All Rights Reserved. // | ||
6 | // Distributed under the BSD Software License (see license.txt) // | ||
7 | //////////////////////////////////////////////////////////////////////////// | ||
8 | |||
9 | // metadata.c | ||
10 | |||
11 | // This module handles the metadata structure introduced in WavPack 4.0 | ||
12 | |||
13 | #include "wavpack.h" | ||
14 | |||
15 | int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd) | ||
16 | { | ||
17 | uchar tchar; | ||
18 | |||
19 | if (!wpc->infile (&wpmd->id, 1) || !wpc->infile (&tchar, 1)) | ||
20 | return FALSE; | ||
21 | |||
22 | wpmd->byte_length = tchar << 1; | ||
23 | |||
24 | if (wpmd->id & ID_LARGE) { | ||
25 | wpmd->id &= ~ID_LARGE; | ||
26 | |||
27 | if (!wpc->infile (&tchar, 1)) | ||
28 | return FALSE; | ||
29 | |||
30 | wpmd->byte_length += (long) tchar << 9; | ||
31 | |||
32 | if (!wpc->infile (&tchar, 1)) | ||
33 | return FALSE; | ||
34 | |||
35 | wpmd->byte_length += (long) tchar << 17; | ||
36 | } | ||
37 | |||
38 | if (wpmd->id & ID_ODD_SIZE) { | ||
39 | wpmd->id &= ~ID_ODD_SIZE; | ||
40 | wpmd->byte_length--; | ||
41 | } | ||
42 | |||
43 | if (wpmd->byte_length && wpmd->byte_length <= sizeof (wpc->read_buffer)) { | ||
44 | ulong bytes_to_read = wpmd->byte_length + (wpmd->byte_length & 1); | ||
45 | |||
46 | if (wpc->infile (wpc->read_buffer, bytes_to_read) != (long) bytes_to_read) { | ||
47 | wpmd->data = NULL; | ||
48 | return FALSE; | ||
49 | } | ||
50 | |||
51 | wpmd->data = wpc->read_buffer; | ||
52 | } | ||
53 | else | ||
54 | wpmd->data = NULL; | ||
55 | |||
56 | return TRUE; | ||
57 | } | ||
58 | |||
59 | int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd) | ||
60 | { | ||
61 | WavpackStream *wps = &wpc->stream; | ||
62 | |||
63 | switch (wpmd->id) { | ||
64 | case ID_DUMMY: | ||
65 | return TRUE; | ||
66 | |||
67 | case ID_DECORR_TERMS: | ||
68 | return read_decorr_terms (wps, wpmd); | ||
69 | |||
70 | case ID_DECORR_WEIGHTS: | ||
71 | return read_decorr_weights (wps, wpmd); | ||
72 | |||
73 | case ID_DECORR_SAMPLES: | ||
74 | return read_decorr_samples (wps, wpmd); | ||
75 | |||
76 | case ID_ENTROPY_VARS: | ||
77 | return read_entropy_vars (wps, wpmd); | ||
78 | |||
79 | case ID_HYBRID_PROFILE: | ||
80 | return read_hybrid_profile (wps, wpmd); | ||
81 | |||
82 | case ID_FLOAT_INFO: | ||
83 | return read_float_info (wps, wpmd); | ||
84 | |||
85 | case ID_INT32_INFO: | ||
86 | return read_int32_info (wps, wpmd); | ||
87 | |||
88 | case ID_CHANNEL_INFO: | ||
89 | return read_channel_info (wpc, wpmd); | ||
90 | |||
91 | case ID_CONFIG_BLOCK: | ||
92 | return read_config_info (wpc, wpmd); | ||
93 | |||
94 | case ID_WV_BITSTREAM: | ||
95 | return init_wv_bitstream (wpc, wpmd); | ||
96 | |||
97 | case ID_SHAPING_WEIGHTS: | ||
98 | case ID_WVC_BITSTREAM: | ||
99 | case ID_WVX_BITSTREAM: | ||
100 | return TRUE; | ||
101 | |||
102 | default: | ||
103 | return (wpmd->id & ID_OPTIONAL_DATA) ? TRUE : FALSE; | ||
104 | } | ||
105 | } | ||
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 | |||
48 | int 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 | |||
92 | int 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 | |||
112 | int 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 | |||
140 | int 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 | |||
173 | int 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 | |||
232 | int 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 | |||
251 | int 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 | |||
273 | int 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 | |||
304 | static void fixup_samples (WavpackStream *wps, long *buffer, ulong sample_count); | ||
305 | |||
306 | long 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 | |||
482 | static 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 | |||
567 | int 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 | } | ||
diff --git a/apps/codecs/libwavpack/wavpack.h b/apps/codecs/libwavpack/wavpack.h new file mode 100644 index 0000000000..af9d88dfe6 --- /dev/null +++ b/apps/codecs/libwavpack/wavpack.h | |||
@@ -0,0 +1,330 @@ | |||
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 | // wavpack.h | ||
10 | |||
11 | #include <sys/types.h> | ||
12 | |||
13 | // This header file contains all the definitions required by WavPack. | ||
14 | |||
15 | typedef unsigned char uchar; | ||
16 | #if !defined(__GNUC__) || defined(WIN32) | ||
17 | typedef unsigned short ushort; | ||
18 | typedef unsigned long ulong; | ||
19 | typedef unsigned int uint; | ||
20 | #elif defined(__APPLE__) | ||
21 | typedef unsigned long ulong; | ||
22 | #endif | ||
23 | |||
24 | // This structure is used to access the individual fields of 32-bit ieee | ||
25 | // floating point numbers. This will not be compatible with compilers that | ||
26 | // allocate bit fields from the most significant bits, although I'm not sure | ||
27 | // how common that is. | ||
28 | |||
29 | typedef struct { | ||
30 | unsigned mantissa : 23; | ||
31 | unsigned exponent : 8; | ||
32 | unsigned sign : 1; | ||
33 | } f32; | ||
34 | |||
35 | #include <stdio.h> | ||
36 | |||
37 | #define FALSE 0 | ||
38 | #define TRUE 1 | ||
39 | |||
40 | ////////////////////////////// WavPack Header ///////////////////////////////// | ||
41 | |||
42 | // Note that this is the ONLY structure that is written to (or read from) | ||
43 | // WavPack 4.0 files, and is the preamble to every block in both the .wv | ||
44 | // and .wvc files. | ||
45 | |||
46 | typedef struct { | ||
47 | char ckID [4]; | ||
48 | ulong ckSize; | ||
49 | short version; | ||
50 | uchar track_no, index_no; | ||
51 | ulong total_samples, block_index, block_samples, flags, crc; | ||
52 | } WavpackHeader; | ||
53 | |||
54 | #define WavpackHeaderFormat "4LS2LLLLL" | ||
55 | |||
56 | // or-values for "flags" | ||
57 | |||
58 | #define BYTES_STORED 3 // 1-4 bytes/sample | ||
59 | #define MONO_FLAG 4 // not stereo | ||
60 | #define HYBRID_FLAG 8 // hybrid mode | ||
61 | #define JOINT_STEREO 0x10 // joint stereo | ||
62 | #define CROSS_DECORR 0x20 // no-delay cross decorrelation | ||
63 | #define HYBRID_SHAPE 0x40 // noise shape (hybrid mode only) | ||
64 | #define FLOAT_DATA 0x80 // ieee 32-bit floating point data | ||
65 | |||
66 | #define INT32_DATA 0x100 // special extended int handling | ||
67 | #define HYBRID_BITRATE 0x200 // bitrate noise (hybrid mode only) | ||
68 | #define HYBRID_BALANCE 0x400 // balance noise (hybrid stereo mode only) | ||
69 | |||
70 | #define INITIAL_BLOCK 0x800 // initial block of multichannel segment | ||
71 | #define FINAL_BLOCK 0x1000 // final block of multichannel segment | ||
72 | |||
73 | #define SHIFT_LSB 13 | ||
74 | #define SHIFT_MASK (0x1fL << SHIFT_LSB) | ||
75 | |||
76 | #define MAG_LSB 18 | ||
77 | #define MAG_MASK (0x1fL << MAG_LSB) | ||
78 | |||
79 | #define SRATE_LSB 23 | ||
80 | #define SRATE_MASK (0xfL << SRATE_LSB) | ||
81 | |||
82 | #define IGNORED_FLAGS 0x18000000 // reserved, but ignore if encountered | ||
83 | #define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping | ||
84 | #define UNKNOWN_FLAGS 0xC0000000 // also reserved, but refuse decode if | ||
85 | // encountered | ||
86 | |||
87 | //////////////////////////// WavPack Metadata ///////////////////////////////// | ||
88 | |||
89 | // This is an internal representation of metadata. | ||
90 | |||
91 | typedef struct { | ||
92 | long byte_length; | ||
93 | void *data; | ||
94 | uchar id; | ||
95 | } WavpackMetadata; | ||
96 | |||
97 | #define ID_OPTIONAL_DATA 0x20 | ||
98 | #define ID_ODD_SIZE 0x40 | ||
99 | #define ID_LARGE 0x80 | ||
100 | |||
101 | #define ID_DUMMY 0x0 | ||
102 | #define ID_ENCODER_INFO 0x1 | ||
103 | #define ID_DECORR_TERMS 0x2 | ||
104 | #define ID_DECORR_WEIGHTS 0x3 | ||
105 | #define ID_DECORR_SAMPLES 0x4 | ||
106 | #define ID_ENTROPY_VARS 0x5 | ||
107 | #define ID_HYBRID_PROFILE 0x6 | ||
108 | #define ID_SHAPING_WEIGHTS 0x7 | ||
109 | #define ID_FLOAT_INFO 0x8 | ||
110 | #define ID_INT32_INFO 0x9 | ||
111 | #define ID_WV_BITSTREAM 0xa | ||
112 | #define ID_WVC_BITSTREAM 0xb | ||
113 | #define ID_WVX_BITSTREAM 0xc | ||
114 | #define ID_CHANNEL_INFO 0xd | ||
115 | |||
116 | #define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1) | ||
117 | #define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2) | ||
118 | #define ID_REPLAY_GAIN (ID_OPTIONAL_DATA | 0x3) | ||
119 | #define ID_CUESHEET (ID_OPTIONAL_DATA | 0x4) | ||
120 | #define ID_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0x5) | ||
121 | #define ID_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x6) | ||
122 | |||
123 | ///////////////////////// WavPack Configuration /////////////////////////////// | ||
124 | |||
125 | // This internal structure is used during encode to provide configuration to | ||
126 | // the encoding engine and during decoding to provide fle information back to | ||
127 | // the higher level functions. Not all fields are used in both modes. | ||
128 | |||
129 | typedef struct { | ||
130 | int bits_per_sample, bytes_per_sample; | ||
131 | int qmode, flags, xmode, num_channels, float_norm_exp; | ||
132 | long block_samples, extra_flags, sample_rate, channel_mask; | ||
133 | } WavpackConfig; | ||
134 | |||
135 | #define CONFIG_BYTES_STORED 3 // 1-4 bytes/sample | ||
136 | #define CONFIG_MONO_FLAG 4 // not stereo | ||
137 | #define CONFIG_HYBRID_FLAG 8 // hybrid mode | ||
138 | #define CONFIG_JOINT_STEREO 0x10 // joint stereo | ||
139 | #define CONFIG_CROSS_DECORR 0x20 // no-delay cross decorrelation | ||
140 | #define CONFIG_HYBRID_SHAPE 0x40 // noise shape (hybrid mode only) | ||
141 | #define CONFIG_FLOAT_DATA 0x80 // ieee 32-bit floating point data | ||
142 | |||
143 | #define CONFIG_ADOBE_MODE 0x100 // "adobe" mode for 32-bit floats | ||
144 | #define CONFIG_FAST_FLAG 0x200 // fast mode | ||
145 | #define CONFIG_VERY_FAST_FLAG 0x400 // double fast | ||
146 | #define CONFIG_HIGH_FLAG 0x800 // high quality mode | ||
147 | #define CONFIG_VERY_HIGH_FLAG 0x1000 // double high (not used yet) | ||
148 | #define CONFIG_BITRATE_KBPS 0x2000 // bitrate is kbps, not bits / sample | ||
149 | #define CONFIG_AUTO_SHAPING 0x4000 // automatic noise shaping | ||
150 | #define CONFIG_SHAPE_OVERRIDE 0x8000 // shaping mode specified | ||
151 | #define CONFIG_JOINT_OVERRIDE 0x10000 // joint-stereo mode specified | ||
152 | #define CONFIG_COPY_TIME 0x20000 // copy file-time from source | ||
153 | #define CONFIG_CREATE_EXE 0x40000 // create executable (not yet) | ||
154 | #define CONFIG_CREATE_WVC 0x80000 // create correction file | ||
155 | #define CONFIG_OPTIMIZE_WVC 0x100000 // maximize bybrid compression | ||
156 | #define CONFIG_QUALITY_MODE 0x200000 // psychoacoustic quality mode | ||
157 | #define CONFIG_RAW_FLAG 0x400000 // raw mode (not implemented yet) | ||
158 | #define CONFIG_CALC_NOISE 0x800000 // calc noise in hybrid mode | ||
159 | #define CONFIG_LOSSY_MODE 0x1000000 // obsolete (for information) | ||
160 | #define CONFIG_EXTRA_MODE 0x2000000 // extra processing mode | ||
161 | #define CONFIG_SKIP_WVX 0x4000000 // no wvx stream w/ floats & big ints | ||
162 | #define CONFIG_MD5_CHECKSUM 0x8000000 // compute & store MD5 signature | ||
163 | #define CONFIG_QUIET_MODE 0x10000000 // don't report progress % | ||
164 | |||
165 | //////////////////////////////// WavPack Stream /////////////////////////////// | ||
166 | |||
167 | // This internal structure contains everything required to handle a WavPack | ||
168 | // "stream", which is defined as a stereo or mono stream of audio samples. For | ||
169 | // multichannel audio several of these would be required. Each stream contains | ||
170 | // pointers to hold a complete allocated block of WavPack data, although it's | ||
171 | // possible to decode WavPack blocks without buffering an entire block. | ||
172 | |||
173 | typedef long (*read_stream)(void *, long); | ||
174 | |||
175 | typedef struct bs { | ||
176 | uchar *buf, *end, *ptr; | ||
177 | void (*wrap)(struct bs *bs); | ||
178 | ulong file_bytes, sr; | ||
179 | int error, bc; | ||
180 | read_stream file; | ||
181 | } Bitstream; | ||
182 | |||
183 | #define MAX_NTERMS 16 | ||
184 | #define MAX_TERM 8 | ||
185 | |||
186 | struct decorr_pass { | ||
187 | short term, delta, weight_A, weight_B; | ||
188 | long samples_A [MAX_TERM], samples_B [MAX_TERM]; | ||
189 | }; | ||
190 | |||
191 | typedef struct { | ||
192 | WavpackHeader wphdr; | ||
193 | |||
194 | int num_terms, mute_error; | ||
195 | ulong sample_index, crc; | ||
196 | Bitstream wvbits; | ||
197 | |||
198 | uchar int32_sent_bits, int32_zeros, int32_ones, int32_dups; | ||
199 | uchar float_flags, float_shift, float_max_exp, float_norm_exp; | ||
200 | |||
201 | struct decorr_pass decorr_passes [MAX_NTERMS]; | ||
202 | |||
203 | struct { | ||
204 | ulong bitrate_delta [2], bitrate_acc [2]; | ||
205 | ulong median [3] [2], slow_level [2], error_limit [2]; | ||
206 | ulong pend_data, holding_one, zeros_acc; | ||
207 | int holding_zero, pend_count; | ||
208 | } w; | ||
209 | } WavpackStream; | ||
210 | |||
211 | // flags for float_flags: | ||
212 | |||
213 | #define FLOAT_SHIFT_ONES 1 // bits left-shifted into float = '1' | ||
214 | #define FLOAT_SHIFT_SAME 2 // bits left-shifted into float are the same | ||
215 | #define FLOAT_SHIFT_SENT 4 // bits shifted into float are sent literally | ||
216 | #define FLOAT_ZEROS_SENT 8 // "zeros" are not all real zeros | ||
217 | #define FLOAT_NEG_ZEROS 0x10 // contains negative zeros | ||
218 | #define FLOAT_EXCEPTIONS 0x20 // contains exceptions (inf, nan, etc.) | ||
219 | |||
220 | /////////////////////////////// WavPack Context /////////////////////////////// | ||
221 | |||
222 | // This internal structure holds everything required to encode or decode WavPack | ||
223 | // files. It is recommended that direct access to this structure be minimized | ||
224 | // and the provided utilities used instead. | ||
225 | |||
226 | typedef struct { | ||
227 | WavpackConfig config; | ||
228 | WavpackStream stream; | ||
229 | |||
230 | uchar read_buffer [1024]; | ||
231 | char error_message [80]; | ||
232 | |||
233 | read_stream infile; | ||
234 | ulong total_samples, crc_errors, first_flags; | ||
235 | int open_flags, norm_offset, reduced_channels, lossy_blocks; | ||
236 | |||
237 | } WavpackContext; | ||
238 | |||
239 | //////////////////////// function prototypes and macros ////////////////////// | ||
240 | |||
241 | #define CLEAR(destin) memset (&destin, 0, sizeof (destin)); | ||
242 | |||
243 | // bits.c | ||
244 | |||
245 | void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end, read_stream file, ulong file_bytes); | ||
246 | |||
247 | #define bs_is_open(bs) ((bs)->ptr != NULL) | ||
248 | |||
249 | #define getbit(bs) ( \ | ||
250 | (((bs)->bc) ? \ | ||
251 | ((bs)->bc--, (bs)->sr & 1) : \ | ||
252 | (((++((bs)->ptr) != (bs)->end) ? (void) 0 : (bs)->wrap (bs)), (bs)->bc = 7, ((bs)->sr = *((bs)->ptr)) & 1) \ | ||
253 | ) ? \ | ||
254 | ((bs)->sr >>= 1, 1) : \ | ||
255 | ((bs)->sr >>= 1, 0) \ | ||
256 | ) | ||
257 | |||
258 | #define getbits(value, nbits, bs) { \ | ||
259 | while ((nbits) > (bs)->bc) { \ | ||
260 | if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \ | ||
261 | (bs)->sr |= (long)*((bs)->ptr) << (bs)->bc; \ | ||
262 | (bs)->bc += 8; \ | ||
263 | } \ | ||
264 | *(value) = (bs)->sr; \ | ||
265 | (bs)->sr >>= (nbits); \ | ||
266 | (bs)->bc -= (nbits); \ | ||
267 | } | ||
268 | |||
269 | void little_endian_to_native (void *data, char *format); | ||
270 | void native_to_little_endian (void *data, char *format); | ||
271 | |||
272 | // unpack.c | ||
273 | |||
274 | int unpack_init (WavpackContext *wpc); | ||
275 | int init_wv_bitstream (WavpackContext *wpc, WavpackMetadata *wpmd); | ||
276 | int read_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd); | ||
277 | int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd); | ||
278 | int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd); | ||
279 | int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd); | ||
280 | int read_int32_info (WavpackStream *wps, WavpackMetadata *wpmd); | ||
281 | int read_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd); | ||
282 | int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd); | ||
283 | long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count); | ||
284 | int check_crc_error (WavpackContext *wpc); | ||
285 | |||
286 | // metadata.c stuff | ||
287 | |||
288 | int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd); | ||
289 | int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd); | ||
290 | |||
291 | // words.c stuff | ||
292 | |||
293 | int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd); | ||
294 | int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd); | ||
295 | long get_word (WavpackStream *wps, int chan); | ||
296 | long exp2s (int log); | ||
297 | int restore_weight (char weight); | ||
298 | |||
299 | #define WORD_EOF (1L << 31) | ||
300 | |||
301 | // float.c | ||
302 | |||
303 | int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd); | ||
304 | void float_values (WavpackStream *wps, long *values, long num_values); | ||
305 | void float_normalize (long *values, long num_values, int delta_exp); | ||
306 | |||
307 | // wputils.c | ||
308 | |||
309 | WavpackContext *WavpackOpenFileInput (read_stream infile, char *error); | ||
310 | |||
311 | int WavpackGetMode (WavpackContext *wpc); | ||
312 | |||
313 | #define MODE_WVC 0x1 | ||
314 | #define MODE_LOSSLESS 0x2 | ||
315 | #define MODE_HYBRID 0x4 | ||
316 | #define MODE_FLOAT 0x8 | ||
317 | #define MODE_VALID_TAG 0x10 | ||
318 | #define MODE_HIGH 0x20 | ||
319 | #define MODE_FAST 0x40 | ||
320 | |||
321 | ulong WavpackUnpackSamples (WavpackContext *wpc, long *buffer, ulong samples); | ||
322 | ulong WavpackGetNumSamples (WavpackContext *wpc); | ||
323 | ulong WavpackGetSampleIndex (WavpackContext *wpc); | ||
324 | int WavpackGetNumErrors (WavpackContext *wpc); | ||
325 | int WavpackLossyBlocks (WavpackContext *wpc); | ||
326 | ulong WavpackGetSampleRate (WavpackContext *wpc); | ||
327 | int WavpackGetBitsPerSample (WavpackContext *wpc); | ||
328 | int WavpackGetBytesPerSample (WavpackContext *wpc); | ||
329 | int WavpackGetNumChannels (WavpackContext *wpc); | ||
330 | int WavpackGetReducedChannels (WavpackContext *wpc); | ||
diff --git a/apps/codecs/libwavpack/words.c b/apps/codecs/libwavpack/words.c new file mode 100644 index 0000000000..35061b69a9 --- /dev/null +++ b/apps/codecs/libwavpack/words.c | |||
@@ -0,0 +1,503 @@ | |||
1 | //////////////////////////////////////////////////////////////////////////// | ||
2 | // **** WAVPACK **** // | ||
3 | // Hybrid Lossless Wavefile Compressor // | ||
4 | // Copyright (c) 1998 - 2004 Conifer Software. // | ||
5 | // All Rights Reserved. // | ||
6 | //////////////////////////////////////////////////////////////////////////// | ||
7 | |||
8 | // words.c | ||
9 | |||
10 | // This module provides entropy word encoding and decoding functions using | ||
11 | // a variation on the Rice method. This was introduced in version 3.93 | ||
12 | // because it allows splitting the data into a "lossy" stream and a | ||
13 | // "correction" stream in a very efficient manner and is therefore ideal | ||
14 | // for the "hybrid" mode. For 4.0, the efficiency of this method was | ||
15 | // significantly improved by moving away from the normal Rice restriction of | ||
16 | // using powers of two for the modulus divisions and now the method can be | ||
17 | // used for both hybrid and pure lossless encoding. | ||
18 | |||
19 | // Samples are divided by median probabilities at 5/7 (71.43%), 10/49 (20.41%), | ||
20 | // and 20/343 (5.83%). Each zone has 3.5 times fewer samples than the | ||
21 | // previous. Using standard Rice coding on this data would result in 1.4 | ||
22 | // bits per sample average (not counting sign bit). However, there is a | ||
23 | // very simple encoding that is over 99% efficient with this data and | ||
24 | // results in about 1.22 bits per sample. | ||
25 | |||
26 | #include "wavpack.h" | ||
27 | |||
28 | #include <string.h> | ||
29 | |||
30 | //////////////////////////////// local macros ///////////////////////////////// | ||
31 | |||
32 | #define LIMIT_ONES 16 // maximum consecutive 1s sent for "div" data | ||
33 | |||
34 | // these control the time constant "slow_level" which is used for hybrid mode | ||
35 | // that controls bitrate as a function of residual level (HYBRID_BITRATE). | ||
36 | #define SLS 8 | ||
37 | #define SLO ((1 << (SLS - 1))) | ||
38 | |||
39 | // these control the time constant of the 3 median level breakpoints | ||
40 | #define DIV0 128 // 5/7 of samples | ||
41 | #define DIV1 64 // 10/49 of samples | ||
42 | #define DIV2 32 // 20/343 of samples | ||
43 | |||
44 | // this macro retrieves the specified median breakpoint (without frac; min = 1) | ||
45 | #define GET_MED(med) (((wps->w.median [med] [chan]) >> 4) + 1) | ||
46 | |||
47 | // These macros update the specified median breakpoints. Note that the median | ||
48 | // is incremented when the sample is higher than the median, else decremented. | ||
49 | // They are designed so that the median will never drop below 1 and the value | ||
50 | // is essentially stationary if there are 2 increments for every 5 decrements. | ||
51 | |||
52 | #define INC_MED0() (wps->w.median [0] [chan] += ((wps->w.median [0] [chan] + DIV0) / DIV0) * 5) | ||
53 | #define DEC_MED0() (wps->w.median [0] [chan] -= ((wps->w.median [0] [chan] + (DIV0-2)) / DIV0) * 2) | ||
54 | #define INC_MED1() (wps->w.median [1] [chan] += ((wps->w.median [1] [chan] + DIV1) / DIV1) * 5) | ||
55 | #define DEC_MED1() (wps->w.median [1] [chan] -= ((wps->w.median [1] [chan] + (DIV1-2)) / DIV1) * 2) | ||
56 | #define INC_MED2() (wps->w.median [2] [chan] += ((wps->w.median [2] [chan] + DIV2) / DIV2) * 5) | ||
57 | #define DEC_MED2() (wps->w.median [2] [chan] -= ((wps->w.median [2] [chan] + (DIV2-2)) / DIV2) * 2) | ||
58 | |||
59 | #define count_bits(av) ( \ | ||
60 | (av) < (1 << 8) ? nbits_table [av] : \ | ||
61 | ( \ | ||
62 | (av) < (1L << 16) ? nbits_table [(av) >> 8] + 8 : \ | ||
63 | ((av) < (1L << 24) ? nbits_table [(av) >> 16] + 16 : nbits_table [(av) >> 24] + 24) \ | ||
64 | ) \ | ||
65 | ) | ||
66 | |||
67 | ///////////////////////////// local table storage //////////////////////////// | ||
68 | |||
69 | const char nbits_table [] = { | ||
70 | 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, // 0 - 15 | ||
71 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 16 - 31 | ||
72 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 32 - 47 | ||
73 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 48 - 63 | ||
74 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 64 - 79 | ||
75 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 80 - 95 | ||
76 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 96 - 111 | ||
77 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 112 - 127 | ||
78 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 128 - 143 | ||
79 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 144 - 159 | ||
80 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 160 - 175 | ||
81 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 176 - 191 | ||
82 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 192 - 207 | ||
83 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 208 - 223 | ||
84 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 224 - 239 | ||
85 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 // 240 - 255 | ||
86 | }; | ||
87 | |||
88 | static const uchar log2_table [] = { | ||
89 | 0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15, | ||
90 | 0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, | ||
91 | 0x2c, 0x2d, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e, | ||
92 | 0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x51, | ||
93 | 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, | ||
94 | 0x64, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75, | ||
95 | 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, | ||
96 | 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, | ||
97 | 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, | ||
98 | 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb2, | ||
99 | 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc0, | ||
100 | 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xce, | ||
101 | 0xcf, 0xd0, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xdb, | ||
102 | 0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe4, 0xe5, 0xe6, 0xe7, 0xe7, | ||
103 | 0xe8, 0xe9, 0xea, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xee, 0xef, 0xf0, 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, | ||
104 | 0xf4, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0xff | ||
105 | }; | ||
106 | |||
107 | static const uchar exp2_table [] = { | ||
108 | 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b, | ||
109 | 0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16, | ||
110 | 0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23, | ||
111 | 0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, | ||
112 | 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d, | ||
113 | 0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b, | ||
114 | 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, | ||
115 | 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, | ||
116 | 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, | ||
117 | 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, | ||
118 | 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, | ||
119 | 0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, | ||
120 | 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, | ||
121 | 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4, | ||
122 | 0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9, | ||
123 | 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff | ||
124 | }; | ||
125 | |||
126 | ///////////////////////////// executable code //////////////////////////////// | ||
127 | |||
128 | static int log2 (unsigned long avalue); | ||
129 | |||
130 | // Read the median log2 values from the specifed metadata structure, convert | ||
131 | // them back to 32-bit unsigned values and store them. If length is not | ||
132 | // exactly correct then we flag and return an error. | ||
133 | |||
134 | int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd) | ||
135 | { | ||
136 | uchar *byteptr = wpmd->data; | ||
137 | |||
138 | if (wpmd->byte_length != ((wps->wphdr.flags & MONO_FLAG) ? 6 : 12)) | ||
139 | return FALSE; | ||
140 | |||
141 | wps->w.median [0] [0] = exp2s (byteptr [0] + (byteptr [1] << 8)); | ||
142 | wps->w.median [1] [0] = exp2s (byteptr [2] + (byteptr [3] << 8)); | ||
143 | wps->w.median [2] [0] = exp2s (byteptr [4] + (byteptr [5] << 8)); | ||
144 | |||
145 | if (!(wps->wphdr.flags & MONO_FLAG)) { | ||
146 | wps->w.median [0] [1] = exp2s (byteptr [6] + (byteptr [7] << 8)); | ||
147 | wps->w.median [1] [1] = exp2s (byteptr [8] + (byteptr [9] << 8)); | ||
148 | wps->w.median [2] [1] = exp2s (byteptr [10] + (byteptr [11] << 8)); | ||
149 | } | ||
150 | |||
151 | return TRUE; | ||
152 | } | ||
153 | |||
154 | // Read the hybrid related values from the specifed metadata structure, convert | ||
155 | // them back to their internal formats and store them. The extended profile | ||
156 | // stuff is not implemented yet, so return an error if we get more data than | ||
157 | // we know what to do with. | ||
158 | |||
159 | int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd) | ||
160 | { | ||
161 | uchar *byteptr = wpmd->data; | ||
162 | uchar *endptr = byteptr + wpmd->byte_length; | ||
163 | |||
164 | if (wps->wphdr.flags & HYBRID_BITRATE) { | ||
165 | wps->w.slow_level [0] = exp2s (byteptr [0] + (byteptr [1] << 8)); | ||
166 | byteptr += 2; | ||
167 | |||
168 | if (!(wps->wphdr.flags & MONO_FLAG)) { | ||
169 | wps->w.slow_level [1] = exp2s (byteptr [0] + (byteptr [1] << 8)); | ||
170 | byteptr += 2; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | wps->w.bitrate_acc [0] = (long)(byteptr [0] + (byteptr [1] << 8)) << 16; | ||
175 | byteptr += 2; | ||
176 | |||
177 | if (!(wps->wphdr.flags & MONO_FLAG)) { | ||
178 | wps->w.bitrate_acc [1] = (long)(byteptr [0] + (byteptr [1] << 8)) << 16; | ||
179 | byteptr += 2; | ||
180 | } | ||
181 | |||
182 | if (byteptr < endptr) { | ||
183 | wps->w.bitrate_delta [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8))); | ||
184 | byteptr += 2; | ||
185 | |||
186 | if (!(wps->wphdr.flags & MONO_FLAG)) { | ||
187 | wps->w.bitrate_delta [1] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8))); | ||
188 | byteptr += 2; | ||
189 | } | ||
190 | |||
191 | if (byteptr < endptr) | ||
192 | return FALSE; | ||
193 | } | ||
194 | else | ||
195 | wps->w.bitrate_delta [0] = wps->w.bitrate_delta [1] = 0; | ||
196 | |||
197 | return TRUE; | ||
198 | } | ||
199 | |||
200 | // This function is called during both encoding and decoding of hybrid data to | ||
201 | // update the "error_limit" variable which determines the maximum sample error | ||
202 | // allowed in the main bitstream. In the HYBRID_BITRATE mode (which is the only | ||
203 | // currently implemented) this is calculated from the slow_level values and the | ||
204 | // bitrate accumulators. Note that the bitrate accumulators can be changing. | ||
205 | |||
206 | static void update_error_limit (WavpackStream *wps) | ||
207 | { | ||
208 | int bitrate_0 = (wps->w.bitrate_acc [0] += wps->w.bitrate_delta [0]) >> 16; | ||
209 | |||
210 | if (wps->wphdr.flags & MONO_FLAG) { | ||
211 | if (wps->wphdr.flags & HYBRID_BITRATE) { | ||
212 | int slow_log_0 = (wps->w.slow_level [0] + SLO) >> SLS; | ||
213 | |||
214 | if (slow_log_0 - bitrate_0 > -0x100) | ||
215 | wps->w.error_limit [0] = exp2s (slow_log_0 - bitrate_0 + 0x100); | ||
216 | else | ||
217 | wps->w.error_limit [0] = 0; | ||
218 | } | ||
219 | else | ||
220 | wps->w.error_limit [0] = exp2s (bitrate_0); | ||
221 | } | ||
222 | else { | ||
223 | int bitrate_1 = (wps->w.bitrate_acc [1] += wps->w.bitrate_delta [1]) >> 16; | ||
224 | |||
225 | if (wps->wphdr.flags & HYBRID_BITRATE) { | ||
226 | int slow_log_0 = (wps->w.slow_level [0] + SLO) >> SLS; | ||
227 | int slow_log_1 = (wps->w.slow_level [1] + SLO) >> SLS; | ||
228 | |||
229 | if (wps->wphdr.flags & HYBRID_BALANCE) { | ||
230 | int balance = (slow_log_1 - slow_log_0 + bitrate_1 + 1) >> 1; | ||
231 | |||
232 | if (balance > bitrate_0) { | ||
233 | bitrate_1 = bitrate_0 * 2; | ||
234 | bitrate_0 = 0; | ||
235 | } | ||
236 | else if (-balance > bitrate_0) { | ||
237 | bitrate_0 = bitrate_0 * 2; | ||
238 | bitrate_1 = 0; | ||
239 | } | ||
240 | else { | ||
241 | bitrate_1 = bitrate_0 + balance; | ||
242 | bitrate_0 = bitrate_0 - balance; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | if (slow_log_0 - bitrate_0 > -0x100) | ||
247 | wps->w.error_limit [0] = exp2s (slow_log_0 - bitrate_0 + 0x100); | ||
248 | else | ||
249 | wps->w.error_limit [0] = 0; | ||
250 | |||
251 | if (slow_log_1 - bitrate_1 > -0x100) | ||
252 | wps->w.error_limit [1] = exp2s (slow_log_1 - bitrate_1 + 0x100); | ||
253 | else | ||
254 | wps->w.error_limit [1] = 0; | ||
255 | } | ||
256 | else { | ||
257 | wps->w.error_limit [0] = exp2s (bitrate_0); | ||
258 | wps->w.error_limit [1] = exp2s (bitrate_1); | ||
259 | } | ||
260 | } | ||
261 | } | ||
262 | |||
263 | static ulong read_code (Bitstream *bs, ulong maxcode); | ||
264 | |||
265 | // Read the next word from the bitstream "wvbits" and return the value. This | ||
266 | // function can be used for hybrid or lossless streams, but since an | ||
267 | // optimized version is available for lossless this function would normally | ||
268 | // be used for hybrid only. If a hybrid lossless stream is being read then | ||
269 | // the "correction" offset is written at the specified pointer. A return value | ||
270 | // of WORD_EOF indicates that the end of the bitstream was reached (all 1s) or | ||
271 | // some other error occurred. | ||
272 | |||
273 | long get_word (WavpackStream *wps, int chan) | ||
274 | { | ||
275 | ulong ones_count, low, mid, high; | ||
276 | int sign; | ||
277 | |||
278 | if (wps->w.zeros_acc) { | ||
279 | if (--wps->w.zeros_acc) { | ||
280 | wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; | ||
281 | return 0; | ||
282 | } | ||
283 | } | ||
284 | else if (!wps->w.holding_zero && !wps->w.holding_one && !(wps->w.median [0] [0] & ~1) && !(wps->w.median [0] [1] & ~1)) { | ||
285 | ulong mask; | ||
286 | int cbits; | ||
287 | |||
288 | for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); | ||
289 | |||
290 | if (cbits == 33) | ||
291 | return WORD_EOF; | ||
292 | |||
293 | if (cbits < 2) | ||
294 | wps->w.zeros_acc = cbits; | ||
295 | else { | ||
296 | for (mask = 1, wps->w.zeros_acc = 0; --cbits; mask <<= 1) | ||
297 | if (getbit (&wps->wvbits)) | ||
298 | wps->w.zeros_acc |= mask; | ||
299 | |||
300 | wps->w.zeros_acc |= mask; | ||
301 | } | ||
302 | |||
303 | if (wps->w.zeros_acc) { | ||
304 | wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; | ||
305 | CLEAR (wps->w.median); | ||
306 | return 0; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | if (wps->w.holding_zero) | ||
311 | ones_count = wps->w.holding_zero = 0; | ||
312 | else { | ||
313 | #ifdef LIMIT_ONES | ||
314 | for (ones_count = 0; ones_count < (LIMIT_ONES + 1) && getbit (&wps->wvbits); ++ones_count); | ||
315 | |||
316 | if (ones_count == (LIMIT_ONES + 1)) | ||
317 | return WORD_EOF; | ||
318 | |||
319 | if (ones_count == LIMIT_ONES) { | ||
320 | ulong mask; | ||
321 | int cbits; | ||
322 | |||
323 | for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); | ||
324 | |||
325 | if (cbits == 33) | ||
326 | return WORD_EOF; | ||
327 | |||
328 | if (cbits < 2) | ||
329 | ones_count = cbits; | ||
330 | else { | ||
331 | for (mask = 1, ones_count = 0; --cbits; mask <<= 1) | ||
332 | if (getbit (&wps->wvbits)) | ||
333 | ones_count |= mask; | ||
334 | |||
335 | ones_count |= mask; | ||
336 | } | ||
337 | |||
338 | ones_count += LIMIT_ONES; | ||
339 | } | ||
340 | #else | ||
341 | for (ones_count = 0; getbit (&wps->wvbits); ++ones_count); | ||
342 | #endif | ||
343 | |||
344 | if (wps->w.holding_one) { | ||
345 | wps->w.holding_one = ones_count & 1; | ||
346 | ones_count = (ones_count >> 1) + 1; | ||
347 | } | ||
348 | else { | ||
349 | wps->w.holding_one = ones_count & 1; | ||
350 | ones_count >>= 1; | ||
351 | } | ||
352 | |||
353 | wps->w.holding_zero = ~wps->w.holding_one & 1; | ||
354 | } | ||
355 | |||
356 | if ((wps->wphdr.flags & HYBRID_FLAG) && !chan) | ||
357 | update_error_limit (wps); | ||
358 | |||
359 | if (ones_count == 0) { | ||
360 | low = 0; | ||
361 | high = GET_MED (0) - 1; | ||
362 | DEC_MED0 (); | ||
363 | } | ||
364 | else { | ||
365 | low = GET_MED (0); | ||
366 | INC_MED0 (); | ||
367 | |||
368 | if (ones_count == 1) { | ||
369 | high = low + GET_MED (1) - 1; | ||
370 | DEC_MED1 (); | ||
371 | } | ||
372 | else { | ||
373 | low += GET_MED (1); | ||
374 | INC_MED1 (); | ||
375 | |||
376 | if (ones_count == 2) { | ||
377 | high = low + GET_MED (2) - 1; | ||
378 | DEC_MED2 (); | ||
379 | } | ||
380 | else { | ||
381 | low += (ones_count - 2) * GET_MED (2); | ||
382 | high = low + GET_MED (2) - 1; | ||
383 | INC_MED2 (); | ||
384 | } | ||
385 | } | ||
386 | } | ||
387 | |||
388 | mid = (high + low + 1) >> 1; | ||
389 | |||
390 | if (!wps->w.error_limit [chan]) | ||
391 | mid = read_code (&wps->wvbits, high - low) + low; | ||
392 | else while (high - low > wps->w.error_limit [chan]) { | ||
393 | if (getbit (&wps->wvbits)) | ||
394 | mid = (high + (low = mid) + 1) >> 1; | ||
395 | else | ||
396 | mid = ((high = mid - 1) + low + 1) >> 1; | ||
397 | } | ||
398 | |||
399 | sign = getbit (&wps->wvbits); | ||
400 | |||
401 | if (wps->wphdr.flags & HYBRID_BITRATE) { | ||
402 | wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; | ||
403 | wps->w.slow_level [chan] += log2 (mid); | ||
404 | } | ||
405 | |||
406 | return sign ? ~mid : mid; | ||
407 | } | ||
408 | |||
409 | // Read a single unsigned value from the specified bitstream with a value | ||
410 | // from 0 to maxcode. If there are exactly a power of two number of possible | ||
411 | // codes then this will read a fixed number of bits; otherwise it reads the | ||
412 | // minimum number of bits and then determines whether another bit is needed | ||
413 | // to define the code. | ||
414 | |||
415 | static ulong read_code (Bitstream *bs, ulong maxcode) | ||
416 | { | ||
417 | int bitcount = count_bits (maxcode); | ||
418 | ulong extras = (1L << bitcount) - maxcode - 1, code; | ||
419 | |||
420 | if (!bitcount) | ||
421 | return 0; | ||
422 | |||
423 | getbits (&code, bitcount - 1, bs); | ||
424 | code &= (1L << (bitcount - 1)) - 1; | ||
425 | |||
426 | if (code >= extras) { | ||
427 | code = (code << 1) - extras; | ||
428 | |||
429 | if (getbit (bs)) | ||
430 | ++code; | ||
431 | } | ||
432 | |||
433 | return code; | ||
434 | } | ||
435 | |||
436 | // The concept of a base 2 logarithm is used in many parts of WavPack. It is | ||
437 | // a way of sufficiently accurately representing 32-bit signed and unsigned | ||
438 | // values storing only 16 bits (actually fewer). It is also used in the hybrid | ||
439 | // mode for quickly comparing the relative magnitude of large values (i.e. | ||
440 | // division) and providing smooth exponentials using only addition. | ||
441 | |||
442 | // These are not strict logarithms in that they become linear around zero and | ||
443 | // can therefore represent both zero and negative values. They have 8 bits | ||
444 | // of precision and in "roundtrip" conversions the total error never exceeds 1 | ||
445 | // part in 225 except for the cases of +/-115 and +/-195 (which error by 1). | ||
446 | |||
447 | |||
448 | // This function returns the log2 for the specified 32-bit unsigned value. | ||
449 | // The maximum value allowed is about 0xff800000 and returns 8447. | ||
450 | |||
451 | static int log2 (unsigned long avalue) | ||
452 | { | ||
453 | int dbits; | ||
454 | |||
455 | if ((avalue += avalue >> 9) < (1 << 8)) { | ||
456 | dbits = nbits_table [avalue]; | ||
457 | return (dbits << 8) + log2_table [(avalue << (9 - dbits)) & 0xff]; | ||
458 | } | ||
459 | else { | ||
460 | if (avalue < (1L << 16)) | ||
461 | dbits = nbits_table [avalue >> 8] + 8; | ||
462 | else if (avalue < (1L << 24)) | ||
463 | dbits = nbits_table [avalue >> 16] + 16; | ||
464 | else | ||
465 | dbits = nbits_table [avalue >> 24] + 24; | ||
466 | |||
467 | return (dbits << 8) + log2_table [(avalue >> (dbits - 9)) & 0xff]; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | // This function returns the original integer represented by the supplied | ||
472 | // logarithm (at least within the provided accuracy). The log is signed, | ||
473 | // but since a full 32-bit value is returned this can be used for unsigned | ||
474 | // conversions as well (i.e. the input range is -8192 to +8447). | ||
475 | |||
476 | long exp2s (int log) | ||
477 | { | ||
478 | ulong value; | ||
479 | |||
480 | if (log < 0) | ||
481 | return -exp2s (-log); | ||
482 | |||
483 | value = exp2_table [log & 0xff] | 0x100; | ||
484 | |||
485 | if ((log >>= 8) <= 9) | ||
486 | return value >> (9 - log); | ||
487 | else | ||
488 | return value << (log - 9); | ||
489 | } | ||
490 | |||
491 | // These two functions convert internal weights (which are normally +/-1024) | ||
492 | // to and from an 8-bit signed character version for storage in metadata. The | ||
493 | // weights are clipped here in the case that they are outside that range. | ||
494 | |||
495 | int restore_weight (char weight) | ||
496 | { | ||
497 | int result; | ||
498 | |||
499 | if ((result = (int) weight << 3) > 0) | ||
500 | result += (result + 64) >> 7; | ||
501 | |||
502 | return result; | ||
503 | } | ||
diff --git a/apps/codecs/libwavpack/wputils.c b/apps/codecs/libwavpack/wputils.c new file mode 100644 index 0000000000..21c399f517 --- /dev/null +++ b/apps/codecs/libwavpack/wputils.c | |||
@@ -0,0 +1,354 @@ | |||
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 | // wputils.c | ||
10 | |||
11 | // This module provides a high-level interface for decoding WavPack 4.0 audio | ||
12 | // streams and files. WavPack data is read with a stream reading callback. No | ||
13 | // direct seeking is provided for, but it is possible to start decoding | ||
14 | // anywhere in a WavPack stream. In this case, WavPack will be able to provide | ||
15 | // the sample-accurate position when it synchs with the data and begins | ||
16 | // decoding. | ||
17 | |||
18 | #include "wavpack.h" | ||
19 | |||
20 | #include <string.h> | ||
21 | |||
22 | ///////////////////////////// local table storage //////////////////////////// | ||
23 | |||
24 | const ulong sample_rates [] = { 6000, 8000, 9600, 11025, 12000, 16000, 22050, | ||
25 | 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000 }; | ||
26 | |||
27 | ///////////////////////////// executable code //////////////////////////////// | ||
28 | |||
29 | static ulong read_next_header (read_stream infile, WavpackHeader *wphdr); | ||
30 | |||
31 | // This function reads data from the specified stream in search of a valid | ||
32 | // WavPack 4.0 audio block. If this fails in 1 megabyte (or an invalid or | ||
33 | // unsupported WavPack block is encountered) then an appropriate message is | ||
34 | // copied to "error" and NULL is returned, otherwise a pointer to a | ||
35 | // WavpackContext structure is returned (which is used to call all other | ||
36 | // functions in this module). This can be initiated at the beginning of a | ||
37 | // WavPack file, or anywhere inside a WavPack file. To determine the exact | ||
38 | // position within the file use WavpackGetSampleIndex(). For demonstration | ||
39 | // purposes this uses a single static copy of the WavpackContext structure, | ||
40 | // so obviously it cannot be used for more than one file at a time. Also, | ||
41 | // this function will not handle "correction" files, plays only the first | ||
42 | // two channels of multi-channel files, and is limited in resolution in some | ||
43 | // large integer or floating point files (but always provides at least 24 bits | ||
44 | // of resolution). | ||
45 | |||
46 | static WavpackContext wpc; | ||
47 | |||
48 | WavpackContext *WavpackOpenFileInput (read_stream infile, char *error) | ||
49 | { | ||
50 | WavpackStream *wps = &wpc.stream; | ||
51 | ulong bcount; | ||
52 | |||
53 | CLEAR (wpc); | ||
54 | wpc.infile = infile; | ||
55 | wpc.total_samples = (ulong) -1; | ||
56 | wpc.norm_offset = 0; | ||
57 | wpc.open_flags = 0; | ||
58 | |||
59 | // open the source file for reading and store the size | ||
60 | |||
61 | while (!wps->wphdr.block_samples) { | ||
62 | |||
63 | bcount = read_next_header (wpc.infile, &wps->wphdr); | ||
64 | |||
65 | if (bcount == (ulong) -1) { | ||
66 | strcpy (error, "not compatible with this version of WavPack file!"); | ||
67 | return NULL; | ||
68 | } | ||
69 | |||
70 | if ((wps->wphdr.flags & UNKNOWN_FLAGS) || wps->wphdr.version < 0x402 || wps->wphdr.version > 0x40f) { | ||
71 | strcpy (error, "not compatible with this version of WavPack file!"); | ||
72 | return NULL; | ||
73 | } | ||
74 | |||
75 | if (wps->wphdr.block_samples && wps->wphdr.total_samples != (ulong) -1) | ||
76 | wpc.total_samples = wps->wphdr.total_samples; | ||
77 | |||
78 | if (!unpack_init (&wpc)) { | ||
79 | strcpy (error, wpc.error_message [0] ? wpc.error_message : | ||
80 | "not compatible with this version of WavPack file!"); | ||
81 | |||
82 | return NULL; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | wpc.config.flags &= ~0xff; | ||
87 | wpc.config.flags |= wps->wphdr.flags & 0xff; | ||
88 | wpc.config.bytes_per_sample = (wps->wphdr.flags & BYTES_STORED) + 1; | ||
89 | wpc.config.float_norm_exp = wps->float_norm_exp; | ||
90 | |||
91 | wpc.config.bits_per_sample = (wpc.config.bytes_per_sample * 8) - | ||
92 | ((wps->wphdr.flags & SHIFT_MASK) >> SHIFT_LSB); | ||
93 | |||
94 | if (!wpc.config.sample_rate) { | ||
95 | if (!wps || !wps->wphdr.block_samples || (wps->wphdr.flags & SRATE_MASK) == SRATE_MASK) | ||
96 | wpc.config.sample_rate = 44100; | ||
97 | else | ||
98 | wpc.config.sample_rate = sample_rates [(wps->wphdr.flags & SRATE_MASK) >> SRATE_LSB]; | ||
99 | } | ||
100 | |||
101 | if (!wpc.config.num_channels) { | ||
102 | wpc.config.num_channels = (wps->wphdr.flags & MONO_FLAG) ? 1 : 2; | ||
103 | wpc.config.channel_mask = 0x5 - wpc.config.num_channels; | ||
104 | } | ||
105 | |||
106 | if (!(wps->wphdr.flags & FINAL_BLOCK)) | ||
107 | wpc.reduced_channels = (wps->wphdr.flags & MONO_FLAG) ? 1 : 2; | ||
108 | |||
109 | return &wpc; | ||
110 | } | ||
111 | |||
112 | // This function obtains general information about an open file and returns | ||
113 | // a mask with the following bit values: | ||
114 | |||
115 | // MODE_LOSSLESS: file is lossless (pure lossless only) | ||
116 | // MODE_HYBRID: file is hybrid mode (lossy part only) | ||
117 | // MODE_FLOAT: audio data is 32-bit ieee floating point | ||
118 | // MODE_HIGH: file was created in "high" mode (information only) | ||
119 | // MODE_FAST: file was created in "fast" mode (information only) | ||
120 | |||
121 | int WavpackGetMode (WavpackContext *wpc) | ||
122 | { | ||
123 | int mode = 0; | ||
124 | |||
125 | if (wpc) { | ||
126 | if (wpc->config.flags & CONFIG_HYBRID_FLAG) | ||
127 | mode |= MODE_HYBRID; | ||
128 | else if (!(wpc->config.flags & CONFIG_LOSSY_MODE)) | ||
129 | mode |= MODE_LOSSLESS; | ||
130 | |||
131 | if (wpc->lossy_blocks) | ||
132 | mode &= ~MODE_LOSSLESS; | ||
133 | |||
134 | if (wpc->config.flags & CONFIG_FLOAT_DATA) | ||
135 | mode |= MODE_FLOAT; | ||
136 | |||
137 | if (wpc->config.flags & CONFIG_HIGH_FLAG) | ||
138 | mode |= MODE_HIGH; | ||
139 | |||
140 | if (wpc->config.flags & CONFIG_FAST_FLAG) | ||
141 | mode |= MODE_FAST; | ||
142 | } | ||
143 | |||
144 | return mode; | ||
145 | } | ||
146 | |||
147 | // Unpack the specified number of samples from the current file position. | ||
148 | // Note that "samples" here refers to "complete" samples, which would be | ||
149 | // 2 longs for stereo files. The audio data is returned right-justified in | ||
150 | // 32-bit longs in the endian mode native to the executing processor. So, | ||
151 | // if the original data was 16-bit, then the values returned would be | ||
152 | // +/-32k. Floating point data can also be returned if the source was | ||
153 | // floating point data (and this is normalized to +/-1.0). The actual number | ||
154 | // of samples unpacked is returned, which should be equal to the number | ||
155 | // requested unless the end of fle is encountered or an error occurs. | ||
156 | |||
157 | ulong WavpackUnpackSamples (WavpackContext *wpc, long *buffer, ulong samples) | ||
158 | { | ||
159 | WavpackStream *wps = &wpc->stream; | ||
160 | ulong bcount, samples_unpacked = 0, samples_to_unpack; | ||
161 | int num_channels = wpc->config.num_channels; | ||
162 | |||
163 | while (samples) { | ||
164 | if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) || | ||
165 | wps->sample_index >= wps->wphdr.block_index + wps->wphdr.block_samples) { | ||
166 | bcount = read_next_header (wpc->infile, &wps->wphdr); | ||
167 | |||
168 | if (bcount == (ulong) -1) | ||
169 | break; | ||
170 | |||
171 | if (wps->wphdr.version < 0x402 || wps->wphdr.version > 0x40f) { | ||
172 | strcpy (wpc->error_message, "not compatible with this version of WavPack file!"); | ||
173 | break; | ||
174 | } | ||
175 | |||
176 | if (!wps->wphdr.block_samples || wps->sample_index == wps->wphdr.block_index) | ||
177 | if (!unpack_init (wpc)) | ||
178 | break; | ||
179 | } | ||
180 | |||
181 | if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) || | ||
182 | wps->sample_index >= wps->wphdr.block_index + wps->wphdr.block_samples) | ||
183 | continue; | ||
184 | |||
185 | if (wps->sample_index < wps->wphdr.block_index) { | ||
186 | samples_to_unpack = wps->wphdr.block_index - wps->sample_index; | ||
187 | |||
188 | if (samples_to_unpack > samples) | ||
189 | samples_to_unpack = samples; | ||
190 | |||
191 | wps->sample_index += samples_to_unpack; | ||
192 | samples_unpacked += samples_to_unpack; | ||
193 | samples -= samples_to_unpack; | ||
194 | |||
195 | if (wpc->reduced_channels) | ||
196 | samples_to_unpack *= wpc->reduced_channels; | ||
197 | else | ||
198 | samples_to_unpack *= num_channels; | ||
199 | |||
200 | while (samples_to_unpack--) | ||
201 | *buffer++ = 0; | ||
202 | |||
203 | continue; | ||
204 | } | ||
205 | |||
206 | samples_to_unpack = wps->wphdr.block_index + wps->wphdr.block_samples - wps->sample_index; | ||
207 | |||
208 | if (samples_to_unpack > samples) | ||
209 | samples_to_unpack = samples; | ||
210 | |||
211 | unpack_samples (wpc, buffer, samples_to_unpack); | ||
212 | |||
213 | if (wpc->reduced_channels) | ||
214 | buffer += samples_to_unpack * wpc->reduced_channels; | ||
215 | else | ||
216 | buffer += samples_to_unpack * num_channels; | ||
217 | |||
218 | samples_unpacked += samples_to_unpack; | ||
219 | samples -= samples_to_unpack; | ||
220 | |||
221 | if (wps->sample_index == wps->wphdr.block_index + wps->wphdr.block_samples) { | ||
222 | if (check_crc_error (wpc)) | ||
223 | wpc->crc_errors++; | ||
224 | } | ||
225 | |||
226 | if (wps->sample_index == wpc->total_samples) | ||
227 | break; | ||
228 | } | ||
229 | |||
230 | return samples_unpacked; | ||
231 | } | ||
232 | |||
233 | // Get total number of samples contained in the WavPack file, or -1 if unknown | ||
234 | |||
235 | ulong WavpackGetNumSamples (WavpackContext *wpc) | ||
236 | { | ||
237 | return wpc ? wpc->total_samples : (ulong) -1; | ||
238 | } | ||
239 | |||
240 | // Get the current sample index position, or -1 if unknown | ||
241 | |||
242 | ulong WavpackGetSampleIndex (WavpackContext *wpc) | ||
243 | { | ||
244 | if (wpc) | ||
245 | return wpc->stream.sample_index; | ||
246 | |||
247 | return (ulong) -1; | ||
248 | } | ||
249 | |||
250 | // Get the number of errors encountered so far | ||
251 | |||
252 | int WavpackGetNumErrors (WavpackContext *wpc) | ||
253 | { | ||
254 | return wpc ? wpc->crc_errors : 0; | ||
255 | } | ||
256 | |||
257 | // return TRUE if any uncorrected lossy blocks were actually written or read | ||
258 | |||
259 | int WavpackLossyBlocks (WavpackContext *wpc) | ||
260 | { | ||
261 | return wpc ? wpc->lossy_blocks : 0; | ||
262 | } | ||
263 | |||
264 | // Returns the sample rate of the specified WavPack file | ||
265 | |||
266 | ulong WavpackGetSampleRate (WavpackContext *wpc) | ||
267 | { | ||
268 | return wpc ? wpc->config.sample_rate : 44100; | ||
269 | } | ||
270 | |||
271 | // Returns the number of channels of the specified WavPack file. Note that | ||
272 | // this is the actual number of channels contained in the file, but this | ||
273 | // version can only decode the first two. | ||
274 | |||
275 | int WavpackGetNumChannels (WavpackContext *wpc) | ||
276 | { | ||
277 | return wpc ? wpc->config.num_channels : 2; | ||
278 | } | ||
279 | |||
280 | // Returns the actual number of valid bits per sample contained in the | ||
281 | // original file, which may or may not be a multiple of 8. Floating data | ||
282 | // always has 32 bits, integers may be from 1 to 32 bits each. When this | ||
283 | // value is not a multiple of 8, then the "extra" bits are located in the | ||
284 | // LSBs of the results. That is, values are right justified when unpacked | ||
285 | // into longs, but are left justified in the number of bytes used by the | ||
286 | // original data. | ||
287 | |||
288 | int WavpackGetBitsPerSample (WavpackContext *wpc) | ||
289 | { | ||
290 | return wpc ? wpc->config.bits_per_sample : 16; | ||
291 | } | ||
292 | |||
293 | // Returns the number of bytes used for each sample (1 to 4) in the original | ||
294 | // file. This is required information for the user of this module because the | ||
295 | // audio data is returned in the LOWER bytes of the long buffer and must be | ||
296 | // left-shifted 8, 16, or 24 bits if normalized longs are required. | ||
297 | |||
298 | int WavpackGetBytesPerSample (WavpackContext *wpc) | ||
299 | { | ||
300 | return wpc ? wpc->config.bytes_per_sample : 2; | ||
301 | } | ||
302 | |||
303 | // This function will return the actual number of channels decoded from the | ||
304 | // file (which may or may not be less than the actual number of channels, but | ||
305 | // will always be 1 or 2). Normally, this will be the front left and right | ||
306 | // channels of a multi-channel file. | ||
307 | |||
308 | int WavpackGetReducedChannels (WavpackContext *wpc) | ||
309 | { | ||
310 | if (wpc) | ||
311 | return wpc->reduced_channels ? wpc->reduced_channels : wpc->config.num_channels; | ||
312 | else | ||
313 | return 2; | ||
314 | } | ||
315 | |||
316 | // Read from current file position until a valid 32-byte WavPack 4.0 header is | ||
317 | // found and read into the specified pointer. The number of bytes skipped is | ||
318 | // returned. If no WavPack header is found within 1 meg, then a -1 is returned | ||
319 | // to indicate the error. No additional bytes are read past the header and it | ||
320 | // is returned in the processor's native endian mode. Seeking is not required. | ||
321 | |||
322 | static ulong read_next_header (read_stream infile, WavpackHeader *wphdr) | ||
323 | { | ||
324 | char buffer [sizeof (*wphdr)], *sp = buffer + sizeof (*wphdr), *ep = sp; | ||
325 | ulong bytes_skipped = 0; | ||
326 | int bleft; | ||
327 | |||
328 | while (1) { | ||
329 | if (sp < ep) { | ||
330 | bleft = ep - sp; | ||
331 | memcpy (buffer, sp, bleft); | ||
332 | } | ||
333 | else | ||
334 | bleft = 0; | ||
335 | |||
336 | if (infile (buffer + bleft, sizeof (*wphdr) - bleft) != (long) sizeof (*wphdr) - bleft) | ||
337 | return -1; | ||
338 | |||
339 | sp = buffer; | ||
340 | |||
341 | if (*sp++ == 'w' && *sp == 'v' && *++sp == 'p' && *++sp == 'k' && | ||
342 | !(*++sp & 1) && sp [2] < 16 && !sp [3] && sp [5] == 4 && sp [4] >= 2 && sp [4] <= 0xf) { | ||
343 | memcpy (wphdr, buffer, sizeof (*wphdr)); | ||
344 | little_endian_to_native (wphdr, WavpackHeaderFormat); | ||
345 | return bytes_skipped; | ||
346 | } | ||
347 | |||
348 | while (sp < ep && *sp != 'w') | ||
349 | sp++; | ||
350 | |||
351 | if ((bytes_skipped += sp - buffer) > 1024 * 1024) | ||
352 | return -1; | ||
353 | } | ||
354 | } | ||