annotate wmavoice.c @ 11211:dfeaae916502 libavcodec

Since WavPack chunk can contain more samples than FFmpeg is guaranteed to hold, decode it in several iterations outputting as many samples as possible.
author kostya
date Fri, 19 Feb 2010 14:05:41 +0000
parents d59349627f52
children b94e1810ce4c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11123
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1 /*
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
2 * Windows Media Audio Voice decoder.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
3 * Copyright (c) 2009 Ronald S. Bultje
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
4 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
5 * This file is part of FFmpeg.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
6 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
11 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
15 * Lesser General Public License for more details.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
16 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
20 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
21
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
22 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
23 * @file libavcodec/wmavoice.c
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
24 * @brief Windows Media Audio Voice compatible decoder
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
25 * @author Ronald S. Bultje <rsbultje@gmail.com>
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
26 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
27
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
28 #include <math.h>
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
29 #include "avcodec.h"
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
30 #include "get_bits.h"
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
31 #include "put_bits.h"
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
32 #include "wmavoice_data.h"
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
33 #include "celp_math.h"
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
34 #include "celp_filters.h"
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
35 #include "acelp_vectors.h"
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
36 #include "acelp_filters.h"
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
37 #include "lsp.h"
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
38 #include "libavutil/lzo.h"
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
39
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
40 #define MAX_BLOCKS 8 ///< maximum number of blocks per frame
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
41 #define MAX_LSPS 16 ///< maximum filter order
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
42 #define MAX_FRAMES 3 ///< maximum number of frames per superframe
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
43 #define MAX_FRAMESIZE 160 ///< maximum number of samples per frame
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
44 #define MAX_SIGNAL_HISTORY 416 ///< maximum excitation signal history
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
45 #define MAX_SFRAMESIZE (MAX_FRAMESIZE * MAX_FRAMES)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
46 ///< maximum number of samples per superframe
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
47 #define SFRAME_CACHE_MAXSIZE 256 ///< maximum cache size for frame data that
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
48 ///< was split over two packets
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
49 #define VLC_NBITS 6 ///< number of bits to read per VLC iteration
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
50
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
51 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
52 * Frame type VLC coding.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
53 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
54 static VLC frame_type_vlc;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
55
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
56 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
57 * Adaptive codebook types.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
58 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
59 enum {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
60 ACB_TYPE_NONE = 0, ///< no adaptive codebook (only hardcoded fixed)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
61 ACB_TYPE_ASYMMETRIC = 1, ///< adaptive codebook with per-frame pitch, which
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
62 ///< we interpolate to get a per-sample pitch.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
63 ///< Signal is generated using an asymmetric sinc
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
64 ///< window function
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
65 ///< @note see #wmavoice_ipol1_coeffs
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
66 ACB_TYPE_HAMMING = 2 ///< Per-block pitch with signal generation using
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
67 ///< a Hamming sinc window function
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
68 ///< @note see #wmavoice_ipol2_coeffs
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
69 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
70
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
71 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
72 * Fixed codebook types.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
73 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
74 enum {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
75 FCB_TYPE_SILENCE = 0, ///< comfort noise during silence
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
76 ///< generated from a hardcoded (fixed) codebook
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
77 ///< with per-frame (low) gain values
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
78 FCB_TYPE_HARDCODED = 1, ///< hardcoded (fixed) codebook with per-block
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
79 ///< gain values
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
80 FCB_TYPE_AW_PULSES = 2, ///< Pitch-adaptive window (AW) pulse signals,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
81 ///< used in particular for low-bitrate streams
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
82 FCB_TYPE_EXC_PULSES = 3, ///< Innovation (fixed) codebook pulse sets in
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
83 ///< combinations of either single pulses or
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
84 ///< pulse pairs
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
85 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
86
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
87 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
88 * Description of frame types.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
89 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
90 static const struct frame_type_desc {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
91 uint8_t n_blocks; ///< amount of blocks per frame (each block
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
92 ///< (contains 160/#n_blocks samples)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
93 uint8_t log_n_blocks; ///< log2(#n_blocks)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
94 uint8_t acb_type; ///< Adaptive codebook type (ACB_TYPE_*)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
95 uint8_t fcb_type; ///< Fixed codebook type (FCB_TYPE_*)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
96 uint8_t dbl_pulses; ///< how many pulse vectors have pulse pairs
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
97 ///< (rather than just one single pulse)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
98 ///< only if #fcb_type == #FCB_TYPE_EXC_PULSES
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
99 uint16_t frame_size; ///< the amount of bits that make up the block
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
100 ///< data (per frame)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
101 } frame_descs[17] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
102 { 1, 0, ACB_TYPE_NONE, FCB_TYPE_SILENCE, 0, 0 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
103 { 2, 1, ACB_TYPE_NONE, FCB_TYPE_HARDCODED, 0, 28 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
104 { 2, 1, ACB_TYPE_ASYMMETRIC, FCB_TYPE_AW_PULSES, 0, 46 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
105 { 2, 1, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 2, 80 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
106 { 2, 1, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 5, 104 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
107 { 4, 2, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 0, 108 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
108 { 4, 2, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 2, 132 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
109 { 4, 2, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 5, 168 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
110 { 2, 1, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 0, 64 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
111 { 2, 1, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 2, 80 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
112 { 2, 1, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 5, 104 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
113 { 4, 2, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 0, 108 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
114 { 4, 2, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 2, 132 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
115 { 4, 2, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 5, 168 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
116 { 8, 3, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 0, 176 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
117 { 8, 3, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 2, 208 },
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
118 { 8, 3, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 5, 256 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
119 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
120
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
121 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
122 * WMA Voice decoding context.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
123 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
124 typedef struct {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
125 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
126 * @defgroup struct_global Global values
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
127 * Global values, specified in the stream header / extradata or used
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
128 * all over.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
129 * @{
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
130 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
131 GetBitContext gb; ///< packet bitreader. During decoder init,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
132 ///< it contains the extradata from the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
133 ///< demuxer. During decoding, it contains
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
134 ///< packet data.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
135 int8_t vbm_tree[25]; ///< converts VLC codes to frame type
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
136
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
137 int spillover_bitsize; ///< number of bits used to specify
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
138 ///< #spillover_nbits in the packet header
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
139 ///< = ceil(log2(ctx->block_align << 3))
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
140 int history_nsamples; ///< number of samples in history for signal
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
141 ///< prediction (through ACB)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
142
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
143 int do_apf; ///< whether to apply the averaged
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
144 ///< projection filter (APF)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
145
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
146 int lsps; ///< number of LSPs per frame [10 or 16]
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
147 int lsp_q_mode; ///< defines quantizer defaults [0, 1]
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
148 int lsp_def_mode; ///< defines different sets of LSP defaults
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
149 ///< [0, 1]
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
150 int frame_lsp_bitsize; ///< size (in bits) of LSPs, when encoded
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
151 ///< per-frame (independent coding)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
152 int sframe_lsp_bitsize; ///< size (in bits) of LSPs, when encoded
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
153 ///< per superframe (residual coding)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
154
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
155 int min_pitch_val; ///< base value for pitch parsing code
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
156 int max_pitch_val; ///< max value + 1 for pitch parsing
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
157 int pitch_nbits; ///< number of bits used to specify the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
158 ///< pitch value in the frame header
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
159 int block_pitch_nbits; ///< number of bits used to specify the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
160 ///< first block's pitch value
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
161 int block_pitch_range; ///< range of the block pitch
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
162 int block_delta_pitch_nbits; ///< number of bits used to specify the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
163 ///< delta pitch between this and the last
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
164 ///< block's pitch value, used in all but
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
165 ///< first block
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
166 int block_delta_pitch_hrange; ///< 1/2 range of the delta (full range is
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
167 ///< from -this to +this-1)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
168 uint16_t block_conv_table[4]; ///< boundaries for block pitch unit/scale
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
169 ///< conversion
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
170
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
171 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
172 * @}
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
173 * @defgroup struct_packet Packet values
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
174 * Packet values, specified in the packet header or related to a packet.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
175 * A packet is considered to be a single unit of data provided to this
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
176 * decoder by the demuxer.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
177 * @{
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
178 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
179 int spillover_nbits; ///< number of bits of the previous packet's
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
180 ///< last superframe preceeding this
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
181 ///< packet's first full superframe (useful
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
182 ///< for re-synchronization also)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
183 int has_residual_lsps; ///< if set, superframes contain one set of
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
184 ///< LSPs that cover all frames, encoded as
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
185 ///< independent and residual LSPs; if not
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
186 ///< set, each frame contains its own, fully
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
187 ///< independent, LSPs
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
188 int skip_bits_next; ///< number of bits to skip at the next call
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
189 ///< to #wmavoice_decode_packet() (since
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
190 ///< they're part of the previous superframe)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
191
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
192 uint8_t sframe_cache[SFRAME_CACHE_MAXSIZE + FF_INPUT_BUFFER_PADDING_SIZE];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
193 ///< cache for superframe data split over
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
194 ///< multiple packets
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
195 int sframe_cache_size; ///< set to >0 if we have data from an
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
196 ///< (incomplete) superframe from a previous
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
197 ///< packet that spilled over in the current
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
198 ///< packet; specifies the amount of bits in
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
199 ///< #sframe_cache
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
200 PutBitContext pb; ///< bitstream writer for #sframe_cache
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
201
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
202 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
203 * @}
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
204 * @defgroup struct_frame Frame and superframe values
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
205 * Superframe and frame data - these can change from frame to frame,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
206 * although some of them do in that case serve as a cache / history for
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
207 * the next frame or superframe.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
208 * @{
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
209 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
210 double prev_lsps[MAX_LSPS]; ///< LSPs of the last frame of the previous
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
211 ///< superframe
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
212 int last_pitch_val; ///< pitch value of the previous frame
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
213 int last_acb_type; ///< frame type [0-2] of the previous frame
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
214 int pitch_diff_sh16; ///< ((cur_pitch_val - #last_pitch_val)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
215 ///< << 16) / #MAX_FRAMESIZE
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
216 float silence_gain; ///< set for use in blocks if #ACB_TYPE_NONE
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
217
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
218 int aw_idx_is_ext; ///< whether the AW index was encoded in
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
219 ///< 8 bits (instead of 6)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
220 int aw_pulse_range; ///< the range over which #aw_pulse_set1()
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
221 ///< can apply the pulse, relative to the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
222 ///< value in aw_first_pulse_off. The exact
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
223 ///< position of the first AW-pulse is within
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
224 ///< [pulse_off, pulse_off + this], and
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
225 ///< depends on bitstream values; [16 or 24]
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
226 int aw_n_pulses[2]; ///< number of AW-pulses in each block; note
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
227 ///< that this number can be negative (in
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
228 ///< which case it basically means "zero")
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
229 int aw_first_pulse_off[2]; ///< index of first sample to which to
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
230 ///< apply AW-pulses, or -0xff if unset
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
231 int aw_next_pulse_off_cache; ///< the position (relative to start of the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
232 ///< second block) at which pulses should
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
233 ///< start to be positioned, serves as a
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
234 ///< cache for pitch-adaptive window pulses
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
235 ///< between blocks
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
236
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
237 int frame_cntr; ///< current frame index [0 - 0xFFFE]; is
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
238 ///< only used for comfort noise in #pRNG()
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
239 float gain_pred_err[6]; ///< cache for gain prediction
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
240 float excitation_history[MAX_SIGNAL_HISTORY];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
241 ///< cache of the signal of previous
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
242 ///< superframes, used as a history for
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
243 ///< signal generation
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
244 float synth_history[MAX_LSPS]; ///< see #excitation_history
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
245 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
246 * @}
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
247 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
248 } WMAVoiceContext;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
249
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
250 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
251 * Sets up the variable bit mode (VBM) tree from container extradata.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
252 * @param gb bit I/O context.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
253 * The bit context (s->gb) should be loaded with byte 23-46 of the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
254 * container extradata (i.e. the ones containing the VBM tree).
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
255 * @param vbm_tree pointer to array to which the decoded VBM tree will be
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
256 * written.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
257 * @return 0 on success, <0 on error.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
258 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
259 static av_cold int decode_vbmtree(GetBitContext *gb, int8_t vbm_tree[25])
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
260 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
261 static const uint8_t bits[] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
262 2, 2, 2, 4, 4, 4,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
263 6, 6, 6, 8, 8, 8,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
264 10, 10, 10, 12, 12, 12,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
265 14, 14, 14, 14
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
266 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
267 static const uint16_t codes[] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
268 0x0000, 0x0001, 0x0002, // 00/01/10
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
269 0x000c, 0x000d, 0x000e, // 11+00/01/10
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
270 0x003c, 0x003d, 0x003e, // 1111+00/01/10
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
271 0x00fc, 0x00fd, 0x00fe, // 111111+00/01/10
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
272 0x03fc, 0x03fd, 0x03fe, // 11111111+00/01/10
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
273 0x0ffc, 0x0ffd, 0x0ffe, // 1111111111+00/01/10
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
274 0x3ffc, 0x3ffd, 0x3ffe, 0x3fff // 111111111111+xx
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
275 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
276 int cntr[8], n, res;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
277
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
278 memset(vbm_tree, 0xff, sizeof(vbm_tree));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
279 memset(cntr, 0, sizeof(cntr));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
280 for (n = 0; n < 17; n++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
281 res = get_bits(gb, 3);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
282 if (cntr[res] > 3) // should be >= 3 + (res == 7))
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
283 return -1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
284 vbm_tree[res * 3 + cntr[res]++] = n;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
285 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
286 INIT_VLC_STATIC(&frame_type_vlc, VLC_NBITS, sizeof(bits),
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
287 bits, 1, 1, codes, 2, 2, 132);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
288 return 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
289 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
290
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
291 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
292 * Set up decoder with parameters from demuxer (extradata etc.).
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
293 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
294 static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
295 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
296 int n, flags, pitch_range, lsp16_flag;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
297 WMAVoiceContext *s = ctx->priv_data;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
298
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
299 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
300 * Extradata layout:
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
301 * - byte 0-18: WMAPro-in-WMAVoice extradata (see wmaprodec.c),
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
302 * - byte 19-22: flags field (annoyingly in LE; see below for known
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
303 * values),
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
304 * - byte 23-46: variable bitmode tree (really just 17 * 3 bits,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
305 * rest is 0).
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
306 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
307 if (ctx->extradata_size != 46) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
308 av_log(ctx, AV_LOG_ERROR,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
309 "Invalid extradata size %d (should be 46)\n",
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
310 ctx->extradata_size);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
311 return -1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
312 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
313 flags = AV_RL32(ctx->extradata + 18);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
314 s->spillover_bitsize = 3 + av_ceil_log2(ctx->block_align);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
315 s->do_apf = flags & 0x1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
316 s->lsp_q_mode = !!(flags & 0x2000);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
317 s->lsp_def_mode = !!(flags & 0x4000);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
318 lsp16_flag = flags & 0x1000;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
319 if (lsp16_flag) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
320 s->lsps = 16;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
321 s->frame_lsp_bitsize = 34;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
322 s->sframe_lsp_bitsize = 60;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
323 } else {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
324 s->lsps = 10;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
325 s->frame_lsp_bitsize = 24;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
326 s->sframe_lsp_bitsize = 48;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
327 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
328 for (n = 0; n < s->lsps; n++)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
329 s->prev_lsps[n] = M_PI * (n + 1.0) / (s->lsps + 1.0);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
330
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
331 init_get_bits(&s->gb, ctx->extradata + 22, (ctx->extradata_size - 22) << 3);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
332 if (decode_vbmtree(&s->gb, s->vbm_tree) < 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
333 av_log(ctx, AV_LOG_ERROR, "Invalid VBM tree; broken extradata?\n");
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
334 return -1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
335 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
336
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
337 s->min_pitch_val = ((ctx->sample_rate << 8) / 400 + 50) >> 8;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
338 s->max_pitch_val = ((ctx->sample_rate << 8) * 37 / 2000 + 50) >> 8;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
339 pitch_range = s->max_pitch_val - s->min_pitch_val;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
340 s->pitch_nbits = av_ceil_log2(pitch_range);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
341 s->last_pitch_val = 40;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
342 s->last_acb_type = ACB_TYPE_NONE;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
343 s->history_nsamples = s->max_pitch_val + 8;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
344
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
345 if (s->min_pitch_val < 1 || s->history_nsamples > MAX_SIGNAL_HISTORY) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
346 int min_sr = ((((1 << 8) - 50) * 400) + 0xFF) >> 8,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
347 max_sr = ((((MAX_SIGNAL_HISTORY - 8) << 8) + 205) * 2000 / 37) >> 8;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
348
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
349 av_log(ctx, AV_LOG_ERROR,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
350 "Unsupported samplerate %d (min=%d, max=%d)\n",
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
351 ctx->sample_rate, min_sr, max_sr); // 322-22097 Hz
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
352
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
353 return -1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
354 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
355
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
356 s->block_conv_table[0] = s->min_pitch_val;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
357 s->block_conv_table[1] = (pitch_range * 25) >> 6;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
358 s->block_conv_table[2] = (pitch_range * 44) >> 6;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
359 s->block_conv_table[3] = s->max_pitch_val - 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
360 s->block_delta_pitch_hrange = (pitch_range >> 3) & ~0xF;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
361 s->block_delta_pitch_nbits = 1 + av_ceil_log2(s->block_delta_pitch_hrange);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
362 s->block_pitch_range = s->block_conv_table[2] +
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
363 s->block_conv_table[3] + 1 +
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
364 2 * (s->block_conv_table[1] - 2 * s->min_pitch_val);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
365 s->block_pitch_nbits = av_ceil_log2(s->block_pitch_range);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
366
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
367 ctx->sample_fmt = SAMPLE_FMT_FLT;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
368
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
369 return 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
370 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
371
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
372 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
373 * Dequantize LSPs
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
374 * @param lsps output pointer to the array that will hold the LSPs
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
375 * @param num number of LSPs to be dequantized
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
376 * @param values quantized values, contains n_stages values
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
377 * @param sizes range (i.e. max value) of each quantized value
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
378 * @param n_stages number of dequantization runs
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
379 * @param table dequantization table to be used
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
380 * @param mul_q LSF multiplier
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
381 * @param base_q base (lowest) LSF values
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
382 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
383 static void dequant_lsps(double *lsps, int num,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
384 const uint16_t *values,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
385 const uint16_t *sizes,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
386 int n_stages, const uint8_t *table,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
387 const double *mul_q,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
388 const double *base_q)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
389 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
390 int n, m;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
391
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
392 memset(lsps, 0, num * sizeof(*lsps));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
393 for (n = 0; n < n_stages; n++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
394 const uint8_t *t_off = &table[values[n] * num];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
395 double base = base_q[n], mul = mul_q[n];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
396
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
397 for (m = 0; m < num; m++)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
398 lsps[m] += base + mul * t_off[m];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
399
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
400 table += sizes[n] * num;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
401 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
402 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
403
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
404 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
405 * @defgroup lsp_dequant LSP dequantization routines
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
406 * LSP dequantization routines, for 10/16LSPs and independent/residual coding.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
407 * @note we assume enough bits are available, caller should check.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
408 * lsp10i() consumes 24 bits; lsp10r() consumes an additional 24 bits;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
409 * lsp16i() consumes 34 bits; lsp16r() consumes an additional 26 bits.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
410 * @{
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
411 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
412 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
413 * Parse 10 independently-coded LSPs.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
414 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
415 static void dequant_lsp10i(GetBitContext *gb, double *lsps)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
416 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
417 static const uint16_t vec_sizes[4] = { 256, 64, 32, 32 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
418 static const double mul_lsf[4] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
419 5.2187144800e-3, 1.4626986422e-3,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
420 9.6179549166e-4, 1.1325736225e-3
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
421 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
422 static const double base_lsf[4] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
423 M_PI * -2.15522e-1, M_PI * -6.1646e-2,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
424 M_PI * -3.3486e-2, M_PI * -5.7408e-2
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
425 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
426 uint16_t v[4];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
427
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
428 v[0] = get_bits(gb, 8);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
429 v[1] = get_bits(gb, 6);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
430 v[2] = get_bits(gb, 5);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
431 v[3] = get_bits(gb, 5);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
432
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
433 dequant_lsps(lsps, 10, v, vec_sizes, 4, wmavoice_dq_lsp10i,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
434 mul_lsf, base_lsf);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
435 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
436
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
437 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
438 * Parse 10 independently-coded LSPs, and then derive the tables to
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
439 * generate LSPs for the other frames from them (residual coding).
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
440 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
441 static void dequant_lsp10r(GetBitContext *gb,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
442 double *i_lsps, const double *old,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
443 double *a1, double *a2, int q_mode)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
444 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
445 static const uint16_t vec_sizes[3] = { 128, 64, 64 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
446 static const double mul_lsf[3] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
447 2.5807601174e-3, 1.2354460219e-3, 1.1763821673e-3
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
448 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
449 static const double base_lsf[3] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
450 M_PI * -1.07448e-1, M_PI * -5.2706e-2, M_PI * -5.1634e-2
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
451 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
452 const float (*ipol_tab)[2][10] = q_mode ?
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
453 wmavoice_lsp10_intercoeff_b : wmavoice_lsp10_intercoeff_a;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
454 uint16_t interpol, v[3];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
455 int n;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
456
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
457 dequant_lsp10i(gb, i_lsps);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
458
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
459 interpol = get_bits(gb, 5);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
460 v[0] = get_bits(gb, 7);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
461 v[1] = get_bits(gb, 6);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
462 v[2] = get_bits(gb, 6);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
463
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
464 for (n = 0; n < 10; n++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
465 double delta = old[n] - i_lsps[n];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
466 a1[n] = ipol_tab[interpol][0][n] * delta + i_lsps[n];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
467 a1[10 + n] = ipol_tab[interpol][1][n] * delta + i_lsps[n];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
468 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
469
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
470 dequant_lsps(a2, 20, v, vec_sizes, 3, wmavoice_dq_lsp10r,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
471 mul_lsf, base_lsf);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
472 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
473
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
474 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
475 * Parse 16 independently-coded LSPs.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
476 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
477 static void dequant_lsp16i(GetBitContext *gb, double *lsps)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
478 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
479 static const uint16_t vec_sizes[5] = { 256, 64, 128, 64, 128 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
480 static const double mul_lsf[5] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
481 3.3439586280e-3, 6.9908173703e-4,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
482 3.3216608306e-3, 1.0334960326e-3,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
483 3.1899104283e-3
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
484 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
485 static const double base_lsf[5] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
486 M_PI * -1.27576e-1, M_PI * -2.4292e-2,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
487 M_PI * -1.28094e-1, M_PI * -3.2128e-2,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
488 M_PI * -1.29816e-1
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
489 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
490 uint16_t v[5];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
491
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
492 v[0] = get_bits(gb, 8);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
493 v[1] = get_bits(gb, 6);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
494 v[2] = get_bits(gb, 7);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
495 v[3] = get_bits(gb, 6);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
496 v[4] = get_bits(gb, 7);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
497
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
498 dequant_lsps( lsps, 5, v, vec_sizes, 2,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
499 wmavoice_dq_lsp16i1, mul_lsf, base_lsf);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
500 dequant_lsps(&lsps[5], 5, &v[2], &vec_sizes[2], 2,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
501 wmavoice_dq_lsp16i2, &mul_lsf[2], &base_lsf[2]);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
502 dequant_lsps(&lsps[10], 6, &v[4], &vec_sizes[4], 1,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
503 wmavoice_dq_lsp16i3, &mul_lsf[4], &base_lsf[4]);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
504 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
505
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
506 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
507 * Parse 16 independently-coded LSPs, and then derive the tables to
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
508 * generate LSPs for the other frames from them (residual coding).
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
509 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
510 static void dequant_lsp16r(GetBitContext *gb,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
511 double *i_lsps, const double *old,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
512 double *a1, double *a2, int q_mode)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
513 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
514 static const uint16_t vec_sizes[3] = { 128, 128, 128 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
515 static const double mul_lsf[3] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
516 1.2232979501e-3, 1.4062241527e-3, 1.6114744851e-3
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
517 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
518 static const double base_lsf[3] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
519 M_PI * -5.5830e-2, M_PI * -5.2908e-2, M_PI * -5.4776e-2
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
520 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
521 const float (*ipol_tab)[2][16] = q_mode ?
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
522 wmavoice_lsp16_intercoeff_b : wmavoice_lsp16_intercoeff_a;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
523 uint16_t interpol, v[3];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
524 int n;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
525
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
526 dequant_lsp16i(gb, i_lsps);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
527
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
528 interpol = get_bits(gb, 5);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
529 v[0] = get_bits(gb, 7);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
530 v[1] = get_bits(gb, 7);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
531 v[2] = get_bits(gb, 7);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
532
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
533 for (n = 0; n < 16; n++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
534 double delta = old[n] - i_lsps[n];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
535 a1[n] = ipol_tab[interpol][0][n] * delta + i_lsps[n];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
536 a1[16 + n] = ipol_tab[interpol][1][n] * delta + i_lsps[n];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
537 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
538
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
539 dequant_lsps( a2, 10, v, vec_sizes, 1,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
540 wmavoice_dq_lsp16r1, mul_lsf, base_lsf);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
541 dequant_lsps(&a2[10], 10, &v[1], &vec_sizes[1], 1,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
542 wmavoice_dq_lsp16r2, &mul_lsf[1], &base_lsf[1]);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
543 dequant_lsps(&a2[20], 12, &v[2], &vec_sizes[2], 1,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
544 wmavoice_dq_lsp16r3, &mul_lsf[2], &base_lsf[2]);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
545 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
546
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
547 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
548 * @}
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
549 * @defgroup aw Pitch-adaptive window coding functions
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
550 * The next few functions are for pitch-adaptive window coding.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
551 * @{
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
552 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
553 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
554 * Parse the offset of the first pitch-adaptive window pulses, and
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
555 * the distribution of pulses between the two blocks in this frame.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
556 * @param s WMA Voice decoding context private data
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
557 * @param gb bit I/O context
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
558 * @param pitch pitch for each block in this frame
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
559 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
560 static void aw_parse_coords(WMAVoiceContext *s, GetBitContext *gb,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
561 const int *pitch)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
562 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
563 static const int16_t start_offset[94] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
564 -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
565 13, 15, 18, 17, 19, 20, 21, 22, 23, 24, 25, 26,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
566 27, 28, 29, 30, 31, 32, 33, 35, 37, 39, 41, 43,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
567 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
568 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
569 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, 115,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
570 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
571 141, 143, 145, 147, 149, 151, 153, 155, 157, 159
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
572 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
573 int bits, offset;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
574
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
575 /* position of pulse */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
576 s->aw_idx_is_ext = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
577 if ((bits = get_bits(gb, 6)) >= 54) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
578 s->aw_idx_is_ext = 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
579 bits += (bits - 54) * 3 + get_bits(gb, 2);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
580 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
581
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
582 /* for a repeated pulse at pulse_off with a pitch_lag of pitch[], count
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
583 * the distribution of the pulses in each block contained in this frame. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
584 s->aw_pulse_range = FFMIN(pitch[0], pitch[1]) > 32 ? 24 : 16;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
585 for (offset = start_offset[bits]; offset < 0; offset += pitch[0]) ;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
586 s->aw_n_pulses[0] = (pitch[0] - 1 + MAX_FRAMESIZE / 2 - offset) / pitch[0];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
587 s->aw_first_pulse_off[0] = offset - s->aw_pulse_range / 2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
588 offset += s->aw_n_pulses[0] * pitch[0];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
589 s->aw_n_pulses[1] = (pitch[1] - 1 + MAX_FRAMESIZE - offset) / pitch[1];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
590 s->aw_first_pulse_off[1] = offset - (MAX_FRAMESIZE + s->aw_pulse_range) / 2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
591
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
592 /* if continuing from a position before the block, reset position to
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
593 * start of block (when corrected for the range over which it can be
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
594 * spread in aw_pulse_set1()). */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
595 if (start_offset[bits] < MAX_FRAMESIZE / 2) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
596 while (s->aw_first_pulse_off[1] - pitch[1] + s->aw_pulse_range > 0)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
597 s->aw_first_pulse_off[1] -= pitch[1];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
598 if (start_offset[bits] < 0)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
599 while (s->aw_first_pulse_off[0] - pitch[0] + s->aw_pulse_range > 0)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
600 s->aw_first_pulse_off[0] -= pitch[0];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
601 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
602 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
603
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
604 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
605 * Apply second set of pitch-adaptive window pulses.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
606 * @param s WMA Voice decoding context private data
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
607 * @param gb bit I/O context
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
608 * @param block_idx block index in frame [0, 1]
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
609 * @param fcb structure containing fixed codebook vector info
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
610 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
611 static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
612 int block_idx, AMRFixed *fcb)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
613 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
614 uint16_t use_mask[7]; // only 5 are used, rest is padding
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
615 /* in this function, idx is the index in the 80-bit (+ padding) use_mask
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
616 * bit-array. Since use_mask consists of 16-bit values, the lower 4 bits
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
617 * of idx are the position of the bit within a particular item in the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
618 * array (0 being the most significant bit, and 15 being the least
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
619 * significant bit), and the remainder (>> 4) is the index in the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
620 * use_mask[]-array. This is faster and uses less memory than using a
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
621 * 80-byte/80-int array. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
622 int pulse_off = s->aw_first_pulse_off[block_idx],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
623 pulse_start, n, idx, range, aidx, start_off = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
624
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
625 /* set offset of first pulse to within this block */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
626 if (s->aw_n_pulses[block_idx] > 0)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
627 while (pulse_off + s->aw_pulse_range < 1)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
628 pulse_off += fcb->pitch_lag;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
629
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
630 /* find range per pulse */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
631 if (s->aw_n_pulses[0] > 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
632 if (block_idx == 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
633 range = 32;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
634 } else /* block_idx = 1 */ {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
635 range = 8;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
636 if (s->aw_n_pulses[block_idx] > 0)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
637 pulse_off = s->aw_next_pulse_off_cache;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
638 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
639 } else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
640 range = 16;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
641 pulse_start = s->aw_n_pulses[block_idx] > 0 ? pulse_off - range / 2 : 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
642
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
643 /* aw_pulse_set1() already applies pulses around pulse_off (to be exactly,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
644 * in the range of [pulse_off, pulse_off + s->aw_pulse_range], and thus
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
645 * we exclude that range from being pulsed again in this function. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
646 memset( use_mask, -1, 5 * sizeof(use_mask[0]));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
647 memset(&use_mask[5], 0, 2 * sizeof(use_mask[0]));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
648 if (s->aw_n_pulses[block_idx] > 0)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
649 for (idx = pulse_off; idx < MAX_FRAMESIZE / 2; idx += fcb->pitch_lag) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
650 int excl_range = s->aw_pulse_range; // always 16 or 24
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
651 uint16_t *use_mask_ptr = &use_mask[idx >> 4];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
652 int first_sh = 16 - (idx & 15);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
653 *use_mask_ptr++ &= 0xFFFF << first_sh;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
654 excl_range -= first_sh;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
655 if (excl_range >= 16) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
656 *use_mask_ptr++ = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
657 *use_mask_ptr &= 0xFFFF >> (excl_range - 16);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
658 } else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
659 *use_mask_ptr &= 0xFFFF >> excl_range;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
660 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
661
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
662 /* find the 'aidx'th offset that is not excluded */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
663 aidx = get_bits(gb, s->aw_n_pulses[0] > 0 ? 5 - 2 * block_idx : 4);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
664 for (n = 0; n <= aidx; pulse_start++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
665 for (idx = pulse_start; idx < 0; idx += fcb->pitch_lag) ;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
666 if (idx >= MAX_FRAMESIZE / 2) { // find from zero
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
667 if (use_mask[0]) idx = 0x0F;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
668 else if (use_mask[1]) idx = 0x1F;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
669 else if (use_mask[2]) idx = 0x2F;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
670 else if (use_mask[3]) idx = 0x3F;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
671 else if (use_mask[4]) idx = 0x4F;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
672 else return;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
673 idx -= av_log2_16bit(use_mask[idx >> 4]);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
674 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
675 if (use_mask[idx >> 4] & (0x8000 >> (idx & 15))) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
676 use_mask[idx >> 4] &= ~(0x8000 >> (idx & 15));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
677 n++;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
678 start_off = idx;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
679 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
680 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
681
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
682 fcb->x[fcb->n] = start_off;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
683 fcb->y[fcb->n] = get_bits1(gb) ? -1.0 : 1.0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
684 fcb->n++;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
685
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
686 /* set offset for next block, relative to start of that block */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
687 n = (MAX_FRAMESIZE / 2 - start_off) % fcb->pitch_lag;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
688 s->aw_next_pulse_off_cache = n ? fcb->pitch_lag - n : 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
689 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
690
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
691 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
692 * Apply first set of pitch-adaptive window pulses.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
693 * @param s WMA Voice decoding context private data
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
694 * @param gb bit I/O context
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
695 * @param block_idx block index in frame [0, 1]
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
696 * @param fcb storage location for fixed codebook pulse info
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
697 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
698 static void aw_pulse_set1(WMAVoiceContext *s, GetBitContext *gb,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
699 int block_idx, AMRFixed *fcb)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
700 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
701 int val = get_bits(gb, 12 - 2 * (s->aw_idx_is_ext && !block_idx));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
702 float v;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
703
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
704 if (s->aw_n_pulses[block_idx] > 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
705 int n, v_mask, i_mask, sh, n_pulses;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
706
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
707 if (s->aw_pulse_range == 24) { // 3 pulses, 1:sign + 3:index each
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
708 n_pulses = 3;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
709 v_mask = 8;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
710 i_mask = 7;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
711 sh = 4;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
712 } else { // 4 pulses, 1:sign + 2:index each
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
713 n_pulses = 4;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
714 v_mask = 4;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
715 i_mask = 3;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
716 sh = 3;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
717 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
718
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
719 for (n = n_pulses - 1; n >= 0; n--, val >>= sh) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
720 fcb->y[fcb->n] = (val & v_mask) ? -1.0 : 1.0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
721 fcb->x[fcb->n] = (val & i_mask) * n_pulses + n +
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
722 s->aw_first_pulse_off[block_idx];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
723 while (fcb->x[fcb->n] < 0)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
724 fcb->x[fcb->n] += fcb->pitch_lag;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
725 if (fcb->x[fcb->n] < MAX_FRAMESIZE / 2)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
726 fcb->n++;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
727 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
728 } else {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
729 int num2 = (val & 0x1FF) >> 1, delta, idx;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
730
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
731 if (num2 < 1 * 79) { delta = 1; idx = num2 + 1; }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
732 else if (num2 < 2 * 78) { delta = 3; idx = num2 + 1 - 1 * 77; }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
733 else if (num2 < 3 * 77) { delta = 5; idx = num2 + 1 - 2 * 76; }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
734 else { delta = 7; idx = num2 + 1 - 3 * 75; }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
735 v = (val & 0x200) ? -1.0 : 1.0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
736
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
737 fcb->no_repeat_mask |= 3 << fcb->n;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
738 fcb->x[fcb->n] = idx - delta;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
739 fcb->y[fcb->n] = v;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
740 fcb->x[fcb->n + 1] = idx;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
741 fcb->y[fcb->n + 1] = (val & 1) ? -v : v;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
742 fcb->n += 2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
743 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
744 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
745
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
746 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
747 * @}
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
748 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
749 * Generate a random number from frame_cntr and block_idx, which will lief
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
750 * in the range [0, 1000 - block_size] (so it can be used as an index in a
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
751 * table of size 1000 of which you want to read block_size entries).
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
752 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
753 * @param frame_cntr current frame number
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
754 * @param block_num current block index
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
755 * @param block_size amount of entries we want to read from a table
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
756 * that has 1000 entries
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
757 * @returns a (non-)random number in the [0, 1000 - block_size] range.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
758 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
759 static int pRNG(int frame_cntr, int block_num, int block_size)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
760 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
761 /* array to simplify the calculation of z:
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
762 * y = (x % 9) * 5 + 6;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
763 * z = (49995 * x) / y;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
764 * Since y only has 9 values, we can remove the division by using a
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
765 * LUT and using FASTDIV-style divisions. For each of the 9 values
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
766 * of y, we can rewrite z as:
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
767 * z = x * (49995 / y) + x * ((49995 % y) / y)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
768 * In this table, each col represents one possible value of y, the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
769 * first number is 49995 / y, and the second is the FASTDIV variant
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
770 * of 49995 % y / y. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
771 static const unsigned int div_tbl[9][2] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
772 { 8332, 3 * 715827883U }, // y = 6
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
773 { 4545, 0 * 390451573U }, // y = 11
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
774 { 3124, 11 * 268435456U }, // y = 16
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
775 { 2380, 15 * 204522253U }, // y = 21
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
776 { 1922, 23 * 165191050U }, // y = 26
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
777 { 1612, 23 * 138547333U }, // y = 31
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
778 { 1388, 27 * 119304648U }, // y = 36
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
779 { 1219, 16 * 104755300U }, // y = 41
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
780 { 1086, 39 * 93368855U } // y = 46
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
781 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
782 unsigned int z, y, x = MUL16(block_num, 1877) + frame_cntr;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
783 if (x >= 0xFFFF) x -= 0xFFFF; // max value of x is 8*1877+0xFFFE=0x13AA6,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
784 // so this is effectively a modulo (%)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
785 y = x - 9 * MULH(477218589, x); // x % 9
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
786 z = (uint16_t) (x * div_tbl[y][0] + UMULH(x, div_tbl[y][1]));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
787 // z = x * 49995 / (y * 5 + 6)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
788 return z % (1000 - block_size);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
789 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
790
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
791 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
792 * Parse hardcoded signal for a single block.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
793 * @note see #synth_block().
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
794 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
795 static void synth_block_hardcoded(WMAVoiceContext *s, GetBitContext *gb,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
796 int block_idx, int size,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
797 const struct frame_type_desc *frame_desc,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
798 float *excitation)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
799 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
800 float gain;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
801 int n, r_idx;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
802
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
803 assert(size <= MAX_FRAMESIZE);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
804
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
805 /* Set the offset from which we start reading wmavoice_std_codebook */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
806 if (frame_desc->fcb_type == FCB_TYPE_SILENCE) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
807 r_idx = pRNG(s->frame_cntr, block_idx, size);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
808 gain = s->silence_gain;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
809 } else /* FCB_TYPE_HARDCODED */ {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
810 r_idx = get_bits(gb, 8);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
811 gain = wmavoice_gain_universal[get_bits(gb, 6)];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
812 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
813
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
814 /* Clear gain prediction parameters */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
815 memset(s->gain_pred_err, 0, sizeof(s->gain_pred_err));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
816
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
817 /* Apply gain to hardcoded codebook and use that as excitation signal */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
818 for (n = 0; n < size; n++)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
819 excitation[n] = wmavoice_std_codebook[r_idx + n] * gain;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
820 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
821
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
822 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
823 * Parse FCB/ACB signal for a single block.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
824 * @note see #synth_block().
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
825 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
826 static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
827 int block_idx, int size,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
828 int block_pitch_sh2,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
829 const struct frame_type_desc *frame_desc,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
830 float *excitation)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
831 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
832 static const float gain_coeff[6] = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
833 0.8169, -0.06545, 0.1726, 0.0185, -0.0359, 0.0458
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
834 };
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
835 float pulses[MAX_FRAMESIZE / 2], pred_err, acb_gain, fcb_gain;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
836 int n, idx, gain_weight;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
837 AMRFixed fcb;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
838
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
839 assert(size <= MAX_FRAMESIZE / 2);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
840 memset(pulses, 0, sizeof(*pulses) * size);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
841
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
842 fcb.pitch_lag = block_pitch_sh2 >> 2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
843 fcb.pitch_fac = 1.0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
844 fcb.no_repeat_mask = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
845 fcb.n = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
846
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
847 /* For the other frame types, this is where we apply the innovation
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
848 * (fixed) codebook pulses of the speech signal. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
849 if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
850 aw_pulse_set1(s, gb, block_idx, &fcb);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
851 aw_pulse_set2(s, gb, block_idx, &fcb);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
852 } else /* FCB_TYPE_EXC_PULSES */ {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
853 int offset_nbits = 5 - frame_desc->log_n_blocks;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
854
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
855 fcb.no_repeat_mask = -1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
856 /* similar to ff_decode_10_pulses_35bits(), but with single pulses
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
857 * (instead of double) for a subset of pulses */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
858 for (n = 0; n < 5; n++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
859 float sign;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
860 int pos1, pos2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
861
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
862 sign = get_bits1(gb) ? 1.0 : -1.0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
863 pos1 = get_bits(gb, offset_nbits);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
864 fcb.x[fcb.n] = n + 5 * pos1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
865 fcb.y[fcb.n++] = sign;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
866 if (n < frame_desc->dbl_pulses) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
867 pos2 = get_bits(gb, offset_nbits);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
868 fcb.x[fcb.n] = n + 5 * pos2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
869 fcb.y[fcb.n++] = (pos1 < pos2) ? -sign : sign;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
870 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
871 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
872 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
873 ff_set_fixed_vector(pulses, &fcb, 1.0, size);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
874
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
875 /* Calculate gain for adaptive & fixed codebook signal.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
876 * see ff_amr_set_fixed_gain(). */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
877 idx = get_bits(gb, 7);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
878 fcb_gain = expf(ff_dot_productf(s->gain_pred_err, gain_coeff, 6) -
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
879 5.2409161640 + wmavoice_gain_codebook_fcb[idx]);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
880 acb_gain = wmavoice_gain_codebook_acb[idx];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
881 pred_err = av_clipf(wmavoice_gain_codebook_fcb[idx],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
882 -2.9957322736 /* log(0.05) */,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
883 1.6094379124 /* log(5.0) */);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
884
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
885 gain_weight = 8 >> frame_desc->log_n_blocks;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
886 memmove(&s->gain_pred_err[gain_weight], s->gain_pred_err,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
887 sizeof(*s->gain_pred_err) * (6 - gain_weight));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
888 for (n = 0; n < gain_weight; n++)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
889 s->gain_pred_err[n] = pred_err;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
890
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
891 /* Calculation of adaptive codebook */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
892 if (frame_desc->acb_type == ACB_TYPE_ASYMMETRIC) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
893 int len;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
894 for (n = 0; n < size; n += len) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
895 int next_idx_sh16;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
896 int abs_idx = block_idx * size + n;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
897 int pitch_sh16 = (s->last_pitch_val << 16) +
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
898 s->pitch_diff_sh16 * abs_idx;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
899 int pitch = (pitch_sh16 + 0x6FFF) >> 16;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
900 int idx_sh16 = ((pitch << 16) - pitch_sh16) * 8 + 0x58000;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
901 idx = idx_sh16 >> 16;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
902 if (s->pitch_diff_sh16) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
903 if (s->pitch_diff_sh16 > 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
904 next_idx_sh16 = (idx_sh16) &~ 0xFFFF;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
905 } else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
906 next_idx_sh16 = (idx_sh16 + 0x10000) &~ 0xFFFF;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
907 len = av_clip((idx_sh16 - next_idx_sh16) / s->pitch_diff_sh16 / 8,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
908 1, size - n);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
909 } else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
910 len = size;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
911
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
912 ff_acelp_interpolatef(&excitation[n], &excitation[n - pitch],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
913 wmavoice_ipol1_coeffs, 17,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
914 idx, 9, len);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
915 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
916 } else /* ACB_TYPE_HAMMING */ {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
917 int block_pitch = block_pitch_sh2 >> 2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
918 idx = block_pitch_sh2 & 3;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
919 if (idx) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
920 ff_acelp_interpolatef(excitation, &excitation[-block_pitch],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
921 wmavoice_ipol2_coeffs, 4,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
922 idx, 8, size);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
923 } else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
924 av_memcpy_backptr(excitation, sizeof(float) * block_pitch,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
925 sizeof(float) * size);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
926 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
927
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
928 /* Interpolate ACB/FCB and use as excitation signal */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
929 ff_weighted_vector_sumf(excitation, excitation, pulses,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
930 acb_gain, fcb_gain, size);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
931 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
932
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
933 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
934 * Parse data in a single block.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
935 * @note we assume enough bits are available, caller should check.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
936 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
937 * @param s WMA Voice decoding context private data
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
938 * @param gb bit I/O context
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
939 * @param block_idx index of the to-be-read block
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
940 * @param size amount of samples to be read in this block
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
941 * @param block_pitch_sh2 pitch for this block << 2
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
942 * @param lsps LSPs for (the end of) this frame
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
943 * @param prev_lsps LSPs for the last frame
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
944 * @param frame_desc frame type descriptor
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
945 * @param excitation target memory for the ACB+FCB interpolated signal
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
946 * @param synth target memory for the speech synthesis filter output
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
947 * @return 0 on success, <0 on error.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
948 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
949 static void synth_block(WMAVoiceContext *s, GetBitContext *gb,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
950 int block_idx, int size,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
951 int block_pitch_sh2,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
952 const double *lsps, const double *prev_lsps,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
953 const struct frame_type_desc *frame_desc,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
954 float *excitation, float *synth)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
955 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
956 double i_lsps[MAX_LSPS];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
957 float lpcs[MAX_LSPS];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
958 float fac;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
959 int n;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
960
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
961 if (frame_desc->acb_type == ACB_TYPE_NONE)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
962 synth_block_hardcoded(s, gb, block_idx, size, frame_desc, excitation);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
963 else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
964 synth_block_fcb_acb(s, gb, block_idx, size, block_pitch_sh2,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
965 frame_desc, excitation);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
966
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
967 /* convert interpolated LSPs to LPCs */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
968 fac = (block_idx + 0.5) / frame_desc->n_blocks;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
969 for (n = 0; n < s->lsps; n++) // LSF -> LSP
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
970 i_lsps[n] = cos(prev_lsps[n] + fac * (lsps[n] - prev_lsps[n]));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
971 ff_acelp_lspd2lpc(i_lsps, lpcs, s->lsps >> 1);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
972
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
973 /* Speech synthesis */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
974 ff_celp_lp_synthesis_filterf(synth, lpcs, excitation, size, s->lsps);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
975 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
976
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
977 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
978 * Synthesize output samples for a single frame.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
979 * @note we assume enough bits are available, caller should check.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
980 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
981 * @param ctx WMA Voice decoder context
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
982 * @param gb bit I/O context (s->gb or one for cross-packet superframes)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
983 * @param samples pointer to output sample buffer, has space for at least 160
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
984 * samples
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
985 * @param lsps LSP array
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
986 * @param prev_lsps array of previous frame's LSPs
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
987 * @param excitation target buffer for excitation signal
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
988 * @param synth target buffer for synthesized speech data
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
989 * @return 0 on success, <0 on error.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
990 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
991 static int synth_frame(AVCodecContext *ctx, GetBitContext *gb,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
992 float *samples,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
993 const double *lsps, const double *prev_lsps,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
994 float *excitation, float *synth)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
995 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
996 WMAVoiceContext *s = ctx->priv_data;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
997 int n, n_blocks_x2, log_n_blocks_x2, cur_pitch_val;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
998 int pitch[MAX_BLOCKS], last_block_pitch;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
999
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1000 /* Parse frame type ("frame header"), see frame_descs */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1001 int bd_idx = s->vbm_tree[get_vlc2(gb, frame_type_vlc.table, 6, 3)],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1002 block_nsamples = MAX_FRAMESIZE / frame_descs[bd_idx].n_blocks;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1003
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1004 if (bd_idx < 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1005 av_log(ctx, AV_LOG_ERROR,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1006 "Invalid frame type VLC code, skipping\n");
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1007 return -1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1008 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1009
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1010 /* Pitch calculation for ACB_TYPE_ASYMMETRIC ("pitch-per-frame") */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1011 if (frame_descs[bd_idx].acb_type == ACB_TYPE_ASYMMETRIC) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1012 /* Pitch is provided per frame, which is interpreted as the pitch of
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1013 * the last sample of the last block of this frame. We can interpolate
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1014 * the pitch of other blocks (and even pitch-per-sample) by gradually
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1015 * incrementing/decrementing prev_frame_pitch to cur_pitch_val. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1016 n_blocks_x2 = frame_descs[bd_idx].n_blocks << 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1017 log_n_blocks_x2 = frame_descs[bd_idx].log_n_blocks + 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1018 cur_pitch_val = s->min_pitch_val + get_bits(gb, s->pitch_nbits);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1019 cur_pitch_val = FFMIN(cur_pitch_val, s->max_pitch_val - 1);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1020 if (s->last_acb_type == ACB_TYPE_NONE ||
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1021 20 * abs(cur_pitch_val - s->last_pitch_val) >
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1022 (cur_pitch_val + s->last_pitch_val))
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1023 s->last_pitch_val = cur_pitch_val;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1024
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1025 /* pitch per block */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1026 for (n = 0; n < frame_descs[bd_idx].n_blocks; n++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1027 int fac = n * 2 + 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1028
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1029 pitch[n] = (MUL16(fac, cur_pitch_val) +
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1030 MUL16((n_blocks_x2 - fac), s->last_pitch_val) +
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1031 frame_descs[bd_idx].n_blocks) >> log_n_blocks_x2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1032 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1033
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1034 /* "pitch-diff-per-sample" for calculation of pitch per sample */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1035 s->pitch_diff_sh16 =
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1036 ((cur_pitch_val - s->last_pitch_val) << 16) / MAX_FRAMESIZE;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1037 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1038
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1039 /* Global gain (if silence) and pitch-adaptive window coordinates */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1040 switch (frame_descs[bd_idx].fcb_type) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1041 case FCB_TYPE_SILENCE:
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1042 s->silence_gain = wmavoice_gain_silence[get_bits(gb, 8)];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1043 break;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1044 case FCB_TYPE_AW_PULSES:
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1045 aw_parse_coords(s, gb, pitch);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1046 break;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1047 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1048
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1049 for (n = 0; n < frame_descs[bd_idx].n_blocks; n++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1050 int bl_pitch_sh2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1051
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1052 /* Pitch calculation for ACB_TYPE_HAMMING ("pitch-per-block") */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1053 switch (frame_descs[bd_idx].acb_type) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1054 case ACB_TYPE_HAMMING: {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1055 /* Pitch is given per block. Per-block pitches are encoded as an
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1056 * absolute value for the first block, and then delta values
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1057 * relative to this value) for all subsequent blocks. The scale of
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1058 * this pitch value is semi-logaritmic compared to its use in the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1059 * decoder, so we convert it to normal scale also. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1060 int block_pitch,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1061 t1 = (s->block_conv_table[1] - s->block_conv_table[0]) << 2,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1062 t2 = (s->block_conv_table[2] - s->block_conv_table[1]) << 1,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1063 t3 = s->block_conv_table[3] - s->block_conv_table[2] + 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1064
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1065 if (n == 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1066 block_pitch = get_bits(gb, s->block_pitch_nbits);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1067 } else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1068 block_pitch = last_block_pitch - s->block_delta_pitch_hrange +
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1069 get_bits(gb, s->block_delta_pitch_nbits);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1070 /* Convert last_ so that any next delta is within _range */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1071 last_block_pitch = av_clip(block_pitch,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1072 s->block_delta_pitch_hrange,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1073 s->block_pitch_range -
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1074 s->block_delta_pitch_hrange);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1075
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1076 /* Convert semi-log-style scale back to normal scale */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1077 if (block_pitch < t1) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1078 bl_pitch_sh2 = (s->block_conv_table[0] << 2) + block_pitch;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1079 } else {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1080 block_pitch -= t1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1081 if (block_pitch < t2) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1082 bl_pitch_sh2 =
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1083 (s->block_conv_table[1] << 2) + (block_pitch << 1);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1084 } else {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1085 block_pitch -= t2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1086 if (block_pitch < t3) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1087 bl_pitch_sh2 =
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1088 (s->block_conv_table[2] + block_pitch) << 2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1089 } else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1090 bl_pitch_sh2 = s->block_conv_table[3] << 2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1091 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1092 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1093 pitch[n] = bl_pitch_sh2 >> 2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1094 break;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1095 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1096
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1097 case ACB_TYPE_ASYMMETRIC: {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1098 bl_pitch_sh2 = pitch[n] << 2;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1099 break;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1100 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1101
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1102 default: // ACB_TYPE_NONE has no pitch
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1103 bl_pitch_sh2 = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1104 break;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1105 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1106
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1107 synth_block(s, gb, n, block_nsamples, bl_pitch_sh2,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1108 lsps, prev_lsps, &frame_descs[bd_idx],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1109 &excitation[n * block_nsamples],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1110 &synth[n * block_nsamples]);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1111 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1112
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1113 /* Averaging projection filter, if applicable. Else, just copy samples
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1114 * from synthesis buffer */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1115 if (s->do_apf) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1116 // FIXME this is where APF would take place, currently not implemented
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1117 av_log_missing_feature(ctx, "APF", 0);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1118 s->do_apf = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1119 } //else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1120 for (n = 0; n < 160; n++)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1121 samples[n] = av_clipf(synth[n], -1.0, 1.0);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1122
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1123 /* Cache values for next frame */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1124 s->frame_cntr++;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1125 if (s->frame_cntr >= 0xFFFF) s->frame_cntr -= 0xFFFF; // i.e. modulo (%)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1126 s->last_acb_type = frame_descs[bd_idx].acb_type;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1127 switch (frame_descs[bd_idx].acb_type) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1128 case ACB_TYPE_NONE:
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1129 s->last_pitch_val = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1130 break;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1131 case ACB_TYPE_ASYMMETRIC:
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1132 s->last_pitch_val = cur_pitch_val;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1133 break;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1134 case ACB_TYPE_HAMMING:
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1135 s->last_pitch_val = pitch[frame_descs[bd_idx].n_blocks - 1];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1136 break;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1137 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1138
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1139 return 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1140 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1141
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1142 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1143 * Ensure minimum value for first item, maximum value for last value,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1144 * proper spacing between each value and proper ordering.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1145 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1146 * @param lsps array of LSPs
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1147 * @param num size of LSP array
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1148 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1149 * @note basically a double version of #ff_acelp_reorder_lsf(), might be
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1150 * useful to put in a generic location later on. Parts are also
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1151 * present in #ff_set_min_dist_lsf() + #ff_sort_nearly_sorted_floats(),
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1152 * which is in float.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1153 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1154 static void stabilize_lsps(double *lsps, int num)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1155 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1156 int n, m, l;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1157
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1158 /* set minimum value for first, maximum value for last and minimum
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1159 * spacing between LSF values.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1160 * Very similar to ff_set_min_dist_lsf(), but in double. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1161 lsps[0] = FFMAX(lsps[0], 0.0015 * M_PI);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1162 for (n = 1; n < num; n++)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1163 lsps[n] = FFMAX(lsps[n], lsps[n - 1] + 0.0125 * M_PI);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1164 lsps[num - 1] = FFMIN(lsps[num - 1], 0.9985 * M_PI);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1165
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1166 /* reorder (looks like one-time / non-recursed bubblesort).
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1167 * Very similar to ff_sort_nearly_sorted_floats(), but in double. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1168 for (n = 1; n < num; n++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1169 if (lsps[n] < lsps[n - 1]) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1170 for (m = 1; m < num; m++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1171 double tmp = lsps[m];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1172 for (l = m - 1; l >= 0; l--) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1173 if (lsps[l] <= tmp) break;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1174 lsps[l + 1] = lsps[l];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1175 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1176 lsps[l + 1] = tmp;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1177 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1178 break;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1179 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1180 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1181 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1182
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1183 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1184 * Test if there's enough bits to read 1 superframe.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1185 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1186 * @param orig_gb bit I/O context used for reading. This function
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1187 * does not modify the state of the bitreader; it
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1188 * only uses it to copy the current stream position
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1189 * @param s WMA Voice decoding context private data
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1190 * @returns -1 if unsupported, 1 on not enough bits or 0 if OK.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1191 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1192 static int check_bits_for_superframe(GetBitContext *orig_gb,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1193 WMAVoiceContext *s)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1194 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1195 GetBitContext s_gb, *gb = &s_gb;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1196 int n, need_bits, bd_idx;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1197 const struct frame_type_desc *frame_desc;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1198
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1199 /* initialize a copy */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1200 init_get_bits(gb, orig_gb->buffer, orig_gb->size_in_bits);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1201 skip_bits_long(gb, get_bits_count(orig_gb));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1202 assert(get_bits_left(gb) == get_bits_left(orig_gb));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1203
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1204 /* superframe header */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1205 if (get_bits_left(gb) < 14)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1206 return 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1207 if (!get_bits1(gb))
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1208 return -1; // WMAPro-in-WMAVoice superframe
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1209 if (get_bits1(gb)) skip_bits(gb, 12); // number of samples in superframe
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1210 if (s->has_residual_lsps) { // residual LSPs (for all frames)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1211 if (get_bits_left(gb) < s->sframe_lsp_bitsize)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1212 return 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1213 skip_bits_long(gb, s->sframe_lsp_bitsize);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1214 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1215
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1216 /* frames */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1217 for (n = 0; n < MAX_FRAMES; n++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1218 int aw_idx_is_ext = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1219
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1220 if (!s->has_residual_lsps) { // independent LSPs (per-frame)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1221 if (get_bits_left(gb) < s->frame_lsp_bitsize) return 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1222 skip_bits_long(gb, s->frame_lsp_bitsize);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1223 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1224 bd_idx = s->vbm_tree[get_vlc2(gb, frame_type_vlc.table, 6, 3)];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1225 if (bd_idx < 0)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1226 return -1; // invalid frame type VLC code
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1227 frame_desc = &frame_descs[bd_idx];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1228 if (frame_desc->acb_type == ACB_TYPE_ASYMMETRIC) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1229 if (get_bits_left(gb) < s->pitch_nbits)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1230 return 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1231 skip_bits_long(gb, s->pitch_nbits);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1232 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1233 if (frame_desc->fcb_type == FCB_TYPE_SILENCE) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1234 skip_bits(gb, 8);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1235 } else if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1236 int tmp = get_bits(gb, 6);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1237 if (tmp >= 0x36) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1238 skip_bits(gb, 2);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1239 aw_idx_is_ext = 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1240 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1241 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1242
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1243 /* blocks */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1244 if (frame_desc->acb_type == ACB_TYPE_HAMMING) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1245 need_bits = s->block_pitch_nbits +
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1246 (frame_desc->n_blocks - 1) * s->block_delta_pitch_nbits;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1247 } else if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1248 need_bits = 2 * !aw_idx_is_ext;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1249 } else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1250 need_bits = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1251 need_bits += frame_desc->frame_size;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1252 if (get_bits_left(gb) < need_bits)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1253 return 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1254 skip_bits_long(gb, need_bits);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1255 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1256
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1257 return 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1258 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1259
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1260 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1261 * Synthesize output samples for a single superframe. If we have any data
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1262 * cached in s->sframe_cache, that will be used instead of whatever is loaded
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1263 * in s->gb.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1264 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1265 * WMA Voice superframes contain 3 frames, each containing 160 audio samples,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1266 * to give a total of 480 samples per frame. See #synth_frame() for frame
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1267 * parsing. In addition to 3 frames, superframes can also contain the LSPs
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1268 * (if these are globally specified for all frames (residually); they can
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1269 * also be specified individually per-frame. See the s->has_residual_lsps
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1270 * option), and can specify the number of samples encoded in this superframe
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1271 * (if less than 480), usually used to prevent blanks at track boundaries.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1272 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1273 * @param ctx WMA Voice decoder context
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1274 * @param samples pointer to output buffer for voice samples
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1275 * @param data_size pointer containing the size of #samples on input, and the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1276 * amount of #samples filled on output
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1277 * @return 0 on success, <0 on error or 1 if there was not enough data to
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1278 * fully parse the superframe
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1279 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1280 static int synth_superframe(AVCodecContext *ctx,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1281 float *samples, int *data_size)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1282 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1283 WMAVoiceContext *s = ctx->priv_data;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1284 GetBitContext *gb = &s->gb, s_gb;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1285 int n, res, n_samples = 480;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1286 double lsps[MAX_FRAMES][MAX_LSPS];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1287 const double *mean_lsf = s->lsps == 16 ?
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1288 wmavoice_mean_lsf16[s->lsp_def_mode] : wmavoice_mean_lsf10[s->lsp_def_mode];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1289 float excitation[MAX_SIGNAL_HISTORY + MAX_SFRAMESIZE + 12];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1290 float synth[MAX_LSPS + MAX_SFRAMESIZE];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1291
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1292 memcpy(synth, s->synth_history,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1293 s->lsps * sizeof(*synth));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1294 memcpy(excitation, s->excitation_history,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1295 s->history_nsamples * sizeof(*excitation));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1296
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1297 if (s->sframe_cache_size > 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1298 gb = &s_gb;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1299 init_get_bits(gb, s->sframe_cache, s->sframe_cache_size);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1300 s->sframe_cache_size = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1301 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1302
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1303 if ((res = check_bits_for_superframe(gb, s)) == 1) return 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1304
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1305 /* First bit is speech/music bit, it differentiates between WMAVoice
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1306 * speech samples (the actual codec) and WMAVoice music samples, which
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1307 * are really WMAPro-in-WMAVoice-superframes. I've never seen those in
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1308 * the wild yet. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1309 if (!get_bits1(gb)) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1310 av_log_missing_feature(ctx, "WMAPro-in-WMAVoice support", 1);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1311 return -1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1312 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1313
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1314 /* (optional) nr. of samples in superframe; always <= 480 and >= 0 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1315 if (get_bits1(gb)) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1316 if ((n_samples = get_bits(gb, 12)) > 480) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1317 av_log(ctx, AV_LOG_ERROR,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1318 "Superframe encodes >480 samples (%d), not allowed\n",
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1319 n_samples);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1320 return -1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1321 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1322 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1323 /* Parse LSPs, if global for the superframe (can also be per-frame). */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1324 if (s->has_residual_lsps) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1325 double prev_lsps[MAX_LSPS], a1[MAX_LSPS * 2], a2[MAX_LSPS * 2];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1326
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1327 for (n = 0; n < s->lsps; n++)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1328 prev_lsps[n] = s->prev_lsps[n] - mean_lsf[n];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1329
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1330 if (s->lsps == 10) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1331 dequant_lsp10r(gb, lsps[2], prev_lsps, a1, a2, s->lsp_q_mode);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1332 } else /* s->lsps == 16 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1333 dequant_lsp16r(gb, lsps[2], prev_lsps, a1, a2, s->lsp_q_mode);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1334
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1335 for (n = 0; n < s->lsps; n++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1336 lsps[0][n] = mean_lsf[n] + (a1[n] - a2[n * 2]);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1337 lsps[1][n] = mean_lsf[n] + (a1[s->lsps + n] - a2[n * 2 + 1]);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1338 lsps[2][n] += mean_lsf[n];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1339 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1340 for (n = 0; n < 3; n++)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1341 stabilize_lsps(lsps[n], s->lsps);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1342 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1343
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1344 /* Parse frames, optionally preceeded by per-frame (independent) LSPs. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1345 for (n = 0; n < 3; n++) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1346 if (!s->has_residual_lsps) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1347 int m;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1348
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1349 if (s->lsps == 10) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1350 dequant_lsp10i(gb, lsps[n]);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1351 } else /* s->lsps == 16 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1352 dequant_lsp16i(gb, lsps[n]);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1353
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1354 for (m = 0; m < s->lsps; m++)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1355 lsps[n][m] += mean_lsf[m];
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1356 stabilize_lsps(lsps[n], s->lsps);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1357 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1358
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1359 if ((res = synth_frame(ctx, gb,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1360 &samples[n * MAX_FRAMESIZE],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1361 lsps[n], n == 0 ? s->prev_lsps : lsps[n - 1],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1362 &excitation[s->history_nsamples + n * MAX_FRAMESIZE],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1363 &synth[s->lsps + n * MAX_FRAMESIZE])))
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1364 return res;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1365 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1366
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1367 /* Statistics? FIXME - we don't check for length, a slight overrun
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1368 * will be caught by internal buffer padding, and anything else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1369 * will be skipped, not read. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1370 if (get_bits1(gb)) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1371 res = get_bits(gb, 4);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1372 skip_bits(gb, 10 * (res + 1));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1373 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1374
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1375 /* Specify nr. of output samples */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1376 *data_size = n_samples * sizeof(float);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1377
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1378 /* Update history */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1379 memcpy(s->prev_lsps, lsps[2],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1380 s->lsps * sizeof(*s->prev_lsps));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1381 memcpy(s->synth_history, &synth[MAX_SFRAMESIZE],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1382 s->lsps * sizeof(*synth));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1383 memcpy(s->excitation_history, &excitation[MAX_SFRAMESIZE],
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1384 s->history_nsamples * sizeof(*excitation));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1385
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1386 return 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1387 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1388
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1389 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1390 * Parse the packet header at the start of each packet (input data to this
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1391 * decoder).
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1392 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1393 * @param s WMA Voice decoding context private data
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1394 * @returns 1 if not enough bits were available, or 0 on success.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1395 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1396 static int parse_packet_header(WMAVoiceContext *s)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1397 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1398 GetBitContext *gb = &s->gb;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1399 unsigned int res;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1400
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1401 if (get_bits_left(gb) < 11)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1402 return 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1403 skip_bits(gb, 4); // packet sequence number
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1404 s->has_residual_lsps = get_bits1(gb);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1405 do {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1406 res = get_bits(gb, 6); // number of superframes per packet
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1407 // (minus first one if there is spillover)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1408 if (get_bits_left(gb) < 6 * (res == 0x3F) + s->spillover_bitsize)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1409 return 1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1410 } while (res == 0x3F);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1411 s->spillover_nbits = get_bits(gb, s->spillover_bitsize);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1412
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1413 return 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1414 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1415
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1416 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1417 * Copy (unaligned) bits from gb/data/size to pb.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1418 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1419 * @param pb target buffer to copy bits into
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1420 * @param data source buffer to copy bits from
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1421 * @param size size of the source data, in bytes
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1422 * @param gb bit I/O context specifying the current position in the source.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1423 * data. This function might use this to align the bit position to
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1424 * a whole-byte boundary before calling #ff_copy_bits() on aligned
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1425 * source data
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1426 * @param nbits the amount of bits to copy from source to target
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1427 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1428 * @note after calling this function, the current position in the input bit
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1429 * I/O context is undefined.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1430 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1431 static void copy_bits(PutBitContext *pb,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1432 const uint8_t *data, int size,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1433 GetBitContext *gb, int nbits)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1434 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1435 int rmn_bytes, rmn_bits;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1436
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1437 rmn_bits = rmn_bytes = get_bits_left(gb);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1438 if (rmn_bits < nbits)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1439 return;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1440 rmn_bits &= 7; rmn_bytes >>= 3;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1441 if ((rmn_bits = FFMIN(rmn_bits, nbits)) > 0)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1442 put_bits(pb, rmn_bits, get_bits(gb, rmn_bits));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1443 ff_copy_bits(pb, data + size - rmn_bytes,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1444 FFMIN(nbits - rmn_bits, rmn_bytes << 3));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1445 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1446
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1447 /**
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1448 * Packet decoding: a packet is anything that the (ASF) demuxer contains,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1449 * and we expect that the demuxer / application provides it to us as such
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1450 * (else you'll probably get garbage as output). Every packet has a size of
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1451 * ctx->block_align bytes, starts with a packet header (see
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1452 * #parse_packet_header()), and then a series of superframes. Superframe
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1453 * boundaries may exceed packets, i.e. superframes can split data over
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1454 * multiple (two) packets.
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1455 *
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1456 * For more information about frames, see #synth_superframe().
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1457 */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1458 static int wmavoice_decode_packet(AVCodecContext *ctx, void *data,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1459 int *data_size, AVPacket *avpkt)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1460 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1461 WMAVoiceContext *s = ctx->priv_data;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1462 GetBitContext *gb = &s->gb;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1463 int size, res, pos;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1464
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1465 if (*data_size < 480 * sizeof(float)) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1466 av_log(ctx, AV_LOG_ERROR,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1467 "Output buffer too small (%d given - %lu needed)\n",
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1468 *data_size, 480 * sizeof(float));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1469 return -1;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1470 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1471 *data_size = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1472
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1473 /* Packets are sometimes a multiple of ctx->block_align, with a packet
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1474 * header at each ctx->block_align bytes. However, FFmpeg's ASF demuxer
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1475 * feeds us ASF packets, which may concatenate multiple "codec" packets
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1476 * in a single "muxer" packet, so we artificially emulate that by
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1477 * capping the packet size at ctx->block_align. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1478 for (size = avpkt->size; size > ctx->block_align; size -= ctx->block_align);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1479 if (!size)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1480 return 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1481 init_get_bits(&s->gb, avpkt->data, size << 3);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1482
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1483 /* size == ctx->block_align is used to indicate whether we are dealing with
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1484 * a new packet or a packet of which we already read the packet header
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1485 * previously. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1486 if (size == ctx->block_align) { // new packet header
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1487 if ((res = parse_packet_header(s)) < 0)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1488 return res;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1489
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1490 /* If the packet header specifies a s->spillover_nbits, then we want
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1491 * to push out all data of the previous packet (+ spillover) before
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1492 * continuing to parse new superframes in the current packet. */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1493 if (s->spillover_nbits > 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1494 if (s->sframe_cache_size > 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1495 int cnt = get_bits_count(gb);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1496 copy_bits(&s->pb, avpkt->data, size, gb, s->spillover_nbits);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1497 flush_put_bits(&s->pb);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1498 s->sframe_cache_size += s->spillover_nbits;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1499 if ((res = synth_superframe(ctx, data, data_size)) == 0 &&
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1500 *data_size > 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1501 cnt += s->spillover_nbits;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1502 s->skip_bits_next = cnt & 7;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1503 return cnt >> 3;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1504 } else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1505 skip_bits_long (gb, s->spillover_nbits - cnt +
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1506 get_bits_count(gb)); // resync
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1507 } else
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1508 skip_bits_long(gb, s->spillover_nbits); // resync
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1509 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1510 } else if (s->skip_bits_next)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1511 skip_bits(gb, s->skip_bits_next);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1512
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1513 /* Try parsing superframes in current packet */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1514 s->sframe_cache_size = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1515 s->skip_bits_next = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1516 pos = get_bits_left(gb);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1517 if ((res = synth_superframe(ctx, data, data_size)) < 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1518 return res;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1519 } else if (*data_size > 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1520 int cnt = get_bits_count(gb);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1521 s->skip_bits_next = cnt & 7;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1522 return cnt >> 3;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1523 } else if ((s->sframe_cache_size = pos) > 0) {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1524 /* rewind bit reader to start of last (incomplete) superframe... */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1525 init_get_bits(gb, avpkt->data, size << 3);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1526 skip_bits_long(gb, (size << 3) - pos);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1527 assert(get_bits_left(gb) == pos);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1528
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1529 /* ...and cache it for spillover in next packet */
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1530 init_put_bits(&s->pb, s->sframe_cache, SFRAME_CACHE_MAXSIZE);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1531 copy_bits(&s->pb, avpkt->data, size, gb, s->sframe_cache_size);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1532 // FIXME bad - just copy bytes as whole and add use the
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1533 // skip_bits_next field
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1534 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1535
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1536 return size;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1537 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1538
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1539 static av_cold void wmavoice_flush(AVCodecContext *ctx)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1540 {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1541 WMAVoiceContext *s = ctx->priv_data;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1542 int n;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1543
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1544 s->sframe_cache_size = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1545 s->skip_bits_next = 0;
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1546 for (n = 0; n < s->lsps; n++)
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1547 s->prev_lsps[n] = M_PI * (n + 1.0) / (s->lsps + 1.0);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1548 memset(s->excitation_history, 0,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1549 sizeof(*s->excitation_history) * MAX_SIGNAL_HISTORY);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1550 memset(s->synth_history, 0,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1551 sizeof(*s->synth_history) * MAX_LSPS);
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1552 memset(s->gain_pred_err, 0,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1553 sizeof(s->gain_pred_err));
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1554 }
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1555
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1556 AVCodec wmavoice_decoder = {
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1557 "wmavoice",
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1558 CODEC_TYPE_AUDIO,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1559 CODEC_ID_WMAVOICE,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1560 sizeof(WMAVoiceContext),
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1561 wmavoice_decode_init,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1562 NULL,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1563 NULL,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1564 wmavoice_decode_packet,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1565 CODEC_CAP_SUBFRAMES,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1566 .flush = wmavoice_flush,
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1567 .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"),
d59349627f52 WMAVoice decoder.
rbultje
parents:
diff changeset
1568 };