summaryrefslogtreecommitdiff
path: root/apps/codecs/libwavpack/words.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libwavpack/words.c')
-rw-r--r--apps/codecs/libwavpack/words.c238
1 files changed, 138 insertions, 100 deletions
diff --git a/apps/codecs/libwavpack/words.c b/apps/codecs/libwavpack/words.c
index 35061b69a9..370c0d4857 100644
--- a/apps/codecs/libwavpack/words.c
+++ b/apps/codecs/libwavpack/words.c
@@ -123,9 +123,20 @@ static const uchar exp2_table [] = {
123 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff 123 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff
124}; 124};
125 125
126static const char ones_count_table [] = {
127 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
128 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
129 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
130 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,
131 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
132 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
133 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
134 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8
135};
136
126///////////////////////////// executable code //////////////////////////////// 137///////////////////////////// executable code ////////////////////////////////
127 138
128static int log2 (unsigned long avalue); 139static int mylog2 (unsigned long avalue);
129 140
130// Read the median log2 values from the specifed metadata structure, convert 141// Read the median log2 values from the specifed metadata structure, convert
131// them back to 32-bit unsigned values and store them. If length is not 142// them back to 32-bit unsigned values and store them. If length is not
@@ -270,140 +281,167 @@ static ulong read_code (Bitstream *bs, ulong maxcode);
270// of WORD_EOF indicates that the end of the bitstream was reached (all 1s) or 281// of WORD_EOF indicates that the end of the bitstream was reached (all 1s) or
271// some other error occurred. 282// some other error occurred.
272 283
273long get_word (WavpackStream *wps, int chan) 284long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer)
274{ 285{
275 ulong ones_count, low, mid, high; 286 ulong tsamples = nsamples * nchans, ones_count, low, mid, high;
276 int sign; 287 int next8, sign, chan;
288 long *bptr = buffer;
277 289
278 if (wps->w.zeros_acc) { 290 while (tsamples--) {
279 if (--wps->w.zeros_acc) {
280 wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS;
281 return 0;
282 }
283 }
284 else if (!wps->w.holding_zero && !wps->w.holding_one && !(wps->w.median [0] [0] & ~1) && !(wps->w.median [0] [1] & ~1)) {
285 ulong mask;
286 int cbits;
287 291
288 for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); 292 chan = (nchans == 1) ? 0 : (~tsamples & 1);
289 293
290 if (cbits == 33) 294 if (!(wps->w.median [0] [0] & ~1) && !wps->w.holding_zero && !wps->w.holding_one && !(wps->w.median [0] [1] & ~1)) {
291 return WORD_EOF; 295 ulong mask;
296 int cbits;
297
298 if (wps->w.zeros_acc) {
299 if (--wps->w.zeros_acc) {
300 wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS;
301 *bptr++ = 0;
302 continue;
303 }
304 }
305 else {
306 for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits);
307
308 if (cbits == 33)
309 break;
310
311 if (cbits < 2)
312 wps->w.zeros_acc = cbits;
313 else {
314 for (mask = 1, wps->w.zeros_acc = 0; --cbits; mask <<= 1)
315 if (getbit (&wps->wvbits))
316 wps->w.zeros_acc |= mask;
292 317
293 if (cbits < 2)
294 wps->w.zeros_acc = cbits;
295 else {
296 for (mask = 1, wps->w.zeros_acc = 0; --cbits; mask <<= 1)
297 if (getbit (&wps->wvbits))
298 wps->w.zeros_acc |= mask; 318 wps->w.zeros_acc |= mask;
319 }
299 320
300 wps->w.zeros_acc |= mask; 321 if (wps->w.zeros_acc) {
322 wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS;
323 CLEAR (wps->w.median);
324 *bptr++ = 0;
325 continue;
326 }
327 }
301 } 328 }
302 329
303 if (wps->w.zeros_acc) { 330 if (wps->w.holding_zero)
304 wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; 331 ones_count = wps->w.holding_zero = 0;
305 CLEAR (wps->w.median); 332 else {
306 return 0; 333 if (wps->wvbits.bc < 8) {
307 } 334 if (++(wps->wvbits.ptr) == wps->wvbits.end)
308 } 335 wps->wvbits.wrap (&wps->wvbits);
309 336
310 if (wps->w.holding_zero) 337 next8 = (wps->wvbits.sr |= *(wps->wvbits.ptr) << wps->wvbits.bc) & 0xff;
311 ones_count = wps->w.holding_zero = 0; 338 wps->wvbits.bc += 8;
312 else { 339 }
313#ifdef LIMIT_ONES 340 else
314 for (ones_count = 0; ones_count < (LIMIT_ONES + 1) && getbit (&wps->wvbits); ++ones_count); 341 next8 = wps->wvbits.sr & 0xff;
315 342
316 if (ones_count == (LIMIT_ONES + 1)) 343 if (next8 == 0xff) {
317 return WORD_EOF; 344 wps->wvbits.bc -= 8;
345 wps->wvbits.sr >>= 8;
318 346
319 if (ones_count == LIMIT_ONES) { 347 for (ones_count = 8; ones_count < (LIMIT_ONES + 1) && getbit (&wps->wvbits); ++ones_count);
320 ulong mask;
321 int cbits;
322 348
323 for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); 349 if (ones_count == (LIMIT_ONES + 1))
350 break;
324 351
325 if (cbits == 33) 352 if (ones_count == LIMIT_ONES) {
326 return WORD_EOF; 353 ulong mask;
354 int cbits;
355
356 for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits);
357
358 if (cbits == 33)
359 break;
360
361 if (cbits < 2)
362 ones_count = cbits;
363 else {
364 for (mask = 1, ones_count = 0; --cbits; mask <<= 1)
365 if (getbit (&wps->wvbits))
366 ones_count |= mask;
327 367
328 if (cbits < 2)
329 ones_count = cbits;
330 else {
331 for (mask = 1, ones_count = 0; --cbits; mask <<= 1)
332 if (getbit (&wps->wvbits))
333 ones_count |= mask; 368 ones_count |= mask;
369 }
334 370
335 ones_count |= mask; 371 ones_count += LIMIT_ONES;
372 }
373 }
374 else {
375 wps->wvbits.bc -= (ones_count = ones_count_table [next8]) + 1;
376 wps->wvbits.sr >>= ones_count + 1;
336 } 377 }
337 378
338 ones_count += LIMIT_ONES; 379 if (wps->w.holding_one) {
339 } 380 wps->w.holding_one = ones_count & 1;
340#else 381 ones_count = (ones_count >> 1) + 1;
341 for (ones_count = 0; getbit (&wps->wvbits); ++ones_count); 382 }
342#endif 383 else {
384 wps->w.holding_one = ones_count & 1;
385 ones_count >>= 1;
386 }
343 387
344 if (wps->w.holding_one) { 388 wps->w.holding_zero = ~wps->w.holding_one & 1;
345 wps->w.holding_one = ones_count & 1;
346 ones_count = (ones_count >> 1) + 1;
347 } 389 }
348 else {
349 wps->w.holding_one = ones_count & 1;
350 ones_count >>= 1;
351 }
352
353 wps->w.holding_zero = ~wps->w.holding_one & 1;
354 }
355 390
356 if ((wps->wphdr.flags & HYBRID_FLAG) && !chan) 391 if ((wps->wphdr.flags & HYBRID_FLAG) && !chan)
357 update_error_limit (wps); 392 update_error_limit (wps);
358
359 if (ones_count == 0) {
360 low = 0;
361 high = GET_MED (0) - 1;
362 DEC_MED0 ();
363 }
364 else {
365 low = GET_MED (0);
366 INC_MED0 ();
367 393
368 if (ones_count == 1) { 394 if (ones_count == 0) {
369 high = low + GET_MED (1) - 1; 395 low = 0;
370 DEC_MED1 (); 396 high = GET_MED (0) - 1;
397 DEC_MED0 ();
371 } 398 }
372 else { 399 else {
373 low += GET_MED (1); 400 low = GET_MED (0);
374 INC_MED1 (); 401 INC_MED0 ();
375 402
376 if (ones_count == 2) { 403 if (ones_count == 1) {
377 high = low + GET_MED (2) - 1; 404 high = low + GET_MED (1) - 1;
378 DEC_MED2 (); 405 DEC_MED1 ();
379 } 406 }
380 else { 407 else {
381 low += (ones_count - 2) * GET_MED (2); 408 low += GET_MED (1);
382 high = low + GET_MED (2) - 1; 409 INC_MED1 ();
383 INC_MED2 (); 410
411 if (ones_count == 2) {
412 high = low + GET_MED (2) - 1;
413 DEC_MED2 ();
414 }
415 else {
416 low += (ones_count - 2) * GET_MED (2);
417 high = low + GET_MED (2) - 1;
418 INC_MED2 ();
419 }
384 } 420 }
385 } 421 }
386 }
387 422
388 mid = (high + low + 1) >> 1; 423 mid = (high + low + 1) >> 1;
389 424
390 if (!wps->w.error_limit [chan]) 425 if (!wps->w.error_limit [chan])
391 mid = read_code (&wps->wvbits, high - low) + low; 426 mid = read_code (&wps->wvbits, high - low) + low;
392 else while (high - low > wps->w.error_limit [chan]) { 427 else while (high - low > wps->w.error_limit [chan]) {
393 if (getbit (&wps->wvbits)) 428 if (getbit (&wps->wvbits))
394 mid = (high + (low = mid) + 1) >> 1; 429 mid = (high + (low = mid) + 1) >> 1;
395 else 430 else
396 mid = ((high = mid - 1) + low + 1) >> 1; 431 mid = ((high = mid - 1) + low + 1) >> 1;
397 } 432 }
398 433
399 sign = getbit (&wps->wvbits); 434 sign = getbit (&wps->wvbits);
400 435
401 if (wps->wphdr.flags & HYBRID_BITRATE) { 436 if (wps->wphdr.flags & HYBRID_BITRATE) {
402 wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; 437 wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS;
403 wps->w.slow_level [chan] += log2 (mid); 438 wps->w.slow_level [chan] += mylog2 (mid);
439 }
440
441 *bptr++ = sign ? ~mid : mid;
404 } 442 }
405 443
406 return sign ? ~mid : mid; 444 return nchans == 1 ? (bptr - buffer) : ((bptr - buffer) / 2);
407} 445}
408 446
409// Read a single unsigned value from the specified bitstream with a value 447// Read a single unsigned value from the specified bitstream with a value
@@ -448,7 +486,7 @@ static ulong read_code (Bitstream *bs, ulong maxcode)
448// This function returns the log2 for the specified 32-bit unsigned value. 486// This function returns the log2 for the specified 32-bit unsigned value.
449// The maximum value allowed is about 0xff800000 and returns 8447. 487// The maximum value allowed is about 0xff800000 and returns 8447.
450 488
451static int log2 (unsigned long avalue) 489static int mylog2 (unsigned long avalue)
452{ 490{
453 int dbits; 491 int dbits;
454 492