1/* 2 * WavPack decoder/encoder common code 3 * Copyright (c) 2006,2011 Konstantin Shishkov 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#ifndef AVCODEC_WAVPACK_H 23#define AVCODEC_WAVPACK_H 24 25#include <limits.h> 26#include <stdint.h> 27#include "libavutil/attributes.h" 28#include "libavutil/intmath.h" 29 30#define MAX_TERMS 16 31#define MAX_TERM 8 32 33#define WV_HEADER_SIZE 32 34 35#define WV_MONO 0x00000004 36#define WV_JOINT_STEREO 0x00000010 37#define WV_CROSS_DECORR 0x00000020 38#define WV_FLOAT_DATA 0x00000080 39#define WV_INT32_DATA 0x00000100 40#define WV_FALSE_STEREO 0x40000000 41#define WV_DSD_DATA 0x80000000 42 43#define WV_HYBRID_MODE 0x00000008 44#define WV_HYBRID_SHAPE 0x00000008 45#define WV_HYBRID_BITRATE 0x00000200 46#define WV_HYBRID_BALANCE 0x00000400 47#define WV_INITIAL_BLOCK 0x00000800 48#define WV_FINAL_BLOCK 0x00001000 49 50#define WV_MONO_DATA (WV_MONO | WV_FALSE_STEREO) 51 52#define WV_SINGLE_BLOCK (WV_INITIAL_BLOCK | WV_FINAL_BLOCK) 53 54#define WV_FLT_SHIFT_ONES 0x01 55#define WV_FLT_SHIFT_SAME 0x02 56#define WV_FLT_SHIFT_SENT 0x04 57#define WV_FLT_ZERO_SENT 0x08 58#define WV_FLT_ZERO_SIGN 0x10 59 60#define WV_MAX_SAMPLES 150000 61 62enum WP_ID_Flags { 63 WP_IDF_MASK = 0x3F, 64 WP_IDF_IGNORE = 0x20, 65 WP_IDF_ODD = 0x40, 66 WP_IDF_LONG = 0x80 67}; 68 69enum WP_ID { 70 WP_ID_DUMMY = 0, 71 WP_ID_ENCINFO, 72 WP_ID_DECTERMS, 73 WP_ID_DECWEIGHTS, 74 WP_ID_DECSAMPLES, 75 WP_ID_ENTROPY, 76 WP_ID_HYBRID, 77 WP_ID_SHAPING, 78 WP_ID_FLOATINFO, 79 WP_ID_INT32INFO, 80 WP_ID_DATA, 81 WP_ID_CORR, 82 WP_ID_EXTRABITS, 83 WP_ID_CHANINFO, 84 WP_ID_DSD_DATA, 85 WP_ID_SAMPLE_RATE = 0x27, 86}; 87 88typedef struct Decorr { 89 int delta; 90 int value; 91 int weightA; 92 int weightB; 93 int samplesA[MAX_TERM]; 94 int samplesB[MAX_TERM]; 95 int sumA; 96 int sumB; 97} Decorr; 98 99typedef struct WvChannel { 100 int median[3]; 101 int slow_level, error_limit; 102 unsigned bitrate_acc, bitrate_delta; 103} WvChannel; 104 105// macros for manipulating median values 106#define GET_MED(n) ((c->median[n] >> 4) + 1) 107#define DEC_MED(n) c->median[n] -= ((int)(c->median[n] + (128U >> (n)) - 2) / (128 >> (n))) * 2U 108#define INC_MED(n) c->median[n] += ((int)(c->median[n] + (128U >> (n)) ) / (128 >> (n))) * 5U 109 110// macros for applying weight 111#define UPDATE_WEIGHT_CLIP(weight, delta, samples, in) \ 112 if ((samples) && (in)) { \ 113 if (((samples) ^ (in)) < 0) { \ 114 (weight) -= (delta); \ 115 if ((weight) < -1024) \ 116 (weight) = -1024; \ 117 } else { \ 118 (weight) += (delta); \ 119 if ((weight) > 1024) \ 120 (weight) = 1024; \ 121 } \ 122 } 123 124static const int wv_rates[16] = { 125 6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000, 126 32000, 44100, 48000, 64000, 88200, 96000, 192000, 0 127}; 128 129// exponent table copied from WavPack source 130extern const uint8_t ff_wp_exp2_table[256]; 131extern const uint8_t ff_wp_log2_table[256]; 132 133static av_always_inline int wp_exp2(int16_t val) 134{ 135 int res, neg = 0; 136 137 if (val < 0) { 138 val = -val; 139 neg = 1; 140 } 141 142 res = ff_wp_exp2_table[val & 0xFF] | 0x100; 143 val >>= 8; 144 if (val > 31U) 145 return INT_MIN; 146 res = (val > 9) ? (res << (val - 9)) : (res >> (9 - val)); 147 return neg ? -res : res; 148} 149 150static av_always_inline int wp_log2(uint32_t val) 151{ 152 int bits; 153 154 if (!val) 155 return 0; 156 if (val == 1) 157 return 256; 158 val += val >> 9; 159 bits = av_log2(val) + 1; 160 if (bits < 9) 161 return (bits << 8) + ff_wp_log2_table[(val << (9 - bits)) & 0xFF]; 162 else 163 return (bits << 8) + ff_wp_log2_table[(val >> (bits - 9)) & 0xFF]; 164} 165 166#endif /* AVCODEC_WAVPACK_H */ 167