summaryrefslogtreecommitdiff
path: root/apps/codecs/libwavpack
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libwavpack')
-rw-r--r--apps/codecs/libwavpack/wavpack.h21
-rw-r--r--apps/codecs/libwavpack/words.c91
2 files changed, 59 insertions, 53 deletions
diff --git a/apps/codecs/libwavpack/wavpack.h b/apps/codecs/libwavpack/wavpack.h
index 06f86cb15a..3aee4718b1 100644
--- a/apps/codecs/libwavpack/wavpack.h
+++ b/apps/codecs/libwavpack/wavpack.h
@@ -187,24 +187,29 @@ struct decorr_pass {
187 long samples_A [MAX_TERM], samples_B [MAX_TERM]; 187 long samples_A [MAX_TERM], samples_B [MAX_TERM];
188}; 188};
189 189
190struct entropy_data {
191 ulong median [3], slow_level, error_limit;
192};
193
190typedef struct { 194typedef struct {
191 WavpackHeader wphdr; 195 WavpackHeader wphdr;
196 Bitstream wvbits;
197
198 struct {
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;
192 204
193 int num_terms, mute_error; 205 int num_terms, mute_error;
194 ulong sample_index, crc; 206 ulong sample_index, crc;
195 Bitstream wvbits;
196 207
197 uchar int32_sent_bits, int32_zeros, int32_ones, int32_dups; 208 uchar int32_sent_bits, int32_zeros, int32_ones, int32_dups;
198 uchar float_flags, float_shift, float_max_exp, float_norm_exp; 209 uchar float_flags, float_shift, float_max_exp, float_norm_exp;
199 210
200 struct decorr_pass decorr_passes [MAX_NTERMS]; 211 struct decorr_pass decorr_passes [MAX_NTERMS];
201 212
202 struct {
203 ulong bitrate_delta [2], bitrate_acc [2];
204 ulong median [3] [2], slow_level [2], error_limit [2];
205 ulong pend_data, holding_one, zeros_acc;
206 int holding_zero, pend_count;
207 } w;
208} WavpackStream; 213} WavpackStream;
209 214
210// flags for float_flags: 215// flags for float_flags:
@@ -223,8 +228,8 @@ typedef struct {
223// and the provided utilities used instead. 228// and the provided utilities used instead.
224 229
225typedef struct { 230typedef struct {
226 WavpackConfig config;
227 WavpackStream stream; 231 WavpackStream stream;
232 WavpackConfig config;
228 233
229 uchar read_buffer [1024]; 234 uchar read_buffer [1024];
230 char error_message [80]; 235 char error_message [80];
diff --git a/apps/codecs/libwavpack/words.c b/apps/codecs/libwavpack/words.c
index 370c0d4857..8e2fc427a6 100644
--- a/apps/codecs/libwavpack/words.c
+++ b/apps/codecs/libwavpack/words.c
@@ -42,19 +42,19 @@
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) (((wps->w.median [med] [chan]) >> 4) + 1) 45#define GET_MED(med) (((c->median [med]) >> 4) + 1)
46 46
47// These macros update the specified median breakpoints. Note that the median 47// These macros update the specified median breakpoints. Note that the median
48// is incremented when the sample is higher than the median, else decremented. 48// is incremented when the sample is higher than the median, else decremented.
49// They are designed so that the median will never drop below 1 and the value 49// They are designed so that the median will never drop below 1 and the value
50// is essentially stationary if there are 2 increments for every 5 decrements. 50// is essentially stationary if there are 2 increments for every 5 decrements.
51 51
52#define INC_MED0() (wps->w.median [0] [chan] += ((wps->w.median [0] [chan] + DIV0) / DIV0) * 5) 52#define INC_MED0() (c->median [0] += ((c->median [0] + DIV0) / DIV0) * 5)
53#define DEC_MED0() (wps->w.median [0] [chan] -= ((wps->w.median [0] [chan] + (DIV0-2)) / DIV0) * 2) 53#define DEC_MED0() (c->median [0] -= ((c->median [0] + (DIV0-2)) / DIV0) * 2)
54#define INC_MED1() (wps->w.median [1] [chan] += ((wps->w.median [1] [chan] + DIV1) / DIV1) * 5) 54#define INC_MED1() (c->median [1] += ((c->median [1] + DIV1) / DIV1) * 5)
55#define DEC_MED1() (wps->w.median [1] [chan] -= ((wps->w.median [1] [chan] + (DIV1-2)) / DIV1) * 2) 55#define DEC_MED1() (c->median [1] -= ((c->median [1] + (DIV1-2)) / DIV1) * 2)
56#define INC_MED2() (wps->w.median [2] [chan] += ((wps->w.median [2] [chan] + DIV2) / DIV2) * 5) 56#define INC_MED2() (c->median [2] += ((c->median [2] + DIV2) / DIV2) * 5)
57#define DEC_MED2() (wps->w.median [2] [chan] -= ((wps->w.median [2] [chan] + (DIV2-2)) / DIV2) * 2) 57#define DEC_MED2() (c->median [2] -= ((c->median [2] + (DIV2-2)) / DIV2) * 2)
58 58
59#define count_bits(av) ( \ 59#define count_bits(av) ( \
60 (av) < (1 << 8) ? nbits_table [av] : \ 60 (av) < (1 << 8) ? nbits_table [av] : \
@@ -149,14 +149,14 @@ int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd)
149 if (wpmd->byte_length != ((wps->wphdr.flags & MONO_FLAG) ? 6 : 12)) 149 if (wpmd->byte_length != ((wps->wphdr.flags & MONO_FLAG) ? 6 : 12))
150 return FALSE; 150 return FALSE;
151 151
152 wps->w.median [0] [0] = exp2s (byteptr [0] + (byteptr [1] << 8)); 152 wps->w.c [0].median [0] = exp2s (byteptr [0] + (byteptr [1] << 8));
153 wps->w.median [1] [0] = exp2s (byteptr [2] + (byteptr [3] << 8)); 153 wps->w.c [0].median [1] = exp2s (byteptr [2] + (byteptr [3] << 8));
154 wps->w.median [2] [0] = exp2s (byteptr [4] + (byteptr [5] << 8)); 154 wps->w.c [0].median [2] = exp2s (byteptr [4] + (byteptr [5] << 8));
155 155
156 if (!(wps->wphdr.flags & MONO_FLAG)) { 156 if (!(wps->wphdr.flags & MONO_FLAG)) {
157 wps->w.median [0] [1] = exp2s (byteptr [6] + (byteptr [7] << 8)); 157 wps->w.c [1].median [0] = exp2s (byteptr [6] + (byteptr [7] << 8));
158 wps->w.median [1] [1] = exp2s (byteptr [8] + (byteptr [9] << 8)); 158 wps->w.c [1].median [1] = exp2s (byteptr [8] + (byteptr [9] << 8));
159 wps->w.median [2] [1] = exp2s (byteptr [10] + (byteptr [11] << 8)); 159 wps->w.c [1].median [2] = exp2s (byteptr [10] + (byteptr [11] << 8));
160 } 160 }
161 161
162 return TRUE; 162 return TRUE;
@@ -173,11 +173,11 @@ int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd)
173 uchar *endptr = byteptr + wpmd->byte_length; 173 uchar *endptr = byteptr + wpmd->byte_length;
174 174
175 if (wps->wphdr.flags & HYBRID_BITRATE) { 175 if (wps->wphdr.flags & HYBRID_BITRATE) {
176 wps->w.slow_level [0] = exp2s (byteptr [0] + (byteptr [1] << 8)); 176 wps->w.c [0].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8));
177 byteptr += 2; 177 byteptr += 2;
178 178
179 if (!(wps->wphdr.flags & MONO_FLAG)) { 179 if (!(wps->wphdr.flags & MONO_FLAG)) {
180 wps->w.slow_level [1] = exp2s (byteptr [0] + (byteptr [1] << 8)); 180 wps->w.c [1].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8));
181 byteptr += 2; 181 byteptr += 2;
182 } 182 }
183 } 183 }
@@ -220,22 +220,22 @@ static void update_error_limit (WavpackStream *wps)
220 220
221 if (wps->wphdr.flags & MONO_FLAG) { 221 if (wps->wphdr.flags & MONO_FLAG) {
222 if (wps->wphdr.flags & HYBRID_BITRATE) { 222 if (wps->wphdr.flags & HYBRID_BITRATE) {
223 int slow_log_0 = (wps->w.slow_level [0] + SLO) >> SLS; 223 int slow_log_0 = (wps->w.c [0].slow_level + SLO) >> SLS;
224 224
225 if (slow_log_0 - bitrate_0 > -0x100) 225 if (slow_log_0 - bitrate_0 > -0x100)
226 wps->w.error_limit [0] = exp2s (slow_log_0 - bitrate_0 + 0x100); 226 wps->w.c [0].error_limit = exp2s (slow_log_0 - bitrate_0 + 0x100);
227 else 227 else
228 wps->w.error_limit [0] = 0; 228 wps->w.c [0].error_limit = 0;
229 } 229 }
230 else 230 else
231 wps->w.error_limit [0] = exp2s (bitrate_0); 231 wps->w.c [0].error_limit = exp2s (bitrate_0);
232 } 232 }
233 else { 233 else {
234 int bitrate_1 = (wps->w.bitrate_acc [1] += wps->w.bitrate_delta [1]) >> 16; 234 int bitrate_1 = (wps->w.bitrate_acc [1] += wps->w.bitrate_delta [1]) >> 16;
235 235
236 if (wps->wphdr.flags & HYBRID_BITRATE) { 236 if (wps->wphdr.flags & HYBRID_BITRATE) {
237 int slow_log_0 = (wps->w.slow_level [0] + SLO) >> SLS; 237 int slow_log_0 = (wps->w.c [0].slow_level + SLO) >> SLS;
238 int slow_log_1 = (wps->w.slow_level [1] + SLO) >> SLS; 238 int slow_log_1 = (wps->w.c [1].slow_level + SLO) >> SLS;
239 239
240 if (wps->wphdr.flags & HYBRID_BALANCE) { 240 if (wps->wphdr.flags & HYBRID_BALANCE) {
241 int balance = (slow_log_1 - slow_log_0 + bitrate_1 + 1) >> 1; 241 int balance = (slow_log_1 - slow_log_0 + bitrate_1 + 1) >> 1;
@@ -255,18 +255,18 @@ static void update_error_limit (WavpackStream *wps)
255 } 255 }
256 256
257 if (slow_log_0 - bitrate_0 > -0x100) 257 if (slow_log_0 - bitrate_0 > -0x100)
258 wps->w.error_limit [0] = exp2s (slow_log_0 - bitrate_0 + 0x100); 258 wps->w.c [0].error_limit = exp2s (slow_log_0 - bitrate_0 + 0x100);
259 else 259 else
260 wps->w.error_limit [0] = 0; 260 wps->w.c [0].error_limit = 0;
261 261
262 if (slow_log_1 - bitrate_1 > -0x100) 262 if (slow_log_1 - bitrate_1 > -0x100)
263 wps->w.error_limit [1] = exp2s (slow_log_1 - bitrate_1 + 0x100); 263 wps->w.c [1].error_limit = exp2s (slow_log_1 - bitrate_1 + 0x100);
264 else 264 else
265 wps->w.error_limit [1] = 0; 265 wps->w.c [1].error_limit = 0;
266 } 266 }
267 else { 267 else {
268 wps->w.error_limit [0] = exp2s (bitrate_0); 268 wps->w.c [0].error_limit = exp2s (bitrate_0);
269 wps->w.error_limit [1] = exp2s (bitrate_1); 269 wps->w.c [1].error_limit = exp2s (bitrate_1);
270 } 270 }
271 } 271 }
272} 272}
@@ -283,21 +283,23 @@ static ulong read_code (Bitstream *bs, ulong maxcode);
283 283
284long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer) 284long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer)
285{ 285{
286 ulong tsamples = nsamples * nchans, ones_count, low, mid, high; 286 ulong ones_count, low, mid, high;
287 int next8, sign, chan; 287 register struct entropy_data *c;
288 long *bptr = buffer; 288 long *bptr = buffer;
289 289
290 while (tsamples--) { 290 nsamples *= nchans;
291 291
292 chan = (nchans == 1) ? 0 : (~tsamples & 1); 292 while (nsamples--) {
293 293
294 if (!(wps->w.median [0] [0] & ~1) && !wps->w.holding_zero && !wps->w.holding_one && !(wps->w.median [0] [1] & ~1)) { 294 c = wps->w.c + ((nchans == 1) ? 0 : (~nsamples & 1));
295
296 if (!(wps->w.c [0].median [0] & ~1) && !wps->w.holding_zero && !wps->w.holding_one && !(wps->w.c [1].median [0] & ~1)) {
295 ulong mask; 297 ulong mask;
296 int cbits; 298 int cbits;
297 299
298 if (wps->w.zeros_acc) { 300 if (wps->w.zeros_acc) {
299 if (--wps->w.zeros_acc) { 301 if (--wps->w.zeros_acc) {
300 wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; 302 c->slow_level -= (c->slow_level + SLO) >> SLS;
301 *bptr++ = 0; 303 *bptr++ = 0;
302 continue; 304 continue;
303 } 305 }
@@ -319,8 +321,9 @@ long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer)
319 } 321 }
320 322
321 if (wps->w.zeros_acc) { 323 if (wps->w.zeros_acc) {
322 wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; 324 c->slow_level -= (c->slow_level + SLO) >> SLS;
323 CLEAR (wps->w.median); 325 CLEAR (wps->w.c [0].median);
326 CLEAR (wps->w.c [1].median);
324 *bptr++ = 0; 327 *bptr++ = 0;
325 continue; 328 continue;
326 } 329 }
@@ -330,6 +333,8 @@ long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer)
330 if (wps->w.holding_zero) 333 if (wps->w.holding_zero)
331 ones_count = wps->w.holding_zero = 0; 334 ones_count = wps->w.holding_zero = 0;
332 else { 335 else {
336 int next8;
337
333 if (wps->wvbits.bc < 8) { 338 if (wps->wvbits.bc < 8) {
334 if (++(wps->wvbits.ptr) == wps->wvbits.end) 339 if (++(wps->wvbits.ptr) == wps->wvbits.end)
335 wps->wvbits.wrap (&wps->wvbits); 340 wps->wvbits.wrap (&wps->wvbits);
@@ -388,7 +393,7 @@ long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer)
388 wps->w.holding_zero = ~wps->w.holding_one & 1; 393 wps->w.holding_zero = ~wps->w.holding_one & 1;
389 } 394 }
390 395
391 if ((wps->wphdr.flags & HYBRID_FLAG) && !chan) 396 if ((wps->wphdr.flags & HYBRID_FLAG) && (nchans == 1 || (nsamples & 1)))
392 update_error_limit (wps); 397 update_error_limit (wps);
393 398
394 if (ones_count == 0) { 399 if (ones_count == 0) {
@@ -422,23 +427,19 @@ long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer)
422 427
423 mid = (high + low + 1) >> 1; 428 mid = (high + low + 1) >> 1;
424 429
425 if (!wps->w.error_limit [chan]) 430 if (!c->error_limit)
426 mid = read_code (&wps->wvbits, high - low) + low; 431 mid = read_code (&wps->wvbits, high - low) + low;
427 else while (high - low > wps->w.error_limit [chan]) { 432 else while (high - low > c->error_limit) {
428 if (getbit (&wps->wvbits)) 433 if (getbit (&wps->wvbits))
429 mid = (high + (low = mid) + 1) >> 1; 434 mid = (high + (low = mid) + 1) >> 1;
430 else 435 else
431 mid = ((high = mid - 1) + low + 1) >> 1; 436 mid = ((high = mid - 1) + low + 1) >> 1;
432 } 437 }
433 438
434 sign = getbit (&wps->wvbits); 439 *bptr++ = getbit (&wps->wvbits) ? ~mid : mid;
435
436 if (wps->wphdr.flags & HYBRID_BITRATE) {
437 wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS;
438 wps->w.slow_level [chan] += mylog2 (mid);
439 }
440 440
441 *bptr++ = sign ? ~mid : mid; 441 if (wps->wphdr.flags & HYBRID_BITRATE)
442 c->slow_level = c->slow_level - ((c->slow_level + SLO) >> SLS) + mylog2 (mid);
442 } 443 }
443 444
444 return nchans == 1 ? (bptr - buffer) : ((bptr - buffer) / 2); 445 return nchans == 1 ? (bptr - buffer) : ((bptr - buffer) / 2);