Mercurial > libavcodec.hg
comparison wavpack.c @ 9610:ad0e96494f1e libavcodec
Add floating point audio decoding to WavPack decoder.
Patch by Laurent Aimar (fenrir at `antonym of 'audio'+antonym of 'WAN'` dot org)
author | kostya |
---|---|
date | Wed, 06 May 2009 05:40:43 +0000 |
parents | 71c0f08bd41d |
children | a514a601bf26 |
comparison
equal
deleted
inserted
replaced
9609:71c0f08bd41d | 9610:ad0e96494f1e |
---|---|
35 #define WV_HYBRID_MODE 0x00000008 | 35 #define WV_HYBRID_MODE 0x00000008 |
36 #define WV_HYBRID_SHAPE 0x00000008 | 36 #define WV_HYBRID_SHAPE 0x00000008 |
37 #define WV_HYBRID_BITRATE 0x00000200 | 37 #define WV_HYBRID_BITRATE 0x00000200 |
38 #define WV_HYBRID_BALANCE 0x00000400 | 38 #define WV_HYBRID_BALANCE 0x00000400 |
39 | 39 |
40 #define WV_FLT_SHIFT_ONES 0x01 | |
41 #define WV_FLT_SHIFT_SAME 0x02 | |
42 #define WV_FLT_SHIFT_SENT 0x04 | |
43 #define WV_FLT_ZERO_SENT 0x08 | |
44 #define WV_FLT_ZERO_SIGN 0x10 | |
45 | |
40 enum WP_ID_Flags{ | 46 enum WP_ID_Flags{ |
41 WP_IDF_MASK = 0x1F, | 47 WP_IDF_MASK = 0x1F, |
42 WP_IDF_IGNORE = 0x20, | 48 WP_IDF_IGNORE = 0x20, |
43 WP_IDF_ODD = 0x40, | 49 WP_IDF_ODD = 0x40, |
44 WP_IDF_LONG = 0x80 | 50 WP_IDF_LONG = 0x80 |
95 int zero, one, zeroes; | 101 int zero, one, zeroes; |
96 int extra_bits; | 102 int extra_bits; |
97 int and, or, shift; | 103 int and, or, shift; |
98 int post_shift; | 104 int post_shift; |
99 int hybrid, hybrid_bitrate; | 105 int hybrid, hybrid_bitrate; |
106 int float_flag; | |
107 int float_shift; | |
108 int float_max_exp; | |
100 WvChannel ch[2]; | 109 WvChannel ch[2]; |
101 } WavpackContext; | 110 } WavpackContext; |
102 | 111 |
103 // exponent table copied from WavPack source | 112 // exponent table copied from WavPack source |
104 static const uint8_t wp_exp2_table [256] = { | 113 static const uint8_t wp_exp2_table [256] = { |
355 } | 364 } |
356 bit = (S & s->and) | s->or; | 365 bit = (S & s->and) | s->or; |
357 return (((S + bit) << s->shift) - bit) << s->post_shift; | 366 return (((S + bit) << s->shift) - bit) << s->post_shift; |
358 } | 367 } |
359 | 368 |
369 static float wv_get_value_float(WavpackContext *s, uint32_t *crc, int S) | |
370 { | |
371 union { | |
372 float f; | |
373 uint32_t u; | |
374 } value; | |
375 | |
376 int sign; | |
377 int exp = s->float_max_exp; | |
378 | |
379 if(s->got_extra_bits){ | |
380 const int max_bits = 1 + 23 + 8 + 1; | |
381 const int left_bits = s->gb_extra_bits.size_in_bits - get_bits_count(&s->gb_extra_bits); | |
382 | |
383 if(left_bits + 8 * FF_INPUT_BUFFER_PADDING_SIZE < max_bits) | |
384 return 0.0; | |
385 } | |
386 | |
387 if(S){ | |
388 S <<= s->float_shift; | |
389 sign = S < 0; | |
390 if(sign) | |
391 S = -S; | |
392 if(S >= 0x1000000){ | |
393 if(s->got_extra_bits && get_bits1(&s->gb_extra_bits)){ | |
394 S = get_bits(&s->gb_extra_bits, 23); | |
395 }else{ | |
396 S = 0; | |
397 } | |
398 exp = 255; | |
399 }else if(exp){ | |
400 int shift = 23 - av_log2(S); | |
401 exp = s->float_max_exp; | |
402 if(exp <= shift){ | |
403 shift = --exp; | |
404 } | |
405 exp -= shift; | |
406 | |
407 if(shift){ | |
408 S <<= shift; | |
409 if((s->float_flag & WV_FLT_SHIFT_ONES) || | |
410 (s->got_extra_bits && (s->float_flag & WV_FLT_SHIFT_SAME) && get_bits1(&s->gb_extra_bits)) ){ | |
411 S |= (1 << shift) - 1; | |
412 } else if(s->got_extra_bits && (s->float_flag & WV_FLT_SHIFT_SENT)){ | |
413 S |= get_bits(&s->gb_extra_bits, shift); | |
414 } | |
415 } | |
416 }else{ | |
417 exp = s->float_max_exp; | |
418 } | |
419 S &= 0x7fffff; | |
420 }else{ | |
421 sign = 0; | |
422 exp = 0; | |
423 if(s->got_extra_bits && (s->float_flag & WV_FLT_ZERO_SENT)){ | |
424 if(get_bits1(&s->gb_extra_bits)){ | |
425 S = get_bits(&s->gb_extra_bits, 23); | |
426 if(s->float_max_exp >= 25) | |
427 exp = get_bits(&s->gb_extra_bits, 8); | |
428 sign = get_bits1(&s->gb_extra_bits); | |
429 }else{ | |
430 if(s->float_flag & WV_FLT_ZERO_SIGN) | |
431 sign = get_bits1(&s->gb_extra_bits); | |
432 } | |
433 } | |
434 } | |
435 | |
436 *crc = *crc * 27 + S * 9 + exp * 3 + sign; | |
437 | |
438 value.u = (sign << 31) | (exp << 23) | S; | |
439 return value.f; | |
440 } | |
441 | |
360 static inline int wv_unpack_stereo(WavpackContext *s, GetBitContext *gb, void *dst, const int type) | 442 static inline int wv_unpack_stereo(WavpackContext *s, GetBitContext *gb, void *dst, const int type) |
361 { | 443 { |
362 int i, j, count = 0; | 444 int i, j, count = 0; |
363 int last, t; | 445 int last, t; |
364 int A, B, L, L2, R, R2; | 446 int A, B, L, L2, R, R2; |
365 int pos = 0; | 447 int pos = 0; |
366 uint32_t crc = 0xFFFFFFFF; | 448 uint32_t crc = 0xFFFFFFFF; |
367 uint32_t crc_extra_bits = 0xFFFFFFFF; | 449 uint32_t crc_extra_bits = 0xFFFFFFFF; |
368 int16_t *dst16 = dst; | 450 int16_t *dst16 = dst; |
369 int32_t *dst32 = dst; | 451 int32_t *dst32 = dst; |
452 float *dstfl = dst; | |
370 | 453 |
371 s->one = s->zero = s->zeroes = 0; | 454 s->one = s->zero = s->zeroes = 0; |
372 do{ | 455 do{ |
373 L = wv_get_value(s, gb, 0, &last); | 456 L = wv_get_value(s, gb, 0, &last); |
374 if(last) break; | 457 if(last) break; |
443 pos = (pos + 1) & 7; | 526 pos = (pos + 1) & 7; |
444 if(s->joint) | 527 if(s->joint) |
445 L += (R -= (L >> 1)); | 528 L += (R -= (L >> 1)); |
446 crc = (crc * 3 + L) * 3 + R; | 529 crc = (crc * 3 + L) * 3 + R; |
447 | 530 |
448 if(type == SAMPLE_FMT_S32){ | 531 if(type == SAMPLE_FMT_FLT){ |
532 *dstfl++ = wv_get_value_float(s, &crc_extra_bits, L); | |
533 *dstfl++ = wv_get_value_float(s, &crc_extra_bits, R); | |
534 } else if(type == SAMPLE_FMT_S32){ | |
449 *dst32++ = wv_get_value_integer(s, &crc_extra_bits, L); | 535 *dst32++ = wv_get_value_integer(s, &crc_extra_bits, L); |
450 *dst32++ = wv_get_value_integer(s, &crc_extra_bits, R); | 536 *dst32++ = wv_get_value_integer(s, &crc_extra_bits, R); |
451 } else { | 537 } else { |
452 *dst16++ = wv_get_value_integer(s, &crc_extra_bits, L); | 538 *dst16++ = wv_get_value_integer(s, &crc_extra_bits, L); |
453 *dst16++ = wv_get_value_integer(s, &crc_extra_bits, R); | 539 *dst16++ = wv_get_value_integer(s, &crc_extra_bits, R); |
474 int pos = 0; | 560 int pos = 0; |
475 uint32_t crc = 0xFFFFFFFF; | 561 uint32_t crc = 0xFFFFFFFF; |
476 uint32_t crc_extra_bits = 0xFFFFFFFF; | 562 uint32_t crc_extra_bits = 0xFFFFFFFF; |
477 int16_t *dst16 = dst; | 563 int16_t *dst16 = dst; |
478 int32_t *dst32 = dst; | 564 int32_t *dst32 = dst; |
565 float *dstfl = dst; | |
479 | 566 |
480 s->one = s->zero = s->zeroes = 0; | 567 s->one = s->zero = s->zeroes = 0; |
481 do{ | 568 do{ |
482 T = wv_get_value(s, gb, 0, &last); | 569 T = wv_get_value(s, gb, 0, &last); |
483 S = 0; | 570 S = 0; |
503 s->decorr[i].samplesA[j] = T = S; | 590 s->decorr[i].samplesA[j] = T = S; |
504 } | 591 } |
505 pos = (pos + 1) & 7; | 592 pos = (pos + 1) & 7; |
506 crc = crc * 3 + S; | 593 crc = crc * 3 + S; |
507 | 594 |
508 if(type == SAMPLE_FMT_S32) | 595 if(type == SAMPLE_FMT_FLT) |
596 *dstfl++ = wv_get_value_float(s, &crc_extra_bits, S); | |
597 else if(type == SAMPLE_FMT_S32) | |
509 *dst32++ = wv_get_value_integer(s, &crc_extra_bits, S); | 598 *dst32++ = wv_get_value_integer(s, &crc_extra_bits, S); |
510 else | 599 else |
511 *dst16++ = wv_get_value_integer(s, &crc_extra_bits, S); | 600 *dst16++ = wv_get_value_integer(s, &crc_extra_bits, S); |
512 count++; | 601 count++; |
513 }while(!last && count < s->samples); | 602 }while(!last && count < s->samples); |
545 const uint8_t *buf = avpkt->data; | 634 const uint8_t *buf = avpkt->data; |
546 int buf_size = avpkt->size; | 635 int buf_size = avpkt->size; |
547 WavpackContext *s = avctx->priv_data; | 636 WavpackContext *s = avctx->priv_data; |
548 void *samples = data; | 637 void *samples = data; |
549 int samplecount; | 638 int samplecount; |
550 int got_terms = 0, got_weights = 0, got_samples = 0, got_entropy = 0, got_bs = 0; | 639 int got_terms = 0, got_weights = 0, got_samples = 0, got_entropy = 0, got_bs = 0, got_float = 0; |
551 int got_hybrid = 0; | 640 int got_hybrid = 0; |
552 const uint8_t* buf_end = buf + buf_size; | 641 const uint8_t* buf_end = buf + buf_size; |
553 int i, j, id, size, ssize, weights, t; | 642 int i, j, id, size, ssize, weights, t; |
554 int bpp; | 643 int bpp; |
555 | 644 |
568 if(!s->samples){ | 657 if(!s->samples){ |
569 *data_size = 0; | 658 *data_size = 0; |
570 return buf_size; | 659 return buf_size; |
571 } | 660 } |
572 s->frame_flags = AV_RL32(buf); buf += 4; | 661 s->frame_flags = AV_RL32(buf); buf += 4; |
573 if((s->frame_flags&0x03) <= 1){ | 662 if(s->frame_flags&0x80){ |
663 bpp = sizeof(float); | |
664 avctx->sample_fmt = SAMPLE_FMT_FLT; | |
665 } else if((s->frame_flags&0x03) <= 1){ | |
574 bpp = 2; | 666 bpp = 2; |
575 avctx->sample_fmt = SAMPLE_FMT_S16; | 667 avctx->sample_fmt = SAMPLE_FMT_S16; |
576 } else { | 668 } else { |
577 bpp = 4; | 669 bpp = 4; |
578 avctx->sample_fmt = SAMPLE_FMT_S32; | 670 avctx->sample_fmt = SAMPLE_FMT_S32; |
740 s->and = 1; | 832 s->and = 1; |
741 s->shift = buf[3]; | 833 s->shift = buf[3]; |
742 } | 834 } |
743 buf += 4; | 835 buf += 4; |
744 break; | 836 break; |
837 case WP_ID_FLOATINFO: | |
838 if(size != 4){ | |
839 av_log(avctx, AV_LOG_ERROR, "Invalid FLOATINFO, size = %i\n", size); | |
840 buf += ssize; | |
841 continue; | |
842 } | |
843 s->float_flag = buf[0]; | |
844 s->float_shift = buf[1]; | |
845 s->float_max_exp = buf[2]; | |
846 buf += 4; | |
847 got_float = 1; | |
848 break; | |
745 case WP_ID_DATA: | 849 case WP_ID_DATA: |
746 init_get_bits(&s->gb, buf, size * 8); | 850 init_get_bits(&s->gb, buf, size * 8); |
747 s->data_size = size * 8; | 851 s->data_size = size * 8; |
748 buf += size; | 852 buf += size; |
749 got_bs = 1; | 853 got_bs = 1; |
786 } | 890 } |
787 if(!got_bs){ | 891 if(!got_bs){ |
788 av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n"); | 892 av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n"); |
789 return -1; | 893 return -1; |
790 } | 894 } |
791 if(s->got_extra_bits){ | 895 if(!got_float && avctx->sample_fmt == SAMPLE_FMT_FLT){ |
896 av_log(avctx, AV_LOG_ERROR, "Float information not found\n"); | |
897 return -1; | |
898 } | |
899 if(s->got_extra_bits && avctx->sample_fmt != SAMPLE_FMT_FLT){ | |
792 const int size = s->gb_extra_bits.size_in_bits - get_bits_count(&s->gb_extra_bits); | 900 const int size = s->gb_extra_bits.size_in_bits - get_bits_count(&s->gb_extra_bits); |
793 const int wanted = s->samples * s->extra_bits << s->stereo_in; | 901 const int wanted = s->samples * s->extra_bits << s->stereo_in; |
794 if(size < wanted){ | 902 if(size < wanted){ |
795 av_log(avctx, AV_LOG_ERROR, "Too small EXTRABITS\n"); | 903 av_log(avctx, AV_LOG_ERROR, "Too small EXTRABITS\n"); |
796 s->got_extra_bits = 0; | 904 s->got_extra_bits = 0; |
798 } | 906 } |
799 | 907 |
800 if(s->stereo_in){ | 908 if(s->stereo_in){ |
801 if(avctx->sample_fmt == SAMPLE_FMT_S16) | 909 if(avctx->sample_fmt == SAMPLE_FMT_S16) |
802 samplecount = wv_unpack_stereo(s, &s->gb, samples, SAMPLE_FMT_S16); | 910 samplecount = wv_unpack_stereo(s, &s->gb, samples, SAMPLE_FMT_S16); |
911 else if(avctx->sample_fmt == SAMPLE_FMT_S32) | |
912 samplecount = wv_unpack_stereo(s, &s->gb, samples, SAMPLE_FMT_S32); | |
803 else | 913 else |
804 samplecount = wv_unpack_stereo(s, &s->gb, samples, SAMPLE_FMT_S32); | 914 samplecount = wv_unpack_stereo(s, &s->gb, samples, SAMPLE_FMT_FLT); |
915 | |
805 }else{ | 916 }else{ |
806 if(avctx->sample_fmt == SAMPLE_FMT_S16) | 917 if(avctx->sample_fmt == SAMPLE_FMT_S16) |
807 samplecount = wv_unpack_mono(s, &s->gb, samples, SAMPLE_FMT_S16); | 918 samplecount = wv_unpack_mono(s, &s->gb, samples, SAMPLE_FMT_S16); |
919 else if(avctx->sample_fmt == SAMPLE_FMT_S32) | |
920 samplecount = wv_unpack_mono(s, &s->gb, samples, SAMPLE_FMT_S32); | |
808 else | 921 else |
809 samplecount = wv_unpack_mono(s, &s->gb, samples, SAMPLE_FMT_S32); | 922 samplecount = wv_unpack_mono(s, &s->gb, samples, SAMPLE_FMT_FLT); |
923 | |
810 if(s->stereo && avctx->sample_fmt == SAMPLE_FMT_S16){ | 924 if(s->stereo && avctx->sample_fmt == SAMPLE_FMT_S16){ |
811 int16_t *dst = (int16_t*)samples + samplecount * 2; | 925 int16_t *dst = (int16_t*)samples + samplecount * 2; |
812 int16_t *src = (int16_t*)samples + samplecount; | 926 int16_t *src = (int16_t*)samples + samplecount; |
813 int cnt = samplecount; | 927 int cnt = samplecount; |
814 while(cnt--){ | 928 while(cnt--){ |
815 *--dst = *--src; | 929 *--dst = *--src; |
816 *--dst = *src; | 930 *--dst = *src; |
817 } | 931 } |
818 samplecount *= 2; | 932 samplecount *= 2; |
819 }else if(s->stereo){ //32-bit output | 933 }else if(s->stereo && avctx->sample_fmt == SAMPLE_FMT_S32){ |
820 int32_t *dst = (int32_t*)samples + samplecount * 2; | 934 int32_t *dst = (int32_t*)samples + samplecount * 2; |
821 int32_t *src = (int32_t*)samples + samplecount; | 935 int32_t *src = (int32_t*)samples + samplecount; |
936 int cnt = samplecount; | |
937 while(cnt--){ | |
938 *--dst = *--src; | |
939 *--dst = *src; | |
940 } | |
941 samplecount *= 2; | |
942 }else if(s->stereo){ | |
943 float *dst = (float*)samples + samplecount * 2; | |
944 float *src = (float*)samples + samplecount; | |
822 int cnt = samplecount; | 945 int cnt = samplecount; |
823 while(cnt--){ | 946 while(cnt--){ |
824 *--dst = *--src; | 947 *--dst = *--src; |
825 *--dst = *src; | 948 *--dst = *src; |
826 } | 949 } |