MP3 Player. You can change fwd/rev speed and skip. see: http://mbed.org/users/okini3939/notebook/lpc4088_madplayer/
Dependencies: I2SSlave SDFileSystem TLV320 mbed
madplayer/layer3.cpp@0:8ba6230eefbd, 2014-02-18 (annotated)
- Committer:
- okini3939
- Date:
- Tue Feb 18 00:22:50 2014 +0000
- Revision:
- 0:8ba6230eefbd
1st build
Who changed what in which revision?
User | Revision | Line number | New 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 | } |