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 | #include "sbr_huff.h" | 38 | #include "sbr_huff.h" |
| 39 | #include "sbr_e_nf.h" | 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 | typedef const int8_t (*sbr_huff_tab)[2]; | 57 | typedef const int8_t (*sbr_huff_tab)[2]; |
| 43 | 58 | ||
| 44 | static const int8_t t_huffman_env_1_5dB[120][2] = { | 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 | static const int8_t t_huffman_env_bal_1_5dB[48][2] = { | 125 | static const int8_t t_huffman_env_bal_1_5dB[48][2] = { |
| 111 | { -64, 1 }, { -63, 2 }, { -65, 3 }, { -62, 4 }, | 126 | {-64, 1}, {-62, 2}, {-66, 3}, {-60, 4}, {-68, 5}, |
| 112 | { -66, 5 }, { -61, 6 }, { -67, 7 }, { -60, 8 }, | 127 | {-58, 6}, {-70, 7}, {-56, 8}, {-72, 9}, {10, 11}, |
| 113 | { -68, 9 }, { 10, 11 }, { -69, -59 }, { 12, 13 }, | 128 | {-74, -54}, {12, 13}, {-76, -52}, {14, 28}, {15, 21}, |
| 114 | { -70, -58 }, { 14, 28 }, { 15, 21 }, { 16, 18 }, | 129 | {16, 18}, {-50, 17}, {-78, -48}, {19, 20}, {-112, -110}, |
| 115 | { -57, 17 }, { -71, -56 }, { 19, 20 }, { -88, -87 }, | 130 | {-108, -106}, {22, 25}, {23, 24}, {-104, -102}, {-100, -98}, |
| 116 | { -86, -85 }, { 22, 25 }, { 23, 24 }, { -84, -83 }, | 131 | {26, 27}, {-96, -94}, {-92, -90}, {29, 36}, {30, 33}, |
| 117 | { -82, -81 }, { 26, 27 }, { -80, -79 }, { -78, -77 }, | 132 | {31, 32}, {-88, -86}, {-84, -82}, {34, 35}, {-80, -46}, |
| 118 | { 29, 36 }, { 30, 33 }, { 31, 32 }, { -76, -75 }, | 133 | {-44, -42}, {37, 41}, {38, 39}, {-40, -38}, {-36, 40}, |
| 119 | { -74, -73 }, { 34, 35 }, { -72, -55 }, { -54, -53 }, | 134 | {-34, -32}, {42, 45}, {43, 44}, {-30, -28}, {-26, -24}, |
| 120 | { 37, 41 }, { 38, 39 }, { -52, -51 }, { -50, 40 }, | 135 | {46, 47}, {-22, -20}, {-18, -16} |
| 121 | { -49, -48 }, { 42, 45 }, { 43, 44 }, { -47, -46 }, | ||
| 122 | { -45, -44 }, { 46, 47 }, { -43, -42 }, { -41, -40 } | ||
| 123 | }; | 136 | }; |
| 124 | 137 | ||
| 125 | static const int8_t f_huffman_env_bal_1_5dB[48][2] = { | 138 | static const int8_t f_huffman_env_bal_1_5dB[48][2] = { |
| 126 | { -64, 1 }, { -65, 2 }, { -63, 3 }, { -66, 4 }, | 139 | {-64, 1}, {-66, 2}, {-62, 3}, {-68, 4}, {-60, 5}, |
| 127 | { -62, 5 }, { -61, 6 }, { -67, 7 }, { -68, 8 }, | 140 | {-58, 6}, {-70, 7}, {-72, 8}, {-56, 9}, {10, 11}, |
| 128 | { -60, 9 }, { 10, 11 }, { -69, -59 }, { -70, 12 }, | 141 | {-74, -54}, {-76, 12}, {-52, 13}, {14, 17}, {-78, 15}, |
| 129 | { -58, 13 }, { 14, 17 }, { -71, 15 }, { -57, 16 }, | 142 | {-50, 16}, {-48, -82}, {18, 32}, {19, 25}, {20, 22}, |
| 130 | { -56, -73 }, { 18, 32 }, { 19, 25 }, { 20, 22 }, | 143 | {-80, 21}, {-112, -110}, {23, 24}, {-108, -106}, {-104, -102}, |
| 131 | { -72, 21 }, { -88, -87 }, { 23, 24 }, { -86, -85 }, | 144 | {26, 29}, {27, 28}, {-100, -98}, {-96, -94}, {30, 31}, |
| 132 | { -84, -83 }, { 26, 29 }, { 27, 28 }, { -82, -81 }, | 145 | {-92, -90}, {-88, -86}, {33, 40}, {34, 37}, {35, 36}, |
| 133 | { -80, -79 }, { 30, 31 }, { -78, -77 }, { -76, -75 }, | 146 | {-84, -46}, {-44, -42}, {38, 39}, {-40, -38}, {-36, -34}, |
| 134 | { 33, 40 }, { 34, 37 }, { 35, 36 }, { -74, -55 }, | 147 | {41, 44}, {42, 43}, {-32, -30}, {-28, -26}, {45, 46}, |
| 135 | { -54, -53 }, { 38, 39 }, { -52, -51 }, { -50, -49 }, | 148 | {-24, -22}, {-20, 47}, {-18, -16} |
| 136 | { 41, 44 }, { 42, 43 }, { -48, -47 }, { -46, -45 }, | ||
| 137 | { 45, 46 }, { -44, -43 }, { -42, 47 }, { -41, -40 } | ||
| 138 | }; | 149 | }; |
| 139 | 150 | ||
| 140 | static const int8_t t_huffman_env_3_0dB[62][2] = { | 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 | static const int8_t t_huffman_env_bal_3_0dB[24][2] = { | 189 | static const int8_t t_huffman_env_bal_3_0dB[24][2] = { |
| 179 | { -64, 1 }, { -63, 2 }, { -65, 3 }, { -66, 4 }, | 190 | {-64, 1}, {-62, 2}, {-66, 3}, {-68, 4}, {-60, 5}, {-58, 6}, |
| 180 | { -62, 5 }, { -61, 6 }, { -67, 7 }, { -68, 8 }, | 191 | {-70, 7}, {-72, 8}, {-56, 9}, {10, 16}, {11, 13}, {-74, 12}, |
| 181 | { -60, 9 }, { 10, 16 }, { 11, 13 }, { -69, 12 }, | 192 | {-88, -86}, {14, 15}, {-84, -82}, {-80, -78}, {17, 20}, {18, 19}, |
| 182 | { -76, -75 }, { 14, 15 }, { -74, -73 }, { -72, -71 }, | 193 | {-76, -54}, {-52, -50}, {21, 22}, {-48, -46}, {-44, 23}, {-42, -40} |
| 183 | { 17, 20 }, { 18, 19 }, { -70, -59 }, { -58, -57 }, | ||
| 184 | { 21, 22 }, { -56, -55 }, { -54, 23 }, { -53, -52 } | ||
| 185 | }; | 194 | }; |
| 186 | 195 | ||
| 187 | static const int8_t f_huffman_env_bal_3_0dB[24][2] = { | 196 | static const int8_t f_huffman_env_bal_3_0dB[24][2] = { |
| 188 | { -64, 1 }, { -65, 2 }, { -63, 3 }, { -66, 4 }, | 197 | {-64, 1}, {-66, 2}, {-62, 3}, {-68, 4}, {-60, 5}, {-58, 6}, |
| 189 | { -62, 5 }, { -61, 6 }, { -67, 7 }, { -68, 8 }, | 198 | {-70, 7}, {-72, 8}, {-56, 9}, {10, 13}, {-74, 11}, {-54, 12}, |
| 190 | { -60, 9 }, { 10, 13 }, { -69, 11 }, { -59, 12 }, | 199 | {-52, -88}, {14, 17}, {15, 16}, {-86, -84}, {-82, -80}, {18, 21}, |
| 191 | { -58, -76 }, { 14, 17 }, { 15, 16 }, { -75, -74 }, | 200 | {19, 20}, {-78, -76}, {-50, -48}, {22, 23}, {-46, -44}, {-42, -40} |
| 192 | { -73, -72 }, { 18, 21 }, { 19, 20 }, { -71, -70 }, | ||
| 193 | { -57, -56 }, { 22, 23 }, { -55, -54 }, { -53, -52 } | ||
| 194 | }; | 201 | }; |
| 195 | 202 | ||
| 196 | static const int8_t t_huffman_noise_3_0dB[62][2] = { | 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 | static const int8_t t_huffman_noise_bal_3_0dB[24][2] = { | 222 | static const int8_t t_huffman_noise_bal_3_0dB[24][2] = { |
| 216 | { -64, 1 }, { -65, 2 }, { -63, 3 }, { 4, 9 }, | 223 | {-64, 1}, {-66, 2}, {-62, 3}, {4, 9}, {-68, 5}, {-60, 6}, |
| 217 | { -66, 5 }, { -62, 6 }, { 7, 8 }, { -76, -75 }, | 224 | {7, 8}, {-88, -86}, {-84, -82}, {10, 17}, {11, 14}, {12, 13}, |
| 218 | { -74, -73 }, { 10, 17 }, { 11, 14 }, { 12, 13 }, | 225 | {-80, -78}, {-76, -74}, {15, 16}, {-72, -70}, {-58, -56}, {18, 21}, |
| 219 | { -72, -71 }, { -70, -69 }, { 15, 16 }, { -68, -67 }, | 226 | {19, 20}, {-54, -52}, {-50, -48}, {22, 23}, {-46, -44}, {-42, -40} |
| 220 | { -61, -60 }, { 18, 21 }, { 19, 20 }, { -59, -58 }, | ||
| 221 | { -57, -56 }, { 22, 23 }, { -55, -54 }, { -53, -52 } | ||
| 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 | for (band = 1; band < sbr->n[sbr->f[ch][env]]; band++) | 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 | } else { | 309 | } else { |
| 305 | for (band = 0; band < sbr->n[sbr->f[ch][env]]; band++) | 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 | for (band = 1; band < sbr->N_Q; band++) | 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 | } else { | 354 | } else { |
| 350 | for (band = 0; band < sbr->N_Q; band++) | 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 | } |