//////////////////////////////////////////////////////////////////////////// // **** WAVPACK **** // // Hybrid Lossless Wavefile Compressor // // Copyright (c) 1998 - 2006 Conifer Software. // // MMX optimizations (c) 2006 Joachim Henke // // All Rights Reserved. // // Distributed under the BSD Software License (see license.txt) // //////////////////////////////////////////////////////////////////////////// // pack.c // This module actually handles the compression of the audio data, except for // the entropy coding which is handled by the words? modules. For efficiency, // the conversion is isolated to tight loops that handle an entire buffer. #include "wavpack_local.h" #include #include #include #include #ifdef DEBUG_ALLOC #define malloc malloc_db #define realloc realloc_db #define free free_db void *malloc_db (uint32_t size); void *realloc_db (void *ptr, uint32_t size); void free_db (void *ptr); int32_t dump_alloc (void); #endif //////////////////////////////// local tables /////////////////////////////// // These two tables specify the characteristics of the decorrelation filters. // Each term represents one layer of the sequential filter, where positive // values indicate the relative sample involved from the same channel (1=prev), // 17 & 18 are special functions using the previous 2 samples, and negative // values indicate cross channel decorrelation (in stereo only). static const WavpackDecorrSpec fast_specs [] = { { 1, 2,18,17 }, // 0 { 1, 1,17,17 }, // 1 { 0, 2,18,17 }, // 2 { 0, 1,17,17 }, // 3 { 1, 3, 1,18 }, // 4 { 1, 1,17, 1 }, // 5 { 0, 1, 1,17 }, // 6 { 0, 1,-2,17 }, // 7 { 0, 2,-1,17 }, // 8 { 1, 1,17, 2 }, // 9 { 0, 3,18,18 }, // 10 { 0, 1,17, 1 }, // 11 { 1, 6, 1, 2 }, // 12 { 1, 1,17, 3 }, // 13 { 0, 1,-2, 3 }, // 14 { 0, 1, 2,17 }, // 15 { 0, 1,18,-2 }, // 16 { 0, 1,-1,17 }, // 17 { 0, 1,18,17 }, // 18 { 0, 1,17, 2 }, // 19 { 1, 2,18,-2 }, // 20 { 1, 1, 1,17 }, // 21 { 0, 3,18, 2 }, // 22 { 0, 1,17,-2 }, // 23 { 0, 1,18,-2 }, // 24 { 1, 2,17,-3 }, // 25 { 0, 1,18, 3 }, // 26 { 0, 1,18,18 }, // 27 { 1, 1, 1, 3 }, // 28 { 1, 1,18, 3 }, // 29 { 1, 1, 1, 3 }, // 30 { 0, 2,18,17 }, // 31 { 1, 1, 1,17 }, // 32 { 1, 1,17, 3 }, // 33 { 0, 3,18,17 }, // 34 { 0, 1,18,18 }, // 35 { 1, 1, 1, 3 }, // 36 { 1, 1, 1,18 }, // 37 { 0, 1,18,-2 }, // 38 { 0, 2,18,17 }, // 39 { 0, 1,-1,18 }, // 40 { 1, 1,17, 3 }, // 41 { 0, 1,17, 2 }, // 42 { 0, 1,17, 3 }, // 43 { 1, 1,18, 2 }, // 44 { 1, 1,17,-2 }, // 45 { 0, 1, 1,-2 }, // 46 { 0, 2,18,17 }, // 47 { 0, 1,17,-2 }, // 48 { 1, 1,17,-2 }, // 49 { 0, 1,18, 3 }, // 50 { 0, 1, 2,17 }, // 51 { 1, 2,18,-3 }, // 52 { 1, 2, 1,18 }, // 53 { 1, 2,18, 2 }, // 54 { 0, 1,17,-1 }, // 55 { 0, 1,17,-2 }, // 56 { 1, 1,17,-2 }, // 57 { 1, 1, 1, 3 }, // 58 { 0, 1, 1,17 }, // 59 { 1, 2,18,-2 }, // 60 { 1, 2,17,-3 }, // 61 { 0, 2,18,17 }, // 62 { 0, 2,18,17 }, // 63 { 1, 1,17, 2 }, // 64 { 1, 2,18,18 }, // 65 { 0, 1,17, 2 }, // 66 { 0, 1,18,17 }, // 67 { 1, 1, 1,17 }, // 68 { 1, 1,17, 2 }, // 69 { 0, 2,18,18 }, // 70 { 0, 2,18,17 }, // 71 { 1, 2,17,-3 }, // 72 { 1, 6, 1, 2 }, // 73 { 0, 3,17,17 }, // 74 { 0, 1, 1,18 }, // 75 { 0, 1, 1,-2 }, // 76 { 1, 1,17, 2 }, // 77 { 0, 2,18,17 }, // 78 { 0, 2,18,17 }, // 79 { 1, 1,18, 3 }, // 80 { 1, 2,17,-3 }, // 81 { 0, 1,17, 2 }, // 82 { 0, 1,17, 3 }, // 83 { 0, 1,18,-2 }, // 84 { 1, 1,18,18 }, // 85 { 1, 6, 1, 2 }, // 86 { 0, 2,18,17 }, // 87 { 0, 2,18,17 }, // 88 { 0, 1,-1,17 }, // 89 { 1, 1,18, 3 }, // 90 { 0, 1,17,18 }, // 91 { 1, 1,17, 3 }, // 92 { 0, 1,18, 3 }, // 93 { 0, 2,18,17 }, // 94 { 0, 2,18,17 }, // 95 { 1, 2,18, 2 }, // 96 { 0, 1,-2, 3 }, // 97 { 0, 4,18,-1 }, // 98 { 0, 2,18,18 }, // 99 { 0, 1,-2, 3 }, // 100 { 1, 1,17,-2 }, // 101 { 0, 1,17, 3 }, // 102 { 0, 2,18,17 }, // 103 { 0, 2,-1,18 }, // 104 { 1, 1, 2,17 }, // 105 { 0, 2,17,-2 }, // 106 { 0, 1,17, 2 }, // 107 { 1, 2,18,-3 }, // 108 { 0, 1,17,-2 }, // 109 { 0, 2,18,17 }, // 110 { 0, 2,18,17 }, // 111 { 1, 1,17,-2 }, // 112 { 1, 2,17,-3 }, // 113 { 1, 1, 1, 3 }, // 114 { 1, 1, 2,17 }, // 115 { 1, 2,18, 2 }, // 116 { 1, 1, 2,17 }, // 117 { 1, 1,18, 2 }, // 118 { 0, 2,18,17 }, // 119 { 0, 2,18,17 }, // 120 { 0, 1,17,-2 }, // 121 { 0, 2,18,17 }, // 122 { 0, 2,17,-1 }, // 123 { 0, 2,18,-2 }, // 124 { 0, 2,18,17 }, // 125 { 0, 2,18,17 }, // 126 { 0, 2,18,17 }, // 127 { 1, 1, 1, 3 }, // 128 { 0, 2,-2,17 }, // 129 { 0, 2,18,-2 }, // 130 { 0, 2,17,-2 }, // 131 { 1, 1, 2,17 }, // 132 { 1, 1, 1, 3 }, // 133 { 0, 1, 2,17 }, // 134 { 0, 2,18,17 }, // 135 { 0, 3,-1,17 }, // 136 { 1, 1, 2,17 }, // 137 { 0, 2,18,18 }, // 138 { 0, 1,17, 2 }, // 139 { 1, 4,18,-3 }, // 140 { 1, 1,18, 1 }, // 141 { 0, 2,18,17 }, // 142 { 0, 2,18,17 }, // 143 { 1, 2,18,-1 }, // 144 { 0, 1,-1,18 }, // 145 { 1, 6, 1, 2 }, // 146 { 1, 1,17, 2 }, // 147 { 1, 4,18, 3 }, // 148 { 0, 1, 1,17 }, // 149 { 0, 1,18, 2 }, // 150 { 0, 2,18,17 }, // 151 { 0, 2,18,17 }, // 152 { 1, 2,17, 2 }, // 153 { 0, 2,18,-2 }, // 154 { 0, 1, 1,18 }, // 155 { 1, 2,18,-3 }, // 156 { 0, 2,18,17 }, // 157 { 0, 2,18,17 }, // 158 { 0, 2,18,17 }, // 159 { 1, 2,18,18 }, // 160 { 1, 3,17,17 }, // 161 { 0, 1,-2,17 }, // 162 { 0, 1,17,18 }, // 163 { 0, 1,-1, 3 }, // 164 { 1, 1, 2,17 }, // 165 { 0, 2,18,-1 }, // 166 { 0, 2,18,17 }, // 167 { 0, 2,18,17 }, // 168 { 1, 1,17,-2 }, // 169 { 1, 2,17, 2 }, // 170 { 1, 1,18, 3 }, // 171 { 0, 1,18, 2 }, // 172 { 1, 2,17,-3 }, // 173 { 0, 2,18,17 }, // 174 { 0, 2,18,17 }, // 175 { 0, 1,-2,17 }, // 176 { 0, 1,17,-1 }, // 177 { 0, 1,18,-1 }, // 178 { 0, 2,18,17 }, // 179 { 1, 2,17,-3 }, // 180 { 1, 1, 1,18 }, // 181 { 1, 3,18, 2 }, // 182 { 0, 2,18,17 }, // 183 { 0, 2,18,17 }, // 184 { 0, 2,18,17 }, // 185 { 0, 2,18,17 }, // 186 { 0, 3,18,18 }, // 187 { 0, 1, 1,-2 }, // 188 { 0, 2,18,17 }, // 189 { 0, 2,18,17 }, // 190 { 0, 2,18,17 }, // 191 { 1, 2,17,-3 }, // 192 { 1, 1,18,18 }, // 193 { 0, 2,18, 2 }, // 194 { 0, 1,17,18 }, // 195 { 1, 2,18, 2 }, // 196 { 1, 1,17,-2 }, // 197 { 0, 2,17,-1 }, // 198 { 0, 2,18,17 }, // 199 { 0, 2,18,17 }, // 200 { 0, 2,18,17 }, // 201 { 0, 1, 1,-2 }, // 202 { 0, 1,18, 1 }, // 203 { 1, 2,18,-2 }, // 204 { 0, 1,17, 2 }, // 205 { 0, 2,18,17 }, // 206 { 0, 2,18,17 }, // 207 { 1, 1,17, 3 }, // 208 { 0, 1,17,-1 }, // 209 { 0, 1,18, 2 }, // 210 { 1, 1,17, 3 }, // 211 { 1, 1,17,-2 }, // 212 { 0, 1,18,18 }, // 213 { 0, 2,18,17 }, // 214 { 0, 2,18,17 }, // 215 { 0, 2,18,17 }, // 216 { 0, 2,18,17 }, // 217 { 0, 2,18,17 }, // 218 { 1, 1,17,18 }, // 219 { 0, 1,-2, 3 }, // 220 { 0, 2,18,17 }, // 221 { 0, 2,18,17 }, // 222 { 0, 2,18,17 }, // 223 { 1, 2,18,-3 }, // 224 { 0, 2,18,17 }, // 225 { 0, 3,18, 2 }, // 226 { 0, 1, 1,18 }, // 227 { 0, 2,18,17 }, // 228 { 0, 1,17,-1 }, // 229 { 0, 2,18,17 }, // 230 { 0, 2,18,17 }, // 231 { 0, 2,18,17 }, // 232 { 0, 1,-2, 3 }, // 233 { 0, 3,17,17 }, // 234 { 0, 2,18,17 }, // 235 { 0, 2,18,17 }, // 236 { 1, 1,17, 2 }, // 237 { 0, 2,18,17 }, // 238 { 0, 2,18,17 }, // 239 { 1, 1,17, 2 }, // 240 { 0, 2,18,17 }, // 241 { 0, 2,18,17 }, // 242 { 0, 2,18,17 }, // 243 { 0, 2,18, 2 }, // 244 { 0, 2,18,17 }, // 245 { 0, 2,18,17 }, // 246 { 0, 2,18,17 }, // 247 { 0, 2,18,17 }, // 248 { 0, 2,18,17 }, // 249 { 0, 2,18,17 }, // 250 { 0, 2,18,17 }, // 251 { 0, 2,18,17 }, // 252 { 0, 2,18,17 }, // 253 { 0, 2,18,17 }, // 254 { 0, 2,18,17 }, // 255 }; static const WavpackDecorrSpec default_specs [] = { { 1, 2,18,18, 2,17, 3 }, // 0 { 0, 2,18,17,-1, 3, 2 }, // 1 { 1, 1,17,18,18,-2, 2 }, // 2 { 0, 2,18,17, 3,-2,17 }, // 3 { 1, 2,18,17, 2,17, 3 }, // 4 { 0, 1,18,18,-1, 2,17 }, // 5 { 0, 1,17,17,-2, 2, 3 }, // 6 { 0, 1,18,-2,18, 2,17 }, // 7 { 1, 2,18,18,-1, 2, 3 }, // 8 { 0, 2,18,17, 3, 2, 5 }, // 9 { 1, 1,18,17,18, 2, 5 }, // 10 { 0, 1,17,17,-2, 2, 3 }, // 11 { 0, 1,18,-2,18, 2, 5 }, // 12 { 0, 1,17,-2,17, 2,-3 }, // 13 { 1, 1,17,-2,17, 1, 2 }, // 14 { 0, 1,17,17,-2, 2, 3 }, // 15 { 1, 1,18, 3, 1, 5, 4 }, // 16 { 1, 4,18,18, 2, 3,-2 }, // 17 { 0, 1, 1,-1,-1, 2,17 }, // 18 { 0, 2,18,17, 3, 2, 5 }, // 19 { 0, 1,18,18,18, 2,17 }, // 20 { 0, 1,18,17,-1, 2,18 }, // 21 { 1, 1,17, 3, 2, 1, 7 }, // 22 { 0, 2,18,-2,18, 2, 3 }, // 23 { 1, 3,18,-3,18, 2, 3 }, // 24 { 0, 3,18,17, 2, 3,17 }, // 25 { 1, 1,17,17, 2, 1, 4 }, // 26 { 0, 1,17,18,-2, 2,17 }, // 27 { 1, 1,18,18, 3, 5, 2 }, // 28 { 0, 1,17,17, 2,18, 4 }, // 29 { 0, 1,18,17, 1, 4, 6 }, // 30 { 1, 1, 3,17,18, 2,17 }, // 31 { 1, 1,17, 3, 2, 1, 7 }, // 32 { 0, 1,18,17,-1, 2, 3 }, // 33 { 1, 1,17,17, 2, 1, 4 }, // 34 { 1, 2,18,17,-1,17, 3 }, // 35 { 1, 2,18,17, 2, 3,-1 }, // 36 { 0, 2,18,18,-2, 2,17 }, // 37 { 0, 1,17,17, 2,18, 4 }, // 38 { 0, 5,-2,18,18,18, 2 }, // 39 { 1, 1,18,18,-1, 6, 3 }, // 40 { 0, 1,17,17,-2, 2, 3 }, // 41 { 1, 1,18,17,18, 2,17 }, // 42 { 0, 1,18,17, 4, 3, 1 }, // 43 { 0, 1,-2,18, 2, 2,18 }, // 44 { 1, 2,18,18,-2, 2,-1 }, // 45 { 1, 1,17,17, 2, 1, 4 }, // 46 { 0, 1,17,18,-2, 2,17 }, // 47 { 1, 1,17, 3, 2, 1, 7 }, // 48 { 1, 3,18,-3,18, 2, 3 }, // 49 { 1, 2,18,18,-2, 2,-1 }, // 50 { 1, 1,18,18, 3, 5, 2 }, // 51 { 0, 2,18,18,-1, 2,17 }, // 52 { 0, 1,18,-1,17,18, 2 }, // 53 { 0, 1,17,-1, 2, 3, 6 }, // 54 { 0, 1,18,-2,18, 2, 5 }, // 55 { 1, 2,18,18,-2, 2,-1 }, // 56 { 0, 3,18,18, 2, 3,17 }, // 57 { 0, 1,17,17, 2,18, 4 }, // 58 { 1, 1,17,-2,17, 1, 2 }, // 59 { 0, 1,-1, 3, 5, 4, 7 }, // 60 { 0, 3,18,18, 3, 2, 5 }, // 61 { 0, 1,17,17, 2,18, 4 }, // 62 { 0, 1,18,17,-2,18, 3 }, // 63 { 0, 2,18,18,-2, 2,17 }, // 64 { 0, 3,18,17,-2, 2, 3 }, // 65 { 1, 1,18,18,-2, 2,17 }, // 66 { 0, 1,18,17, 4, 3, 1 }, // 67 { 1, 2, 3,18,17, 2,17 }, // 68 { 1, 2,18,18, 2,-2,18 }, // 69 { 1, 2,18,18,-1,18, 2 }, // 70 { 0, 2,18,18,-2, 2,17 }, // 71 { 1, 3,18,18, 2, 3,-2 }, // 72 { 0, 3,18,18, 3, 2, 5 }, // 73 { 0, 1,18,-2,18, 2, 5 }, // 74 { 1, 1,17, 3, 2, 1, 7 }, // 75 { 1, 3,18,18,-2, 2,18 }, // 76 { 1, 1,17,18,18,-2, 2 }, // 77 { 0, 1,18,-2,18, 2, 5 }, // 78 { 0, 2,18,-2,18, 2, 3 }, // 79 { 0, 1,-1, 3, 4, 5, 7 }, // 80 { 1, 1,17,17, 2,-1, 7 }, // 81 { 0, 1,18,-1,-1, 2,-2 }, // 82 { 0, 2,18,17, 2, 3,17 }, // 83 { 0, 1,18,17, 2,18, 2 }, // 84 { 0, 2,18,17,-1, 2,17 }, // 85 { 0, 1, 1,18, 3, 2, 5 }, // 86 { 0, 2,18,-2, 4,18, 2 }, // 87 { 1, 1,18, 3, 1, 5, 4 }, // 88 { 0, 1,18,17,18, 2, 5 }, // 89 { 1, 1,18, 3, 1, 5, 4 }, // 90 { 0, 4,18,18,-2, 2,18 }, // 91 { 1, 1,18,18, 3, 2, 5 }, // 92 { 1, 1,17,17, 2, 1, 4 }, // 93 { 0, 2,18,18,-2,18, 2 }, // 94 { 0, 2,18,18,-2,18, 2 }, // 95 { 1, 1,18,18, 2, 1, 3 }, // 96 { 1, 1,17,17, 2, 1, 4 }, // 97 { 1, 2,17,17, 2,18, 3 }, // 98 { 0, 1,18,17, 1, 4, 6 }, // 99 { 1, 2,18,18,-2, 2,-1 }, // 100 { 0, 1,18,-2,18, 2, 5 }, // 101 { 1, 1,17, 2,18, 2,17 }, // 102 { 0, 2,18,18,-2,18, 2 }, // 103 { 0, 1,18,18, 3, 6,-1 }, // 104 { 0, 1,18,17, 2,18, 3 }, // 105 { 0, 1,18,17,-2, 2,17 }, // 106 { 1, 1, 3,17,18, 2,17 }, // 107 { 1, 3,18,-3,18, 2, 3 }, // 108 { 1, 3,18,18,-3,18, 2 }, // 109 { 1, 1,18, 3, 1, 5, 4 }, // 110 { 0, 1,17,-2,17, 2,-3 }, // 111 { 1, 1,18,18, 3, 5, 2 }, // 112 { 1, 2,18,18,-2, 2,-1 }, // 113 { 0, 1,18,-1,-1, 2,-2 }, // 114 { 1, 1,18, 3, 1, 5, 4 }, // 115 { 0, 3,18,17,-1, 2,17 }, // 116 { 1, 3,18,17, 2,18,-2 }, // 117 { 0, 2,18,18,-2,18, 2 }, // 118 { 1, 2,18,18,-2, 2,-1 }, // 119 { 1, 1,18, 3, 1, 5, 4 }, // 120 { 0, 4, 3,18,18, 2,17 }, // 121 { 0, 2,18,18,-2,18, 2 }, // 122 { 1, 1,18,17,-1,18, 2 }, // 123 { 0, 2,18,18,-2,18, 2 }, // 124 { 0, 2,18,18,-2,18, 2 }, // 125 { 0, 2,18,18,-2,18, 2 }, // 126 { 0, 2,18,18,-2,18, 2 }, // 127 { 1, 1,18,18,18, 3, 2 }, // 128 { 0, 1,17,-1, 2, 3, 6 }, // 129 { 0, 1,17,-1, 2, 3, 6 }, // 130 { 0, 2,18,17,-2, 3, 2 }, // 131 { 1, 3,18,17, 2,-2,18 }, // 132 { 0, 2,18,18, 2,17, 3 }, // 133 { 0, 1,18,18, 2,18,-2 }, // 134 { 0, 2,18,-2, 4,18, 2 }, // 135 { 0, 1,-2,18, 2, 2,18 }, // 136 { 0, 2,18,17, 3, 6, 2 }, // 137 { 0, 1,18,17,18, 2, 5 }, // 138 { 0, 3,18,18,-2, 3, 2 }, // 139 { 1, 1,18,18, 2,18, 5 }, // 140 { 0, 1,17,-1, 2, 3, 6 }, // 141 { 1, 4,18,18, 2, 3,-2 }, // 142 { 0, 2,18,17,18, 2,-2 }, // 143 { 0, 1, 1,18, 3, 2, 5 }, // 144 { 1, 4,18,-2,18, 2, 3 }, // 145 { 1, 2,18, 2,18, 3,-2 }, // 146 { 0, 2,18,18,18, 2, 4 }, // 147 { 0, 2, 3,17,18, 2,17 }, // 148 { 1, 1,18,-1,18, 2,17 }, // 149 { 1, 2,17,17, 2,18, 3 }, // 150 { 0, 2,18,17,-2, 3, 2 }, // 151 { 0, 1, 1,-1,-1, 2,17 }, // 152 { 0, 3, 3,18,18, 2,17 }, // 153 { 0, 1,18,-1,17,18, 2 }, // 154 { 0, 1,18,17, 2,18, 3 }, // 155 { 0, 2,18,18,-2,18, 2 }, // 156 { 0, 1,18,17, 2,18, 2 }, // 157 { 0, 2,18,18,-2,18, 2 }, // 158 { 0, 2,18,18,-2,18, 2 }, // 159 { 1, 2,17,17, 2,18, 3 }, // 160 { 0, 1,18,17,-2, 2, 3 }, // 161 { 0, 1,18,-2,18, 2, 5 }, // 162 { 1, 4,18,-2,18, 2, 3 }, // 163 { 1, 3,18,17, 2, 3, 6 }, // 164 { 0, 2,18,18, 2,17, 3 }, // 165 { 0, 2,18,17, 2,18, 2 }, // 166 { 0, 2,18,18,-2,18, 2 }, // 167 { 1, 1,18,18, 3, 5, 2 }, // 168 { 0, 2,18,18,-2, 2, 3 }, // 169 { 1, 2,18,17, 2,17, 3 }, // 170 { 0, 1,18,17, 2, 3,18 }, // 171 { 0, 2,18,18,-2,18, 2 }, // 172 { 1, 4,18,18, 2, 3,-2 }, // 173 { 0, 1,17,-2,17, 2,-3 }, // 174 { 0, 1,17,17, 2,18, 4 }, // 175 { 1, 1,18,18,18, 2, 4 }, // 176 { 1, 2,18, 2,18, 3,-2 }, // 177 { 1, 1,18,18,-2, 2,17 }, // 178 { 0, 2,18,18,-2,18, 2 }, // 179 { 0, 2,18,18, 2,17, 3 }, // 180 { 0, 2,18,18,18, 2, 4 }, // 181 { 0, 2,18,18,-2,18, 2 }, // 182 { 0, 2,18,17,-2, 3, 2 }, // 183 { 0, 1, 1,-1,-1, 2,17 }, // 184 { 1, 4,18,18, 2, 3,-2 }, // 185 { 0, 2,18,18,-2,18, 2 }, // 186 { 0, 1,18,-2,18, 3, 2 }, // 187 { 0, 2,18,18,-2,18, 2 }, // 188 { 0, 2,18,18,-2,18, 2 }, // 189 { 0, 2,18,18,-2,18, 2 }, // 190 { 0, 2,18,18,-2,18, 2 }, // 191 { 0, 1,18,18,-2, 2,17 }, // 192 { 0, 3,18,17, 2, 3,17 }, // 193 { 1, 2,18,18, 2,-2,18 }, // 194 { 0, 1,-1, 3, 5, 4, 7 }, // 195 { 1, 1,18, 3, 1, 5, 4 }, // 196 { 1, 1,18,18,-2,18, 3 }, // 197 { 0, 2,18,17,18, 2,-2 }, // 198 { 0, 2,18,18, 2,17, 3 }, // 199 { 1, 2,18, 2,18, 3,-2 }, // 200 { 1, 4,18,18, 2, 3,-2 }, // 201 { 1, 3,18,17, 2, 3, 6 }, // 202 { 0, 2,18,18,-2,18, 2 }, // 203 { 1, 2,18,17,-2,-1,17 }, // 204 { 0, 1,17,-1, 2, 3, 6 }, // 205 { 0, 2,18,18,-2,18, 2 }, // 206 { 0, 2,18,18,-2, 2, 3 }, // 207 { 1, 1,18,18,18, 2, 5 }, // 208 { 0, 1,17,17,-2, 2, 3 }, // 209 { 0, 2,18,18,-2,18, 2 }, // 210 { 0, 2,18,17, 3, 6, 2 }, // 211 { 0, 2,18,17,18, 2, 3 }, // 212 { 0, 3,18,17,-3,18, 2 }, // 213 { 0, 1,18,18,18, 2, 3 }, // 214 { 0, 1,18,-2,-3, 2, 6 }, // 215 { 0, 2,18,18,-2,18, 2 }, // 216 { 1, 1,18,17,18, 2, 5 }, // 217 { 0, 2,18,18,-2,18, 2 }, // 218 { 0, 2,18,18,-2,18, 2 }, // 219 { 1, 1,18,17,18, 2, 5 }, // 220 { 0, 2,18,18,-2,18, 2 }, // 221 { 0, 2,18,18,-2,18, 2 }, // 222 { 0, 2,18,18,-2,18, 2 }, // 223 { 0, 1,18,18,18, 2, 3 }, // 224 { 1, 1,17,-2,17, 1, 2 }, // 225 { 1, 1,17,17, 2,-1, 7 }, // 226 { 0, 1,18,17, 4, 3, 1 }, // 227 { 1, 3,18,-3,18, 2, 3 }, // 228 { 0, 1, 1,18, 3, 2, 5 }, // 229 { 0, 2,18,18,-2,18, 2 }, // 230 { 0, 2,18,18,-2,18, 2 }, // 231 { 0, 1,18,18, 3, 6, 2 }, // 232 { 0, 1,17,17, 2,18, 4 }, // 233 { 0, 1,17,17, 2,18, 4 }, // 234 { 0, 2,18,18,-2,18, 2 }, // 235 { 0, 2,18,18,-2,18, 2 }, // 236 { 0, 2,18,18,-2,18, 2 }, // 237 { 1, 2,18,-2,18, 3, 2 }, // 238 { 1, 1,17,-2,17, 1, 2 }, // 239 { 1, 1,18,18, 3, 2, 5 }, // 240 { 0, 1,18,18,-1, 2, 3 }, // 241 { 0, 2,18,18,-2,18, 2 }, // 242 { 0, 2,18,18,-2,18, 2 }, // 243 { 0, 1,18,17,18, 2, 5 }, // 244 { 0, 2,18,18,-2,18, 2 }, // 245 { 0, 2,18,18,-2,18, 2 }, // 246 { 0, 2,18,18,-2,18, 2 }, // 247 { 0, 2,18,18,-2,18, 2 }, // 248 { 0, 1, 3,18,18, 2,17 }, // 249 { 0, 2,18,18,-2,18, 2 }, // 250 { 0, 2,18,18,-2,18, 2 }, // 251 { 0, 2,18,18,-2,18, 2 }, // 252 { 0, 2,18,18,-2,18, 2 }, // 253 { 0, 2,18,18,-2,18, 2 }, // 254 { 0, 2,18,18,-2,18, 2 }, // 255 }; static const WavpackDecorrSpec high_specs [] = { { 1, 2,18,18,18,-2, 2, 3, 5,-1,17, 4 }, // 0 { 0, 1,18,17,-2, 2,18, 3, 7, 2, 5, 4 }, // 1 { 1, 2, 1,18, 3, 6,-2,18, 2, 3, 4, 5 }, // 2 { 0, 2,18,18,-2, 2,18, 3, 6, 2,17, 4 }, // 3 { 1, 2,18,18, 2,18, 3, 2,-1, 4,18, 5 }, // 4 { 1, 1, 7, 6, 5, 3, 4, 2, 5, 4, 3, 7 }, // 5 { 1, 1,17, 3,18, 7, 2, 6, 1, 4, 3, 5 }, // 6 { 1, 1,-2,18,18,18, 3,-2, 6, 5, 2, 1 }, // 7 { 1, 2,18,18,-1,18, 2, 3, 6,-2,17, 5 }, // 8 { 0, 1,17,17,18, 3, 6, 4, 5, 2,18,-2 }, // 9 { 1, 2, 1,18,-2, 3, 5, 2, 4,-1, 6, 1 }, // 10 { 0, 2,18,18, 3, 6,18, 2, 4, 8, 5, 3 }, // 11 { 0, 1,-2, 1,18, 2,-2, 7,18, 2,-1, 5 }, // 12 { 1, 1, 4, 3, 8, 1, 5, 2, 5, 6, 2, 8 }, // 13 { 1, 1,17,18, 2, 6, 3, 4,-1, 1, 8, 6 }, // 14 { 0, 1,18,18, 3, 6, 3,-2, 2, 5,-1, 1 }, // 15 { 0, 1,18,18,17,-1, 2,-2,18, 3, 4, 5 }, // 16 { 1, 2,18,17, 2,-2,18, 3, 5, 7, 2, 4 }, // 17 { 1, 2,18,18, 3, 6,-2,18, 2, 5, 8, 3 }, // 18 { 0, 1,18,17, 2,18,18, 2, 6, 5,17, 7 }, // 19 { 1, 2,18,17, 2,18, 3, 2, 6,18,-1, 4 }, // 20 { 1, 1, 5, 3, 6, 5, 3, 4, 1, 2, 4, 7 }, // 21 { 1, 1, 5, 3, 6, 5, 3, 4, 1, 2, 4, 7 }, // 22 { 0, 1,-2,18,18,18,-2, 3, 2, 4, 6, 5 }, // 23 { 1, 2,18,17,-3, 3,-1,18, 2, 3, 6, 5 }, // 24 { 0, 1,17,18, 7, 3,-2, 7, 1, 2, 4, 5 }, // 25 { 1, 1, 2,18,18,-2, 2, 4,-1,18, 3, 6 }, // 26 { 0, 3, 1,18, 4, 3, 5, 2, 4,18, 2, 3 }, // 27 { 0, 1,-2,18, 2,18, 3, 7,18, 2, 6,-2 }, // 28 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 29 { 1, 1,18,18, 5, 4, 6, 4, 5, 1, 4, 3 }, // 30 { 1, 1,18, 3, 6, 5, 7, 8, 2, 3, 1,-1 }, // 31 { 1, 1,18,18,18, 2,-2, 3, 5,18, 2, 8 }, // 32 { 0, 2,18,17,-2, 2, 3,18,-3, 5, 2, 7 }, // 33 { 1, 1, 1, 1,-1, 8,17, 3,-2, 2, 6,17 }, // 34 { 0, 2,18,18,17, 2,-2, 3, 2, 4,18, 5 }, // 35 { 1, 1,17,18, 2,-1, 5, 7,18, 3, 4, 6 }, // 36 { 1, 1, 5, 4, 5,17, 3, 6, 3, 4, 7, 2 }, // 37 { 0, 1,17, 3, 1, 7, 4, 2, 5,-2,18, 6 }, // 38 { 0, 1,17,18, 2,18, 4, 3, 5, 7,-3, 6 }, // 39 { 1, 2,17,17,-3,-2, 2, 8,18,-1, 3, 5 }, // 40 { 0, 1,17,17,18, 2, 3, 6,-2, 8, 1, 7 }, // 41 { 1, 1, 1, 2, 6,-2,18, 2, 5,-3, 7,-2 }, // 42 { 0, 1,18,18, 3,18, 6, 8,-2, 2, 3, 5 }, // 43 { 0, 1,18,17, 2,18,-2, 3, 7, 6, 2, 4 }, // 44 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 45 { 1, 1,18,18, 2,-1, 3, 6, 1, 3, 4, 8 }, // 46 { 0, 1,18,18, 3, 6, 5, 3,-2, 2,18,-1 }, // 47 { 0, 1,18,17,-3,18, 2, 4,-2, 3, 6,17 }, // 48 { 1, 3, 1, 2,17, 3,18, 7,-1, 5, 2, 4 }, // 49 { 1, 1,18, 3,18, 6, 8,18,-2, 5, 7, 2 }, // 50 { 0, 1,17, 2,18, 6, 3, 2, 5, 4, 8, 1 }, // 51 { 0, 1,18,17,-1, 2, 3,18,18, 2, 3,17 }, // 52 { 1, 1,18, 7, 6, 5, 5, 3, 1, 4, 2, 4 }, // 53 { 1, 1, 6,17, 3, 8, 1, 5, 7,-1, 2, 1 }, // 54 { 1, 1,18,-2,18, 3,-2, 2, 7, 4, 6,18 }, // 55 { 1, 3,18,-3,18, 2, 3,18,-1, 7, 2, 5 }, // 56 { 0, 2,18,-2, 7, 1, 3, 2, 4, 6,-3, 7 }, // 57 { 1, 1,18,-2, 2,-3,18,-2,17,-1, 4, 2 }, // 58 { 0, 3,17,17, 2, 5, 3, 7,18, 6, 4, 2 }, // 59 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 60 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 61 { 1, 1,18,17, 4, 6, 6, 4, 5, 3, 4, 1 }, // 62 { 0, 1,18, 5, 3, 6, 2, 3, 8, 1, 3, 7 }, // 63 { 1, 2,18,17,-2, 2,18, 3, 5, 7,-1, 2 }, // 64 { 0, 1, 1,18,18, 3, 6,-1, 4, 8, 5, 2 }, // 65 { 1, 1, 1, 5, 3, 4, 1, 1, 3, 5, 7, 3 }, // 66 { 0, 1, 3,18,18, 2,18,18,-1, 2, 3,18 }, // 67 { 1, 2,18,18,-1,18, 2, 3, 4, 6,18, 5 }, // 68 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 69 { 1, 1,18, 3, 1, 4, 5, 2, 7, 1, 3, 6 }, // 70 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 71 { 1, 2,18,18,-1,18, 2, 3, 5,-2, 6, 8 }, // 72 { 1, 1,17,18, 4, 8, 3, 2, 5, 2, 7, 6 }, // 73 { 1, 4, 1, 2, 5,18,-2, 2, 3, 7,-1, 4 }, // 74 { 0, 2,18,17,-1, 3, 6,18, 2, 3, 7, 5 }, // 75 { 0, 1,-2,18, 2,-3, 6,18, 4, 3,-2, 5 }, // 76 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 77 { 0, 1,17,17, 6, 2, 4, 8, 3, 5,-1,17 }, // 78 { 1, 1,18, 3,18, 6, 8,18,-2, 5, 7, 2 }, // 79 { 1, 2,17,17,-3, 2,18,-2, 8, 3, 6,-1 }, // 80 { 1, 1,18,-2,17,18, 2, 3,-2, 6, 5, 4 }, // 81 { 1, 2,18,17,-1, 3,18, 2, 5, 3, 6,-3 }, // 82 { 0, 1,18,17, 2,18, 7,18, 2, 4, 3,17 }, // 83 { 1, 3,18,18, 5, 6, 4, 3, 4,18, 6, 5 }, // 84 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 85 { 1, 1, 7, 6, 5, 3, 4, 2, 5, 4, 3, 7 }, // 86 { 0, 1,-2,18,18,18, 3, 6, 4, 2, 5, 2 }, // 87 { 0, 3,18,17,-3,18, 3, 2, 5,-1,17, 3 }, // 88 { 1, 1,17,18, 7, 3, 1, 7, 4, 2, 6, 5 }, // 89 { 1, 1,18, 2,-2,-1,18, 5, 3,-2, 1, 2 }, // 90 { 0, 3,18,18,-1, 3, 2, 7, 5,18, 4, 3 }, // 91 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 92 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 93 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 94 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 95 { 1, 1,17,18, 2,-2, 4, 8,18, 3, 6, 5 }, // 96 { 0, 2,18,17, 3, 5,-2, 7, 2,18, 3,-1 }, // 97 { 1, 1,18, 2,-2,-1,18, 5, 3,-2, 1, 2 }, // 98 { 0, 2, 3,17,18,18, 2, 5, 7, 6,18, 3 }, // 99 { 1, 1,17,18,18, 4, 3, 2,18, 7, 8,-1 }, // 100 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 101 { 0, 1,17, 1, 2, 3, 5, 6, 1, 4, 8,17 }, // 102 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 103 { 0, 2,18,17,-1,18,-3, 2, 8, 3, 6,17 }, // 104 { 1, 1,17,17, 1, 2, 4, 5,-1, 2, 1, 6 }, // 105 { 1, 1, 1, 2, 6,-2,18, 2,-3, 3,-2, 5 }, // 106 { 0, 1,18, 3,18, 6,18, 5, 2, 4,-1, 8 }, // 107 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 108 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 109 { 1, 1,18,18,-1, 2,18, 3, 6, 4,-2, 7 }, // 110 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 111 { 0, 2,-1,18,18,18, 2,-2, 4, 7, 2, 3 }, // 112 { 0, 3, 3,17,-2, 5, 2, 7,18, 6, 4, 5 }, // 113 { 0, 1,17, 6,18, 3, 8, 4, 5, 3, 8,18 }, // 114 { 0, 2,18, 2, 6, 2,18, 3, 2, 4, 5, 8 }, // 115 { 0, 1, 3,18,18, 2,18,-1, 2,18, 2,17 }, // 116 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 117 { 0, 1, 3, 6,17,-2, 5, 1, 2, 7, 4, 8 }, // 118 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 119 { 1, 3, 3,18,17, 5, 6, 2, 7,-2, 8,18 }, // 120 { 1, 1,18,-1, 3, 1, 7, 2,-1, 4, 6,17 }, // 121 { 1, 1,18, 2,-2,-1,18, 5, 3,-2, 1, 2 }, // 122 { 0, 2,18, 1, 2,18, 3, 6, 5, 2, 4, 8 }, // 123 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 124 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 125 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 126 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 127 { 1, 1,17,-2, 2,18,18, 8, 5, 3, 2, 6 }, // 128 { 0, 1,18,17, 2,18, 3, 2, 7,-2,18, 4 }, // 129 { 1, 2, 1,18, 2, 3,-1, 5, 6, 4, 7,17 }, // 130 { 0, 2,18,17, 3, 6,-2, 2, 3, 8, 5,17 }, // 131 { 0, 2,18,18, 3, 2,18,-1, 2, 4, 3,17 }, // 132 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 133 { 1, 2,17,-1,18, 2, 3,-2, 5,18, 2, 7 }, // 134 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 135 { 1, 2,18,-3,18, 2, 3,-2,18, 5, 6,-3 }, // 136 { 0, 2,18,17, 3, 5,-2, 7, 2,18, 3,-1 }, // 137 { 1, 1, 1,18,-1, 2, 3, 1,-2, 8, 2, 5 }, // 138 { 0, 1,18,18, 3, 6,18, 2, 3, 4, 8, 5 }, // 139 { 0, 1,-2, 1,18, 2,-2, 5, 7,18, 2,-1 }, // 140 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 141 { 1, 1,17,18,-1, 2, 8, 3, 4, 5, 1, 7 }, // 142 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 143 { 0, 2,18,18,-1, 2,18, 3,-2, 5, 4, 2 }, // 144 { 1, 1,18,17, 2,18, 3, 8, 5, 2, 7,17 }, // 145 { 0, 1,18,18, 3,18, 6, 8,-2, 2, 3, 5 }, // 146 { 0, 1,18,18, 2,18, 2, 6,18, 2,17, 7 }, // 147 { 1, 3,18,17,18, 2, 8,18, 5,-1, 3, 6 }, // 148 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 149 { 1, 1,18, 7, 6, 5, 5, 3, 1, 4, 2, 4 }, // 150 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 151 { 1, 2,18,17,-1, 3, 6,18, 2, 5, 8, 3 }, // 152 { 0, 1,17,18,18, 4, 7, 2, 3,-2,18, 5 }, // 153 { 1, 2,18, 1, 2, 6, 2, 5,18, 2, 4, 8 }, // 154 { 0, 4,18, 4, 1, 2, 3, 5, 4, 1, 2, 6 }, // 155 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 156 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 157 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 158 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 159 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 160 { 0, 2,18,17, 2,-1,18, 3,-3, 5, 2, 4 }, // 161 { 0, 1,17,17, 3, 6, 3, 5,-2, 2,18,-1 }, // 162 { 0, 2,18,18, 3,-2,18, 2,-3, 5, 3, 6 }, // 163 { 1, 1,17,17, 2, 4, 1, 3, 5, 2, 6,-3 }, // 164 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 165 { 0, 1,17, 1, 3, 2, 7, 1, 6, 3, 4, 8 }, // 166 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 167 { 0, 1,17,-1,18, 2, 1, 5, 3, 8,-1,-2 }, // 168 { 1, 1,17,18,-1, 8, 2, 5, 3, 4, 1, 6 }, // 169 { 1, 2, 1,18, 3,-1, 5, 1, 2, 4, 7, 6 }, // 170 { 0, 1,18,18, 3, 6, 5, 3,-2, 2,18,-1 }, // 171 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 172 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 173 { 0, 1, 1,18,-1, 3, 8, 5, 6, 1, 2, 3 }, // 174 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 175 { 0, 2,18,18, 2, 3, 6,18,-1, 4, 2, 3 }, // 176 { 1, 1, 1, 3, 5,18, 2, 6, 7, 2, 3, 1 }, // 177 { 1, 1, 1, 3, 8,18, 5, 2, 7, 1, 3,-2 }, // 178 { 0, 2,17, 2,18, 3, 6, 2, 4, 5, 8, 3 }, // 179 { 0, 1,18,17, 2,18, 3, 2, 7,-2,18, 4 }, // 180 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 181 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 182 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 183 { 1, 2,18,-3,18,-1, 3,-2, 5, 7, 1, 2 }, // 184 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 185 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 186 { 0, 3,18,18, 2, 6,18, 5,18, 2, 3,17 }, // 187 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 188 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 189 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 190 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 191 { 1, 3, 1,-1, 1, 3,-2, 2, 5, 7,-3,18 }, // 192 { 1, 2,18, 7, 3,-3, 2, 8, 2, 5, 4,17 }, // 193 { 1, 1, 1, 4, 5, 1, 3, 4, 6, 7, 8, 3 }, // 194 { 0, 1,18,17, 2,18,-1, 2, 3,18, 2, 4 }, // 195 { 0, 2,18,18,-2,18, 2, 3, 4, 7, 5,17 }, // 196 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 197 { 1, 1,17,18, 2, 1, 3, 2, 5, 1, 2, 3 }, // 198 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 199 { 0, 2,18,18,-1, 2, 3, 5, 8, 6, 1,-2 }, // 200 { 0, 1,17,18, 8, 3, 4, 6, 5, 2, 8, 7 }, // 201 { 1, 2, 1, 3,-2,18, 2, 5, 1, 7,-1,-2 }, // 202 { 0, 3,18,17,-1, 3,18, 2, 3, 6, 4,17 }, // 203 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 204 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 205 { 1, 2,18,18, 4,18, 6, 7, 8, 3,18, 2 }, // 206 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 207 { 0, 2,17,-3,17, 2,-2, 8, 3,18, 4,-3 }, // 208 { 1, 1,18,17, 3, 5, 6, 2, 8, 1, 3, 7 }, // 209 { 0, 1,18,18, 3, 6, 5, 3,-2, 2,18,-1 }, // 210 { 0, 3,18,18, 2, 6,18, 5,18, 2, 3,17 }, // 211 { 1, 1,18,18, 5, 4, 6, 4, 5, 1, 4, 3 }, // 212 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 213 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 214 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 215 { 0, 2, 3,17,18,-3, 2, 5,18, 6,-1, 7 }, // 216 { 1, 1,17,18, 3, 2, 5,-1, 6, 8, 4, 7 }, // 217 { 1, 1,18, 1,-2, 3, 2, 1, 7, 6, 3, 4 }, // 218 { 0, 3, 1, 2,17, 3,18, 2, 7, 5, 4,-1 }, // 219 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 220 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 221 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 222 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 223 { 1, 1,17,-2, 2,18,18, 8, 5, 3, 2, 6 }, // 224 { 0, 2,18, 5,18, 2, 3, 7,-2, 1, 6, 8 }, // 225 { 0, 1, 2,-1,18,-1, 2, 4,-3, 5,18, 3 }, // 226 { 0, 1, 3,17,18, 5, 2,18, 7, 3, 6, 5 }, // 227 { 1, 4, 1, 2, 5,18,-2, 2, 3, 7,-1, 4 }, // 228 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 229 { 0, 1, 1,18, 2, 1, 3, 4, 1, 5, 2, 7 }, // 230 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 231 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 232 { 0, 1,17,17,18, 2, 4, 5,18,-2, 6, 3 }, // 233 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 234 { 0, 2,18,18,-1, 3, 5, 6, 8,18, 2, 3 }, // 235 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 236 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 237 { 0, 1,18,18, 4, 6, 8,18, 7, 3, 2, 5 }, // 238 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 239 { 0, 2,-1,18,18,18, 2, 4,-2, 2, 3, 6 }, // 240 { 0, 2,18,-2, 7, 1, 3, 2, 4, 6,-3, 7 }, // 241 { 1, 1,17,18, 8, 3, 4, 6,-2, 5, 3, 8 }, // 242 { 0, 2,18, 1, 2, 6, 2, 8, 3,18, 5, 4 }, // 243 { 1, 1, 3,18,18, 2,18, 2,18, 3, 2,18 }, // 244 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 245 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 246 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 247 { 1, 1, 3,17,18, 5, 2, 6, 7, 1, 4, 8 }, // 248 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 249 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 250 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 251 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 252 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 253 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 254 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2, 8 }, // 255 }; static const WavpackDecorrSpec very_high_specs [] = { { 1, 2,18,18, 2, 3,-2,18, 2, 4, 7, 5, 3, 6, 8,-1,18, 2 }, // 0 { 0, 1,18,18,-1,18, 2, 3, 4, 6, 5, 7,18,-3, 8, 2,-1, 3 }, // 1 { 1, 2, 1,18,-2, 4,18, 2, 3, 6,-1, 7, 5,-2,18, 8, 2, 4 }, // 2 { 0, 1,17,17, 2, 3, 4,18,-1, 5, 6, 7,18, 2, 8,17, 3,-2 }, // 3 { 1, 1,18,18, 2,18, 3, 2,18, 4,-1, 3,18, 2, 6, 8,17, 5 }, // 4 { 0, 2,18,17, 2, 3,-2, 5,18,-3, 2, 4, 7, 3, 6, 8, 5,17 }, // 5 { 1, 1,18,-2, 2,-3,18, 5,-2,18, 2, 3, 6, 2,17, 4, 7,-1 }, // 6 { 1, 1,17, 8,18, 3,-2, 2, 5, 4,18, 6, 3, 8, 7, 2, 5, 4 }, // 7 { 0, 2,18,17,-2, 2,18, 3, 2, 5,-3, 4, 7,18, 3, 8, 6, 2 }, // 8 { 1, 1, 3, 6, 5, 5, 1, 3, 7, 4, 2, 6, 4,18, 3, 7, 5, 6 }, // 9 { 1, 2, 1,18, 3, 2,-2, 1, 5, 4, 6, 2, 7, 1, 8, 3,-1, 1 }, // 10 { 0, 1,18,18, 2, 3, 6, 3, 5,-2, 2, 4,18, 3,-2,-1, 6, 7 }, // 11 { 0, 1,-2,18, 2,18, 7, 2, 6,-2, 3, 4,18,18, 2,-3, 8, 5 }, // 12 { 0, 2,18,18,18, 2, 4, 3,18, 5, 3, 6,-2, 2, 4,18, 8, 7 }, // 13 { 0, 1,-2, 1,18, 2,-2,18,-1, 5, 7, 2, 3, 4,18, 2, 6, 2 }, // 14 { 1, 1,17,18, 3, 2, 1, 7,-1, 2, 4, 3, 5, 6,-2,18, 7, 8 }, // 15 { 1, 1,18,18, 2,18, 3, 4, 6,-2,18, 5, 8, 2, 3, 7, 4,-1 }, // 16 { 0, 1,18,18,18,-1, 2, 3, 4, 6, 8,18, 3, 5, 2, 6, 7, 4 }, // 17 { 1, 1,17,-2,18,18, 2, 5, 3, 8, 2,-1, 6, 1, 3, 4, 7, 5 }, // 18 { 0, 1,17,17,18, 2, 3, 6,-2, 8, 1, 7, 5, 2, 3, 1, 4, 8 }, // 19 { 1, 1,17,17, 3, 2, 7, 1, 4, 3, 6, 2, 5,-2, 8, 7,18, 6 }, // 20 { 0, 1,18,17,-2, 2,18, 3,-3, 7, 6, 5, 2, 4,-1, 8, 3,17 }, // 21 { 1, 1, 2,18,18,-2, 2, 4,-1, 5,18, 3, 8, 6, 2, 7,17, 4 }, // 22 { 0, 1,17, 3, 6, 8, 5, 4, 3, 8, 1,18, 7, 2, 4, 5, 6, 3 }, // 23 { 1, 2,17,18, 4, 8, 3, 2, 5, 7, 6, 8, 2, 7,-2,18, 3, 4 }, // 24 { 1, 1, 6, 5, 5, 3, 4, 7, 3, 2, 4, 6, 3, 7, 1, 5, 2, 4 }, // 25 { 1, 1, 1,18,-1, 2, 1, 3, 8,-2, 2, 5, 6, 3, 8, 7,18, 4 }, // 26 { 0, 1, 1,17,-1,18, 3, 2, 5, 4, 6, 7, 8, 3, 4, 2, 1,-2 }, // 27 { 0, 1,18, 2,18,18, 2,18, 6,-2,18, 7, 5, 4, 3, 2,18,-2 }, // 28 { 0, 3, 1, 4,18, 3, 2, 4, 1, 5, 2, 3, 6,18, 8, 7, 2, 4 }, // 29 { 0, 1,17,-2, 1,-3, 2,18, 3,-2, 4,18, 3, 6, 7,-3, 2, 8 }, // 30 { 1, 1,17,18,18, 4, 2, 3, 7, 6,18, 8, 5,-1, 4, 2, 3,17 }, // 31 { 1, 2,18,-1,17,18, 2, 3,-2,18, 5, 8, 2, 4, 3, 7, 6,-1 }, // 32 { 1, 1,18,18,18,-2, 4, 2, 3,18, 5, 8, 2, 4, 6, 7,-2, 3 }, // 33 { 1, 2,18,18,-2,18,-1, 3, 2, 5,18,-2, 7, 2, 3, 4, 6, 8 }, // 34 { 0, 1,17,18,-1, 2, 4,18, 8, 3, 6, 5, 7,-3, 2, 4, 3,17 }, // 35 { 1, 1,18,18,17, 2,-1,18, 3, 2,18, 6, 5, 4,18, 7, 2,-1 }, // 36 { 0, 2, 1,18,-1,18, 3, 2, 4, 6,-3, 7,-1, 5, 1, 2, 3, 8 }, // 37 { 1, 1, 1,17,-2, 2,-3, 6, 3, 5, 1, 2, 7, 6, 8,-2, 4, 1 }, // 38 { 0, 1,17,-1, 5, 1, 4, 3, 6, 2,-2,18, 3, 2, 4, 5, 8,-1 }, // 39 { 0, 2,18,18,17, 2, 3,-2, 5,18, 2, 4, 7, 8, 6,17, 3, 5 }, // 40 { 1, 1, 1, 5, 1, 3, 4, 3, 7, 5, 1, 3, 6, 1, 2, 4, 3, 8 }, // 41 { 1, 2, 1,-1, 3, 2,18, 7,-2, 5, 2, 6, 4, 3,-1,18, 8, 7 }, // 42 { 0, 2,18,17, 3,18, 2, 5, 4, 3, 6, 2, 7, 8,18, 3, 4, 5 }, // 43 { 1, 1, 3, 6,17, 8, 7, 5,18,-1, 1, 2, 3, 4, 2, 6, 8, 1 }, // 44 { 0, 2,18,18, 3,-3,18, 2, 6, 5, 3, 7,18, 4,-2, 8, 2, 3 }, // 45 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 46 { 1, 1,17, 1, 7, 2, 3,18,-2, 3, 6, 4, 2, 7, 8, 5, 3,17 }, // 47 { 1, 1, 3, 6, 5, 5, 1, 3, 7, 4, 2, 6, 4,18, 3, 7, 5, 6 }, // 48 { 0, 1,18,18,18, 2, 4,-1,18, 8,-1, 2, 3, 4, 6,-2, 1, 7 }, // 49 { 1, 1,18,-2,17,18, 2, 6, 3,-2, 5, 4, 7, 1,-3, 8, 2, 6 }, // 50 { 0, 1,17,18,18, 4, 2, 7, 3, 6,-2,18, 8, 4, 5, 2, 7,17 }, // 51 { 1, 1,18,18, 5, 4, 6, 4, 1, 5, 4, 3, 2, 5, 6, 1, 4, 5 }, // 52 { 0, 1,18,18,-2,18, 2,-3, 3, 8, 5,18, 6, 4, 3,-1, 7, 2 }, // 53 { 1, 1,18, 2,-2,-3,18, 5, 2, 3,-2, 4, 6, 1,-3, 2, 7, 8 }, // 54 { 0, 1,18, 3, 5, 8, 2, 6, 7, 3, 1, 5, 2,-1, 8, 6, 7, 4 }, // 55 { 1, 1, 4, 3, 8, 1, 5, 6, 2, 5, 8,-2, 2, 7, 3,18, 5, 4 }, // 56 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 57 { 1, 1,17, 3,18,18, 7, 2, 4,18, 6, 2, 3,-1, 8, 5,18,-3 }, // 58 { 0, 1, 3,17,18, 2,18, 6, 7,-3,18, 2, 5, 6, 3, 8, 7,-1 }, // 59 { 1, 1,18,18, 2,18,18, 2,-1, 7, 3,18, 5, 2, 6, 4,-1,18 }, // 60 { 0, 3,18, 3, 4, 1, 5, 2,18, 4, 2, 3,18, 7, 6, 1, 2, 4 }, // 61 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 62 { 1, 1,17, 1,18, 2, 3, 6, 4, 5, 7,18, 3, 8, 2, 4,-2,17 }, // 63 { 1, 2,18,17, 2, 3, 5,18, 6,-2, 7, 3, 2, 4,18, 8,-1, 5 }, // 64 { 0, 2, 1,18,-1,18, 3, 2, 4, 6,-3, 7,-1, 5, 1, 2, 3, 8 }, // 65 { 1, 1, 1,18,-1, 8, 2, 6, 3,-2, 1, 2, 5, 4,-3, 8, 6, 3 }, // 66 { 0, 1,18,18, 2,18, 2,18, 7, 6,18, 2,-2, 3, 5, 4,18, 8 }, // 67 { 1, 2,18,17, 2, 3,18,-1, 2, 3, 6,18, 5, 4, 3, 7, 2, 8 }, // 68 { 1, 2,18,18, 3,-2, 4,18, 5, 7, 6, 2, 4,-3, 8, 5,18, 3 }, // 69 { 1, 1,17,-2,18,18, 2, 5, 3, 8, 2,-1, 6, 1, 3, 4, 7, 5 }, // 70 { 1, 1, 3,17,18, 5, 7, 2, 4, 6, 1, 8,-1, 3, 7, 4, 1, 2 }, // 71 { 0, 2, 1,-2, 2,18, 3, 5, 2, 4, 7,-1, 2, 3, 5,18,-2, 4 }, // 72 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 73 { 1, 1, 1, 2,-2, 6,18,-3, 2, 7, 3,-2, 5, 6, 1, 8, 2, 4 }, // 74 { 0, 1,18,18,18, 3,-2, 6,18, 2, 4, 3, 5, 8, 7, 6, 2,-2 }, // 75 { 1, 1, 1, 5, 1, 3, 4, 3, 7, 5, 1, 3, 6, 1, 2, 4, 3, 8 }, // 76 { 0, 1, 3,17,18, 2, 5,18, 6, 7, 5,-2, 2, 4,18, 3, 6, 8 }, // 77 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 78 { 0, 2,17,-1,18, 2, 4,-1, 8, 3,18, 7,-3, 4, 5, 1, 2,-2 }, // 79 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 8, 6, 4, 5, 7,-1 }, // 80 { 1, 1,18,18, 3, 6, 4, 8,-2, 2, 5, 3, 7,18, 6, 8, 4, 2 }, // 81 { 1, 1,17,18,18,-2, 5, 2, 3, 1, 4,-1, 8, 6, 5, 3, 2,18 }, // 82 { 1, 1,17,17, 1, 2, 4, 5, 2, 6,-1, 3, 1, 1,-2, 4, 2, 7 }, // 83 { 1, 1,17, 1, 7, 2, 3,18,-2, 3, 6, 4, 2, 7, 8, 5, 3,17 }, // 84 { 0, 1,18,17,-2,-3, 1, 2, 3, 2, 5, 4, 7,-3, 6,-2, 2, 1 }, // 85 { 1, 1, 1, 3, 5,18, 1, 2, 7, 3, 6, 2, 5, 8,-1, 1, 4, 7 }, // 86 { 1, 1,17, 3, 6, 8, 1, 4, 5, 3,-2, 7, 2, 8, 5, 6,18, 3 }, // 87 { 1, 1,17,18, 2, 4, 8,-2, 3, 1, 5, 6, 7, 1, 2, 3, 4, 7 }, // 88 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 89 { 1, 1, 3, 1, 8,18, 5, 2, 3,18, 6, 7,-2, 4, 3, 2, 8,18 }, // 90 { 0, 1,18,17, 2,18, 3, 4,-1,18, 7, 6, 2, 8, 4,18,18, 5 }, // 91 { 0, 1,18,18, 2,18,18, 2, 7,-2, 6, 5, 4, 3,18, 3, 2,17 }, // 92 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 93 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 94 { 1, 1,17, 8,18, 3, 2, 1, 5, 4, 6,-1, 3,-3, 8,18, 7, 2 }, // 95 { 1, 2,18,17,18, 2, 3, 5,-2,18, 6,-1, 2, 3, 7, 4, 8,17 }, // 96 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 8, 6, 4, 5, 7,-1 }, // 97 { 1, 2,18,18,-2,17, 2,18, 3, 4,18, 8, 7,-1, 2, 4, 5,17 }, // 98 { 0, 2,17,-3,17, 3, 2,-2,18, 8, 4,-3, 2,18, 5, 3,-2, 6 }, // 99 { 0, 1,18,18, 2,18,18, 2, 7,-2, 6, 5, 4, 3,18, 3, 2,17 }, // 100 { 0, 2, 1,18,-1, 3, 5, 2,-3,18, 7, 3,-1, 6, 4, 2,17, 5 }, // 101 { 1, 1,17,-2,17, 2,-3, 1, 5,-1, 4, 6, 3, 2, 8, 7,-2, 5 }, // 102 { 1, 1, 1,18, 1, 3, 5, 8, 6, 2, 3,-1, 7, 1, 4, 8, 5,-3 }, // 103 { 0, 2, 3,18,18, 2,18,-2, 6, 5, 7, 2, 4,18, 3, 6,-3, 5 }, // 104 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 105 { 1, 1, 3, 6,17, 8, 7, 5,18,-1, 1, 2, 3, 4, 2, 6, 8, 1 }, // 106 { 0, 4,18, 2,17, 3,18,-2, 2, 6,18, 2, 7, 3, 5, 4, 8,18 }, // 107 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 108 { 0, 1,18,18, 2, 3, 6, 3, 5,-2, 2, 4,18, 3,-2,-1, 6, 7 }, // 109 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 110 { 1, 1,17, 1, 2, 5, 3,-2, 1, 4, 3, 7, 6,-3, 2, 1, 1, 2 }, // 111 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 112 { 1, 1,18,18,-2,18,-2, 2, 3, 6,18, 4,-1, 2, 3, 8, 1, 4 }, // 113 { 1, 1,17,-2,17, 2,-3, 1, 5,-1, 4, 6, 3, 2, 8, 7,-2, 5 }, // 114 { 0, 1,17,17,18, 3, 2,18,18, 6, 8, 2,-2, 3, 5, 4,17,18 }, // 115 { 1, 1, 1, 5, 1, 3, 4, 3, 7, 5, 1, 3, 6, 1, 2, 4, 3, 8 }, // 116 { 1, 1, 1, 3,-3,18,18, 6, 5,18, 2,-1, 3, 8, 7,-3, 4,17 }, // 117 { 1, 1,18, 1, 2, 1, 3, 8, 7, 4, 1, 5, 2,-1,-3,18, 6, 2 }, // 118 { 0, 1,18, 3, 5, 2, 6, 8,18, 5, 7, 2, 3,-1, 6, 7, 8, 5 }, // 119 { 0, 2,18, 3,-2, 7, 8, 2, 5, 4,-3, 8, 3, 2,18, 5, 4, 6 }, // 120 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 121 { 1, 3, 1, 1, 2, 5, 2, 7, 4, 3,-1,18,-2, 8, 2, 1, 6, 7 }, // 122 { 0, 1, 3,17,18, 5, 2, 6, 7,18, 4, 5, 3, 6,18, 2, 7, 8 }, // 123 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 124 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 125 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 126 { 0, 1, 1,18, 1, 2, 3, 5, 1, 2, 6, 7, 4, 3, 8, 1,17, 5 }, // 127 { 1, 2,17,-1,18,-2, 2, 3, 5,18, 2, 4, 6, 7, 3,-1, 5, 8 }, // 128 { 1, 1,18,18,-3,18,-2, 2, 3,-2,18, 6, 4, 5, 8, 3,17,-3 }, // 129 { 1, 1,18, 7, 6, 5, 5, 3, 1, 4, 2, 7, 3, 4,-3, 6,18, 8 }, // 130 { 0, 2,18,18, 2, 3, 5,18, 2, 4, 3, 6,18, 7, 8,-1, 5, 2 }, // 131 { 0, 1,18,17,-1, 2,18, 3, 2,18, 4, 3,18, 2, 6, 5, 8,17 }, // 132 { 0, 2,18,17, 2, 3,18, 5,-1, 6, 7, 8, 2, 3, 4, 5,18, 6 }, // 133 { 1, 2,18,-3,18, 2, 3,-2,-3, 5,18, 7, 6, 2, 4, 3, 8,-2 }, // 134 { 1, 1,17,18,18,-2, 2, 3, 5, 4, 8,18,-1, 5, 3, 6,-2, 7 }, // 135 { 1, 2,18,17, 2,-2,18, 3,-1, 4,18, 2, 7, 5, 3, 8, 6, 4 }, // 136 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 137 { 1, 1, 1, 5, 1, 3, 4, 3, 7, 5, 1, 3, 6, 1, 2, 4, 3, 8 }, // 138 { 0, 2,18,18, 3, 3,-2, 2, 5,18, 6, 3,-1, 4, 7,-1, 1, 2 }, // 139 { 0, 1,-2, 1,18, 2,-2, 5, 7,18, 3, 2, 6, 2,-1, 4,-2,17 }, // 140 { 0, 2,18,18,18, 2, 3,-2,18, 5, 4, 2, 6, 8, 3,-2, 4,18 }, // 141 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 142 { 1, 1,17,18,-1, 3, 2, 5, 1, 3, 2, 8, 4, 7, 6, 2,-1, 5 }, // 143 { 1, 1,17,18,18, 4, 2, 3, 7, 6,18, 8, 5,-1, 4, 2, 3,17 }, // 144 { 0, 1,18,18,-2,18, 2, 3, 4, 5, 6,18, 8, 2, 3, 7,-2, 4 }, // 145 { 0, 1,18,-2,18,18,-3,-2, 2, 3, 5, 8, 1, 2, 6, 4, 7,-1 }, // 146 { 0, 1,18,17, 2,18, 3,-2, 2, 7, 6, 4,18, 3, 8, 7, 4, 2 }, // 147 { 1, 1,17,18,18, 4, 2, 3, 7, 6,18, 8, 5,-1, 4, 2, 3,17 }, // 148 { 1, 1,18,17,18, 2, 5, 3,-2,18, 6, 2, 3, 4, 8, 7, 5,-1 }, // 149 { 0, 1, 2,-1,18,-1, 2, 4,-3,18, 5, 3, 6,18, 2, 4, 7, 8 }, // 150 { 1, 1,17,18, 8, 3, 6, 4,-1, 5, 2, 7, 3, 8, 6, 5,18, 4 }, // 151 { 0, 2,18, 3,-2, 7, 8, 2, 5, 4,-3, 8, 3, 2,18, 5, 4, 6 }, // 152 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 153 { 1, 1, 1,18,-1, 8, 2, 6, 3,-2, 1, 2, 5, 4,-3, 8, 6, 3 }, // 154 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 155 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 156 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 157 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 158 { 0, 1,17,18,18, 4, 2, 7, 3, 6,-2,18, 8, 4, 5, 2, 7,17 }, // 159 { 1, 2,18,-1,18, 3,-2,18, 2, 5, 3, 6, 7, 2,-1,18, 8, 4 }, // 160 { 1, 2, 1,18,-2, 4,18, 2, 3, 6,-1, 7, 5,-2,18, 8, 2, 4 }, // 161 { 1, 2, 1,18,-3, 2, 3,18,-1, 5, 6, 2, 8, 3, 4, 1,-2, 7 }, // 162 { 0, 1, 1,17,-1,18, 3, 2, 5, 4, 6, 7, 8, 3, 4, 2, 1,-2 }, // 163 { 1, 1,18,17,18, 4, 3, 5, 1, 2, 6, 3, 4, 7, 1, 8, 5, 2 }, // 164 { 0, 1,18,-2, 7, 1, 3, 2,-3, 4, 6,-2, 7, 8, 1, 5, 4, 3 }, // 165 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 166 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 167 { 0, 2,18,18,18,-2, 2, 5, 3, 7,18, 2, 4,-3, 5, 6, 3, 8 }, // 168 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 169 { 0, 3, 3,18,-1, 5, 2, 7,18, 6, 5, 2, 4, 3,-1, 7,18, 6 }, // 170 { 0, 2,18,18,18, 4, 3, 2, 6, 4, 8,18, 5, 3, 2, 7,-2, 6 }, // 171 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 172 { 0, 2,18,18,18, 2, 3,-2,18, 5, 4, 2, 6, 8, 3,-2, 4,18 }, // 173 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 174 { 1, 1,17, 8,18, 3, 2, 1, 5, 4, 6,-1, 3,-3, 8,18, 7, 2 }, // 175 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 176 { 0, 1,-1,18,18,18, 2, 4, 6,-2, 2, 8, 3, 4,18, 7,-1, 6 }, // 177 { 0, 1,18, 1,-2, 2, 4, 1, 3,-1, 2, 5, 7, 1, 6, 8,-2,17 }, // 178 { 0, 1,17,17,18, 2, 5, 4,18, 3, 8, 7, 4, 6, 8, 1, 5, 2 }, // 179 { 1, 2,18,18, 5, 4, 6, 3, 4,18, 8, 4,-1, 7, 5, 3, 6, 2 }, // 180 { 0, 1,18,18,-3,18, 3, 6, 2, 5, 7,18, 3, 8,-1, 4, 5, 2 }, // 181 { 1, 1,18, 2,-2,-3,18, 5, 2,-2, 4, 3, 6,18, 8,-1, 2, 7 }, // 182 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 183 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 184 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 185 { 1, 1,17, 1, 7, 2, 3,18,-2, 3, 6, 4, 2, 7, 8, 5, 3,17 }, // 186 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 187 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 188 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 189 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 190 { 0, 1,17,18, 3,18, 2, 5, 4, 7,-3, 6, 3, 2,18, 4, 7, 3 }, // 191 { 1, 1, 1, 7, 4, 5, 3, 4, 5, 1, 3, 6, 3, 2, 4, 8,-2, 7 }, // 192 { 0, 1, 1,18,-1,-2,18, 3, 2,-1, 6, 7, 4, 5, 3,18, 2,-3 }, // 193 { 1, 1,18,18,-1, 3, 6,18, 5, 4, 8, 2, 3, 6,18, 7, 4,-2 }, // 194 { 0, 2,18,18, 2, 6,18, 2,18, 5, 3,18, 2, 4, 7, 8, 3,18 }, // 195 { 1, 1, 3,18,18, 5,18, 6, 2, 4, 7,-2,18, 5, 8, 6, 3, 2 }, // 196 { 0, 1,18,-2, 7, 1, 3, 2,-3, 4, 6,-2, 7, 8, 1, 5, 4, 3 }, // 197 { 1, 1,18,-2,18, 2, 5,18, 3,-2, 4, 7, 2,-1, 8, 6, 5, 1 }, // 198 { 1, 1,17,17, 5,18, 4, 1, 2, 8, 6, 4,-2, 3, 5,-1, 1, 8 }, // 199 { 0, 2, 1, 2,17, 3, 7,18, 2,-1, 4, 5,18, 2, 7, 3, 6, 8 }, // 200 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 201 { 1, 1, 3, 6,17, 8, 7, 5,18,-1, 1, 2, 3, 4, 2, 6, 8, 1 }, // 202 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 203 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 204 { 0, 2,18,18,18, 2,-2, 3, 6, 4, 8,18, 2, 5, 7, 4, 3, 6 }, // 205 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 206 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 207 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 208 { 1, 1,18, 1, 8, 3, 5, 6, 4,-1, 8, 3, 7,18, 2, 5, 8, 4 }, // 209 { 1, 1,17,18, 5, 2, 4, 3, 1, 6,-2, 1, 3, 2, 4, 5,-1,17 }, // 210 { 1, 1,18,17, 2,18, 3,-3, 7, 2, 6, 4, 3, 5,18, 8, 2,-2 }, // 211 { 1, 1,18,17,18, 4, 3, 5,-1,18, 2, 7, 8, 4, 6, 3,18, 5 }, // 212 { 0, 1,18,17,18,-2, 2,-3, 3, 4, 8, 5, 2,18, 6, 3, 7,-2 }, // 213 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 214 { 1, 1,17,18, 8, 3, 4, 6,18, 5,-2, 3, 8, 5, 2, 4, 7, 6 }, // 215 { 0, 1,18,-2, 3, 5, 1, 7, 3, 2, 6,-3, 4, 1, 5, 8, 3,-2 }, // 216 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 217 { 1, 1, 3,17,18, 5,-1,18, 2, 6, 7,18, 5, 3,-3,-1, 6, 2 }, // 218 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 219 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 220 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 221 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 222 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 223 { 1, 3,18,17,-2, 3,-1,18, 2, 5, 3, 7, 6, 2, 4, 8,18, 5 }, // 224 { 0, 1,18,-1,18, 2,18, 3, 5,18, 2, 8,18, 5, 4,-1, 6, 2 }, // 225 { 1, 2,18,-2,18,18, 2, 3, 4,-3, 2, 5,18, 7, 4, 3, 8, 6 }, // 226 { 0, 2,17,-1,18, 2,-1, 1, 7, 3, 8, 5,-2, 4, 1, 2,-3, 6 }, // 227 { 0, 1,18,17, 2,18, 2,18, 6, 7, 4, 3,18, 5, 2,-2,17, 8 }, // 228 { 0, 3,18,17, 2, 3,-3,-1,18, 2, 4, 5,18, 7, 3, 2,-3, 6 }, // 229 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 230 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 231 { 0, 2, 3,18,18,18, 2, 6, 5,18, 7, 2, 4, 6,18, 5, 3, 8 }, // 232 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 233 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 234 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 235 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 236 { 0, 1,18,18, 3, 6, 3,-2, 2,18, 5,-1, 7, 3, 4,-2, 2, 6 }, // 237 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 238 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 239 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 240 { 1, 1,18,17,18,18,-2, 2, 3,-3,18, 6, 4, 2,-2, 8, 3, 7 }, // 241 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 242 { 0, 1,18,18,18, 4, 2, 7, 8,18, 3, 2,-2, 4, 7, 6,17, 5 }, // 243 { 1, 1,18,18,-1,-2, 8, 3,18, 6, 3, 5, 8, 2, 4, 7, 1, 6 }, // 244 { 1, 1, 1,-3, 3,18,18, 2,-1, 3, 6, 5,18, 4, 7,-2, 8, 3 }, // 245 { 1, 1, 1,18, 4, 2, 5,18, 1, 3,-1, 6, 1, 4, 8, 2, 5, 1 }, // 246 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 247 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 248 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 249 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 250 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 251 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 252 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 253 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 254 { 0, 1,-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1 }, // 255 }; #define NUM_FAST_SPECS (sizeof (fast_specs) / sizeof (fast_specs [0])) #define NUM_DEFAULT_SPECS (sizeof (default_specs) / sizeof (default_specs [0])) #define NUM_HIGH_SPECS (sizeof (high_specs) / sizeof (high_specs [0])) #define NUM_VERY_HIGH_SPECS (sizeof (very_high_specs) / sizeof (very_high_specs [0])) ///////////////////////////// executable code //////////////////////////////// // This function initializes everything required to pack WavPack bitstreams // and must be called BEFORE any other function in this module. void pack_init (WavpackContext *wpc) { WavpackStream *wps = wpc->streams [wpc->current_stream]; wps->sample_index = 0; wps->delta_decay = 2.0; CLEAR (wps->decorr_passes); CLEAR (wps->dc); /* although we set the term and delta values here for clarity, they're * actually hardcoded in the analysis function for speed */ CLEAR (wps->analysis_pass); wps->analysis_pass.term = 18; wps->analysis_pass.delta = 2; if (wpc->config.flags & CONFIG_AUTO_SHAPING) { if (wpc->config.flags & CONFIG_OPTIMIZE_WVC) wps->dc.shaping_acc [0] = wps->dc.shaping_acc [1] = -512L << 16; else if (wpc->config.sample_rate >= 64000) wps->dc.shaping_acc [0] = wps->dc.shaping_acc [1] = 1024L << 16; else wpc->config.flags |= CONFIG_DYNAMIC_SHAPING; } else { int32_t weight = (int32_t) floor (wpc->config.shaping_weight * 1024.0 + 0.5); if (weight <= -1000) weight = -1000; wps->dc.shaping_acc [0] = wps->dc.shaping_acc [1] = weight << 16; } if (wpc->config.flags & CONFIG_DYNAMIC_SHAPING) wps->dc.shaping_data = malloc (wpc->max_samples * sizeof (*wps->dc.shaping_data)); if (!wpc->config.xmode) wps->num_passes = 0; else if (wpc->config.xmode == 1) wps->num_passes = 2; else if (wpc->config.xmode == 2) wps->num_passes = 4; else wps->num_passes = 9; if (wpc->config.flags & CONFIG_VERY_HIGH_FLAG) { wps->num_decorrs = NUM_VERY_HIGH_SPECS; wps->decorr_specs = very_high_specs; } else if (wpc->config.flags & CONFIG_HIGH_FLAG) { wps->num_decorrs = NUM_HIGH_SPECS; wps->decorr_specs = high_specs; } else if (wpc->config.flags & CONFIG_FAST_FLAG) { wps->num_decorrs = NUM_FAST_SPECS; wps->decorr_specs = fast_specs; } else { wps->num_decorrs = NUM_DEFAULT_SPECS; wps->decorr_specs = default_specs; } init_words (wps); } // Allocate room for and copy the decorrelation terms from the decorr_passes // array into the specified metadata structure. Both the actual term id and // the delta are packed into single characters. void write_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd) { int tcount = wps->num_terms; struct decorr_pass *dpp; char *byteptr; byteptr = wpmd->data = malloc (tcount + 1); wpmd->id = ID_DECORR_TERMS; for (dpp = wps->decorr_passes; tcount--; ++dpp) *byteptr++ = ((dpp->term + 5) & 0x1f) | ((dpp->delta << 5) & 0xe0); wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); } // Allocate room for and copy the decorrelation term weights from the // decorr_passes array into the specified metadata structure. The weights // range +/-1024, but are rounded and truncated to fit in signed chars for // metadata storage. Weights are separate for the two channels void write_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd) { struct decorr_pass *dpp = wps->decorr_passes; int tcount = wps->num_terms, i; char *byteptr; byteptr = wpmd->data = malloc ((tcount * 2) + 1); wpmd->id = ID_DECORR_WEIGHTS; for (i = wps->num_terms - 1; i >= 0; --i) if (store_weight (dpp [i].weight_A) || (!(wps->wphdr.flags & MONO_DATA) && store_weight (dpp [i].weight_B))) break; tcount = i + 1; for (i = 0; i < wps->num_terms; ++i) { if (i < tcount) { dpp [i].weight_A = restore_weight (*byteptr++ = store_weight (dpp [i].weight_A)); if (!(wps->wphdr.flags & MONO_DATA)) dpp [i].weight_B = restore_weight (*byteptr++ = store_weight (dpp [i].weight_B)); } else dpp [i].weight_A = dpp [i].weight_B = 0; } wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); } // Allocate room for and copy the decorrelation samples from the decorr_passes // array into the specified metadata structure. The samples are signed 32-bit // values, but are converted to signed log2 values for storage in metadata. // Values are stored for both channels and are specified from the first term // with unspecified samples set to zero. The number of samples stored varies // with the actual term value, so those must obviously be specified before // these in the metadata list. Any number of terms can have their samples // specified from no terms to all the terms, however I have found that // sending more than the first term's samples is a waste. The "wcount" // variable can be set to the number of terms to have their samples stored. void write_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd) { int tcount = wps->num_terms, wcount = 1, temp; struct decorr_pass *dpp; unsigned char *byteptr; byteptr = wpmd->data = malloc (256); wpmd->id = ID_DECORR_SAMPLES; for (dpp = wps->decorr_passes; tcount--; ++dpp) if (wcount) { if (dpp->term > MAX_TERM) { dpp->samples_A [0] = exp2s (temp = log2s (dpp->samples_A [0])); *byteptr++ = temp; *byteptr++ = temp >> 8; dpp->samples_A [1] = exp2s (temp = log2s (dpp->samples_A [1])); *byteptr++ = temp; *byteptr++ = temp >> 8; if (!(wps->wphdr.flags & MONO_DATA)) { dpp->samples_B [0] = exp2s (temp = log2s (dpp->samples_B [0])); *byteptr++ = temp; *byteptr++ = temp >> 8; dpp->samples_B [1] = exp2s (temp = log2s (dpp->samples_B [1])); *byteptr++ = temp; *byteptr++ = temp >> 8; } } else if (dpp->term < 0) { dpp->samples_A [0] = exp2s (temp = log2s (dpp->samples_A [0])); *byteptr++ = temp; *byteptr++ = temp >> 8; dpp->samples_B [0] = exp2s (temp = log2s (dpp->samples_B [0])); *byteptr++ = temp; *byteptr++ = temp >> 8; } else { int m = 0, cnt = dpp->term; while (cnt--) { dpp->samples_A [m] = exp2s (temp = log2s (dpp->samples_A [m])); *byteptr++ = temp; *byteptr++ = temp >> 8; if (!(wps->wphdr.flags & MONO_DATA)) { dpp->samples_B [m] = exp2s (temp = log2s (dpp->samples_B [m])); *byteptr++ = temp; *byteptr++ = temp >> 8; } m++; } } wcount--; } else { CLEAR (dpp->samples_A); CLEAR (dpp->samples_B); } wpmd->byte_length = (int32_t)(byteptr - (unsigned char *) wpmd->data); } // Allocate room for and copy the noise shaping info into the specified // metadata structure. These would normally be written to the // "correction" file and are used for lossless reconstruction of // hybrid data. The "delta" parameter is not yet used in encoding as it // will be part of the "quality" mode. void write_shaping_info (WavpackStream *wps, WavpackMetadata *wpmd) { char *byteptr; int temp; byteptr = wpmd->data = malloc (12); wpmd->id = ID_SHAPING_WEIGHTS; wps->dc.error [0] = exp2s (temp = log2s (wps->dc.error [0])); *byteptr++ = temp; *byteptr++ = temp >> 8; wps->dc.shaping_acc [0] = exp2s (temp = log2s (wps->dc.shaping_acc [0])); *byteptr++ = temp; *byteptr++ = temp >> 8; if (!(wps->wphdr.flags & MONO_DATA)) { wps->dc.error [1] = exp2s (temp = log2s (wps->dc.error [1])); *byteptr++ = temp; *byteptr++ = temp >> 8; wps->dc.shaping_acc [1] = exp2s (temp = log2s (wps->dc.shaping_acc [1])); *byteptr++ = temp; *byteptr++ = temp >> 8; } if (wps->dc.shaping_delta [0] | wps->dc.shaping_delta [1]) { wps->dc.shaping_delta [0] = exp2s (temp = log2s (wps->dc.shaping_delta [0])); *byteptr++ = temp; *byteptr++ = temp >> 8; if (!(wps->wphdr.flags & MONO_DATA)) { wps->dc.shaping_delta [1] = exp2s (temp = log2s (wps->dc.shaping_delta [1])); *byteptr++ = temp; *byteptr++ = temp >> 8; } } wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); } // Allocate room for and copy the int32 data values into the specified // metadata structure. This data is used for integer data that has more // than 24 bits of magnitude or, in some cases, it's used to eliminate // redundant bits from any audio stream. void write_int32_info (WavpackStream *wps, WavpackMetadata *wpmd) { char *byteptr; byteptr = wpmd->data = malloc (4); wpmd->id = ID_INT32_INFO; *byteptr++ = wps->int32_sent_bits; *byteptr++ = wps->int32_zeros; *byteptr++ = wps->int32_ones; *byteptr++ = wps->int32_dups; wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); } // Allocate room for and copy the multichannel information into the specified // metadata structure. The first byte is the total number of channels and the // following bytes represent the channel_mask as described for Microsoft // WAVEFORMATEX. void write_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd) { uint32_t mask = wpc->config.channel_mask; char *byteptr; if (wpc->num_streams > OLD_MAX_STREAMS) { byteptr = wpmd->data = malloc (6); wpmd->id = ID_CHANNEL_INFO; *byteptr++ = wpc->config.num_channels - 1; *byteptr++ = wpc->num_streams - 1; *byteptr++ = (((wpc->num_streams - 1) >> 4) & 0xf0) | (((wpc->config.num_channels - 1) >> 8) & 0xf); *byteptr++ = mask; *byteptr++ = (mask >> 8); *byteptr++ = (mask >> 16); } else { byteptr = wpmd->data = malloc (4); wpmd->id = ID_CHANNEL_INFO; *byteptr++ = wpc->config.num_channels; while (mask) { *byteptr++ = mask; mask >>= 8; } } wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); } // Allocate room for and copy the configuration information into the specified // metadata structure. Currently, we just store the upper 3 bytes of // config.flags and only in the first block of audio data. Note that this is // for informational purposes not required for playback or decoding (like // whether high or fast mode was specified). void write_config_info (WavpackContext *wpc, WavpackMetadata *wpmd) { char *byteptr; byteptr = wpmd->data = malloc (4); wpmd->id = ID_CONFIG_BLOCK; *byteptr++ = (char) (wpc->config.flags >> 8); *byteptr++ = (char) (wpc->config.flags >> 16); *byteptr++ = (char) (wpc->config.flags >> 24); if (wpc->config.flags & CONFIG_EXTRA_MODE) *byteptr++ = (char) wpc->config.xmode; wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); } // Allocate room for and copy the non-standard sampling rateinto the specified // metadata structure. We just store the lower 3 bytes of the sampling rate. // Note that this would only be used when the sampling rate was not included // in the table of 15 "standard" values. void write_sample_rate (WavpackContext *wpc, WavpackMetadata *wpmd) { char *byteptr; byteptr = wpmd->data = malloc (4); wpmd->id = ID_SAMPLE_RATE; *byteptr++ = (char) (wpc->config.sample_rate); *byteptr++ = (char) (wpc->config.sample_rate >> 8); *byteptr++ = (char) (wpc->config.sample_rate >> 16); wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); } // Pack an entire block of samples (either mono or stereo) into a completed // WavPack block. This function is actually a shell for pack_samples() and // performs tasks like handling any shift required by the format, preprocessing // of floating point data or integer data over 24 bits wide, and implementing // the "extra" mode (via the extra?.c modules). It is assumed that there is // sufficient space for the completed block at "wps->blockbuff" and that // "wps->blockend" points to the end of the available space. A return value of // FALSE indicates an error. static void best_floating_line (short *values, int num_values, double *initial_y, double *final_y, short *max_error); static void dynamic_noise_shaping (WavpackContext *wpc, int32_t *buffer, int shortening_allowed); static int scan_int32_data (WavpackStream *wps, int32_t *values, int32_t num_values); static void scan_int32_quick (WavpackStream *wps, int32_t *values, int32_t num_values); static void send_int32_data (WavpackStream *wps, int32_t *values, int32_t num_values); static int scan_redundancy (int32_t *values, int32_t num_values); static int pack_samples (WavpackContext *wpc, int32_t *buffer); int pack_block (WavpackContext *wpc, int32_t *buffer) { WavpackStream *wps = wpc->streams [wpc->current_stream]; uint32_t flags = wps->wphdr.flags, sflags = wps->wphdr.flags; int32_t sample_count = wps->wphdr.block_samples, *orig_data = NULL; int dynamic_shaping_done = FALSE; if (!wpc->current_stream && !(flags & FLOAT_DATA) && (flags & MAG_MASK) >> MAG_LSB < 24) { if ((wpc->config.flags & CONFIG_DYNAMIC_SHAPING) && !wpc->config.block_samples) { dynamic_noise_shaping (wpc, buffer, TRUE); sample_count = wps->wphdr.block_samples; dynamic_shaping_done = TRUE; } else if (wpc->block_boundary && sample_count >= (int32_t) wpc->block_boundary * 2) { int bc = sample_count / wpc->block_boundary, chans = (flags & MONO_DATA) ? 1 : 2; int res = scan_redundancy (buffer, wpc->block_boundary * chans), i; for (i = 1; i < bc; ++i) if (res != scan_redundancy (buffer + (i * wpc->block_boundary * chans), wpc->block_boundary * chans)) { sample_count = wps->wphdr.block_samples = wpc->block_boundary * i; break; } } } if (!(flags & MONO_FLAG) && wpc->stream_version >= 0x410) { int32_t lor = 0, diff = 0; int32_t *sptr, *dptr, i; for (sptr = buffer, i = 0; i < (int32_t) sample_count; sptr += 2, i++) { lor |= sptr [0] | sptr [1]; diff |= sptr [0] - sptr [1]; if (lor && diff) break; } if (i == sample_count && lor && !diff) { flags &= ~(JOINT_STEREO | CROSS_DECORR | HYBRID_BALANCE); wps->wphdr.flags = flags |= FALSE_STEREO; dptr = buffer; sptr = buffer; for (i = sample_count; i--; sptr++) *dptr++ = *sptr++; if (!wps->false_stereo) { wps->false_stereo = 1; wps->num_terms = 0; init_words (wps); } } else if (wps->false_stereo) { wps->false_stereo = 0; wps->num_terms = 0; init_words (wps); } } if (flags & SHIFT_MASK) { int shift = (flags & SHIFT_MASK) >> SHIFT_LSB; int mag = (flags & MAG_MASK) >> MAG_LSB; uint32_t cnt = sample_count; int32_t *ptr = buffer; if (flags & MONO_DATA) while (cnt--) *ptr++ >>= shift; else while (cnt--) { *ptr++ >>= shift; *ptr++ >>= shift; } if ((mag -= shift) < 0) flags &= ~MAG_MASK; else flags -= (1 << MAG_LSB) * shift; wps->wphdr.flags = flags; } if ((flags & FLOAT_DATA) || (flags & MAG_MASK) >> MAG_LSB >= 24) { if ((!(flags & HYBRID_FLAG) || wpc->wvc_flag) && !(wpc->config.flags & CONFIG_SKIP_WVX)) { orig_data = malloc (sizeof (f32) * ((flags & MONO_DATA) ? sample_count : sample_count * 2)); memcpy (orig_data, buffer, sizeof (f32) * ((flags & MONO_DATA) ? sample_count : sample_count * 2)); if (flags & FLOAT_DATA) { wps->float_norm_exp = wpc->config.float_norm_exp; if (!scan_float_data (wps, (f32 *) buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2)) { free (orig_data); orig_data = NULL; } } else { if (!scan_int32_data (wps, buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2)) { free (orig_data); orig_data = NULL; } } } else { if (flags & FLOAT_DATA) { wps->float_norm_exp = wpc->config.float_norm_exp; if (scan_float_data (wps, (f32 *) buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2)) wpc->lossy_blocks = TRUE; } else if (scan_int32_data (wps, buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2)) wpc->lossy_blocks = TRUE; } wps->num_terms = 0; } else { scan_int32_quick (wps, buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2); if (wps->shift != wps->int32_zeros + wps->int32_ones + wps->int32_dups) { wps->shift = wps->int32_zeros + wps->int32_ones + wps->int32_dups; wps->num_terms = 0; } } if ((wpc->config.flags & CONFIG_DYNAMIC_SHAPING) && !dynamic_shaping_done) dynamic_noise_shaping (wpc, buffer, FALSE); if (!wps->num_passes && !wps->num_terms) { wps->num_passes = 1; if (flags & MONO_DATA) execute_mono (wpc, buffer, 1, 0); else execute_stereo (wpc, buffer, 1, 0); wps->num_passes = 0; } if (!pack_samples (wpc, buffer)) { wps->wphdr.flags = sflags; if (orig_data) free (orig_data); return FALSE; } else wps->wphdr.flags = sflags; if (wps->dc.shaping_data) { if (wps->dc.shaping_samples != sample_count) memmove (wps->dc.shaping_data, wps->dc.shaping_data + sample_count, (wps->dc.shaping_samples - sample_count) * sizeof (*wps->dc.shaping_data)); wps->dc.shaping_samples -= sample_count; } if (orig_data) { uint32_t data_count; unsigned char *cptr; if (wpc->wvc_flag) cptr = wps->block2buff + ((WavpackHeader *) wps->block2buff)->ckSize + 8; else cptr = wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 8; bs_open_write (&wps->wvxbits, cptr + 8, wpc->wvc_flag ? wps->block2end : wps->blockend); if (flags & FLOAT_DATA) send_float_data (wps, (f32*) orig_data, (flags & MONO_DATA) ? sample_count : sample_count * 2); else send_int32_data (wps, orig_data, (flags & MONO_DATA) ? sample_count : sample_count * 2); data_count = bs_close_write (&wps->wvxbits); free (orig_data); if (data_count) { if (data_count != (uint32_t) -1) { *cptr++ = ID_WVX_BITSTREAM | ID_LARGE; *cptr++ = (data_count += 4) >> 1; *cptr++ = data_count >> 9; *cptr++ = data_count >> 17; *cptr++ = wps->crc_x; *cptr++ = wps->crc_x >> 8; *cptr++ = wps->crc_x >> 16; *cptr = wps->crc_x >> 24; if (wpc->wvc_flag) ((WavpackHeader *) wps->block2buff)->ckSize += data_count + 4; else ((WavpackHeader *) wps->blockbuff)->ckSize += data_count + 4; } else return FALSE; } } return TRUE; } static void dynamic_noise_shaping (WavpackContext *wpc, int32_t *buffer, int shortening_allowed) { WavpackStream *wps = wpc->streams [wpc->current_stream]; int32_t sample_count = wps->wphdr.block_samples; struct decorr_pass *ap = &wps->analysis_pass; uint32_t flags = wps->wphdr.flags; int32_t *bptr, temp, sam; short *swptr; int sc; if (!wps->num_terms && sample_count > 8) { if (flags & MONO_DATA) for (bptr = buffer + sample_count - 3, sc = sample_count - 2; sc--;) { sam = (3 * bptr [1] - bptr [2]) >> 1; temp = *bptr-- - apply_weight (ap->weight_A, sam); update_weight (ap->weight_A, 2, sam, temp); } else for (bptr = buffer + (sample_count - 3) * 2 + 1, sc = sample_count - 2; sc--;) { sam = (3 * bptr [2] - bptr [4]) >> 1; temp = *bptr-- - apply_weight (ap->weight_B, sam); update_weight (ap->weight_B, 2, sam, temp); sam = (3 * bptr [2] - bptr [4]) >> 1; temp = *bptr-- - apply_weight (ap->weight_A, sam); update_weight (ap->weight_A, 2, sam, temp); } } if (sample_count > wps->dc.shaping_samples) { sc = sample_count - wps->dc.shaping_samples; swptr = wps->dc.shaping_data + wps->dc.shaping_samples; bptr = buffer + wps->dc.shaping_samples * ((flags & MONO_DATA) ? 1 : 2); if (flags & MONO_DATA) while (sc--) { sam = (3 * ap->samples_A [0] - ap->samples_A [1]) >> 1; temp = *bptr - apply_weight (ap->weight_A, sam); update_weight (ap->weight_A, 2, sam, temp); ap->samples_A [1] = ap->samples_A [0]; ap->samples_A [0] = *bptr++; *swptr++ = (ap->weight_A < 256) ? 1024 : 1536 - ap->weight_A * 2; } else while (sc--) { sam = (3 * ap->samples_A [0] - ap->samples_A [1]) >> 1; temp = *bptr - apply_weight (ap->weight_A, sam); update_weight (ap->weight_A, 2, sam, temp); ap->samples_A [1] = ap->samples_A [0]; ap->samples_A [0] = *bptr++; sam = (3 * ap->samples_B [0] - ap->samples_B [1]) >> 1; temp = *bptr - apply_weight (ap->weight_B, sam); update_weight (ap->weight_B, 2, sam, temp); ap->samples_B [1] = ap->samples_B [0]; ap->samples_B [0] = *bptr++; *swptr++ = (ap->weight_A + ap->weight_B < 512) ? 1024 : 1536 - ap->weight_A - ap->weight_B; } wps->dc.shaping_samples = sample_count; } if (wpc->wvc_flag) { int max_allowed_error = 1000000 / wpc->ave_block_samples; short max_error, trial_max_error; double initial_y, final_y; if (max_allowed_error < 128) max_allowed_error = 128; best_floating_line (wps->dc.shaping_data, sample_count, &initial_y, &final_y, &max_error); if (shortening_allowed && max_error > max_allowed_error) { int min_samples = 0, max_samples = sample_count, trial_count; double trial_initial_y, trial_final_y; while (1) { trial_count = (min_samples + max_samples) / 2; best_floating_line (wps->dc.shaping_data, trial_count, &trial_initial_y, &trial_final_y, &trial_max_error); if (trial_max_error < max_allowed_error) { max_error = trial_max_error; min_samples = trial_count; initial_y = trial_initial_y; final_y = trial_final_y; } else max_samples = trial_count; if (min_samples > 10000 || max_samples - min_samples < 2) break; } sample_count = min_samples; } if (initial_y < -512) initial_y = -512; else if (initial_y > 1024) initial_y = 1024; if (final_y < -512) final_y = -512; else if (final_y > 1024) final_y = 1024; #if 0 error_line ("%.2f sec, sample count = %5d, max error = %3d, range = %5d, %5d, actual = %5d, %5d", (double) wps->sample_index / wpc->config.sample_rate, sample_count, max_error, (int) floor (initial_y), (int) floor (final_y), wps->dc.shaping_data [0], wps->dc.shaping_data [sample_count-1]); #endif if (sample_count != wps->wphdr.block_samples) wps->wphdr.block_samples = sample_count; if (wpc->wvc_flag) { wps->dc.shaping_acc [0] = wps->dc.shaping_acc [1] = (int32_t) floor (initial_y * 65536.0 + 0.5); wps->dc.shaping_delta [0] = wps->dc.shaping_delta [1] = (int32_t) floor ((final_y - initial_y) / (sample_count - 1) * 65536.0 + 0.5); wps->dc.shaping_array = NULL; } else wps->dc.shaping_array = wps->dc.shaping_data; } else wps->dc.shaping_array = wps->dc.shaping_data; } // Quickly scan a buffer of long integer data and determine whether any // redundancy in the LSBs can be used to reduce the data's magnitude. If yes, // then the INT32_DATA flag is set and the int32 parameters are set. This // version is designed to terminate as soon as it figures out that no // redundancy is available so that it can be used for all files. static void scan_int32_quick (WavpackStream *wps, int32_t *values, int32_t num_values) { uint32_t magdata = 0, ordata = 0, xordata = 0, anddata = ~0; int total_shift = 0; int32_t *dp, count; wps->int32_sent_bits = wps->int32_zeros = wps->int32_ones = wps->int32_dups = 0; for (dp = values, count = num_values; count--; dp++) { magdata |= (*dp < 0) ? ~*dp : *dp; xordata |= *dp ^ -(*dp & 1); anddata &= *dp; ordata |= *dp; if ((ordata & 1) && !(anddata & 1) && (xordata & 2)) return; } wps->wphdr.flags &= ~MAG_MASK; while (magdata) { wps->wphdr.flags += 1 << MAG_LSB; magdata >>= 1; } if (!(wps->wphdr.flags & MAG_MASK)) return; if (!(ordata & 1)) while (!(ordata & 1)) { wps->wphdr.flags -= 1 << MAG_LSB; wps->int32_zeros++; total_shift++; ordata >>= 1; } else if (anddata & 1) while (anddata & 1) { wps->wphdr.flags -= 1 << MAG_LSB; wps->int32_ones++; total_shift++; anddata >>= 1; } else if (!(xordata & 2)) while (!(xordata & 2)) { wps->wphdr.flags -= 1 << MAG_LSB; wps->int32_dups++; total_shift++; xordata >>= 1; } if (total_shift) { wps->wphdr.flags |= INT32_DATA; for (dp = values, count = num_values; count--; dp++) *dp >>= total_shift; } } static int scan_redundancy (int32_t *values, int32_t num_values) { uint32_t ordata = 0, xordata = 0, anddata = ~0; int redundant_bits = 0; int32_t *dp, count; for (dp = values, count = num_values; count--; dp++) { xordata |= *dp ^ -(*dp & 1); anddata &= *dp; ordata |= *dp; if ((ordata & 1) && !(anddata & 1) && (xordata & 2)) return 0; } if (!ordata || anddata == ~0 || !xordata) return 0; if (!(ordata & 1)) while (!(ordata & 1)) { redundant_bits++; ordata >>= 1; } else if (anddata & 1) while (anddata & 1) { redundant_bits = (redundant_bits + 1) | 0x40; anddata >>= 1; } else if (!(xordata & 2)) while (!(xordata & 2)) { redundant_bits = (redundant_bits + 1) | 0x80; redundant_bits++; xordata >>= 1; } return redundant_bits; } // Scan a buffer of long integer data and determine whether any redundancy in // the LSBs can be used to reduce the data's magnitude. If yes, then the // INT32_DATA flag is set and the int32 parameters are set. If bits must still // be transmitted literally to get down to 24 bits (which is all the integer // compression code can handle) then we return TRUE to indicate that a wvx // stream must be created in either lossless mode. static int scan_int32_data (WavpackStream *wps, int32_t *values, int32_t num_values) { uint32_t magdata = 0, ordata = 0, xordata = 0, anddata = ~0; uint32_t crc = 0xffffffff; int total_shift = 0; int32_t *dp, count; wps->int32_sent_bits = wps->int32_zeros = wps->int32_ones = wps->int32_dups = 0; for (dp = values, count = num_values; count--; dp++) { crc = crc * 9 + (*dp & 0xffff) * 3 + ((*dp >> 16) & 0xffff); magdata |= (*dp < 0) ? ~*dp : *dp; xordata |= *dp ^ -(*dp & 1); anddata &= *dp; ordata |= *dp; } wps->crc_x = crc; wps->wphdr.flags &= ~MAG_MASK; while (magdata) { wps->wphdr.flags += 1 << MAG_LSB; magdata >>= 1; } if (!((wps->wphdr.flags & MAG_MASK) >> MAG_LSB)) { wps->wphdr.flags &= ~INT32_DATA; return FALSE; } if (!(ordata & 1)) while (!(ordata & 1)) { wps->wphdr.flags -= 1 << MAG_LSB; wps->int32_zeros++; total_shift++; ordata >>= 1; } else if (anddata & 1) while (anddata & 1) { wps->wphdr.flags -= 1 << MAG_LSB; wps->int32_ones++; total_shift++; anddata >>= 1; } else if (!(xordata & 2)) while (!(xordata & 2)) { wps->wphdr.flags -= 1 << MAG_LSB; wps->int32_dups++; total_shift++; xordata >>= 1; } if (((wps->wphdr.flags & MAG_MASK) >> MAG_LSB) > 23) { wps->int32_sent_bits = (unsigned char)(((wps->wphdr.flags & MAG_MASK) >> MAG_LSB) - 23); total_shift += wps->int32_sent_bits; wps->wphdr.flags &= ~MAG_MASK; wps->wphdr.flags += 23 << MAG_LSB; } if (total_shift) { wps->wphdr.flags |= INT32_DATA; for (dp = values, count = num_values; count--; dp++) *dp >>= total_shift; } return wps->int32_sent_bits; } // For the specified buffer values and the int32 parameters stored in "wps", // send the literal bits required to the "wvxbits" bitstream. static void send_int32_data (WavpackStream *wps, int32_t *values, int32_t num_values) { int sent_bits = wps->int32_sent_bits, pre_shift; int32_t mask = (1 << sent_bits) - 1; int32_t count, value, *dp; pre_shift = wps->int32_zeros + wps->int32_ones + wps->int32_dups; if (sent_bits) for (dp = values, count = num_values; count--; dp++) { value = (*dp >> pre_shift) & mask; putbits (value, sent_bits, &wps->wvxbits); } } // Pack an entire block of samples (either mono or stereo) into a completed // WavPack block. It is assumed that there is sufficient space for the // completed block at "wps->blockbuff" and that "wps->blockend" points to the // end of the available space. A return value of FALSE indicates an error. // Any unsent metadata is transmitted first, then required metadata for this // block is sent, and finally the compressed integer data is sent. If a "wpx" // stream is required for floating point data or large integer data, then this // must be handled outside this function. To find out how much data was written // the caller must look at the ckSize field of the written WavpackHeader, NOT // the one in the WavpackStream. static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count); static void decorr_stereo_pass_id2 (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count); static int pack_samples (WavpackContext *wpc, int32_t *buffer) { WavpackStream *wps = wpc->streams [wpc->current_stream]; uint32_t flags = wps->wphdr.flags, data_count, crc, crc2, i; uint32_t sample_count = wps->wphdr.block_samples; short *shaping_array = wps->dc.shaping_array; int tcount, lossy = FALSE, m = 0; double noise_acc = 0.0, noise; struct decorr_pass *dpp; WavpackMetadata wpmd; int32_t *bptr; crc = crc2 = 0xffffffff; if (!(flags & HYBRID_FLAG) && (flags & MONO_DATA)) { int32_t *eptr = buffer + sample_count; for (bptr = buffer; bptr < eptr;) crc += (crc << 1) + *bptr++; if (wps->num_passes) execute_mono (wpc, buffer, !wps->num_terms, 1); } else if (!(flags & HYBRID_FLAG) && !(flags & MONO_DATA)) { int32_t *eptr = buffer + (sample_count * 2); for (bptr = buffer; bptr < eptr; bptr += 2) crc += (crc << 3) + (bptr [0] << 1) + bptr [0] + bptr [1]; if (wps->num_passes) { execute_stereo (wpc, buffer, !wps->num_terms, 1); flags = wps->wphdr.flags; } } else if ((flags & HYBRID_FLAG) && (flags & MONO_DATA)) { if (wps->num_passes) execute_mono (wpc, buffer, !wps->num_terms, 0); } else if ((flags & HYBRID_FLAG) && !(flags & MONO_DATA)) { if (wps->num_passes) { execute_stereo (wpc, buffer, !wps->num_terms, 0); flags = wps->wphdr.flags; } } wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; memcpy (wps->blockbuff, &wps->wphdr, sizeof (WavpackHeader)); if (wpc->metacount) { WavpackMetadata *wpmdp = wpc->metadata; while (wpc->metacount) { copy_metadata (wpmdp, wps->blockbuff, wps->blockend); wpc->metabytes -= wpmdp->byte_length; free_metadata (wpmdp++); wpc->metacount--; } free (wpc->metadata); wpc->metadata = NULL; } if (!sample_count) return TRUE; write_decorr_terms (wps, &wpmd); copy_metadata (&wpmd, wps->blockbuff, wps->blockend); free_metadata (&wpmd); write_decorr_weights (wps, &wpmd); copy_metadata (&wpmd, wps->blockbuff, wps->blockend); free_metadata (&wpmd); write_decorr_samples (wps, &wpmd); copy_metadata (&wpmd, wps->blockbuff, wps->blockend); free_metadata (&wpmd); write_entropy_vars (wps, &wpmd); copy_metadata (&wpmd, wps->blockbuff, wps->blockend); free_metadata (&wpmd); if ((flags & SRATE_MASK) == SRATE_MASK && wpc->config.sample_rate != 44100) { write_sample_rate (wpc, &wpmd); copy_metadata (&wpmd, wps->blockbuff, wps->blockend); free_metadata (&wpmd); } if (flags & HYBRID_FLAG) { write_hybrid_profile (wps, &wpmd); copy_metadata (&wpmd, wps->blockbuff, wps->blockend); free_metadata (&wpmd); } if (flags & FLOAT_DATA) { write_float_info (wps, &wpmd); copy_metadata (&wpmd, wps->blockbuff, wps->blockend); free_metadata (&wpmd); } if (flags & INT32_DATA) { write_int32_info (wps, &wpmd); copy_metadata (&wpmd, wps->blockbuff, wps->blockend); free_metadata (&wpmd); } if ((flags & INITIAL_BLOCK) && (wpc->config.num_channels > 2 || wpc->config.channel_mask != 0x5 - wpc->config.num_channels)) { write_channel_info (wpc, &wpmd); copy_metadata (&wpmd, wps->blockbuff, wps->blockend); free_metadata (&wpmd); } if ((flags & INITIAL_BLOCK) && !wps->sample_index) { write_config_info (wpc, &wpmd); copy_metadata (&wpmd, wps->blockbuff, wps->blockend); free_metadata (&wpmd); } bs_open_write (&wps->wvbits, wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 12, wps->blockend); if (wpc->wvc_flag) { wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; memcpy (wps->block2buff, &wps->wphdr, sizeof (WavpackHeader)); if (flags & HYBRID_SHAPE) { write_shaping_info (wps, &wpmd); copy_metadata (&wpmd, wps->block2buff, wps->block2end); free_metadata (&wpmd); } bs_open_write (&wps->wvcbits, wps->block2buff + ((WavpackHeader *) wps->block2buff)->ckSize + 12, wps->block2end); } /////////////////////// handle lossless mono mode ///////////////////////// if (!(flags & HYBRID_FLAG) && (flags & MONO_DATA)) { if (!wps->num_passes) for (bptr = buffer, i = 0; i < sample_count; ++i) { int32_t code = *bptr; for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { int32_t sam; if (dpp->term > MAX_TERM) { if (dpp->term & 1) sam = 2 * dpp->samples_A [0] - dpp->samples_A [1]; else sam = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; dpp->samples_A [1] = dpp->samples_A [0]; dpp->samples_A [0] = code; } else { sam = dpp->samples_A [m]; dpp->samples_A [(m + dpp->term) & (MAX_TERM - 1)] = code; } code -= apply_weight (dpp->weight_A, sam); update_weight (dpp->weight_A, dpp->delta, sam, code); } m = (m + 1) & (MAX_TERM - 1); *bptr++ = code; } send_words_lossless (wps, buffer, sample_count); } //////////////////// handle the lossless stereo mode ////////////////////// else if (!(flags & HYBRID_FLAG) && !(flags & MONO_DATA)) { int32_t *eptr = buffer + (sample_count * 2); if (!wps->num_passes) { if (flags & JOINT_STEREO) for (bptr = buffer; bptr < eptr; bptr += 2) bptr [1] += ((bptr [0] -= bptr [1]) >> 1); for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount-- ; dpp++) if (((flags & MAG_MASK) >> MAG_LSB) >= 16 || dpp->delta != 2) decorr_stereo_pass (dpp, buffer, sample_count); else decorr_stereo_pass_id2 (dpp, buffer, sample_count); } send_words_lossless (wps, buffer, sample_count); } /////////////////// handle the lossy/hybrid mono mode ///////////////////// else if ((flags & HYBRID_FLAG) && (flags & MONO_DATA)) for (bptr = buffer, i = 0; i < sample_count; ++i) { int32_t code, temp; int shaping_weight; crc2 += (crc2 << 1) + (code = *bptr++); if (flags & HYBRID_SHAPE) { if (shaping_array) shaping_weight = *shaping_array++; else shaping_weight = (wps->dc.shaping_acc [0] += wps->dc.shaping_delta [0]) >> 16; temp = -apply_weight (shaping_weight, wps->dc.error [0]); if ((flags & NEW_SHAPING) && shaping_weight < 0 && temp) { if (temp == wps->dc.error [0]) temp = (temp < 0) ? temp + 1 : temp - 1; wps->dc.error [0] = -code; code += temp; } else wps->dc.error [0] = -(code += temp); } for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount-- ; dpp++) if (dpp->term > MAX_TERM) { if (dpp->term & 1) dpp->samples_A [2] = 2 * dpp->samples_A [0] - dpp->samples_A [1]; else dpp->samples_A [2] = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; code -= (dpp->aweight_A = apply_weight (dpp->weight_A, dpp->samples_A [2])); } else code -= (dpp->aweight_A = apply_weight (dpp->weight_A, dpp->samples_A [m])); code = send_word (wps, code, 0); while (--dpp >= wps->decorr_passes) { if (dpp->term > MAX_TERM) { update_weight (dpp->weight_A, dpp->delta, dpp->samples_A [2], code); dpp->samples_A [1] = dpp->samples_A [0]; dpp->samples_A [0] = (code += dpp->aweight_A); } else { int32_t sam = dpp->samples_A [m]; update_weight (dpp->weight_A, dpp->delta, sam, code); dpp->samples_A [(m + dpp->term) & (MAX_TERM - 1)] = (code += dpp->aweight_A); } } wps->dc.error [0] += code; m = (m + 1) & (MAX_TERM - 1); if ((crc += (crc << 1) + code) != crc2) lossy = TRUE; if (wpc->config.flags & CONFIG_CALC_NOISE) { noise = code - bptr [-1]; noise_acc += noise *= noise; wps->dc.noise_ave = (wps->dc.noise_ave * 0.99) + (noise * 0.01); if (wps->dc.noise_ave > wps->dc.noise_max) wps->dc.noise_max = wps->dc.noise_ave; } } /////////////////// handle the lossy/hybrid stereo mode /////////////////// else if ((flags & HYBRID_FLAG) && !(flags & MONO_DATA)) for (bptr = buffer, i = 0; i < sample_count; ++i) { int32_t left, right, temp; int shaping_weight; left = *bptr++; crc2 += (crc2 << 3) + (left << 1) + left + (right = *bptr++); if (flags & HYBRID_SHAPE) { if (shaping_array) shaping_weight = *shaping_array++; else shaping_weight = (wps->dc.shaping_acc [0] += wps->dc.shaping_delta [0]) >> 16; temp = -apply_weight (shaping_weight, wps->dc.error [0]); if ((flags & NEW_SHAPING) && shaping_weight < 0 && temp) { if (temp == wps->dc.error [0]) temp = (temp < 0) ? temp + 1 : temp - 1; wps->dc.error [0] = -left; left += temp; } else wps->dc.error [0] = -(left += temp); if (!shaping_array) shaping_weight = (wps->dc.shaping_acc [1] += wps->dc.shaping_delta [1]) >> 16; temp = -apply_weight (shaping_weight, wps->dc.error [1]); if ((flags & NEW_SHAPING) && shaping_weight < 0 && temp) { if (temp == wps->dc.error [1]) temp = (temp < 0) ? temp + 1 : temp - 1; wps->dc.error [1] = -right; right += temp; } else wps->dc.error [1] = -(right += temp); } if (flags & JOINT_STEREO) right += ((left -= right) >> 1); for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount-- ; dpp++) if (dpp->term > MAX_TERM) { if (dpp->term & 1) { dpp->samples_A [2] = 2 * dpp->samples_A [0] - dpp->samples_A [1]; dpp->samples_B [2] = 2 * dpp->samples_B [0] - dpp->samples_B [1]; } else { dpp->samples_A [2] = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; dpp->samples_B [2] = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1; } left -= (dpp->aweight_A = apply_weight (dpp->weight_A, dpp->samples_A [2])); right -= (dpp->aweight_B = apply_weight (dpp->weight_B, dpp->samples_B [2])); } else if (dpp->term > 0) { left -= (dpp->aweight_A = apply_weight (dpp->weight_A, dpp->samples_A [m])); right -= (dpp->aweight_B = apply_weight (dpp->weight_B, dpp->samples_B [m])); } else { if (dpp->term == -1) dpp->samples_B [0] = left; else if (dpp->term == -2) dpp->samples_A [0] = right; left -= (dpp->aweight_A = apply_weight (dpp->weight_A, dpp->samples_A [0])); right -= (dpp->aweight_B = apply_weight (dpp->weight_B, dpp->samples_B [0])); } left = send_word (wps, left, 0); right = send_word (wps, right, 1); while (--dpp >= wps->decorr_passes) if (dpp->term > MAX_TERM) { update_weight (dpp->weight_A, dpp->delta, dpp->samples_A [2], left); update_weight (dpp->weight_B, dpp->delta, dpp->samples_B [2], right); dpp->samples_A [1] = dpp->samples_A [0]; dpp->samples_B [1] = dpp->samples_B [0]; dpp->samples_A [0] = (left += dpp->aweight_A); dpp->samples_B [0] = (right += dpp->aweight_B); } else if (dpp->term > 0) { int k = (m + dpp->term) & (MAX_TERM - 1); update_weight (dpp->weight_A, dpp->delta, dpp->samples_A [m], left); dpp->samples_A [k] = (left += dpp->aweight_A); update_weight (dpp->weight_B, dpp->delta, dpp->samples_B [m], right); dpp->samples_B [k] = (right += dpp->aweight_B); } else { if (dpp->term == -1) { dpp->samples_B [0] = left + dpp->aweight_A; dpp->aweight_B = apply_weight (dpp->weight_B, dpp->samples_B [0]); } else if (dpp->term == -2) { dpp->samples_A [0] = right + dpp->aweight_B; dpp->aweight_A = apply_weight (dpp->weight_A, dpp->samples_A [0]); } update_weight_clip (dpp->weight_A, dpp->delta, dpp->samples_A [0], left); update_weight_clip (dpp->weight_B, dpp->delta, dpp->samples_B [0], right); dpp->samples_B [0] = (left += dpp->aweight_A); dpp->samples_A [0] = (right += dpp->aweight_B); } if (flags & JOINT_STEREO) left += (right -= (left >> 1)); wps->dc.error [0] += left; wps->dc.error [1] += right; m = (m + 1) & (MAX_TERM - 1); if ((crc += (crc << 3) + (left << 1) + left + right) != crc2) lossy = TRUE; if (wpc->config.flags & CONFIG_CALC_NOISE) { noise = (double)(left - bptr [-2]) * (left - bptr [-2]); noise += (double)(right - bptr [-1]) * (right - bptr [-1]); noise_acc += noise /= 2.0; wps->dc.noise_ave = (wps->dc.noise_ave * 0.99) + (noise * 0.01); if (wps->dc.noise_ave > wps->dc.noise_max) wps->dc.noise_max = wps->dc.noise_ave; } } if (m) for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) if (dpp->term > 0 && dpp->term <= MAX_TERM) { int32_t temp_A [MAX_TERM], temp_B [MAX_TERM]; int k; memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A)); memcpy (temp_B, dpp->samples_B, sizeof (dpp->samples_B)); for (k = 0; k < MAX_TERM; k++) { dpp->samples_A [k] = temp_A [m]; dpp->samples_B [k] = temp_B [m]; m = (m + 1) & (MAX_TERM - 1); } } if (wpc->config.flags & CONFIG_CALC_NOISE) wps->dc.noise_sum += noise_acc; flush_word (wps); data_count = bs_close_write (&wps->wvbits); if (data_count) { if (data_count != (uint32_t) -1) { unsigned char *cptr = wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 8; *cptr++ = ID_WV_BITSTREAM | ID_LARGE; *cptr++ = data_count >> 1; *cptr++ = data_count >> 9; *cptr++ = data_count >> 17; ((WavpackHeader *) wps->blockbuff)->ckSize += data_count + 4; } else return FALSE; } ((WavpackHeader *) wps->blockbuff)->crc = crc; if (wpc->wvc_flag) { data_count = bs_close_write (&wps->wvcbits); if (data_count && lossy) { if (data_count != (uint32_t) -1) { unsigned char *cptr = wps->block2buff + ((WavpackHeader *) wps->block2buff)->ckSize + 8; *cptr++ = ID_WVC_BITSTREAM | ID_LARGE; *cptr++ = data_count >> 1; *cptr++ = data_count >> 9; *cptr++ = data_count >> 17; ((WavpackHeader *) wps->block2buff)->ckSize += data_count + 4; } else return FALSE; } ((WavpackHeader *) wps->block2buff)->crc = crc2; } else if (lossy) wpc->lossy_blocks = TRUE; wps->sample_index += sample_count; return TRUE; } // Perform a pass of the stereo decorrelation as specified by the referenced // dpp structure. This version is optimized for samples that can use the // simple apply_weight macro (i.e. <= 16-bit audio) and for when the weight // delta is 2 (which is the case with all the default, non -x modes). For // cases that do not fit this model, the more general decorr_stereo_pass() // is provided. Note that this function returns the dpp->samples_X[] values // in the "normalized" positions for terms 1-8. static void decorr_stereo_pass_id2 (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count) { int32_t *bptr, *eptr = buffer + (sample_count * 2); int m, k; switch (dpp->term) { case 17: for (bptr = buffer; bptr < eptr; bptr += 2) { int32_t sam, tmp; sam = 2 * dpp->samples_A [0] - dpp->samples_A [1]; dpp->samples_A [1] = dpp->samples_A [0]; bptr [0] = tmp = (dpp->samples_A [0] = bptr [0]) - apply_weight_i (dpp->weight_A, sam); update_weight_d2 (dpp->weight_A, dpp->delta, sam, tmp); sam = 2 * dpp->samples_B [0] - dpp->samples_B [1]; dpp->samples_B [1] = dpp->samples_B [0]; bptr [1] = tmp = (dpp->samples_B [0] = bptr [1]) - apply_weight_i (dpp->weight_B, sam); update_weight_d2 (dpp->weight_B, dpp->delta, sam, tmp); } break; case 18: for (bptr = buffer; bptr < eptr; bptr += 2) { int32_t sam, tmp; sam = dpp->samples_A [0] + ((dpp->samples_A [0] - dpp->samples_A [1]) >> 1); dpp->samples_A [1] = dpp->samples_A [0]; bptr [0] = tmp = (dpp->samples_A [0] = bptr [0]) - apply_weight_i (dpp->weight_A, sam); update_weight_d2 (dpp->weight_A, dpp->delta, sam, tmp); sam = dpp->samples_B [0] + ((dpp->samples_B [0] - dpp->samples_B [1]) >> 1); dpp->samples_B [1] = dpp->samples_B [0]; bptr [1] = tmp = (dpp->samples_B [0] = bptr [1]) - apply_weight_i (dpp->weight_B, sam); update_weight_d2 (dpp->weight_B, dpp->delta, sam, tmp); } break; default: for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr += 2) { int32_t sam, tmp; sam = dpp->samples_A [m]; bptr [0] = tmp = (dpp->samples_A [k] = bptr [0]) - apply_weight_i (dpp->weight_A, sam); update_weight_d2 (dpp->weight_A, dpp->delta, sam, tmp); sam = dpp->samples_B [m]; bptr [1] = tmp = (dpp->samples_B [k] = bptr [1]) - apply_weight_i (dpp->weight_B, sam); update_weight_d2 (dpp->weight_B, dpp->delta, sam, tmp); m = (m + 1) & (MAX_TERM - 1); k = (k + 1) & (MAX_TERM - 1); } if (m) { int32_t temp_A [MAX_TERM], temp_B [MAX_TERM]; memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A)); memcpy (temp_B, dpp->samples_B, sizeof (dpp->samples_B)); for (k = 0; k < MAX_TERM; k++) { dpp->samples_A [k] = temp_A [m]; dpp->samples_B [k] = temp_B [m]; m = (m + 1) & (MAX_TERM - 1); } } break; case -1: for (bptr = buffer; bptr < eptr; bptr += 2) { int32_t sam_A, sam_B, tmp; sam_A = dpp->samples_A [0]; bptr [0] = tmp = (sam_B = bptr [0]) - apply_weight_i (dpp->weight_A, sam_A); update_weight_clip_d2 (dpp->weight_A, dpp->delta, sam_A, tmp); bptr [1] = tmp = (dpp->samples_A [0] = bptr [1]) - apply_weight_i (dpp->weight_B, sam_B); update_weight_clip_d2 (dpp->weight_B, dpp->delta, sam_B, tmp); } break; case -2: for (bptr = buffer; bptr < eptr; bptr += 2) { int32_t sam_A, sam_B, tmp; sam_B = dpp->samples_B [0]; bptr [1] = tmp = (sam_A = bptr [1]) - apply_weight_i (dpp->weight_B, sam_B); update_weight_clip_d2 (dpp->weight_B, dpp->delta, sam_B, tmp); bptr [0] = tmp = (dpp->samples_B [0] = bptr [0]) - apply_weight_i (dpp->weight_A, sam_A); update_weight_clip_d2 (dpp->weight_A, dpp->delta, sam_A, tmp); } break; case -3: for (bptr = buffer; bptr < eptr; bptr += 2) { int32_t sam_A, sam_B, tmp; sam_A = dpp->samples_A [0]; sam_B = dpp->samples_B [0]; dpp->samples_A [0] = tmp = bptr [1]; bptr [1] = tmp -= apply_weight_i (dpp->weight_B, sam_B); update_weight_clip_d2 (dpp->weight_B, dpp->delta, sam_B, tmp); dpp->samples_B [0] = tmp = bptr [0]; bptr [0] = tmp -= apply_weight_i (dpp->weight_A, sam_A); update_weight_clip_d2 (dpp->weight_A, dpp->delta, sam_A, tmp); } break; } } // Perform a pass of the stereo decorrelation as specified by the referenced // dpp structure. This function is provided in both a regular C version and // an MMX version (using intrinsics) written by Joachim Henke. The MMX version // is significantly faster when the sample data requires the full-resolution // apply_weight macro. However, when the data is lower resolution (<= 16-bit) // then the difference is slight (or the MMX is even slower), so for these // cases the simpler decorr_stereo_pass_id2() is used. Note that this function // returns the dpp->samples_X[] values in the "normalized" positions for // terms 1-8. #ifdef OPT_MMX static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count) { const __m64 delta = _mm_set1_pi32 (dpp->delta), fill = _mm_set1_pi32 (0x7bff), mask = _mm_set1_pi32 (0x7fff), round = _mm_set1_pi32 (512), zero = _mm_set1_pi32 (0); __m64 weight_AB = _mm_set_pi32 (restore_weight (store_weight (dpp->weight_B)), restore_weight (store_weight (dpp->weight_A))), left_right, sam_AB, tmp0, tmp1, samples_AB [MAX_TERM]; int k, m = 0; for (k = 0; k < MAX_TERM; ++k) { ((int32_t *) samples_AB) [k * 2] = exp2s (log2s (dpp->samples_A [k])); ((int32_t *) samples_AB) [k * 2 + 1] = exp2s (log2s (dpp->samples_B [k])); } if (dpp->term > 0) { if (dpp->term == 17) { while (sample_count--) { left_right = *(__m64 *) buffer; tmp0 = samples_AB [0]; sam_AB = _m_paddd (tmp0, tmp0); sam_AB = _m_psubd (sam_AB, samples_AB [1]); samples_AB [0] = left_right; samples_AB [1] = tmp0; tmp0 = _m_paddd (sam_AB, sam_AB); tmp1 = _m_pand (sam_AB, mask); tmp0 = _m_psrldi (tmp0, 16); tmp1 = _m_pmaddwd (tmp1, weight_AB); tmp0 = _m_pmaddwd (tmp0, weight_AB); tmp1 = _m_paddd (tmp1, round); tmp0 = _m_pslldi (tmp0, 5); tmp1 = _m_psradi (tmp1, 10); left_right = _m_psubd (left_right, tmp0); left_right = _m_psubd (left_right, tmp1); *(__m64 *) buffer = left_right; tmp0 = _m_pxor (sam_AB, left_right); tmp0 = _m_psradi (tmp0, 31); tmp1 = _m_pxor (delta, tmp0); tmp1 = _m_psubd (tmp1, tmp0); sam_AB = _m_pcmpeqd (sam_AB, zero); tmp0 = _m_pcmpeqd (left_right, zero); tmp0 = _m_por (tmp0, sam_AB); tmp0 = _m_pandn (tmp0, tmp1); weight_AB = _m_paddd (weight_AB, tmp0); buffer += 2; } } else if (dpp->term == 18) { while (sample_count--) { left_right = *(__m64 *) buffer; tmp0 = samples_AB [0]; sam_AB = _m_psubd (tmp0, samples_AB [1]); sam_AB = _m_psradi (sam_AB, 1); sam_AB = _m_paddd (sam_AB, tmp0); samples_AB [0] = left_right; samples_AB [1] = tmp0; tmp0 = _m_paddd (sam_AB, sam_AB); tmp1 = _m_pand (sam_AB, mask); tmp0 = _m_psrldi (tmp0, 16); tmp1 = _m_pmaddwd (tmp1, weight_AB); tmp0 = _m_pmaddwd (tmp0, weight_AB); tmp1 = _m_paddd (tmp1, round); tmp0 = _m_pslldi (tmp0, 5); tmp1 = _m_psradi (tmp1, 10); left_right = _m_psubd (left_right, tmp0); left_right = _m_psubd (left_right, tmp1); *(__m64 *) buffer = left_right; tmp0 = _m_pxor (sam_AB, left_right); tmp0 = _m_psradi (tmp0, 31); tmp1 = _m_pxor (delta, tmp0); tmp1 = _m_psubd (tmp1, tmp0); sam_AB = _m_pcmpeqd (sam_AB, zero); tmp0 = _m_pcmpeqd (left_right, zero); tmp0 = _m_por (tmp0, sam_AB); tmp0 = _m_pandn (tmp0, tmp1); weight_AB = _m_paddd (weight_AB, tmp0); buffer += 2; } } else { k = dpp->term & (MAX_TERM - 1); while (sample_count--) { left_right = *(__m64 *) buffer; sam_AB = samples_AB [m]; samples_AB [k] = left_right; tmp0 = _m_paddd (sam_AB, sam_AB); tmp1 = _m_pand (sam_AB, mask); tmp0 = _m_psrldi (tmp0, 16); tmp1 = _m_pmaddwd (tmp1, weight_AB); tmp0 = _m_pmaddwd (tmp0, weight_AB); tmp1 = _m_paddd (tmp1, round); tmp0 = _m_pslldi (tmp0, 5); tmp1 = _m_psradi (tmp1, 10); left_right = _m_psubd (left_right, tmp0); left_right = _m_psubd (left_right, tmp1); *(__m64 *) buffer = left_right; tmp0 = _m_pxor (sam_AB, left_right); tmp0 = _m_psradi (tmp0, 31); tmp1 = _m_pxor (delta, tmp0); tmp1 = _m_psubd (tmp1, tmp0); sam_AB = _m_pcmpeqd (sam_AB, zero); tmp0 = _m_pcmpeqd (left_right, zero); tmp0 = _m_por (tmp0, sam_AB); tmp0 = _m_pandn (tmp0, tmp1); weight_AB = _m_paddd (weight_AB, tmp0); buffer += 2; k = (k + 1) & (MAX_TERM - 1); m = (m + 1) & (MAX_TERM - 1); } } } else { if (dpp->term == -1) { while (sample_count--) { left_right = *(__m64 *) buffer; sam_AB = samples_AB [0]; samples_AB [0] = _m_punpckhdq (left_right, sam_AB); sam_AB = _m_punpckldq (sam_AB, left_right); tmp0 = _m_paddd (sam_AB, sam_AB); tmp1 = _m_pand (sam_AB, mask); tmp0 = _m_psrldi (tmp0, 16); tmp1 = _m_pmaddwd (tmp1, weight_AB); tmp0 = _m_pmaddwd (tmp0, weight_AB); tmp1 = _m_paddd (tmp1, round); tmp0 = _m_pslldi (tmp0, 5); tmp1 = _m_psradi (tmp1, 10); left_right = _m_psubd (left_right, tmp0); left_right = _m_psubd (left_right, tmp1); *(__m64 *) buffer = left_right; tmp0 = _m_pcmpeqd (sam_AB, zero); tmp1 = _m_pcmpeqd (left_right, zero); tmp0 = _m_por (tmp0, tmp1); tmp0 = _m_pandn (tmp0, delta); sam_AB = _m_pxor (sam_AB, left_right); sam_AB = _m_psradi (sam_AB, 31); tmp1 = _m_psubd (fill, sam_AB); weight_AB = _m_pxor (weight_AB, sam_AB); weight_AB = _m_paddd (weight_AB, tmp1); weight_AB = _m_paddsw (weight_AB, tmp0); weight_AB = _m_psubd (weight_AB, tmp1); weight_AB = _m_pxor (weight_AB, sam_AB); buffer += 2; } } else if (dpp->term == -2) { while (sample_count--) { left_right = *(__m64 *) buffer; sam_AB = samples_AB [0]; samples_AB [0] = _m_punpckldq (sam_AB, left_right); sam_AB = _m_punpckhdq (left_right, sam_AB); tmp0 = _m_paddd (sam_AB, sam_AB); tmp1 = _m_pand (sam_AB, mask); tmp0 = _m_psrldi (tmp0, 16); tmp1 = _m_pmaddwd (tmp1, weight_AB); tmp0 = _m_pmaddwd (tmp0, weight_AB); tmp1 = _m_paddd (tmp1, round); tmp0 = _m_pslldi (tmp0, 5); tmp1 = _m_psradi (tmp1, 10); left_right = _m_psubd (left_right, tmp0); left_right = _m_psubd (left_right, tmp1); *(__m64 *) buffer = left_right; tmp0 = _m_pcmpeqd (sam_AB, zero); tmp1 = _m_pcmpeqd (left_right, zero); tmp0 = _m_por (tmp0, tmp1); tmp0 = _m_pandn (tmp0, delta); sam_AB = _m_pxor (sam_AB, left_right); sam_AB = _m_psradi (sam_AB, 31); tmp1 = _m_psubd (fill, sam_AB); weight_AB = _m_pxor (weight_AB, sam_AB); weight_AB = _m_paddd (weight_AB, tmp1); weight_AB = _m_paddsw (weight_AB, tmp0); weight_AB = _m_psubd (weight_AB, tmp1); weight_AB = _m_pxor (weight_AB, sam_AB); buffer += 2; } } else if (dpp->term == -3) { while (sample_count--) { left_right = *(__m64 *) buffer; sam_AB = samples_AB [0]; tmp0 = _m_punpckhdq (left_right, left_right); samples_AB [0] = _m_punpckldq (tmp0, left_right); tmp0 = _m_paddd (sam_AB, sam_AB); tmp1 = _m_pand (sam_AB, mask); tmp0 = _m_psrldi (tmp0, 16); tmp1 = _m_pmaddwd (tmp1, weight_AB); tmp0 = _m_pmaddwd (tmp0, weight_AB); tmp1 = _m_paddd (tmp1, round); tmp0 = _m_pslldi (tmp0, 5); tmp1 = _m_psradi (tmp1, 10); left_right = _m_psubd (left_right, tmp0); left_right = _m_psubd (left_right, tmp1); *(__m64 *) buffer = left_right; tmp0 = _m_pcmpeqd (sam_AB, zero); tmp1 = _m_pcmpeqd (left_right, zero); tmp0 = _m_por (tmp0, tmp1); tmp0 = _m_pandn (tmp0, delta); sam_AB = _m_pxor (sam_AB, left_right); sam_AB = _m_psradi (sam_AB, 31); tmp1 = _m_psubd (fill, sam_AB); weight_AB = _m_pxor (weight_AB, sam_AB); weight_AB = _m_paddd (weight_AB, tmp1); weight_AB = _m_paddsw (weight_AB, tmp0); weight_AB = _m_psubd (weight_AB, tmp1); weight_AB = _m_pxor (weight_AB, sam_AB); buffer += 2; } } } dpp->weight_A = ((int32_t *) &weight_AB) [0]; dpp->weight_B = ((int32_t *) &weight_AB) [1]; for (k = 0; k < MAX_TERM; ++k) { dpp->samples_A [k] = ((int32_t *) samples_AB) [m * 2]; dpp->samples_B [k] = ((int32_t *) samples_AB) [m * 2 + 1]; m = (m + 1) & (MAX_TERM - 1); } _mm_empty (); } #else static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count) { int32_t *bptr, *eptr = buffer + (sample_count * 2); int m, k; switch (dpp->term) { case 17: for (bptr = buffer; bptr < eptr; bptr += 2) { int32_t sam, tmp; sam = 2 * dpp->samples_A [0] - dpp->samples_A [1]; dpp->samples_A [1] = dpp->samples_A [0]; bptr [0] = tmp = (dpp->samples_A [0] = bptr [0]) - apply_weight (dpp->weight_A, sam); update_weight (dpp->weight_A, dpp->delta, sam, tmp); sam = 2 * dpp->samples_B [0] - dpp->samples_B [1]; dpp->samples_B [1] = dpp->samples_B [0]; bptr [1] = tmp = (dpp->samples_B [0] = bptr [1]) - apply_weight (dpp->weight_B, sam); update_weight (dpp->weight_B, dpp->delta, sam, tmp); } break; case 18: for (bptr = buffer; bptr < eptr; bptr += 2) { int32_t sam, tmp; sam = dpp->samples_A [0] + ((dpp->samples_A [0] - dpp->samples_A [1]) >> 1); dpp->samples_A [1] = dpp->samples_A [0]; bptr [0] = tmp = (dpp->samples_A [0] = bptr [0]) - apply_weight (dpp->weight_A, sam); update_weight (dpp->weight_A, dpp->delta, sam, tmp); sam = dpp->samples_B [0] + ((dpp->samples_B [0] - dpp->samples_B [1]) >> 1); dpp->samples_B [1] = dpp->samples_B [0]; bptr [1] = tmp = (dpp->samples_B [0] = bptr [1]) - apply_weight (dpp->weight_B, sam); update_weight (dpp->weight_B, dpp->delta, sam, tmp); } break; default: for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr += 2) { int32_t sam, tmp; sam = dpp->samples_A [m]; bptr [0] = tmp = (dpp->samples_A [k] = bptr [0]) - apply_weight (dpp->weight_A, sam); update_weight (dpp->weight_A, dpp->delta, sam, tmp); sam = dpp->samples_B [m]; bptr [1] = tmp = (dpp->samples_B [k] = bptr [1]) - apply_weight (dpp->weight_B, sam); update_weight (dpp->weight_B, dpp->delta, sam, tmp); m = (m + 1) & (MAX_TERM - 1); k = (k + 1) & (MAX_TERM - 1); } if (m) { int32_t temp_A [MAX_TERM], temp_B [MAX_TERM]; memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A)); memcpy (temp_B, dpp->samples_B, sizeof (dpp->samples_B)); for (k = 0; k < MAX_TERM; k++) { dpp->samples_A [k] = temp_A [m]; dpp->samples_B [k] = temp_B [m]; m = (m + 1) & (MAX_TERM - 1); } } break; case -1: for (bptr = buffer; bptr < eptr; bptr += 2) { int32_t sam_A, sam_B, tmp; sam_A = dpp->samples_A [0]; bptr [0] = tmp = (sam_B = bptr [0]) - apply_weight (dpp->weight_A, sam_A); update_weight_clip (dpp->weight_A, dpp->delta, sam_A, tmp); bptr [1] = tmp = (dpp->samples_A [0] = bptr [1]) - apply_weight (dpp->weight_B, sam_B); update_weight_clip (dpp->weight_B, dpp->delta, sam_B, tmp); } break; case -2: for (bptr = buffer; bptr < eptr; bptr += 2) { int32_t sam_A, sam_B, tmp; sam_B = dpp->samples_B [0]; bptr [1] = tmp = (sam_A = bptr [1]) - apply_weight (dpp->weight_B, sam_B); update_weight_clip (dpp->weight_B, dpp->delta, sam_B, tmp); bptr [0] = tmp = (dpp->samples_B [0] = bptr [0]) - apply_weight (dpp->weight_A, sam_A); update_weight_clip (dpp->weight_A, dpp->delta, sam_A, tmp); } break; case -3: for (bptr = buffer; bptr < eptr; bptr += 2) { int32_t sam_A, sam_B, tmp; sam_A = dpp->samples_A [0]; sam_B = dpp->samples_B [0]; dpp->samples_A [0] = tmp = bptr [1]; bptr [1] = tmp -= apply_weight (dpp->weight_B, sam_B); update_weight_clip (dpp->weight_B, dpp->delta, sam_B, tmp); dpp->samples_B [0] = tmp = bptr [0]; bptr [0] = tmp -= apply_weight (dpp->weight_A, sam_A); update_weight_clip (dpp->weight_A, dpp->delta, sam_A, tmp); } break; } } #endif ////////////////////////////////////////////////////////////////////////////// // This function returns the accumulated RMS noise as a double if the // // CALC_NOISE bit was set in the WavPack header. The peak noise can also be // // returned if desired. See wavpack.c for the calculations required to // // convert this into decibels of noise below full scale. // ////////////////////////////////////////////////////////////////////////////// double WavpackGetEncodedNoise (WavpackContext *wpc, double *peak) { WavpackStream *wps = wpc->streams [wpc->current_stream]; if (peak) *peak = wps->dc.noise_max; return wps->dc.noise_sum; } // Given an array of integer data (in shorts), find the linear function that most closely // represents it (based on minimum sum of absolute errors). This is returned as the double // precision initial & final Y values of the best-fit line. The function can also optionally // compute and return a maximum error value (as a short). Note that the ends of the resulting // line may fall way outside the range of input values, so some sort of clipping may be // needed. void best_floating_line (short *values, int num_values, double *initial_y, double *final_y, short *max_error) { double left_sum = 0.0, right_sum = 0.0, center_x = (num_values - 1) / 2.0, center_y, m; int i; for (i = 0; i < num_values >> 1; ++i) { right_sum += values [num_values - i - 1]; left_sum += values [i]; } if (num_values & 1) { right_sum += values [num_values >> 1] * 0.5; left_sum += values [num_values >> 1] * 0.5; } center_y = (right_sum + left_sum) / num_values; m = (right_sum - left_sum) / ((double) num_values * num_values) * 4.0; if (initial_y) *initial_y = center_y - m * center_x; if (final_y) *final_y = center_y + m * center_x; if (max_error) { double max = 0.0; for (i = 0; i < num_values; ++i) if (fabs (values [i] - (center_y + (i - center_x) * m)) > max) max = fabs (values [i] - (center_y + (i - center_x) * m)); *max_error = (short) floor (max + 0.5); } }