summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/codecs/libwavpack/SOURCES1
-rw-r--r--apps/codecs/libwavpack/bits.c163
-rw-r--r--apps/codecs/libwavpack/float.c90
-rw-r--r--apps/codecs/libwavpack/metadata.c136
-rw-r--r--apps/codecs/libwavpack/pack.c450
-rw-r--r--apps/codecs/libwavpack/unpack.c869
-rw-r--r--apps/codecs/libwavpack/wavpack.h317
-rw-r--r--apps/codecs/libwavpack/words.c798
-rw-r--r--apps/codecs/libwavpack/wputils.c431
9 files changed, 2156 insertions, 1099 deletions
diff --git a/apps/codecs/libwavpack/SOURCES b/apps/codecs/libwavpack/SOURCES
index a4f0f2f7a9..17399351fd 100644
--- a/apps/codecs/libwavpack/SOURCES
+++ b/apps/codecs/libwavpack/SOURCES
@@ -2,6 +2,7 @@ bits.c
2float.c 2float.c
3metadata.c 3metadata.c
4unpack.c 4unpack.c
5pack.c
5words.c 6words.c
6wputils.c 7wputils.c
7#if CONFIG_CPU==MCF5249 && !defined(SIMULATOR) 8#if CONFIG_CPU==MCF5249 && !defined(SIMULATOR)
diff --git a/apps/codecs/libwavpack/bits.c b/apps/codecs/libwavpack/bits.c
index 1fe6aacf75..bf056a9392 100644
--- a/apps/codecs/libwavpack/bits.c
+++ b/apps/codecs/libwavpack/bits.c
@@ -31,12 +31,12 @@ void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end, read_s
31 bs->end = buffer_end; 31 bs->end = buffer_end;
32 32
33 if (file) { 33 if (file) {
34 bs->ptr = bs->end - 1; 34 bs->ptr = bs->end - 1;
35 bs->file_bytes = file_bytes; 35 bs->file_bytes = file_bytes;
36 bs->file = file; 36 bs->file = file;
37 } 37 }
38 else 38 else
39 bs->ptr = bs->buf - 1; 39 bs->ptr = bs->buf - 1;
40 40
41 bs->wrap = bs_read; 41 bs->wrap = bs_read;
42} 42}
@@ -49,31 +49,70 @@ void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end, read_s
49static void bs_read (Bitstream *bs) 49static void bs_read (Bitstream *bs)
50{ 50{
51 if (bs->file && bs->file_bytes) { 51 if (bs->file && bs->file_bytes) {
52 ulong bytes_read, bytes_to_read = bs->end - bs->buf; 52 ulong bytes_read, bytes_to_read = bs->end - bs->buf;
53 53
54 if (bytes_to_read > bs->file_bytes) 54 if (bytes_to_read > bs->file_bytes)
55 bytes_to_read = bs->file_bytes; 55 bytes_to_read = bs->file_bytes;
56 56
57 bytes_read = bs->file (bs->buf, bytes_to_read); 57 bytes_read = bs->file (bs->buf, bytes_to_read);
58 58
59 if (bytes_read) { 59 if (bytes_read) {
60 bs->end = bs->buf + bytes_read; 60 bs->end = bs->buf + bytes_read;
61 bs->file_bytes -= bytes_read; 61 bs->file_bytes -= bytes_read;
62 } 62 }
63 else { 63 else {
64 memset (bs->buf, -1, bs->end - bs->buf); 64 memset (bs->buf, -1, bs->end - bs->buf);
65 bs->error = 1; 65 bs->error = 1;
66 } 66 }
67 } 67 }
68 else 68 else
69 bs->error = 1; 69 bs->error = 1;
70 70
71 if (bs->error) 71 if (bs->error)
72 memset (bs->buf, -1, bs->end - bs->buf); 72 memset (bs->buf, -1, bs->end - bs->buf);
73 73
74 bs->ptr = bs->buf; 74 bs->ptr = bs->buf;
75} 75}
76 76
77// Open the specified BitStream using the specified buffer pointers. It is
78// assumed that enough buffer space has been allocated for all data that will
79// be written, otherwise an error will be generated.
80
81static void bs_write (Bitstream *bs);
82
83void bs_open_write (Bitstream *bs, uchar *buffer_start, uchar *buffer_end)
84{
85 bs->error = bs->sr = bs->bc = 0;
86 bs->ptr = bs->buf = buffer_start;
87 bs->end = buffer_end;
88 bs->wrap = bs_write;
89}
90
91// This function is only called from the putbit() and putbits() macros when
92// the buffer is full, which is now flagged as an error.
93
94static void bs_write (Bitstream *bs)
95{
96 bs->ptr = bs->buf;
97 bs->error = 1;
98}
99
100// This function forces a flushing write of the specified BitStream, and
101// returns the total number of bytes written into the buffer.
102
103ulong bs_close_write (Bitstream *bs)
104{
105 ulong bytes_written;
106
107 if (bs->error)
108 return (ulong) -1;
109
110 while (bs->bc || ((bs->ptr - bs->buf) & 1)) putbit_1 (bs);
111 bytes_written = bs->ptr - bs->buf;
112 CLEAR (*bs);
113 return bytes_written;
114}
115
77/////////////////////// Endian Correction Routines //////////////////////////// 116/////////////////////// Endian Correction Routines ////////////////////////////
78 117
79void little_endian_to_native (void *data, char *format) 118void little_endian_to_native (void *data, char *format)
@@ -82,27 +121,27 @@ void little_endian_to_native (void *data, char *format)
82 long temp; 121 long temp;
83 122
84 while (*format) { 123 while (*format) {
85 switch (*format) { 124 switch (*format) {
86 case 'L': 125 case 'L':
87 temp = cp [0] + ((long) cp [1] << 8) + ((long) cp [2] << 16) + ((long) cp [3] << 24); 126 temp = cp [0] + ((long) cp [1] << 8) + ((long) cp [2] << 16) + ((long) cp [3] << 24);
88 * (long *) cp = temp; 127 * (long *) cp = temp;
89 cp += 4; 128 cp += 4;
90 break; 129 break;
91 130
92 case 'S': 131 case 'S':
93 temp = cp [0] + (cp [1] << 8); 132 temp = cp [0] + (cp [1] << 8);
94 * (short *) cp = (short) temp; 133 * (short *) cp = (short) temp;
95 cp += 2; 134 cp += 2;
96 break; 135 break;
97 136
98 default: 137 default:
99 if (*format >= '0' && *format <= '9') 138 if (*format >= '0' && *format <= '9')
100 cp += *format - '0'; 139 cp += *format - '0';
101 140
102 break; 141 break;
103 } 142 }
104 143
105 format++; 144 format++;
106 } 145 }
107} 146}
108 147
@@ -112,28 +151,28 @@ void native_to_little_endian (void *data, char *format)
112 long temp; 151 long temp;
113 152
114 while (*format) { 153 while (*format) {
115 switch (*format) { 154 switch (*format) {
116 case 'L': 155 case 'L':
117 temp = * (long *) cp; 156 temp = * (long *) cp;
118 *cp++ = (uchar) temp; 157 *cp++ = (uchar) temp;
119 *cp++ = (uchar) (temp >> 8); 158 *cp++ = (uchar) (temp >> 8);
120 *cp++ = (uchar) (temp >> 16); 159 *cp++ = (uchar) (temp >> 16);
121 *cp++ = (uchar) (temp >> 24); 160 *cp++ = (uchar) (temp >> 24);
122 break; 161 break;
123 162
124 case 'S': 163 case 'S':
125 temp = * (short *) cp; 164 temp = * (short *) cp;
126 *cp++ = (uchar) temp; 165 *cp++ = (uchar) temp;
127 *cp++ = (uchar) (temp >> 8); 166 *cp++ = (uchar) (temp >> 8);
128 break; 167 break;
129 168
130 default: 169 default:
131 if (*format >= '0' && *format <= '9') 170 if (*format >= '0' && *format <= '9')
132 cp += *format - '0'; 171 cp += *format - '0';
133 172
134 break; 173 break;
135 } 174 }
136 175
137 format++; 176 format++;
138 } 177 }
139} 178}
diff --git a/apps/codecs/libwavpack/float.c b/apps/codecs/libwavpack/float.c
index 3e678e824d..2208e616d8 100644
--- a/apps/codecs/libwavpack/float.c
+++ b/apps/codecs/libwavpack/float.c
@@ -1,8 +1,8 @@
1//////////////////////////////////////////////////////////////////////////// 1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** // 2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor // 3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 Conifer Software. // 4// Copyright (c) 1998 - 2004 Conifer Software. //
5// All Rights Reserved. // 5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) // 6// Distributed under the BSD Software License (see license.txt) //
7//////////////////////////////////////////////////////////////////////////// 7////////////////////////////////////////////////////////////////////////////
8 8
@@ -16,7 +16,7 @@ int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd)
16 char *byteptr = wpmd->data; 16 char *byteptr = wpmd->data;
17 17
18 if (bytecnt != 4) 18 if (bytecnt != 4)
19 return FALSE; 19 return FALSE;
20 20
21 wps->float_flags = *byteptr++; 21 wps->float_flags = *byteptr++;
22 wps->float_shift = *byteptr++; 22 wps->float_shift = *byteptr++;
@@ -28,35 +28,35 @@ int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd)
28void float_values (WavpackStream *wps, long *values, long num_values) 28void float_values (WavpackStream *wps, long *values, long num_values)
29{ 29{
30 while (num_values--) { 30 while (num_values--) {
31 int shift_count = 0, exp = wps->float_max_exp; 31 int shift_count = 0, exp = wps->float_max_exp;
32 f32 outval = { 0, 0, 0 }; 32 f32 outval = { 0, 0, 0 };
33 33
34 if (*values) { 34 if (*values) {
35 *values <<= wps->float_shift; 35 *values <<= wps->float_shift;
36 36
37 if (*values < 0) { 37 if (*values < 0) {
38 *values = -*values; 38 *values = -*values;
39 outval.sign = 1; 39 outval.sign = 1;
40 } 40 }
41 41
42 if (*values == 0x1000000) 42 if (*values == 0x1000000)
43 outval.exponent = 255; 43 outval.exponent = 255;
44 else { 44 else {
45 if (exp) 45 if (exp)
46 while (!(*values & 0x800000) && --exp) { 46 while (!(*values & 0x800000) && --exp) {
47 shift_count++; 47 shift_count++;
48 *values <<= 1; 48 *values <<= 1;
49 } 49 }
50 50
51 if (shift_count && (wps->float_flags & FLOAT_SHIFT_ONES)) 51 if (shift_count && (wps->float_flags & FLOAT_SHIFT_ONES))
52 *values |= ((1 << shift_count) - 1); 52 *values |= ((1 << shift_count) - 1);
53 53
54 outval.mantissa = *values; 54 outval.mantissa = *values;
55 outval.exponent = exp; 55 outval.exponent = exp;
56 } 56 }
57 } 57 }
58 58
59 * (f32 *) values++ = outval; 59 * (f32 *) values++ = outval;
60 } 60 }
61} 61}
62 62
@@ -66,18 +66,18 @@ void float_normalize (long *values, long num_values, int delta_exp)
66 int exp; 66 int exp;
67 67
68 if (!delta_exp) 68 if (!delta_exp)
69 return; 69 return;
70 70
71 while (num_values--) { 71 while (num_values--) {
72 if ((exp = fvalues->exponent) == 0 || exp + delta_exp <= 0) 72 if ((exp = fvalues->exponent) == 0 || exp + delta_exp <= 0)
73 *fvalues = fzero; 73 *fvalues = fzero;
74 else if (exp == 255 || (exp += delta_exp) >= 255) { 74 else if (exp == 255 || (exp += delta_exp) >= 255) {
75 fvalues->exponent = 255; 75 fvalues->exponent = 255;
76 fvalues->mantissa = 0; 76 fvalues->mantissa = 0;
77 } 77 }
78 else 78 else
79 fvalues->exponent = exp; 79 fvalues->exponent = exp;
80 80
81 fvalues++; 81 fvalues++;
82 } 82 }
83} 83}
diff --git a/apps/codecs/libwavpack/metadata.c b/apps/codecs/libwavpack/metadata.c
index 661b25edc8..ebc7dcf99d 100644
--- a/apps/codecs/libwavpack/metadata.c
+++ b/apps/codecs/libwavpack/metadata.c
@@ -12,46 +12,48 @@
12 12
13#include "wavpack.h" 13#include "wavpack.h"
14 14
15#include <string.h>
16
15int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd) 17int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd)
16{ 18{
17 uchar tchar; 19 uchar tchar;
18 20
19 if (!wpc->infile (&wpmd->id, 1) || !wpc->infile (&tchar, 1)) 21 if (!wpc->infile (&wpmd->id, 1) || !wpc->infile (&tchar, 1))
20 return FALSE; 22 return FALSE;
21 23
22 wpmd->byte_length = tchar << 1; 24 wpmd->byte_length = tchar << 1;
23 25
24 if (wpmd->id & ID_LARGE) { 26 if (wpmd->id & ID_LARGE) {
25 wpmd->id &= ~ID_LARGE; 27 wpmd->id &= ~ID_LARGE;
26 28
27 if (!wpc->infile (&tchar, 1)) 29 if (!wpc->infile (&tchar, 1))
28 return FALSE; 30 return FALSE;
29 31
30 wpmd->byte_length += (long) tchar << 9; 32 wpmd->byte_length += (long) tchar << 9;
31 33
32 if (!wpc->infile (&tchar, 1)) 34 if (!wpc->infile (&tchar, 1))
33 return FALSE; 35 return FALSE;
34 36
35 wpmd->byte_length += (long) tchar << 17; 37 wpmd->byte_length += (long) tchar << 17;
36 } 38 }
37 39
38 if (wpmd->id & ID_ODD_SIZE) { 40 if (wpmd->id & ID_ODD_SIZE) {
39 wpmd->id &= ~ID_ODD_SIZE; 41 wpmd->id &= ~ID_ODD_SIZE;
40 wpmd->byte_length--; 42 wpmd->byte_length--;
41 } 43 }
42 44
43 if (wpmd->byte_length && wpmd->byte_length <= (long)sizeof (wpc->read_buffer)) { 45 if (wpmd->byte_length && wpmd->byte_length <= (long)sizeof (wpc->read_buffer)) {
44 ulong bytes_to_read = wpmd->byte_length + (wpmd->byte_length & 1); 46 ulong bytes_to_read = wpmd->byte_length + (wpmd->byte_length & 1);
45 47
46 if (wpc->infile (wpc->read_buffer, bytes_to_read) != (long) bytes_to_read) { 48 if (wpc->infile (wpc->read_buffer, bytes_to_read) != (long) bytes_to_read) {
47 wpmd->data = NULL; 49 wpmd->data = NULL;
48 return FALSE; 50 return FALSE;
49 } 51 }
50 52
51 wpmd->data = wpc->read_buffer; 53 wpmd->data = wpc->read_buffer;
52 } 54 }
53 else 55 else
54 wpmd->data = NULL; 56 wpmd->data = NULL;
55 57
56 return TRUE; 58 return TRUE;
57} 59}
@@ -61,45 +63,89 @@ int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd)
61 WavpackStream *wps = &wpc->stream; 63 WavpackStream *wps = &wpc->stream;
62 64
63 switch (wpmd->id) { 65 switch (wpmd->id) {
64 case ID_DUMMY: 66 case ID_DUMMY:
65 return TRUE; 67 return TRUE;
68
69 case ID_DECORR_TERMS:
70 return read_decorr_terms (wps, wpmd);
71
72 case ID_DECORR_WEIGHTS:
73 return read_decorr_weights (wps, wpmd);
74
75 case ID_DECORR_SAMPLES:
76 return read_decorr_samples (wps, wpmd);
77
78 case ID_ENTROPY_VARS:
79 return read_entropy_vars (wps, wpmd);
66 80
67 case ID_DECORR_TERMS: 81 case ID_HYBRID_PROFILE:
68 return read_decorr_terms (wps, wpmd); 82 return read_hybrid_profile (wps, wpmd);
69 83
70 case ID_DECORR_WEIGHTS: 84 case ID_FLOAT_INFO:
71 return read_decorr_weights (wps, wpmd); 85 return read_float_info (wps, wpmd);
72 86
73 case ID_DECORR_SAMPLES: 87 case ID_INT32_INFO:
74 return read_decorr_samples (wps, wpmd); 88 return read_int32_info (wps, wpmd);
75 89
76 case ID_ENTROPY_VARS: 90 case ID_CHANNEL_INFO:
77 return read_entropy_vars (wps, wpmd); 91 return read_channel_info (wpc, wpmd);
78 92
79 case ID_HYBRID_PROFILE: 93 case ID_CONFIG_BLOCK:
80 return read_hybrid_profile (wps, wpmd); 94 return read_config_info (wpc, wpmd);
95
96 case ID_WV_BITSTREAM:
97 return init_wv_bitstream (wpc, wpmd);
98
99 case ID_SHAPING_WEIGHTS:
100 case ID_WVC_BITSTREAM:
101 case ID_WVX_BITSTREAM:
102 return TRUE;
103
104 default:
105 return (wpmd->id & ID_OPTIONAL_DATA) ? TRUE : FALSE;
106 }
107}
81 108
82 case ID_FLOAT_INFO: 109int copy_metadata (WavpackMetadata *wpmd, uchar *buffer_start, uchar *buffer_end)
83 return read_float_info (wps, wpmd); 110{
111 ulong mdsize = wpmd->byte_length + (wpmd->byte_length & 1);
112 WavpackHeader *wphdr = (WavpackHeader *) buffer_start;
84 113
85 case ID_INT32_INFO: 114 if (wpmd->byte_length & 1)
86 return read_int32_info (wps, wpmd); 115 ((char *) wpmd->data) [wpmd->byte_length] = 0;
87 116
88 case ID_CHANNEL_INFO: 117 mdsize += (wpmd->byte_length > 510) ? 4 : 2;
89 return read_channel_info (wpc, wpmd); 118 buffer_start += wphdr->ckSize + 8;
90 119
91 case ID_CONFIG_BLOCK: 120 if (buffer_start + mdsize >= buffer_end)
92 return read_config_info (wpc, wpmd); 121 return FALSE;
93 122
94 case ID_WV_BITSTREAM: 123 buffer_start [0] = wpmd->id | (wpmd->byte_length & 1 ? ID_ODD_SIZE : 0);
95 return init_wv_bitstream (wpc, wpmd); 124 buffer_start [1] = (wpmd->byte_length + 1) >> 1;
96 125
97 case ID_SHAPING_WEIGHTS: 126 if (wpmd->byte_length > 510) {
98 case ID_WVC_BITSTREAM: 127 buffer_start [0] |= ID_LARGE;
99 case ID_WVX_BITSTREAM: 128 buffer_start [2] = (wpmd->byte_length + 1) >> 9;
100 return TRUE; 129 buffer_start [3] = (wpmd->byte_length + 1) >> 17;
130 }
101 131
102 default: 132 if (wpmd->data && wpmd->byte_length) {
103 return (wpmd->id & ID_OPTIONAL_DATA) ? TRUE : FALSE; 133 if (wpmd->byte_length > 510) {
134 buffer_start [0] |= ID_LARGE;
135 buffer_start [2] = (wpmd->byte_length + 1) >> 9;
136 buffer_start [3] = (wpmd->byte_length + 1) >> 17;
137 memcpy (buffer_start + 4, wpmd->data, mdsize - 4);
138 }
139 else
140 memcpy (buffer_start + 2, wpmd->data, mdsize - 2);
104 } 141 }
142
143 wphdr->ckSize += mdsize;
144 return TRUE;
105} 145}
146
147void free_metadata (WavpackMetadata *wpmd)
148{
149 wpmd->data = NULL;
150}
151
diff --git a/apps/codecs/libwavpack/pack.c b/apps/codecs/libwavpack/pack.c
new file mode 100644
index 0000000000..e695388d45
--- /dev/null
+++ b/apps/codecs/libwavpack/pack.c
@@ -0,0 +1,450 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2005 Conifer Software. //
5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) //
7////////////////////////////////////////////////////////////////////////////
8
9// pack.c
10
11// This module actually handles the compression of the audio data, except for
12// the entropy coding which is handled by the words? modules. For efficiency,
13// the conversion is isolated to tight loops that handle an entire buffer.
14
15#include "wavpack.h"
16
17#include <string.h>
18
19// This flag provides faster encoding speed at the expense of more code. The
20// improvement applies to 16-bit stereo lossless only.
21
22//////////////////////////////// local tables ///////////////////////////////
23
24// These two tables specify the characteristics of the decorrelation filters.
25// Each term represents one layer of the sequential filter, where positive
26// values indicate the relative sample involved from the same channel (1=prev),
27// 17 & 18 are special functions using the previous 2 samples, and negative
28// values indicate cross channel decorrelation (in stereo only).
29
30static const char default_terms [] = { 18,18,2,3,-2,0 };
31static const char high_terms [] = { 18,18,2,3,-2,18,2,4,7,5,3,6,8,-1,18,2,0 };
32static const char fast_terms [] = { 17,17,0 };
33
34///////////////////////////// executable code ////////////////////////////////
35
36// This function initializes everything required to pack WavPack bitstreams
37// and must be called BEFORE any other function in this module.
38
39void pack_init (WavpackContext *wpc)
40{
41 WavpackStream *wps = &wpc->stream;
42 ulong flags = wps->wphdr.flags;
43 struct decorr_pass *dpp;
44 const char *term_string;
45 int ti;
46
47 wps->sample_index = 0;
48 CLEAR (wps->decorr_passes);
49
50 if (wpc->config.flags & CONFIG_HIGH_FLAG)
51 term_string = high_terms;
52 else if (wpc->config.flags & CONFIG_FAST_FLAG)
53 term_string = fast_terms;
54 else
55 term_string = default_terms;
56
57 for (dpp = wps->decorr_passes, ti = 0; term_string [ti]; ti++)
58 if (term_string [ti] >= 0 || (flags & CROSS_DECORR)) {
59 dpp->term = term_string [ti];
60 dpp++->delta = 2;
61 }
62 else if (!(flags & MONO_FLAG)) {
63 dpp->term = -3;
64 dpp++->delta = 2;
65 }
66
67 wps->num_terms = dpp - wps->decorr_passes;
68 init_words (wps);
69}
70
71// Allocate room for and copy the decorrelation terms from the decorr_passes
72// array into the specified metadata structure. Both the actual term id and
73// the delta are packed into single characters.
74
75static void write_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd)
76{
77 int tcount = wps->num_terms;
78 struct decorr_pass *dpp;
79 char *byteptr;
80
81 byteptr = wpmd->data = wpmd->temp_data;
82 wpmd->id = ID_DECORR_TERMS;
83
84 for (dpp = wps->decorr_passes; tcount--; ++dpp)
85 *byteptr++ = ((dpp->term + 5) & 0x1f) | ((dpp->delta << 5) & 0xe0);
86
87 wpmd->byte_length = byteptr - (char *) wpmd->data;
88}
89
90// Allocate room for and copy the decorrelation term weights from the
91// decorr_passes array into the specified metadata structure. The weights
92// range +/-1024, but are rounded and truncated to fit in signed chars for
93// metadata storage. Weights are separate for the two channels
94
95static void write_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd)
96{
97 int tcount = wps->num_terms;
98 struct decorr_pass *dpp;
99 char *byteptr;
100
101 byteptr = wpmd->data = wpmd->temp_data;
102 wpmd->id = ID_DECORR_WEIGHTS;
103
104 for (dpp = wps->decorr_passes; tcount--; ++dpp) {
105 dpp->weight_A = restore_weight (*byteptr++ = store_weight (dpp->weight_A));
106
107 if (!(wps->wphdr.flags & MONO_FLAG))
108 dpp->weight_B = restore_weight (*byteptr++ = store_weight (dpp->weight_B));
109 }
110
111 wpmd->byte_length = byteptr - (char *) wpmd->data;
112}
113
114// Allocate room for and copy the decorrelation samples from the decorr_passes
115// array into the specified metadata structure. The samples are signed 32-bit
116// values, but are converted to signed log2 values for storage in metadata.
117// Values are stored for both channels and are specified from the first term
118// with unspecified samples set to zero. The number of samples stored varies
119// with the actual term value, so those must obviously be specified before
120// these in the metadata list. Any number of terms can have their samples
121// specified from no terms to all the terms, however I have found that
122// sending more than the first term's samples is a waste. The "wcount"
123// variable can be set to the number of terms to have their samples stored.
124
125static void write_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd)
126{
127 int tcount = wps->num_terms, wcount = 1, temp;
128 struct decorr_pass *dpp;
129 uchar *byteptr;
130
131 byteptr = wpmd->data = wpmd->temp_data;
132 wpmd->id = ID_DECORR_SAMPLES;
133
134 for (dpp = wps->decorr_passes; tcount--; ++dpp)
135 if (wcount) {
136 if (dpp->term > MAX_TERM) {
137 dpp->samples_A [0] = exp2s (temp = log2s (dpp->samples_A [0]));
138 *byteptr++ = temp;
139 *byteptr++ = temp >> 8;
140 dpp->samples_A [1] = exp2s (temp = log2s (dpp->samples_A [1]));
141 *byteptr++ = temp;
142 *byteptr++ = temp >> 8;
143
144 if (!(wps->wphdr.flags & MONO_FLAG)) {
145 dpp->samples_B [0] = exp2s (temp = log2s (dpp->samples_B [0]));
146 *byteptr++ = temp;
147 *byteptr++ = temp >> 8;
148 dpp->samples_B [1] = exp2s (temp = log2s (dpp->samples_B [1]));
149 *byteptr++ = temp;
150 *byteptr++ = temp >> 8;
151 }
152 }
153 else if (dpp->term < 0) {
154 dpp->samples_A [0] = exp2s (temp = log2s (dpp->samples_A [0]));
155 *byteptr++ = temp;
156 *byteptr++ = temp >> 8;
157 dpp->samples_B [0] = exp2s (temp = log2s (dpp->samples_B [0]));
158 *byteptr++ = temp;
159 *byteptr++ = temp >> 8;
160 }
161 else {
162 int m = 0, cnt = dpp->term;
163
164 while (cnt--) {
165 dpp->samples_A [m] = exp2s (temp = log2s (dpp->samples_A [m]));
166 *byteptr++ = temp;
167 *byteptr++ = temp >> 8;
168
169 if (!(wps->wphdr.flags & MONO_FLAG)) {
170 dpp->samples_B [m] = exp2s (temp = log2s (dpp->samples_B [m]));
171 *byteptr++ = temp;
172 *byteptr++ = temp >> 8;
173 }
174
175 m++;
176 }
177 }
178
179 wcount--;
180 }
181 else {
182 CLEAR (dpp->samples_A);
183 CLEAR (dpp->samples_B);
184 }
185
186 wpmd->byte_length = byteptr - (uchar *) wpmd->data;
187}
188
189// Allocate room for and copy the configuration information into the specified
190// metadata structure. Currently, we just store the upper 3 bytes of
191// config.flags and only in the first block of audio data. Note that this is
192// for informational purposes not required for playback or decoding (like
193// whether high or fast mode was specified).
194
195static void write_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
196{
197 char *byteptr;
198
199 byteptr = wpmd->data = wpmd->temp_data;
200 wpmd->id = ID_CONFIG_BLOCK;
201 *byteptr++ = (char) (wpc->config.flags >> 8);
202 *byteptr++ = (char) (wpc->config.flags >> 16);
203 *byteptr++ = (char) (wpc->config.flags >> 24);
204 wpmd->byte_length = byteptr - (char *) wpmd->data;
205}
206
207// Pack an entire block of samples (either mono or stereo) into a completed
208// WavPack block. This function is actually a shell for pack_samples() and
209// performs tasks like handling any shift required by the format, preprocessing
210// of floating point data or integer data over 24 bits wide, and implementing
211// the "extra" mode (via the extra?.c modules). It is assumed that there is
212// sufficient space for the completed block at "wps->blockbuff" and that
213// "wps->blockend" points to the end of the available space. A return value of
214// FALSE indicates an error.
215
216static int pack_samples (WavpackContext *wpc, long *buffer);
217
218int pack_block (WavpackContext *wpc, long *buffer)
219{
220 WavpackStream *wps = &wpc->stream;
221 ulong flags = wps->wphdr.flags, sflags = wps->wphdr.flags;
222 ulong sample_count = wps->wphdr.block_samples;
223
224 if (flags & SHIFT_MASK) {
225 int shift = (flags & SHIFT_MASK) >> SHIFT_LSB;
226 int mag = (flags & MAG_MASK) >> MAG_LSB;
227 ulong cnt = sample_count;
228 long *ptr = buffer;
229
230 if (flags & MONO_FLAG)
231 while (cnt--)
232 *ptr++ >>= shift;
233 else
234 while (cnt--) {
235 *ptr++ >>= shift;
236 *ptr++ >>= shift;
237 }
238
239 if ((mag -= shift) < 0)
240 flags &= ~MAG_MASK;
241 else
242 flags -= (1 << MAG_LSB) * shift;
243
244 wps->wphdr.flags = flags;
245 }
246
247 if (!pack_samples (wpc, buffer)) {
248 wps->wphdr.flags = sflags;
249 return FALSE;
250 }
251 else {
252 wps->wphdr.flags = sflags;
253 return TRUE;
254 }
255}
256
257// Pack an entire block of samples (either mono or stereo) into a completed
258// WavPack block. It is assumed that there is sufficient space for the
259// completed block at "wps->blockbuff" and that "wps->blockend" points to the
260// end of the available space. A return value of FALSE indicates an error.
261// Any unsent metadata is transmitted first, then required metadata for this
262// block is sent, and finally the compressed integer data is sent. If a "wpx"
263// stream is required for floating point data or large integer data, then this
264// must be handled outside this function. To find out how much data was written
265// the caller must look at the ckSize field of the written WavpackHeader, NOT
266// the one in the WavpackStream.
267
268static int pack_samples (WavpackContext *wpc, long *buffer)
269{
270 WavpackStream *wps = &wpc->stream;
271 ulong sample_count = wps->wphdr.block_samples;
272 ulong flags = wps->wphdr.flags, data_count;
273 struct decorr_pass *dpp;
274 WavpackMetadata wpmd;
275 int tcount, m = 0;
276 ulong crc, i;
277 long *bptr;
278
279 crc = 0xffffffff;
280 wps->wphdr.ckSize = sizeof (WavpackHeader) - 8;
281 memcpy (wps->blockbuff, &wps->wphdr, sizeof (WavpackHeader));
282
283 if (wpc->wrapper_bytes) {
284 wpmd.id = ID_RIFF_HEADER;
285 wpmd.byte_length = wpc->wrapper_bytes;
286 wpmd.data = wpc->wrapper_data;
287 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
288 free_metadata (&wpmd);
289 wpc->wrapper_data = NULL;
290 wpc->wrapper_bytes = 0;
291 }
292
293 if (!sample_count)
294 return TRUE;
295
296 write_decorr_terms (wps, &wpmd);
297 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
298 free_metadata (&wpmd);
299
300 write_decorr_weights (wps, &wpmd);
301 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
302 free_metadata (&wpmd);
303
304 write_decorr_samples (wps, &wpmd);
305 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
306 free_metadata (&wpmd);
307
308 write_entropy_vars (wps, &wpmd);
309 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
310 free_metadata (&wpmd);
311
312 if ((flags & INITIAL_BLOCK) && !wps->sample_index) {
313 write_config_info (wpc, &wpmd);
314 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
315 free_metadata (&wpmd);
316 }
317
318 bs_open_write (&wps->wvbits, wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 12, wps->blockend);
319
320 /////////////////////// handle lossless mono mode /////////////////////////
321
322 if (!(flags & HYBRID_FLAG) && (flags & MONO_FLAG))
323 for (bptr = buffer, i = 0; i < sample_count; ++i) {
324 long code;
325
326 crc = crc * 3 + (code = *bptr++);
327
328 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) {
329 long sam;
330
331 if (dpp->term > MAX_TERM) {
332 if (dpp->term & 1)
333 sam = 2 * dpp->samples_A [0] - dpp->samples_A [1];
334 else
335 sam = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
336
337 dpp->samples_A [1] = dpp->samples_A [0];
338 dpp->samples_A [0] = code;
339 }
340 else {
341 sam = dpp->samples_A [m];
342 dpp->samples_A [(m + dpp->term) & (MAX_TERM - 1)] = code;
343 }
344
345 code -= apply_weight_i (dpp->weight_A, sam);
346 update_weight (dpp->weight_A, 2, sam, code);
347 }
348
349 m = (m + 1) & (MAX_TERM - 1);
350 send_word_lossless (wps, code, 0);
351 }
352
353 //////////////////// handle the lossless stereo mode //////////////////////
354
355 else if (!(flags & HYBRID_FLAG) && !(flags & MONO_FLAG))
356 for (bptr = buffer, i = 0; i < sample_count; ++i, bptr += 2) {
357 long left, right, sam_A, sam_B;
358
359 crc = crc * 3 + (left = bptr [0]);
360 crc = crc * 3 + (right = bptr [1]);
361
362 if (flags & JOINT_STEREO)
363 right += ((left -= right) >> 1);
364
365 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount-- ; dpp++) {
366 if (dpp->term > 0) {
367 if (dpp->term > MAX_TERM) {
368 if (dpp->term & 1) {
369 sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
370 sam_B = 2 * dpp->samples_B [0] - dpp->samples_B [1];
371 }
372 else {
373 sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
374 sam_B = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1;
375 }
376
377 dpp->samples_A [1] = dpp->samples_A [0];
378 dpp->samples_B [1] = dpp->samples_B [0];
379 dpp->samples_A [0] = left;
380 dpp->samples_B [0] = right;
381 }
382 else {
383 int k = (m + dpp->term) & (MAX_TERM - 1);
384
385 sam_A = dpp->samples_A [m];
386 sam_B = dpp->samples_B [m];
387 dpp->samples_A [k] = left;
388 dpp->samples_B [k] = right;
389 }
390
391 left -= apply_weight_i (dpp->weight_A, sam_A);
392 right -= apply_weight_i (dpp->weight_B, sam_B);
393 update_weight (dpp->weight_A, 2, sam_A, left);
394 update_weight (dpp->weight_B, 2, sam_B, right);
395 }
396 else {
397 sam_A = (dpp->term == -2) ? right : dpp->samples_A [0];
398 sam_B = (dpp->term == -1) ? left : dpp->samples_B [0];
399 dpp->samples_A [0] = right;
400 dpp->samples_B [0] = left;
401 left -= apply_weight_i (dpp->weight_A, sam_A);
402 right -= apply_weight_i (dpp->weight_B, sam_B);
403 update_weight_clip (dpp->weight_A, 2, sam_A, left);
404 update_weight_clip (dpp->weight_B, 2, sam_B, right);
405 }
406 }
407
408 m = (m + 1) & (MAX_TERM - 1);
409 send_word_lossless (wps, left, 0);
410 send_word_lossless (wps, right, 1);
411 }
412
413 if (m)
414 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
415 if (dpp->term > 0 && dpp->term <= MAX_TERM) {
416 long temp_A [MAX_TERM], temp_B [MAX_TERM];
417 int k;
418
419 memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A));
420 memcpy (temp_B, dpp->samples_B, sizeof (dpp->samples_B));
421
422 for (k = 0; k < MAX_TERM; k++) {
423 dpp->samples_A [k] = temp_A [m];
424 dpp->samples_B [k] = temp_B [m];
425 m = (m + 1) & (MAX_TERM - 1);
426 }
427 }
428
429 flush_word (wps);
430 data_count = bs_close_write (&wps->wvbits);
431
432 if (data_count) {
433 if (data_count != (ulong) -1) {
434 uchar *cptr = wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 8;
435
436 *cptr++ = ID_WV_BITSTREAM | ID_LARGE;
437 *cptr++ = data_count >> 1;
438 *cptr++ = data_count >> 9;
439 *cptr++ = data_count >> 17;
440 ((WavpackHeader *) wps->blockbuff)->ckSize += data_count + 4;
441 }
442 else
443 return FALSE;
444 }
445
446 ((WavpackHeader *) wps->blockbuff)->crc = crc;
447
448 wps->sample_index += sample_count;
449 return TRUE;
450}
diff --git a/apps/codecs/libwavpack/unpack.c b/apps/codecs/libwavpack/unpack.c
index 5afaac3659..aaab2aa928 100644
--- a/apps/codecs/libwavpack/unpack.c
+++ b/apps/codecs/libwavpack/unpack.c
@@ -1,8 +1,8 @@
1//////////////////////////////////////////////////////////////////////////// 1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** // 2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor // 3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 Conifer Software. // 4// Copyright (c) 1998 - 2004 Conifer Software. //
5// All Rights Reserved. // 5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) // 6// Distributed under the BSD Software License (see license.txt) //
7//////////////////////////////////////////////////////////////////////////// 7////////////////////////////////////////////////////////////////////////////
8 8
@@ -15,46 +15,13 @@
15 15
16#include "wavpack.h" 16#include "wavpack.h"
17 17
18#include <stdlib.h>
18#include <string.h> 19#include <string.h>
19#include <math.h>
20 20
21static void strcpy_loc (char *dst, char *src) { while (*src) *dst++ = *src++; *dst = 0; } 21static void strcpy_loc (char *dst, char *src) { while ((*dst++ = *src++) != 0); }
22 22
23#define LOSSY_MUTE 23#define LOSSY_MUTE
24 24
25//////////////////////////////// local macros /////////////////////////////////
26
27// these macros implement the weight application and update operations
28// that are at the heart of the decorrelation loops
29
30#if 0 // PERFCOND
31#define apply_weight_i(weight, sample) ((weight * sample + 512) >> 10)
32#else
33#define apply_weight_i(weight, sample) ((((weight * sample) >> 8) + 2) >> 2)
34#endif
35
36#define apply_weight_f(weight, sample) (((((sample & 0xffff) * weight) >> 9) + \
37 (((sample & ~0xffff) >> 9) * weight) + 1) >> 1)
38
39#if 1 // PERFCOND
40#define apply_weight(weight, sample) (sample != (short) sample ? \
41 apply_weight_f (weight, sample) : apply_weight_i (weight, sample))
42#else
43#define apply_weight(weight, sample) ((int32_t)((weight * (int64_t) sample + 512) >> 10))
44#endif
45
46#if 0 // PERFCOND
47#define update_weight(weight, delta, source, result) \
48 if (source && result) weight -= ((((source ^ result) >> 30) & 2) - 1) * delta;
49#else
50#define update_weight(weight, delta, source, result) \
51 if (source && result) (source ^ result) < 0 ? (weight -= delta) : (weight += delta);
52#endif
53
54#define update_weight_clip(weight, delta, source, result) \
55 if (source && result && ((source ^ result) < 0 ? (weight -= delta) < -1024 : (weight += delta) > 1024)) \
56 weight = weight < 0 ? -1024 : 1024;
57
58///////////////////////////// executable code //////////////////////////////// 25///////////////////////////// executable code ////////////////////////////////
59 26
60// This function initializes everything required to unpack a WavPack block 27// This function initializes everything required to unpack a WavPack block
@@ -69,7 +36,7 @@ int unpack_init (WavpackContext *wpc)
69 WavpackMetadata wpmd; 36 WavpackMetadata wpmd;
70 37
71 if (wps->wphdr.block_samples && wps->wphdr.block_index != (ulong) -1) 38 if (wps->wphdr.block_samples && wps->wphdr.block_index != (ulong) -1)
72 wps->sample_index = wps->wphdr.block_index; 39 wps->sample_index = wps->wphdr.block_index;
73 40
74 wps->mute_error = FALSE; 41 wps->mute_error = FALSE;
75 wps->crc = 0xffffffff; 42 wps->crc = 0xffffffff;
@@ -78,27 +45,27 @@ int unpack_init (WavpackContext *wpc)
78 CLEAR (wps->w); 45 CLEAR (wps->w);
79 46
80 while (read_metadata_buff (wpc, &wpmd)) { 47 while (read_metadata_buff (wpc, &wpmd)) {
81 if (!process_metadata (wpc, &wpmd)) { 48 if (!process_metadata (wpc, &wpmd)) {
82 strcpy_loc (wpc->error_message, "invalid metadata!"); 49 strcpy_loc (wpc->error_message, "invalid metadata!");
83 return FALSE; 50 return FALSE;
84 } 51 }
85 52
86 if (wpmd.id == ID_WV_BITSTREAM) 53 if (wpmd.id == ID_WV_BITSTREAM)
87 break; 54 break;
88 } 55 }
89 56
90 if (wps->wphdr.block_samples && !bs_is_open (&wps->wvbits)) { 57 if (wps->wphdr.block_samples && !bs_is_open (&wps->wvbits)) {
91 strcpy_loc (wpc->error_message, "invalid WavPack file!"); 58 strcpy_loc (wpc->error_message, "invalid WavPack file!");
92 return FALSE; 59 return FALSE;
93 } 60 }
94 61
95 if (wps->wphdr.block_samples) { 62 if (wps->wphdr.block_samples) {
96 if ((wps->wphdr.flags & INT32_DATA) && wps->int32_sent_bits) 63 if ((wps->wphdr.flags & INT32_DATA) && wps->int32_sent_bits)
97 wpc->lossy_blocks = TRUE; 64 wpc->lossy_blocks = TRUE;
98 65
99 if ((wps->wphdr.flags & FLOAT_DATA) && 66 if ((wps->wphdr.flags & FLOAT_DATA) &&
100 wps->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT | FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME)) 67 wps->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT | FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME))
101 wpc->lossy_blocks = TRUE; 68 wpc->lossy_blocks = TRUE;
102 } 69 }
103 70
104 return TRUE; 71 return TRUE;
@@ -112,10 +79,10 @@ int init_wv_bitstream (WavpackContext *wpc, WavpackMetadata *wpmd)
112 WavpackStream *wps = &wpc->stream; 79 WavpackStream *wps = &wpc->stream;
113 80
114 if (wpmd->data) 81 if (wpmd->data)
115 bs_open_read (&wps->wvbits, wpmd->data, (char *) wpmd->data + wpmd->byte_length, NULL, 0); 82 bs_open_read (&wps->wvbits, wpmd->data, (char *) wpmd->data + wpmd->byte_length, NULL, 0);
116 else if (wpmd->byte_length) 83 else if (wpmd->byte_length)
117 bs_open_read (&wps->wvbits, wpc->read_buffer, wpc->read_buffer + sizeof (wpc->read_buffer), 84 bs_open_read (&wps->wvbits, wpc->read_buffer, wpc->read_buffer + sizeof (wpc->read_buffer),
118 wpc->infile, wpmd->byte_length + (wpmd->byte_length & 1)); 85 wpc->infile, wpmd->byte_length + (wpmd->byte_length & 1));
119 86
120 return TRUE; 87 return TRUE;
121} 88}
@@ -134,16 +101,16 @@ int read_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd)
134 struct decorr_pass *dpp; 101 struct decorr_pass *dpp;
135 102
136 if (termcnt > MAX_NTERMS) 103 if (termcnt > MAX_NTERMS)
137 return FALSE; 104 return FALSE;
138 105
139 wps->num_terms = termcnt; 106 wps->num_terms = termcnt;
140 107
141 for (dpp = wps->decorr_passes + termcnt - 1; termcnt--; dpp--) { 108 for (dpp = wps->decorr_passes + termcnt - 1; termcnt--; dpp--) {
142 dpp->term = (int)(*byteptr & 0x1f) - 5; 109 dpp->term = (int)(*byteptr & 0x1f) - 5;
143 dpp->delta = (*byteptr++ >> 5) & 0x7; 110 dpp->delta = (*byteptr++ >> 5) & 0x7;
144 111
145 if (!dpp->term || dpp->term < -3 || (dpp->term > MAX_TERM && dpp->term < 17) || dpp->term > 18) 112 if (!dpp->term || dpp->term < -3 || (dpp->term > MAX_TERM && dpp->term < 17) || dpp->term > 18)
146 return FALSE; 113 return FALSE;
147 } 114 }
148 115
149 return TRUE; 116 return TRUE;
@@ -162,19 +129,19 @@ int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd)
162 struct decorr_pass *dpp; 129 struct decorr_pass *dpp;
163 130
164 if (!(wps->wphdr.flags & MONO_FLAG)) 131 if (!(wps->wphdr.flags & MONO_FLAG))
165 termcnt /= 2; 132 termcnt /= 2;
166 133
167 if (termcnt > wps->num_terms) 134 if (termcnt > wps->num_terms)
168 return FALSE; 135 return FALSE;
169 136
170 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) 137 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
171 dpp->weight_A = dpp->weight_B = 0; 138 dpp->weight_A = dpp->weight_B = 0;
172 139
173 while (--dpp >= wps->decorr_passes && termcnt--) { 140 while (--dpp >= wps->decorr_passes && termcnt--) {
174 dpp->weight_A = restore_weight (*byteptr++); 141 dpp->weight_A = restore_weight (*byteptr++);
175 142
176 if (!(wps->wphdr.flags & MONO_FLAG)) 143 if (!(wps->wphdr.flags & MONO_FLAG))
177 dpp->weight_B = restore_weight (*byteptr++); 144 dpp->weight_B = restore_weight (*byteptr++);
178 } 145 }
179 146
180 return TRUE; 147 return TRUE;
@@ -196,49 +163,49 @@ int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd)
196 int tcount; 163 int tcount;
197 164
198 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { 165 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) {
199 CLEAR (dpp->samples_A); 166 CLEAR (dpp->samples_A);
200 CLEAR (dpp->samples_B); 167 CLEAR (dpp->samples_B);
201 } 168 }
202 169
203 if (wps->wphdr.version == 0x402 && (wps->wphdr.flags & HYBRID_FLAG)) { 170 if (wps->wphdr.version == 0x402 && (wps->wphdr.flags & HYBRID_FLAG)) {
204 byteptr += 2; 171 byteptr += 2;
205 172
206 if (!(wps->wphdr.flags & MONO_FLAG)) 173 if (!(wps->wphdr.flags & MONO_FLAG))
207 byteptr += 2; 174 byteptr += 2;
208 } 175 }
209 176
210 while (dpp-- > wps->decorr_passes && byteptr < endptr) 177 while (dpp-- > wps->decorr_passes && byteptr < endptr)
211 if (dpp->term > MAX_TERM) { 178 if (dpp->term > MAX_TERM) {
212 dpp->samples_A [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8))); 179 dpp->samples_A [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
213 dpp->samples_A [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8))); 180 dpp->samples_A [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
214 byteptr += 4; 181 byteptr += 4;
215 182
216 if (!(wps->wphdr.flags & MONO_FLAG)) { 183 if (!(wps->wphdr.flags & MONO_FLAG)) {
217 dpp->samples_B [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8))); 184 dpp->samples_B [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
218 dpp->samples_B [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8))); 185 dpp->samples_B [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
219 byteptr += 4; 186 byteptr += 4;
220 } 187 }
221 } 188 }
222 else if (dpp->term < 0) { 189 else if (dpp->term < 0) {
223 dpp->samples_A [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8))); 190 dpp->samples_A [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
224 dpp->samples_B [0] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8))); 191 dpp->samples_B [0] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
225 byteptr += 4; 192 byteptr += 4;
226 } 193 }
227 else { 194 else {
228 int m = 0, cnt = dpp->term; 195 int m = 0, cnt = dpp->term;
229 196
230 while (cnt--) { 197 while (cnt--) {
231 dpp->samples_A [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8))); 198 dpp->samples_A [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
232 byteptr += 2; 199 byteptr += 2;
233 200
234 if (!(wps->wphdr.flags & MONO_FLAG)) { 201 if (!(wps->wphdr.flags & MONO_FLAG)) {
235 dpp->samples_B [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8))); 202 dpp->samples_B [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
236 byteptr += 2; 203 byteptr += 2;
237 } 204 }
238 205
239 m++; 206 m++;
240 } 207 }
241 } 208 }
242 209
243 return byteptr == endptr; 210 return byteptr == endptr;
244} 211}
@@ -253,7 +220,7 @@ int read_int32_info (WavpackStream *wps, WavpackMetadata *wpmd)
253 char *byteptr = wpmd->data; 220 char *byteptr = wpmd->data;
254 221
255 if (bytecnt != 4) 222 if (bytecnt != 4)
256 return FALSE; 223 return FALSE;
257 224
258 wps->int32_sent_bits = *byteptr++; 225 wps->int32_sent_bits = *byteptr++;
259 wps->int32_zeros = *byteptr++; 226 wps->int32_zeros = *byteptr++;
@@ -273,13 +240,13 @@ int read_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd)
273 ulong mask = 0; 240 ulong mask = 0;
274 241
275 if (!bytecnt || bytecnt > 5) 242 if (!bytecnt || bytecnt > 5)
276 return FALSE; 243 return FALSE;
277 244
278 wpc->config.num_channels = *byteptr++; 245 wpc->config.num_channels = *byteptr++;
279 246
280 while (--bytecnt) { 247 while (--bytecnt) {
281 mask |= (ulong) *byteptr++ << shift; 248 mask |= (ulong) *byteptr++ << shift;
282 shift += 8; 249 shift += 8;
283 } 250 }
284 251
285 wpc->config.channel_mask = mask; 252 wpc->config.channel_mask = mask;
@@ -294,10 +261,10 @@ int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
294 uchar *byteptr = wpmd->data; 261 uchar *byteptr = wpmd->data;
295 262
296 if (bytecnt >= 3) { 263 if (bytecnt >= 3) {
297 wpc->config.flags &= 0xff; 264 wpc->config.flags &= 0xff;
298 wpc->config.flags |= (long) *byteptr++ << 8; 265 wpc->config.flags |= (long) *byteptr++ << 8;
299 wpc->config.flags |= (long) *byteptr++ << 16; 266 wpc->config.flags |= (long) *byteptr++ << 16;
300 wpc->config.flags |= (long) *byteptr << 24; 267 wpc->config.flags |= (long) *byteptr << 24;
301 } 268 }
302 269
303 return TRUE; 270 return TRUE;
@@ -339,88 +306,88 @@ long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count)
339 int tcount; 306 int tcount;
340 307
341 if (wps->sample_index + sample_count > wps->wphdr.block_index + wps->wphdr.block_samples) 308 if (wps->sample_index + sample_count > wps->wphdr.block_index + wps->wphdr.block_samples)
342 sample_count = wps->wphdr.block_index + wps->wphdr.block_samples - wps->sample_index; 309 sample_count = wps->wphdr.block_index + wps->wphdr.block_samples - wps->sample_index;
343 310
344 if (wps->mute_error) { 311 if (wps->mute_error) {
345 memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8)); 312 memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8));
346 wps->sample_index += sample_count; 313 wps->sample_index += sample_count;
347 return sample_count; 314 return sample_count;
348 } 315 }
349 316
350 if (flags & HYBRID_FLAG) 317 if (flags & HYBRID_FLAG)
351 mute_limit *= 2; 318 mute_limit *= 2;
352 319
353 ///////////////////// handle version 4 mono data ///////////////////////// 320 ///////////////////// handle version 4 mono data /////////////////////////
354 321
355 if (flags & MONO_FLAG) { 322 if (flags & MONO_FLAG) {
356 eptr = buffer + sample_count; 323 eptr = buffer + sample_count;
357 i = get_words (wps, 1, sample_count, buffer); 324 i = get_words (buffer, sample_count, flags, &wps->w, &wps->wvbits);
358 325
359 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) 326 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
360 decorr_mono_pass (dpp, buffer, sample_count); 327 decorr_mono_pass (dpp, buffer, sample_count);
361 328
362 for (bptr = buffer; bptr < eptr; ++bptr) { 329 for (bptr = buffer; bptr < eptr; ++bptr) {
363 if (labs (bptr [0]) > mute_limit) { 330 if (labs (bptr [0]) > mute_limit) {
364 i = bptr - buffer; 331 i = bptr - buffer;
365 break; 332 break;
366 } 333 }
367 334
368 crc = crc * 3 + bptr [0]; 335 crc = crc * 3 + bptr [0];
369 } 336 }
370 } 337 }
371 338
372 //////////////////// handle version 4 stereo data //////////////////////// 339 //////////////////// handle version 4 stereo data ////////////////////////
373 340
374 else { 341 else {
375 eptr = buffer + (sample_count * 2); 342 eptr = buffer + (sample_count * 2);
376 i = get_words (wps, 2, sample_count, buffer); 343 i = get_words (buffer, sample_count, flags, &wps->w, &wps->wvbits);
377 344
378 if (sample_count < 16) 345 if (sample_count < 16)
379 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) 346 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
380 decorr_stereo_pass (dpp, buffer, sample_count); 347 decorr_stereo_pass (dpp, buffer, sample_count);
381 else 348 else
382 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { 349 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) {
383 decorr_stereo_pass (dpp, buffer, 8); 350 decorr_stereo_pass (dpp, buffer, 8);
384#if CONFIG_CPU==MCF5249 && !defined(SIMULATOR) 351#if CONFIG_CPU==MCF5249 && !defined(SIMULATOR)
385 decorr_stereo_pass_cont_mcf5249 (dpp, buffer + 16, sample_count - 8); 352 decorr_stereo_pass_cont_mcf5249 (dpp, buffer + 16, sample_count - 8);
386#else 353#else
387 decorr_stereo_pass_cont (dpp, buffer + 16, sample_count - 8); 354 decorr_stereo_pass_cont (dpp, buffer + 16, sample_count - 8);
388#endif 355#endif
389 } 356 }
390 357
391 if (flags & JOINT_STEREO) 358 if (flags & JOINT_STEREO)
392 for (bptr = buffer; bptr < eptr; bptr += 2) { 359 for (bptr = buffer; bptr < eptr; bptr += 2) {
393 bptr [0] += (bptr [1] -= (bptr [0] >> 1)); 360 bptr [0] += (bptr [1] -= (bptr [0] >> 1));
394 361
395 if (labs (bptr [0]) > mute_limit || labs (bptr [1]) > mute_limit) { 362 if (labs (bptr [0]) > mute_limit || labs (bptr [1]) > mute_limit) {
396 i = (bptr - buffer) / 2; 363 i = (bptr - buffer) / 2;
397 break; 364 break;
398 } 365 }
399 366
400 crc = (crc * 3 + bptr [0]) * 3 + bptr [1]; 367 crc = (crc * 3 + bptr [0]) * 3 + bptr [1];
401 } 368 }
402 else 369 else
403 for (bptr = buffer; bptr < eptr; bptr += 2) { 370 for (bptr = buffer; bptr < eptr; bptr += 2) {
404 if (labs (bptr [0]) > mute_limit || labs (bptr [1]) > mute_limit) { 371 if (labs (bptr [0]) > mute_limit || labs (bptr [1]) > mute_limit) {
405 i = (bptr - buffer) / 2; 372 i = (bptr - buffer) / 2;
406 break; 373 break;
407 } 374 }
408 375
409 crc = (crc * 3 + bptr [0]) * 3 + bptr [1]; 376 crc = (crc * 3 + bptr [0]) * 3 + bptr [1];
410 } 377 }
411 } 378 }
412 379
413 if (i != sample_count) { 380 if (i != sample_count) {
414 memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8)); 381 memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8));
415 wps->mute_error = TRUE; 382 wps->mute_error = TRUE;
416 i = sample_count; 383 i = sample_count;
417 } 384 }
418 385
419 fixup_samples (wps, buffer, i); 386 fixup_samples (wps, buffer, i);
420 387
421 if (flags & FLOAT_DATA) 388 if (flags & FLOAT_DATA)
422 float_normalize (buffer, (flags & MONO_FLAG) ? i : i * 2, 389 float_normalize (buffer, (flags & MONO_FLAG) ? i : i * 2,
423 127 - wps->float_norm_exp + wpc->norm_offset); 390 127 - wps->float_norm_exp + wpc->norm_offset);
424 391
425 wps->sample_index += i; 392 wps->sample_index += i;
426 wps->crc = crc; 393 wps->crc = crc;
@@ -436,107 +403,107 @@ static void decorr_stereo_pass (struct decorr_pass *dpp, long *buffer, long samp
436 403
437 switch (dpp->term) { 404 switch (dpp->term) {
438 405
439 case 17: 406 case 17:
440 for (bptr = buffer; bptr < eptr; bptr += 2) { 407 for (bptr = buffer; bptr < eptr; bptr += 2) {
441 sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; 408 sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
442 dpp->samples_A [1] = dpp->samples_A [0]; 409 dpp->samples_A [1] = dpp->samples_A [0];
443 dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0]; 410 dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0];
444 update_weight (weight_A, delta, sam_A, bptr [0]); 411 update_weight (weight_A, delta, sam_A, bptr [0]);
445 bptr [0] = dpp->samples_A [0]; 412 bptr [0] = dpp->samples_A [0];
446 413
447 sam_A = 2 * dpp->samples_B [0] - dpp->samples_B [1]; 414 sam_A = 2 * dpp->samples_B [0] - dpp->samples_B [1];
448 dpp->samples_B [1] = dpp->samples_B [0]; 415 dpp->samples_B [1] = dpp->samples_B [0];
449 dpp->samples_B [0] = apply_weight (weight_B, sam_A) + bptr [1]; 416 dpp->samples_B [0] = apply_weight (weight_B, sam_A) + bptr [1];
450 update_weight (weight_B, delta, sam_A, bptr [1]); 417 update_weight (weight_B, delta, sam_A, bptr [1]);
451 bptr [1] = dpp->samples_B [0]; 418 bptr [1] = dpp->samples_B [0];
452 } 419 }
453 420
454 break; 421 break;
455 422
456 case 18: 423 case 18:
457 for (bptr = buffer; bptr < eptr; bptr += 2) { 424 for (bptr = buffer; bptr < eptr; bptr += 2) {
458 sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; 425 sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
459 dpp->samples_A [1] = dpp->samples_A [0]; 426 dpp->samples_A [1] = dpp->samples_A [0];
460 dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0]; 427 dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0];
461 update_weight (weight_A, delta, sam_A, bptr [0]); 428 update_weight (weight_A, delta, sam_A, bptr [0]);
462 bptr [0] = dpp->samples_A [0]; 429 bptr [0] = dpp->samples_A [0];
463 430
464 sam_A = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1; 431 sam_A = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1;
465 dpp->samples_B [1] = dpp->samples_B [0]; 432 dpp->samples_B [1] = dpp->samples_B [0];
466 dpp->samples_B [0] = apply_weight (weight_B, sam_A) + bptr [1]; 433 dpp->samples_B [0] = apply_weight (weight_B, sam_A) + bptr [1];
467 update_weight (weight_B, delta, sam_A, bptr [1]); 434 update_weight (weight_B, delta, sam_A, bptr [1]);
468 bptr [1] = dpp->samples_B [0]; 435 bptr [1] = dpp->samples_B [0];
469 } 436 }
470 437
471 break; 438 break;
472 439
473 default: 440 default:
474 for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr += 2) { 441 for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr += 2) {
475 sam_A = dpp->samples_A [m]; 442 sam_A = dpp->samples_A [m];
476 dpp->samples_A [k] = apply_weight (weight_A, sam_A) + bptr [0]; 443 dpp->samples_A [k] = apply_weight (weight_A, sam_A) + bptr [0];
477 update_weight (weight_A, delta, sam_A, bptr [0]); 444 update_weight (weight_A, delta, sam_A, bptr [0]);
478 bptr [0] = dpp->samples_A [k]; 445 bptr [0] = dpp->samples_A [k];
479 446
480 sam_A = dpp->samples_B [m]; 447 sam_A = dpp->samples_B [m];
481 dpp->samples_B [k] = apply_weight (weight_B, sam_A) + bptr [1]; 448 dpp->samples_B [k] = apply_weight (weight_B, sam_A) + bptr [1];
482 update_weight (weight_B, delta, sam_A, bptr [1]); 449 update_weight (weight_B, delta, sam_A, bptr [1]);
483 bptr [1] = dpp->samples_B [k]; 450 bptr [1] = dpp->samples_B [k];
484 451
485 m = (m + 1) & (MAX_TERM - 1); 452 m = (m + 1) & (MAX_TERM - 1);
486 k = (k + 1) & (MAX_TERM - 1); 453 k = (k + 1) & (MAX_TERM - 1);
487 } 454 }
488 455
489 if (m) { 456 if (m) {
490 long temp_samples [MAX_TERM]; 457 long temp_samples [MAX_TERM];
491 458
492 memcpy (temp_samples, dpp->samples_A, sizeof (dpp->samples_A)); 459 memcpy (temp_samples, dpp->samples_A, sizeof (dpp->samples_A));
493 460
494 for (k = 0; k < MAX_TERM; k++, m++) 461 for (k = 0; k < MAX_TERM; k++, m++)
495 dpp->samples_A [k] = temp_samples [m & (MAX_TERM - 1)]; 462 dpp->samples_A [k] = temp_samples [m & (MAX_TERM - 1)];
496 463
497 memcpy (temp_samples, dpp->samples_B, sizeof (dpp->samples_B)); 464 memcpy (temp_samples, dpp->samples_B, sizeof (dpp->samples_B));
498 465
499 for (k = 0; k < MAX_TERM; k++, m++) 466 for (k = 0; k < MAX_TERM; k++, m++)
500 dpp->samples_B [k] = temp_samples [m & (MAX_TERM - 1)]; 467 dpp->samples_B [k] = temp_samples [m & (MAX_TERM - 1)];
501 } 468 }
502 469
503 break; 470 break;
504 471
505 case -1: 472 case -1:
506 for (bptr = buffer; bptr < eptr; bptr += 2) { 473 for (bptr = buffer; bptr < eptr; bptr += 2) {
507 sam_A = bptr [0] + apply_weight (weight_A, dpp->samples_A [0]); 474 sam_A = bptr [0] + apply_weight (weight_A, dpp->samples_A [0]);
508 update_weight_clip (weight_A, delta, dpp->samples_A [0], bptr [0]); 475 update_weight_clip (weight_A, delta, dpp->samples_A [0], bptr [0]);
509 bptr [0] = sam_A; 476 bptr [0] = sam_A;
510 dpp->samples_A [0] = bptr [1] + apply_weight (weight_B, sam_A); 477 dpp->samples_A [0] = bptr [1] + apply_weight (weight_B, sam_A);
511 update_weight_clip (weight_B, delta, sam_A, bptr [1]); 478 update_weight_clip (weight_B, delta, sam_A, bptr [1]);
512 bptr [1] = dpp->samples_A [0]; 479 bptr [1] = dpp->samples_A [0];
513 } 480 }
514 481
515 break; 482 break;
516 483
517 case -2: 484 case -2:
518 for (bptr = buffer; bptr < eptr; bptr += 2) { 485 for (bptr = buffer; bptr < eptr; bptr += 2) {
519 sam_B = bptr [1] + apply_weight (weight_B, dpp->samples_B [0]); 486 sam_B = bptr [1] + apply_weight (weight_B, dpp->samples_B [0]);
520 update_weight_clip (weight_B, delta, dpp->samples_B [0], bptr [1]); 487 update_weight_clip (weight_B, delta, dpp->samples_B [0], bptr [1]);
521 bptr [1] = sam_B; 488 bptr [1] = sam_B;
522 dpp->samples_B [0] = bptr [0] + apply_weight (weight_A, sam_B); 489 dpp->samples_B [0] = bptr [0] + apply_weight (weight_A, sam_B);
523 update_weight_clip (weight_A, delta, sam_B, bptr [0]); 490 update_weight_clip (weight_A, delta, sam_B, bptr [0]);
524 bptr [0] = dpp->samples_B [0]; 491 bptr [0] = dpp->samples_B [0];
525 } 492 }
526 493
527 break; 494 break;
528 495
529 case -3: 496 case -3:
530 for (bptr = buffer; bptr < eptr; bptr += 2) { 497 for (bptr = buffer; bptr < eptr; bptr += 2) {
531 sam_A = bptr [0] + apply_weight (weight_A, dpp->samples_A [0]); 498 sam_A = bptr [0] + apply_weight (weight_A, dpp->samples_A [0]);
532 update_weight_clip (weight_A, delta, dpp->samples_A [0], bptr [0]); 499 update_weight_clip (weight_A, delta, dpp->samples_A [0], bptr [0]);
533 sam_B = bptr [1] + apply_weight (weight_B, dpp->samples_B [0]); 500 sam_B = bptr [1] + apply_weight (weight_B, dpp->samples_B [0]);
534 update_weight_clip (weight_B, delta, dpp->samples_B [0], bptr [1]); 501 update_weight_clip (weight_B, delta, dpp->samples_B [0], bptr [1]);
535 bptr [0] = dpp->samples_B [0] = sam_A; 502 bptr [0] = dpp->samples_B [0] = sam_A;
536 bptr [1] = dpp->samples_A [0] = sam_B; 503 bptr [1] = dpp->samples_A [0] = sam_B;
537 } 504 }
538 505
539 break; 506 break;
540 } 507 }
541 508
542 dpp->weight_A = weight_A; 509 dpp->weight_A = weight_A;
@@ -553,89 +520,89 @@ static void decorr_stereo_pass_cont (struct decorr_pass *dpp, long *buffer, long
553 520
554 switch (dpp->term) { 521 switch (dpp->term) {
555 522
556 case 17: 523 case 17:
557 for (bptr = buffer; bptr < eptr; bptr += 2) { 524 for (bptr = buffer; bptr < eptr; bptr += 2) {
558 sam_A = 2 * bptr [-2] - bptr [-4]; 525 sam_A = 2 * bptr [-2] - bptr [-4];
559 bptr [0] = apply_weight (weight_A, sam_A) + (sam_B = bptr [0]); 526 bptr [0] = apply_weight (weight_A, sam_A) + (sam_B = bptr [0]);
560 update_weight (weight_A, delta, sam_A, sam_B); 527 update_weight (weight_A, delta, sam_A, sam_B);
561 528
562 sam_A = 2 * bptr [-1] - bptr [-3]; 529 sam_A = 2 * bptr [-1] - bptr [-3];
563 bptr [1] = apply_weight (weight_B, sam_A) + (sam_B = bptr [1]); 530 bptr [1] = apply_weight (weight_B, sam_A) + (sam_B = bptr [1]);
564 update_weight (weight_B, delta, sam_A, sam_B); 531 update_weight (weight_B, delta, sam_A, sam_B);
565 } 532 }
566 533
567 dpp->samples_B [0] = bptr [-1]; 534 dpp->samples_B [0] = bptr [-1];
568 dpp->samples_A [0] = bptr [-2]; 535 dpp->samples_A [0] = bptr [-2];
569 dpp->samples_B [1] = bptr [-3]; 536 dpp->samples_B [1] = bptr [-3];
570 dpp->samples_A [1] = bptr [-4]; 537 dpp->samples_A [1] = bptr [-4];
571 break; 538 break;
572 539
573 case 18: 540 case 18:
574 for (bptr = buffer; bptr < eptr; bptr += 2) { 541 for (bptr = buffer; bptr < eptr; bptr += 2) {
575 sam_A = (3 * bptr [-2] - bptr [-4]) >> 1; 542 sam_A = (3 * bptr [-2] - bptr [-4]) >> 1;
576 bptr [0] = apply_weight (weight_A, sam_A) + (sam_B = bptr [0]); 543 bptr [0] = apply_weight (weight_A, sam_A) + (sam_B = bptr [0]);
577 update_weight (weight_A, delta, sam_A, sam_B); 544 update_weight (weight_A, delta, sam_A, sam_B);
578 545
579 sam_A = (3 * bptr [-1] - bptr [-3]) >> 1; 546 sam_A = (3 * bptr [-1] - bptr [-3]) >> 1;
580 bptr [1] = apply_weight (weight_B, sam_A) + (sam_B = bptr [1]); 547 bptr [1] = apply_weight (weight_B, sam_A) + (sam_B = bptr [1]);
581 update_weight (weight_B, delta, sam_A, sam_B); 548 update_weight (weight_B, delta, sam_A, sam_B);
582 } 549 }
583 550
584 dpp->samples_B [0] = bptr [-1]; 551 dpp->samples_B [0] = bptr [-1];
585 dpp->samples_A [0] = bptr [-2]; 552 dpp->samples_A [0] = bptr [-2];
586 dpp->samples_B [1] = bptr [-3]; 553 dpp->samples_B [1] = bptr [-3];
587 dpp->samples_A [1] = bptr [-4]; 554 dpp->samples_A [1] = bptr [-4];
588 break; 555 break;
589 556
590 default: 557 default:
591 for (bptr = buffer, tptr = buffer - (dpp->term * 2); bptr < eptr; bptr += 2, tptr += 2) { 558 for (bptr = buffer, tptr = buffer - (dpp->term * 2); bptr < eptr; bptr += 2, tptr += 2) {
592 bptr [0] = apply_weight (weight_A, tptr [0]) + (sam_A = bptr [0]); 559 bptr [0] = apply_weight (weight_A, tptr [0]) + (sam_A = bptr [0]);
593 update_weight (weight_A, delta, tptr [0], sam_A); 560 update_weight (weight_A, delta, tptr [0], sam_A);
594 561
595 bptr [1] = apply_weight (weight_B, tptr [1]) + (sam_A = bptr [1]); 562 bptr [1] = apply_weight (weight_B, tptr [1]) + (sam_A = bptr [1]);
596 update_weight (weight_B, delta, tptr [1], sam_A); 563 update_weight (weight_B, delta, tptr [1], sam_A);
597 } 564 }
598 565
599 for (k = dpp->term - 1, i = 8; i--; k--) { 566 for (k = dpp->term - 1, i = 8; i--; k--) {
600 dpp->samples_B [k & (MAX_TERM - 1)] = *--bptr; 567 dpp->samples_B [k & (MAX_TERM - 1)] = *--bptr;
601 dpp->samples_A [k & (MAX_TERM - 1)] = *--bptr; 568 dpp->samples_A [k & (MAX_TERM - 1)] = *--bptr;
602 } 569 }
603 570
604 break; 571 break;
605 572
606 case -1: 573 case -1:
607 for (bptr = buffer; bptr < eptr; bptr += 2) { 574 for (bptr = buffer; bptr < eptr; bptr += 2) {
608 bptr [0] = apply_weight (weight_A, bptr [-1]) + (sam_A = bptr [0]); 575 bptr [0] = apply_weight (weight_A, bptr [-1]) + (sam_A = bptr [0]);
609 update_weight_clip (weight_A, delta, bptr [-1], sam_A); 576 update_weight_clip (weight_A, delta, bptr [-1], sam_A);
610 bptr [1] = apply_weight (weight_B, bptr [0]) + (sam_A = bptr [1]); 577 bptr [1] = apply_weight (weight_B, bptr [0]) + (sam_A = bptr [1]);
611 update_weight_clip (weight_B, delta, bptr [0], sam_A); 578 update_weight_clip (weight_B, delta, bptr [0], sam_A);
612 } 579 }
613 580
614 dpp->samples_A [0] = bptr [-1]; 581 dpp->samples_A [0] = bptr [-1];
615 break; 582 break;
616 583
617 case -2: 584 case -2:
618 for (bptr = buffer; bptr < eptr; bptr += 2) { 585 for (bptr = buffer; bptr < eptr; bptr += 2) {
619 bptr [1] = apply_weight (weight_B, bptr [-2]) + (sam_A = bptr [1]); 586 bptr [1] = apply_weight (weight_B, bptr [-2]) + (sam_A = bptr [1]);
620 update_weight_clip (weight_B, delta, bptr [-2], sam_A); 587 update_weight_clip (weight_B, delta, bptr [-2], sam_A);
621 bptr [0] = apply_weight (weight_A, bptr [1]) + (sam_A = bptr [0]); 588 bptr [0] = apply_weight (weight_A, bptr [1]) + (sam_A = bptr [0]);
622 update_weight_clip (weight_A, delta, bptr [1], sam_A); 589 update_weight_clip (weight_A, delta, bptr [1], sam_A);
623 } 590 }
624 591
625 dpp->samples_B [0] = bptr [-2]; 592 dpp->samples_B [0] = bptr [-2];
626 break; 593 break;
627 594
628 case -3: 595 case -3:
629 for (bptr = buffer; bptr < eptr; bptr += 2) { 596 for (bptr = buffer; bptr < eptr; bptr += 2) {
630 bptr [0] = apply_weight (weight_A, bptr [-1]) + (sam_A = bptr [0]); 597 bptr [0] = apply_weight (weight_A, bptr [-1]) + (sam_A = bptr [0]);
631 update_weight_clip (weight_A, delta, bptr [-1], sam_A); 598 update_weight_clip (weight_A, delta, bptr [-1], sam_A);
632 bptr [1] = apply_weight (weight_B, bptr [-2]) + (sam_A = bptr [1]); 599 bptr [1] = apply_weight (weight_B, bptr [-2]) + (sam_A = bptr [1]);
633 update_weight_clip (weight_B, delta, bptr [-2], sam_A); 600 update_weight_clip (weight_B, delta, bptr [-2], sam_A);
634 } 601 }
635 602
636 dpp->samples_A [0] = bptr [-1]; 603 dpp->samples_A [0] = bptr [-1];
637 dpp->samples_B [0] = bptr [-2]; 604 dpp->samples_B [0] = bptr [-2];
638 break; 605 break;
639 } 606 }
640 607
641 dpp->weight_A = weight_A; 608 dpp->weight_A = weight_A;
@@ -652,48 +619,48 @@ static void decorr_mono_pass (struct decorr_pass *dpp, long *buffer, long sample
652 619
653 switch (dpp->term) { 620 switch (dpp->term) {
654 621
655 case 17: 622 case 17:
656 for (bptr = buffer; bptr < eptr; bptr++) { 623 for (bptr = buffer; bptr < eptr; bptr++) {
657 sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; 624 sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
658 dpp->samples_A [1] = dpp->samples_A [0]; 625 dpp->samples_A [1] = dpp->samples_A [0];
659 dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0]; 626 dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0];
660 update_weight (weight_A, delta, sam_A, bptr [0]); 627 update_weight (weight_A, delta, sam_A, bptr [0]);
661 bptr [0] = dpp->samples_A [0]; 628 bptr [0] = dpp->samples_A [0];
662 } 629 }
663 630
664 break; 631 break;
665 632
666 case 18: 633 case 18:
667 for (bptr = buffer; bptr < eptr; bptr++) { 634 for (bptr = buffer; bptr < eptr; bptr++) {
668 sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; 635 sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
669 dpp->samples_A [1] = dpp->samples_A [0]; 636 dpp->samples_A [1] = dpp->samples_A [0];
670 dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0]; 637 dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0];
671 update_weight (weight_A, delta, sam_A, bptr [0]); 638 update_weight (weight_A, delta, sam_A, bptr [0]);
672 bptr [0] = dpp->samples_A [0]; 639 bptr [0] = dpp->samples_A [0];
673 } 640 }
674 641
675 break; 642 break;
676 643
677 default: 644 default:
678 for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr++) { 645 for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr++) {
679 sam_A = dpp->samples_A [m]; 646 sam_A = dpp->samples_A [m];
680 dpp->samples_A [k] = apply_weight (weight_A, sam_A) + bptr [0]; 647 dpp->samples_A [k] = apply_weight (weight_A, sam_A) + bptr [0];
681 update_weight (weight_A, delta, sam_A, bptr [0]); 648 update_weight (weight_A, delta, sam_A, bptr [0]);
682 bptr [0] = dpp->samples_A [k]; 649 bptr [0] = dpp->samples_A [k];
683 m = (m + 1) & (MAX_TERM - 1); 650 m = (m + 1) & (MAX_TERM - 1);
684 k = (k + 1) & (MAX_TERM - 1); 651 k = (k + 1) & (MAX_TERM - 1);
685 } 652 }
686 653
687 if (m) { 654 if (m) {
688 long temp_samples [MAX_TERM]; 655 long temp_samples [MAX_TERM];
689 656
690 memcpy (temp_samples, dpp->samples_A, sizeof (dpp->samples_A)); 657 memcpy (temp_samples, dpp->samples_A, sizeof (dpp->samples_A));
691 658
692 for (k = 0; k < MAX_TERM; k++, m++) 659 for (k = 0; k < MAX_TERM; k++, m++)
693 dpp->samples_A [k] = temp_samples [m & (MAX_TERM - 1)]; 660 dpp->samples_A [k] = temp_samples [m & (MAX_TERM - 1)];
694 } 661 }
695 662
696 break; 663 break;
697 } 664 }
698 665
699 dpp->weight_A = weight_A; 666 dpp->weight_A = weight_A;
@@ -714,76 +681,76 @@ static void fixup_samples (WavpackStream *wps, long *buffer, ulong sample_count)
714 int shift = (flags & SHIFT_MASK) >> SHIFT_LSB; 681 int shift = (flags & SHIFT_MASK) >> SHIFT_LSB;
715 682
716 if (flags & FLOAT_DATA) { 683 if (flags & FLOAT_DATA) {
717 float_values (wps, buffer, (flags & MONO_FLAG) ? sample_count : sample_count * 2); 684 float_values (wps, buffer, (flags & MONO_FLAG) ? sample_count : sample_count * 2);
718 return; 685 return;
719 } 686 }
720 687
721 if (flags & INT32_DATA) { 688 if (flags & INT32_DATA) {
722 ulong count = (flags & MONO_FLAG) ? sample_count : sample_count * 2; 689 ulong count = (flags & MONO_FLAG) ? sample_count : sample_count * 2;
723 int sent_bits = wps->int32_sent_bits, zeros = wps->int32_zeros; 690 int sent_bits = wps->int32_sent_bits, zeros = wps->int32_zeros;
724 int ones = wps->int32_ones, dups = wps->int32_dups; 691 int ones = wps->int32_ones, dups = wps->int32_dups;
725// ulong mask = (1 << sent_bits) - 1; 692// ulong mask = (1 << sent_bits) - 1;
726 long *dptr = buffer; 693 long *dptr = buffer;
727 694
728 if (!(flags & HYBRID_FLAG) && !sent_bits && (zeros + ones + dups)) 695 if (!(flags & HYBRID_FLAG) && !sent_bits && (zeros + ones + dups))
729 while (count--) { 696 while (count--) {
730 if (zeros) 697 if (zeros)
731 *dptr <<= zeros; 698 *dptr <<= zeros;
732 else if (ones) 699 else if (ones)
733 *dptr = ((*dptr + 1) << ones) - 1; 700 *dptr = ((*dptr + 1) << ones) - 1;
734 else if (dups) 701 else if (dups)
735 *dptr = ((*dptr + (*dptr & 1)) << dups) - (*dptr & 1); 702 *dptr = ((*dptr + (*dptr & 1)) << dups) - (*dptr & 1);
736 703
737 dptr++; 704 dptr++;
738 } 705 }
739 else 706 else
740 shift += zeros + sent_bits + ones + dups; 707 shift += zeros + sent_bits + ones + dups;
741 } 708 }
742 709
743 if (flags & HYBRID_FLAG) { 710 if (flags & HYBRID_FLAG) {
744 long min_value, max_value, min_shifted, max_shifted; 711 long min_value, max_value, min_shifted, max_shifted;
745 712
746 switch (flags & BYTES_STORED) { 713 switch (flags & BYTES_STORED) {
747 case 0: 714 case 0:
748 min_shifted = (min_value = -128 >> shift) << shift; 715 min_shifted = (min_value = -128 >> shift) << shift;
749 max_shifted = (max_value = 127 >> shift) << shift; 716 max_shifted = (max_value = 127 >> shift) << shift;
750 break; 717 break;
751 718
752 case 1: 719 case 1:
753 min_shifted = (min_value = -32768 >> shift) << shift; 720 min_shifted = (min_value = -32768 >> shift) << shift;
754 max_shifted = (max_value = 32767 >> shift) << shift; 721 max_shifted = (max_value = 32767 >> shift) << shift;
755 break; 722 break;
756 723
757 case 2: 724 case 2:
758 min_shifted = (min_value = -8388608 >> shift) << shift; 725 min_shifted = (min_value = -8388608 >> shift) << shift;
759 max_shifted = (max_value = 8388607 >> shift) << shift; 726 max_shifted = (max_value = 8388607 >> shift) << shift;
760 break; 727 break;
761 728
762 case 3: 729 case 3:
763 default: 730 default:
764 min_shifted = (min_value = (long) 0x80000000 >> shift) << shift; 731 min_shifted = (min_value = (long) 0x80000000 >> shift) << shift;
765 max_shifted = (max_value = (long) 0x7FFFFFFF >> shift) << shift; 732 max_shifted = (max_value = (long) 0x7FFFFFFF >> shift) << shift;
766 break; 733 break;
767 } 734 }
768 735
769 if (!(flags & MONO_FLAG)) 736 if (!(flags & MONO_FLAG))
770 sample_count *= 2; 737 sample_count *= 2;
771 738
772 while (sample_count--) { 739 while (sample_count--) {
773 if (*buffer < min_value) 740 if (*buffer < min_value)
774 *buffer++ = min_shifted; 741 *buffer++ = min_shifted;
775 else if (*buffer > max_value) 742 else if (*buffer > max_value)
776 *buffer++ = max_shifted; 743 *buffer++ = max_shifted;
777 else 744 else
778 *buffer++ <<= shift; 745 *buffer++ <<= shift;
779 } 746 }
780 } 747 }
781 else if (shift) { 748 else if (shift) {
782 if (!(flags & MONO_FLAG)) 749 if (!(flags & MONO_FLAG))
783 sample_count *= 2; 750 sample_count *= 2;
784 751
785 while (sample_count--) 752 while (sample_count--)
786 *buffer++ <<= shift; 753 *buffer++ <<= shift;
787 } 754 }
788} 755}
789 756
@@ -800,7 +767,7 @@ int check_crc_error (WavpackContext *wpc)
800 int result = 0; 767 int result = 0;
801 768
802 if (wps->crc != wps->wphdr.crc) 769 if (wps->crc != wps->wphdr.crc)
803 ++result; 770 ++result;
804 771
805 return result; 772 return result;
806} 773}
diff --git a/apps/codecs/libwavpack/wavpack.h b/apps/codecs/libwavpack/wavpack.h
index 3aee4718b1..12212bb0f8 100644
--- a/apps/codecs/libwavpack/wavpack.h
+++ b/apps/codecs/libwavpack/wavpack.h
@@ -14,11 +14,10 @@
14 14
15// This header file contains all the definitions required by WavPack. 15// This header file contains all the definitions required by WavPack.
16 16
17// not sure about them.. testing will bring more light into it.. 17typedef unsigned char uchar;
18typedef unsigned char uchar; 18typedef unsigned short ushort;
19typedef unsigned short ushort; 19typedef unsigned long ulong;
20typedef unsigned long ulong; 20typedef unsigned int uint;
21typedef unsigned int uint;
22 21
23// This structure is used to access the individual fields of 32-bit ieee 22// This structure is used to access the individual fields of 32-bit ieee
24// floating point numbers. This will not be compatible with compilers that 23// floating point numbers. This will not be compatible with compilers that
@@ -54,70 +53,71 @@ typedef struct {
54 53
55// or-values for "flags" 54// or-values for "flags"
56 55
57#define BYTES_STORED 3 // 1-4 bytes/sample 56#define BYTES_STORED 3 // 1-4 bytes/sample
58#define MONO_FLAG 4 // not stereo 57#define MONO_FLAG 4 // not stereo
59#define HYBRID_FLAG 8 // hybrid mode 58#define HYBRID_FLAG 8 // hybrid mode
60#define JOINT_STEREO 0x10 // joint stereo 59#define JOINT_STEREO 0x10 // joint stereo
61#define CROSS_DECORR 0x20 // no-delay cross decorrelation 60#define CROSS_DECORR 0x20 // no-delay cross decorrelation
62#define HYBRID_SHAPE 0x40 // noise shape (hybrid mode only) 61#define HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
63#define FLOAT_DATA 0x80 // ieee 32-bit floating point data 62#define FLOAT_DATA 0x80 // ieee 32-bit floating point data
64 63
65#define INT32_DATA 0x100 // special extended int handling 64#define INT32_DATA 0x100 // special extended int handling
66#define HYBRID_BITRATE 0x200 // bitrate noise (hybrid mode only) 65#define HYBRID_BITRATE 0x200 // bitrate noise (hybrid mode only)
67#define HYBRID_BALANCE 0x400 // balance noise (hybrid stereo mode only) 66#define HYBRID_BALANCE 0x400 // balance noise (hybrid stereo mode only)
68 67
69#define INITIAL_BLOCK 0x800 // initial block of multichannel segment 68#define INITIAL_BLOCK 0x800 // initial block of multichannel segment
70#define FINAL_BLOCK 0x1000 // final block of multichannel segment 69#define FINAL_BLOCK 0x1000 // final block of multichannel segment
71 70
72#define SHIFT_LSB 13 71#define SHIFT_LSB 13
73#define SHIFT_MASK (0x1fL << SHIFT_LSB) 72#define SHIFT_MASK (0x1fL << SHIFT_LSB)
74 73
75#define MAG_LSB 18 74#define MAG_LSB 18
76#define MAG_MASK (0x1fL << MAG_LSB) 75#define MAG_MASK (0x1fL << MAG_LSB)
77 76
78#define SRATE_LSB 23 77#define SRATE_LSB 23
79#define SRATE_MASK (0xfL << SRATE_LSB) 78#define SRATE_MASK (0xfL << SRATE_LSB)
80 79
81#define IGNORED_FLAGS 0x18000000 // reserved, but ignore if encountered 80#define IGNORED_FLAGS 0x18000000 // reserved, but ignore if encountered
82#define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping 81#define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping
83#define UNKNOWN_FLAGS 0xC0000000 // also reserved, but refuse decode if 82#define UNKNOWN_FLAGS 0xC0000000 // also reserved, but refuse decode if
84 // encountered 83 // encountered
85 84
86//////////////////////////// WavPack Metadata ///////////////////////////////// 85//////////////////////////// WavPack Metadata /////////////////////////////////
87 86
88// This is an internal representation of metadata. 87// This is an internal representation of metadata.
89 88
90typedef struct { 89typedef struct {
90 uchar temp_data [64];
91 long byte_length; 91 long byte_length;
92 void *data; 92 void *data;
93 uchar id; 93 uchar id;
94} WavpackMetadata; 94} WavpackMetadata;
95 95
96#define ID_OPTIONAL_DATA 0x20 96#define ID_OPTIONAL_DATA 0x20
97#define ID_ODD_SIZE 0x40 97#define ID_ODD_SIZE 0x40
98#define ID_LARGE 0x80 98#define ID_LARGE 0x80
99 99
100#define ID_DUMMY 0x0 100#define ID_DUMMY 0x0
101#define ID_ENCODER_INFO 0x1 101#define ID_ENCODER_INFO 0x1
102#define ID_DECORR_TERMS 0x2 102#define ID_DECORR_TERMS 0x2
103#define ID_DECORR_WEIGHTS 0x3 103#define ID_DECORR_WEIGHTS 0x3
104#define ID_DECORR_SAMPLES 0x4 104#define ID_DECORR_SAMPLES 0x4
105#define ID_ENTROPY_VARS 0x5 105#define ID_ENTROPY_VARS 0x5
106#define ID_HYBRID_PROFILE 0x6 106#define ID_HYBRID_PROFILE 0x6
107#define ID_SHAPING_WEIGHTS 0x7 107#define ID_SHAPING_WEIGHTS 0x7
108#define ID_FLOAT_INFO 0x8 108#define ID_FLOAT_INFO 0x8
109#define ID_INT32_INFO 0x9 109#define ID_INT32_INFO 0x9
110#define ID_WV_BITSTREAM 0xa 110#define ID_WV_BITSTREAM 0xa
111#define ID_WVC_BITSTREAM 0xb 111#define ID_WVC_BITSTREAM 0xb
112#define ID_WVX_BITSTREAM 0xc 112#define ID_WVX_BITSTREAM 0xc
113#define ID_CHANNEL_INFO 0xd 113#define ID_CHANNEL_INFO 0xd
114 114
115#define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1) 115#define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1)
116#define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2) 116#define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2)
117#define ID_REPLAY_GAIN (ID_OPTIONAL_DATA | 0x3) 117#define ID_REPLAY_GAIN (ID_OPTIONAL_DATA | 0x3)
118#define ID_CUESHEET (ID_OPTIONAL_DATA | 0x4) 118#define ID_CUESHEET (ID_OPTIONAL_DATA | 0x4)
119#define ID_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0x5) 119#define ID_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0x5)
120#define ID_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x6) 120#define ID_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x6)
121 121
122///////////////////////// WavPack Configuration /////////////////////////////// 122///////////////////////// WavPack Configuration ///////////////////////////////
123 123
@@ -127,39 +127,39 @@ typedef struct {
127 127
128typedef struct { 128typedef struct {
129 int bits_per_sample, bytes_per_sample; 129 int bits_per_sample, bytes_per_sample;
130 int qmode, flags, xmode, num_channels, float_norm_exp; 130 int flags, num_channels, float_norm_exp;
131 long block_samples, extra_flags, sample_rate, channel_mask; 131 ulong sample_rate, channel_mask;
132} WavpackConfig; 132} WavpackConfig;
133 133
134#define CONFIG_BYTES_STORED 3 // 1-4 bytes/sample 134#define CONFIG_BYTES_STORED 3 // 1-4 bytes/sample
135#define CONFIG_MONO_FLAG 4 // not stereo 135#define CONFIG_MONO_FLAG 4 // not stereo
136#define CONFIG_HYBRID_FLAG 8 // hybrid mode 136#define CONFIG_HYBRID_FLAG 8 // hybrid mode
137#define CONFIG_JOINT_STEREO 0x10 // joint stereo 137#define CONFIG_JOINT_STEREO 0x10 // joint stereo
138#define CONFIG_CROSS_DECORR 0x20 // no-delay cross decorrelation 138#define CONFIG_CROSS_DECORR 0x20 // no-delay cross decorrelation
139#define CONFIG_HYBRID_SHAPE 0x40 // noise shape (hybrid mode only) 139#define CONFIG_HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
140#define CONFIG_FLOAT_DATA 0x80 // ieee 32-bit floating point data 140#define CONFIG_FLOAT_DATA 0x80 // ieee 32-bit floating point data
141 141
142#define CONFIG_ADOBE_MODE 0x100 // "adobe" mode for 32-bit floats 142#define CONFIG_ADOBE_MODE 0x100 // "adobe" mode for 32-bit floats
143#define CONFIG_FAST_FLAG 0x200 // fast mode 143#define CONFIG_FAST_FLAG 0x200 // fast mode
144#define CONFIG_VERY_FAST_FLAG 0x400 // double fast 144#define CONFIG_VERY_FAST_FLAG 0x400 // double fast
145#define CONFIG_HIGH_FLAG 0x800 // high quality mode 145#define CONFIG_HIGH_FLAG 0x800 // high quality mode
146#define CONFIG_VERY_HIGH_FLAG 0x1000 // double high (not used yet) 146#define CONFIG_VERY_HIGH_FLAG 0x1000 // double high (not used yet)
147#define CONFIG_BITRATE_KBPS 0x2000 // bitrate is kbps, not bits / sample 147#define CONFIG_BITRATE_KBPS 0x2000 // bitrate is kbps, not bits / sample
148#define CONFIG_AUTO_SHAPING 0x4000 // automatic noise shaping 148#define CONFIG_AUTO_SHAPING 0x4000 // automatic noise shaping
149#define CONFIG_SHAPE_OVERRIDE 0x8000 // shaping mode specified 149#define CONFIG_SHAPE_OVERRIDE 0x8000 // shaping mode specified
150#define CONFIG_JOINT_OVERRIDE 0x10000 // joint-stereo mode specified 150#define CONFIG_JOINT_OVERRIDE 0x10000 // joint-stereo mode specified
151#define CONFIG_COPY_TIME 0x20000 // copy file-time from source 151#define CONFIG_COPY_TIME 0x20000 // copy file-time from source
152#define CONFIG_CREATE_EXE 0x40000 // create executable (not yet) 152#define CONFIG_CREATE_EXE 0x40000 // create executable (not yet)
153#define CONFIG_CREATE_WVC 0x80000 // create correction file 153#define CONFIG_CREATE_WVC 0x80000 // create correction file
154#define CONFIG_OPTIMIZE_WVC 0x100000 // maximize bybrid compression 154#define CONFIG_OPTIMIZE_WVC 0x100000 // maximize bybrid compression
155#define CONFIG_QUALITY_MODE 0x200000 // psychoacoustic quality mode 155#define CONFIG_QUALITY_MODE 0x200000 // psychoacoustic quality mode
156#define CONFIG_RAW_FLAG 0x400000 // raw mode (not implemented yet) 156#define CONFIG_RAW_FLAG 0x400000 // raw mode (not implemented yet)
157#define CONFIG_CALC_NOISE 0x800000 // calc noise in hybrid mode 157#define CONFIG_CALC_NOISE 0x800000 // calc noise in hybrid mode
158#define CONFIG_LOSSY_MODE 0x1000000 // obsolete (for information) 158#define CONFIG_LOSSY_MODE 0x1000000 // obsolete (for information)
159#define CONFIG_EXTRA_MODE 0x2000000 // extra processing mode 159#define CONFIG_EXTRA_MODE 0x2000000 // extra processing mode
160#define CONFIG_SKIP_WVX 0x4000000 // no wvx stream w/ floats & big ints 160#define CONFIG_SKIP_WVX 0x4000000 // no wvx stream w/ floats & big ints
161#define CONFIG_MD5_CHECKSUM 0x8000000 // compute & store MD5 signature 161#define CONFIG_MD5_CHECKSUM 0x8000000 // compute & store MD5 signature
162#define CONFIG_QUIET_MODE 0x10000000 // don't report progress % 162#define CONFIG_QUIET_MODE 0x10000000 // don't report progress %
163 163
164//////////////////////////////// WavPack Stream /////////////////////////////// 164//////////////////////////////// WavPack Stream ///////////////////////////////
165 165
@@ -191,35 +191,38 @@ struct entropy_data {
191 ulong median [3], slow_level, error_limit; 191 ulong median [3], slow_level, error_limit;
192}; 192};
193 193
194struct words_data {
195 ulong bitrate_delta [2], bitrate_acc [2];
196 ulong pend_data, holding_one, zeros_acc;
197 int holding_zero, pend_count;
198 struct entropy_data c [2];
199};
200
194typedef struct { 201typedef struct {
195 WavpackHeader wphdr; 202 WavpackHeader wphdr;
196 Bitstream wvbits; 203 Bitstream wvbits;
197 204
198 struct { 205 struct words_data w;
199 ulong bitrate_delta [2], bitrate_acc [2];
200 ulong pend_data, holding_one, zeros_acc;
201 int holding_zero, pend_count;
202 struct entropy_data c [2];
203 } w;
204 206
205 int num_terms, mute_error; 207 int num_terms, mute_error;
206 ulong sample_index, crc; 208 ulong sample_index, crc;
207 209
208 uchar int32_sent_bits, int32_zeros, int32_ones, int32_dups; 210 uchar int32_sent_bits, int32_zeros, int32_ones, int32_dups;
209 uchar float_flags, float_shift, float_max_exp, float_norm_exp; 211 uchar float_flags, float_shift, float_max_exp, float_norm_exp;
210 212 uchar *blockbuff, *blockend;
213
211 struct decorr_pass decorr_passes [MAX_NTERMS]; 214 struct decorr_pass decorr_passes [MAX_NTERMS];
212 215
213} WavpackStream; 216} WavpackStream;
214 217
215// flags for float_flags: 218// flags for float_flags:
216 219
217#define FLOAT_SHIFT_ONES 1 // bits left-shifted into float = '1' 220#define FLOAT_SHIFT_ONES 1 // bits left-shifted into float = '1'
218#define FLOAT_SHIFT_SAME 2 // bits left-shifted into float are the same 221#define FLOAT_SHIFT_SAME 2 // bits left-shifted into float are the same
219#define FLOAT_SHIFT_SENT 4 // bits shifted into float are sent literally 222#define FLOAT_SHIFT_SENT 4 // bits shifted into float are sent literally
220#define FLOAT_ZEROS_SENT 8 // "zeros" are not all real zeros 223#define FLOAT_ZEROS_SENT 8 // "zeros" are not all real zeros
221#define FLOAT_NEG_ZEROS 0x10 // contains negative zeros 224#define FLOAT_NEG_ZEROS 0x10 // contains negative zeros
222#define FLOAT_EXCEPTIONS 0x20 // contains exceptions (inf, nan, etc.) 225#define FLOAT_EXCEPTIONS 0x20 // contains exceptions (inf, nan, etc.)
223 226
224/////////////////////////////// WavPack Context /////////////////////////////// 227/////////////////////////////// WavPack Context ///////////////////////////////
225 228
@@ -231,6 +234,13 @@ typedef struct {
231 WavpackStream stream; 234 WavpackStream stream;
232 WavpackConfig config; 235 WavpackConfig config;
233 236
237 WavpackMetadata *metadata;
238 ulong metabytes;
239 int metacount;
240
241 uchar *wrapper_data;
242 int wrapper_bytes;
243
234 uchar read_buffer [1024]; 244 uchar read_buffer [1024];
235 char error_message [80]; 245 char error_message [80];
236 246
@@ -247,32 +257,96 @@ typedef struct {
247// bits.c 257// bits.c
248 258
249void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end, read_stream file, ulong file_bytes); 259void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end, read_stream file, ulong file_bytes);
260void bs_open_write (Bitstream *bs, uchar *buffer_start, uchar *buffer_end);
261ulong bs_close_write (Bitstream *bs);
250 262
251#define bs_is_open(bs) ((bs)->ptr != NULL) 263#define bs_is_open(bs) ((bs)->ptr != NULL)
252 264
253#define getbit(bs) ( \ 265#define getbit(bs) ( \
254 (((bs)->bc) ? \ 266 (((bs)->bc) ? \
255 ((bs)->bc--, (bs)->sr & 1) : \ 267 ((bs)->bc--, (bs)->sr & 1) : \
256 (((++((bs)->ptr) != (bs)->end) ? (void) 0 : (bs)->wrap (bs)), (bs)->bc = 7, ((bs)->sr = *((bs)->ptr)) & 1) \ 268 (((++((bs)->ptr) != (bs)->end) ? (void) 0 : (bs)->wrap (bs)), (bs)->bc = 7, ((bs)->sr = *((bs)->ptr)) & 1) \
257 ) ? \ 269 ) ? \
258 ((bs)->sr >>= 1, 1) : \ 270 ((bs)->sr >>= 1, 1) : \
259 ((bs)->sr >>= 1, 0) \ 271 ((bs)->sr >>= 1, 0) \
260) 272)
261 273
262#define getbits(value, nbits, bs) { \ 274#define getbits(value, nbits, bs) { \
263 while ((nbits) > (bs)->bc) { \ 275 while ((nbits) > (bs)->bc) { \
264 if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \ 276 if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
265 (bs)->sr |= (long)*((bs)->ptr) << (bs)->bc; \ 277 (bs)->sr |= (long)*((bs)->ptr) << (bs)->bc; \
266 (bs)->bc += 8; \ 278 (bs)->bc += 8; \
267 } \ 279 } \
268 *(value) = (bs)->sr; \ 280 *(value) = (bs)->sr; \
269 (bs)->sr >>= (nbits); \ 281 (bs)->sr >>= (nbits); \
270 (bs)->bc -= (nbits); \ 282 (bs)->bc -= (nbits); \
271} 283}
272 284
285#define putbit(bit, bs) { if (bit) (bs)->sr |= (1 << (bs)->bc); \
286 if (++((bs)->bc) == 8) { \
287 *((bs)->ptr) = (bs)->sr; \
288 (bs)->sr = (bs)->bc = 0; \
289 if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
290 }}
291
292#define putbit_0(bs) { \
293 if (++((bs)->bc) == 8) { \
294 *((bs)->ptr) = (bs)->sr; \
295 (bs)->sr = (bs)->bc = 0; \
296 if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
297 }}
298
299#define putbit_1(bs) { (bs)->sr |= (1 << (bs)->bc); \
300 if (++((bs)->bc) == 8) { \
301 *((bs)->ptr) = (bs)->sr; \
302 (bs)->sr = (bs)->bc = 0; \
303 if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
304 }}
305
306#define putbits(value, nbits, bs) { \
307 (bs)->sr |= (long)(value) << (bs)->bc; \
308 if (((bs)->bc += (nbits)) >= 8) \
309 do { \
310 *((bs)->ptr) = (bs)->sr; \
311 (bs)->sr >>= 8; \
312 if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
313 } while (((bs)->bc -= 8) >= 8); \
314}
315
273void little_endian_to_native (void *data, char *format); 316void little_endian_to_native (void *data, char *format);
274void native_to_little_endian (void *data, char *format); 317void native_to_little_endian (void *data, char *format);
275 318
319// these macros implement the weight application and update operations
320// that are at the heart of the decorrelation loops
321
322#if 0 // PERFCOND
323#define apply_weight_i(weight, sample) ((weight * sample + 512) >> 10)
324#else
325#define apply_weight_i(weight, sample) ((((weight * sample) >> 8) + 2) >> 2)
326#endif
327
328#define apply_weight_f(weight, sample) (((((sample & 0xffff) * weight) >> 9) + \
329 (((sample & ~0xffff) >> 9) * weight) + 1) >> 1)
330
331#if 1 // PERFCOND
332#define apply_weight(weight, sample) (sample != (short) sample ? \
333 apply_weight_f (weight, sample) : apply_weight_i (weight, sample))
334#else
335#define apply_weight(weight, sample) ((int32_t)((weight * (int64_t) sample + 512) >> 10))
336#endif
337
338#if 0 // PERFCOND
339#define update_weight(weight, delta, source, result) \
340 if (source && result) weight -= ((((source ^ result) >> 30) & 2) - 1) * delta;
341#else
342#define update_weight(weight, delta, source, result) \
343 if (source && result) (source ^ result) < 0 ? (weight -= delta) : (weight += delta);
344#endif
345
346#define update_weight_clip(weight, delta, source, result) \
347 if (source && result && ((source ^ result) < 0 ? (weight -= delta) < -1024 : (weight += delta) > 1024)) \
348 weight = weight < 0 ? -1024 : 1024;
349
276// unpack.c 350// unpack.c
277 351
278int unpack_init (WavpackContext *wpc); 352int unpack_init (WavpackContext *wpc);
@@ -287,17 +361,31 @@ int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd);
287long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count); 361long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count);
288int check_crc_error (WavpackContext *wpc); 362int check_crc_error (WavpackContext *wpc);
289 363
364// pack.c
365
366void pack_init (WavpackContext *wpc);
367int pack_block (WavpackContext *wpc, long *buffer);
368
290// metadata.c stuff 369// metadata.c stuff
291 370
292int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd); 371int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd);
293int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd); 372int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd);
373int copy_metadata (WavpackMetadata *wpmd, uchar *buffer_start, uchar *buffer_end);
374void free_metadata (WavpackMetadata *wpmd);
294 375
295// words.c stuff 376// words.c stuff
296 377
378void init_words (WavpackStream *wps);
297int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd); 379int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd);
380void write_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd);
298int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd); 381int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd);
299long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer); 382long get_words (long *buffer, int nsamples, ulong flags,
383 struct words_data *w, Bitstream *bs);
384void send_word_lossless (WavpackStream *wps, long value, int chan);
385void flush_word (WavpackStream *wps);
386int log2s (long value);
300long exp2s (int log); 387long exp2s (int log);
388char store_weight (int weight);
301int restore_weight (char weight); 389int restore_weight (char weight);
302 390
303#define WORD_EOF (1L << 31) 391#define WORD_EOF (1L << 31)
@@ -314,13 +402,13 @@ WavpackContext *WavpackOpenFileInput (read_stream infile, char *error);
314 402
315int WavpackGetMode (WavpackContext *wpc); 403int WavpackGetMode (WavpackContext *wpc);
316 404
317#define MODE_WVC 0x1 405#define MODE_WVC 0x1
318#define MODE_LOSSLESS 0x2 406#define MODE_LOSSLESS 0x2
319#define MODE_HYBRID 0x4 407#define MODE_HYBRID 0x4
320#define MODE_FLOAT 0x8 408#define MODE_FLOAT 0x8
321#define MODE_VALID_TAG 0x10 409#define MODE_VALID_TAG 0x10
322#define MODE_HIGH 0x20 410#define MODE_HIGH 0x20
323#define MODE_FAST 0x40 411#define MODE_FAST 0x40
324 412
325ulong WavpackUnpackSamples (WavpackContext *wpc, long *buffer, ulong samples); 413ulong WavpackUnpackSamples (WavpackContext *wpc, long *buffer, ulong samples);
326ulong WavpackGetNumSamples (WavpackContext *wpc); 414ulong WavpackGetNumSamples (WavpackContext *wpc);
@@ -332,3 +420,10 @@ int WavpackGetBitsPerSample (WavpackContext *wpc);
332int WavpackGetBytesPerSample (WavpackContext *wpc); 420int WavpackGetBytesPerSample (WavpackContext *wpc);
333int WavpackGetNumChannels (WavpackContext *wpc); 421int WavpackGetNumChannels (WavpackContext *wpc);
334int WavpackGetReducedChannels (WavpackContext *wpc); 422int WavpackGetReducedChannels (WavpackContext *wpc);
423WavpackContext *WavpackOpenFileOutput (void);
424void WavpackSetOutputBuffer (WavpackContext *wpc, uchar *begin, uchar *end);
425int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, ulong total_samples);
426void WavpackAddWrapper (WavpackContext *wpc, void *data, ulong bcount);
427ulong WavpackPackSamples (WavpackContext *wpc, long *sample_buffer, ulong sample_count);
428
429
diff --git a/apps/codecs/libwavpack/words.c b/apps/codecs/libwavpack/words.c
index 8e2fc427a6..75d8a86af7 100644
--- a/apps/codecs/libwavpack/words.c
+++ b/apps/codecs/libwavpack/words.c
@@ -29,7 +29,7 @@
29 29
30//////////////////////////////// local macros ///////////////////////////////// 30//////////////////////////////// local macros /////////////////////////////////
31 31
32#define LIMIT_ONES 16 // maximum consecutive 1s sent for "div" data 32#define LIMIT_ONES 16 // maximum consecutive 1s sent for "div" data
33 33
34// these control the time constant "slow_level" which is used for hybrid mode 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). 35// that controls bitrate as a function of residual level (HYBRID_BITRATE).
@@ -37,9 +37,9 @@
37#define SLO ((1 << (SLS - 1))) 37#define SLO ((1 << (SLS - 1)))
38 38
39// these control the time constant of the 3 median level breakpoints 39// these control the time constant of the 3 median level breakpoints
40#define DIV0 128 // 5/7 of samples 40#define DIV0 128 // 5/7 of samples
41#define DIV1 64 // 10/49 of samples 41#define DIV1 64 // 10/49 of samples
42#define DIV2 32 // 20/343 of samples 42#define DIV2 32 // 20/343 of samples
43 43
44// this macro retrieves the specified median breakpoint (without frac; min = 1) 44// this macro retrieves the specified median breakpoint (without frac; min = 1)
45#define GET_MED(med) (((c->median [med]) >> 4) + 1) 45#define GET_MED(med) (((c->median [med]) >> 4) + 1)
@@ -66,23 +66,45 @@
66 66
67///////////////////////////// local table storage //////////////////////////// 67///////////////////////////// local table storage ////////////////////////////
68 68
69const ulong bitset [] = {
70 1L << 0, 1L << 1, 1L << 2, 1L << 3,
71 1L << 4, 1L << 5, 1L << 6, 1L << 7,
72 1L << 8, 1L << 9, 1L << 10, 1L << 11,
73 1L << 12, 1L << 13, 1L << 14, 1L << 15,
74 1L << 16, 1L << 17, 1L << 18, 1L << 19,
75 1L << 20, 1L << 21, 1L << 22, 1L << 23,
76 1L << 24, 1L << 25, 1L << 26, 1L << 27,
77 1L << 28, 1L << 29, 1L << 30, 1L << 31
78};
79
80const ulong bitmask [] = {
81 (1L << 0) - 1, (1L << 1) - 1, (1L << 2) - 1, (1L << 3) - 1,
82 (1L << 4) - 1, (1L << 5) - 1, (1L << 6) - 1, (1L << 7) - 1,
83 (1L << 8) - 1, (1L << 9) - 1, (1L << 10) - 1, (1L << 11) - 1,
84 (1L << 12) - 1, (1L << 13) - 1, (1L << 14) - 1, (1L << 15) - 1,
85 (1L << 16) - 1, (1L << 17) - 1, (1L << 18) - 1, (1L << 19) - 1,
86 (1L << 20) - 1, (1L << 21) - 1, (1L << 22) - 1, (1L << 23) - 1,
87 (1L << 24) - 1, (1L << 25) - 1, (1L << 26) - 1, (1L << 27) - 1,
88 (1L << 28) - 1, (1L << 29) - 1, (1L << 30) - 1, 0x7fffffff
89};
90
69const char nbits_table [] = { 91const char nbits_table [] = {
70 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, // 0 - 15 92 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 93 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 94 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 95 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 96 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 97 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 98 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 99 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 100 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 101 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 102 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 103 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 104 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 105 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 106 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 107 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 // 240 - 255
86}; 108};
87 109
88static const uchar log2_table [] = { 110static const uchar log2_table [] = {
@@ -136,6 +158,11 @@ static const char ones_count_table [] = {
136 158
137///////////////////////////// executable code //////////////////////////////// 159///////////////////////////// executable code ////////////////////////////////
138 160
161void init_words (WavpackStream *wps)
162{
163 CLEAR (wps->w);
164}
165
139static int mylog2 (unsigned long avalue); 166static int mylog2 (unsigned long avalue);
140 167
141// Read the median log2 values from the specifed metadata structure, convert 168// Read the median log2 values from the specifed metadata structure, convert
@@ -147,21 +174,55 @@ int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd)
147 uchar *byteptr = wpmd->data; 174 uchar *byteptr = wpmd->data;
148 175
149 if (wpmd->byte_length != ((wps->wphdr.flags & MONO_FLAG) ? 6 : 12)) 176 if (wpmd->byte_length != ((wps->wphdr.flags & MONO_FLAG) ? 6 : 12))
150 return FALSE; 177 return FALSE;
151 178
152 wps->w.c [0].median [0] = exp2s (byteptr [0] + (byteptr [1] << 8)); 179 wps->w.c [0].median [0] = exp2s (byteptr [0] + (byteptr [1] << 8));
153 wps->w.c [0].median [1] = exp2s (byteptr [2] + (byteptr [3] << 8)); 180 wps->w.c [0].median [1] = exp2s (byteptr [2] + (byteptr [3] << 8));
154 wps->w.c [0].median [2] = exp2s (byteptr [4] + (byteptr [5] << 8)); 181 wps->w.c [0].median [2] = exp2s (byteptr [4] + (byteptr [5] << 8));
155 182
156 if (!(wps->wphdr.flags & MONO_FLAG)) { 183 if (!(wps->wphdr.flags & MONO_FLAG)) {
157 wps->w.c [1].median [0] = exp2s (byteptr [6] + (byteptr [7] << 8)); 184 wps->w.c [1].median [0] = exp2s (byteptr [6] + (byteptr [7] << 8));
158 wps->w.c [1].median [1] = exp2s (byteptr [8] + (byteptr [9] << 8)); 185 wps->w.c [1].median [1] = exp2s (byteptr [8] + (byteptr [9] << 8));
159 wps->w.c [1].median [2] = exp2s (byteptr [10] + (byteptr [11] << 8)); 186 wps->w.c [1].median [2] = exp2s (byteptr [10] + (byteptr [11] << 8));
160 } 187 }
161 188
162 return TRUE; 189 return TRUE;
163} 190}
164 191
192// Allocates the correct space in the metadata structure and writes the
193// current median values to it. Values are converted from 32-bit unsigned
194// to our internal 16-bit mylog2 values, and read_entropy_vars () is called
195// to read the values back because we must compensate for the loss through
196// the log function.
197
198void write_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd)
199{
200 uchar *byteptr;
201 int temp;
202
203 byteptr = wpmd->data = wpmd->temp_data;
204 wpmd->id = ID_ENTROPY_VARS;
205
206 *byteptr++ = temp = mylog2 (wps->w.c [0].median [0]);
207 *byteptr++ = temp >> 8;
208 *byteptr++ = temp = mylog2 (wps->w.c [0].median [1]);
209 *byteptr++ = temp >> 8;
210 *byteptr++ = temp = mylog2 (wps->w.c [0].median [2]);
211 *byteptr++ = temp >> 8;
212
213 if (!(wps->wphdr.flags & MONO_FLAG)) {
214 *byteptr++ = temp = mylog2 (wps->w.c [1].median [0]);
215 *byteptr++ = temp >> 8;
216 *byteptr++ = temp = mylog2 (wps->w.c [1].median [1]);
217 *byteptr++ = temp >> 8;
218 *byteptr++ = temp = mylog2 (wps->w.c [1].median [2]);
219 *byteptr++ = temp >> 8;
220 }
221
222 wpmd->byte_length = byteptr - (uchar *) wpmd->data;
223 read_entropy_vars (wps, wpmd);
224}
225
165// Read the hybrid related values from the specifed metadata structure, convert 226// Read the hybrid related values from the specifed metadata structure, convert
166// them back to their internal formats and store them. The extended profile 227// them back to their internal formats and store them. The extended profile
167// stuff is not implemented yet, so return an error if we get more data than 228// stuff is not implemented yet, so return an error if we get more data than
@@ -173,37 +234,37 @@ int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd)
173 uchar *endptr = byteptr + wpmd->byte_length; 234 uchar *endptr = byteptr + wpmd->byte_length;
174 235
175 if (wps->wphdr.flags & HYBRID_BITRATE) { 236 if (wps->wphdr.flags & HYBRID_BITRATE) {
176 wps->w.c [0].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8)); 237 wps->w.c [0].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8));
177 byteptr += 2; 238 byteptr += 2;
178 239
179 if (!(wps->wphdr.flags & MONO_FLAG)) { 240 if (!(wps->wphdr.flags & MONO_FLAG)) {
180 wps->w.c [1].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8)); 241 wps->w.c [1].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8));
181 byteptr += 2; 242 byteptr += 2;
182 } 243 }
183 } 244 }
184 245
185 wps->w.bitrate_acc [0] = (long)(byteptr [0] + (byteptr [1] << 8)) << 16; 246 wps->w.bitrate_acc [0] = (long)(byteptr [0] + (byteptr [1] << 8)) << 16;
186 byteptr += 2; 247 byteptr += 2;
187 248
188 if (!(wps->wphdr.flags & MONO_FLAG)) { 249 if (!(wps->wphdr.flags & MONO_FLAG)) {
189 wps->w.bitrate_acc [1] = (long)(byteptr [0] + (byteptr [1] << 8)) << 16; 250 wps->w.bitrate_acc [1] = (long)(byteptr [0] + (byteptr [1] << 8)) << 16;
190 byteptr += 2; 251 byteptr += 2;
191 } 252 }
192 253
193 if (byteptr < endptr) { 254 if (byteptr < endptr) {
194 wps->w.bitrate_delta [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8))); 255 wps->w.bitrate_delta [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
195 byteptr += 2; 256 byteptr += 2;
196 257
197 if (!(wps->wphdr.flags & MONO_FLAG)) { 258 if (!(wps->wphdr.flags & MONO_FLAG)) {
198 wps->w.bitrate_delta [1] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8))); 259 wps->w.bitrate_delta [1] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
199 byteptr += 2; 260 byteptr += 2;
200 } 261 }
201 262
202 if (byteptr < endptr) 263 if (byteptr < endptr)
203 return FALSE; 264 return FALSE;
204 } 265 }
205 else 266 else
206 wps->w.bitrate_delta [0] = wps->w.bitrate_delta [1] = 0; 267 wps->w.bitrate_delta [0] = wps->w.bitrate_delta [1] = 0;
207 268
208 return TRUE; 269 return TRUE;
209} 270}
@@ -214,60 +275,60 @@ int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd)
214// currently implemented) this is calculated from the slow_level values and the 275// currently implemented) this is calculated from the slow_level values and the
215// bitrate accumulators. Note that the bitrate accumulators can be changing. 276// bitrate accumulators. Note that the bitrate accumulators can be changing.
216 277
217static void update_error_limit (WavpackStream *wps) 278void update_error_limit (struct words_data *w, ulong flags)
218{ 279{
219 int bitrate_0 = (wps->w.bitrate_acc [0] += wps->w.bitrate_delta [0]) >> 16; 280 int bitrate_0 = (w->bitrate_acc [0] += w->bitrate_delta [0]) >> 16;
220 281
221 if (wps->wphdr.flags & MONO_FLAG) { 282 if (flags & MONO_FLAG) {
222 if (wps->wphdr.flags & HYBRID_BITRATE) { 283 if (flags & HYBRID_BITRATE) {
223 int slow_log_0 = (wps->w.c [0].slow_level + SLO) >> SLS; 284 int slow_log_0 = (w->c [0].slow_level + SLO) >> SLS;
224 285
225 if (slow_log_0 - bitrate_0 > -0x100) 286 if (slow_log_0 - bitrate_0 > -0x100)
226 wps->w.c [0].error_limit = exp2s (slow_log_0 - bitrate_0 + 0x100); 287 w->c [0].error_limit = exp2s (slow_log_0 - bitrate_0 + 0x100);
227 else 288 else
228 wps->w.c [0].error_limit = 0; 289 w->c [0].error_limit = 0;
229 } 290 }
230 else 291 else
231 wps->w.c [0].error_limit = exp2s (bitrate_0); 292 w->c [0].error_limit = exp2s (bitrate_0);
232 } 293 }
233 else { 294 else {
234 int bitrate_1 = (wps->w.bitrate_acc [1] += wps->w.bitrate_delta [1]) >> 16; 295 int bitrate_1 = (w->bitrate_acc [1] += w->bitrate_delta [1]) >> 16;
235 296
236 if (wps->wphdr.flags & HYBRID_BITRATE) { 297 if (flags & HYBRID_BITRATE) {
237 int slow_log_0 = (wps->w.c [0].slow_level + SLO) >> SLS; 298 int slow_log_0 = (w->c [0].slow_level + SLO) >> SLS;
238 int slow_log_1 = (wps->w.c [1].slow_level + SLO) >> SLS; 299 int slow_log_1 = (w->c [1].slow_level + SLO) >> SLS;
239 300
240 if (wps->wphdr.flags & HYBRID_BALANCE) { 301 if (flags & HYBRID_BALANCE) {
241 int balance = (slow_log_1 - slow_log_0 + bitrate_1 + 1) >> 1; 302 int balance = (slow_log_1 - slow_log_0 + bitrate_1 + 1) >> 1;
242 303
243 if (balance > bitrate_0) { 304 if (balance > bitrate_0) {
244 bitrate_1 = bitrate_0 * 2; 305 bitrate_1 = bitrate_0 * 2;
245 bitrate_0 = 0; 306 bitrate_0 = 0;
246 } 307 }
247 else if (-balance > bitrate_0) { 308 else if (-balance > bitrate_0) {
248 bitrate_0 = bitrate_0 * 2; 309 bitrate_0 = bitrate_0 * 2;
249 bitrate_1 = 0; 310 bitrate_1 = 0;
250 } 311 }
251 else { 312 else {
252 bitrate_1 = bitrate_0 + balance; 313 bitrate_1 = bitrate_0 + balance;
253 bitrate_0 = bitrate_0 - balance; 314 bitrate_0 = bitrate_0 - balance;
254 } 315 }
255 } 316 }
256 317
257 if (slow_log_0 - bitrate_0 > -0x100) 318 if (slow_log_0 - bitrate_0 > -0x100)
258 wps->w.c [0].error_limit = exp2s (slow_log_0 - bitrate_0 + 0x100); 319 w->c [0].error_limit = exp2s (slow_log_0 - bitrate_0 + 0x100);
259 else 320 else
260 wps->w.c [0].error_limit = 0; 321 w->c [0].error_limit = 0;
261 322
262 if (slow_log_1 - bitrate_1 > -0x100) 323 if (slow_log_1 - bitrate_1 > -0x100)
263 wps->w.c [1].error_limit = exp2s (slow_log_1 - bitrate_1 + 0x100); 324 w->c [1].error_limit = exp2s (slow_log_1 - bitrate_1 + 0x100);
264 else 325 else
265 wps->w.c [1].error_limit = 0; 326 w->c [1].error_limit = 0;
266 } 327 }
267 else { 328 else {
268 wps->w.c [0].error_limit = exp2s (bitrate_0); 329 w->c [0].error_limit = exp2s (bitrate_0);
269 wps->w.c [1].error_limit = exp2s (bitrate_1); 330 w->c [1].error_limit = exp2s (bitrate_1);
270 } 331 }
271 } 332 }
272} 333}
273 334
@@ -281,168 +342,171 @@ static ulong read_code (Bitstream *bs, ulong maxcode);
281// of WORD_EOF indicates that the end of the bitstream was reached (all 1s) or 342// of WORD_EOF indicates that the end of the bitstream was reached (all 1s) or
282// some other error occurred. 343// some other error occurred.
283 344
284long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer) 345long get_words (long *buffer, int nsamples, ulong flags,
346 struct words_data *w, Bitstream *bs)
285{ 347{
286 ulong ones_count, low, mid, high; 348 register struct entropy_data *c = w->c;
287 register struct entropy_data *c; 349 int csamples;
288 long *bptr = buffer; 350
289 351 if (!(flags & MONO_FLAG))
290 nsamples *= nchans; 352 nsamples *= 2;
291 353
292 while (nsamples--) { 354 for (csamples = 0; csamples < nsamples; ++csamples) {
293 355 ulong ones_count, low, mid, high;
294 c = wps->w.c + ((nchans == 1) ? 0 : (~nsamples & 1)); 356
295 357 if (!(flags & MONO_FLAG))
296 if (!(wps->w.c [0].median [0] & ~1) && !wps->w.holding_zero && !wps->w.holding_one && !(wps->w.c [1].median [0] & ~1)) { 358 c = w->c + (csamples & 1);
297 ulong mask; 359
298 int cbits; 360 if (!(w->c [0].median [0] & ~1) && !w->holding_zero && !w->holding_one && !(w->c [1].median [0] & ~1)) {
299 361 ulong mask;
300 if (wps->w.zeros_acc) { 362 int cbits;
301 if (--wps->w.zeros_acc) { 363
302 c->slow_level -= (c->slow_level + SLO) >> SLS; 364 if (w->zeros_acc) {
303 *bptr++ = 0; 365 if (--w->zeros_acc) {
304 continue; 366 c->slow_level -= (c->slow_level + SLO) >> SLS;
305 } 367 *buffer++ = 0;
306 } 368 continue;
307 else { 369 }
308 for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); 370 }
309 371 else {
310 if (cbits == 33) 372 for (cbits = 0; cbits < 33 && getbit (bs); ++cbits);
311 break; 373
312 374 if (cbits == 33)
313 if (cbits < 2) 375 break;
314 wps->w.zeros_acc = cbits; 376
315 else { 377 if (cbits < 2)
316 for (mask = 1, wps->w.zeros_acc = 0; --cbits; mask <<= 1) 378 w->zeros_acc = cbits;
317 if (getbit (&wps->wvbits)) 379 else {
318 wps->w.zeros_acc |= mask; 380 for (mask = 1, w->zeros_acc = 0; --cbits; mask <<= 1)
319 381 if (getbit (bs))
320 wps->w.zeros_acc |= mask; 382 w->zeros_acc |= mask;
321 } 383
322 384 w->zeros_acc |= mask;
323 if (wps->w.zeros_acc) { 385 }
324 c->slow_level -= (c->slow_level + SLO) >> SLS; 386
325 CLEAR (wps->w.c [0].median); 387 if (w->zeros_acc) {
326 CLEAR (wps->w.c [1].median); 388 c->slow_level -= (c->slow_level + SLO) >> SLS;
327 *bptr++ = 0; 389 CLEAR (w->c [0].median);
328 continue; 390 CLEAR (w->c [1].median);
329 } 391 *buffer++ = 0;
330 } 392 continue;
331 } 393 }
332 394 }
333 if (wps->w.holding_zero) 395 }
334 ones_count = wps->w.holding_zero = 0; 396
335 else { 397 if (w->holding_zero)
336 int next8; 398 ones_count = w->holding_zero = 0;
337 399 else {
338 if (wps->wvbits.bc < 8) { 400 int next8;
339 if (++(wps->wvbits.ptr) == wps->wvbits.end) 401
340 wps->wvbits.wrap (&wps->wvbits); 402 if (bs->bc < 8) {
341 403 if (++(bs->ptr) == bs->end)
342 next8 = (wps->wvbits.sr |= *(wps->wvbits.ptr) << wps->wvbits.bc) & 0xff; 404 bs->wrap (bs);
343 wps->wvbits.bc += 8; 405
344 } 406 next8 = (bs->sr |= *(bs->ptr) << bs->bc) & 0xff;
345 else 407 bs->bc += 8;
346 next8 = wps->wvbits.sr & 0xff; 408 }
347 409 else
348 if (next8 == 0xff) { 410 next8 = bs->sr & 0xff;
349 wps->wvbits.bc -= 8; 411
350 wps->wvbits.sr >>= 8; 412 if (next8 == 0xff) {
351 413 bs->bc -= 8;
352 for (ones_count = 8; ones_count < (LIMIT_ONES + 1) && getbit (&wps->wvbits); ++ones_count); 414 bs->sr >>= 8;
353 415
354 if (ones_count == (LIMIT_ONES + 1)) 416 for (ones_count = 8; ones_count < (LIMIT_ONES + 1) && getbit (bs); ++ones_count);
355 break; 417
356 418 if (ones_count == (LIMIT_ONES + 1))
357 if (ones_count == LIMIT_ONES) { 419 break;
358 ulong mask; 420
359 int cbits; 421 if (ones_count == LIMIT_ONES) {
360 422 ulong mask;
361 for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); 423 int cbits;
362 424
363 if (cbits == 33) 425 for (cbits = 0; cbits < 33 && getbit (bs); ++cbits);
364 break; 426
365 427 if (cbits == 33)
366 if (cbits < 2) 428 break;
367 ones_count = cbits; 429
368 else { 430 if (cbits < 2)
369 for (mask = 1, ones_count = 0; --cbits; mask <<= 1) 431 ones_count = cbits;
370 if (getbit (&wps->wvbits)) 432 else {
371 ones_count |= mask; 433 for (mask = 1, ones_count = 0; --cbits; mask <<= 1)
372 434 if (getbit (bs))
373 ones_count |= mask; 435 ones_count |= mask;
374 } 436
375 437 ones_count |= mask;
376 ones_count += LIMIT_ONES; 438 }
377 } 439
378 } 440 ones_count += LIMIT_ONES;
379 else { 441 }
380 wps->wvbits.bc -= (ones_count = ones_count_table [next8]) + 1; 442 }
381 wps->wvbits.sr >>= ones_count + 1; 443 else {
382 } 444 bs->bc -= (ones_count = ones_count_table [next8]) + 1;
383 445 bs->sr >>= ones_count + 1;
384 if (wps->w.holding_one) { 446 }
385 wps->w.holding_one = ones_count & 1; 447
386 ones_count = (ones_count >> 1) + 1; 448 if (w->holding_one) {
387 } 449 w->holding_one = ones_count & 1;
388 else { 450 ones_count = (ones_count >> 1) + 1;
389 wps->w.holding_one = ones_count & 1; 451 }
390 ones_count >>= 1; 452 else {
391 } 453 w->holding_one = ones_count & 1;
392 454 ones_count >>= 1;
393 wps->w.holding_zero = ~wps->w.holding_one & 1; 455 }
394 } 456
395 457 w->holding_zero = ~w->holding_one & 1;
396 if ((wps->wphdr.flags & HYBRID_FLAG) && (nchans == 1 || (nsamples & 1))) 458 }
397 update_error_limit (wps); 459
398 460 if ((flags & HYBRID_FLAG) && ((flags & MONO_FLAG) || !(csamples & 1)))
399 if (ones_count == 0) { 461 update_error_limit (w, flags);
400 low = 0; 462
401 high = GET_MED (0) - 1; 463 if (ones_count == 0) {
402 DEC_MED0 (); 464 low = 0;
403 } 465 high = GET_MED (0) - 1;
404 else { 466 DEC_MED0 ();
405 low = GET_MED (0); 467 }
406 INC_MED0 (); 468 else {
407 469 low = GET_MED (0);
408 if (ones_count == 1) { 470 INC_MED0 ();
409 high = low + GET_MED (1) - 1; 471
410 DEC_MED1 (); 472 if (ones_count == 1) {
411 } 473 high = low + GET_MED (1) - 1;
412 else { 474 DEC_MED1 ();
413 low += GET_MED (1); 475 }
414 INC_MED1 (); 476 else {
415 477 low += GET_MED (1);
416 if (ones_count == 2) { 478 INC_MED1 ();
417 high = low + GET_MED (2) - 1; 479
418 DEC_MED2 (); 480 if (ones_count == 2) {
419 } 481 high = low + GET_MED (2) - 1;
420 else { 482 DEC_MED2 ();
421 low += (ones_count - 2) * GET_MED (2); 483 }
422 high = low + GET_MED (2) - 1; 484 else {
423 INC_MED2 (); 485 low += (ones_count - 2) * GET_MED (2);
424 } 486 high = low + GET_MED (2) - 1;
425 } 487 INC_MED2 ();
426 } 488 }
427 489 }
428 mid = (high + low + 1) >> 1; 490 }
429 491
430 if (!c->error_limit) 492 mid = (high + low + 1) >> 1;
431 mid = read_code (&wps->wvbits, high - low) + low; 493
432 else while (high - low > c->error_limit) { 494 if (!c->error_limit)
433 if (getbit (&wps->wvbits)) 495 mid = read_code (bs, high - low) + low;
434 mid = (high + (low = mid) + 1) >> 1; 496 else while (high - low > c->error_limit) {
435 else 497 if (getbit (bs))
436 mid = ((high = mid - 1) + low + 1) >> 1; 498 mid = (high + (low = mid) + 1) >> 1;
437 } 499 else
438 500 mid = ((high = mid - 1) + low + 1) >> 1;
439 *bptr++ = getbit (&wps->wvbits) ? ~mid : mid; 501 }
440 502
441 if (wps->wphdr.flags & HYBRID_BITRATE) 503 *buffer++ = getbit (bs) ? ~mid : mid;
442 c->slow_level = c->slow_level - ((c->slow_level + SLO) >> SLS) + mylog2 (mid); 504
505 if (flags & HYBRID_BITRATE)
506 c->slow_level = c->slow_level - ((c->slow_level + SLO) >> SLS) + mylog2 (mid);
443 } 507 }
444 508
445 return nchans == 1 ? (bptr - buffer) : ((bptr - buffer) / 2); 509 return (flags & MONO_FLAG) ? csamples : (csamples / 2);
446} 510}
447 511
448// Read a single unsigned value from the specified bitstream with a value 512// Read a single unsigned value from the specified bitstream with a value
@@ -457,21 +521,195 @@ static ulong read_code (Bitstream *bs, ulong maxcode)
457 ulong extras = (1L << bitcount) - maxcode - 1, code; 521 ulong extras = (1L << bitcount) - maxcode - 1, code;
458 522
459 if (!bitcount) 523 if (!bitcount)
460 return 0; 524 return 0;
461 525
462 getbits (&code, bitcount - 1, bs); 526 getbits (&code, bitcount - 1, bs);
463 code &= (1L << (bitcount - 1)) - 1; 527 code &= (1L << (bitcount - 1)) - 1;
464 528
465 if (code >= extras) { 529 if (code >= extras) {
466 code = (code << 1) - extras; 530 code = (code << 1) - extras;
467 531
468 if (getbit (bs)) 532 if (getbit (bs))
469 ++code; 533 ++code;
470 } 534 }
471 535
472 return code; 536 return code;
473} 537}
474 538
539// This function is an optimized version of send_word() that only handles
540// lossless (error_limit == 0). It does not return a value because it always
541// encodes the exact value passed.
542
543void send_word_lossless (WavpackStream *wps, long value, int chan)
544{
545 register struct words_data *w = &wps->w;
546 register struct entropy_data *c = w->c + chan;
547 int sign = (value < 0) ? 1 : 0;
548 ulong ones_count, low, high;
549
550 if (!(wps->w.c [0].median [0] & ~1) && !wps->w.holding_zero && !(wps->w.c [1].median [0] & ~1)) {
551 if (wps->w.zeros_acc) {
552 if (value)
553 flush_word (wps);
554 else {
555 wps->w.zeros_acc++;
556 return;
557 }
558 }
559 else if (value) {
560 putbit_0 (&wps->wvbits);
561 }
562 else {
563 CLEAR (wps->w.c [0].median);
564 CLEAR (wps->w.c [1].median);
565 wps->w.zeros_acc = 1;
566 return;
567 }
568 }
569
570 if (sign)
571 value = ~value;
572
573 if ((unsigned long) value < GET_MED (0)) {
574 ones_count = low = 0;
575 high = GET_MED (0) - 1;
576 DEC_MED0 ();
577 }
578 else {
579 low = GET_MED (0);
580 INC_MED0 ();
581
582 if (value - low < GET_MED (1)) {
583 ones_count = 1;
584 high = low + GET_MED (1) - 1;
585 DEC_MED1 ();
586 }
587 else {
588 low += GET_MED (1);
589 INC_MED1 ();
590
591 if (value - low < GET_MED (2)) {
592 ones_count = 2;
593 high = low + GET_MED (2) - 1;
594 DEC_MED2 ();
595 }
596 else {
597 ones_count = 2 + (value - low) / GET_MED (2);
598 low += (ones_count - 2) * GET_MED (2);
599 high = low + GET_MED (2) - 1;
600 INC_MED2 ();
601 }
602 }
603 }
604
605 if (wps->w.holding_zero) {
606 if (ones_count)
607 wps->w.holding_one++;
608
609 flush_word (wps);
610
611 if (ones_count) {
612 wps->w.holding_zero = 1;
613 ones_count--;
614 }
615 else
616 wps->w.holding_zero = 0;
617 }
618 else
619 wps->w.holding_zero = 1;
620
621 wps->w.holding_one = ones_count * 2;
622
623 if (high != low) {
624 ulong maxcode = high - low, code = value - low;
625 int bitcount = count_bits (maxcode);
626 ulong extras = bitset [bitcount] - maxcode - 1;
627
628 if (code < extras) {
629 wps->w.pend_data |= code << wps->w.pend_count;
630 wps->w.pend_count += bitcount - 1;
631 }
632 else {
633 wps->w.pend_data |= ((code + extras) >> 1) << wps->w.pend_count;
634 wps->w.pend_count += bitcount - 1;
635 wps->w.pend_data |= ((code + extras) & 1) << wps->w.pend_count++;
636 }
637 }
638
639 wps->w.pend_data |= ((long) sign << wps->w.pend_count++);
640
641 if (!wps->w.holding_zero)
642 flush_word (wps);
643}
644
645// Used by send_word() and send_word_lossless() to actually send most the
646// accumulated data onto the bitstream. This is also called directly from
647// clients when all words have been sent.
648
649void flush_word (WavpackStream *wps)
650{
651 if (wps->w.zeros_acc) {
652 int cbits = count_bits (wps->w.zeros_acc);
653
654 while (cbits--) {
655 putbit_1 (&wps->wvbits);
656 }
657
658 putbit_0 (&wps->wvbits);
659
660 while (wps->w.zeros_acc > 1) {
661 putbit (wps->w.zeros_acc & 1, &wps->wvbits);
662 wps->w.zeros_acc >>= 1;
663 }
664
665 wps->w.zeros_acc = 0;
666 }
667
668 if (wps->w.holding_one) {
669 if (wps->w.holding_one >= LIMIT_ONES) {
670 int cbits;
671
672 putbits ((1L << LIMIT_ONES) - 1, LIMIT_ONES + 1, &wps->wvbits);
673 wps->w.holding_one -= LIMIT_ONES;
674 cbits = count_bits (wps->w.holding_one);
675
676 while (cbits--) {
677 putbit_1 (&wps->wvbits);
678 }
679
680 putbit_0 (&wps->wvbits);
681
682 while (wps->w.holding_one > 1) {
683 putbit (wps->w.holding_one & 1, &wps->wvbits);
684 wps->w.holding_one >>= 1;
685 }
686
687 wps->w.holding_zero = 0;
688 }
689 else
690 putbits (bitmask [wps->w.holding_one], wps->w.holding_one, &wps->wvbits);
691
692 wps->w.holding_one = 0;
693 }
694
695 if (wps->w.holding_zero) {
696 putbit_0 (&wps->wvbits);
697 wps->w.holding_zero = 0;
698 }
699
700 if (wps->w.pend_count) {
701
702 while (wps->w.pend_count > 24) {
703 putbit (wps->w.pend_data & 1, &wps->wvbits);
704 wps->w.pend_data >>= 1;
705 wps->w.pend_count--;
706 }
707
708 putbits (wps->w.pend_data, wps->w.pend_count, &wps->wvbits);
709 wps->w.pend_data = wps->w.pend_count = 0;
710 }
711}
712
475// The concept of a base 2 logarithm is used in many parts of WavPack. It is 713// The concept of a base 2 logarithm is used in many parts of WavPack. It is
476// a way of sufficiently accurately representing 32-bit signed and unsigned 714// a way of sufficiently accurately representing 32-bit signed and unsigned
477// values storing only 16 bits (actually fewer). It is also used in the hybrid 715// values storing only 16 bits (actually fewer). It is also used in the hybrid
@@ -492,21 +730,30 @@ static int mylog2 (unsigned long avalue)
492 int dbits; 730 int dbits;
493 731
494 if ((avalue += avalue >> 9) < (1 << 8)) { 732 if ((avalue += avalue >> 9) < (1 << 8)) {
495 dbits = nbits_table [avalue]; 733 dbits = nbits_table [avalue];
496 return (dbits << 8) + log2_table [(avalue << (9 - dbits)) & 0xff]; 734 return (dbits << 8) + log2_table [(avalue << (9 - dbits)) & 0xff];
497 } 735 }
498 else { 736 else {
499 if (avalue < (1L << 16)) 737 if (avalue < (1L << 16))
500 dbits = nbits_table [avalue >> 8] + 8; 738 dbits = nbits_table [avalue >> 8] + 8;
501 else if (avalue < (1L << 24)) 739 else if (avalue < (1L << 24))
502 dbits = nbits_table [avalue >> 16] + 16; 740 dbits = nbits_table [avalue >> 16] + 16;
503 else 741 else
504 dbits = nbits_table [avalue >> 24] + 24; 742 dbits = nbits_table [avalue >> 24] + 24;
505 743
506 return (dbits << 8) + log2_table [(avalue >> (dbits - 9)) & 0xff]; 744 return (dbits << 8) + log2_table [(avalue >> (dbits - 9)) & 0xff];
507 } 745 }
508} 746}
509 747
748// This function returns the log2 for the specified 32-bit signed value.
749// All input values are valid and the return values are in the range of
750// +/- 8192.
751
752int log2s (long value)
753{
754 return (value < 0) ? -mylog2 (-value) : mylog2 (value);
755}
756
510// This function returns the original integer represented by the supplied 757// This function returns the original integer represented by the supplied
511// logarithm (at least within the provided accuracy). The log is signed, 758// logarithm (at least within the provided accuracy). The log is signed,
512// but since a full 32-bit value is returned this can be used for unsigned 759// but since a full 32-bit value is returned this can be used for unsigned
@@ -517,26 +764,39 @@ long exp2s (int log)
517 ulong value; 764 ulong value;
518 765
519 if (log < 0) 766 if (log < 0)
520 return -exp2s (-log); 767 return -exp2s (-log);
521 768
522 value = exp2_table [log & 0xff] | 0x100; 769 value = exp2_table [log & 0xff] | 0x100;
523 770
524 if ((log >>= 8) <= 9) 771 if ((log >>= 8) <= 9)
525 return value >> (9 - log); 772 return value >> (9 - log);
526 else 773 else
527 return value << (log - 9); 774 return value << (log - 9);
528} 775}
529 776
530// These two functions convert internal weights (which are normally +/-1024) 777// These two functions convert internal weights (which are normally +/-1024)
531// to and from an 8-bit signed character version for storage in metadata. The 778// to and from an 8-bit signed character version for storage in metadata. The
532// weights are clipped here in the case that they are outside that range. 779// weights are clipped here in the case that they are outside that range.
533 780
781char store_weight (int weight)
782{
783 if (weight > 1024)
784 weight = 1024;
785 else if (weight < -1024)
786 weight = -1024;
787
788 if (weight > 0)
789 weight -= (weight + 64) >> 7;
790
791 return (weight + 4) >> 3;
792}
793
534int restore_weight (char weight) 794int restore_weight (char weight)
535{ 795{
536 int result; 796 int result;
537 797
538 if ((result = (int) weight << 3) > 0) 798 if ((result = (int) weight << 3) > 0)
539 result += (result + 64) >> 7; 799 result += (result + 64) >> 7;
540 800
541 return result; 801 return result;
542} 802}
diff --git a/apps/codecs/libwavpack/wputils.c b/apps/codecs/libwavpack/wputils.c
index 8d58b3b4d7..7f2ab14c44 100644
--- a/apps/codecs/libwavpack/wputils.c
+++ b/apps/codecs/libwavpack/wputils.c
@@ -1,8 +1,8 @@
1//////////////////////////////////////////////////////////////////////////// 1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** // 2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor // 3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 Conifer Software. // 4// Copyright (c) 1998 - 2004 Conifer Software. //
5// All Rights Reserved. // 5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) // 6// Distributed under the BSD Software License (see license.txt) //
7//////////////////////////////////////////////////////////////////////////// 7////////////////////////////////////////////////////////////////////////////
8 8
@@ -19,7 +19,7 @@
19 19
20#include <string.h> 20#include <string.h>
21 21
22static void strcpy_loc (char *dst, char *src) { while (*src) *dst++ = *src++; *dst = 0; } 22static void strcpy_loc (char *dst, char *src) { while ((*dst++ = *src++) != 0); }
23 23
24///////////////////////////// local table storage //////////////////////////// 24///////////////////////////// local table storage ////////////////////////////
25 25
@@ -29,7 +29,7 @@ const ulong sample_rates [] = { 6000, 8000, 9600, 11025, 12000, 16000, 22050,
29///////////////////////////// executable code //////////////////////////////// 29///////////////////////////// executable code ////////////////////////////////
30 30
31static ulong read_next_header (read_stream infile, WavpackHeader *wphdr); 31static ulong read_next_header (read_stream infile, WavpackHeader *wphdr);
32 32
33// This function reads data from the specified stream in search of a valid 33// This function reads data from the specified stream in search of a valid
34// WavPack 4.0 audio block. If this fails in 1 megabyte (or an invalid or 34// WavPack 4.0 audio block. If this fails in 1 megabyte (or an invalid or
35// unsupported WavPack block is encountered) then an appropriate message is 35// unsupported WavPack block is encountered) then an appropriate message is
@@ -62,27 +62,27 @@ WavpackContext *WavpackOpenFileInput (read_stream infile, char *error)
62 62
63 while (!wps->wphdr.block_samples) { 63 while (!wps->wphdr.block_samples) {
64 64
65 bcount = read_next_header (wpc.infile, &wps->wphdr); 65 bcount = read_next_header (wpc.infile, &wps->wphdr);
66 66
67 if (bcount == (ulong) -1) { 67 if (bcount == (ulong) -1) {
68 strcpy_loc (error, "invalid WavPack file!"); 68 strcpy_loc (error, "invalid WavPack file!");
69 return NULL; 69 return NULL;
70 } 70 }
71 71
72 if ((wps->wphdr.flags & UNKNOWN_FLAGS) || wps->wphdr.version < 0x402 || wps->wphdr.version > 0x40f) { 72 if ((wps->wphdr.flags & UNKNOWN_FLAGS) || wps->wphdr.version < 0x402 || wps->wphdr.version > 0x40f) {
73 strcpy_loc (error, "invalid WavPack file!"); 73 strcpy_loc (error, "invalid WavPack file!");
74 return NULL; 74 return NULL;
75 } 75 }
76 76
77 if (wps->wphdr.block_samples && wps->wphdr.total_samples != (ulong) -1) 77 if (wps->wphdr.block_samples && wps->wphdr.total_samples != (ulong) -1)
78 wpc.total_samples = wps->wphdr.total_samples; 78 wpc.total_samples = wps->wphdr.total_samples;
79 79
80 if (!unpack_init (&wpc)) { 80 if (!unpack_init (&wpc)) {
81 strcpy_loc (error, wpc.error_message [0] ? wpc.error_message : 81 strcpy_loc (error, wpc.error_message [0] ? wpc.error_message :
82 "invalid WavPack file!"); 82 "invalid WavPack file!");
83 83
84 return NULL; 84 return NULL;
85 } 85 }
86 } 86 }
87 87
88 wpc.config.flags &= ~0xff; 88 wpc.config.flags &= ~0xff;
@@ -91,22 +91,22 @@ WavpackContext *WavpackOpenFileInput (read_stream infile, char *error)
91 wpc.config.float_norm_exp = wps->float_norm_exp; 91 wpc.config.float_norm_exp = wps->float_norm_exp;
92 92
93 wpc.config.bits_per_sample = (wpc.config.bytes_per_sample * 8) - 93 wpc.config.bits_per_sample = (wpc.config.bytes_per_sample * 8) -
94 ((wps->wphdr.flags & SHIFT_MASK) >> SHIFT_LSB); 94 ((wps->wphdr.flags & SHIFT_MASK) >> SHIFT_LSB);
95 95
96 if (!wpc.config.sample_rate) { 96 if (!wpc.config.sample_rate) {
97 if (!wps || !wps->wphdr.block_samples || (wps->wphdr.flags & SRATE_MASK) == SRATE_MASK) 97 if (!wps || !wps->wphdr.block_samples || (wps->wphdr.flags & SRATE_MASK) == SRATE_MASK)
98 wpc.config.sample_rate = 44100; 98 wpc.config.sample_rate = 44100;
99 else 99 else
100 wpc.config.sample_rate = sample_rates [(wps->wphdr.flags & SRATE_MASK) >> SRATE_LSB]; 100 wpc.config.sample_rate = sample_rates [(wps->wphdr.flags & SRATE_MASK) >> SRATE_LSB];
101 } 101 }
102 102
103 if (!wpc.config.num_channels) { 103 if (!wpc.config.num_channels) {
104 wpc.config.num_channels = (wps->wphdr.flags & MONO_FLAG) ? 1 : 2; 104 wpc.config.num_channels = (wps->wphdr.flags & MONO_FLAG) ? 1 : 2;
105 wpc.config.channel_mask = 0x5 - wpc.config.num_channels; 105 wpc.config.channel_mask = 0x5 - wpc.config.num_channels;
106 } 106 }
107 107
108 if (!(wps->wphdr.flags & FINAL_BLOCK)) 108 if (!(wps->wphdr.flags & FINAL_BLOCK))
109 wpc.reduced_channels = (wps->wphdr.flags & MONO_FLAG) ? 1 : 2; 109 wpc.reduced_channels = (wps->wphdr.flags & MONO_FLAG) ? 1 : 2;
110 110
111 return &wpc; 111 return &wpc;
112} 112}
@@ -125,22 +125,22 @@ int WavpackGetMode (WavpackContext *wpc)
125 int mode = 0; 125 int mode = 0;
126 126
127 if (wpc) { 127 if (wpc) {
128 if (wpc->config.flags & CONFIG_HYBRID_FLAG) 128 if (wpc->config.flags & CONFIG_HYBRID_FLAG)
129 mode |= MODE_HYBRID; 129 mode |= MODE_HYBRID;
130 else if (!(wpc->config.flags & CONFIG_LOSSY_MODE)) 130 else if (!(wpc->config.flags & CONFIG_LOSSY_MODE))
131 mode |= MODE_LOSSLESS; 131 mode |= MODE_LOSSLESS;
132 132
133 if (wpc->lossy_blocks) 133 if (wpc->lossy_blocks)
134 mode &= ~MODE_LOSSLESS; 134 mode &= ~MODE_LOSSLESS;
135 135
136 if (wpc->config.flags & CONFIG_FLOAT_DATA) 136 if (wpc->config.flags & CONFIG_FLOAT_DATA)
137 mode |= MODE_FLOAT; 137 mode |= MODE_FLOAT;
138 138
139 if (wpc->config.flags & CONFIG_HIGH_FLAG) 139 if (wpc->config.flags & CONFIG_HIGH_FLAG)
140 mode |= MODE_HIGH; 140 mode |= MODE_HIGH;
141 141
142 if (wpc->config.flags & CONFIG_FAST_FLAG) 142 if (wpc->config.flags & CONFIG_FAST_FLAG)
143 mode |= MODE_FAST; 143 mode |= MODE_FAST;
144 } 144 }
145 145
146 return mode; 146 return mode;
@@ -163,70 +163,70 @@ ulong WavpackUnpackSamples (WavpackContext *wpc, long *buffer, ulong samples)
163 int num_channels = wpc->config.num_channels; 163 int num_channels = wpc->config.num_channels;
164 164
165 while (samples) { 165 while (samples) {
166 if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) || 166 if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) ||
167 wps->sample_index >= wps->wphdr.block_index + wps->wphdr.block_samples) { 167 wps->sample_index >= wps->wphdr.block_index + wps->wphdr.block_samples) {
168 bcount = read_next_header (wpc->infile, &wps->wphdr); 168 bcount = read_next_header (wpc->infile, &wps->wphdr);
169 169
170 if (bcount == (ulong) -1) 170 if (bcount == (ulong) -1)
171 break; 171 break;
172 172
173 if (wps->wphdr.version < 0x402 || wps->wphdr.version > 0x40f) { 173 if (wps->wphdr.version < 0x402 || wps->wphdr.version > 0x40f) {
174 strcpy_loc (wpc->error_message, "invalid WavPack file!"); 174 strcpy_loc (wpc->error_message, "invalid WavPack file!");
175 break; 175 break;
176 } 176 }
177 177
178 if (!wps->wphdr.block_samples || wps->sample_index == wps->wphdr.block_index) 178 if (!wps->wphdr.block_samples || wps->sample_index == wps->wphdr.block_index)
179 if (!unpack_init (wpc)) 179 if (!unpack_init (wpc))
180 break; 180 break;
181 } 181 }
182 182
183 if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) || 183 if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) ||
184 wps->sample_index >= wps->wphdr.block_index + wps->wphdr.block_samples) 184 wps->sample_index >= wps->wphdr.block_index + wps->wphdr.block_samples)
185 continue; 185 continue;
186 186
187 if (wps->sample_index < wps->wphdr.block_index) { 187 if (wps->sample_index < wps->wphdr.block_index) {
188 samples_to_unpack = wps->wphdr.block_index - wps->sample_index; 188 samples_to_unpack = wps->wphdr.block_index - wps->sample_index;
189 189
190 if (samples_to_unpack > samples) 190 if (samples_to_unpack > samples)
191 samples_to_unpack = samples; 191 samples_to_unpack = samples;
192 192
193 wps->sample_index += samples_to_unpack; 193 wps->sample_index += samples_to_unpack;
194 samples_unpacked += samples_to_unpack; 194 samples_unpacked += samples_to_unpack;
195 samples -= samples_to_unpack; 195 samples -= samples_to_unpack;
196 196
197 if (wpc->reduced_channels) 197 if (wpc->reduced_channels)
198 samples_to_unpack *= wpc->reduced_channels; 198 samples_to_unpack *= wpc->reduced_channels;
199 else 199 else
200 samples_to_unpack *= num_channels; 200 samples_to_unpack *= num_channels;
201 201
202 while (samples_to_unpack--) 202 while (samples_to_unpack--)
203 *buffer++ = 0; 203 *buffer++ = 0;
204 204
205 continue; 205 continue;
206 } 206 }
207 207
208 samples_to_unpack = wps->wphdr.block_index + wps->wphdr.block_samples - wps->sample_index; 208 samples_to_unpack = wps->wphdr.block_index + wps->wphdr.block_samples - wps->sample_index;
209 209
210 if (samples_to_unpack > samples) 210 if (samples_to_unpack > samples)
211 samples_to_unpack = samples; 211 samples_to_unpack = samples;
212 212
213 unpack_samples (wpc, buffer, samples_to_unpack); 213 unpack_samples (wpc, buffer, samples_to_unpack);
214 214
215 if (wpc->reduced_channels) 215 if (wpc->reduced_channels)
216 buffer += samples_to_unpack * wpc->reduced_channels; 216 buffer += samples_to_unpack * wpc->reduced_channels;
217 else 217 else
218 buffer += samples_to_unpack * num_channels; 218 buffer += samples_to_unpack * num_channels;
219 219
220 samples_unpacked += samples_to_unpack; 220 samples_unpacked += samples_to_unpack;
221 samples -= samples_to_unpack; 221 samples -= samples_to_unpack;
222 222
223 if (wps->sample_index == wps->wphdr.block_index + wps->wphdr.block_samples) { 223 if (wps->sample_index == wps->wphdr.block_index + wps->wphdr.block_samples) {
224 if (check_crc_error (wpc)) 224 if (check_crc_error (wpc))
225 wpc->crc_errors++; 225 wpc->crc_errors++;
226 } 226 }
227 227
228 if (wps->sample_index == wpc->total_samples) 228 if (wps->sample_index == wpc->total_samples)
229 break; 229 break;
230 } 230 }
231 231
232 return samples_unpacked; 232 return samples_unpacked;
@@ -244,7 +244,7 @@ ulong WavpackGetNumSamples (WavpackContext *wpc)
244ulong WavpackGetSampleIndex (WavpackContext *wpc) 244ulong WavpackGetSampleIndex (WavpackContext *wpc)
245{ 245{
246 if (wpc) 246 if (wpc)
247 return wpc->stream.sample_index; 247 return wpc->stream.sample_index;
248 248
249 return (ulong) -1; 249 return (ulong) -1;
250} 250}
@@ -310,9 +310,9 @@ int WavpackGetBytesPerSample (WavpackContext *wpc)
310int WavpackGetReducedChannels (WavpackContext *wpc) 310int WavpackGetReducedChannels (WavpackContext *wpc)
311{ 311{
312 if (wpc) 312 if (wpc)
313 return wpc->reduced_channels ? wpc->reduced_channels : wpc->config.num_channels; 313 return wpc->reduced_channels ? wpc->reduced_channels : wpc->config.num_channels;
314 else 314 else
315 return 2; 315 return 2;
316} 316}
317 317
318// Read from current file position until a valid 32-byte WavPack 4.0 header is 318// Read from current file position until a valid 32-byte WavPack 4.0 header is
@@ -328,29 +328,228 @@ static ulong read_next_header (read_stream infile, WavpackHeader *wphdr)
328 int bleft; 328 int bleft;
329 329
330 while (1) { 330 while (1) {
331 if (sp < ep) { 331 if (sp < ep) {
332 bleft = ep - sp; 332 bleft = ep - sp;
333 memcpy (buffer, sp, bleft); 333 memcpy (buffer, sp, bleft);
334 } 334 }
335 else 335 else
336 bleft = 0; 336 bleft = 0;
337 337
338 if (infile (buffer + bleft, sizeof (*wphdr) - bleft) != (long) sizeof (*wphdr) - bleft) 338 if (infile (buffer + bleft, sizeof (*wphdr) - bleft) != (long) sizeof (*wphdr) - bleft)
339 return -1; 339 return -1;
340 340
341 sp = buffer; 341 sp = buffer;
342 342
343 if (*sp++ == 'w' && *sp == 'v' && *++sp == 'p' && *++sp == 'k' && 343 if (*sp++ == 'w' && *sp == 'v' && *++sp == 'p' && *++sp == 'k' &&
344 !(*++sp & 1) && sp [2] < 16 && !sp [3] && sp [5] == 4 && sp [4] >= 2 && sp [4] <= 0xf) { 344 !(*++sp & 1) && sp [2] < 16 && !sp [3] && sp [5] == 4 && sp [4] >= 2 && sp [4] <= 0xf) {
345 memcpy (wphdr, buffer, sizeof (*wphdr)); 345 memcpy (wphdr, buffer, sizeof (*wphdr));
346 little_endian_to_native (wphdr, WavpackHeaderFormat); 346 little_endian_to_native (wphdr, WavpackHeaderFormat);
347 return bytes_skipped; 347 return bytes_skipped;
348 } 348 }
349 349
350 while (sp < ep && *sp != 'w') 350 while (sp < ep && *sp != 'w')
351 sp++; 351 sp++;
352 352
353 if ((bytes_skipped += sp - buffer) > 1024 * 1024) 353 if ((bytes_skipped += sp - buffer) > 1024 * 1024)
354 return -1; 354 return -1;
355 } 355 }
356} 356}
357
358// Open context for writing WavPack files. The returned context pointer is used
359// in all following calls to the library. A return value of NULL indicates
360// that memory could not be allocated for the context.
361
362WavpackContext *WavpackOpenFileOutput (void)
363{
364 CLEAR (wpc);
365 return &wpc;
366}
367
368// Set the output buffer limits. This must be done before calling
369// WavpackPackSamples(), but also may be done afterward to adjust
370// the usable buffer. Note that writing CANNOT wrap in the buffer; the
371// entire output block must fit in the buffer.
372
373void WavpackSetOutputBuffer (WavpackContext *wpc, uchar *begin, uchar *end)
374{
375 wpc->stream.blockbuff = begin;
376 wpc->stream.blockend = end;
377}
378
379// Set configuration for writing WavPack files. This must be done before
380// sending any actual samples, however it is okay to send wrapper or other
381// metadata before calling this. The "config" structure contains the following
382// required information:
383
384// config->bytes_per_sample see WavpackGetBytesPerSample() for info
385// config->bits_per_sample see WavpackGetBitsPerSample() for info
386// config->num_channels self evident
387// config->sample_rate self evident
388
389// In addition, the following fields and flags may be set:
390
391// config->flags:
392// --------------
393// o CONFIG_HYBRID_FLAG select hybrid mode (must set bitrate)
394// o CONFIG_JOINT_STEREO select joint stereo (must set override also)
395// o CONFIG_JOINT_OVERRIDE override default joint stereo selection
396// o CONFIG_HYBRID_SHAPE select hybrid noise shaping (set override &
397// shaping_weight != 0.0)
398// o CONFIG_SHAPE_OVERRIDE override default hybrid noise shaping
399// (set CONFIG_HYBRID_SHAPE and shaping_weight)
400// o CONFIG_FAST_FLAG "fast" compression mode
401// o CONFIG_HIGH_FLAG "high" compression mode
402// o CONFIG_BITRATE_KBPS hybrid bitrate is kbps, not bits / sample
403
404// config->bitrate hybrid bitrate in either bits/sample or kbps
405// config->shaping_weight hybrid noise shaping coefficient override
406// config->float_norm_exp select floating-point data (127 for +/-1.0)
407
408// If the number of samples to be written is known then it should be passed
409// here. If the duration is not known then pass -1. In the case that the size
410// is not known (or the writing is terminated early) then it is suggested that
411// the application retrieve the first block written and let the library update
412// the total samples indication. A function is provided to do this update and
413// it should be done to the "correction" file also. If this cannot be done
414// (because a pipe is being used, for instance) then a valid WavPack will still
415// be created, but when applications want to access that file they will have
416// to seek all the way to the end to determine the actual duration. Also, if
417// a RIFF header has been included then it should be updated as well or the
418// WavPack file will not be directly unpackable to a valid wav file (although
419// it will still be usable by itself). A return of FALSE indicates an error.
420
421int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, ulong total_samples)
422{
423 WavpackStream *wps = &wpc->stream;
424 ulong flags = (config->bytes_per_sample - 1), shift = 0;
425 int num_chans = config->num_channels;
426 int i;
427
428 if ((wpc->config.flags & CONFIG_HYBRID_FLAG) ||
429 wpc->config.float_norm_exp ||
430 num_chans < 1 || num_chans > 2)
431 return FALSE;
432
433 wpc->total_samples = total_samples;
434 wpc->config.sample_rate = config->sample_rate;
435 wpc->config.num_channels = config->num_channels;
436 wpc->config.bits_per_sample = config->bits_per_sample;
437 wpc->config.bytes_per_sample = config->bytes_per_sample;
438 wpc->config.flags = config->flags;
439
440 shift = (config->bytes_per_sample * 8) - config->bits_per_sample;
441
442 for (i = 0; i < 15; ++i)
443 if (wpc->config.sample_rate == sample_rates [i])
444 break;
445
446 flags |= i << SRATE_LSB;
447 flags |= shift << SHIFT_LSB;
448 flags |= CROSS_DECORR;
449
450 if (!(config->flags & CONFIG_JOINT_OVERRIDE) || (config->flags & CONFIG_JOINT_STEREO))
451 flags |= JOINT_STEREO;
452
453 memcpy (wps->wphdr.ckID, "wvpk", 4);
454 wps->wphdr.ckSize = sizeof (WavpackHeader) - 8;
455 wps->wphdr.total_samples = wpc->total_samples;
456 wps->wphdr.version = 0x403;
457 wps->wphdr.flags = flags;
458
459 wps->wphdr.flags |= INITIAL_BLOCK;
460 wps->wphdr.flags |= FINAL_BLOCK;
461
462 if (num_chans == 1) {
463 wps->wphdr.flags &= ~(JOINT_STEREO | CROSS_DECORR | HYBRID_BALANCE);
464 wps->wphdr.flags |= MONO_FLAG;
465 }
466
467 pack_init (wpc);
468 return TRUE;
469}
470
471// Add wrapper (currently RIFF only) to WavPack blocks. This should be called
472// before sending any audio samples for the RIFF header or after all samples
473// have been sent for any RIFF trailer. WavpackFlushSamples() should be called
474// between sending the last samples and calling this for trailer data to make
475// sure that headers and trailers don't get mixed up in very short files. If
476// the exact contents of the RIFF header are not known because, for example,
477// the file duration is uncertain or trailing chunks are possible, simply write
478// a "dummy" header of the correct length. When all data has been written it
479// will be possible to read the first block written and update the header
480// directly. An example of this can be found in the Audition filter. A
481// return of FALSE indicates an error.
482
483void WavpackAddWrapper (WavpackContext *wpc, void *data, ulong bcount)
484{
485 wpc->wrapper_data = data;
486 wpc->wrapper_bytes = bcount;
487}
488
489// Pack the specified samples. Samples must be stored in longs in the native
490// endian format of the executing processor. The number of samples specified
491// indicates composite samples (sometimes called "frames"). So, the actual
492// number of data points would be this "sample_count" times the number of
493// channels. Note that samples are accumulated here until enough exist to
494// create a complete WavPack block (or several blocks for multichannel audio).
495// If an application wants to break a block at a specific sample, then it must
496// simply call WavpackFlushSamples() to force an early termination. Completed
497// WavPack blocks are send to the function provided in the initial call to
498// WavpackOpenFileOutput(). A return of FALSE indicates an error.
499
500ulong WavpackPackSamples (WavpackContext *wpc, long *sample_buffer, ulong sample_count)
501{
502 WavpackStream *wps = &wpc->stream;
503 ulong flags = wps->wphdr.flags;
504 ulong bcount;
505 int result;
506
507 flags &= ~MAG_MASK;
508 flags += (1 << MAG_LSB) * ((flags & BYTES_STORED) * 8 + 7);
509
510 wps->wphdr.block_index = wps->sample_index;
511 wps->wphdr.block_samples = sample_count;
512 wps->wphdr.flags = flags;
513
514 result = pack_block (wpc, sample_buffer);
515
516 if (!result) {
517 strcpy_loc (wpc->error_message, "output buffer overflowed!");
518 return 0;
519 }
520
521 bcount = ((WavpackHeader *) wps->blockbuff)->ckSize + 8;
522 native_to_little_endian ((WavpackHeader *) wps->blockbuff, WavpackHeaderFormat);
523
524 return bcount;
525}
526
527// Given the pointer to the first block written (to either a .wv or .wvc file),
528// update the block with the actual number of samples written. This should
529// be done if WavpackSetConfiguration() was called with an incorrect number
530// of samples (or -1). It is the responsibility of the application to read and
531// rewrite the block. An example of this can be found in the Audition filter.
532
533void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block)
534{
535 little_endian_to_native (wpc, WavpackHeaderFormat);
536 ((WavpackHeader *) first_block)->total_samples = WavpackGetSampleIndex (wpc);
537 native_to_little_endian (wpc, WavpackHeaderFormat);
538}
539
540// Given the pointer to the first block written to a WavPack file, this
541// function returns the location of the stored RIFF header that was originally
542// written with WavpackAddWrapper(). This would normally be used to update
543// the wav header to indicate that a different number of samples was actually
544// written or if additional RIFF chunks are written at the end of the file.
545// It is the responsibility of the application to read and rewrite the block.
546// An example of this can be found in the Audition filter.
547
548void *WavpackGetWrapperLocation (void *first_block)
549{
550 if (((uchar *) first_block) [32] == ID_RIFF_HEADER)
551 return ((uchar *) first_block) + 34;
552 else
553 return NULL;
554}
555