diff options
-rw-r--r-- | apps/codecs/libwavpack/SOURCES | 1 | ||||
-rw-r--r-- | apps/codecs/libwavpack/bits.c | 163 | ||||
-rw-r--r-- | apps/codecs/libwavpack/float.c | 90 | ||||
-rw-r--r-- | apps/codecs/libwavpack/metadata.c | 136 | ||||
-rw-r--r-- | apps/codecs/libwavpack/pack.c | 450 | ||||
-rw-r--r-- | apps/codecs/libwavpack/unpack.c | 869 | ||||
-rw-r--r-- | apps/codecs/libwavpack/wavpack.h | 317 | ||||
-rw-r--r-- | apps/codecs/libwavpack/words.c | 798 | ||||
-rw-r--r-- | apps/codecs/libwavpack/wputils.c | 431 |
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 | |||
2 | float.c | 2 | float.c |
3 | metadata.c | 3 | metadata.c |
4 | unpack.c | 4 | unpack.c |
5 | pack.c | ||
5 | words.c | 6 | words.c |
6 | wputils.c | 7 | wputils.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 | |||
49 | static void bs_read (Bitstream *bs) | 49 | static 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 | |||
81 | static void bs_write (Bitstream *bs); | ||
82 | |||
83 | void 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 | |||
94 | static 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 | |||
103 | ulong 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 | ||
79 | void little_endian_to_native (void *data, char *format) | 118 | void 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) | |||
28 | void float_values (WavpackStream *wps, long *values, long num_values) | 28 | void 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 | |||
15 | int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd) | 17 | int 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: | 109 | int 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 | |||
147 | void 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 | |||
30 | static const char default_terms [] = { 18,18,2,3,-2,0 }; | ||
31 | static const char high_terms [] = { 18,18,2,3,-2,18,2,4,7,5,3,6,8,-1,18,2,0 }; | ||
32 | static 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 | |||
39 | void 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 | |||
75 | static 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 | |||
95 | static 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 | |||
125 | static 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 | |||
195 | static 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 | |||
216 | static int pack_samples (WavpackContext *wpc, long *buffer); | ||
217 | |||
218 | int 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 | |||
268 | static 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 | ||
21 | static void strcpy_loc (char *dst, char *src) { while (*src) *dst++ = *src++; *dst = 0; } | 21 | static 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.. | 17 | typedef unsigned char uchar; |
18 | typedef unsigned char uchar; | 18 | typedef unsigned short ushort; |
19 | typedef unsigned short ushort; | 19 | typedef unsigned long ulong; |
20 | typedef unsigned long ulong; | 20 | typedef unsigned int uint; |
21 | typedef 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 | ||
90 | typedef struct { | 89 | typedef 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 | ||
128 | typedef struct { | 128 | typedef 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 | ||
194 | struct 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 | |||
194 | typedef struct { | 201 | typedef 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 | ||
249 | void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end, read_stream file, ulong file_bytes); | 259 | void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end, read_stream file, ulong file_bytes); |
260 | void bs_open_write (Bitstream *bs, uchar *buffer_start, uchar *buffer_end); | ||
261 | ulong 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 | |||
273 | void little_endian_to_native (void *data, char *format); | 316 | void little_endian_to_native (void *data, char *format); |
274 | void native_to_little_endian (void *data, char *format); | 317 | void 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 | ||
278 | int unpack_init (WavpackContext *wpc); | 352 | int unpack_init (WavpackContext *wpc); |
@@ -287,17 +361,31 @@ int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd); | |||
287 | long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count); | 361 | long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count); |
288 | int check_crc_error (WavpackContext *wpc); | 362 | int check_crc_error (WavpackContext *wpc); |
289 | 363 | ||
364 | // pack.c | ||
365 | |||
366 | void pack_init (WavpackContext *wpc); | ||
367 | int pack_block (WavpackContext *wpc, long *buffer); | ||
368 | |||
290 | // metadata.c stuff | 369 | // metadata.c stuff |
291 | 370 | ||
292 | int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd); | 371 | int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd); |
293 | int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd); | 372 | int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd); |
373 | int copy_metadata (WavpackMetadata *wpmd, uchar *buffer_start, uchar *buffer_end); | ||
374 | void free_metadata (WavpackMetadata *wpmd); | ||
294 | 375 | ||
295 | // words.c stuff | 376 | // words.c stuff |
296 | 377 | ||
378 | void init_words (WavpackStream *wps); | ||
297 | int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd); | 379 | int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd); |
380 | void write_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd); | ||
298 | int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd); | 381 | int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd); |
299 | long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer); | 382 | long get_words (long *buffer, int nsamples, ulong flags, |
383 | struct words_data *w, Bitstream *bs); | ||
384 | void send_word_lossless (WavpackStream *wps, long value, int chan); | ||
385 | void flush_word (WavpackStream *wps); | ||
386 | int log2s (long value); | ||
300 | long exp2s (int log); | 387 | long exp2s (int log); |
388 | char store_weight (int weight); | ||
301 | int restore_weight (char weight); | 389 | int 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 | ||
315 | int WavpackGetMode (WavpackContext *wpc); | 403 | int 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 | ||
325 | ulong WavpackUnpackSamples (WavpackContext *wpc, long *buffer, ulong samples); | 413 | ulong WavpackUnpackSamples (WavpackContext *wpc, long *buffer, ulong samples); |
326 | ulong WavpackGetNumSamples (WavpackContext *wpc); | 414 | ulong WavpackGetNumSamples (WavpackContext *wpc); |
@@ -332,3 +420,10 @@ int WavpackGetBitsPerSample (WavpackContext *wpc); | |||
332 | int WavpackGetBytesPerSample (WavpackContext *wpc); | 420 | int WavpackGetBytesPerSample (WavpackContext *wpc); |
333 | int WavpackGetNumChannels (WavpackContext *wpc); | 421 | int WavpackGetNumChannels (WavpackContext *wpc); |
334 | int WavpackGetReducedChannels (WavpackContext *wpc); | 422 | int WavpackGetReducedChannels (WavpackContext *wpc); |
423 | WavpackContext *WavpackOpenFileOutput (void); | ||
424 | void WavpackSetOutputBuffer (WavpackContext *wpc, uchar *begin, uchar *end); | ||
425 | int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, ulong total_samples); | ||
426 | void WavpackAddWrapper (WavpackContext *wpc, void *data, ulong bcount); | ||
427 | ulong 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 | ||
69 | const 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 | |||
80 | const 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 | |||
69 | const char nbits_table [] = { | 91 | const 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 | ||
88 | static const uchar log2_table [] = { | 110 | static const uchar log2_table [] = { |
@@ -136,6 +158,11 @@ static const char ones_count_table [] = { | |||
136 | 158 | ||
137 | ///////////////////////////// executable code //////////////////////////////// | 159 | ///////////////////////////// executable code //////////////////////////////// |
138 | 160 | ||
161 | void init_words (WavpackStream *wps) | ||
162 | { | ||
163 | CLEAR (wps->w); | ||
164 | } | ||
165 | |||
139 | static int mylog2 (unsigned long avalue); | 166 | static 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 | |||
198 | void 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 | ||
217 | static void update_error_limit (WavpackStream *wps) | 278 | void 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 | ||
284 | long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer) | 345 | long 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 | |||
543 | void 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 | |||
649 | void 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 | |||
752 | int 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 | ||
781 | char 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 | |||
534 | int restore_weight (char weight) | 794 | int 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 | ||
22 | static void strcpy_loc (char *dst, char *src) { while (*src) *dst++ = *src++; *dst = 0; } | 22 | static 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 | ||
31 | static ulong read_next_header (read_stream infile, WavpackHeader *wphdr); | 31 | static 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) | |||
244 | ulong WavpackGetSampleIndex (WavpackContext *wpc) | 244 | ulong 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) | |||
310 | int WavpackGetReducedChannels (WavpackContext *wpc) | 310 | int 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 | |||
362 | WavpackContext *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 | |||
373 | void 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 | |||
421 | int 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 | |||
483 | void 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 | |||
500 | ulong 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 | |||
533 | void 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 | |||
548 | void *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 | |||