/src/wavpack/src/unpack_dsd.c
Line | Count | Source (jump to first uncovered line) |
1 | | //////////////////////////////////////////////////////////////////////////// |
2 | | // **** DSDPACK **** // |
3 | | // Lossless DSD (Direct Stream Digital) Audio Compressor // |
4 | | // Copyright (c) 2013 - 2024 David Bryant. // |
5 | | // All Rights Reserved. // |
6 | | // Distributed under the BSD Software License (see license.txt) // |
7 | | //////////////////////////////////////////////////////////////////////////// |
8 | | |
9 | | // unpack_dsd.c |
10 | | |
11 | | // This module actually handles the uncompression of the DSD audio data. |
12 | | |
13 | | #ifdef ENABLE_DSD |
14 | | |
15 | | #include <stdlib.h> |
16 | | #include <string.h> |
17 | | #include <math.h> |
18 | | |
19 | | #include "wavpack_local.h" |
20 | | |
21 | | ///////////////////////////// executable code //////////////////////////////// |
22 | | |
23 | | // This function initializes the main range-encoded data for DSD audio samples |
24 | | |
25 | | static int init_dsd_block_fast (WavpackStream *wps, WavpackMetadata *wpmd); |
26 | | static int init_dsd_block_high (WavpackStream *wps, WavpackMetadata *wpmd); |
27 | | static int decode_fast (WavpackStream *wps, int32_t *output, int sample_count); |
28 | | static int decode_high (WavpackStream *wps, int32_t *output, int sample_count); |
29 | | |
30 | | int init_dsd_block (WavpackStream *wps, WavpackMetadata *wpmd) |
31 | 11.1k | { |
32 | 11.1k | if (wpmd->byte_length < 2) |
33 | 203 | return FALSE; |
34 | | |
35 | 10.9k | wps->dsd.byteptr = (unsigned char *)wpmd->data; |
36 | 10.9k | wps->dsd.endptr = wps->dsd.byteptr + wpmd->byte_length; |
37 | | |
38 | 10.9k | if (*wps->dsd.byteptr > 31) |
39 | 205 | return FALSE; |
40 | | |
41 | | // safe to cast away const on stream 0 only |
42 | 10.7k | if (!wps->stream_index) |
43 | 5.17k | ((WavpackContext *)wps->wpc)->dsd_multiplier = 1U << *wps->dsd.byteptr++; |
44 | 5.61k | else |
45 | 5.61k | wps->dsd.byteptr++; |
46 | | |
47 | 10.7k | wps->dsd.mode = *wps->dsd.byteptr++; |
48 | | |
49 | 10.7k | if (!wps->dsd.mode) { |
50 | 1.84k | if (wps->dsd.endptr - wps->dsd.byteptr != wps->wphdr.block_samples * (wps->wphdr.flags & MONO_DATA ? 1 : 2)) { |
51 | 240 | return FALSE; |
52 | 240 | } |
53 | | |
54 | 1.60k | wps->dsd.ready = 1; |
55 | 1.60k | return TRUE; |
56 | 1.84k | } |
57 | | |
58 | 8.94k | if (wps->dsd.mode == 1) |
59 | 4.15k | return init_dsd_block_fast (wps, wpmd); |
60 | 4.79k | else if (wps->dsd.mode == 3) |
61 | 4.53k | return init_dsd_block_high (wps, wpmd); |
62 | 255 | else |
63 | 255 | return FALSE; |
64 | 8.94k | } |
65 | | |
66 | | int32_t unpack_dsd_samples (WavpackStream *wps, int32_t *buffer, uint32_t sample_count) |
67 | 129k | { |
68 | 129k | uint32_t flags = wps->wphdr.flags; |
69 | | |
70 | | // don't attempt to decode past the end of the block, but watch out for overflow! |
71 | | |
72 | 129k | if (wps->sample_index + sample_count > GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples && |
73 | 129k | (uint32_t) (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index) < sample_count) |
74 | 78.3k | sample_count = (uint32_t) (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index); |
75 | | |
76 | 129k | if (GET_BLOCK_INDEX (wps->wphdr) > wps->sample_index || wps->wphdr.block_samples < sample_count) |
77 | 22.8k | wps->mute_error = TRUE; |
78 | | |
79 | 129k | if (!wps->mute_error) { |
80 | 27.0k | if (!wps->dsd.mode) { |
81 | 2.91k | int total_samples = sample_count * ((flags & MONO_DATA) ? 1 : 2); |
82 | 2.91k | int32_t *bptr = buffer; |
83 | | |
84 | 2.91k | if (wps->dsd.endptr - wps->dsd.byteptr < total_samples) |
85 | 0 | total_samples = (int)(wps->dsd.endptr - wps->dsd.byteptr); |
86 | | |
87 | 15.0k | while (total_samples--) |
88 | 12.1k | wps->crc += (wps->crc << 1) + (*bptr++ = *wps->dsd.byteptr++); |
89 | 2.91k | } |
90 | 24.1k | else if (wps->dsd.mode == 1) { |
91 | 5.46k | if (!decode_fast (wps, buffer, sample_count)) |
92 | 1.00k | wps->mute_error = TRUE; |
93 | 5.46k | } |
94 | 18.7k | else if (!decode_high (wps, buffer, sample_count)) |
95 | 224 | wps->mute_error = TRUE; |
96 | | |
97 | | // If we just finished this block, then it's time to check if the applicable checksum matches. Like |
98 | | // other decoding errors, this is indicated by setting the mute_error flag. |
99 | | |
100 | 27.0k | if (wps->sample_index + sample_count == GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples && |
101 | 27.0k | !wps->mute_error && wps->crc != wps->wphdr.crc) |
102 | 3.29k | wps->mute_error = TRUE; |
103 | 27.0k | } |
104 | | |
105 | 129k | if (wps->mute_error) { |
106 | 106k | int samples_to_null; |
107 | 106k | if (wps->wpc->reduced_channels == 1 || wps->wpc->config.num_channels == 1 || (flags & MONO_FLAG)) |
108 | 10.1k | samples_to_null = sample_count; |
109 | 96.6k | else |
110 | 96.6k | samples_to_null = sample_count * 2; |
111 | | |
112 | 82.3M | while (samples_to_null--) |
113 | 82.2M | *buffer++ = 0x55; |
114 | | |
115 | 106k | wps->sample_index += sample_count; |
116 | 106k | return sample_count; |
117 | 106k | } |
118 | | |
119 | 22.5k | if (flags & FALSE_STEREO) { |
120 | 7.84k | int32_t *dptr = buffer + sample_count * 2; |
121 | 7.84k | int32_t *sptr = buffer + sample_count; |
122 | 7.84k | int32_t c = sample_count; |
123 | | |
124 | 8.24M | while (c--) { |
125 | 8.23M | *--dptr = *--sptr; |
126 | 8.23M | *--dptr = *sptr; |
127 | 8.23M | } |
128 | 7.84k | } |
129 | | |
130 | 22.5k | wps->sample_index += sample_count; |
131 | | |
132 | 22.5k | return sample_count; |
133 | 129k | } |
134 | | |
135 | | /*------------------------------------------------------------------------------------------------------------------------*/ |
136 | | |
137 | | // #define DSD_BYTE_READY(low,high) (((low) >> 24) == ((high) >> 24)) |
138 | | // #define DSD_BYTE_READY(low,high) (!(((low) ^ (high)) >> 24)) |
139 | 481M | #define DSD_BYTE_READY(low,high) (!(((low) ^ (high)) & 0xff000000)) |
140 | | |
141 | | static int init_dsd_block_fast (WavpackStream *wps, WavpackMetadata *wpmd) |
142 | 4.15k | { |
143 | 4.15k | unsigned char history_bits, max_probability, *lb_ptr; |
144 | 4.15k | int total_summed_probabilities = 0, bi, i; |
145 | | |
146 | 4.15k | (void) wpmd; |
147 | | |
148 | 4.15k | if (wps->dsd.byteptr == wps->dsd.endptr) |
149 | 223 | return FALSE; |
150 | | |
151 | 3.93k | history_bits = *wps->dsd.byteptr++; |
152 | | |
153 | 3.93k | if (wps->dsd.byteptr == wps->dsd.endptr || history_bits > MAX_HISTORY_BITS) |
154 | 453 | return FALSE; |
155 | | |
156 | 3.47k | wps->dsd.history_bins = 1 << history_bits; |
157 | | |
158 | 3.47k | free_dsd_tables (wps); |
159 | 3.47k | lb_ptr = wps->dsd.lookup_buffer = (unsigned char *)malloc (wps->dsd.history_bins * MAX_BYTES_PER_BIN); |
160 | 3.47k | wps->dsd.value_lookup = (unsigned char **)malloc (sizeof (*wps->dsd.value_lookup) * wps->dsd.history_bins); |
161 | 3.47k | memset (wps->dsd.value_lookup, 0, sizeof (*wps->dsd.value_lookup) * wps->dsd.history_bins); |
162 | 3.47k | wps->dsd.summed_probabilities = (uint16_t (*)[256])malloc (sizeof (*wps->dsd.summed_probabilities) * wps->dsd.history_bins); |
163 | 3.47k | wps->dsd.probabilities = (unsigned char (*)[256])malloc (sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins); |
164 | | |
165 | 3.47k | max_probability = *wps->dsd.byteptr++; |
166 | | |
167 | 3.47k | if (max_probability < 0xff) { |
168 | 2.99k | unsigned char *outptr = (unsigned char *) wps->dsd.probabilities; |
169 | 2.99k | unsigned char *outend = outptr + sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins; |
170 | | |
171 | 38.8k | while (outptr < outend && wps->dsd.byteptr < wps->dsd.endptr) { |
172 | 36.1k | int code = *wps->dsd.byteptr++; |
173 | | |
174 | 36.1k | if (code > max_probability) { |
175 | 18.3k | int zcount = code - max_probability; |
176 | | |
177 | 1.66M | while (outptr < outend && zcount--) |
178 | 1.64M | *outptr++ = 0; |
179 | 18.3k | } |
180 | 17.8k | else if (code) |
181 | 17.5k | *outptr++ = (unsigned char)code; |
182 | 273 | else |
183 | 273 | break; |
184 | 36.1k | } |
185 | | |
186 | 2.99k | if (outptr < outend || (wps->dsd.byteptr < wps->dsd.endptr && *wps->dsd.byteptr++)) |
187 | 582 | return FALSE; |
188 | 2.99k | } |
189 | 487 | else if (wps->dsd.endptr - wps->dsd.byteptr > (int) sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins) { |
190 | 206 | memcpy (wps->dsd.probabilities, wps->dsd.byteptr, sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins); |
191 | 206 | wps->dsd.byteptr += sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins; |
192 | 206 | } |
193 | 281 | else |
194 | 281 | return FALSE; |
195 | | |
196 | 8.60k | for (bi = 0; bi < wps->dsd.history_bins; ++bi) { |
197 | 6.19k | int32_t sum_values; |
198 | | |
199 | 1.59M | for (sum_values = i = 0; i < 256; ++i) |
200 | 1.58M | wps->dsd.summed_probabilities [bi] [i] = (uint16_t)(sum_values += wps->dsd.probabilities [bi] [i]); |
201 | | |
202 | 6.19k | if (sum_values) { |
203 | 3.33k | if ((total_summed_probabilities += sum_values) > wps->dsd.history_bins * MAX_BYTES_PER_BIN) |
204 | 202 | return FALSE; |
205 | | |
206 | 3.13k | wps->dsd.value_lookup [bi] = lb_ptr; |
207 | | |
208 | 806k | for (i = 0; i < 256; i++) { |
209 | 803k | int c = wps->dsd.probabilities [bi] [i]; |
210 | | |
211 | 1.98M | while (c--) |
212 | 1.17M | *lb_ptr++ = (unsigned char)i; |
213 | 803k | } |
214 | 3.13k | } |
215 | 6.19k | } |
216 | | |
217 | 2.41k | if (wps->dsd.endptr - wps->dsd.byteptr < 4 || total_summed_probabilities > wps->dsd.history_bins * MAX_BYTES_PER_BIN) |
218 | 738 | return FALSE; |
219 | | |
220 | 8.37k | for (i = 4; i--;) |
221 | 6.69k | wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; |
222 | | |
223 | 1.67k | wps->dsd.p0 = wps->dsd.p1 = 0; |
224 | 1.67k | wps->dsd.low = 0; wps->dsd.high = 0xffffffff; |
225 | 1.67k | wps->dsd.ready = 1; |
226 | | |
227 | 1.67k | return TRUE; |
228 | 2.41k | } |
229 | | |
230 | | static int decode_fast (WavpackStream *wps, int32_t *output, int sample_count) |
231 | 5.46k | { |
232 | 5.46k | int total_samples = sample_count; |
233 | | |
234 | 5.46k | if (!(wps->wphdr.flags & MONO_DATA)) |
235 | 1.77k | total_samples *= 2; |
236 | | |
237 | 8.57M | while (total_samples--) { |
238 | 8.56M | unsigned int mult, index, code, i; |
239 | | |
240 | 8.56M | if (!wps->dsd.summed_probabilities [wps->dsd.p0] [255]) |
241 | 728 | return 0; |
242 | | |
243 | 8.56M | mult = (wps->dsd.high - wps->dsd.low) / wps->dsd.summed_probabilities [wps->dsd.p0] [255]; |
244 | | |
245 | 8.56M | if (!mult) { |
246 | 336k | if (wps->dsd.endptr - wps->dsd.byteptr >= 4) |
247 | 2.70k | for (i = 4; i--;) |
248 | 2.16k | wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; |
249 | | |
250 | 336k | wps->dsd.low = 0; |
251 | 336k | wps->dsd.high = 0xffffffff; |
252 | 336k | mult = wps->dsd.high / wps->dsd.summed_probabilities [wps->dsd.p0] [255]; |
253 | | |
254 | 336k | if (!mult) |
255 | 0 | return 0; |
256 | 336k | } |
257 | | |
258 | 8.56M | index = (wps->dsd.value - wps->dsd.low) / mult; |
259 | | |
260 | 8.56M | if (index >= wps->dsd.summed_probabilities [wps->dsd.p0] [255]) |
261 | 281 | return 0; |
262 | | |
263 | 8.56M | if ((*output++ = code = wps->dsd.value_lookup [wps->dsd.p0] [index]) != 0) |
264 | 4.03M | wps->dsd.low += wps->dsd.summed_probabilities [wps->dsd.p0] [code-1] * mult; |
265 | | |
266 | 8.56M | wps->dsd.high = wps->dsd.low + wps->dsd.probabilities [wps->dsd.p0] [code] * mult - 1; |
267 | 8.56M | wps->crc += (wps->crc << 1) + code; |
268 | | |
269 | 8.56M | if (wps->wphdr.flags & MONO_DATA) |
270 | 3.24M | wps->dsd.p0 = code & (wps->dsd.history_bins-1); |
271 | 5.31M | else { |
272 | 5.31M | wps->dsd.p0 = wps->dsd.p1; |
273 | 5.31M | wps->dsd.p1 = code & (wps->dsd.history_bins-1); |
274 | 5.31M | } |
275 | | |
276 | 8.57M | while (DSD_BYTE_READY (wps->dsd.high, wps->dsd.low) && wps->dsd.byteptr < wps->dsd.endptr) { |
277 | 7.48k | wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; |
278 | 7.48k | wps->dsd.high = (wps->dsd.high << 8) | 0xff; |
279 | 7.48k | wps->dsd.low <<= 8; |
280 | 7.48k | } |
281 | 8.56M | } |
282 | | |
283 | 4.45k | return sample_count; |
284 | 5.46k | } |
285 | | |
286 | | /*------------------------------------------------------------------------------------------------------------------------*/ |
287 | | |
288 | 233M | #define PTABLE_BITS 8 |
289 | 233M | #define PTABLE_BINS (1<<PTABLE_BITS) |
290 | 232M | #define PTABLE_MASK (PTABLE_BINS-1) |
291 | | |
292 | 230M | #define UP 0x010000fe |
293 | 7.67M | #define DOWN 0x00010000 |
294 | 238M | #define DECAY 8 |
295 | | |
296 | 697M | #define PRECISION 20 |
297 | 464M | #define VALUE_ONE (1 << PRECISION) |
298 | 232M | #define PRECISION_USE 12 |
299 | | |
300 | 4.34k | #define RATE_S 20 |
301 | | |
302 | | static void init_ptable (int *table, int rate_i, int rate_s) |
303 | 4.14k | { |
304 | 4.14k | int value = 0x808000, rate = rate_i << 8, c, i; |
305 | | |
306 | 308k | for (c = (rate + 128) >> 8; c--;) |
307 | 304k | value += (DOWN - value) >> DECAY; |
308 | | |
309 | 534k | for (i = 0; i < PTABLE_BINS/2; ++i) { |
310 | 530k | table [i] = value; |
311 | 530k | table [PTABLE_BINS-1-i] = 0x100ffff - value; |
312 | | |
313 | 530k | if (value > 0x010000) { |
314 | 290k | rate += (rate * rate_s + 128) >> 8; |
315 | | |
316 | 6.16M | for (c = (rate + 64) >> 7; c--;) |
317 | 5.87M | value += (DOWN - value) >> DECAY; |
318 | 290k | } |
319 | 530k | } |
320 | 4.14k | } |
321 | | |
322 | | static int init_dsd_block_high (WavpackStream *wps, WavpackMetadata *wpmd) |
323 | 4.53k | { |
324 | 4.53k | uint32_t flags = wps->wphdr.flags; |
325 | 4.53k | int channel, rate_i, rate_s, i; |
326 | | |
327 | 4.53k | (void) wpmd; |
328 | | |
329 | 4.53k | if (wps->dsd.endptr - wps->dsd.byteptr < ((flags & MONO_DATA) ? 13 : 20)) |
330 | 194 | return FALSE; |
331 | | |
332 | 4.34k | rate_i = *wps->dsd.byteptr++; |
333 | 4.34k | rate_s = *wps->dsd.byteptr++; |
334 | | |
335 | 4.34k | if (rate_s != RATE_S) |
336 | 200 | return FALSE; |
337 | | |
338 | 4.14k | if (!wps->dsd.ptable) |
339 | 3.34k | wps->dsd.ptable = (int32_t *)malloc (PTABLE_BINS * sizeof (*wps->dsd.ptable)); |
340 | | |
341 | 4.14k | init_ptable (wps->dsd.ptable, rate_i, rate_s); |
342 | | |
343 | 9.36k | for (channel = 0; channel < ((flags & MONO_DATA) ? 1 : 2); ++channel) { |
344 | 5.21k | DSDfilters *sp = wps->dsd.filters + channel; |
345 | | |
346 | 5.21k | sp->filter1 = *wps->dsd.byteptr++ << (PRECISION - 8); |
347 | 5.21k | sp->filter2 = *wps->dsd.byteptr++ << (PRECISION - 8); |
348 | 5.21k | sp->filter3 = *wps->dsd.byteptr++ << (PRECISION - 8); |
349 | 5.21k | sp->filter4 = *wps->dsd.byteptr++ << (PRECISION - 8); |
350 | 5.21k | sp->filter5 = *wps->dsd.byteptr++ << (PRECISION - 8); |
351 | 5.21k | sp->filter6 = 0; |
352 | 5.21k | sp->factor = *wps->dsd.byteptr++ & 0xff; |
353 | 5.21k | sp->factor |= (*wps->dsd.byteptr++ << 8) & 0xff00; |
354 | 5.21k | sp->factor = (int32_t)((uint32_t)sp->factor << 16) >> 16; |
355 | 5.21k | } |
356 | | |
357 | 4.14k | wps->dsd.high = 0xffffffff; |
358 | 4.14k | wps->dsd.low = 0x0; |
359 | | |
360 | 20.7k | for (i = 4; i--;) |
361 | 16.5k | wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; |
362 | | |
363 | 4.14k | wps->dsd.ready = 1; |
364 | | |
365 | 4.14k | return TRUE; |
366 | 4.34k | } |
367 | | |
368 | | static int decode_high (WavpackStream *wps, int32_t *output, int sample_count) |
369 | 18.7k | { |
370 | 18.7k | int total_samples = sample_count, stereo = (wps->wphdr.flags & MONO_DATA) ? 0 : 1; |
371 | 18.7k | DSDfilters *sp = wps->dsd.filters; |
372 | | |
373 | 26.5M | while (total_samples--) { |
374 | 26.5M | int bitcount = 8; |
375 | | |
376 | 26.5M | sp [0].value = sp [0].filter1 - sp [0].filter5 + ((sp [0].filter6 * sp [0].factor) >> 2); |
377 | | |
378 | 26.5M | if (stereo) |
379 | 5.19M | sp [1].value = sp [1].filter1 - sp [1].filter5 + ((sp [1].filter6 * sp [1].factor) >> 2); |
380 | | |
381 | 226M | while (bitcount--) { |
382 | 199M | int32_t *pp = wps->dsd.ptable + ((sp [0].value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK); |
383 | 199M | uint32_t split = wps->dsd.low + ((wps->dsd.high - wps->dsd.low) >> 8) * (*pp >> 16); |
384 | | |
385 | 199M | if (wps->dsd.value <= split) { |
386 | 198M | wps->dsd.high = split; |
387 | 198M | *pp += (UP - *pp) >> DECAY; |
388 | 198M | sp [0].filter0 = -1; |
389 | 198M | } |
390 | 1.06M | else { |
391 | 1.06M | wps->dsd.low = split + 1; |
392 | 1.06M | *pp += (DOWN - *pp) >> DECAY; |
393 | 1.06M | sp [0].filter0 = 0; |
394 | 1.06M | } |
395 | | |
396 | 199M | while (DSD_BYTE_READY (wps->dsd.high, wps->dsd.low) && wps->dsd.byteptr < wps->dsd.endptr) { |
397 | 14.2k | wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; |
398 | 14.2k | wps->dsd.high = (wps->dsd.high << 8) | 0xff; |
399 | 14.2k | wps->dsd.low <<= 8; |
400 | 14.2k | } |
401 | | |
402 | 199M | sp [0].value += sp [0].filter6 * 8; |
403 | 199M | sp [0].byte = (sp [0].byte << 1) | (sp [0].filter0 & 1); |
404 | 199M | sp [0].factor += (((sp [0].value ^ sp [0].filter0) >> 31) | 1) & ((sp [0].value ^ (sp [0].value - (sp [0].filter6 * 16))) >> 31); |
405 | 199M | sp [0].filter1 += ((sp [0].filter0 & VALUE_ONE) - sp [0].filter1) >> 6; |
406 | 199M | sp [0].filter2 += ((sp [0].filter0 & VALUE_ONE) - sp [0].filter2) >> 4; |
407 | 199M | sp [0].filter3 += (sp [0].filter2 - sp [0].filter3) >> 4; |
408 | 199M | sp [0].filter4 += (sp [0].filter3 - sp [0].filter4) >> 4; |
409 | 199M | sp [0].value = (sp [0].filter4 - sp [0].filter5) >> 4; |
410 | 199M | sp [0].filter5 += sp [0].value; |
411 | 199M | sp [0].filter6 += (sp [0].value - sp [0].filter6) >> 3; |
412 | 199M | sp [0].value = sp [0].filter1 - sp [0].filter5 + ((sp [0].filter6 * sp [0].factor) >> 2); |
413 | | |
414 | 199M | if (!stereo) |
415 | 167M | continue; |
416 | | |
417 | 32.4M | pp = wps->dsd.ptable + ((sp [1].value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK); |
418 | 32.4M | split = wps->dsd.low + ((wps->dsd.high - wps->dsd.low) >> 8) * (*pp >> 16); |
419 | | |
420 | 32.4M | if (wps->dsd.value <= split) { |
421 | 32.0M | wps->dsd.high = split; |
422 | 32.0M | *pp += (UP - *pp) >> DECAY; |
423 | 32.0M | sp [1].filter0 = -1; |
424 | 32.0M | } |
425 | 425k | else { |
426 | 425k | wps->dsd.low = split + 1; |
427 | 425k | *pp += (DOWN - *pp) >> DECAY; |
428 | 425k | sp [1].filter0 = 0; |
429 | 425k | } |
430 | | |
431 | 32.4M | while (DSD_BYTE_READY (wps->dsd.high, wps->dsd.low) && wps->dsd.byteptr < wps->dsd.endptr) { |
432 | 6.62k | wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; |
433 | 6.62k | wps->dsd.high = (wps->dsd.high << 8) | 0xff; |
434 | 6.62k | wps->dsd.low <<= 8; |
435 | 6.62k | } |
436 | | |
437 | 32.4M | sp [1].value += sp [1].filter6 * 8; |
438 | 32.4M | sp [1].byte = (sp [1].byte << 1) | (sp [1].filter0 & 1); |
439 | 32.4M | sp [1].factor += (((sp [1].value ^ sp [1].filter0) >> 31) | 1) & ((sp [1].value ^ (sp [1].value - (sp [1].filter6 * 16))) >> 31); |
440 | 32.4M | sp [1].filter1 += ((sp [1].filter0 & VALUE_ONE) - sp [1].filter1) >> 6; |
441 | 32.4M | sp [1].filter2 += ((sp [1].filter0 & VALUE_ONE) - sp [1].filter2) >> 4; |
442 | 32.4M | sp [1].filter3 += (sp [1].filter2 - sp [1].filter3) >> 4; |
443 | 32.4M | sp [1].filter4 += (sp [1].filter3 - sp [1].filter4) >> 4; |
444 | 32.4M | sp [1].value = (sp [1].filter4 - sp [1].filter5) >> 4; |
445 | 32.4M | sp [1].filter5 += sp [1].value; |
446 | 32.4M | sp [1].filter6 += (sp [1].value - sp [1].filter6) >> 3; |
447 | 32.4M | sp [1].value = sp [1].filter1 - sp [1].filter5 + ((sp [1].filter6 * sp [1].factor) >> 2); |
448 | 32.4M | } |
449 | | |
450 | 26.5M | wps->crc += (wps->crc << 1) + (*output++ = sp [0].byte & 0xff); |
451 | 26.5M | sp [0].factor -= (sp [0].factor + 512) >> 10; |
452 | | |
453 | 26.5M | if (stereo) { |
454 | 5.23M | wps->crc += (wps->crc << 1) + (*output++ = wps->dsd.filters [1].byte & 0xff); |
455 | 5.23M | wps->dsd.filters [1].factor -= (wps->dsd.filters [1].factor + 512) >> 10; |
456 | 5.23M | } |
457 | 26.5M | } |
458 | | |
459 | 18.7k | return sample_count; |
460 | 18.7k | } |
461 | | |
462 | | /*------------------------------------------------------------------------------------------------------------------------*/ |
463 | | |
464 | | #if 0 |
465 | | |
466 | | // 80 term DSD decimation filter |
467 | | // < 1 dB down at 20 kHz |
468 | | // > 108 dB stopband attenuation (fs/16) |
469 | | |
470 | | static const int32_t decm_filter [] = { |
471 | | 4, 17, 56, 147, 336, 693, 1320, 2359, |
472 | | 4003, 6502, 10170, 15392, 22623, 32389, 45275, 61920, |
473 | | 82994, 109174, 141119, 179431, 224621, 277068, 336983, 404373, |
474 | | 479004, 560384, 647741, 740025, 835917, 933849, 1032042, 1128551, |
475 | | 1221329, 1308290, 1387386, 1456680, 1514425, 1559128, 1589610, 1605059, |
476 | | 1605059, 1589610, 1559128, 1514425, 1456680, 1387386, 1308290, 1221329, |
477 | | 1128551, 1032042, 933849, 835917, 740025, 647741, 560384, 479004, |
478 | | 404373, 336983, 277068, 224621, 179431, 141119, 109174, 82994, |
479 | | 61920, 45275, 32389, 22623, 15392, 10170, 6502, 4003, |
480 | | 2359, 1320, 693, 336, 147, 56, 17, 4, |
481 | | }; |
482 | | |
483 | | #define NUM_FILTER_TERMS 80 |
484 | | |
485 | | #else |
486 | | |
487 | | // 56 term decimation filter |
488 | | // < 0.5 dB down at 20 kHz |
489 | | // > 100 dB stopband attenuation (fs/12) |
490 | | |
491 | | static const int32_t decm_filter [] = { |
492 | | 4, 17, 56, 147, 336, 692, 1315, 2337, |
493 | | 3926, 6281, 9631, 14216, 20275, 28021, 37619, 49155, |
494 | | 62616, 77870, 94649, 112551, 131049, 149507, 167220, 183448, |
495 | | 197472, 208636, 216402, 220385, 220385, 216402, 208636, 197472, |
496 | | 183448, 167220, 149507, 131049, 112551, 94649, 77870, 62616, |
497 | | 49155, 37619, 28021, 20275, 14216, 9631, 6281, 3926, |
498 | | 2337, 1315, 692, 336, 147, 56, 17, 4, |
499 | | }; |
500 | | |
501 | 2.63M | #define NUM_FILTER_TERMS 56 |
502 | | |
503 | | #endif |
504 | | |
505 | 2.51M | #define HISTORY_BYTES ((NUM_FILTER_TERMS+7)/8) |
506 | | |
507 | | typedef struct { |
508 | | unsigned char delay [HISTORY_BYTES]; |
509 | | } DecimationChannel; |
510 | | |
511 | | typedef struct { |
512 | | int32_t conv_tables [HISTORY_BYTES] [256]; |
513 | | DecimationChannel *chans; |
514 | | int num_channels, reset; |
515 | | } DecimationContext; |
516 | | |
517 | | static void extrapolate_pcm (int32_t *samples, int samples_to_extrapolate, int samples_visible, int num_channels); |
518 | | |
519 | | void *decimate_dsd_init (int num_channels) |
520 | 1.02k | { |
521 | 1.02k | DecimationContext *context = (DecimationContext *)malloc (sizeof (DecimationContext)); |
522 | 1.02k | double filter_sum = 0, filter_scale; |
523 | 1.02k | int i, j; |
524 | | |
525 | 1.02k | if (!context) |
526 | 0 | return context; |
527 | | |
528 | 1.02k | memset (context, 0, sizeof (*context)); |
529 | 1.02k | context->num_channels = num_channels; |
530 | 1.02k | context->chans = (DecimationChannel *)malloc (num_channels * sizeof (DecimationChannel)); |
531 | | |
532 | 1.02k | if (!context->chans) { |
533 | 0 | free (context); |
534 | 0 | return NULL; |
535 | 0 | } |
536 | | |
537 | 58.1k | for (i = 0; i < NUM_FILTER_TERMS; ++i) |
538 | 57.1k | filter_sum += decm_filter [i]; |
539 | | |
540 | 1.02k | filter_scale = ((1 << 23) - 1) / filter_sum * 16.0; |
541 | | |
542 | 58.1k | for (i = 0; i < NUM_FILTER_TERMS; ++i) { |
543 | 57.1k | int scaled_term = (int) floor (decm_filter [i] * filter_scale + 0.5); |
544 | | |
545 | 57.1k | if (scaled_term) { |
546 | 14.6M | for (j = 0; j < 256; ++j) |
547 | 14.6M | if (j & (0x80 >> (i & 0x7))) |
548 | 7.31M | context->conv_tables [i >> 3] [j] += scaled_term; |
549 | 7.31M | else |
550 | 7.31M | context->conv_tables [i >> 3] [j] -= scaled_term; |
551 | 57.1k | } |
552 | 57.1k | } |
553 | | |
554 | 1.02k | decimate_dsd_reset (context); |
555 | | |
556 | 1.02k | return context; |
557 | 1.02k | } |
558 | | |
559 | | void decimate_dsd_reset (void *decimate_context) |
560 | 1.54k | { |
561 | 1.54k | DecimationContext *context = (DecimationContext *) decimate_context; |
562 | 1.54k | int chan = 0, i; |
563 | | |
564 | 1.54k | if (!context) |
565 | 0 | return; |
566 | | |
567 | 315k | for (chan = 0; chan < context->num_channels; ++chan) |
568 | 2.51M | for (i = 0; i < HISTORY_BYTES; ++i) |
569 | 2.19M | context->chans [chan].delay [i] = 0x55; |
570 | | |
571 | 1.54k | context->reset = 1; |
572 | 1.54k | } |
573 | | |
574 | | void decimate_dsd_run (void *decimate_context, int32_t *samples, int num_samples) |
575 | 22.1k | { |
576 | 22.1k | DecimationContext *context = (DecimationContext *) decimate_context; |
577 | 22.1k | int chan = 0, scount = num_samples; |
578 | 22.1k | int32_t *samptr = samples; |
579 | | |
580 | 22.1k | if (!context) |
581 | 0 | return; |
582 | | |
583 | 305M | while (scount) { |
584 | 305M | DecimationChannel *sp = context->chans + chan; |
585 | 305M | int32_t sum = 0; |
586 | | |
587 | | #if (HISTORY_BYTES == 10) |
588 | | sum += context->conv_tables [0] [sp->delay [0] = sp->delay [1]]; |
589 | | sum += context->conv_tables [1] [sp->delay [1] = sp->delay [2]]; |
590 | | sum += context->conv_tables [2] [sp->delay [2] = sp->delay [3]]; |
591 | | sum += context->conv_tables [3] [sp->delay [3] = sp->delay [4]]; |
592 | | sum += context->conv_tables [4] [sp->delay [4] = sp->delay [5]]; |
593 | | sum += context->conv_tables [5] [sp->delay [5] = sp->delay [6]]; |
594 | | sum += context->conv_tables [6] [sp->delay [6] = sp->delay [7]]; |
595 | | sum += context->conv_tables [7] [sp->delay [7] = sp->delay [8]]; |
596 | | sum += context->conv_tables [8] [sp->delay [8] = sp->delay [9]]; |
597 | | sum += context->conv_tables [9] [sp->delay [9] = (unsigned char)*samptr]; |
598 | | #elif (HISTORY_BYTES == 7) |
599 | | sum += context->conv_tables [0] [sp->delay [0] = sp->delay [1]]; |
600 | 305M | sum += context->conv_tables [1] [sp->delay [1] = sp->delay [2]]; |
601 | 305M | sum += context->conv_tables [2] [sp->delay [2] = sp->delay [3]]; |
602 | 305M | sum += context->conv_tables [3] [sp->delay [3] = sp->delay [4]]; |
603 | 305M | sum += context->conv_tables [4] [sp->delay [4] = sp->delay [5]]; |
604 | 305M | sum += context->conv_tables [5] [sp->delay [5] = sp->delay [6]]; |
605 | 305M | sum += context->conv_tables [6] [sp->delay [6] = (unsigned char)*samptr]; |
606 | | #else |
607 | | int i; |
608 | | |
609 | | for (i = 0; i < HISTORY_BYTES-1; ++i) |
610 | | sum += context->conv_tables [i] [sp->delay [i] = sp->delay [i+1]]; |
611 | | |
612 | | sum += context->conv_tables [i] [sp->delay [i] = (unsigned char)*samptr]; |
613 | | #endif |
614 | | |
615 | 305M | *samptr++ = (sum + 8) >> 4; |
616 | | |
617 | 305M | if (++chan == context->num_channels) { |
618 | 20.6M | scount--; |
619 | 20.6M | chan = 0; |
620 | 20.6M | } |
621 | 305M | } |
622 | | |
623 | 22.1k | if (context->reset) { |
624 | 1.49k | extrapolate_pcm (samples, HISTORY_BYTES - 1, num_samples, context->num_channels); |
625 | 1.49k | context->reset = 0; |
626 | 1.49k | } |
627 | 22.1k | } |
628 | | |
629 | | // This function is used to linearly extrapolate some samples at the beginning of the first |
630 | | // decoded frame because we don't have the previous DSD data to prefill the decimation filter. |
631 | | // Currently we only extrapolate at the beginning of the file because we have an implicit |
632 | | // delay in the decimation. It might be better, but more complicated, to have zero delay in |
633 | | // the decimation and split the extrapolated samples between the beginning and end of the |
634 | | // file. |
635 | | |
636 | | static void extrapolate_pcm (int32_t *samples, int samples_to_extrapolate, int samples_visible, int num_channels) |
637 | 1.49k | { |
638 | 1.49k | int scount = num_channels, min_period = 5, max_period = 10; |
639 | | |
640 | 1.49k | if (samples_visible < samples_to_extrapolate + min_period * 2) |
641 | 583 | return; |
642 | | |
643 | 908 | if (samples_visible < samples_to_extrapolate + max_period * 2) |
644 | 110 | max_period = (samples_visible - samples_to_extrapolate) / 2; |
645 | | |
646 | 124k | while (scount--) { |
647 | 123k | float left_value_ave = 0.0, right_value_ave = 0.0, slope; |
648 | 123k | int period, i; |
649 | | |
650 | 322k | for (period = min_period; period <= max_period; ++period) { |
651 | 199k | float left_ratio = (samples_to_extrapolate + period / 2.0F) / period, right_ratio = (period / 2.0F) / period; |
652 | 199k | int32_t *sam1 = samples + samples_to_extrapolate * num_channels, *sam2 = sam1 + period * num_channels; |
653 | 199k | float ave1 = 0.0, ave2 = 0.0; |
654 | | |
655 | 1.42M | for (i = 0; i < period; ++i) { |
656 | 1.22M | ave1 += (float) sam1 [i * num_channels] / period; |
657 | 1.22M | ave2 += (float) sam2 [i * num_channels] / period; |
658 | 1.22M | } |
659 | | |
660 | 199k | left_value_ave += ave1 + (ave1 - ave2) * left_ratio; |
661 | 199k | right_value_ave += ave1 + (ave1 - ave2) * right_ratio; |
662 | 199k | } |
663 | | |
664 | 123k | right_value_ave /= (max_period - min_period + 1); |
665 | 123k | left_value_ave /= (max_period - min_period + 1); |
666 | 123k | slope = (right_value_ave - left_value_ave) / (samples_to_extrapolate - 1); |
667 | | |
668 | 861k | for (i = 0; i < samples_to_extrapolate; ++i) |
669 | 738k | samples [i * num_channels] = (int32_t) (left_value_ave + i * slope + 0.5); |
670 | | |
671 | 123k | samples++; |
672 | 123k | } |
673 | 908 | } |
674 | | |
675 | | void decimate_dsd_destroy (void *decimate_context) |
676 | 1.02k | { |
677 | 1.02k | DecimationContext *context = (DecimationContext *) decimate_context; |
678 | | |
679 | 1.02k | if (!context) |
680 | 0 | return; |
681 | | |
682 | 1.02k | if (context->chans) |
683 | 1.02k | free (context->chans); |
684 | | |
685 | 1.02k | free (context); |
686 | 1.02k | } |
687 | | |
688 | | #endif // ENABLE_DSD |