MP3 Player. You can change fwd/rev speed and skip. see: http://mbed.org/users/okini3939/notebook/lpc4088_madplayer/

Dependencies:   I2SSlave SDFileSystem TLV320 mbed

Committer:
okini3939
Date:
Tue Feb 18 00:22:50 2014 +0000
Revision:
0:8ba6230eefbd
1st build

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 0:8ba6230eefbd 1 /*
okini3939 0:8ba6230eefbd 2 * libmad - MPEG audio decoder library
okini3939 0:8ba6230eefbd 3 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
okini3939 0:8ba6230eefbd 4 *
okini3939 0:8ba6230eefbd 5 * This program is free software; you can redistribute it and/or modify
okini3939 0:8ba6230eefbd 6 * it under the terms of the GNU General Public License as published by
okini3939 0:8ba6230eefbd 7 * the Free Software Foundation; either version 2 of the License, or
okini3939 0:8ba6230eefbd 8 * (at your option) any later version.
okini3939 0:8ba6230eefbd 9 *
okini3939 0:8ba6230eefbd 10 * This program is distributed in the hope that it will be useful,
okini3939 0:8ba6230eefbd 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
okini3939 0:8ba6230eefbd 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
okini3939 0:8ba6230eefbd 13 * GNU General Public License for more details.
okini3939 0:8ba6230eefbd 14 *
okini3939 0:8ba6230eefbd 15 * You should have received a copy of the GNU General Public License
okini3939 0:8ba6230eefbd 16 * along with this program; if not, write to the Free Software
okini3939 0:8ba6230eefbd 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
okini3939 0:8ba6230eefbd 18 *
okini3939 0:8ba6230eefbd 19 * $Id: layer3.c,v 1.1 2010/11/23 20:12:57 andy Exp $
okini3939 0:8ba6230eefbd 20 */
okini3939 0:8ba6230eefbd 21
okini3939 0:8ba6230eefbd 22 # include "config.h"
okini3939 0:8ba6230eefbd 23
okini3939 0:8ba6230eefbd 24 # include "global.h"
okini3939 0:8ba6230eefbd 25
okini3939 0:8ba6230eefbd 26 # include <stdlib.h>
okini3939 0:8ba6230eefbd 27 # include <string.h>
okini3939 0:8ba6230eefbd 28
okini3939 0:8ba6230eefbd 29 # ifdef HAVE_LIMITS_H
okini3939 0:8ba6230eefbd 30 # include <limits.h>
okini3939 0:8ba6230eefbd 31 # else
okini3939 0:8ba6230eefbd 32 # define CHAR_BIT 8
okini3939 0:8ba6230eefbd 33 # endif
okini3939 0:8ba6230eefbd 34
okini3939 0:8ba6230eefbd 35 # include "fixed.h"
okini3939 0:8ba6230eefbd 36 # include "bit.h"
okini3939 0:8ba6230eefbd 37 # include "stream.h"
okini3939 0:8ba6230eefbd 38 # include "frame.h"
okini3939 0:8ba6230eefbd 39 # include "huffman.h"
okini3939 0:8ba6230eefbd 40 # include "layer3.h"
okini3939 0:8ba6230eefbd 41
okini3939 0:8ba6230eefbd 42 /* --- Layer III ----------------------------------------------------------- */
okini3939 0:8ba6230eefbd 43
okini3939 0:8ba6230eefbd 44 enum {
okini3939 0:8ba6230eefbd 45 count1table_select = 0x01,
okini3939 0:8ba6230eefbd 46 scalefac_scale = 0x02,
okini3939 0:8ba6230eefbd 47 preflag = 0x04,
okini3939 0:8ba6230eefbd 48 mixed_block_flag = 0x08
okini3939 0:8ba6230eefbd 49 };
okini3939 0:8ba6230eefbd 50
okini3939 0:8ba6230eefbd 51 enum {
okini3939 0:8ba6230eefbd 52 I_STEREO = 0x1,
okini3939 0:8ba6230eefbd 53 MS_STEREO = 0x2
okini3939 0:8ba6230eefbd 54 };
okini3939 0:8ba6230eefbd 55
okini3939 0:8ba6230eefbd 56
okini3939 0:8ba6230eefbd 57 struct channel {
okini3939 0:8ba6230eefbd 58 /* from side info */
okini3939 0:8ba6230eefbd 59 unsigned short part2_3_length;
okini3939 0:8ba6230eefbd 60 unsigned short big_values;
okini3939 0:8ba6230eefbd 61 unsigned short global_gain;
okini3939 0:8ba6230eefbd 62 unsigned short scalefac_compress;
okini3939 0:8ba6230eefbd 63
okini3939 0:8ba6230eefbd 64 unsigned char flags;
okini3939 0:8ba6230eefbd 65 unsigned char block_type;
okini3939 0:8ba6230eefbd 66 unsigned char table_select[3];
okini3939 0:8ba6230eefbd 67 unsigned char subblock_gain[3];
okini3939 0:8ba6230eefbd 68 unsigned char region0_count;
okini3939 0:8ba6230eefbd 69 unsigned char region1_count;
okini3939 0:8ba6230eefbd 70
okini3939 0:8ba6230eefbd 71 /* from main_data */
okini3939 0:8ba6230eefbd 72 unsigned char scalefac[39]; /* scalefac_l and/or scalefac_s */
okini3939 0:8ba6230eefbd 73 };
okini3939 0:8ba6230eefbd 74 struct granule {
okini3939 0:8ba6230eefbd 75 struct channel ch[2];
okini3939 0:8ba6230eefbd 76 };
okini3939 0:8ba6230eefbd 77
okini3939 0:8ba6230eefbd 78
okini3939 0:8ba6230eefbd 79 struct sideinfo {
okini3939 0:8ba6230eefbd 80 unsigned int main_data_begin;
okini3939 0:8ba6230eefbd 81 unsigned int private_bits;
okini3939 0:8ba6230eefbd 82
okini3939 0:8ba6230eefbd 83 unsigned char scfsi[2];
okini3939 0:8ba6230eefbd 84
okini3939 0:8ba6230eefbd 85 struct granule gr[2];
okini3939 0:8ba6230eefbd 86 };
okini3939 0:8ba6230eefbd 87
okini3939 0:8ba6230eefbd 88 /*
okini3939 0:8ba6230eefbd 89 * scalefactor bit lengths
okini3939 0:8ba6230eefbd 90 * derived from section 2.4.2.7 of ISO/IEC 11172-3
okini3939 0:8ba6230eefbd 91 */
okini3939 0:8ba6230eefbd 92 static
okini3939 0:8ba6230eefbd 93 struct {
okini3939 0:8ba6230eefbd 94 unsigned char slen1;
okini3939 0:8ba6230eefbd 95 unsigned char slen2;
okini3939 0:8ba6230eefbd 96 } const sflen_table[16] = {
okini3939 0:8ba6230eefbd 97 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 },
okini3939 0:8ba6230eefbd 98 { 3, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 },
okini3939 0:8ba6230eefbd 99 { 2, 1 }, { 2, 2 }, { 2, 3 }, { 3, 1 },
okini3939 0:8ba6230eefbd 100 { 3, 2 }, { 3, 3 }, { 4, 2 }, { 4, 3 }
okini3939 0:8ba6230eefbd 101 };
okini3939 0:8ba6230eefbd 102
okini3939 0:8ba6230eefbd 103 /*
okini3939 0:8ba6230eefbd 104 * number of LSF scalefactor band values
okini3939 0:8ba6230eefbd 105 * derived from section 2.4.3.2 of ISO/IEC 13818-3
okini3939 0:8ba6230eefbd 106 */
okini3939 0:8ba6230eefbd 107 static
okini3939 0:8ba6230eefbd 108 unsigned char const nsfb_table[6][3][4] = {
okini3939 0:8ba6230eefbd 109 { { 6, 5, 5, 5 },
okini3939 0:8ba6230eefbd 110 { 9, 9, 9, 9 },
okini3939 0:8ba6230eefbd 111 { 6, 9, 9, 9 } },
okini3939 0:8ba6230eefbd 112
okini3939 0:8ba6230eefbd 113 { { 6, 5, 7, 3 },
okini3939 0:8ba6230eefbd 114 { 9, 9, 12, 6 },
okini3939 0:8ba6230eefbd 115 { 6, 9, 12, 6 } },
okini3939 0:8ba6230eefbd 116
okini3939 0:8ba6230eefbd 117 { { 11, 10, 0, 0 },
okini3939 0:8ba6230eefbd 118 { 18, 18, 0, 0 },
okini3939 0:8ba6230eefbd 119 { 15, 18, 0, 0 } },
okini3939 0:8ba6230eefbd 120
okini3939 0:8ba6230eefbd 121 { { 7, 7, 7, 0 },
okini3939 0:8ba6230eefbd 122 { 12, 12, 12, 0 },
okini3939 0:8ba6230eefbd 123 { 6, 15, 12, 0 } },
okini3939 0:8ba6230eefbd 124
okini3939 0:8ba6230eefbd 125 { { 6, 6, 6, 3 },
okini3939 0:8ba6230eefbd 126 { 12, 9, 9, 6 },
okini3939 0:8ba6230eefbd 127 { 6, 12, 9, 6 } },
okini3939 0:8ba6230eefbd 128
okini3939 0:8ba6230eefbd 129 { { 8, 8, 5, 0 },
okini3939 0:8ba6230eefbd 130 { 15, 12, 9, 0 },
okini3939 0:8ba6230eefbd 131 { 6, 18, 9, 0 } }
okini3939 0:8ba6230eefbd 132 };
okini3939 0:8ba6230eefbd 133
okini3939 0:8ba6230eefbd 134 /*
okini3939 0:8ba6230eefbd 135 * MPEG-1 scalefactor band widths
okini3939 0:8ba6230eefbd 136 * derived from Table B.8 of ISO/IEC 11172-3
okini3939 0:8ba6230eefbd 137 */
okini3939 0:8ba6230eefbd 138 static
okini3939 0:8ba6230eefbd 139 unsigned char const sfb_48000_long[] = {
okini3939 0:8ba6230eefbd 140 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10,
okini3939 0:8ba6230eefbd 141 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192
okini3939 0:8ba6230eefbd 142 };
okini3939 0:8ba6230eefbd 143
okini3939 0:8ba6230eefbd 144 static
okini3939 0:8ba6230eefbd 145 unsigned char const sfb_44100_long[] = {
okini3939 0:8ba6230eefbd 146 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10,
okini3939 0:8ba6230eefbd 147 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158
okini3939 0:8ba6230eefbd 148 };
okini3939 0:8ba6230eefbd 149
okini3939 0:8ba6230eefbd 150 static
okini3939 0:8ba6230eefbd 151 unsigned char const sfb_32000_long[] = {
okini3939 0:8ba6230eefbd 152 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12,
okini3939 0:8ba6230eefbd 153 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26
okini3939 0:8ba6230eefbd 154 };
okini3939 0:8ba6230eefbd 155
okini3939 0:8ba6230eefbd 156 static
okini3939 0:8ba6230eefbd 157 unsigned char const sfb_48000_short[] = {
okini3939 0:8ba6230eefbd 158 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
okini3939 0:8ba6230eefbd 159 6, 6, 6, 6, 6, 10, 10, 10, 12, 12, 12, 14, 14,
okini3939 0:8ba6230eefbd 160 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66
okini3939 0:8ba6230eefbd 161 };
okini3939 0:8ba6230eefbd 162
okini3939 0:8ba6230eefbd 163 static
okini3939 0:8ba6230eefbd 164 unsigned char const sfb_44100_short[] = {
okini3939 0:8ba6230eefbd 165 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
okini3939 0:8ba6230eefbd 166 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14,
okini3939 0:8ba6230eefbd 167 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56
okini3939 0:8ba6230eefbd 168 };
okini3939 0:8ba6230eefbd 169
okini3939 0:8ba6230eefbd 170 static
okini3939 0:8ba6230eefbd 171 unsigned char const sfb_32000_short[] = {
okini3939 0:8ba6230eefbd 172 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
okini3939 0:8ba6230eefbd 173 6, 6, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20,
okini3939 0:8ba6230eefbd 174 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12
okini3939 0:8ba6230eefbd 175 };
okini3939 0:8ba6230eefbd 176
okini3939 0:8ba6230eefbd 177 static
okini3939 0:8ba6230eefbd 178 unsigned char const sfb_48000_mixed[] = {
okini3939 0:8ba6230eefbd 179 /* long */ 4, 4, 4, 4, 4, 4, 6, 6,
okini3939 0:8ba6230eefbd 180 /* short */ 4, 4, 4, 6, 6, 6, 6, 6, 6, 10,
okini3939 0:8ba6230eefbd 181 10, 10, 12, 12, 12, 14, 14, 14, 16, 16,
okini3939 0:8ba6230eefbd 182 16, 20, 20, 20, 26, 26, 26, 66, 66, 66
okini3939 0:8ba6230eefbd 183 };
okini3939 0:8ba6230eefbd 184
okini3939 0:8ba6230eefbd 185 static
okini3939 0:8ba6230eefbd 186 unsigned char const sfb_44100_mixed[] = {
okini3939 0:8ba6230eefbd 187 /* long */ 4, 4, 4, 4, 4, 4, 6, 6,
okini3939 0:8ba6230eefbd 188 /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 10,
okini3939 0:8ba6230eefbd 189 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
okini3939 0:8ba6230eefbd 190 18, 22, 22, 22, 30, 30, 30, 56, 56, 56
okini3939 0:8ba6230eefbd 191 };
okini3939 0:8ba6230eefbd 192
okini3939 0:8ba6230eefbd 193 static
okini3939 0:8ba6230eefbd 194 unsigned char const sfb_32000_mixed[] = {
okini3939 0:8ba6230eefbd 195 /* long */ 4, 4, 4, 4, 4, 4, 6, 6,
okini3939 0:8ba6230eefbd 196 /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 12,
okini3939 0:8ba6230eefbd 197 12, 12, 16, 16, 16, 20, 20, 20, 26, 26,
okini3939 0:8ba6230eefbd 198 26, 34, 34, 34, 42, 42, 42, 12, 12, 12
okini3939 0:8ba6230eefbd 199 };
okini3939 0:8ba6230eefbd 200
okini3939 0:8ba6230eefbd 201 /*
okini3939 0:8ba6230eefbd 202 * MPEG-2 scalefactor band widths
okini3939 0:8ba6230eefbd 203 * derived from Table B.2 of ISO/IEC 13818-3
okini3939 0:8ba6230eefbd 204 */
okini3939 0:8ba6230eefbd 205 static
okini3939 0:8ba6230eefbd 206 unsigned char const sfb_24000_long[] = {
okini3939 0:8ba6230eefbd 207 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
okini3939 0:8ba6230eefbd 208 18, 22, 26, 32, 38, 46, 54, 62, 70, 76, 36
okini3939 0:8ba6230eefbd 209 };
okini3939 0:8ba6230eefbd 210
okini3939 0:8ba6230eefbd 211 static
okini3939 0:8ba6230eefbd 212 unsigned char const sfb_22050_long[] = {
okini3939 0:8ba6230eefbd 213 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
okini3939 0:8ba6230eefbd 214 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54
okini3939 0:8ba6230eefbd 215 };
okini3939 0:8ba6230eefbd 216
okini3939 0:8ba6230eefbd 217 # define sfb_16000_long sfb_22050_long
okini3939 0:8ba6230eefbd 218
okini3939 0:8ba6230eefbd 219 static
okini3939 0:8ba6230eefbd 220 unsigned char const sfb_24000_short[] = {
okini3939 0:8ba6230eefbd 221 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8,
okini3939 0:8ba6230eefbd 222 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
okini3939 0:8ba6230eefbd 223 18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12
okini3939 0:8ba6230eefbd 224 };
okini3939 0:8ba6230eefbd 225
okini3939 0:8ba6230eefbd 226 static
okini3939 0:8ba6230eefbd 227 unsigned char const sfb_22050_short[] = {
okini3939 0:8ba6230eefbd 228 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6,
okini3939 0:8ba6230eefbd 229 6, 6, 8, 8, 8, 10, 10, 10, 14, 14, 14, 18, 18,
okini3939 0:8ba6230eefbd 230 18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18
okini3939 0:8ba6230eefbd 231 };
okini3939 0:8ba6230eefbd 232
okini3939 0:8ba6230eefbd 233 static
okini3939 0:8ba6230eefbd 234 unsigned char const sfb_16000_short[] = {
okini3939 0:8ba6230eefbd 235 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8,
okini3939 0:8ba6230eefbd 236 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
okini3939 0:8ba6230eefbd 237 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18
okini3939 0:8ba6230eefbd 238 };
okini3939 0:8ba6230eefbd 239
okini3939 0:8ba6230eefbd 240 static
okini3939 0:8ba6230eefbd 241 unsigned char const sfb_24000_mixed[] = {
okini3939 0:8ba6230eefbd 242 /* long */ 6, 6, 6, 6, 6, 6,
okini3939 0:8ba6230eefbd 243 /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12,
okini3939 0:8ba6230eefbd 244 12, 12, 14, 14, 14, 18, 18, 18, 24, 24,
okini3939 0:8ba6230eefbd 245 24, 32, 32, 32, 44, 44, 44, 12, 12, 12
okini3939 0:8ba6230eefbd 246 };
okini3939 0:8ba6230eefbd 247
okini3939 0:8ba6230eefbd 248 static
okini3939 0:8ba6230eefbd 249 unsigned char const sfb_22050_mixed[] = {
okini3939 0:8ba6230eefbd 250 /* long */ 6, 6, 6, 6, 6, 6,
okini3939 0:8ba6230eefbd 251 /* short */ 6, 6, 6, 6, 6, 6, 8, 8, 8, 10,
okini3939 0:8ba6230eefbd 252 10, 10, 14, 14, 14, 18, 18, 18, 26, 26,
okini3939 0:8ba6230eefbd 253 26, 32, 32, 32, 42, 42, 42, 18, 18, 18
okini3939 0:8ba6230eefbd 254 };
okini3939 0:8ba6230eefbd 255
okini3939 0:8ba6230eefbd 256 static
okini3939 0:8ba6230eefbd 257 unsigned char const sfb_16000_mixed[] = {
okini3939 0:8ba6230eefbd 258 /* long */ 6, 6, 6, 6, 6, 6,
okini3939 0:8ba6230eefbd 259 /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12,
okini3939 0:8ba6230eefbd 260 12, 12, 14, 14, 14, 18, 18, 18, 24, 24,
okini3939 0:8ba6230eefbd 261 24, 30, 30, 30, 40, 40, 40, 18, 18, 18
okini3939 0:8ba6230eefbd 262 };
okini3939 0:8ba6230eefbd 263
okini3939 0:8ba6230eefbd 264 /*
okini3939 0:8ba6230eefbd 265 * MPEG 2.5 scalefactor band widths
okini3939 0:8ba6230eefbd 266 * derived from public sources
okini3939 0:8ba6230eefbd 267 */
okini3939 0:8ba6230eefbd 268 # define sfb_12000_long sfb_16000_long
okini3939 0:8ba6230eefbd 269 # define sfb_11025_long sfb_12000_long
okini3939 0:8ba6230eefbd 270
okini3939 0:8ba6230eefbd 271 static
okini3939 0:8ba6230eefbd 272 unsigned char const sfb_8000_long[] = {
okini3939 0:8ba6230eefbd 273 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32,
okini3939 0:8ba6230eefbd 274 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2
okini3939 0:8ba6230eefbd 275 };
okini3939 0:8ba6230eefbd 276
okini3939 0:8ba6230eefbd 277 # define sfb_12000_short sfb_16000_short
okini3939 0:8ba6230eefbd 278 # define sfb_11025_short sfb_12000_short
okini3939 0:8ba6230eefbd 279
okini3939 0:8ba6230eefbd 280 static
okini3939 0:8ba6230eefbd 281 unsigned char const sfb_8000_short[] = {
okini3939 0:8ba6230eefbd 282 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 16,
okini3939 0:8ba6230eefbd 283 16, 16, 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36,
okini3939 0:8ba6230eefbd 284 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26
okini3939 0:8ba6230eefbd 285 };
okini3939 0:8ba6230eefbd 286
okini3939 0:8ba6230eefbd 287 # define sfb_12000_mixed sfb_16000_mixed
okini3939 0:8ba6230eefbd 288 # define sfb_11025_mixed sfb_12000_mixed
okini3939 0:8ba6230eefbd 289
okini3939 0:8ba6230eefbd 290 /* the 8000 Hz short block scalefactor bands do not break after
okini3939 0:8ba6230eefbd 291 the first 36 frequency lines, so this is probably wrong */
okini3939 0:8ba6230eefbd 292 static
okini3939 0:8ba6230eefbd 293 unsigned char const sfb_8000_mixed[] = {
okini3939 0:8ba6230eefbd 294 /* long */ 12, 12, 12,
okini3939 0:8ba6230eefbd 295 /* short */ 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16,
okini3939 0:8ba6230eefbd 296 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, 36,
okini3939 0:8ba6230eefbd 297 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26
okini3939 0:8ba6230eefbd 298 };
okini3939 0:8ba6230eefbd 299
okini3939 0:8ba6230eefbd 300 static
okini3939 0:8ba6230eefbd 301 struct {
okini3939 0:8ba6230eefbd 302 unsigned char const *l;
okini3939 0:8ba6230eefbd 303 unsigned char const *s;
okini3939 0:8ba6230eefbd 304 unsigned char const *m;
okini3939 0:8ba6230eefbd 305 } const sfbwidth_table[9] = {
okini3939 0:8ba6230eefbd 306 { sfb_48000_long, sfb_48000_short, sfb_48000_mixed },
okini3939 0:8ba6230eefbd 307 { sfb_44100_long, sfb_44100_short, sfb_44100_mixed },
okini3939 0:8ba6230eefbd 308 { sfb_32000_long, sfb_32000_short, sfb_32000_mixed },
okini3939 0:8ba6230eefbd 309 { sfb_24000_long, sfb_24000_short, sfb_24000_mixed },
okini3939 0:8ba6230eefbd 310 { sfb_22050_long, sfb_22050_short, sfb_22050_mixed },
okini3939 0:8ba6230eefbd 311 { sfb_16000_long, sfb_16000_short, sfb_16000_mixed },
okini3939 0:8ba6230eefbd 312 { sfb_12000_long, sfb_12000_short, sfb_12000_mixed },
okini3939 0:8ba6230eefbd 313 { sfb_11025_long, sfb_11025_short, sfb_11025_mixed },
okini3939 0:8ba6230eefbd 314 { sfb_8000_long, sfb_8000_short, sfb_8000_mixed }
okini3939 0:8ba6230eefbd 315 };
okini3939 0:8ba6230eefbd 316
okini3939 0:8ba6230eefbd 317 /*
okini3939 0:8ba6230eefbd 318 * scalefactor band preemphasis (used only when preflag is set)
okini3939 0:8ba6230eefbd 319 * derived from Table B.6 of ISO/IEC 11172-3
okini3939 0:8ba6230eefbd 320 */
okini3939 0:8ba6230eefbd 321 static
okini3939 0:8ba6230eefbd 322 unsigned char const pretab[22] = {
okini3939 0:8ba6230eefbd 323 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0
okini3939 0:8ba6230eefbd 324 };
okini3939 0:8ba6230eefbd 325
okini3939 0:8ba6230eefbd 326 /*
okini3939 0:8ba6230eefbd 327 * table for requantization
okini3939 0:8ba6230eefbd 328 *
okini3939 0:8ba6230eefbd 329 * rq_table[x].mantissa * 2^(rq_table[x].exponent) = x^(4/3)
okini3939 0:8ba6230eefbd 330 */
okini3939 0:8ba6230eefbd 331 static
okini3939 0:8ba6230eefbd 332 struct fixedfloat {
okini3939 0:8ba6230eefbd 333 unsigned long mantissa : 27;
okini3939 0:8ba6230eefbd 334 unsigned short exponent : 5;
okini3939 0:8ba6230eefbd 335 } const rq_table[8207] = {
okini3939 0:8ba6230eefbd 336 # include "rq_table.h"
okini3939 0:8ba6230eefbd 337 };
okini3939 0:8ba6230eefbd 338
okini3939 0:8ba6230eefbd 339 /*
okini3939 0:8ba6230eefbd 340 * fractional powers of two
okini3939 0:8ba6230eefbd 341 * used for requantization and joint stereo decoding
okini3939 0:8ba6230eefbd 342 *
okini3939 0:8ba6230eefbd 343 * root_table[3 + x] = 2^(x/4)
okini3939 0:8ba6230eefbd 344 */
okini3939 0:8ba6230eefbd 345 static
okini3939 0:8ba6230eefbd 346 mad_fixed_t const root_table[7] = {
okini3939 0:8ba6230eefbd 347 MAD_F(0x09837f05) /* 2^(-3/4) == 0.59460355750136 */,
okini3939 0:8ba6230eefbd 348 MAD_F(0x0b504f33) /* 2^(-2/4) == 0.70710678118655 */,
okini3939 0:8ba6230eefbd 349 MAD_F(0x0d744fcd) /* 2^(-1/4) == 0.84089641525371 */,
okini3939 0:8ba6230eefbd 350 MAD_F(0x10000000) /* 2^( 0/4) == 1.00000000000000 */,
okini3939 0:8ba6230eefbd 351 MAD_F(0x1306fe0a) /* 2^(+1/4) == 1.18920711500272 */,
okini3939 0:8ba6230eefbd 352 MAD_F(0x16a09e66) /* 2^(+2/4) == 1.41421356237310 */,
okini3939 0:8ba6230eefbd 353 MAD_F(0x1ae89f99) /* 2^(+3/4) == 1.68179283050743 */
okini3939 0:8ba6230eefbd 354 };
okini3939 0:8ba6230eefbd 355
okini3939 0:8ba6230eefbd 356 /*
okini3939 0:8ba6230eefbd 357 * coefficients for aliasing reduction
okini3939 0:8ba6230eefbd 358 * derived from Table B.9 of ISO/IEC 11172-3
okini3939 0:8ba6230eefbd 359 *
okini3939 0:8ba6230eefbd 360 * c[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 }
okini3939 0:8ba6230eefbd 361 * cs[i] = 1 / sqrt(1 + c[i]^2)
okini3939 0:8ba6230eefbd 362 * ca[i] = c[i] / sqrt(1 + c[i]^2)
okini3939 0:8ba6230eefbd 363 */
okini3939 0:8ba6230eefbd 364 static
okini3939 0:8ba6230eefbd 365 mad_fixed_t const cs[8] = {
okini3939 0:8ba6230eefbd 366 +MAD_F(0x0db84a81) /* +0.857492926 */, +MAD_F(0x0e1b9d7f) /* +0.881741997 */,
okini3939 0:8ba6230eefbd 367 +MAD_F(0x0f31adcf) /* +0.949628649 */, +MAD_F(0x0fbba815) /* +0.983314592 */,
okini3939 0:8ba6230eefbd 368 +MAD_F(0x0feda417) /* +0.995517816 */, +MAD_F(0x0ffc8fc8) /* +0.999160558 */,
okini3939 0:8ba6230eefbd 369 +MAD_F(0x0fff964c) /* +0.999899195 */, +MAD_F(0x0ffff8d3) /* +0.999993155 */
okini3939 0:8ba6230eefbd 370 };
okini3939 0:8ba6230eefbd 371
okini3939 0:8ba6230eefbd 372 static
okini3939 0:8ba6230eefbd 373 mad_fixed_t const ca[8] = {
okini3939 0:8ba6230eefbd 374 -MAD_F(0x083b5fe7) /* -0.514495755 */, -MAD_F(0x078c36d2) /* -0.471731969 */,
okini3939 0:8ba6230eefbd 375 -MAD_F(0x05039814) /* -0.313377454 */, -MAD_F(0x02e91dd1) /* -0.181913200 */,
okini3939 0:8ba6230eefbd 376 -MAD_F(0x0183603a) /* -0.094574193 */, -MAD_F(0x00a7cb87) /* -0.040965583 */,
okini3939 0:8ba6230eefbd 377 -MAD_F(0x003a2847) /* -0.014198569 */, -MAD_F(0x000f27b4) /* -0.003699975 */
okini3939 0:8ba6230eefbd 378 };
okini3939 0:8ba6230eefbd 379
okini3939 0:8ba6230eefbd 380 /*
okini3939 0:8ba6230eefbd 381 * IMDCT coefficients for short blocks
okini3939 0:8ba6230eefbd 382 * derived from section 2.4.3.4.10.2 of ISO/IEC 11172-3
okini3939 0:8ba6230eefbd 383 *
okini3939 0:8ba6230eefbd 384 * imdct_s[i/even][k] = cos((PI / 24) * (2 * (i / 2) + 7) * (2 * k + 1))
okini3939 0:8ba6230eefbd 385 * imdct_s[i /odd][k] = cos((PI / 24) * (2 * (6 + (i-1)/2) + 7) * (2 * k + 1))
okini3939 0:8ba6230eefbd 386 */
okini3939 0:8ba6230eefbd 387 static
okini3939 0:8ba6230eefbd 388 mad_fixed_t const imdct_s[6][6] = {
okini3939 0:8ba6230eefbd 389 # include "imdct_s.h"
okini3939 0:8ba6230eefbd 390 };
okini3939 0:8ba6230eefbd 391
okini3939 0:8ba6230eefbd 392 # if !defined(ASO_IMDCT)
okini3939 0:8ba6230eefbd 393 /*
okini3939 0:8ba6230eefbd 394 * windowing coefficients for long blocks
okini3939 0:8ba6230eefbd 395 * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3
okini3939 0:8ba6230eefbd 396 *
okini3939 0:8ba6230eefbd 397 * window_l[i] = sin((PI / 36) * (i + 1/2))
okini3939 0:8ba6230eefbd 398 */
okini3939 0:8ba6230eefbd 399 static
okini3939 0:8ba6230eefbd 400 mad_fixed_t const window_l[36] = {
okini3939 0:8ba6230eefbd 401 MAD_F(0x00b2aa3e) /* 0.043619387 */, MAD_F(0x0216a2a2) /* 0.130526192 */,
okini3939 0:8ba6230eefbd 402 MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x04cfb0e2) /* 0.300705800 */,
okini3939 0:8ba6230eefbd 403 MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x07635284) /* 0.461748613 */,
okini3939 0:8ba6230eefbd 404 MAD_F(0x0898c779) /* 0.537299608 */, MAD_F(0x09bd7ca0) /* 0.608761429 */,
okini3939 0:8ba6230eefbd 405 MAD_F(0x0acf37ad) /* 0.675590208 */, MAD_F(0x0bcbe352) /* 0.737277337 */,
okini3939 0:8ba6230eefbd 406 MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0d7e8807) /* 0.843391446 */,
okini3939 0:8ba6230eefbd 407
okini3939 0:8ba6230eefbd 408 MAD_F(0x0e313245) /* 0.887010833 */, MAD_F(0x0ec835e8) /* 0.923879533 */,
okini3939 0:8ba6230eefbd 409 MAD_F(0x0f426cb5) /* 0.953716951 */, MAD_F(0x0f9ee890) /* 0.976296007 */,
okini3939 0:8ba6230eefbd 410 MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ffc19fd) /* 0.999048222 */,
okini3939 0:8ba6230eefbd 411 MAD_F(0x0ffc19fd) /* 0.999048222 */, MAD_F(0x0fdcf549) /* 0.991444861 */,
okini3939 0:8ba6230eefbd 412 MAD_F(0x0f9ee890) /* 0.976296007 */, MAD_F(0x0f426cb5) /* 0.953716951 */,
okini3939 0:8ba6230eefbd 413 MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0e313245) /* 0.887010833 */,
okini3939 0:8ba6230eefbd 414
okini3939 0:8ba6230eefbd 415 MAD_F(0x0d7e8807) /* 0.843391446 */, MAD_F(0x0cb19346) /* 0.793353340 */,
okini3939 0:8ba6230eefbd 416 MAD_F(0x0bcbe352) /* 0.737277337 */, MAD_F(0x0acf37ad) /* 0.675590208 */,
okini3939 0:8ba6230eefbd 417 MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0898c779) /* 0.537299608 */,
okini3939 0:8ba6230eefbd 418 MAD_F(0x07635284) /* 0.461748613 */, MAD_F(0x061f78aa) /* 0.382683432 */,
okini3939 0:8ba6230eefbd 419 MAD_F(0x04cfb0e2) /* 0.300705800 */, MAD_F(0x03768962) /* 0.216439614 */,
okini3939 0:8ba6230eefbd 420 MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x00b2aa3e) /* 0.043619387 */,
okini3939 0:8ba6230eefbd 421 };
okini3939 0:8ba6230eefbd 422 # endif /* ASO_IMDCT */
okini3939 0:8ba6230eefbd 423
okini3939 0:8ba6230eefbd 424 /*
okini3939 0:8ba6230eefbd 425 * windowing coefficients for short blocks
okini3939 0:8ba6230eefbd 426 * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3
okini3939 0:8ba6230eefbd 427 *
okini3939 0:8ba6230eefbd 428 * window_s[i] = sin((PI / 12) * (i + 1/2))
okini3939 0:8ba6230eefbd 429 */
okini3939 0:8ba6230eefbd 430 static
okini3939 0:8ba6230eefbd 431 mad_fixed_t const window_s[12] = {
okini3939 0:8ba6230eefbd 432 MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x061f78aa) /* 0.382683432 */,
okini3939 0:8ba6230eefbd 433 MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0cb19346) /* 0.793353340 */,
okini3939 0:8ba6230eefbd 434 MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0fdcf549) /* 0.991444861 */,
okini3939 0:8ba6230eefbd 435 MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ec835e8) /* 0.923879533 */,
okini3939 0:8ba6230eefbd 436 MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x09bd7ca0) /* 0.608761429 */,
okini3939 0:8ba6230eefbd 437 MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0216a2a2) /* 0.130526192 */,
okini3939 0:8ba6230eefbd 438 };
okini3939 0:8ba6230eefbd 439
okini3939 0:8ba6230eefbd 440 /*
okini3939 0:8ba6230eefbd 441 * coefficients for intensity stereo processing
okini3939 0:8ba6230eefbd 442 * derived from section 2.4.3.4.9.3 of ISO/IEC 11172-3
okini3939 0:8ba6230eefbd 443 *
okini3939 0:8ba6230eefbd 444 * is_ratio[i] = tan(i * (PI / 12))
okini3939 0:8ba6230eefbd 445 * is_table[i] = is_ratio[i] / (1 + is_ratio[i])
okini3939 0:8ba6230eefbd 446 */
okini3939 0:8ba6230eefbd 447 static
okini3939 0:8ba6230eefbd 448 mad_fixed_t const is_table[7] = {
okini3939 0:8ba6230eefbd 449 MAD_F(0x00000000) /* 0.000000000 */,
okini3939 0:8ba6230eefbd 450 MAD_F(0x0361962f) /* 0.211324865 */,
okini3939 0:8ba6230eefbd 451 MAD_F(0x05db3d74) /* 0.366025404 */,
okini3939 0:8ba6230eefbd 452 MAD_F(0x08000000) /* 0.500000000 */,
okini3939 0:8ba6230eefbd 453 MAD_F(0x0a24c28c) /* 0.633974596 */,
okini3939 0:8ba6230eefbd 454 MAD_F(0x0c9e69d1) /* 0.788675135 */,
okini3939 0:8ba6230eefbd 455 MAD_F(0x10000000) /* 1.000000000 */
okini3939 0:8ba6230eefbd 456 };
okini3939 0:8ba6230eefbd 457
okini3939 0:8ba6230eefbd 458 /*
okini3939 0:8ba6230eefbd 459 * coefficients for LSF intensity stereo processing
okini3939 0:8ba6230eefbd 460 * derived from section 2.4.3.2 of ISO/IEC 13818-3
okini3939 0:8ba6230eefbd 461 *
okini3939 0:8ba6230eefbd 462 * is_lsf_table[0][i] = (1 / sqrt(sqrt(2)))^(i + 1)
okini3939 0:8ba6230eefbd 463 * is_lsf_table[1][i] = (1 / sqrt(2)) ^(i + 1)
okini3939 0:8ba6230eefbd 464 */
okini3939 0:8ba6230eefbd 465 static
okini3939 0:8ba6230eefbd 466 mad_fixed_t const is_lsf_table[2][15] = {
okini3939 0:8ba6230eefbd 467 {
okini3939 0:8ba6230eefbd 468 MAD_F(0x0d744fcd) /* 0.840896415 */,
okini3939 0:8ba6230eefbd 469 MAD_F(0x0b504f33) /* 0.707106781 */,
okini3939 0:8ba6230eefbd 470 MAD_F(0x09837f05) /* 0.594603558 */,
okini3939 0:8ba6230eefbd 471 MAD_F(0x08000000) /* 0.500000000 */,
okini3939 0:8ba6230eefbd 472 MAD_F(0x06ba27e6) /* 0.420448208 */,
okini3939 0:8ba6230eefbd 473 MAD_F(0x05a8279a) /* 0.353553391 */,
okini3939 0:8ba6230eefbd 474 MAD_F(0x04c1bf83) /* 0.297301779 */,
okini3939 0:8ba6230eefbd 475 MAD_F(0x04000000) /* 0.250000000 */,
okini3939 0:8ba6230eefbd 476 MAD_F(0x035d13f3) /* 0.210224104 */,
okini3939 0:8ba6230eefbd 477 MAD_F(0x02d413cd) /* 0.176776695 */,
okini3939 0:8ba6230eefbd 478 MAD_F(0x0260dfc1) /* 0.148650889 */,
okini3939 0:8ba6230eefbd 479 MAD_F(0x02000000) /* 0.125000000 */,
okini3939 0:8ba6230eefbd 480 MAD_F(0x01ae89fa) /* 0.105112052 */,
okini3939 0:8ba6230eefbd 481 MAD_F(0x016a09e6) /* 0.088388348 */,
okini3939 0:8ba6230eefbd 482 MAD_F(0x01306fe1) /* 0.074325445 */
okini3939 0:8ba6230eefbd 483 }, {
okini3939 0:8ba6230eefbd 484 MAD_F(0x0b504f33) /* 0.707106781 */,
okini3939 0:8ba6230eefbd 485 MAD_F(0x08000000) /* 0.500000000 */,
okini3939 0:8ba6230eefbd 486 MAD_F(0x05a8279a) /* 0.353553391 */,
okini3939 0:8ba6230eefbd 487 MAD_F(0x04000000) /* 0.250000000 */,
okini3939 0:8ba6230eefbd 488 MAD_F(0x02d413cd) /* 0.176776695 */,
okini3939 0:8ba6230eefbd 489 MAD_F(0x02000000) /* 0.125000000 */,
okini3939 0:8ba6230eefbd 490 MAD_F(0x016a09e6) /* 0.088388348 */,
okini3939 0:8ba6230eefbd 491 MAD_F(0x01000000) /* 0.062500000 */,
okini3939 0:8ba6230eefbd 492 MAD_F(0x00b504f3) /* 0.044194174 */,
okini3939 0:8ba6230eefbd 493 MAD_F(0x00800000) /* 0.031250000 */,
okini3939 0:8ba6230eefbd 494 MAD_F(0x005a827a) /* 0.022097087 */,
okini3939 0:8ba6230eefbd 495 MAD_F(0x00400000) /* 0.015625000 */,
okini3939 0:8ba6230eefbd 496 MAD_F(0x002d413d) /* 0.011048543 */,
okini3939 0:8ba6230eefbd 497 MAD_F(0x00200000) /* 0.007812500 */,
okini3939 0:8ba6230eefbd 498 MAD_F(0x0016a09e) /* 0.005524272 */
okini3939 0:8ba6230eefbd 499 }
okini3939 0:8ba6230eefbd 500 };
okini3939 0:8ba6230eefbd 501
okini3939 0:8ba6230eefbd 502 /*
okini3939 0:8ba6230eefbd 503 * NAME: III_sideinfo()
okini3939 0:8ba6230eefbd 504 * DESCRIPTION: decode frame side information from a bitstream
okini3939 0:8ba6230eefbd 505 */
okini3939 0:8ba6230eefbd 506 static
okini3939 0:8ba6230eefbd 507 enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch,
okini3939 0:8ba6230eefbd 508 int lsf, struct sideinfo *si,
okini3939 0:8ba6230eefbd 509 unsigned int *data_bitlen,
okini3939 0:8ba6230eefbd 510 unsigned int *priv_bitlen)
okini3939 0:8ba6230eefbd 511 {
okini3939 0:8ba6230eefbd 512 unsigned int ngr, gr, ch, i;
okini3939 0:8ba6230eefbd 513 enum mad_error result = MAD_ERROR_NONE;
okini3939 0:8ba6230eefbd 514
okini3939 0:8ba6230eefbd 515 *data_bitlen = 0;
okini3939 0:8ba6230eefbd 516 *priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3);
okini3939 0:8ba6230eefbd 517
okini3939 0:8ba6230eefbd 518 si->main_data_begin = mad_bit_read(ptr, lsf ? 8 : 9);
okini3939 0:8ba6230eefbd 519 si->private_bits = mad_bit_read(ptr, *priv_bitlen);
okini3939 0:8ba6230eefbd 520
okini3939 0:8ba6230eefbd 521 ngr = 1;
okini3939 0:8ba6230eefbd 522 if (!lsf) {
okini3939 0:8ba6230eefbd 523 ngr = 2;
okini3939 0:8ba6230eefbd 524
okini3939 0:8ba6230eefbd 525 for (ch = 0; ch < nch; ++ch)
okini3939 0:8ba6230eefbd 526 si->scfsi[ch] = mad_bit_read(ptr, 4);
okini3939 0:8ba6230eefbd 527 }
okini3939 0:8ba6230eefbd 528
okini3939 0:8ba6230eefbd 529 for (gr = 0; gr < ngr; ++gr) {
okini3939 0:8ba6230eefbd 530 struct granule *granule = &si->gr[gr];
okini3939 0:8ba6230eefbd 531
okini3939 0:8ba6230eefbd 532 for (ch = 0; ch < nch; ++ch) {
okini3939 0:8ba6230eefbd 533 struct channel *channel = &granule->ch[ch];
okini3939 0:8ba6230eefbd 534
okini3939 0:8ba6230eefbd 535 channel->part2_3_length = mad_bit_read(ptr, 12);
okini3939 0:8ba6230eefbd 536 channel->big_values = mad_bit_read(ptr, 9);
okini3939 0:8ba6230eefbd 537 channel->global_gain = mad_bit_read(ptr, 8);
okini3939 0:8ba6230eefbd 538 channel->scalefac_compress = mad_bit_read(ptr, lsf ? 9 : 4);
okini3939 0:8ba6230eefbd 539
okini3939 0:8ba6230eefbd 540 *data_bitlen += channel->part2_3_length;
okini3939 0:8ba6230eefbd 541
okini3939 0:8ba6230eefbd 542 if (channel->big_values > 288 && result == 0)
okini3939 0:8ba6230eefbd 543 result = MAD_ERROR_BADBIGVALUES;
okini3939 0:8ba6230eefbd 544
okini3939 0:8ba6230eefbd 545 channel->flags = 0;
okini3939 0:8ba6230eefbd 546
okini3939 0:8ba6230eefbd 547 /* window_switching_flag */
okini3939 0:8ba6230eefbd 548 if (mad_bit_read(ptr, 1)) {
okini3939 0:8ba6230eefbd 549 channel->block_type = mad_bit_read(ptr, 2);
okini3939 0:8ba6230eefbd 550
okini3939 0:8ba6230eefbd 551 if (channel->block_type == 0 && result == 0)
okini3939 0:8ba6230eefbd 552 result = MAD_ERROR_BADBLOCKTYPE;
okini3939 0:8ba6230eefbd 553
okini3939 0:8ba6230eefbd 554 if (!lsf && channel->block_type == 2 && si->scfsi[ch] && result == 0)
okini3939 0:8ba6230eefbd 555 result = MAD_ERROR_BADSCFSI;
okini3939 0:8ba6230eefbd 556
okini3939 0:8ba6230eefbd 557 channel->region0_count = 7;
okini3939 0:8ba6230eefbd 558 channel->region1_count = 36;
okini3939 0:8ba6230eefbd 559
okini3939 0:8ba6230eefbd 560 if (mad_bit_read(ptr, 1))
okini3939 0:8ba6230eefbd 561 channel->flags |= mixed_block_flag;
okini3939 0:8ba6230eefbd 562 else if (channel->block_type == 2)
okini3939 0:8ba6230eefbd 563 channel->region0_count = 8;
okini3939 0:8ba6230eefbd 564
okini3939 0:8ba6230eefbd 565 for (i = 0; i < 2; ++i)
okini3939 0:8ba6230eefbd 566 channel->table_select[i] = mad_bit_read(ptr, 5);
okini3939 0:8ba6230eefbd 567
okini3939 0:8ba6230eefbd 568 # if defined(DEBUG)
okini3939 0:8ba6230eefbd 569 channel->table_select[2] = 4; /* not used */
okini3939 0:8ba6230eefbd 570 # endif
okini3939 0:8ba6230eefbd 571
okini3939 0:8ba6230eefbd 572 for (i = 0; i < 3; ++i)
okini3939 0:8ba6230eefbd 573 channel->subblock_gain[i] = mad_bit_read(ptr, 3);
okini3939 0:8ba6230eefbd 574 }
okini3939 0:8ba6230eefbd 575 else {
okini3939 0:8ba6230eefbd 576 channel->block_type = 0;
okini3939 0:8ba6230eefbd 577
okini3939 0:8ba6230eefbd 578 for (i = 0; i < 3; ++i)
okini3939 0:8ba6230eefbd 579 channel->table_select[i] = mad_bit_read(ptr, 5);
okini3939 0:8ba6230eefbd 580
okini3939 0:8ba6230eefbd 581 channel->region0_count = mad_bit_read(ptr, 4);
okini3939 0:8ba6230eefbd 582 channel->region1_count = mad_bit_read(ptr, 3);
okini3939 0:8ba6230eefbd 583 }
okini3939 0:8ba6230eefbd 584
okini3939 0:8ba6230eefbd 585 /* [preflag,] scalefac_scale, count1table_select */
okini3939 0:8ba6230eefbd 586 channel->flags |= mad_bit_read(ptr, lsf ? 2 : 3);
okini3939 0:8ba6230eefbd 587 }
okini3939 0:8ba6230eefbd 588 }
okini3939 0:8ba6230eefbd 589
okini3939 0:8ba6230eefbd 590 return result;
okini3939 0:8ba6230eefbd 591 }
okini3939 0:8ba6230eefbd 592
okini3939 0:8ba6230eefbd 593 /*
okini3939 0:8ba6230eefbd 594 * NAME: III_scalefactors_lsf()
okini3939 0:8ba6230eefbd 595 * DESCRIPTION: decode channel scalefactors for LSF from a bitstream
okini3939 0:8ba6230eefbd 596 */
okini3939 0:8ba6230eefbd 597 static
okini3939 0:8ba6230eefbd 598 unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr,
okini3939 0:8ba6230eefbd 599 struct channel *channel,
okini3939 0:8ba6230eefbd 600 struct channel *gr1ch, int mode_extension)
okini3939 0:8ba6230eefbd 601 {
okini3939 0:8ba6230eefbd 602 struct mad_bitptr start;
okini3939 0:8ba6230eefbd 603 unsigned int scalefac_compress, index, slen[4], part, n, i;
okini3939 0:8ba6230eefbd 604 unsigned char const *nsfb;
okini3939 0:8ba6230eefbd 605
okini3939 0:8ba6230eefbd 606 start = *ptr;
okini3939 0:8ba6230eefbd 607
okini3939 0:8ba6230eefbd 608 scalefac_compress = channel->scalefac_compress;
okini3939 0:8ba6230eefbd 609 index = (channel->block_type == 2) ?
okini3939 0:8ba6230eefbd 610 ((channel->flags & mixed_block_flag) ? 2 : 1) : 0;
okini3939 0:8ba6230eefbd 611
okini3939 0:8ba6230eefbd 612 if (!((mode_extension & I_STEREO) && gr1ch)) {
okini3939 0:8ba6230eefbd 613 if (scalefac_compress < 400) {
okini3939 0:8ba6230eefbd 614 slen[0] = (scalefac_compress >> 4) / 5;
okini3939 0:8ba6230eefbd 615 slen[1] = (scalefac_compress >> 4) % 5;
okini3939 0:8ba6230eefbd 616 slen[2] = (scalefac_compress % 16) >> 2;
okini3939 0:8ba6230eefbd 617 slen[3] = scalefac_compress % 4;
okini3939 0:8ba6230eefbd 618
okini3939 0:8ba6230eefbd 619 nsfb = nsfb_table[0][index];
okini3939 0:8ba6230eefbd 620 }
okini3939 0:8ba6230eefbd 621 else if (scalefac_compress < 500) {
okini3939 0:8ba6230eefbd 622 scalefac_compress -= 400;
okini3939 0:8ba6230eefbd 623
okini3939 0:8ba6230eefbd 624 slen[0] = (scalefac_compress >> 2) / 5;
okini3939 0:8ba6230eefbd 625 slen[1] = (scalefac_compress >> 2) % 5;
okini3939 0:8ba6230eefbd 626 slen[2] = scalefac_compress % 4;
okini3939 0:8ba6230eefbd 627 slen[3] = 0;
okini3939 0:8ba6230eefbd 628
okini3939 0:8ba6230eefbd 629 nsfb = nsfb_table[1][index];
okini3939 0:8ba6230eefbd 630 }
okini3939 0:8ba6230eefbd 631 else {
okini3939 0:8ba6230eefbd 632 scalefac_compress -= 500;
okini3939 0:8ba6230eefbd 633
okini3939 0:8ba6230eefbd 634 slen[0] = scalefac_compress / 3;
okini3939 0:8ba6230eefbd 635 slen[1] = scalefac_compress % 3;
okini3939 0:8ba6230eefbd 636 slen[2] = 0;
okini3939 0:8ba6230eefbd 637 slen[3] = 0;
okini3939 0:8ba6230eefbd 638
okini3939 0:8ba6230eefbd 639 channel->flags |= preflag;
okini3939 0:8ba6230eefbd 640
okini3939 0:8ba6230eefbd 641 nsfb = nsfb_table[2][index];
okini3939 0:8ba6230eefbd 642 }
okini3939 0:8ba6230eefbd 643
okini3939 0:8ba6230eefbd 644 n = 0;
okini3939 0:8ba6230eefbd 645 for (part = 0; part < 4; ++part) {
okini3939 0:8ba6230eefbd 646 for (i = 0; i < nsfb[part]; ++i)
okini3939 0:8ba6230eefbd 647 channel->scalefac[n++] = mad_bit_read(ptr, slen[part]);
okini3939 0:8ba6230eefbd 648 }
okini3939 0:8ba6230eefbd 649
okini3939 0:8ba6230eefbd 650 while (n < 39)
okini3939 0:8ba6230eefbd 651 channel->scalefac[n++] = 0;
okini3939 0:8ba6230eefbd 652 }
okini3939 0:8ba6230eefbd 653 else { /* (mode_extension & I_STEREO) && gr1ch (i.e. ch == 1) */
okini3939 0:8ba6230eefbd 654 scalefac_compress >>= 1;
okini3939 0:8ba6230eefbd 655
okini3939 0:8ba6230eefbd 656 if (scalefac_compress < 180) {
okini3939 0:8ba6230eefbd 657 slen[0] = scalefac_compress / 36;
okini3939 0:8ba6230eefbd 658 slen[1] = (scalefac_compress % 36) / 6;
okini3939 0:8ba6230eefbd 659 slen[2] = (scalefac_compress % 36) % 6;
okini3939 0:8ba6230eefbd 660 slen[3] = 0;
okini3939 0:8ba6230eefbd 661
okini3939 0:8ba6230eefbd 662 nsfb = nsfb_table[3][index];
okini3939 0:8ba6230eefbd 663 }
okini3939 0:8ba6230eefbd 664 else if (scalefac_compress < 244) {
okini3939 0:8ba6230eefbd 665 scalefac_compress -= 180;
okini3939 0:8ba6230eefbd 666
okini3939 0:8ba6230eefbd 667 slen[0] = (scalefac_compress % 64) >> 4;
okini3939 0:8ba6230eefbd 668 slen[1] = (scalefac_compress % 16) >> 2;
okini3939 0:8ba6230eefbd 669 slen[2] = scalefac_compress % 4;
okini3939 0:8ba6230eefbd 670 slen[3] = 0;
okini3939 0:8ba6230eefbd 671
okini3939 0:8ba6230eefbd 672 nsfb = nsfb_table[4][index];
okini3939 0:8ba6230eefbd 673 }
okini3939 0:8ba6230eefbd 674 else {
okini3939 0:8ba6230eefbd 675 scalefac_compress -= 244;
okini3939 0:8ba6230eefbd 676
okini3939 0:8ba6230eefbd 677 slen[0] = scalefac_compress / 3;
okini3939 0:8ba6230eefbd 678 slen[1] = scalefac_compress % 3;
okini3939 0:8ba6230eefbd 679 slen[2] = 0;
okini3939 0:8ba6230eefbd 680 slen[3] = 0;
okini3939 0:8ba6230eefbd 681
okini3939 0:8ba6230eefbd 682 nsfb = nsfb_table[5][index];
okini3939 0:8ba6230eefbd 683 }
okini3939 0:8ba6230eefbd 684
okini3939 0:8ba6230eefbd 685 n = 0;
okini3939 0:8ba6230eefbd 686 for (part = 0; part < 4; ++part) {
okini3939 0:8ba6230eefbd 687 unsigned int max, is_pos;
okini3939 0:8ba6230eefbd 688
okini3939 0:8ba6230eefbd 689 max = (1 << slen[part]) - 1;
okini3939 0:8ba6230eefbd 690
okini3939 0:8ba6230eefbd 691 for (i = 0; i < nsfb[part]; ++i) {
okini3939 0:8ba6230eefbd 692 is_pos = mad_bit_read(ptr, slen[part]);
okini3939 0:8ba6230eefbd 693
okini3939 0:8ba6230eefbd 694 channel->scalefac[n] = is_pos;
okini3939 0:8ba6230eefbd 695 gr1ch->scalefac[n++] = (is_pos == max);
okini3939 0:8ba6230eefbd 696 }
okini3939 0:8ba6230eefbd 697 }
okini3939 0:8ba6230eefbd 698
okini3939 0:8ba6230eefbd 699 while (n < 39) {
okini3939 0:8ba6230eefbd 700 channel->scalefac[n] = 0;
okini3939 0:8ba6230eefbd 701 gr1ch->scalefac[n++] = 0; /* apparently not illegal */
okini3939 0:8ba6230eefbd 702 }
okini3939 0:8ba6230eefbd 703 }
okini3939 0:8ba6230eefbd 704
okini3939 0:8ba6230eefbd 705 return mad_bit_length(&start, ptr);
okini3939 0:8ba6230eefbd 706 }
okini3939 0:8ba6230eefbd 707
okini3939 0:8ba6230eefbd 708 /*
okini3939 0:8ba6230eefbd 709 * NAME: III_scalefactors()
okini3939 0:8ba6230eefbd 710 * DESCRIPTION: decode channel scalefactors of one granule from a bitstream
okini3939 0:8ba6230eefbd 711 */
okini3939 0:8ba6230eefbd 712 static
okini3939 0:8ba6230eefbd 713 unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel,
okini3939 0:8ba6230eefbd 714 struct channel const *gr0ch, unsigned int scfsi)
okini3939 0:8ba6230eefbd 715 {
okini3939 0:8ba6230eefbd 716 struct mad_bitptr start;
okini3939 0:8ba6230eefbd 717 unsigned int slen1, slen2, sfbi;
okini3939 0:8ba6230eefbd 718
okini3939 0:8ba6230eefbd 719 start = *ptr;
okini3939 0:8ba6230eefbd 720
okini3939 0:8ba6230eefbd 721 slen1 = sflen_table[channel->scalefac_compress].slen1;
okini3939 0:8ba6230eefbd 722 slen2 = sflen_table[channel->scalefac_compress].slen2;
okini3939 0:8ba6230eefbd 723
okini3939 0:8ba6230eefbd 724 if (channel->block_type == 2) {
okini3939 0:8ba6230eefbd 725 unsigned int nsfb;
okini3939 0:8ba6230eefbd 726
okini3939 0:8ba6230eefbd 727 sfbi = 0;
okini3939 0:8ba6230eefbd 728
okini3939 0:8ba6230eefbd 729 nsfb = (channel->flags & mixed_block_flag) ? 8 + 3 * 3 : 6 * 3;
okini3939 0:8ba6230eefbd 730 while (nsfb--)
okini3939 0:8ba6230eefbd 731 channel->scalefac[sfbi++] = mad_bit_read(ptr, slen1);
okini3939 0:8ba6230eefbd 732
okini3939 0:8ba6230eefbd 733 nsfb = 6 * 3;
okini3939 0:8ba6230eefbd 734 while (nsfb--)
okini3939 0:8ba6230eefbd 735 channel->scalefac[sfbi++] = mad_bit_read(ptr, slen2);
okini3939 0:8ba6230eefbd 736
okini3939 0:8ba6230eefbd 737 nsfb = 1 * 3;
okini3939 0:8ba6230eefbd 738 while (nsfb--)
okini3939 0:8ba6230eefbd 739 channel->scalefac[sfbi++] = 0;
okini3939 0:8ba6230eefbd 740 }
okini3939 0:8ba6230eefbd 741 else { /* channel->block_type != 2 */
okini3939 0:8ba6230eefbd 742 if (scfsi & 0x8) {
okini3939 0:8ba6230eefbd 743 for (sfbi = 0; sfbi < 6; ++sfbi)
okini3939 0:8ba6230eefbd 744 channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
okini3939 0:8ba6230eefbd 745 }
okini3939 0:8ba6230eefbd 746 else {
okini3939 0:8ba6230eefbd 747 for (sfbi = 0; sfbi < 6; ++sfbi)
okini3939 0:8ba6230eefbd 748 channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
okini3939 0:8ba6230eefbd 749 }
okini3939 0:8ba6230eefbd 750
okini3939 0:8ba6230eefbd 751 if (scfsi & 0x4) {
okini3939 0:8ba6230eefbd 752 for (sfbi = 6; sfbi < 11; ++sfbi)
okini3939 0:8ba6230eefbd 753 channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
okini3939 0:8ba6230eefbd 754 }
okini3939 0:8ba6230eefbd 755 else {
okini3939 0:8ba6230eefbd 756 for (sfbi = 6; sfbi < 11; ++sfbi)
okini3939 0:8ba6230eefbd 757 channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
okini3939 0:8ba6230eefbd 758 }
okini3939 0:8ba6230eefbd 759
okini3939 0:8ba6230eefbd 760 if (scfsi & 0x2) {
okini3939 0:8ba6230eefbd 761 for (sfbi = 11; sfbi < 16; ++sfbi)
okini3939 0:8ba6230eefbd 762 channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
okini3939 0:8ba6230eefbd 763 }
okini3939 0:8ba6230eefbd 764 else {
okini3939 0:8ba6230eefbd 765 for (sfbi = 11; sfbi < 16; ++sfbi)
okini3939 0:8ba6230eefbd 766 channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
okini3939 0:8ba6230eefbd 767 }
okini3939 0:8ba6230eefbd 768
okini3939 0:8ba6230eefbd 769 if (scfsi & 0x1) {
okini3939 0:8ba6230eefbd 770 for (sfbi = 16; sfbi < 21; ++sfbi)
okini3939 0:8ba6230eefbd 771 channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
okini3939 0:8ba6230eefbd 772 }
okini3939 0:8ba6230eefbd 773 else {
okini3939 0:8ba6230eefbd 774 for (sfbi = 16; sfbi < 21; ++sfbi)
okini3939 0:8ba6230eefbd 775 channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
okini3939 0:8ba6230eefbd 776 }
okini3939 0:8ba6230eefbd 777
okini3939 0:8ba6230eefbd 778 channel->scalefac[21] = 0;
okini3939 0:8ba6230eefbd 779 }
okini3939 0:8ba6230eefbd 780
okini3939 0:8ba6230eefbd 781 return mad_bit_length(&start, ptr);
okini3939 0:8ba6230eefbd 782 }
okini3939 0:8ba6230eefbd 783
okini3939 0:8ba6230eefbd 784 /*
okini3939 0:8ba6230eefbd 785 * The Layer III formula for requantization and scaling is defined by
okini3939 0:8ba6230eefbd 786 * section 2.4.3.4.7.1 of ISO/IEC 11172-3, as follows:
okini3939 0:8ba6230eefbd 787 *
okini3939 0:8ba6230eefbd 788 * long blocks:
okini3939 0:8ba6230eefbd 789 * xr[i] = sign(is[i]) * abs(is[i])^(4/3) *
okini3939 0:8ba6230eefbd 790 * 2^((1/4) * (global_gain - 210)) *
okini3939 0:8ba6230eefbd 791 * 2^-(scalefac_multiplier *
okini3939 0:8ba6230eefbd 792 * (scalefac_l[sfb] + preflag * pretab[sfb]))
okini3939 0:8ba6230eefbd 793 *
okini3939 0:8ba6230eefbd 794 * short blocks:
okini3939 0:8ba6230eefbd 795 * xr[i] = sign(is[i]) * abs(is[i])^(4/3) *
okini3939 0:8ba6230eefbd 796 * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) *
okini3939 0:8ba6230eefbd 797 * 2^-(scalefac_multiplier * scalefac_s[sfb][w])
okini3939 0:8ba6230eefbd 798 *
okini3939 0:8ba6230eefbd 799 * where:
okini3939 0:8ba6230eefbd 800 * scalefac_multiplier = (scalefac_scale + 1) / 2
okini3939 0:8ba6230eefbd 801 *
okini3939 0:8ba6230eefbd 802 * The routines III_exponents() and III_requantize() facilitate this
okini3939 0:8ba6230eefbd 803 * calculation.
okini3939 0:8ba6230eefbd 804 */
okini3939 0:8ba6230eefbd 805
okini3939 0:8ba6230eefbd 806 /*
okini3939 0:8ba6230eefbd 807 * NAME: III_exponents()
okini3939 0:8ba6230eefbd 808 * DESCRIPTION: calculate scalefactor exponents
okini3939 0:8ba6230eefbd 809 */
okini3939 0:8ba6230eefbd 810 static
okini3939 0:8ba6230eefbd 811 void III_exponents(struct channel const *channel,
okini3939 0:8ba6230eefbd 812 unsigned char const *sfbwidth, signed int exponents[39])
okini3939 0:8ba6230eefbd 813 {
okini3939 0:8ba6230eefbd 814 signed int gain;
okini3939 0:8ba6230eefbd 815 unsigned int scalefac_multiplier, sfbi;
okini3939 0:8ba6230eefbd 816
okini3939 0:8ba6230eefbd 817 gain = (signed int) channel->global_gain - 210;
okini3939 0:8ba6230eefbd 818 scalefac_multiplier = (channel->flags & scalefac_scale) ? 2 : 1;
okini3939 0:8ba6230eefbd 819
okini3939 0:8ba6230eefbd 820 if (channel->block_type == 2) {
okini3939 0:8ba6230eefbd 821 unsigned int l;
okini3939 0:8ba6230eefbd 822 signed int gain0, gain1, gain2;
okini3939 0:8ba6230eefbd 823
okini3939 0:8ba6230eefbd 824 sfbi = l = 0;
okini3939 0:8ba6230eefbd 825
okini3939 0:8ba6230eefbd 826 if (channel->flags & mixed_block_flag) {
okini3939 0:8ba6230eefbd 827 unsigned int premask;
okini3939 0:8ba6230eefbd 828
okini3939 0:8ba6230eefbd 829 premask = (channel->flags & preflag) ? ~0 : 0;
okini3939 0:8ba6230eefbd 830
okini3939 0:8ba6230eefbd 831 /* long block subbands 0-1 */
okini3939 0:8ba6230eefbd 832
okini3939 0:8ba6230eefbd 833 while (l < 36) {
okini3939 0:8ba6230eefbd 834 exponents[sfbi] = gain -
okini3939 0:8ba6230eefbd 835 (signed int) ((channel->scalefac[sfbi] + (pretab[sfbi] & premask)) <<
okini3939 0:8ba6230eefbd 836 scalefac_multiplier);
okini3939 0:8ba6230eefbd 837
okini3939 0:8ba6230eefbd 838 l += sfbwidth[sfbi++];
okini3939 0:8ba6230eefbd 839 }
okini3939 0:8ba6230eefbd 840 }
okini3939 0:8ba6230eefbd 841
okini3939 0:8ba6230eefbd 842 /* this is probably wrong for 8000 Hz short/mixed blocks */
okini3939 0:8ba6230eefbd 843
okini3939 0:8ba6230eefbd 844 gain0 = gain - 8 * (signed int) channel->subblock_gain[0];
okini3939 0:8ba6230eefbd 845 gain1 = gain - 8 * (signed int) channel->subblock_gain[1];
okini3939 0:8ba6230eefbd 846 gain2 = gain - 8 * (signed int) channel->subblock_gain[2];
okini3939 0:8ba6230eefbd 847
okini3939 0:8ba6230eefbd 848 while (l < 576) {
okini3939 0:8ba6230eefbd 849 exponents[sfbi + 0] = gain0 -
okini3939 0:8ba6230eefbd 850 (signed int) (channel->scalefac[sfbi + 0] << scalefac_multiplier);
okini3939 0:8ba6230eefbd 851 exponents[sfbi + 1] = gain1 -
okini3939 0:8ba6230eefbd 852 (signed int) (channel->scalefac[sfbi + 1] << scalefac_multiplier);
okini3939 0:8ba6230eefbd 853 exponents[sfbi + 2] = gain2 -
okini3939 0:8ba6230eefbd 854 (signed int) (channel->scalefac[sfbi + 2] << scalefac_multiplier);
okini3939 0:8ba6230eefbd 855
okini3939 0:8ba6230eefbd 856 l += 3 * sfbwidth[sfbi];
okini3939 0:8ba6230eefbd 857 sfbi += 3;
okini3939 0:8ba6230eefbd 858 }
okini3939 0:8ba6230eefbd 859 }
okini3939 0:8ba6230eefbd 860 else { /* channel->block_type != 2 */
okini3939 0:8ba6230eefbd 861 if (channel->flags & preflag) {
okini3939 0:8ba6230eefbd 862 for (sfbi = 0; sfbi < 22; ++sfbi) {
okini3939 0:8ba6230eefbd 863 exponents[sfbi] = gain -
okini3939 0:8ba6230eefbd 864 (signed int) ((channel->scalefac[sfbi] + pretab[sfbi]) <<
okini3939 0:8ba6230eefbd 865 scalefac_multiplier);
okini3939 0:8ba6230eefbd 866 }
okini3939 0:8ba6230eefbd 867 }
okini3939 0:8ba6230eefbd 868 else {
okini3939 0:8ba6230eefbd 869 for (sfbi = 0; sfbi < 22; ++sfbi) {
okini3939 0:8ba6230eefbd 870 exponents[sfbi] = gain -
okini3939 0:8ba6230eefbd 871 (signed int) (channel->scalefac[sfbi] << scalefac_multiplier);
okini3939 0:8ba6230eefbd 872 }
okini3939 0:8ba6230eefbd 873 }
okini3939 0:8ba6230eefbd 874 }
okini3939 0:8ba6230eefbd 875 }
okini3939 0:8ba6230eefbd 876
okini3939 0:8ba6230eefbd 877 /*
okini3939 0:8ba6230eefbd 878 * NAME: III_requantize()
okini3939 0:8ba6230eefbd 879 * DESCRIPTION: requantize one (positive) value
okini3939 0:8ba6230eefbd 880 */
okini3939 0:8ba6230eefbd 881 static
okini3939 0:8ba6230eefbd 882 mad_fixed_t III_requantize(unsigned int value, signed int exp)
okini3939 0:8ba6230eefbd 883 {
okini3939 0:8ba6230eefbd 884 mad_fixed_t requantized;
okini3939 0:8ba6230eefbd 885 signed int frac;
okini3939 0:8ba6230eefbd 886 struct fixedfloat const *power;
okini3939 0:8ba6230eefbd 887
okini3939 0:8ba6230eefbd 888 frac = exp % 4; /* assumes sign(frac) == sign(exp) */
okini3939 0:8ba6230eefbd 889 exp /= 4;
okini3939 0:8ba6230eefbd 890
okini3939 0:8ba6230eefbd 891 power = &rq_table[value];
okini3939 0:8ba6230eefbd 892 requantized = power->mantissa;
okini3939 0:8ba6230eefbd 893 exp += power->exponent;
okini3939 0:8ba6230eefbd 894
okini3939 0:8ba6230eefbd 895 if (exp < 0) {
okini3939 0:8ba6230eefbd 896 if (-exp >= sizeof(mad_fixed_t) * CHAR_BIT) {
okini3939 0:8ba6230eefbd 897 /* underflow */
okini3939 0:8ba6230eefbd 898 requantized = 0;
okini3939 0:8ba6230eefbd 899 }
okini3939 0:8ba6230eefbd 900 else {
okini3939 0:8ba6230eefbd 901 requantized += 1L << (-exp - 1);
okini3939 0:8ba6230eefbd 902 requantized >>= -exp;
okini3939 0:8ba6230eefbd 903 }
okini3939 0:8ba6230eefbd 904 }
okini3939 0:8ba6230eefbd 905 else {
okini3939 0:8ba6230eefbd 906 if (exp >= 5) {
okini3939 0:8ba6230eefbd 907 /* overflow */
okini3939 0:8ba6230eefbd 908 # if defined(DEBUG)
okini3939 0:8ba6230eefbd 909 fprintf(stderr, "requantize overflow (%f * 2^%d)\n",
okini3939 0:8ba6230eefbd 910 mad_f_todouble(requantized), exp);
okini3939 0:8ba6230eefbd 911 # endif
okini3939 0:8ba6230eefbd 912 requantized = MAD_F_MAX;
okini3939 0:8ba6230eefbd 913 }
okini3939 0:8ba6230eefbd 914 else
okini3939 0:8ba6230eefbd 915 requantized <<= exp;
okini3939 0:8ba6230eefbd 916 }
okini3939 0:8ba6230eefbd 917
okini3939 0:8ba6230eefbd 918 return frac ? mad_f_mul(requantized, root_table[3 + frac]) : requantized;
okini3939 0:8ba6230eefbd 919 }
okini3939 0:8ba6230eefbd 920
okini3939 0:8ba6230eefbd 921 /* we must take care that sz >= bits and sz < sizeof(long) lest bits == 0 */
okini3939 0:8ba6230eefbd 922 # define MASK(cache, sz, bits) \
okini3939 0:8ba6230eefbd 923 (((cache) >> ((sz) - (bits))) & ((1 << (bits)) - 1))
okini3939 0:8ba6230eefbd 924 # define MASK1BIT(cache, sz) \
okini3939 0:8ba6230eefbd 925 ((cache) & (1 << ((sz) - 1)))
okini3939 0:8ba6230eefbd 926
okini3939 0:8ba6230eefbd 927 /*
okini3939 0:8ba6230eefbd 928 * NAME: III_huffdecode()
okini3939 0:8ba6230eefbd 929 * DESCRIPTION: decode Huffman code words of one channel of one granule
okini3939 0:8ba6230eefbd 930 */
okini3939 0:8ba6230eefbd 931 static
okini3939 0:8ba6230eefbd 932 enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576],
okini3939 0:8ba6230eefbd 933 struct channel *channel,
okini3939 0:8ba6230eefbd 934 unsigned char const *sfbwidth,
okini3939 0:8ba6230eefbd 935 unsigned int part2_length)
okini3939 0:8ba6230eefbd 936 {
okini3939 0:8ba6230eefbd 937 signed int exponents[39], exp;
okini3939 0:8ba6230eefbd 938 signed int const *expptr;
okini3939 0:8ba6230eefbd 939 struct mad_bitptr peek;
okini3939 0:8ba6230eefbd 940 signed int bits_left, cachesz;
okini3939 0:8ba6230eefbd 941 register mad_fixed_t *xrptr;
okini3939 0:8ba6230eefbd 942 mad_fixed_t const *sfbound;
okini3939 0:8ba6230eefbd 943 register unsigned long bitcache;
okini3939 0:8ba6230eefbd 944
okini3939 0:8ba6230eefbd 945 bits_left = (signed) channel->part2_3_length - (signed) part2_length;
okini3939 0:8ba6230eefbd 946 if (bits_left < 0)
okini3939 0:8ba6230eefbd 947 return MAD_ERROR_BADPART3LEN;
okini3939 0:8ba6230eefbd 948
okini3939 0:8ba6230eefbd 949 III_exponents(channel, sfbwidth, exponents);
okini3939 0:8ba6230eefbd 950
okini3939 0:8ba6230eefbd 951 peek = *ptr;
okini3939 0:8ba6230eefbd 952 mad_bit_skip(ptr, bits_left);
okini3939 0:8ba6230eefbd 953
okini3939 0:8ba6230eefbd 954 /* align bit reads to byte boundaries */
okini3939 0:8ba6230eefbd 955 cachesz = mad_bit_bitsleft(&peek);
okini3939 0:8ba6230eefbd 956 cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7;
okini3939 0:8ba6230eefbd 957
okini3939 0:8ba6230eefbd 958 bitcache = mad_bit_read(&peek, cachesz);
okini3939 0:8ba6230eefbd 959 bits_left -= cachesz;
okini3939 0:8ba6230eefbd 960
okini3939 0:8ba6230eefbd 961 xrptr = &xr[0];
okini3939 0:8ba6230eefbd 962
okini3939 0:8ba6230eefbd 963 /* big_values */
okini3939 0:8ba6230eefbd 964 {
okini3939 0:8ba6230eefbd 965 unsigned int region, rcount;
okini3939 0:8ba6230eefbd 966 struct hufftable const *entry;
okini3939 0:8ba6230eefbd 967 union huffpair const *table;
okini3939 0:8ba6230eefbd 968 unsigned int linbits, startbits, big_values, reqhits;
okini3939 0:8ba6230eefbd 969 mad_fixed_t reqcache[16];
okini3939 0:8ba6230eefbd 970
okini3939 0:8ba6230eefbd 971 sfbound = xrptr + *sfbwidth++;
okini3939 0:8ba6230eefbd 972 rcount = channel->region0_count + 1;
okini3939 0:8ba6230eefbd 973
okini3939 0:8ba6230eefbd 974 entry = &mad_huff_pair_table[channel->table_select[region = 0]];
okini3939 0:8ba6230eefbd 975 table = entry->table;
okini3939 0:8ba6230eefbd 976 linbits = entry->linbits;
okini3939 0:8ba6230eefbd 977 startbits = entry->startbits;
okini3939 0:8ba6230eefbd 978
okini3939 0:8ba6230eefbd 979 if (table == 0)
okini3939 0:8ba6230eefbd 980 return MAD_ERROR_BADHUFFTABLE;
okini3939 0:8ba6230eefbd 981
okini3939 0:8ba6230eefbd 982 expptr = &exponents[0];
okini3939 0:8ba6230eefbd 983 exp = *expptr++;
okini3939 0:8ba6230eefbd 984 reqhits = 0;
okini3939 0:8ba6230eefbd 985
okini3939 0:8ba6230eefbd 986 big_values = channel->big_values;
okini3939 0:8ba6230eefbd 987
okini3939 0:8ba6230eefbd 988 while (big_values-- && cachesz + bits_left > 0) {
okini3939 0:8ba6230eefbd 989 union huffpair const *pair;
okini3939 0:8ba6230eefbd 990 unsigned int clumpsz, value;
okini3939 0:8ba6230eefbd 991 register mad_fixed_t requantized;
okini3939 0:8ba6230eefbd 992
okini3939 0:8ba6230eefbd 993 if (xrptr == sfbound) {
okini3939 0:8ba6230eefbd 994 sfbound += *sfbwidth++;
okini3939 0:8ba6230eefbd 995
okini3939 0:8ba6230eefbd 996 /* change table if region boundary */
okini3939 0:8ba6230eefbd 997
okini3939 0:8ba6230eefbd 998 if (--rcount == 0) {
okini3939 0:8ba6230eefbd 999 if (region == 0)
okini3939 0:8ba6230eefbd 1000 rcount = channel->region1_count + 1;
okini3939 0:8ba6230eefbd 1001 else
okini3939 0:8ba6230eefbd 1002 rcount = 0; /* all remaining */
okini3939 0:8ba6230eefbd 1003
okini3939 0:8ba6230eefbd 1004 entry = &mad_huff_pair_table[channel->table_select[++region]];
okini3939 0:8ba6230eefbd 1005 table = entry->table;
okini3939 0:8ba6230eefbd 1006 linbits = entry->linbits;
okini3939 0:8ba6230eefbd 1007 startbits = entry->startbits;
okini3939 0:8ba6230eefbd 1008
okini3939 0:8ba6230eefbd 1009 if (table == 0)
okini3939 0:8ba6230eefbd 1010 return MAD_ERROR_BADHUFFTABLE;
okini3939 0:8ba6230eefbd 1011 }
okini3939 0:8ba6230eefbd 1012
okini3939 0:8ba6230eefbd 1013 if (exp != *expptr) {
okini3939 0:8ba6230eefbd 1014 exp = *expptr;
okini3939 0:8ba6230eefbd 1015 reqhits = 0;
okini3939 0:8ba6230eefbd 1016 }
okini3939 0:8ba6230eefbd 1017
okini3939 0:8ba6230eefbd 1018 ++expptr;
okini3939 0:8ba6230eefbd 1019 }
okini3939 0:8ba6230eefbd 1020
okini3939 0:8ba6230eefbd 1021 if (cachesz < 21) {
okini3939 0:8ba6230eefbd 1022 unsigned int bits;
okini3939 0:8ba6230eefbd 1023
okini3939 0:8ba6230eefbd 1024 bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7;
okini3939 0:8ba6230eefbd 1025 bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
okini3939 0:8ba6230eefbd 1026 cachesz += bits;
okini3939 0:8ba6230eefbd 1027 bits_left -= bits;
okini3939 0:8ba6230eefbd 1028 }
okini3939 0:8ba6230eefbd 1029
okini3939 0:8ba6230eefbd 1030 /* hcod (0..19) */
okini3939 0:8ba6230eefbd 1031
okini3939 0:8ba6230eefbd 1032 clumpsz = startbits;
okini3939 0:8ba6230eefbd 1033 pair = &table[MASK(bitcache, cachesz, clumpsz)];
okini3939 0:8ba6230eefbd 1034
okini3939 0:8ba6230eefbd 1035 while (!pair->final) {
okini3939 0:8ba6230eefbd 1036 cachesz -= clumpsz;
okini3939 0:8ba6230eefbd 1037
okini3939 0:8ba6230eefbd 1038 clumpsz = pair->ptr.bits;
okini3939 0:8ba6230eefbd 1039 pair = &table[pair->ptr.offset + MASK(bitcache, cachesz, clumpsz)];
okini3939 0:8ba6230eefbd 1040 }
okini3939 0:8ba6230eefbd 1041
okini3939 0:8ba6230eefbd 1042 cachesz -= pair->value.hlen;
okini3939 0:8ba6230eefbd 1043
okini3939 0:8ba6230eefbd 1044 if (linbits) {
okini3939 0:8ba6230eefbd 1045 /* x (0..14) */
okini3939 0:8ba6230eefbd 1046
okini3939 0:8ba6230eefbd 1047 value = pair->value.x;
okini3939 0:8ba6230eefbd 1048
okini3939 0:8ba6230eefbd 1049 switch (value) {
okini3939 0:8ba6230eefbd 1050 case 0:
okini3939 0:8ba6230eefbd 1051 xrptr[0] = 0;
okini3939 0:8ba6230eefbd 1052 break;
okini3939 0:8ba6230eefbd 1053
okini3939 0:8ba6230eefbd 1054 case 15:
okini3939 0:8ba6230eefbd 1055 if (cachesz < linbits + 2) {
okini3939 0:8ba6230eefbd 1056 bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
okini3939 0:8ba6230eefbd 1057 cachesz += 16;
okini3939 0:8ba6230eefbd 1058 bits_left -= 16;
okini3939 0:8ba6230eefbd 1059 }
okini3939 0:8ba6230eefbd 1060
okini3939 0:8ba6230eefbd 1061 value += MASK(bitcache, cachesz, linbits);
okini3939 0:8ba6230eefbd 1062 cachesz -= linbits;
okini3939 0:8ba6230eefbd 1063
okini3939 0:8ba6230eefbd 1064 requantized = III_requantize(value, exp);
okini3939 0:8ba6230eefbd 1065 goto x_final;
okini3939 0:8ba6230eefbd 1066
okini3939 0:8ba6230eefbd 1067 default:
okini3939 0:8ba6230eefbd 1068 if (reqhits & (1 << value))
okini3939 0:8ba6230eefbd 1069 requantized = reqcache[value];
okini3939 0:8ba6230eefbd 1070 else {
okini3939 0:8ba6230eefbd 1071 reqhits |= (1 << value);
okini3939 0:8ba6230eefbd 1072 requantized = reqcache[value] = III_requantize(value, exp);
okini3939 0:8ba6230eefbd 1073 }
okini3939 0:8ba6230eefbd 1074
okini3939 0:8ba6230eefbd 1075 x_final:
okini3939 0:8ba6230eefbd 1076 xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
okini3939 0:8ba6230eefbd 1077 -requantized : requantized;
okini3939 0:8ba6230eefbd 1078 }
okini3939 0:8ba6230eefbd 1079
okini3939 0:8ba6230eefbd 1080 /* y (0..14) */
okini3939 0:8ba6230eefbd 1081
okini3939 0:8ba6230eefbd 1082 value = pair->value.y;
okini3939 0:8ba6230eefbd 1083
okini3939 0:8ba6230eefbd 1084 switch (value) {
okini3939 0:8ba6230eefbd 1085 case 0:
okini3939 0:8ba6230eefbd 1086 xrptr[1] = 0;
okini3939 0:8ba6230eefbd 1087 break;
okini3939 0:8ba6230eefbd 1088
okini3939 0:8ba6230eefbd 1089 case 15:
okini3939 0:8ba6230eefbd 1090 if (cachesz < linbits + 1) {
okini3939 0:8ba6230eefbd 1091 bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
okini3939 0:8ba6230eefbd 1092 cachesz += 16;
okini3939 0:8ba6230eefbd 1093 bits_left -= 16;
okini3939 0:8ba6230eefbd 1094 }
okini3939 0:8ba6230eefbd 1095
okini3939 0:8ba6230eefbd 1096 value += MASK(bitcache, cachesz, linbits);
okini3939 0:8ba6230eefbd 1097 cachesz -= linbits;
okini3939 0:8ba6230eefbd 1098
okini3939 0:8ba6230eefbd 1099 requantized = III_requantize(value, exp);
okini3939 0:8ba6230eefbd 1100 goto y_final;
okini3939 0:8ba6230eefbd 1101
okini3939 0:8ba6230eefbd 1102 default:
okini3939 0:8ba6230eefbd 1103 if (reqhits & (1 << value))
okini3939 0:8ba6230eefbd 1104 requantized = reqcache[value];
okini3939 0:8ba6230eefbd 1105 else {
okini3939 0:8ba6230eefbd 1106 reqhits |= (1 << value);
okini3939 0:8ba6230eefbd 1107 requantized = reqcache[value] = III_requantize(value, exp);
okini3939 0:8ba6230eefbd 1108 }
okini3939 0:8ba6230eefbd 1109
okini3939 0:8ba6230eefbd 1110 y_final:
okini3939 0:8ba6230eefbd 1111 xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
okini3939 0:8ba6230eefbd 1112 -requantized : requantized;
okini3939 0:8ba6230eefbd 1113 }
okini3939 0:8ba6230eefbd 1114 }
okini3939 0:8ba6230eefbd 1115 else {
okini3939 0:8ba6230eefbd 1116 /* x (0..1) */
okini3939 0:8ba6230eefbd 1117
okini3939 0:8ba6230eefbd 1118 value = pair->value.x;
okini3939 0:8ba6230eefbd 1119
okini3939 0:8ba6230eefbd 1120 if (value == 0)
okini3939 0:8ba6230eefbd 1121 xrptr[0] = 0;
okini3939 0:8ba6230eefbd 1122 else {
okini3939 0:8ba6230eefbd 1123 if (reqhits & (1 << value))
okini3939 0:8ba6230eefbd 1124 requantized = reqcache[value];
okini3939 0:8ba6230eefbd 1125 else {
okini3939 0:8ba6230eefbd 1126 reqhits |= (1 << value);
okini3939 0:8ba6230eefbd 1127 requantized = reqcache[value] = III_requantize(value, exp);
okini3939 0:8ba6230eefbd 1128 }
okini3939 0:8ba6230eefbd 1129
okini3939 0:8ba6230eefbd 1130 xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
okini3939 0:8ba6230eefbd 1131 -requantized : requantized;
okini3939 0:8ba6230eefbd 1132 }
okini3939 0:8ba6230eefbd 1133
okini3939 0:8ba6230eefbd 1134 /* y (0..1) */
okini3939 0:8ba6230eefbd 1135
okini3939 0:8ba6230eefbd 1136 value = pair->value.y;
okini3939 0:8ba6230eefbd 1137
okini3939 0:8ba6230eefbd 1138 if (value == 0)
okini3939 0:8ba6230eefbd 1139 xrptr[1] = 0;
okini3939 0:8ba6230eefbd 1140 else {
okini3939 0:8ba6230eefbd 1141 if (reqhits & (1 << value))
okini3939 0:8ba6230eefbd 1142 requantized = reqcache[value];
okini3939 0:8ba6230eefbd 1143 else {
okini3939 0:8ba6230eefbd 1144 reqhits |= (1 << value);
okini3939 0:8ba6230eefbd 1145 requantized = reqcache[value] = III_requantize(value, exp);
okini3939 0:8ba6230eefbd 1146 }
okini3939 0:8ba6230eefbd 1147
okini3939 0:8ba6230eefbd 1148 xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
okini3939 0:8ba6230eefbd 1149 -requantized : requantized;
okini3939 0:8ba6230eefbd 1150 }
okini3939 0:8ba6230eefbd 1151 }
okini3939 0:8ba6230eefbd 1152
okini3939 0:8ba6230eefbd 1153 xrptr += 2;
okini3939 0:8ba6230eefbd 1154 }
okini3939 0:8ba6230eefbd 1155 }
okini3939 0:8ba6230eefbd 1156
okini3939 0:8ba6230eefbd 1157 if (cachesz + bits_left < 0)
okini3939 0:8ba6230eefbd 1158 return MAD_ERROR_BADHUFFDATA; /* big_values overrun */
okini3939 0:8ba6230eefbd 1159
okini3939 0:8ba6230eefbd 1160 /* count1 */
okini3939 0:8ba6230eefbd 1161 {
okini3939 0:8ba6230eefbd 1162 union huffquad const *table;
okini3939 0:8ba6230eefbd 1163 register mad_fixed_t requantized;
okini3939 0:8ba6230eefbd 1164
okini3939 0:8ba6230eefbd 1165 table = mad_huff_quad_table[channel->flags & count1table_select];
okini3939 0:8ba6230eefbd 1166
okini3939 0:8ba6230eefbd 1167 requantized = III_requantize(1, exp);
okini3939 0:8ba6230eefbd 1168
okini3939 0:8ba6230eefbd 1169 while (cachesz + bits_left > 0 && xrptr <= &xr[572]) {
okini3939 0:8ba6230eefbd 1170 union huffquad const *quad;
okini3939 0:8ba6230eefbd 1171
okini3939 0:8ba6230eefbd 1172 /* hcod (1..6) */
okini3939 0:8ba6230eefbd 1173
okini3939 0:8ba6230eefbd 1174 if (cachesz < 10) {
okini3939 0:8ba6230eefbd 1175 bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
okini3939 0:8ba6230eefbd 1176 cachesz += 16;
okini3939 0:8ba6230eefbd 1177 bits_left -= 16;
okini3939 0:8ba6230eefbd 1178 }
okini3939 0:8ba6230eefbd 1179
okini3939 0:8ba6230eefbd 1180 quad = &table[MASK(bitcache, cachesz, 4)];
okini3939 0:8ba6230eefbd 1181
okini3939 0:8ba6230eefbd 1182 /* quad tables guaranteed to have at most one extra lookup */
okini3939 0:8ba6230eefbd 1183 if (!quad->final) {
okini3939 0:8ba6230eefbd 1184 cachesz -= 4;
okini3939 0:8ba6230eefbd 1185
okini3939 0:8ba6230eefbd 1186 quad = &table[quad->ptr.offset +
okini3939 0:8ba6230eefbd 1187 MASK(bitcache, cachesz, quad->ptr.bits)];
okini3939 0:8ba6230eefbd 1188 }
okini3939 0:8ba6230eefbd 1189
okini3939 0:8ba6230eefbd 1190 cachesz -= quad->value.hlen;
okini3939 0:8ba6230eefbd 1191
okini3939 0:8ba6230eefbd 1192 if (xrptr == sfbound) {
okini3939 0:8ba6230eefbd 1193 sfbound += *sfbwidth++;
okini3939 0:8ba6230eefbd 1194
okini3939 0:8ba6230eefbd 1195 if (exp != *expptr) {
okini3939 0:8ba6230eefbd 1196 exp = *expptr;
okini3939 0:8ba6230eefbd 1197 requantized = III_requantize(1, exp);
okini3939 0:8ba6230eefbd 1198 }
okini3939 0:8ba6230eefbd 1199
okini3939 0:8ba6230eefbd 1200 ++expptr;
okini3939 0:8ba6230eefbd 1201 }
okini3939 0:8ba6230eefbd 1202
okini3939 0:8ba6230eefbd 1203 /* v (0..1) */
okini3939 0:8ba6230eefbd 1204
okini3939 0:8ba6230eefbd 1205 xrptr[0] = quad->value.v ?
okini3939 0:8ba6230eefbd 1206 (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
okini3939 0:8ba6230eefbd 1207
okini3939 0:8ba6230eefbd 1208 /* w (0..1) */
okini3939 0:8ba6230eefbd 1209
okini3939 0:8ba6230eefbd 1210 xrptr[1] = quad->value.w ?
okini3939 0:8ba6230eefbd 1211 (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
okini3939 0:8ba6230eefbd 1212
okini3939 0:8ba6230eefbd 1213 xrptr += 2;
okini3939 0:8ba6230eefbd 1214
okini3939 0:8ba6230eefbd 1215 if (xrptr == sfbound) {
okini3939 0:8ba6230eefbd 1216 sfbound += *sfbwidth++;
okini3939 0:8ba6230eefbd 1217
okini3939 0:8ba6230eefbd 1218 if (exp != *expptr) {
okini3939 0:8ba6230eefbd 1219 exp = *expptr;
okini3939 0:8ba6230eefbd 1220 requantized = III_requantize(1, exp);
okini3939 0:8ba6230eefbd 1221 }
okini3939 0:8ba6230eefbd 1222
okini3939 0:8ba6230eefbd 1223 ++expptr;
okini3939 0:8ba6230eefbd 1224 }
okini3939 0:8ba6230eefbd 1225
okini3939 0:8ba6230eefbd 1226 /* x (0..1) */
okini3939 0:8ba6230eefbd 1227
okini3939 0:8ba6230eefbd 1228 xrptr[0] = quad->value.x ?
okini3939 0:8ba6230eefbd 1229 (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
okini3939 0:8ba6230eefbd 1230
okini3939 0:8ba6230eefbd 1231 /* y (0..1) */
okini3939 0:8ba6230eefbd 1232
okini3939 0:8ba6230eefbd 1233 xrptr[1] = quad->value.y ?
okini3939 0:8ba6230eefbd 1234 (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
okini3939 0:8ba6230eefbd 1235
okini3939 0:8ba6230eefbd 1236 xrptr += 2;
okini3939 0:8ba6230eefbd 1237 }
okini3939 0:8ba6230eefbd 1238
okini3939 0:8ba6230eefbd 1239 if (cachesz + bits_left < 0) {
okini3939 0:8ba6230eefbd 1240 # if 0 && defined(DEBUG)
okini3939 0:8ba6230eefbd 1241 fprintf(stderr, "huffman count1 overrun (%d bits)\n",
okini3939 0:8ba6230eefbd 1242 -(cachesz + bits_left));
okini3939 0:8ba6230eefbd 1243 # endif
okini3939 0:8ba6230eefbd 1244
okini3939 0:8ba6230eefbd 1245 /* technically the bitstream is misformatted, but apparently
okini3939 0:8ba6230eefbd 1246 some encoders are just a bit sloppy with stuffing bits */
okini3939 0:8ba6230eefbd 1247
okini3939 0:8ba6230eefbd 1248 xrptr -= 4;
okini3939 0:8ba6230eefbd 1249 }
okini3939 0:8ba6230eefbd 1250 }
okini3939 0:8ba6230eefbd 1251
okini3939 0:8ba6230eefbd 1252 /* assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT);*/
okini3939 0:8ba6230eefbd 1253
okini3939 0:8ba6230eefbd 1254 # if 0 && defined(DEBUG)
okini3939 0:8ba6230eefbd 1255 if (bits_left < 0)
okini3939 0:8ba6230eefbd 1256 fprintf(stderr, "read %d bits too many\n", -bits_left);
okini3939 0:8ba6230eefbd 1257 else if (cachesz + bits_left > 0)
okini3939 0:8ba6230eefbd 1258 fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left);
okini3939 0:8ba6230eefbd 1259 # endif
okini3939 0:8ba6230eefbd 1260
okini3939 0:8ba6230eefbd 1261 /* rzero */
okini3939 0:8ba6230eefbd 1262 while (xrptr < &xr[576]) {
okini3939 0:8ba6230eefbd 1263 xrptr[0] = 0;
okini3939 0:8ba6230eefbd 1264 xrptr[1] = 0;
okini3939 0:8ba6230eefbd 1265
okini3939 0:8ba6230eefbd 1266 xrptr += 2;
okini3939 0:8ba6230eefbd 1267 }
okini3939 0:8ba6230eefbd 1268
okini3939 0:8ba6230eefbd 1269 return MAD_ERROR_NONE;
okini3939 0:8ba6230eefbd 1270 }
okini3939 0:8ba6230eefbd 1271
okini3939 0:8ba6230eefbd 1272 # undef MASK
okini3939 0:8ba6230eefbd 1273 # undef MASK1BIT
okini3939 0:8ba6230eefbd 1274
okini3939 0:8ba6230eefbd 1275 /*
okini3939 0:8ba6230eefbd 1276 * NAME: III_reorder()
okini3939 0:8ba6230eefbd 1277 * DESCRIPTION: reorder frequency lines of a short block into subband order
okini3939 0:8ba6230eefbd 1278 */
okini3939 0:8ba6230eefbd 1279 static
okini3939 0:8ba6230eefbd 1280 void III_reorder(mad_fixed_t xr[576], struct channel const *channel,
okini3939 0:8ba6230eefbd 1281 unsigned char const sfbwidth[39])
okini3939 0:8ba6230eefbd 1282 {
okini3939 0:8ba6230eefbd 1283 mad_fixed_t tmp[32][3][6];
okini3939 0:8ba6230eefbd 1284 unsigned int sb, l, f, w, sbw[3], sw[3];
okini3939 0:8ba6230eefbd 1285
okini3939 0:8ba6230eefbd 1286 /* this is probably wrong for 8000 Hz mixed blocks */
okini3939 0:8ba6230eefbd 1287
okini3939 0:8ba6230eefbd 1288 sb = 0;
okini3939 0:8ba6230eefbd 1289 if (channel->flags & mixed_block_flag) {
okini3939 0:8ba6230eefbd 1290 sb = 2;
okini3939 0:8ba6230eefbd 1291
okini3939 0:8ba6230eefbd 1292 l = 0;
okini3939 0:8ba6230eefbd 1293 while (l < 36)
okini3939 0:8ba6230eefbd 1294 l += *sfbwidth++;
okini3939 0:8ba6230eefbd 1295 }
okini3939 0:8ba6230eefbd 1296
okini3939 0:8ba6230eefbd 1297 for (w = 0; w < 3; ++w) {
okini3939 0:8ba6230eefbd 1298 sbw[w] = sb;
okini3939 0:8ba6230eefbd 1299 sw[w] = 0;
okini3939 0:8ba6230eefbd 1300 }
okini3939 0:8ba6230eefbd 1301
okini3939 0:8ba6230eefbd 1302 f = *sfbwidth++;
okini3939 0:8ba6230eefbd 1303 w = 0;
okini3939 0:8ba6230eefbd 1304
okini3939 0:8ba6230eefbd 1305 for (l = 18 * sb; l < 576; ++l) {
okini3939 0:8ba6230eefbd 1306 if (f-- == 0) {
okini3939 0:8ba6230eefbd 1307 f = *sfbwidth++ - 1;
okini3939 0:8ba6230eefbd 1308 w = (w + 1) % 3;
okini3939 0:8ba6230eefbd 1309 }
okini3939 0:8ba6230eefbd 1310
okini3939 0:8ba6230eefbd 1311 tmp[sbw[w]][w][sw[w]++] = xr[l];
okini3939 0:8ba6230eefbd 1312
okini3939 0:8ba6230eefbd 1313 if (sw[w] == 6) {
okini3939 0:8ba6230eefbd 1314 sw[w] = 0;
okini3939 0:8ba6230eefbd 1315 ++sbw[w];
okini3939 0:8ba6230eefbd 1316 }
okini3939 0:8ba6230eefbd 1317 }
okini3939 0:8ba6230eefbd 1318
okini3939 0:8ba6230eefbd 1319 memcpy(&xr[18 * sb], &tmp[sb], (576 - 18 * sb) * sizeof(mad_fixed_t));
okini3939 0:8ba6230eefbd 1320 }
okini3939 0:8ba6230eefbd 1321
okini3939 0:8ba6230eefbd 1322 /*
okini3939 0:8ba6230eefbd 1323 * NAME: III_stereo()
okini3939 0:8ba6230eefbd 1324 * DESCRIPTION: perform joint stereo processing on a granule
okini3939 0:8ba6230eefbd 1325 */
okini3939 0:8ba6230eefbd 1326 static
okini3939 0:8ba6230eefbd 1327 enum mad_error III_stereo(mad_fixed_t xr[2][576],
okini3939 0:8ba6230eefbd 1328 struct granule const *granule,
okini3939 0:8ba6230eefbd 1329 struct mad_header *header,
okini3939 0:8ba6230eefbd 1330 unsigned char const *sfbwidth)
okini3939 0:8ba6230eefbd 1331 {
okini3939 0:8ba6230eefbd 1332 short modes[39];
okini3939 0:8ba6230eefbd 1333 unsigned int sfbi, l, n, i;
okini3939 0:8ba6230eefbd 1334
okini3939 0:8ba6230eefbd 1335 if (granule->ch[0].block_type !=
okini3939 0:8ba6230eefbd 1336 granule->ch[1].block_type ||
okini3939 0:8ba6230eefbd 1337 (granule->ch[0].flags & mixed_block_flag) !=
okini3939 0:8ba6230eefbd 1338 (granule->ch[1].flags & mixed_block_flag))
okini3939 0:8ba6230eefbd 1339 return MAD_ERROR_BADSTEREO;
okini3939 0:8ba6230eefbd 1340
okini3939 0:8ba6230eefbd 1341 for (i = 0; i < 39; ++i)
okini3939 0:8ba6230eefbd 1342 modes[i] = header->mode_extension;
okini3939 0:8ba6230eefbd 1343
okini3939 0:8ba6230eefbd 1344 /* intensity stereo */
okini3939 0:8ba6230eefbd 1345
okini3939 0:8ba6230eefbd 1346 if (header->mode_extension & I_STEREO) {
okini3939 0:8ba6230eefbd 1347 struct channel const *right_ch = &granule->ch[1];
okini3939 0:8ba6230eefbd 1348 mad_fixed_t const *right_xr = xr[1];
okini3939 0:8ba6230eefbd 1349 unsigned int is_pos;
okini3939 0:8ba6230eefbd 1350
okini3939 0:8ba6230eefbd 1351 header->flags |= MAD_FLAG_I_STEREO;
okini3939 0:8ba6230eefbd 1352
okini3939 0:8ba6230eefbd 1353 /* first determine which scalefactor bands are to be processed */
okini3939 0:8ba6230eefbd 1354
okini3939 0:8ba6230eefbd 1355 if (right_ch->block_type == 2) {
okini3939 0:8ba6230eefbd 1356 unsigned int lower, start, max, bound[3], w;
okini3939 0:8ba6230eefbd 1357
okini3939 0:8ba6230eefbd 1358 lower = start = max = bound[0] = bound[1] = bound[2] = 0;
okini3939 0:8ba6230eefbd 1359
okini3939 0:8ba6230eefbd 1360 sfbi = l = 0;
okini3939 0:8ba6230eefbd 1361
okini3939 0:8ba6230eefbd 1362 if (right_ch->flags & mixed_block_flag) {
okini3939 0:8ba6230eefbd 1363 while (l < 36) {
okini3939 0:8ba6230eefbd 1364 n = sfbwidth[sfbi++];
okini3939 0:8ba6230eefbd 1365
okini3939 0:8ba6230eefbd 1366 for (i = 0; i < n; ++i) {
okini3939 0:8ba6230eefbd 1367 if (right_xr[i]) {
okini3939 0:8ba6230eefbd 1368 lower = sfbi;
okini3939 0:8ba6230eefbd 1369 break;
okini3939 0:8ba6230eefbd 1370 }
okini3939 0:8ba6230eefbd 1371 }
okini3939 0:8ba6230eefbd 1372
okini3939 0:8ba6230eefbd 1373 right_xr += n;
okini3939 0:8ba6230eefbd 1374 l += n;
okini3939 0:8ba6230eefbd 1375 }
okini3939 0:8ba6230eefbd 1376
okini3939 0:8ba6230eefbd 1377 start = sfbi;
okini3939 0:8ba6230eefbd 1378 }
okini3939 0:8ba6230eefbd 1379
okini3939 0:8ba6230eefbd 1380 w = 0;
okini3939 0:8ba6230eefbd 1381 while (l < 576) {
okini3939 0:8ba6230eefbd 1382 n = sfbwidth[sfbi++];
okini3939 0:8ba6230eefbd 1383
okini3939 0:8ba6230eefbd 1384 for (i = 0; i < n; ++i) {
okini3939 0:8ba6230eefbd 1385 if (right_xr[i]) {
okini3939 0:8ba6230eefbd 1386 max = bound[w] = sfbi;
okini3939 0:8ba6230eefbd 1387 break;
okini3939 0:8ba6230eefbd 1388 }
okini3939 0:8ba6230eefbd 1389 }
okini3939 0:8ba6230eefbd 1390
okini3939 0:8ba6230eefbd 1391 right_xr += n;
okini3939 0:8ba6230eefbd 1392 l += n;
okini3939 0:8ba6230eefbd 1393 w = (w + 1) % 3;
okini3939 0:8ba6230eefbd 1394 }
okini3939 0:8ba6230eefbd 1395
okini3939 0:8ba6230eefbd 1396 if (max)
okini3939 0:8ba6230eefbd 1397 lower = start;
okini3939 0:8ba6230eefbd 1398
okini3939 0:8ba6230eefbd 1399 /* long blocks */
okini3939 0:8ba6230eefbd 1400
okini3939 0:8ba6230eefbd 1401 for (i = 0; i < lower; ++i)
okini3939 0:8ba6230eefbd 1402 modes[i] = header->mode_extension & ~I_STEREO;
okini3939 0:8ba6230eefbd 1403
okini3939 0:8ba6230eefbd 1404 /* short blocks */
okini3939 0:8ba6230eefbd 1405
okini3939 0:8ba6230eefbd 1406 w = 0;
okini3939 0:8ba6230eefbd 1407 for (i = start; i < max; ++i) {
okini3939 0:8ba6230eefbd 1408 if (i < bound[w])
okini3939 0:8ba6230eefbd 1409 modes[i] = header->mode_extension & ~I_STEREO;
okini3939 0:8ba6230eefbd 1410
okini3939 0:8ba6230eefbd 1411 w = (w + 1) % 3;
okini3939 0:8ba6230eefbd 1412 }
okini3939 0:8ba6230eefbd 1413 }
okini3939 0:8ba6230eefbd 1414 else { /* right_ch->block_type != 2 */
okini3939 0:8ba6230eefbd 1415 unsigned int bound;
okini3939 0:8ba6230eefbd 1416
okini3939 0:8ba6230eefbd 1417 bound = 0;
okini3939 0:8ba6230eefbd 1418 for (sfbi = l = 0; l < 576; l += n) {
okini3939 0:8ba6230eefbd 1419 n = sfbwidth[sfbi++];
okini3939 0:8ba6230eefbd 1420
okini3939 0:8ba6230eefbd 1421 for (i = 0; i < n; ++i) {
okini3939 0:8ba6230eefbd 1422 if (right_xr[i]) {
okini3939 0:8ba6230eefbd 1423 bound = sfbi;
okini3939 0:8ba6230eefbd 1424 break;
okini3939 0:8ba6230eefbd 1425 }
okini3939 0:8ba6230eefbd 1426 }
okini3939 0:8ba6230eefbd 1427
okini3939 0:8ba6230eefbd 1428 right_xr += n;
okini3939 0:8ba6230eefbd 1429 }
okini3939 0:8ba6230eefbd 1430
okini3939 0:8ba6230eefbd 1431 for (i = 0; i < bound; ++i)
okini3939 0:8ba6230eefbd 1432 modes[i] = header->mode_extension & ~I_STEREO;
okini3939 0:8ba6230eefbd 1433 }
okini3939 0:8ba6230eefbd 1434
okini3939 0:8ba6230eefbd 1435 /* now do the actual processing */
okini3939 0:8ba6230eefbd 1436
okini3939 0:8ba6230eefbd 1437 if (header->flags & MAD_FLAG_LSF_EXT) {
okini3939 0:8ba6230eefbd 1438 unsigned char const *illegal_pos = granule[1].ch[1].scalefac;
okini3939 0:8ba6230eefbd 1439 mad_fixed_t const *lsf_scale;
okini3939 0:8ba6230eefbd 1440
okini3939 0:8ba6230eefbd 1441 /* intensity_scale */
okini3939 0:8ba6230eefbd 1442 lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1];
okini3939 0:8ba6230eefbd 1443
okini3939 0:8ba6230eefbd 1444 for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
okini3939 0:8ba6230eefbd 1445 n = sfbwidth[sfbi];
okini3939 0:8ba6230eefbd 1446
okini3939 0:8ba6230eefbd 1447 if (!(modes[sfbi] & I_STEREO))
okini3939 0:8ba6230eefbd 1448 continue;
okini3939 0:8ba6230eefbd 1449
okini3939 0:8ba6230eefbd 1450 if (illegal_pos[sfbi]) {
okini3939 0:8ba6230eefbd 1451 modes[sfbi] &= ~I_STEREO;
okini3939 0:8ba6230eefbd 1452 continue;
okini3939 0:8ba6230eefbd 1453 }
okini3939 0:8ba6230eefbd 1454
okini3939 0:8ba6230eefbd 1455 is_pos = right_ch->scalefac[sfbi];
okini3939 0:8ba6230eefbd 1456
okini3939 0:8ba6230eefbd 1457 for (i = 0; i < n; ++i) {
okini3939 0:8ba6230eefbd 1458 register mad_fixed_t left;
okini3939 0:8ba6230eefbd 1459
okini3939 0:8ba6230eefbd 1460 left = xr[0][l + i];
okini3939 0:8ba6230eefbd 1461
okini3939 0:8ba6230eefbd 1462 if (is_pos == 0)
okini3939 0:8ba6230eefbd 1463 xr[1][l + i] = left;
okini3939 0:8ba6230eefbd 1464 else {
okini3939 0:8ba6230eefbd 1465 register mad_fixed_t opposite;
okini3939 0:8ba6230eefbd 1466
okini3939 0:8ba6230eefbd 1467 opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]);
okini3939 0:8ba6230eefbd 1468
okini3939 0:8ba6230eefbd 1469 if (is_pos & 1) {
okini3939 0:8ba6230eefbd 1470 xr[0][l + i] = opposite;
okini3939 0:8ba6230eefbd 1471 xr[1][l + i] = left;
okini3939 0:8ba6230eefbd 1472 }
okini3939 0:8ba6230eefbd 1473 else
okini3939 0:8ba6230eefbd 1474 xr[1][l + i] = opposite;
okini3939 0:8ba6230eefbd 1475 }
okini3939 0:8ba6230eefbd 1476 }
okini3939 0:8ba6230eefbd 1477 }
okini3939 0:8ba6230eefbd 1478 }
okini3939 0:8ba6230eefbd 1479 else { /* !(header->flags & MAD_FLAG_LSF_EXT) */
okini3939 0:8ba6230eefbd 1480 for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
okini3939 0:8ba6230eefbd 1481 n = sfbwidth[sfbi];
okini3939 0:8ba6230eefbd 1482
okini3939 0:8ba6230eefbd 1483 if (!(modes[sfbi] & I_STEREO))
okini3939 0:8ba6230eefbd 1484 continue;
okini3939 0:8ba6230eefbd 1485
okini3939 0:8ba6230eefbd 1486 is_pos = right_ch->scalefac[sfbi];
okini3939 0:8ba6230eefbd 1487
okini3939 0:8ba6230eefbd 1488 if (is_pos >= 7) { /* illegal intensity position */
okini3939 0:8ba6230eefbd 1489 modes[sfbi] &= ~I_STEREO;
okini3939 0:8ba6230eefbd 1490 continue;
okini3939 0:8ba6230eefbd 1491 }
okini3939 0:8ba6230eefbd 1492
okini3939 0:8ba6230eefbd 1493 for (i = 0; i < n; ++i) {
okini3939 0:8ba6230eefbd 1494 register mad_fixed_t left;
okini3939 0:8ba6230eefbd 1495
okini3939 0:8ba6230eefbd 1496 left = xr[0][l + i];
okini3939 0:8ba6230eefbd 1497
okini3939 0:8ba6230eefbd 1498 xr[0][l + i] = mad_f_mul(left, is_table[ is_pos]);
okini3939 0:8ba6230eefbd 1499 xr[1][l + i] = mad_f_mul(left, is_table[6 - is_pos]);
okini3939 0:8ba6230eefbd 1500 }
okini3939 0:8ba6230eefbd 1501 }
okini3939 0:8ba6230eefbd 1502 }
okini3939 0:8ba6230eefbd 1503 }
okini3939 0:8ba6230eefbd 1504
okini3939 0:8ba6230eefbd 1505 /* middle/side stereo */
okini3939 0:8ba6230eefbd 1506
okini3939 0:8ba6230eefbd 1507 if (header->mode_extension & MS_STEREO) {
okini3939 0:8ba6230eefbd 1508 register mad_fixed_t invsqrt2;
okini3939 0:8ba6230eefbd 1509
okini3939 0:8ba6230eefbd 1510 header->flags |= MAD_FLAG_MS_STEREO;
okini3939 0:8ba6230eefbd 1511
okini3939 0:8ba6230eefbd 1512 invsqrt2 = root_table[3 + -2];
okini3939 0:8ba6230eefbd 1513
okini3939 0:8ba6230eefbd 1514 for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
okini3939 0:8ba6230eefbd 1515 n = sfbwidth[sfbi];
okini3939 0:8ba6230eefbd 1516
okini3939 0:8ba6230eefbd 1517 if (modes[sfbi] != MS_STEREO)
okini3939 0:8ba6230eefbd 1518 continue;
okini3939 0:8ba6230eefbd 1519
okini3939 0:8ba6230eefbd 1520 for (i = 0; i < n; ++i) {
okini3939 0:8ba6230eefbd 1521 register mad_fixed_t m, s;
okini3939 0:8ba6230eefbd 1522
okini3939 0:8ba6230eefbd 1523 m = xr[0][l + i];
okini3939 0:8ba6230eefbd 1524 s = xr[1][l + i];
okini3939 0:8ba6230eefbd 1525
okini3939 0:8ba6230eefbd 1526 xr[0][l + i] = mad_f_mul(m + s, invsqrt2); /* l = (m + s) / sqrt(2) */
okini3939 0:8ba6230eefbd 1527 xr[1][l + i] = mad_f_mul(m - s, invsqrt2); /* r = (m - s) / sqrt(2) */
okini3939 0:8ba6230eefbd 1528 }
okini3939 0:8ba6230eefbd 1529 }
okini3939 0:8ba6230eefbd 1530 }
okini3939 0:8ba6230eefbd 1531
okini3939 0:8ba6230eefbd 1532 return MAD_ERROR_NONE;
okini3939 0:8ba6230eefbd 1533 }
okini3939 0:8ba6230eefbd 1534
okini3939 0:8ba6230eefbd 1535 /*
okini3939 0:8ba6230eefbd 1536 * NAME: III_aliasreduce()
okini3939 0:8ba6230eefbd 1537 * DESCRIPTION: perform frequency line alias reduction
okini3939 0:8ba6230eefbd 1538 */
okini3939 0:8ba6230eefbd 1539 static
okini3939 0:8ba6230eefbd 1540 void III_aliasreduce(mad_fixed_t xr[576], int lines)
okini3939 0:8ba6230eefbd 1541 {
okini3939 0:8ba6230eefbd 1542 mad_fixed_t const *bound;
okini3939 0:8ba6230eefbd 1543 int i;
okini3939 0:8ba6230eefbd 1544
okini3939 0:8ba6230eefbd 1545 bound = &xr[lines];
okini3939 0:8ba6230eefbd 1546 for (xr += 18; xr < bound; xr += 18) {
okini3939 0:8ba6230eefbd 1547 for (i = 0; i < 8; ++i) {
okini3939 0:8ba6230eefbd 1548 register mad_fixed_t a, b;
okini3939 0:8ba6230eefbd 1549 register mad_fixed64hi_t hi;
okini3939 0:8ba6230eefbd 1550 register mad_fixed64lo_t lo;
okini3939 0:8ba6230eefbd 1551
okini3939 0:8ba6230eefbd 1552 a = xr[-1 - i];
okini3939 0:8ba6230eefbd 1553 b = xr[ i];
okini3939 0:8ba6230eefbd 1554
okini3939 0:8ba6230eefbd 1555 # if defined(ASO_ZEROCHECK)
okini3939 0:8ba6230eefbd 1556 if (a | b) {
okini3939 0:8ba6230eefbd 1557 # endif
okini3939 0:8ba6230eefbd 1558 MAD_F_ML0(hi, lo, a, cs[i]);
okini3939 0:8ba6230eefbd 1559 MAD_F_MLA(hi, lo, -b, ca[i]);
okini3939 0:8ba6230eefbd 1560
okini3939 0:8ba6230eefbd 1561 xr[-1 - i] = MAD_F_MLZ(hi, lo);
okini3939 0:8ba6230eefbd 1562
okini3939 0:8ba6230eefbd 1563 MAD_F_ML0(hi, lo, b, cs[i]);
okini3939 0:8ba6230eefbd 1564 MAD_F_MLA(hi, lo, a, ca[i]);
okini3939 0:8ba6230eefbd 1565
okini3939 0:8ba6230eefbd 1566 xr[ i] = MAD_F_MLZ(hi, lo);
okini3939 0:8ba6230eefbd 1567 # if defined(ASO_ZEROCHECK)
okini3939 0:8ba6230eefbd 1568 }
okini3939 0:8ba6230eefbd 1569 # endif
okini3939 0:8ba6230eefbd 1570 }
okini3939 0:8ba6230eefbd 1571 }
okini3939 0:8ba6230eefbd 1572 }
okini3939 0:8ba6230eefbd 1573
okini3939 0:8ba6230eefbd 1574 # if defined(ASO_IMDCT)
okini3939 0:8ba6230eefbd 1575 void III_imdct_l(mad_fixed_t const [18], mad_fixed_t [36], unsigned int);
okini3939 0:8ba6230eefbd 1576 # else
okini3939 0:8ba6230eefbd 1577 # if 1
okini3939 0:8ba6230eefbd 1578 static
okini3939 0:8ba6230eefbd 1579 void fastsdct(mad_fixed_t const x[9], mad_fixed_t y[18])
okini3939 0:8ba6230eefbd 1580 {
okini3939 0:8ba6230eefbd 1581 mad_fixed_t a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12;
okini3939 0:8ba6230eefbd 1582 mad_fixed_t a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25;
okini3939 0:8ba6230eefbd 1583 mad_fixed_t m0, m1, m2, m3, m4, m5, m6, m7;
okini3939 0:8ba6230eefbd 1584
okini3939 0:8ba6230eefbd 1585 enum {
okini3939 0:8ba6230eefbd 1586 c0 = MAD_F(0x1f838b8d), /* 2 * cos( 1 * PI / 18) */
okini3939 0:8ba6230eefbd 1587 c1 = MAD_F(0x1bb67ae8), /* 2 * cos( 3 * PI / 18) */
okini3939 0:8ba6230eefbd 1588 c2 = MAD_F(0x18836fa3), /* 2 * cos( 4 * PI / 18) */
okini3939 0:8ba6230eefbd 1589 c3 = MAD_F(0x1491b752), /* 2 * cos( 5 * PI / 18) */
okini3939 0:8ba6230eefbd 1590 c4 = MAD_F(0x0af1d43a), /* 2 * cos( 7 * PI / 18) */
okini3939 0:8ba6230eefbd 1591 c5 = MAD_F(0x058e86a0), /* 2 * cos( 8 * PI / 18) */
okini3939 0:8ba6230eefbd 1592 c6 = -MAD_F(0x1e11f642) /* 2 * cos(16 * PI / 18) */
okini3939 0:8ba6230eefbd 1593 };
okini3939 0:8ba6230eefbd 1594
okini3939 0:8ba6230eefbd 1595 a0 = x[3] + x[5];
okini3939 0:8ba6230eefbd 1596 a1 = x[3] - x[5];
okini3939 0:8ba6230eefbd 1597 a2 = x[6] + x[2];
okini3939 0:8ba6230eefbd 1598 a3 = x[6] - x[2];
okini3939 0:8ba6230eefbd 1599 a4 = x[1] + x[7];
okini3939 0:8ba6230eefbd 1600 a5 = x[1] - x[7];
okini3939 0:8ba6230eefbd 1601 a6 = x[8] + x[0];
okini3939 0:8ba6230eefbd 1602 a7 = x[8] - x[0];
okini3939 0:8ba6230eefbd 1603
okini3939 0:8ba6230eefbd 1604 a8 = a0 + a2;
okini3939 0:8ba6230eefbd 1605 a9 = a0 - a2;
okini3939 0:8ba6230eefbd 1606 a10 = a0 - a6;
okini3939 0:8ba6230eefbd 1607 a11 = a2 - a6;
okini3939 0:8ba6230eefbd 1608 a12 = a8 + a6;
okini3939 0:8ba6230eefbd 1609 a13 = a1 - a3;
okini3939 0:8ba6230eefbd 1610 a14 = a13 + a7;
okini3939 0:8ba6230eefbd 1611 a15 = a3 + a7;
okini3939 0:8ba6230eefbd 1612 a16 = a1 - a7;
okini3939 0:8ba6230eefbd 1613 a17 = a1 + a3;
okini3939 0:8ba6230eefbd 1614
okini3939 0:8ba6230eefbd 1615 m0 = mad_f_mul(a17, -c3);
okini3939 0:8ba6230eefbd 1616 m1 = mad_f_mul(a16, -c0);
okini3939 0:8ba6230eefbd 1617 m2 = mad_f_mul(a15, -c4);
okini3939 0:8ba6230eefbd 1618 m3 = mad_f_mul(a14, -c1);
okini3939 0:8ba6230eefbd 1619 m4 = mad_f_mul(a5, -c1);
okini3939 0:8ba6230eefbd 1620 m5 = mad_f_mul(a11, -c6);
okini3939 0:8ba6230eefbd 1621 m6 = mad_f_mul(a10, -c5);
okini3939 0:8ba6230eefbd 1622 m7 = mad_f_mul(a9, -c2);
okini3939 0:8ba6230eefbd 1623
okini3939 0:8ba6230eefbd 1624 a18 = x[4] + a4;
okini3939 0:8ba6230eefbd 1625 a19 = 2 * x[4] - a4;
okini3939 0:8ba6230eefbd 1626 a20 = a19 + m5;
okini3939 0:8ba6230eefbd 1627 a21 = a19 - m5;
okini3939 0:8ba6230eefbd 1628 a22 = a19 + m6;
okini3939 0:8ba6230eefbd 1629 a23 = m4 + m2;
okini3939 0:8ba6230eefbd 1630 a24 = m4 - m2;
okini3939 0:8ba6230eefbd 1631 a25 = m4 + m1;
okini3939 0:8ba6230eefbd 1632
okini3939 0:8ba6230eefbd 1633 /* output to every other slot for convenience */
okini3939 0:8ba6230eefbd 1634
okini3939 0:8ba6230eefbd 1635 y[ 0] = a18 + a12;
okini3939 0:8ba6230eefbd 1636 y[ 2] = m0 - a25;
okini3939 0:8ba6230eefbd 1637 y[ 4] = m7 - a20;
okini3939 0:8ba6230eefbd 1638 y[ 6] = m3;
okini3939 0:8ba6230eefbd 1639 y[ 8] = a21 - m6;
okini3939 0:8ba6230eefbd 1640 y[10] = a24 - m1;
okini3939 0:8ba6230eefbd 1641 y[12] = a12 - 2 * a18;
okini3939 0:8ba6230eefbd 1642 y[14] = a23 + m0;
okini3939 0:8ba6230eefbd 1643 y[16] = a22 + m7;
okini3939 0:8ba6230eefbd 1644 }
okini3939 0:8ba6230eefbd 1645
okini3939 0:8ba6230eefbd 1646 static inline
okini3939 0:8ba6230eefbd 1647 void sdctII(mad_fixed_t const x[18], mad_fixed_t X[18])
okini3939 0:8ba6230eefbd 1648 {
okini3939 0:8ba6230eefbd 1649 mad_fixed_t tmp[9];
okini3939 0:8ba6230eefbd 1650 int i;
okini3939 0:8ba6230eefbd 1651
okini3939 0:8ba6230eefbd 1652 /* scale[i] = 2 * cos(PI * (2 * i + 1) / (2 * 18)) */
okini3939 0:8ba6230eefbd 1653 static mad_fixed_t const scale[9] = {
okini3939 0:8ba6230eefbd 1654 MAD_F(0x1fe0d3b4), MAD_F(0x1ee8dd47), MAD_F(0x1d007930),
okini3939 0:8ba6230eefbd 1655 MAD_F(0x1a367e59), MAD_F(0x16a09e66), MAD_F(0x125abcf8),
okini3939 0:8ba6230eefbd 1656 MAD_F(0x0d8616bc), MAD_F(0x08483ee1), MAD_F(0x02c9fad7)
okini3939 0:8ba6230eefbd 1657 };
okini3939 0:8ba6230eefbd 1658
okini3939 0:8ba6230eefbd 1659 /* divide the 18-point SDCT-II into two 9-point SDCT-IIs */
okini3939 0:8ba6230eefbd 1660
okini3939 0:8ba6230eefbd 1661 /* even input butterfly */
okini3939 0:8ba6230eefbd 1662
okini3939 0:8ba6230eefbd 1663 for (i = 0; i < 9; i += 3) {
okini3939 0:8ba6230eefbd 1664 tmp[i + 0] = x[i + 0] + x[18 - (i + 0) - 1];
okini3939 0:8ba6230eefbd 1665 tmp[i + 1] = x[i + 1] + x[18 - (i + 1) - 1];
okini3939 0:8ba6230eefbd 1666 tmp[i + 2] = x[i + 2] + x[18 - (i + 2) - 1];
okini3939 0:8ba6230eefbd 1667 }
okini3939 0:8ba6230eefbd 1668
okini3939 0:8ba6230eefbd 1669 fastsdct(tmp, &X[0]);
okini3939 0:8ba6230eefbd 1670
okini3939 0:8ba6230eefbd 1671 /* odd input butterfly and scaling */
okini3939 0:8ba6230eefbd 1672
okini3939 0:8ba6230eefbd 1673 for (i = 0; i < 9; i += 3) {
okini3939 0:8ba6230eefbd 1674 tmp[i + 0] = mad_f_mul(x[i + 0] - x[18 - (i + 0) - 1], scale[i + 0]);
okini3939 0:8ba6230eefbd 1675 tmp[i + 1] = mad_f_mul(x[i + 1] - x[18 - (i + 1) - 1], scale[i + 1]);
okini3939 0:8ba6230eefbd 1676 tmp[i + 2] = mad_f_mul(x[i + 2] - x[18 - (i + 2) - 1], scale[i + 2]);
okini3939 0:8ba6230eefbd 1677 }
okini3939 0:8ba6230eefbd 1678
okini3939 0:8ba6230eefbd 1679 fastsdct(tmp, &X[1]);
okini3939 0:8ba6230eefbd 1680
okini3939 0:8ba6230eefbd 1681 /* output accumulation */
okini3939 0:8ba6230eefbd 1682
okini3939 0:8ba6230eefbd 1683 for (i = 3; i < 18; i += 8) {
okini3939 0:8ba6230eefbd 1684 X[i + 0] -= X[(i + 0) - 2];
okini3939 0:8ba6230eefbd 1685 X[i + 2] -= X[(i + 2) - 2];
okini3939 0:8ba6230eefbd 1686 X[i + 4] -= X[(i + 4) - 2];
okini3939 0:8ba6230eefbd 1687 X[i + 6] -= X[(i + 6) - 2];
okini3939 0:8ba6230eefbd 1688 }
okini3939 0:8ba6230eefbd 1689 }
okini3939 0:8ba6230eefbd 1690
okini3939 0:8ba6230eefbd 1691 static inline
okini3939 0:8ba6230eefbd 1692 void dctIV(mad_fixed_t const y[18], mad_fixed_t X[18])
okini3939 0:8ba6230eefbd 1693 {
okini3939 0:8ba6230eefbd 1694 mad_fixed_t tmp[18];
okini3939 0:8ba6230eefbd 1695 int i;
okini3939 0:8ba6230eefbd 1696
okini3939 0:8ba6230eefbd 1697 /* scale[i] = 2 * cos(PI * (2 * i + 1) / (4 * 18)) */
okini3939 0:8ba6230eefbd 1698 static mad_fixed_t const scale[18] = {
okini3939 0:8ba6230eefbd 1699 MAD_F(0x1ff833fa), MAD_F(0x1fb9ea93), MAD_F(0x1f3dd120),
okini3939 0:8ba6230eefbd 1700 MAD_F(0x1e84d969), MAD_F(0x1d906bcf), MAD_F(0x1c62648b),
okini3939 0:8ba6230eefbd 1701 MAD_F(0x1afd100f), MAD_F(0x1963268b), MAD_F(0x1797c6a4),
okini3939 0:8ba6230eefbd 1702 MAD_F(0x159e6f5b), MAD_F(0x137af940), MAD_F(0x11318ef3),
okini3939 0:8ba6230eefbd 1703 MAD_F(0x0ec6a507), MAD_F(0x0c3ef153), MAD_F(0x099f61c5),
okini3939 0:8ba6230eefbd 1704 MAD_F(0x06ed12c5), MAD_F(0x042d4544), MAD_F(0x0165547c)
okini3939 0:8ba6230eefbd 1705 };
okini3939 0:8ba6230eefbd 1706
okini3939 0:8ba6230eefbd 1707 /* scaling */
okini3939 0:8ba6230eefbd 1708
okini3939 0:8ba6230eefbd 1709 for (i = 0; i < 18; i += 3) {
okini3939 0:8ba6230eefbd 1710 tmp[i + 0] = mad_f_mul(y[i + 0], scale[i + 0]);
okini3939 0:8ba6230eefbd 1711 tmp[i + 1] = mad_f_mul(y[i + 1], scale[i + 1]);
okini3939 0:8ba6230eefbd 1712 tmp[i + 2] = mad_f_mul(y[i + 2], scale[i + 2]);
okini3939 0:8ba6230eefbd 1713 }
okini3939 0:8ba6230eefbd 1714
okini3939 0:8ba6230eefbd 1715 /* SDCT-II */
okini3939 0:8ba6230eefbd 1716
okini3939 0:8ba6230eefbd 1717 sdctII(tmp, X);
okini3939 0:8ba6230eefbd 1718
okini3939 0:8ba6230eefbd 1719 /* scale reduction and output accumulation */
okini3939 0:8ba6230eefbd 1720
okini3939 0:8ba6230eefbd 1721 X[0] /= 2;
okini3939 0:8ba6230eefbd 1722 for (i = 1; i < 17; i += 4) {
okini3939 0:8ba6230eefbd 1723 X[i + 0] = X[i + 0] / 2 - X[(i + 0) - 1];
okini3939 0:8ba6230eefbd 1724 X[i + 1] = X[i + 1] / 2 - X[(i + 1) - 1];
okini3939 0:8ba6230eefbd 1725 X[i + 2] = X[i + 2] / 2 - X[(i + 2) - 1];
okini3939 0:8ba6230eefbd 1726 X[i + 3] = X[i + 3] / 2 - X[(i + 3) - 1];
okini3939 0:8ba6230eefbd 1727 }
okini3939 0:8ba6230eefbd 1728 X[17] = X[17] / 2 - X[16];
okini3939 0:8ba6230eefbd 1729 }
okini3939 0:8ba6230eefbd 1730
okini3939 0:8ba6230eefbd 1731 /*
okini3939 0:8ba6230eefbd 1732 * NAME: imdct36
okini3939 0:8ba6230eefbd 1733 * DESCRIPTION: perform X[18]->x[36] IMDCT using Szu-Wei Lee's fast algorithm
okini3939 0:8ba6230eefbd 1734 */
okini3939 0:8ba6230eefbd 1735 static inline
okini3939 0:8ba6230eefbd 1736 void imdct36(mad_fixed_t const x[18], mad_fixed_t y[36])
okini3939 0:8ba6230eefbd 1737 {
okini3939 0:8ba6230eefbd 1738 mad_fixed_t tmp[18];
okini3939 0:8ba6230eefbd 1739 int i;
okini3939 0:8ba6230eefbd 1740
okini3939 0:8ba6230eefbd 1741 /* DCT-IV */
okini3939 0:8ba6230eefbd 1742
okini3939 0:8ba6230eefbd 1743 dctIV(x, tmp);
okini3939 0:8ba6230eefbd 1744
okini3939 0:8ba6230eefbd 1745 /* convert 18-point DCT-IV to 36-point IMDCT */
okini3939 0:8ba6230eefbd 1746
okini3939 0:8ba6230eefbd 1747 for (i = 0; i < 9; i += 3) {
okini3939 0:8ba6230eefbd 1748 y[i + 0] = tmp[9 + (i + 0)];
okini3939 0:8ba6230eefbd 1749 y[i + 1] = tmp[9 + (i + 1)];
okini3939 0:8ba6230eefbd 1750 y[i + 2] = tmp[9 + (i + 2)];
okini3939 0:8ba6230eefbd 1751 }
okini3939 0:8ba6230eefbd 1752 for (i = 9; i < 27; i += 3) {
okini3939 0:8ba6230eefbd 1753 y[i + 0] = -tmp[36 - (9 + (i + 0)) - 1];
okini3939 0:8ba6230eefbd 1754 y[i + 1] = -tmp[36 - (9 + (i + 1)) - 1];
okini3939 0:8ba6230eefbd 1755 y[i + 2] = -tmp[36 - (9 + (i + 2)) - 1];
okini3939 0:8ba6230eefbd 1756 }
okini3939 0:8ba6230eefbd 1757 for (i = 27; i < 36; i += 3) {
okini3939 0:8ba6230eefbd 1758 y[i + 0] = -tmp[(i + 0) - 27];
okini3939 0:8ba6230eefbd 1759 y[i + 1] = -tmp[(i + 1) - 27];
okini3939 0:8ba6230eefbd 1760 y[i + 2] = -tmp[(i + 2) - 27];
okini3939 0:8ba6230eefbd 1761 }
okini3939 0:8ba6230eefbd 1762 }
okini3939 0:8ba6230eefbd 1763 # else
okini3939 0:8ba6230eefbd 1764 /*
okini3939 0:8ba6230eefbd 1765 * NAME: imdct36
okini3939 0:8ba6230eefbd 1766 * DESCRIPTION: perform X[18]->x[36] IMDCT
okini3939 0:8ba6230eefbd 1767 */
okini3939 0:8ba6230eefbd 1768 static inline
okini3939 0:8ba6230eefbd 1769 void imdct36(mad_fixed_t const X[18], mad_fixed_t x[36])
okini3939 0:8ba6230eefbd 1770 {
okini3939 0:8ba6230eefbd 1771 mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7;
okini3939 0:8ba6230eefbd 1772 mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15;
okini3939 0:8ba6230eefbd 1773 register mad_fixed64hi_t hi;
okini3939 0:8ba6230eefbd 1774 register mad_fixed64lo_t lo;
okini3939 0:8ba6230eefbd 1775
okini3939 0:8ba6230eefbd 1776 MAD_F_ML0(hi, lo, X[4], MAD_F(0x0ec835e8));
okini3939 0:8ba6230eefbd 1777 MAD_F_MLA(hi, lo, X[13], MAD_F(0x061f78aa));
okini3939 0:8ba6230eefbd 1778
okini3939 0:8ba6230eefbd 1779 t6 = MAD_F_MLZ(hi, lo);
okini3939 0:8ba6230eefbd 1780
okini3939 0:8ba6230eefbd 1781 MAD_F_MLA(hi, lo, (t14 = X[1] - X[10]), -MAD_F(0x061f78aa));
okini3939 0:8ba6230eefbd 1782 MAD_F_MLA(hi, lo, (t15 = X[7] + X[16]), -MAD_F(0x0ec835e8));
okini3939 0:8ba6230eefbd 1783
okini3939 0:8ba6230eefbd 1784 t0 = MAD_F_MLZ(hi, lo);
okini3939 0:8ba6230eefbd 1785
okini3939 0:8ba6230eefbd 1786 MAD_F_MLA(hi, lo, (t8 = X[0] - X[11] - X[12]), MAD_F(0x0216a2a2));
okini3939 0:8ba6230eefbd 1787 MAD_F_MLA(hi, lo, (t9 = X[2] - X[9] - X[14]), MAD_F(0x09bd7ca0));
okini3939 0:8ba6230eefbd 1788 MAD_F_MLA(hi, lo, (t10 = X[3] - X[8] - X[15]), -MAD_F(0x0cb19346));
okini3939 0:8ba6230eefbd 1789 MAD_F_MLA(hi, lo, (t11 = X[5] - X[6] - X[17]), -MAD_F(0x0fdcf549));
okini3939 0:8ba6230eefbd 1790
okini3939 0:8ba6230eefbd 1791 x[7] = MAD_F_MLZ(hi, lo);
okini3939 0:8ba6230eefbd 1792 x[10] = -x[7];
okini3939 0:8ba6230eefbd 1793
okini3939 0:8ba6230eefbd 1794 MAD_F_ML0(hi, lo, t8, -MAD_F(0x0cb19346));
okini3939 0:8ba6230eefbd 1795 MAD_F_MLA(hi, lo, t9, MAD_F(0x0fdcf549));
okini3939 0:8ba6230eefbd 1796 MAD_F_MLA(hi, lo, t10, MAD_F(0x0216a2a2));
okini3939 0:8ba6230eefbd 1797 MAD_F_MLA(hi, lo, t11, -MAD_F(0x09bd7ca0));
okini3939 0:8ba6230eefbd 1798
okini3939 0:8ba6230eefbd 1799 x[19] = x[34] = MAD_F_MLZ(hi, lo) - t0;
okini3939 0:8ba6230eefbd 1800
okini3939 0:8ba6230eefbd 1801 t12 = X[0] - X[3] + X[8] - X[11] - X[12] + X[15];
okini3939 0:8ba6230eefbd 1802 t13 = X[2] + X[5] - X[6] - X[9] - X[14] - X[17];
okini3939 0:8ba6230eefbd 1803
okini3939 0:8ba6230eefbd 1804 MAD_F_ML0(hi, lo, t12, -MAD_F(0x0ec835e8));
okini3939 0:8ba6230eefbd 1805 MAD_F_MLA(hi, lo, t13, MAD_F(0x061f78aa));
okini3939 0:8ba6230eefbd 1806
okini3939 0:8ba6230eefbd 1807 x[22] = x[31] = MAD_F_MLZ(hi, lo) + t0;
okini3939 0:8ba6230eefbd 1808
okini3939 0:8ba6230eefbd 1809 MAD_F_ML0(hi, lo, X[1], -MAD_F(0x09bd7ca0));
okini3939 0:8ba6230eefbd 1810 MAD_F_MLA(hi, lo, X[7], MAD_F(0x0216a2a2));
okini3939 0:8ba6230eefbd 1811 MAD_F_MLA(hi, lo, X[10], -MAD_F(0x0fdcf549));
okini3939 0:8ba6230eefbd 1812 MAD_F_MLA(hi, lo, X[16], MAD_F(0x0cb19346));
okini3939 0:8ba6230eefbd 1813
okini3939 0:8ba6230eefbd 1814 t1 = MAD_F_MLZ(hi, lo) + t6;
okini3939 0:8ba6230eefbd 1815
okini3939 0:8ba6230eefbd 1816 MAD_F_ML0(hi, lo, X[0], MAD_F(0x03768962));
okini3939 0:8ba6230eefbd 1817 MAD_F_MLA(hi, lo, X[2], MAD_F(0x0e313245));
okini3939 0:8ba6230eefbd 1818 MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0ffc19fd));
okini3939 0:8ba6230eefbd 1819 MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0acf37ad));
okini3939 0:8ba6230eefbd 1820 MAD_F_MLA(hi, lo, X[6], MAD_F(0x04cfb0e2));
okini3939 0:8ba6230eefbd 1821 MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0898c779));
okini3939 0:8ba6230eefbd 1822 MAD_F_MLA(hi, lo, X[9], MAD_F(0x0d7e8807));
okini3939 0:8ba6230eefbd 1823 MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f426cb5));
okini3939 0:8ba6230eefbd 1824 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0bcbe352));
okini3939 0:8ba6230eefbd 1825 MAD_F_MLA(hi, lo, X[14], MAD_F(0x00b2aa3e));
okini3939 0:8ba6230eefbd 1826 MAD_F_MLA(hi, lo, X[15], -MAD_F(0x07635284));
okini3939 0:8ba6230eefbd 1827 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0f9ee890));
okini3939 0:8ba6230eefbd 1828
okini3939 0:8ba6230eefbd 1829 x[6] = MAD_F_MLZ(hi, lo) + t1;
okini3939 0:8ba6230eefbd 1830 x[11] = -x[6];
okini3939 0:8ba6230eefbd 1831
okini3939 0:8ba6230eefbd 1832 MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f426cb5));
okini3939 0:8ba6230eefbd 1833 MAD_F_MLA(hi, lo, X[2], -MAD_F(0x00b2aa3e));
okini3939 0:8ba6230eefbd 1834 MAD_F_MLA(hi, lo, X[3], MAD_F(0x0898c779));
okini3939 0:8ba6230eefbd 1835 MAD_F_MLA(hi, lo, X[5], MAD_F(0x0f9ee890));
okini3939 0:8ba6230eefbd 1836 MAD_F_MLA(hi, lo, X[6], MAD_F(0x0acf37ad));
okini3939 0:8ba6230eefbd 1837 MAD_F_MLA(hi, lo, X[8], -MAD_F(0x07635284));
okini3939 0:8ba6230eefbd 1838 MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0e313245));
okini3939 0:8ba6230eefbd 1839 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0bcbe352));
okini3939 0:8ba6230eefbd 1840 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x03768962));
okini3939 0:8ba6230eefbd 1841 MAD_F_MLA(hi, lo, X[14], MAD_F(0x0d7e8807));
okini3939 0:8ba6230eefbd 1842 MAD_F_MLA(hi, lo, X[15], MAD_F(0x0ffc19fd));
okini3939 0:8ba6230eefbd 1843 MAD_F_MLA(hi, lo, X[17], MAD_F(0x04cfb0e2));
okini3939 0:8ba6230eefbd 1844
okini3939 0:8ba6230eefbd 1845 x[23] = x[30] = MAD_F_MLZ(hi, lo) + t1;
okini3939 0:8ba6230eefbd 1846
okini3939 0:8ba6230eefbd 1847 MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0bcbe352));
okini3939 0:8ba6230eefbd 1848 MAD_F_MLA(hi, lo, X[2], MAD_F(0x0d7e8807));
okini3939 0:8ba6230eefbd 1849 MAD_F_MLA(hi, lo, X[3], -MAD_F(0x07635284));
okini3939 0:8ba6230eefbd 1850 MAD_F_MLA(hi, lo, X[5], MAD_F(0x04cfb0e2));
okini3939 0:8ba6230eefbd 1851 MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f9ee890));
okini3939 0:8ba6230eefbd 1852 MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0ffc19fd));
okini3939 0:8ba6230eefbd 1853 MAD_F_MLA(hi, lo, X[9], -MAD_F(0x00b2aa3e));
okini3939 0:8ba6230eefbd 1854 MAD_F_MLA(hi, lo, X[11], MAD_F(0x03768962));
okini3939 0:8ba6230eefbd 1855 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0f426cb5));
okini3939 0:8ba6230eefbd 1856 MAD_F_MLA(hi, lo, X[14], MAD_F(0x0e313245));
okini3939 0:8ba6230eefbd 1857 MAD_F_MLA(hi, lo, X[15], MAD_F(0x0898c779));
okini3939 0:8ba6230eefbd 1858 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0acf37ad));
okini3939 0:8ba6230eefbd 1859
okini3939 0:8ba6230eefbd 1860 x[18] = x[35] = MAD_F_MLZ(hi, lo) - t1;
okini3939 0:8ba6230eefbd 1861
okini3939 0:8ba6230eefbd 1862 MAD_F_ML0(hi, lo, X[4], MAD_F(0x061f78aa));
okini3939 0:8ba6230eefbd 1863 MAD_F_MLA(hi, lo, X[13], -MAD_F(0x0ec835e8));
okini3939 0:8ba6230eefbd 1864
okini3939 0:8ba6230eefbd 1865 t7 = MAD_F_MLZ(hi, lo);
okini3939 0:8ba6230eefbd 1866
okini3939 0:8ba6230eefbd 1867 MAD_F_MLA(hi, lo, X[1], -MAD_F(0x0cb19346));
okini3939 0:8ba6230eefbd 1868 MAD_F_MLA(hi, lo, X[7], MAD_F(0x0fdcf549));
okini3939 0:8ba6230eefbd 1869 MAD_F_MLA(hi, lo, X[10], MAD_F(0x0216a2a2));
okini3939 0:8ba6230eefbd 1870 MAD_F_MLA(hi, lo, X[16], -MAD_F(0x09bd7ca0));
okini3939 0:8ba6230eefbd 1871
okini3939 0:8ba6230eefbd 1872 t2 = MAD_F_MLZ(hi, lo);
okini3939 0:8ba6230eefbd 1873
okini3939 0:8ba6230eefbd 1874 MAD_F_MLA(hi, lo, X[0], MAD_F(0x04cfb0e2));
okini3939 0:8ba6230eefbd 1875 MAD_F_MLA(hi, lo, X[2], MAD_F(0x0ffc19fd));
okini3939 0:8ba6230eefbd 1876 MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0d7e8807));
okini3939 0:8ba6230eefbd 1877 MAD_F_MLA(hi, lo, X[5], MAD_F(0x03768962));
okini3939 0:8ba6230eefbd 1878 MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0bcbe352));
okini3939 0:8ba6230eefbd 1879 MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0e313245));
okini3939 0:8ba6230eefbd 1880 MAD_F_MLA(hi, lo, X[9], MAD_F(0x07635284));
okini3939 0:8ba6230eefbd 1881 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0acf37ad));
okini3939 0:8ba6230eefbd 1882 MAD_F_MLA(hi, lo, X[12], MAD_F(0x0f9ee890));
okini3939 0:8ba6230eefbd 1883 MAD_F_MLA(hi, lo, X[14], MAD_F(0x0898c779));
okini3939 0:8ba6230eefbd 1884 MAD_F_MLA(hi, lo, X[15], MAD_F(0x00b2aa3e));
okini3939 0:8ba6230eefbd 1885 MAD_F_MLA(hi, lo, X[17], MAD_F(0x0f426cb5));
okini3939 0:8ba6230eefbd 1886
okini3939 0:8ba6230eefbd 1887 x[5] = MAD_F_MLZ(hi, lo);
okini3939 0:8ba6230eefbd 1888 x[12] = -x[5];
okini3939 0:8ba6230eefbd 1889
okini3939 0:8ba6230eefbd 1890 MAD_F_ML0(hi, lo, X[0], MAD_F(0x0acf37ad));
okini3939 0:8ba6230eefbd 1891 MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0898c779));
okini3939 0:8ba6230eefbd 1892 MAD_F_MLA(hi, lo, X[3], MAD_F(0x0e313245));
okini3939 0:8ba6230eefbd 1893 MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0f426cb5));
okini3939 0:8ba6230eefbd 1894 MAD_F_MLA(hi, lo, X[6], -MAD_F(0x03768962));
okini3939 0:8ba6230eefbd 1895 MAD_F_MLA(hi, lo, X[8], MAD_F(0x00b2aa3e));
okini3939 0:8ba6230eefbd 1896 MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0ffc19fd));
okini3939 0:8ba6230eefbd 1897 MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f9ee890));
okini3939 0:8ba6230eefbd 1898 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x04cfb0e2));
okini3939 0:8ba6230eefbd 1899 MAD_F_MLA(hi, lo, X[14], MAD_F(0x07635284));
okini3939 0:8ba6230eefbd 1900 MAD_F_MLA(hi, lo, X[15], MAD_F(0x0d7e8807));
okini3939 0:8ba6230eefbd 1901 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0bcbe352));
okini3939 0:8ba6230eefbd 1902
okini3939 0:8ba6230eefbd 1903 x[0] = MAD_F_MLZ(hi, lo) + t2;
okini3939 0:8ba6230eefbd 1904 x[17] = -x[0];
okini3939 0:8ba6230eefbd 1905
okini3939 0:8ba6230eefbd 1906 MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f9ee890));
okini3939 0:8ba6230eefbd 1907 MAD_F_MLA(hi, lo, X[2], -MAD_F(0x07635284));
okini3939 0:8ba6230eefbd 1908 MAD_F_MLA(hi, lo, X[3], -MAD_F(0x00b2aa3e));
okini3939 0:8ba6230eefbd 1909 MAD_F_MLA(hi, lo, X[5], MAD_F(0x0bcbe352));
okini3939 0:8ba6230eefbd 1910 MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f426cb5));
okini3939 0:8ba6230eefbd 1911 MAD_F_MLA(hi, lo, X[8], MAD_F(0x0d7e8807));
okini3939 0:8ba6230eefbd 1912 MAD_F_MLA(hi, lo, X[9], MAD_F(0x0898c779));
okini3939 0:8ba6230eefbd 1913 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x04cfb0e2));
okini3939 0:8ba6230eefbd 1914 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0acf37ad));
okini3939 0:8ba6230eefbd 1915 MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0ffc19fd));
okini3939 0:8ba6230eefbd 1916 MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0e313245));
okini3939 0:8ba6230eefbd 1917 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x03768962));
okini3939 0:8ba6230eefbd 1918
okini3939 0:8ba6230eefbd 1919 x[24] = x[29] = MAD_F_MLZ(hi, lo) + t2;
okini3939 0:8ba6230eefbd 1920
okini3939 0:8ba6230eefbd 1921 MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0216a2a2));
okini3939 0:8ba6230eefbd 1922 MAD_F_MLA(hi, lo, X[7], -MAD_F(0x09bd7ca0));
okini3939 0:8ba6230eefbd 1923 MAD_F_MLA(hi, lo, X[10], MAD_F(0x0cb19346));
okini3939 0:8ba6230eefbd 1924 MAD_F_MLA(hi, lo, X[16], MAD_F(0x0fdcf549));
okini3939 0:8ba6230eefbd 1925
okini3939 0:8ba6230eefbd 1926 t3 = MAD_F_MLZ(hi, lo) + t7;
okini3939 0:8ba6230eefbd 1927
okini3939 0:8ba6230eefbd 1928 MAD_F_ML0(hi, lo, X[0], MAD_F(0x00b2aa3e));
okini3939 0:8ba6230eefbd 1929 MAD_F_MLA(hi, lo, X[2], MAD_F(0x03768962));
okini3939 0:8ba6230eefbd 1930 MAD_F_MLA(hi, lo, X[3], -MAD_F(0x04cfb0e2));
okini3939 0:8ba6230eefbd 1931 MAD_F_MLA(hi, lo, X[5], -MAD_F(0x07635284));
okini3939 0:8ba6230eefbd 1932 MAD_F_MLA(hi, lo, X[6], MAD_F(0x0898c779));
okini3939 0:8ba6230eefbd 1933 MAD_F_MLA(hi, lo, X[8], MAD_F(0x0acf37ad));
okini3939 0:8ba6230eefbd 1934 MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0bcbe352));
okini3939 0:8ba6230eefbd 1935 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0d7e8807));
okini3939 0:8ba6230eefbd 1936 MAD_F_MLA(hi, lo, X[12], MAD_F(0x0e313245));
okini3939 0:8ba6230eefbd 1937 MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f426cb5));
okini3939 0:8ba6230eefbd 1938 MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0f9ee890));
okini3939 0:8ba6230eefbd 1939 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0ffc19fd));
okini3939 0:8ba6230eefbd 1940
okini3939 0:8ba6230eefbd 1941 x[8] = MAD_F_MLZ(hi, lo) + t3;
okini3939 0:8ba6230eefbd 1942 x[9] = -x[8];
okini3939 0:8ba6230eefbd 1943
okini3939 0:8ba6230eefbd 1944 MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0e313245));
okini3939 0:8ba6230eefbd 1945 MAD_F_MLA(hi, lo, X[2], MAD_F(0x0bcbe352));
okini3939 0:8ba6230eefbd 1946 MAD_F_MLA(hi, lo, X[3], MAD_F(0x0f9ee890));
okini3939 0:8ba6230eefbd 1947 MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0898c779));
okini3939 0:8ba6230eefbd 1948 MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0ffc19fd));
okini3939 0:8ba6230eefbd 1949 MAD_F_MLA(hi, lo, X[8], MAD_F(0x04cfb0e2));
okini3939 0:8ba6230eefbd 1950 MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f426cb5));
okini3939 0:8ba6230eefbd 1951 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x00b2aa3e));
okini3939 0:8ba6230eefbd 1952 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0d7e8807));
okini3939 0:8ba6230eefbd 1953 MAD_F_MLA(hi, lo, X[14], -MAD_F(0x03768962));
okini3939 0:8ba6230eefbd 1954 MAD_F_MLA(hi, lo, X[15], MAD_F(0x0acf37ad));
okini3939 0:8ba6230eefbd 1955 MAD_F_MLA(hi, lo, X[17], MAD_F(0x07635284));
okini3939 0:8ba6230eefbd 1956
okini3939 0:8ba6230eefbd 1957 x[21] = x[32] = MAD_F_MLZ(hi, lo) + t3;
okini3939 0:8ba6230eefbd 1958
okini3939 0:8ba6230eefbd 1959 MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0d7e8807));
okini3939 0:8ba6230eefbd 1960 MAD_F_MLA(hi, lo, X[2], MAD_F(0x0f426cb5));
okini3939 0:8ba6230eefbd 1961 MAD_F_MLA(hi, lo, X[3], MAD_F(0x0acf37ad));
okini3939 0:8ba6230eefbd 1962 MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0ffc19fd));
okini3939 0:8ba6230eefbd 1963 MAD_F_MLA(hi, lo, X[6], -MAD_F(0x07635284));
okini3939 0:8ba6230eefbd 1964 MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f9ee890));
okini3939 0:8ba6230eefbd 1965 MAD_F_MLA(hi, lo, X[9], MAD_F(0x03768962));
okini3939 0:8ba6230eefbd 1966 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0e313245));
okini3939 0:8ba6230eefbd 1967 MAD_F_MLA(hi, lo, X[12], MAD_F(0x00b2aa3e));
okini3939 0:8ba6230eefbd 1968 MAD_F_MLA(hi, lo, X[14], MAD_F(0x0bcbe352));
okini3939 0:8ba6230eefbd 1969 MAD_F_MLA(hi, lo, X[15], -MAD_F(0x04cfb0e2));
okini3939 0:8ba6230eefbd 1970 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0898c779));
okini3939 0:8ba6230eefbd 1971
okini3939 0:8ba6230eefbd 1972 x[20] = x[33] = MAD_F_MLZ(hi, lo) - t3;
okini3939 0:8ba6230eefbd 1973
okini3939 0:8ba6230eefbd 1974 MAD_F_ML0(hi, lo, t14, -MAD_F(0x0ec835e8));
okini3939 0:8ba6230eefbd 1975 MAD_F_MLA(hi, lo, t15, MAD_F(0x061f78aa));
okini3939 0:8ba6230eefbd 1976
okini3939 0:8ba6230eefbd 1977 t4 = MAD_F_MLZ(hi, lo) - t7;
okini3939 0:8ba6230eefbd 1978
okini3939 0:8ba6230eefbd 1979 MAD_F_ML0(hi, lo, t12, MAD_F(0x061f78aa));
okini3939 0:8ba6230eefbd 1980 MAD_F_MLA(hi, lo, t13, MAD_F(0x0ec835e8));
okini3939 0:8ba6230eefbd 1981
okini3939 0:8ba6230eefbd 1982 x[4] = MAD_F_MLZ(hi, lo) + t4;
okini3939 0:8ba6230eefbd 1983 x[13] = -x[4];
okini3939 0:8ba6230eefbd 1984
okini3939 0:8ba6230eefbd 1985 MAD_F_ML0(hi, lo, t8, MAD_F(0x09bd7ca0));
okini3939 0:8ba6230eefbd 1986 MAD_F_MLA(hi, lo, t9, -MAD_F(0x0216a2a2));
okini3939 0:8ba6230eefbd 1987 MAD_F_MLA(hi, lo, t10, MAD_F(0x0fdcf549));
okini3939 0:8ba6230eefbd 1988 MAD_F_MLA(hi, lo, t11, -MAD_F(0x0cb19346));
okini3939 0:8ba6230eefbd 1989
okini3939 0:8ba6230eefbd 1990 x[1] = MAD_F_MLZ(hi, lo) + t4;
okini3939 0:8ba6230eefbd 1991 x[16] = -x[1];
okini3939 0:8ba6230eefbd 1992
okini3939 0:8ba6230eefbd 1993 MAD_F_ML0(hi, lo, t8, -MAD_F(0x0fdcf549));
okini3939 0:8ba6230eefbd 1994 MAD_F_MLA(hi, lo, t9, -MAD_F(0x0cb19346));
okini3939 0:8ba6230eefbd 1995 MAD_F_MLA(hi, lo, t10, -MAD_F(0x09bd7ca0));
okini3939 0:8ba6230eefbd 1996 MAD_F_MLA(hi, lo, t11, -MAD_F(0x0216a2a2));
okini3939 0:8ba6230eefbd 1997
okini3939 0:8ba6230eefbd 1998 x[25] = x[28] = MAD_F_MLZ(hi, lo) + t4;
okini3939 0:8ba6230eefbd 1999
okini3939 0:8ba6230eefbd 2000 MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0fdcf549));
okini3939 0:8ba6230eefbd 2001 MAD_F_MLA(hi, lo, X[7], -MAD_F(0x0cb19346));
okini3939 0:8ba6230eefbd 2002 MAD_F_MLA(hi, lo, X[10], -MAD_F(0x09bd7ca0));
okini3939 0:8ba6230eefbd 2003 MAD_F_MLA(hi, lo, X[16], -MAD_F(0x0216a2a2));
okini3939 0:8ba6230eefbd 2004
okini3939 0:8ba6230eefbd 2005 t5 = MAD_F_MLZ(hi, lo) - t6;
okini3939 0:8ba6230eefbd 2006
okini3939 0:8ba6230eefbd 2007 MAD_F_ML0(hi, lo, X[0], MAD_F(0x0898c779));
okini3939 0:8ba6230eefbd 2008 MAD_F_MLA(hi, lo, X[2], MAD_F(0x04cfb0e2));
okini3939 0:8ba6230eefbd 2009 MAD_F_MLA(hi, lo, X[3], MAD_F(0x0bcbe352));
okini3939 0:8ba6230eefbd 2010 MAD_F_MLA(hi, lo, X[5], MAD_F(0x00b2aa3e));
okini3939 0:8ba6230eefbd 2011 MAD_F_MLA(hi, lo, X[6], MAD_F(0x0e313245));
okini3939 0:8ba6230eefbd 2012 MAD_F_MLA(hi, lo, X[8], -MAD_F(0x03768962));
okini3939 0:8ba6230eefbd 2013 MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f9ee890));
okini3939 0:8ba6230eefbd 2014 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x07635284));
okini3939 0:8ba6230eefbd 2015 MAD_F_MLA(hi, lo, X[12], MAD_F(0x0ffc19fd));
okini3939 0:8ba6230eefbd 2016 MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0acf37ad));
okini3939 0:8ba6230eefbd 2017 MAD_F_MLA(hi, lo, X[15], MAD_F(0x0f426cb5));
okini3939 0:8ba6230eefbd 2018 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0d7e8807));
okini3939 0:8ba6230eefbd 2019
okini3939 0:8ba6230eefbd 2020 x[2] = MAD_F_MLZ(hi, lo) + t5;
okini3939 0:8ba6230eefbd 2021 x[15] = -x[2];
okini3939 0:8ba6230eefbd 2022
okini3939 0:8ba6230eefbd 2023 MAD_F_ML0(hi, lo, X[0], MAD_F(0x07635284));
okini3939 0:8ba6230eefbd 2024 MAD_F_MLA(hi, lo, X[2], MAD_F(0x0acf37ad));
okini3939 0:8ba6230eefbd 2025 MAD_F_MLA(hi, lo, X[3], MAD_F(0x03768962));
okini3939 0:8ba6230eefbd 2026 MAD_F_MLA(hi, lo, X[5], MAD_F(0x0d7e8807));
okini3939 0:8ba6230eefbd 2027 MAD_F_MLA(hi, lo, X[6], -MAD_F(0x00b2aa3e));
okini3939 0:8ba6230eefbd 2028 MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f426cb5));
okini3939 0:8ba6230eefbd 2029 MAD_F_MLA(hi, lo, X[9], -MAD_F(0x04cfb0e2));
okini3939 0:8ba6230eefbd 2030 MAD_F_MLA(hi, lo, X[11], MAD_F(0x0ffc19fd));
okini3939 0:8ba6230eefbd 2031 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0898c779));
okini3939 0:8ba6230eefbd 2032 MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f9ee890));
okini3939 0:8ba6230eefbd 2033 MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0bcbe352));
okini3939 0:8ba6230eefbd 2034 MAD_F_MLA(hi, lo, X[17], MAD_F(0x0e313245));
okini3939 0:8ba6230eefbd 2035
okini3939 0:8ba6230eefbd 2036 x[3] = MAD_F_MLZ(hi, lo) + t5;
okini3939 0:8ba6230eefbd 2037 x[14] = -x[3];
okini3939 0:8ba6230eefbd 2038
okini3939 0:8ba6230eefbd 2039 MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0ffc19fd));
okini3939 0:8ba6230eefbd 2040 MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0f9ee890));
okini3939 0:8ba6230eefbd 2041 MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0f426cb5));
okini3939 0:8ba6230eefbd 2042 MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0e313245));
okini3939 0:8ba6230eefbd 2043 MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0d7e8807));
okini3939 0:8ba6230eefbd 2044 MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0bcbe352));
okini3939 0:8ba6230eefbd 2045 MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0acf37ad));
okini3939 0:8ba6230eefbd 2046 MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0898c779));
okini3939 0:8ba6230eefbd 2047 MAD_F_MLA(hi, lo, X[12], -MAD_F(0x07635284));
okini3939 0:8ba6230eefbd 2048 MAD_F_MLA(hi, lo, X[14], -MAD_F(0x04cfb0e2));
okini3939 0:8ba6230eefbd 2049 MAD_F_MLA(hi, lo, X[15], -MAD_F(0x03768962));
okini3939 0:8ba6230eefbd 2050 MAD_F_MLA(hi, lo, X[17], -MAD_F(0x00b2aa3e));
okini3939 0:8ba6230eefbd 2051
okini3939 0:8ba6230eefbd 2052 x[26] = x[27] = MAD_F_MLZ(hi, lo) + t5;
okini3939 0:8ba6230eefbd 2053 }
okini3939 0:8ba6230eefbd 2054 # endif
okini3939 0:8ba6230eefbd 2055
okini3939 0:8ba6230eefbd 2056 /*
okini3939 0:8ba6230eefbd 2057 * NAME: III_imdct_l()
okini3939 0:8ba6230eefbd 2058 * DESCRIPTION: perform IMDCT and windowing for long blocks
okini3939 0:8ba6230eefbd 2059 */
okini3939 0:8ba6230eefbd 2060 static
okini3939 0:8ba6230eefbd 2061 void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36],
okini3939 0:8ba6230eefbd 2062 unsigned int block_type)
okini3939 0:8ba6230eefbd 2063 {
okini3939 0:8ba6230eefbd 2064 unsigned int i;
okini3939 0:8ba6230eefbd 2065
okini3939 0:8ba6230eefbd 2066 /* IMDCT */
okini3939 0:8ba6230eefbd 2067
okini3939 0:8ba6230eefbd 2068 imdct36(X, z);
okini3939 0:8ba6230eefbd 2069
okini3939 0:8ba6230eefbd 2070 /* windowing */
okini3939 0:8ba6230eefbd 2071
okini3939 0:8ba6230eefbd 2072 switch (block_type) {
okini3939 0:8ba6230eefbd 2073 case 0: /* normal window */
okini3939 0:8ba6230eefbd 2074 # if defined(ASO_INTERLEAVE1)
okini3939 0:8ba6230eefbd 2075 {
okini3939 0:8ba6230eefbd 2076 register mad_fixed_t tmp1, tmp2;
okini3939 0:8ba6230eefbd 2077
okini3939 0:8ba6230eefbd 2078 tmp1 = window_l[0];
okini3939 0:8ba6230eefbd 2079 tmp2 = window_l[1];
okini3939 0:8ba6230eefbd 2080
okini3939 0:8ba6230eefbd 2081 for (i = 0; i < 34; i += 2) {
okini3939 0:8ba6230eefbd 2082 z[i + 0] = mad_f_mul(z[i + 0], tmp1);
okini3939 0:8ba6230eefbd 2083 tmp1 = window_l[i + 2];
okini3939 0:8ba6230eefbd 2084 z[i + 1] = mad_f_mul(z[i + 1], tmp2);
okini3939 0:8ba6230eefbd 2085 tmp2 = window_l[i + 3];
okini3939 0:8ba6230eefbd 2086 }
okini3939 0:8ba6230eefbd 2087
okini3939 0:8ba6230eefbd 2088 z[34] = mad_f_mul(z[34], tmp1);
okini3939 0:8ba6230eefbd 2089 z[35] = mad_f_mul(z[35], tmp2);
okini3939 0:8ba6230eefbd 2090 }
okini3939 0:8ba6230eefbd 2091 # elif defined(ASO_INTERLEAVE2)
okini3939 0:8ba6230eefbd 2092 {
okini3939 0:8ba6230eefbd 2093 register mad_fixed_t tmp1, tmp2;
okini3939 0:8ba6230eefbd 2094
okini3939 0:8ba6230eefbd 2095 tmp1 = z[0];
okini3939 0:8ba6230eefbd 2096 tmp2 = window_l[0];
okini3939 0:8ba6230eefbd 2097
okini3939 0:8ba6230eefbd 2098 for (i = 0; i < 35; ++i) {
okini3939 0:8ba6230eefbd 2099 z[i] = mad_f_mul(tmp1, tmp2);
okini3939 0:8ba6230eefbd 2100 tmp1 = z[i + 1];
okini3939 0:8ba6230eefbd 2101 tmp2 = window_l[i + 1];
okini3939 0:8ba6230eefbd 2102 }
okini3939 0:8ba6230eefbd 2103
okini3939 0:8ba6230eefbd 2104 z[35] = mad_f_mul(tmp1, tmp2);
okini3939 0:8ba6230eefbd 2105 }
okini3939 0:8ba6230eefbd 2106 # elif 1
okini3939 0:8ba6230eefbd 2107 for (i = 0; i < 36; i += 4) {
okini3939 0:8ba6230eefbd 2108 z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
okini3939 0:8ba6230eefbd 2109 z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
okini3939 0:8ba6230eefbd 2110 z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
okini3939 0:8ba6230eefbd 2111 z[i + 3] = mad_f_mul(z[i + 3], window_l[i + 3]);
okini3939 0:8ba6230eefbd 2112 }
okini3939 0:8ba6230eefbd 2113 # else
okini3939 0:8ba6230eefbd 2114 for (i = 0; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]);
okini3939 0:8ba6230eefbd 2115 # endif
okini3939 0:8ba6230eefbd 2116 break;
okini3939 0:8ba6230eefbd 2117
okini3939 0:8ba6230eefbd 2118 case 1: /* start block */
okini3939 0:8ba6230eefbd 2119 for (i = 0; i < 18; i += 3) {
okini3939 0:8ba6230eefbd 2120 z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
okini3939 0:8ba6230eefbd 2121 z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
okini3939 0:8ba6230eefbd 2122 z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
okini3939 0:8ba6230eefbd 2123 }
okini3939 0:8ba6230eefbd 2124 /* (i = 18; i < 24; ++i) z[i] unchanged */
okini3939 0:8ba6230eefbd 2125 for (i = 24; i < 30; ++i) z[i] = mad_f_mul(z[i], window_s[i - 18]);
okini3939 0:8ba6230eefbd 2126 for (i = 30; i < 36; ++i) z[i] = 0;
okini3939 0:8ba6230eefbd 2127 break;
okini3939 0:8ba6230eefbd 2128
okini3939 0:8ba6230eefbd 2129 case 3: /* stop block */
okini3939 0:8ba6230eefbd 2130 for (i = 0; i < 6; ++i) z[i] = 0;
okini3939 0:8ba6230eefbd 2131 for (i = 6; i < 12; ++i) z[i] = mad_f_mul(z[i], window_s[i - 6]);
okini3939 0:8ba6230eefbd 2132 /* (i = 12; i < 18; ++i) z[i] unchanged */
okini3939 0:8ba6230eefbd 2133 for (i = 18; i < 36; i += 3) {
okini3939 0:8ba6230eefbd 2134 z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
okini3939 0:8ba6230eefbd 2135 z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
okini3939 0:8ba6230eefbd 2136 z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
okini3939 0:8ba6230eefbd 2137 }
okini3939 0:8ba6230eefbd 2138 break;
okini3939 0:8ba6230eefbd 2139 }
okini3939 0:8ba6230eefbd 2140 }
okini3939 0:8ba6230eefbd 2141 # endif /* ASO_IMDCT */
okini3939 0:8ba6230eefbd 2142
okini3939 0:8ba6230eefbd 2143 /*
okini3939 0:8ba6230eefbd 2144 * NAME: III_imdct_s()
okini3939 0:8ba6230eefbd 2145 * DESCRIPTION: perform IMDCT and windowing for short blocks
okini3939 0:8ba6230eefbd 2146 */
okini3939 0:8ba6230eefbd 2147 static
okini3939 0:8ba6230eefbd 2148 void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36])
okini3939 0:8ba6230eefbd 2149 {
okini3939 0:8ba6230eefbd 2150 mad_fixed_t y[36], *yptr;
okini3939 0:8ba6230eefbd 2151 mad_fixed_t const *wptr;
okini3939 0:8ba6230eefbd 2152 int w, i;
okini3939 0:8ba6230eefbd 2153 register mad_fixed64hi_t hi;
okini3939 0:8ba6230eefbd 2154 register mad_fixed64lo_t lo;
okini3939 0:8ba6230eefbd 2155
okini3939 0:8ba6230eefbd 2156 /* IMDCT */
okini3939 0:8ba6230eefbd 2157
okini3939 0:8ba6230eefbd 2158 yptr = &y[0];
okini3939 0:8ba6230eefbd 2159
okini3939 0:8ba6230eefbd 2160 for (w = 0; w < 3; ++w) {
okini3939 0:8ba6230eefbd 2161 register mad_fixed_t const (*s)[6];
okini3939 0:8ba6230eefbd 2162
okini3939 0:8ba6230eefbd 2163 s = imdct_s;
okini3939 0:8ba6230eefbd 2164
okini3939 0:8ba6230eefbd 2165 for (i = 0; i < 3; ++i) {
okini3939 0:8ba6230eefbd 2166 MAD_F_ML0(hi, lo, X[0], (*s)[0]);
okini3939 0:8ba6230eefbd 2167 MAD_F_MLA(hi, lo, X[1], (*s)[1]);
okini3939 0:8ba6230eefbd 2168 MAD_F_MLA(hi, lo, X[2], (*s)[2]);
okini3939 0:8ba6230eefbd 2169 MAD_F_MLA(hi, lo, X[3], (*s)[3]);
okini3939 0:8ba6230eefbd 2170 MAD_F_MLA(hi, lo, X[4], (*s)[4]);
okini3939 0:8ba6230eefbd 2171 MAD_F_MLA(hi, lo, X[5], (*s)[5]);
okini3939 0:8ba6230eefbd 2172
okini3939 0:8ba6230eefbd 2173 yptr[i + 0] = MAD_F_MLZ(hi, lo);
okini3939 0:8ba6230eefbd 2174 yptr[5 - i] = -yptr[i + 0];
okini3939 0:8ba6230eefbd 2175
okini3939 0:8ba6230eefbd 2176 ++s;
okini3939 0:8ba6230eefbd 2177
okini3939 0:8ba6230eefbd 2178 MAD_F_ML0(hi, lo, X[0], (*s)[0]);
okini3939 0:8ba6230eefbd 2179 MAD_F_MLA(hi, lo, X[1], (*s)[1]);
okini3939 0:8ba6230eefbd 2180 MAD_F_MLA(hi, lo, X[2], (*s)[2]);
okini3939 0:8ba6230eefbd 2181 MAD_F_MLA(hi, lo, X[3], (*s)[3]);
okini3939 0:8ba6230eefbd 2182 MAD_F_MLA(hi, lo, X[4], (*s)[4]);
okini3939 0:8ba6230eefbd 2183 MAD_F_MLA(hi, lo, X[5], (*s)[5]);
okini3939 0:8ba6230eefbd 2184
okini3939 0:8ba6230eefbd 2185 yptr[ i + 6] = MAD_F_MLZ(hi, lo);
okini3939 0:8ba6230eefbd 2186 yptr[11 - i] = yptr[i + 6];
okini3939 0:8ba6230eefbd 2187
okini3939 0:8ba6230eefbd 2188 ++s;
okini3939 0:8ba6230eefbd 2189 }
okini3939 0:8ba6230eefbd 2190
okini3939 0:8ba6230eefbd 2191 yptr += 12;
okini3939 0:8ba6230eefbd 2192 X += 6;
okini3939 0:8ba6230eefbd 2193 }
okini3939 0:8ba6230eefbd 2194
okini3939 0:8ba6230eefbd 2195 /* windowing, overlapping and concatenation */
okini3939 0:8ba6230eefbd 2196
okini3939 0:8ba6230eefbd 2197 yptr = &y[0];
okini3939 0:8ba6230eefbd 2198 wptr = &window_s[0];
okini3939 0:8ba6230eefbd 2199
okini3939 0:8ba6230eefbd 2200 for (i = 0; i < 6; ++i) {
okini3939 0:8ba6230eefbd 2201 z[i + 0] = 0;
okini3939 0:8ba6230eefbd 2202 z[i + 6] = mad_f_mul(yptr[ 0 + 0], wptr[0]);
okini3939 0:8ba6230eefbd 2203
okini3939 0:8ba6230eefbd 2204 MAD_F_ML0(hi, lo, yptr[ 0 + 6], wptr[6]);
okini3939 0:8ba6230eefbd 2205 MAD_F_MLA(hi, lo, yptr[12 + 0], wptr[0]);
okini3939 0:8ba6230eefbd 2206
okini3939 0:8ba6230eefbd 2207 z[i + 12] = MAD_F_MLZ(hi, lo);
okini3939 0:8ba6230eefbd 2208
okini3939 0:8ba6230eefbd 2209 MAD_F_ML0(hi, lo, yptr[12 + 6], wptr[6]);
okini3939 0:8ba6230eefbd 2210 MAD_F_MLA(hi, lo, yptr[24 + 0], wptr[0]);
okini3939 0:8ba6230eefbd 2211
okini3939 0:8ba6230eefbd 2212 z[i + 18] = MAD_F_MLZ(hi, lo);
okini3939 0:8ba6230eefbd 2213
okini3939 0:8ba6230eefbd 2214 z[i + 24] = mad_f_mul(yptr[24 + 6], wptr[6]);
okini3939 0:8ba6230eefbd 2215 z[i + 30] = 0;
okini3939 0:8ba6230eefbd 2216
okini3939 0:8ba6230eefbd 2217 ++yptr;
okini3939 0:8ba6230eefbd 2218 ++wptr;
okini3939 0:8ba6230eefbd 2219 }
okini3939 0:8ba6230eefbd 2220 }
okini3939 0:8ba6230eefbd 2221
okini3939 0:8ba6230eefbd 2222 /*
okini3939 0:8ba6230eefbd 2223 * NAME: III_overlap()
okini3939 0:8ba6230eefbd 2224 * DESCRIPTION: perform overlap-add of windowed IMDCT outputs
okini3939 0:8ba6230eefbd 2225 */
okini3939 0:8ba6230eefbd 2226 static
okini3939 0:8ba6230eefbd 2227 void III_overlap(mad_fixed_t const output[36], mad_fixed_t overlap[18],
okini3939 0:8ba6230eefbd 2228 mad_fixed_t sample[18][32], unsigned int sb)
okini3939 0:8ba6230eefbd 2229 {
okini3939 0:8ba6230eefbd 2230 unsigned int i;
okini3939 0:8ba6230eefbd 2231
okini3939 0:8ba6230eefbd 2232 # if defined(ASO_INTERLEAVE2)
okini3939 0:8ba6230eefbd 2233 {
okini3939 0:8ba6230eefbd 2234 register mad_fixed_t tmp1, tmp2;
okini3939 0:8ba6230eefbd 2235
okini3939 0:8ba6230eefbd 2236 tmp1 = overlap[0];
okini3939 0:8ba6230eefbd 2237 tmp2 = overlap[1];
okini3939 0:8ba6230eefbd 2238
okini3939 0:8ba6230eefbd 2239 for (i = 0; i < 16; i += 2) {
okini3939 0:8ba6230eefbd 2240 sample[i + 0][sb] = output[i + 0 + 0] + tmp1;
okini3939 0:8ba6230eefbd 2241 overlap[i + 0] = output[i + 0 + 18];
okini3939 0:8ba6230eefbd 2242 tmp1 = overlap[i + 2];
okini3939 0:8ba6230eefbd 2243
okini3939 0:8ba6230eefbd 2244 sample[i + 1][sb] = output[i + 1 + 0] + tmp2;
okini3939 0:8ba6230eefbd 2245 overlap[i + 1] = output[i + 1 + 18];
okini3939 0:8ba6230eefbd 2246 tmp2 = overlap[i + 3];
okini3939 0:8ba6230eefbd 2247 }
okini3939 0:8ba6230eefbd 2248
okini3939 0:8ba6230eefbd 2249 sample[16][sb] = output[16 + 0] + tmp1;
okini3939 0:8ba6230eefbd 2250 overlap[16] = output[16 + 18];
okini3939 0:8ba6230eefbd 2251 sample[17][sb] = output[17 + 0] + tmp2;
okini3939 0:8ba6230eefbd 2252 overlap[17] = output[17 + 18];
okini3939 0:8ba6230eefbd 2253 }
okini3939 0:8ba6230eefbd 2254 # elif 0
okini3939 0:8ba6230eefbd 2255 for (i = 0; i < 18; i += 2) {
okini3939 0:8ba6230eefbd 2256 sample[i + 0][sb] = output[i + 0 + 0] + overlap[i + 0];
okini3939 0:8ba6230eefbd 2257 overlap[i + 0] = output[i + 0 + 18];
okini3939 0:8ba6230eefbd 2258
okini3939 0:8ba6230eefbd 2259 sample[i + 1][sb] = output[i + 1 + 0] + overlap[i + 1];
okini3939 0:8ba6230eefbd 2260 overlap[i + 1] = output[i + 1 + 18];
okini3939 0:8ba6230eefbd 2261 }
okini3939 0:8ba6230eefbd 2262 # else
okini3939 0:8ba6230eefbd 2263 for (i = 0; i < 18; ++i) {
okini3939 0:8ba6230eefbd 2264 sample[i][sb] = output[i + 0] + overlap[i];
okini3939 0:8ba6230eefbd 2265 overlap[i] = output[i + 18];
okini3939 0:8ba6230eefbd 2266 }
okini3939 0:8ba6230eefbd 2267 # endif
okini3939 0:8ba6230eefbd 2268 }
okini3939 0:8ba6230eefbd 2269
okini3939 0:8ba6230eefbd 2270 /*
okini3939 0:8ba6230eefbd 2271 * NAME: III_overlap_z()
okini3939 0:8ba6230eefbd 2272 * DESCRIPTION: perform "overlap-add" of zero IMDCT outputs
okini3939 0:8ba6230eefbd 2273 */
okini3939 0:8ba6230eefbd 2274 static inline
okini3939 0:8ba6230eefbd 2275 void III_overlap_z(mad_fixed_t overlap[18],
okini3939 0:8ba6230eefbd 2276 mad_fixed_t sample[18][32], unsigned int sb)
okini3939 0:8ba6230eefbd 2277 {
okini3939 0:8ba6230eefbd 2278 unsigned int i;
okini3939 0:8ba6230eefbd 2279
okini3939 0:8ba6230eefbd 2280 # if defined(ASO_INTERLEAVE2)
okini3939 0:8ba6230eefbd 2281 {
okini3939 0:8ba6230eefbd 2282 register mad_fixed_t tmp1, tmp2;
okini3939 0:8ba6230eefbd 2283
okini3939 0:8ba6230eefbd 2284 tmp1 = overlap[0];
okini3939 0:8ba6230eefbd 2285 tmp2 = overlap[1];
okini3939 0:8ba6230eefbd 2286
okini3939 0:8ba6230eefbd 2287 for (i = 0; i < 16; i += 2) {
okini3939 0:8ba6230eefbd 2288 sample[i + 0][sb] = tmp1;
okini3939 0:8ba6230eefbd 2289 overlap[i + 0] = 0;
okini3939 0:8ba6230eefbd 2290 tmp1 = overlap[i + 2];
okini3939 0:8ba6230eefbd 2291
okini3939 0:8ba6230eefbd 2292 sample[i + 1][sb] = tmp2;
okini3939 0:8ba6230eefbd 2293 overlap[i + 1] = 0;
okini3939 0:8ba6230eefbd 2294 tmp2 = overlap[i + 3];
okini3939 0:8ba6230eefbd 2295 }
okini3939 0:8ba6230eefbd 2296
okini3939 0:8ba6230eefbd 2297 sample[16][sb] = tmp1;
okini3939 0:8ba6230eefbd 2298 overlap[16] = 0;
okini3939 0:8ba6230eefbd 2299 sample[17][sb] = tmp2;
okini3939 0:8ba6230eefbd 2300 overlap[17] = 0;
okini3939 0:8ba6230eefbd 2301 }
okini3939 0:8ba6230eefbd 2302 # else
okini3939 0:8ba6230eefbd 2303 for (i = 0; i < 18; ++i) {
okini3939 0:8ba6230eefbd 2304 sample[i][sb] = overlap[i];
okini3939 0:8ba6230eefbd 2305 overlap[i] = 0;
okini3939 0:8ba6230eefbd 2306 }
okini3939 0:8ba6230eefbd 2307 # endif
okini3939 0:8ba6230eefbd 2308 }
okini3939 0:8ba6230eefbd 2309
okini3939 0:8ba6230eefbd 2310 /*
okini3939 0:8ba6230eefbd 2311 * NAME: III_freqinver()
okini3939 0:8ba6230eefbd 2312 * DESCRIPTION: perform subband frequency inversion for odd sample lines
okini3939 0:8ba6230eefbd 2313 */
okini3939 0:8ba6230eefbd 2314 static
okini3939 0:8ba6230eefbd 2315 void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb)
okini3939 0:8ba6230eefbd 2316 {
okini3939 0:8ba6230eefbd 2317 unsigned int i;
okini3939 0:8ba6230eefbd 2318
okini3939 0:8ba6230eefbd 2319 # if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2)
okini3939 0:8ba6230eefbd 2320 {
okini3939 0:8ba6230eefbd 2321 register mad_fixed_t tmp1, tmp2;
okini3939 0:8ba6230eefbd 2322
okini3939 0:8ba6230eefbd 2323 tmp1 = sample[1][sb];
okini3939 0:8ba6230eefbd 2324 tmp2 = sample[3][sb];
okini3939 0:8ba6230eefbd 2325
okini3939 0:8ba6230eefbd 2326 for (i = 1; i < 13; i += 4) {
okini3939 0:8ba6230eefbd 2327 sample[i + 0][sb] = -tmp1;
okini3939 0:8ba6230eefbd 2328 tmp1 = sample[i + 4][sb];
okini3939 0:8ba6230eefbd 2329 sample[i + 2][sb] = -tmp2;
okini3939 0:8ba6230eefbd 2330 tmp2 = sample[i + 6][sb];
okini3939 0:8ba6230eefbd 2331 }
okini3939 0:8ba6230eefbd 2332
okini3939 0:8ba6230eefbd 2333 sample[13][sb] = -tmp1;
okini3939 0:8ba6230eefbd 2334 tmp1 = sample[17][sb];
okini3939 0:8ba6230eefbd 2335 sample[15][sb] = -tmp2;
okini3939 0:8ba6230eefbd 2336 sample[17][sb] = -tmp1;
okini3939 0:8ba6230eefbd 2337 }
okini3939 0:8ba6230eefbd 2338 # else
okini3939 0:8ba6230eefbd 2339 for (i = 1; i < 18; i += 2)
okini3939 0:8ba6230eefbd 2340 sample[i][sb] = -sample[i][sb];
okini3939 0:8ba6230eefbd 2341 # endif
okini3939 0:8ba6230eefbd 2342 }
okini3939 0:8ba6230eefbd 2343
okini3939 0:8ba6230eefbd 2344 /*
okini3939 0:8ba6230eefbd 2345 * NAME: III_decode()
okini3939 0:8ba6230eefbd 2346 * DESCRIPTION: decode frame main_data
okini3939 0:8ba6230eefbd 2347 */
okini3939 0:8ba6230eefbd 2348 static
okini3939 0:8ba6230eefbd 2349 enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame,
okini3939 0:8ba6230eefbd 2350 struct sideinfo *si, unsigned int nch)
okini3939 0:8ba6230eefbd 2351 {
okini3939 0:8ba6230eefbd 2352 struct mad_header *header = &frame->header;
okini3939 0:8ba6230eefbd 2353 unsigned int sfreqi, ngr, gr;
okini3939 0:8ba6230eefbd 2354
okini3939 0:8ba6230eefbd 2355 {
okini3939 0:8ba6230eefbd 2356 unsigned int sfreq;
okini3939 0:8ba6230eefbd 2357
okini3939 0:8ba6230eefbd 2358 sfreq = header->samplerate;
okini3939 0:8ba6230eefbd 2359 if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
okini3939 0:8ba6230eefbd 2360 sfreq *= 2;
okini3939 0:8ba6230eefbd 2361
okini3939 0:8ba6230eefbd 2362 /* 48000 => 0, 44100 => 1, 32000 => 2,
okini3939 0:8ba6230eefbd 2363 24000 => 3, 22050 => 4, 16000 => 5 */
okini3939 0:8ba6230eefbd 2364 sfreqi = ((sfreq >> 7) & 0x000f) +
okini3939 0:8ba6230eefbd 2365 ((sfreq >> 15) & 0x0001) - 8;
okini3939 0:8ba6230eefbd 2366
okini3939 0:8ba6230eefbd 2367 if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
okini3939 0:8ba6230eefbd 2368 sfreqi += 3;
okini3939 0:8ba6230eefbd 2369 }
okini3939 0:8ba6230eefbd 2370
okini3939 0:8ba6230eefbd 2371 /* scalefactors, Huffman decoding, requantization */
okini3939 0:8ba6230eefbd 2372
okini3939 0:8ba6230eefbd 2373 ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2;
okini3939 0:8ba6230eefbd 2374
okini3939 0:8ba6230eefbd 2375 for (gr = 0; gr < ngr; ++gr) {
okini3939 0:8ba6230eefbd 2376 struct granule *granule = &si->gr[gr];
okini3939 0:8ba6230eefbd 2377 unsigned char const *sfbwidth[2];
okini3939 0:8ba6230eefbd 2378 mad_fixed_t xr[2][576];
okini3939 0:8ba6230eefbd 2379 unsigned int ch;
okini3939 0:8ba6230eefbd 2380 enum mad_error error;
okini3939 0:8ba6230eefbd 2381
okini3939 0:8ba6230eefbd 2382 for (ch = 0; ch < nch; ++ch) {
okini3939 0:8ba6230eefbd 2383 struct channel *channel = &granule->ch[ch];
okini3939 0:8ba6230eefbd 2384 unsigned int part2_length;
okini3939 0:8ba6230eefbd 2385
okini3939 0:8ba6230eefbd 2386 sfbwidth[ch] = sfbwidth_table[sfreqi].l;
okini3939 0:8ba6230eefbd 2387 if (channel->block_type == 2) {
okini3939 0:8ba6230eefbd 2388 sfbwidth[ch] = (channel->flags & mixed_block_flag) ?
okini3939 0:8ba6230eefbd 2389 sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s;
okini3939 0:8ba6230eefbd 2390 }
okini3939 0:8ba6230eefbd 2391
okini3939 0:8ba6230eefbd 2392 if (header->flags & MAD_FLAG_LSF_EXT) {
okini3939 0:8ba6230eefbd 2393 part2_length = III_scalefactors_lsf(ptr, channel,
okini3939 0:8ba6230eefbd 2394 ch == 0 ? 0 : &si->gr[1].ch[1],
okini3939 0:8ba6230eefbd 2395 header->mode_extension);
okini3939 0:8ba6230eefbd 2396 }
okini3939 0:8ba6230eefbd 2397 else {
okini3939 0:8ba6230eefbd 2398 part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch],
okini3939 0:8ba6230eefbd 2399 gr == 0 ? 0 : si->scfsi[ch]);
okini3939 0:8ba6230eefbd 2400 }
okini3939 0:8ba6230eefbd 2401
okini3939 0:8ba6230eefbd 2402 error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length);
okini3939 0:8ba6230eefbd 2403 if (error)
okini3939 0:8ba6230eefbd 2404 return error;
okini3939 0:8ba6230eefbd 2405 }
okini3939 0:8ba6230eefbd 2406
okini3939 0:8ba6230eefbd 2407 /* joint stereo processing */
okini3939 0:8ba6230eefbd 2408
okini3939 0:8ba6230eefbd 2409 if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) {
okini3939 0:8ba6230eefbd 2410 error = III_stereo(xr, granule, header, sfbwidth[0]);
okini3939 0:8ba6230eefbd 2411 if (error)
okini3939 0:8ba6230eefbd 2412 return error;
okini3939 0:8ba6230eefbd 2413 }
okini3939 0:8ba6230eefbd 2414
okini3939 0:8ba6230eefbd 2415 /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */
okini3939 0:8ba6230eefbd 2416
okini3939 0:8ba6230eefbd 2417 for (ch = 0; ch < nch; ++ch) {
okini3939 0:8ba6230eefbd 2418 struct channel const *channel = &granule->ch[ch];
okini3939 0:8ba6230eefbd 2419 mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr];
okini3939 0:8ba6230eefbd 2420 unsigned int sb, l, i, sblimit;
okini3939 0:8ba6230eefbd 2421 mad_fixed_t output[36];
okini3939 0:8ba6230eefbd 2422
okini3939 0:8ba6230eefbd 2423 if (channel->block_type == 2) {
okini3939 0:8ba6230eefbd 2424 III_reorder(xr[ch], channel, sfbwidth[ch]);
okini3939 0:8ba6230eefbd 2425
okini3939 0:8ba6230eefbd 2426 # if !defined(OPT_STRICT)
okini3939 0:8ba6230eefbd 2427 /*
okini3939 0:8ba6230eefbd 2428 * According to ISO/IEC 11172-3, "Alias reduction is not applied for
okini3939 0:8ba6230eefbd 2429 * granules with block_type == 2 (short block)." However, other
okini3939 0:8ba6230eefbd 2430 * sources suggest alias reduction should indeed be performed on the
okini3939 0:8ba6230eefbd 2431 * lower two subbands of mixed blocks. Most other implementations do
okini3939 0:8ba6230eefbd 2432 * this, so by default we will too.
okini3939 0:8ba6230eefbd 2433 */
okini3939 0:8ba6230eefbd 2434 if (channel->flags & mixed_block_flag)
okini3939 0:8ba6230eefbd 2435 III_aliasreduce(xr[ch], 36);
okini3939 0:8ba6230eefbd 2436 # endif
okini3939 0:8ba6230eefbd 2437 }
okini3939 0:8ba6230eefbd 2438 else
okini3939 0:8ba6230eefbd 2439 III_aliasreduce(xr[ch], 576);
okini3939 0:8ba6230eefbd 2440
okini3939 0:8ba6230eefbd 2441 l = 0;
okini3939 0:8ba6230eefbd 2442
okini3939 0:8ba6230eefbd 2443 /* subbands 0-1 */
okini3939 0:8ba6230eefbd 2444
okini3939 0:8ba6230eefbd 2445 if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) {
okini3939 0:8ba6230eefbd 2446 unsigned int block_type;
okini3939 0:8ba6230eefbd 2447
okini3939 0:8ba6230eefbd 2448 block_type = channel->block_type;
okini3939 0:8ba6230eefbd 2449 if (channel->flags & mixed_block_flag)
okini3939 0:8ba6230eefbd 2450 block_type = 0;
okini3939 0:8ba6230eefbd 2451
okini3939 0:8ba6230eefbd 2452 /* long blocks */
okini3939 0:8ba6230eefbd 2453 for (sb = 0; sb < 2; ++sb, l += 18) {
okini3939 0:8ba6230eefbd 2454 III_imdct_l(&xr[ch][l], output, block_type);
okini3939 0:8ba6230eefbd 2455 III_overlap(output, (frame->overlap)[ch][sb], sample, sb);
okini3939 0:8ba6230eefbd 2456 }
okini3939 0:8ba6230eefbd 2457 }
okini3939 0:8ba6230eefbd 2458 else {
okini3939 0:8ba6230eefbd 2459 /* short blocks */
okini3939 0:8ba6230eefbd 2460 for (sb = 0; sb < 2; ++sb, l += 18) {
okini3939 0:8ba6230eefbd 2461 III_imdct_s(&xr[ch][l], output);
okini3939 0:8ba6230eefbd 2462 III_overlap(output, (frame->overlap)[ch][sb], sample, sb);
okini3939 0:8ba6230eefbd 2463 }
okini3939 0:8ba6230eefbd 2464 }
okini3939 0:8ba6230eefbd 2465
okini3939 0:8ba6230eefbd 2466 III_freqinver(sample, 1);
okini3939 0:8ba6230eefbd 2467
okini3939 0:8ba6230eefbd 2468 /* (nonzero) subbands 2-31 */
okini3939 0:8ba6230eefbd 2469
okini3939 0:8ba6230eefbd 2470 i = 576;
okini3939 0:8ba6230eefbd 2471 while (i > 36 && xr[ch][i - 1] == 0)
okini3939 0:8ba6230eefbd 2472 --i;
okini3939 0:8ba6230eefbd 2473
okini3939 0:8ba6230eefbd 2474 sblimit = 32 - (576 - i) / 18;
okini3939 0:8ba6230eefbd 2475
okini3939 0:8ba6230eefbd 2476 if (channel->block_type != 2) {
okini3939 0:8ba6230eefbd 2477 /* long blocks */
okini3939 0:8ba6230eefbd 2478 for (sb = 2; sb < sblimit; ++sb, l += 18) {
okini3939 0:8ba6230eefbd 2479 III_imdct_l(&xr[ch][l], output, channel->block_type);
okini3939 0:8ba6230eefbd 2480 III_overlap(output, (frame->overlap)[ch][sb], sample, sb);
okini3939 0:8ba6230eefbd 2481
okini3939 0:8ba6230eefbd 2482 if (sb & 1)
okini3939 0:8ba6230eefbd 2483 III_freqinver(sample, sb);
okini3939 0:8ba6230eefbd 2484 }
okini3939 0:8ba6230eefbd 2485 }
okini3939 0:8ba6230eefbd 2486 else {
okini3939 0:8ba6230eefbd 2487 /* short blocks */
okini3939 0:8ba6230eefbd 2488 for (sb = 2; sb < sblimit; ++sb, l += 18) {
okini3939 0:8ba6230eefbd 2489 III_imdct_s(&xr[ch][l], output);
okini3939 0:8ba6230eefbd 2490 III_overlap(output, (frame->overlap)[ch][sb], sample, sb);
okini3939 0:8ba6230eefbd 2491
okini3939 0:8ba6230eefbd 2492 if (sb & 1)
okini3939 0:8ba6230eefbd 2493 III_freqinver(sample, sb);
okini3939 0:8ba6230eefbd 2494 }
okini3939 0:8ba6230eefbd 2495 }
okini3939 0:8ba6230eefbd 2496
okini3939 0:8ba6230eefbd 2497 /* remaining (zero) subbands */
okini3939 0:8ba6230eefbd 2498
okini3939 0:8ba6230eefbd 2499 for (sb = sblimit; sb < 32; ++sb) {
okini3939 0:8ba6230eefbd 2500 III_overlap_z((frame->overlap)[ch][sb], sample, sb);
okini3939 0:8ba6230eefbd 2501
okini3939 0:8ba6230eefbd 2502 if (sb & 1)
okini3939 0:8ba6230eefbd 2503 III_freqinver(sample, sb);
okini3939 0:8ba6230eefbd 2504 }
okini3939 0:8ba6230eefbd 2505 }
okini3939 0:8ba6230eefbd 2506 }
okini3939 0:8ba6230eefbd 2507
okini3939 0:8ba6230eefbd 2508 return MAD_ERROR_NONE;
okini3939 0:8ba6230eefbd 2509 }
okini3939 0:8ba6230eefbd 2510
okini3939 0:8ba6230eefbd 2511 /*
okini3939 0:8ba6230eefbd 2512 * NAME: layer->III()
okini3939 0:8ba6230eefbd 2513 * DESCRIPTION: decode a single Layer III frame
okini3939 0:8ba6230eefbd 2514 */
okini3939 0:8ba6230eefbd 2515 int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame)
okini3939 0:8ba6230eefbd 2516 {
okini3939 0:8ba6230eefbd 2517 struct mad_header *header = &frame->header;
okini3939 0:8ba6230eefbd 2518 unsigned int nch, priv_bitlen, next_md_begin = 0;
okini3939 0:8ba6230eefbd 2519 unsigned int si_len, data_bitlen, md_len;
okini3939 0:8ba6230eefbd 2520 unsigned int frame_space, frame_used, frame_free;
okini3939 0:8ba6230eefbd 2521 struct mad_bitptr ptr;
okini3939 0:8ba6230eefbd 2522 struct sideinfo si;
okini3939 0:8ba6230eefbd 2523 enum mad_error error;
okini3939 0:8ba6230eefbd 2524 int result = 0;
okini3939 0:8ba6230eefbd 2525
okini3939 0:8ba6230eefbd 2526 /* allocate Layer III dynamic structures */
okini3939 0:8ba6230eefbd 2527
okini3939 0:8ba6230eefbd 2528 if (stream->main_data == 0) {
okini3939 0:8ba6230eefbd 2529 #if defined(TARGET_LPC1768)
okini3939 0:8ba6230eefbd 2530 stream->main_data = (unsigned char (*)[MAD_BUFFER_MDLEN])mad_malloc(MAD_BUFFER_MDLEN);
okini3939 0:8ba6230eefbd 2531 #else
okini3939 0:8ba6230eefbd 2532 stream->main_data = (unsigned char (*)[MAD_BUFFER_MDLEN])malloc(MAD_BUFFER_MDLEN);
okini3939 0:8ba6230eefbd 2533 #endif
okini3939 0:8ba6230eefbd 2534 if (stream->main_data == 0) {
okini3939 0:8ba6230eefbd 2535 stream->error = MAD_ERROR_NOMEM;
okini3939 0:8ba6230eefbd 2536 return -1;
okini3939 0:8ba6230eefbd 2537 }
okini3939 0:8ba6230eefbd 2538 }
okini3939 0:8ba6230eefbd 2539
okini3939 0:8ba6230eefbd 2540 nch = MAD_NCHANNELS(header);
okini3939 0:8ba6230eefbd 2541 si_len = (header->flags & MAD_FLAG_LSF_EXT) ?
okini3939 0:8ba6230eefbd 2542 (nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32);
okini3939 0:8ba6230eefbd 2543
okini3939 0:8ba6230eefbd 2544 /* check frame sanity */
okini3939 0:8ba6230eefbd 2545
okini3939 0:8ba6230eefbd 2546 if (stream->next_frame - mad_bit_nextbyte(&stream->ptr) <
okini3939 0:8ba6230eefbd 2547 (signed int) si_len) {
okini3939 0:8ba6230eefbd 2548 stream->error = MAD_ERROR_BADFRAMELEN;
okini3939 0:8ba6230eefbd 2549 stream->md_len = 0;
okini3939 0:8ba6230eefbd 2550 return -1;
okini3939 0:8ba6230eefbd 2551 }
okini3939 0:8ba6230eefbd 2552
okini3939 0:8ba6230eefbd 2553 /* check CRC word */
okini3939 0:8ba6230eefbd 2554
okini3939 0:8ba6230eefbd 2555 if (header->flags & MAD_FLAG_PROTECTION) {
okini3939 0:8ba6230eefbd 2556 header->crc_check =
okini3939 0:8ba6230eefbd 2557 mad_bit_crc(stream->ptr, si_len * CHAR_BIT, header->crc_check);
okini3939 0:8ba6230eefbd 2558
okini3939 0:8ba6230eefbd 2559 if (header->crc_check != header->crc_target &&
okini3939 0:8ba6230eefbd 2560 !(frame->options & MAD_OPTION_IGNORECRC)) {
okini3939 0:8ba6230eefbd 2561 stream->error = MAD_ERROR_BADCRC;
okini3939 0:8ba6230eefbd 2562 result = -1;
okini3939 0:8ba6230eefbd 2563 }
okini3939 0:8ba6230eefbd 2564 }
okini3939 0:8ba6230eefbd 2565
okini3939 0:8ba6230eefbd 2566 /* decode frame side information */
okini3939 0:8ba6230eefbd 2567
okini3939 0:8ba6230eefbd 2568 error = III_sideinfo(&stream->ptr, nch, header->flags & MAD_FLAG_LSF_EXT,
okini3939 0:8ba6230eefbd 2569 &si, &data_bitlen, &priv_bitlen);
okini3939 0:8ba6230eefbd 2570 if (error && result == 0) {
okini3939 0:8ba6230eefbd 2571 stream->error = error;
okini3939 0:8ba6230eefbd 2572 result = -1;
okini3939 0:8ba6230eefbd 2573 }
okini3939 0:8ba6230eefbd 2574
okini3939 0:8ba6230eefbd 2575 header->flags |= priv_bitlen;
okini3939 0:8ba6230eefbd 2576 header->private_bits |= si.private_bits;
okini3939 0:8ba6230eefbd 2577
okini3939 0:8ba6230eefbd 2578 /* find main_data of next frame */
okini3939 0:8ba6230eefbd 2579
okini3939 0:8ba6230eefbd 2580 {
okini3939 0:8ba6230eefbd 2581 struct mad_bitptr peek;
okini3939 0:8ba6230eefbd 2582 unsigned long header;
okini3939 0:8ba6230eefbd 2583
okini3939 0:8ba6230eefbd 2584 mad_bit_init(&peek, stream->next_frame);
okini3939 0:8ba6230eefbd 2585
okini3939 0:8ba6230eefbd 2586 header = mad_bit_read(&peek, 32);
okini3939 0:8ba6230eefbd 2587 if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) {
okini3939 0:8ba6230eefbd 2588 if (!(header & 0x00010000L)) /* protection_bit */
okini3939 0:8ba6230eefbd 2589 mad_bit_skip(&peek, 16); /* crc_check */
okini3939 0:8ba6230eefbd 2590
okini3939 0:8ba6230eefbd 2591 next_md_begin =
okini3939 0:8ba6230eefbd 2592 mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8);
okini3939 0:8ba6230eefbd 2593 }
okini3939 0:8ba6230eefbd 2594
okini3939 0:8ba6230eefbd 2595 mad_bit_finish(&peek);
okini3939 0:8ba6230eefbd 2596 }
okini3939 0:8ba6230eefbd 2597
okini3939 0:8ba6230eefbd 2598 /* find main_data of this frame */
okini3939 0:8ba6230eefbd 2599
okini3939 0:8ba6230eefbd 2600 frame_space = stream->next_frame - mad_bit_nextbyte(&stream->ptr);
okini3939 0:8ba6230eefbd 2601
okini3939 0:8ba6230eefbd 2602 if (next_md_begin > si.main_data_begin + frame_space)
okini3939 0:8ba6230eefbd 2603 next_md_begin = 0;
okini3939 0:8ba6230eefbd 2604
okini3939 0:8ba6230eefbd 2605 md_len = si.main_data_begin + frame_space - next_md_begin;
okini3939 0:8ba6230eefbd 2606
okini3939 0:8ba6230eefbd 2607 frame_used = 0;
okini3939 0:8ba6230eefbd 2608
okini3939 0:8ba6230eefbd 2609 if (si.main_data_begin == 0) {
okini3939 0:8ba6230eefbd 2610 ptr = stream->ptr;
okini3939 0:8ba6230eefbd 2611 stream->md_len = 0;
okini3939 0:8ba6230eefbd 2612
okini3939 0:8ba6230eefbd 2613 frame_used = md_len;
okini3939 0:8ba6230eefbd 2614 }
okini3939 0:8ba6230eefbd 2615 else {
okini3939 0:8ba6230eefbd 2616 if (si.main_data_begin > stream->md_len) {
okini3939 0:8ba6230eefbd 2617 if (result == 0) {
okini3939 0:8ba6230eefbd 2618 stream->error = MAD_ERROR_BADDATAPTR;
okini3939 0:8ba6230eefbd 2619 result = -1;
okini3939 0:8ba6230eefbd 2620 }
okini3939 0:8ba6230eefbd 2621 }
okini3939 0:8ba6230eefbd 2622 else {
okini3939 0:8ba6230eefbd 2623 mad_bit_init(&ptr,
okini3939 0:8ba6230eefbd 2624 *stream->main_data + stream->md_len - si.main_data_begin);
okini3939 0:8ba6230eefbd 2625
okini3939 0:8ba6230eefbd 2626 if (md_len > si.main_data_begin) {
okini3939 0:8ba6230eefbd 2627 /*assert(stream->md_len + md_len -si.main_data_begin <= MAD_BUFFER_MDLEN); */
okini3939 0:8ba6230eefbd 2628
okini3939 0:8ba6230eefbd 2629 memcpy(*stream->main_data + stream->md_len,
okini3939 0:8ba6230eefbd 2630 mad_bit_nextbyte(&stream->ptr),
okini3939 0:8ba6230eefbd 2631 frame_used = md_len - si.main_data_begin);
okini3939 0:8ba6230eefbd 2632 stream->md_len += frame_used;
okini3939 0:8ba6230eefbd 2633 }
okini3939 0:8ba6230eefbd 2634 }
okini3939 0:8ba6230eefbd 2635 }
okini3939 0:8ba6230eefbd 2636
okini3939 0:8ba6230eefbd 2637 frame_free = frame_space - frame_used;
okini3939 0:8ba6230eefbd 2638
okini3939 0:8ba6230eefbd 2639 /* decode main_data */
okini3939 0:8ba6230eefbd 2640
okini3939 0:8ba6230eefbd 2641 if (result == 0) {
okini3939 0:8ba6230eefbd 2642 error = III_decode(&ptr, frame, &si, nch);
okini3939 0:8ba6230eefbd 2643 if (error) {
okini3939 0:8ba6230eefbd 2644 stream->error = error;
okini3939 0:8ba6230eefbd 2645 result = -1;
okini3939 0:8ba6230eefbd 2646 }
okini3939 0:8ba6230eefbd 2647
okini3939 0:8ba6230eefbd 2648 /* designate ancillary bits */
okini3939 0:8ba6230eefbd 2649
okini3939 0:8ba6230eefbd 2650 stream->anc_ptr = ptr;
okini3939 0:8ba6230eefbd 2651 stream->anc_bitlen = md_len * CHAR_BIT - data_bitlen;
okini3939 0:8ba6230eefbd 2652 }
okini3939 0:8ba6230eefbd 2653
okini3939 0:8ba6230eefbd 2654 # if 0 && defined(DEBUG)
okini3939 0:8ba6230eefbd 2655 fprintf(stderr,
okini3939 0:8ba6230eefbd 2656 "main_data_begin:%u, md_len:%u, frame_free:%u, "
okini3939 0:8ba6230eefbd 2657 "data_bitlen:%u, anc_bitlen: %u\n",
okini3939 0:8ba6230eefbd 2658 si.main_data_begin, md_len, frame_free,
okini3939 0:8ba6230eefbd 2659 data_bitlen, stream->anc_bitlen);
okini3939 0:8ba6230eefbd 2660 # endif
okini3939 0:8ba6230eefbd 2661
okini3939 0:8ba6230eefbd 2662 /* preload main_data buffer with up to 511 bytes for next frame(s) */
okini3939 0:8ba6230eefbd 2663
okini3939 0:8ba6230eefbd 2664 if (frame_free >= next_md_begin) {
okini3939 0:8ba6230eefbd 2665 memcpy(*stream->main_data,
okini3939 0:8ba6230eefbd 2666 stream->next_frame - next_md_begin, next_md_begin);
okini3939 0:8ba6230eefbd 2667 stream->md_len = next_md_begin;
okini3939 0:8ba6230eefbd 2668 }
okini3939 0:8ba6230eefbd 2669 else {
okini3939 0:8ba6230eefbd 2670 if (md_len < si.main_data_begin) {
okini3939 0:8ba6230eefbd 2671 unsigned int extra;
okini3939 0:8ba6230eefbd 2672
okini3939 0:8ba6230eefbd 2673 extra = si.main_data_begin - md_len;
okini3939 0:8ba6230eefbd 2674 if (extra + frame_free > next_md_begin)
okini3939 0:8ba6230eefbd 2675 extra = next_md_begin - frame_free;
okini3939 0:8ba6230eefbd 2676
okini3939 0:8ba6230eefbd 2677 if (extra < stream->md_len) {
okini3939 0:8ba6230eefbd 2678 memmove(*stream->main_data,
okini3939 0:8ba6230eefbd 2679 *stream->main_data + stream->md_len - extra, extra);
okini3939 0:8ba6230eefbd 2680 stream->md_len = extra;
okini3939 0:8ba6230eefbd 2681 }
okini3939 0:8ba6230eefbd 2682 }
okini3939 0:8ba6230eefbd 2683 else
okini3939 0:8ba6230eefbd 2684 stream->md_len = 0;
okini3939 0:8ba6230eefbd 2685
okini3939 0:8ba6230eefbd 2686 memcpy(*stream->main_data + stream->md_len,
okini3939 0:8ba6230eefbd 2687 stream->next_frame - frame_free, frame_free);
okini3939 0:8ba6230eefbd 2688 stream->md_len += frame_free;
okini3939 0:8ba6230eefbd 2689 }
okini3939 0:8ba6230eefbd 2690
okini3939 0:8ba6230eefbd 2691 return result;
okini3939 0:8ba6230eefbd 2692 }