For some huffman tables result is left-shifted by 1 bit (delta). When value is negative, it is UB in C (in C++ that would be OK). Desired result of left-shifting is multiplication by 2. It happens that tables whose values are left-shifted have small value range. Thus it is possible to "bake" this multiplication into the Huffman tables. Formulae that transforms table value to result is `x + 64`. To multiply encoded values we do decode-multiply-encode: `(x + 64) * 2 - 64 == x * 2 + 64`. To check that values are still valid, we ensure those are in the range -128..-1. This is applied only to negative values of: - `t_huffman_env_bal_1_5dB` - `f_huffman_env_bal_1_5dB` - `t_huffman_env_bal_3_0dB` - `f_huffman_env_bal_3_0dB` - `t_huffman_noise_bal_3_0dB`
Unified · Split
| @@ -38,7 +38,22 @@ · 37 unmodified lines | ||
| 38 | 38 | #include "sbr_huff.h" |
| 39 | 39 | #include "sbr_e_nf.h" |
| 40 | 40 | |
| 41 | − | |
| 41 | +/* | |
| 42 | + * Huffman tables describe structure and symbols of Huffman trees. Huffman tree | |
| 43 | + * is a kind of binary tree, i. e. each node is either a leaf or has 2 child | |
| 44 | + * nodes. Items of Huffman table describe non-leaf nodes, that is why those are | |
| 45 | + * represented by a pair of integers. Depending on a bit value left (0-th) or | |
| 46 | + * right (1-st) child chosen. If value is non-negative, then it is an index | |
| 47 | + * of next inner node. Otherwise it encodes a leaf (Huffman symbol). To get the | |
| 48 | + * symbol value 64 is added to leaf value. Since all integers are int8_t, the | |
| 49 | + * range of symbol values is -64..63. | |
| 50 | + * | |
| 51 | + * Note: table with N entries describes tree with N+1 leaves. | |
| 52 | + * Note: it is possible to extend range to -64..64, since index 0 is forbidden. | |
| 53 | + * Note: it is possible to extend the range even further by using deltas instead | |
| 54 | + * of absolute indices, switching to uint8_t, and employing all the values | |
| 55 | + * bigger than maximal delta. | |
| 56 | + */ | |
| 42 | 57 | typedef const int8_t (*sbr_huff_tab)[2]; |
| 43 | 58 | |
| 44 | 59 | static const int8_t t_huffman_env_1_5dB[120][2] = { |
| @@ -108,33 +123,29 @@ static const int8_t f_huffman_env_1_5dB[120][2] = { · 63 unmodified lines | ||
| 108 | 123 | }; |
| 109 | 124 | |
| 110 | 125 | static const int8_t t_huffman_env_bal_1_5dB[48][2] = { |
| 111 | − { -64, 1 }, { -63, 2 }, { -65, 3 }, { -62, 4 }, | |
| 112 | − { -66, 5 }, { -61, 6 }, { -67, 7 }, { -60, 8 }, | |
| 113 | − { -68, 9 }, { 10, 11 }, { -69, -59 }, { 12, 13 }, | |
| 114 | − { -70, -58 }, { 14, 28 }, { 15, 21 }, { 16, 18 }, | |
| 115 | − { -57, 17 }, { -71, -56 }, { 19, 20 }, { -88, -87 }, | |
| 116 | − { -86, -85 }, { 22, 25 }, { 23, 24 }, { -84, -83 }, | |
| 117 | − { -82, -81 }, { 26, 27 }, { -80, -79 }, { -78, -77 }, | |
| 118 | − { 29, 36 }, { 30, 33 }, { 31, 32 }, { -76, -75 }, | |
| 119 | − { -74, -73 }, { 34, 35 }, { -72, -55 }, { -54, -53 }, | |
| 120 | − { 37, 41 }, { 38, 39 }, { -52, -51 }, { -50, 40 }, | |
| 121 | − { -49, -48 }, { 42, 45 }, { 43, 44 }, { -47, -46 }, | |
| 122 | − { -45, -44 }, { 46, 47 }, { -43, -42 }, { -41, -40 } | |
| 126 | + {-64, 1}, {-62, 2}, {-66, 3}, {-60, 4}, {-68, 5}, | |
| 127 | + {-58, 6}, {-70, 7}, {-56, 8}, {-72, 9}, {10, 11}, | |
| 128 | + {-74, -54}, {12, 13}, {-76, -52}, {14, 28}, {15, 21}, | |
| 129 | + {16, 18}, {-50, 17}, {-78, -48}, {19, 20}, {-112, -110}, | |
| 130 | + {-108, -106}, {22, 25}, {23, 24}, {-104, -102}, {-100, -98}, | |
| 131 | + {26, 27}, {-96, -94}, {-92, -90}, {29, 36}, {30, 33}, | |
| 132 | + {31, 32}, {-88, -86}, {-84, -82}, {34, 35}, {-80, -46}, | |
| 133 | + {-44, -42}, {37, 41}, {38, 39}, {-40, -38}, {-36, 40}, | |
| 134 | + {-34, -32}, {42, 45}, {43, 44}, {-30, -28}, {-26, -24}, | |
| 135 | + {46, 47}, {-22, -20}, {-18, -16} | |
| 123 | 136 | }; |
| 124 | 137 | |
| 125 | 138 | static const int8_t f_huffman_env_bal_1_5dB[48][2] = { |
| 126 | − { -64, 1 }, { -65, 2 }, { -63, 3 }, { -66, 4 }, | |
| 127 | − { -62, 5 }, { -61, 6 }, { -67, 7 }, { -68, 8 }, | |
| 128 | − { -60, 9 }, { 10, 11 }, { -69, -59 }, { -70, 12 }, | |
| 129 | − { -58, 13 }, { 14, 17 }, { -71, 15 }, { -57, 16 }, | |
| 130 | − { -56, -73 }, { 18, 32 }, { 19, 25 }, { 20, 22 }, | |
| 131 | − { -72, 21 }, { -88, -87 }, { 23, 24 }, { -86, -85 }, | |
| 132 | − { -84, -83 }, { 26, 29 }, { 27, 28 }, { -82, -81 }, | |
| 133 | − { -80, -79 }, { 30, 31 }, { -78, -77 }, { -76, -75 }, | |
| 134 | − { 33, 40 }, { 34, 37 }, { 35, 36 }, { -74, -55 }, | |
| 135 | − { -54, -53 }, { 38, 39 }, { -52, -51 }, { -50, -49 }, | |
| 136 | − { 41, 44 }, { 42, 43 }, { -48, -47 }, { -46, -45 }, | |
| 137 | − { 45, 46 }, { -44, -43 }, { -42, 47 }, { -41, -40 } | |
| 139 | + {-64, 1}, {-66, 2}, {-62, 3}, {-68, 4}, {-60, 5}, | |
| 140 | + {-58, 6}, {-70, 7}, {-72, 8}, {-56, 9}, {10, 11}, | |
| 141 | + {-74, -54}, {-76, 12}, {-52, 13}, {14, 17}, {-78, 15}, | |
| 142 | + {-50, 16}, {-48, -82}, {18, 32}, {19, 25}, {20, 22}, | |
| 143 | + {-80, 21}, {-112, -110}, {23, 24}, {-108, -106}, {-104, -102}, | |
| 144 | + {26, 29}, {27, 28}, {-100, -98}, {-96, -94}, {30, 31}, | |
| 145 | + {-92, -90}, {-88, -86}, {33, 40}, {34, 37}, {35, 36}, | |
| 146 | + {-84, -46}, {-44, -42}, {38, 39}, {-40, -38}, {-36, -34}, | |
| 147 | + {41, 44}, {42, 43}, {-32, -30}, {-28, -26}, {45, 46}, | |
| 148 | + {-24, -22}, {-20, 47}, {-18, -16} | |
| 138 | 149 | }; |
| 139 | 150 | |
| 140 | 151 | static const int8_t t_huffman_env_3_0dB[62][2] = { |
| @@ -176,21 +187,17 @@ static const int8_t f_huffman_env_3_0dB[62][2] = { · 35 unmodified lines | ||
| 176 | 187 | }; |
| 177 | 188 | |
| 178 | 189 | static const int8_t t_huffman_env_bal_3_0dB[24][2] = { |
| 179 | − { -64, 1 }, { -63, 2 }, { -65, 3 }, { -66, 4 }, | |
| 180 | − { -62, 5 }, { -61, 6 }, { -67, 7 }, { -68, 8 }, | |
| 181 | − { -60, 9 }, { 10, 16 }, { 11, 13 }, { -69, 12 }, | |
| 182 | − { -76, -75 }, { 14, 15 }, { -74, -73 }, { -72, -71 }, | |
| 183 | − { 17, 20 }, { 18, 19 }, { -70, -59 }, { -58, -57 }, | |
| 184 | − { 21, 22 }, { -56, -55 }, { -54, 23 }, { -53, -52 } | |
| 190 | + {-64, 1}, {-62, 2}, {-66, 3}, {-68, 4}, {-60, 5}, {-58, 6}, | |
| 191 | + {-70, 7}, {-72, 8}, {-56, 9}, {10, 16}, {11, 13}, {-74, 12}, | |
| 192 | + {-88, -86}, {14, 15}, {-84, -82}, {-80, -78}, {17, 20}, {18, 19}, | |
| 193 | + {-76, -54}, {-52, -50}, {21, 22}, {-48, -46}, {-44, 23}, {-42, -40} | |
| 185 | 194 | }; |
| 186 | 195 | |
| 187 | 196 | static const int8_t f_huffman_env_bal_3_0dB[24][2] = { |
| 188 | − { -64, 1 }, { -65, 2 }, { -63, 3 }, { -66, 4 }, | |
| 189 | − { -62, 5 }, { -61, 6 }, { -67, 7 }, { -68, 8 }, | |
| 190 | − { -60, 9 }, { 10, 13 }, { -69, 11 }, { -59, 12 }, | |
| 191 | − { -58, -76 }, { 14, 17 }, { 15, 16 }, { -75, -74 }, | |
| 192 | − { -73, -72 }, { 18, 21 }, { 19, 20 }, { -71, -70 }, | |
| 193 | − { -57, -56 }, { 22, 23 }, { -55, -54 }, { -53, -52 } | |
| 197 | + {-64, 1}, {-66, 2}, {-62, 3}, {-68, 4}, {-60, 5}, {-58, 6}, | |
| 198 | + {-70, 7}, {-72, 8}, {-56, 9}, {10, 13}, {-74, 11}, {-54, 12}, | |
| 199 | + {-52, -88}, {14, 17}, {15, 16}, {-86, -84}, {-82, -80}, {18, 21}, | |
| 200 | + {19, 20}, {-78, -76}, {-50, -48}, {22, 23}, {-46, -44}, {-42, -40} | |
| 194 | 201 | }; |
| 195 | 202 | |
| 196 | 203 | static const int8_t t_huffman_noise_3_0dB[62][2] = { |
| @@ -213,12 +220,10 @@ static const int8_t t_huffman_noise_3_0dB[62][2] = { · 16 unmodified lines | ||
| 213 | 220 | }; |
| 214 | 221 | |
| 215 | 222 | static const int8_t t_huffman_noise_bal_3_0dB[24][2] = { |
| 216 | − { -64, 1 }, { -65, 2 }, { -63, 3 }, { 4, 9 }, | |
| 217 | − { -66, 5 }, { -62, 6 }, { 7, 8 }, { -76, -75 }, | |
| 218 | − { -74, -73 }, { 10, 17 }, { 11, 14 }, { 12, 13 }, | |
| 219 | − { -72, -71 }, { -70, -69 }, { 15, 16 }, { -68, -67 }, | |
| 220 | − { -61, -60 }, { 18, 21 }, { 19, 20 }, { -59, -58 }, | |
| 221 | − { -57, -56 }, { 22, 23 }, { -55, -54 }, { -53, -52 } | |
| 223 | + {-64, 1}, {-66, 2}, {-62, 3}, {4, 9}, {-68, 5}, {-60, 6}, | |
| 224 | + {7, 8}, {-88, -86}, {-84, -82}, {10, 17}, {11, 14}, {12, 13}, | |
| 225 | + {-80, -78}, {-76, -74}, {15, 16}, {-72, -70}, {-58, -56}, {18, 21}, | |
| 226 | + {19, 20}, {-54, -52}, {-50, -48}, {22, 23}, {-46, -44}, {-42, -40} | |
| 222 | 227 | }; |
| 223 | 228 | |
| 224 | 229 | |
| @@ -298,13 +303,13 @@ void sbr_envelope(bitfile *ld, sbr_info *sbr, uint8_t ch) · 73 unmodified lines | ||
| 298 | 303 | |
| 299 | 304 | for (band = 1; band < sbr->n[sbr->f[ch][env]]; band++) |
| 300 | 305 | { |
| 301 | − sbr->E[ch][band][env] = (sbr_huff_dec(ld, f_huff) << delta); | |
| 306 | + sbr->E[ch][band][env] = (sbr_huff_dec(ld, f_huff)); | |
| 302 | 307 | } |
| 303 | 308 | |
| 304 | 309 | } else { |
| 305 | 310 | for (band = 0; band < sbr->n[sbr->f[ch][env]]; band++) |
| 306 | 311 | { |
| 307 | − sbr->E[ch][band][env] = (sbr_huff_dec(ld, t_huff) << delta); | |
| 312 | + sbr->E[ch][band][env] = (sbr_huff_dec(ld, t_huff)); | |
| 308 | 313 | } |
| 309 | 314 | } |
| 310 | 315 | } |
| @@ -344,12 +349,12 @@ void sbr_noise(bitfile *ld, sbr_info *sbr, uint8_t ch) · 33 unmodified lines | ||
| 344 | 349 | } |
| 345 | 350 | for (band = 1; band < sbr->N_Q; band++) |
| 346 | 351 | { |
| 347 | − sbr->Q[ch][band][noise] = (sbr_huff_dec(ld, f_huff) << delta); | |
| 352 | + sbr->Q[ch][band][noise] = (sbr_huff_dec(ld, f_huff)); | |
| 348 | 353 | } |
| 349 | 354 | } else { |
| 350 | 355 | for (band = 0; band < sbr->N_Q; band++) |
| 351 | 356 | { |
| 352 | − sbr->Q[ch][band][noise] = (sbr_huff_dec(ld, t_huff) << delta); | |
| 357 | + sbr->Q[ch][band][noise] = (sbr_huff_dec(ld, t_huff)); | |
| 353 | 358 | } |
| 354 | 359 | } |
| 355 | 360 | } |