/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 - 2016 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 | 10.5k | { |
32 | 10.5k | if (wpmd->byte_length < 2) |
33 | 239 | return FALSE; |
34 | | |
35 | 10.3k | wps->dsd.byteptr = (unsigned char *)wpmd->data; |
36 | 10.3k | wps->dsd.endptr = wps->dsd.byteptr + wpmd->byte_length; |
37 | | |
38 | 10.3k | if (*wps->dsd.byteptr > 31) |
39 | 215 | return FALSE; |
40 | | |
41 | | // safe to cast away const on stream 0 only |
42 | 10.1k | if (!wps->stream_index) |
43 | 5.14k | ((WavpackContext *)wps->wpc)->dsd_multiplier = 1U << *wps->dsd.byteptr++; |
44 | 4.97k | else |
45 | 4.97k | wps->dsd.byteptr++; |
46 | | |
47 | 10.1k | wps->dsd.mode = *wps->dsd.byteptr++; |
48 | | |
49 | 10.1k | if (!wps->dsd.mode) { |
50 | 1.11k | if (wps->dsd.endptr - wps->dsd.byteptr != wps->wphdr.block_samples * (wps->wphdr.flags & MONO_DATA ? 1 : 2)) { |
51 | 246 | return FALSE; |
52 | 246 | } |
53 | | |
54 | 865 | wps->dsd.ready = 1; |
55 | 865 | return TRUE; |
56 | 1.11k | } |
57 | | |
58 | 9.00k | if (wps->dsd.mode == 1) |
59 | 4.27k | return init_dsd_block_fast (wps, wpmd); |
60 | 4.73k | else if (wps->dsd.mode == 3) |
61 | 4.48k | return init_dsd_block_high (wps, wpmd); |
62 | 249 | else |
63 | 249 | return FALSE; |
64 | 9.00k | } |
65 | | |
66 | | int32_t unpack_dsd_samples (WavpackStream *wps, int32_t *buffer, uint32_t sample_count) |
67 | 85.2k | { |
68 | 85.2k | 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 | 85.2k | if (wps->sample_index + sample_count > GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples && |
73 | 85.2k | (uint32_t) (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index) < sample_count) |
74 | 47.7k | sample_count = (uint32_t) (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index); |
75 | | |
76 | 85.2k | if (GET_BLOCK_INDEX (wps->wphdr) > wps->sample_index || wps->wphdr.block_samples < sample_count) |
77 | 7.00k | wps->mute_error = TRUE; |
78 | | |
79 | 85.2k | if (!wps->mute_error) { |
80 | 22.9k | if (!wps->dsd.mode) { |
81 | 1.09k | int total_samples = sample_count * ((flags & MONO_DATA) ? 1 : 2); |
82 | 1.09k | int32_t *bptr = buffer; |
83 | | |
84 | 1.09k | if (wps->dsd.endptr - wps->dsd.byteptr < total_samples) |
85 | 0 | total_samples = (int)(wps->dsd.endptr - wps->dsd.byteptr); |
86 | | |
87 | 15.1k | while (total_samples--) |
88 | 14.0k | wps->crc += (wps->crc << 1) + (*bptr++ = *wps->dsd.byteptr++); |
89 | 1.09k | } |
90 | 21.8k | else if (wps->dsd.mode == 1) { |
91 | 6.06k | if (!decode_fast (wps, buffer, sample_count)) |
92 | 966 | wps->mute_error = TRUE; |
93 | 6.06k | } |
94 | 15.8k | else if (!decode_high (wps, buffer, sample_count)) |
95 | 201 | 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 | 22.9k | if (wps->sample_index + sample_count == GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples && |
101 | 22.9k | !wps->mute_error && wps->crc != wps->wphdr.crc) |
102 | 2.51k | wps->mute_error = TRUE; |
103 | 22.9k | } |
104 | | |
105 | 85.2k | if (wps->mute_error) { |
106 | 65.9k | int samples_to_null; |
107 | 65.9k | if (wps->wpc->reduced_channels == 1 || wps->wpc->config.num_channels == 1 || (flags & MONO_FLAG)) |
108 | 5.67k | samples_to_null = sample_count; |
109 | 60.2k | else |
110 | 60.2k | samples_to_null = sample_count * 2; |
111 | | |
112 | 47.6M | while (samples_to_null--) |
113 | 47.5M | *buffer++ = 0x55; |
114 | | |
115 | 65.9k | wps->sample_index += sample_count; |
116 | 65.9k | return sample_count; |
117 | 65.9k | } |
118 | | |
119 | 19.3k | if (flags & FALSE_STEREO) { |
120 | 6.89k | int32_t *dptr = buffer + sample_count * 2; |
121 | 6.89k | int32_t *sptr = buffer + sample_count; |
122 | 6.89k | int32_t c = sample_count; |
123 | | |
124 | 8.03M | while (c--) { |
125 | 8.03M | *--dptr = *--sptr; |
126 | 8.03M | *--dptr = *sptr; |
127 | 8.03M | } |
128 | 6.89k | } |
129 | | |
130 | 19.3k | wps->sample_index += sample_count; |
131 | | |
132 | 19.3k | return sample_count; |
133 | 85.2k | } |
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 | 379M | #define DSD_BYTE_READY(low,high) (!(((low) ^ (high)) & 0xff000000)) |
140 | | |
141 | | static int init_dsd_block_fast (WavpackStream *wps, WavpackMetadata *wpmd) |
142 | 4.27k | { |
143 | 4.27k | unsigned char history_bits, max_probability, *lb_ptr; |
144 | 4.27k | int total_summed_probabilities = 0, bi, i; |
145 | | |
146 | 4.27k | if (wps->dsd.byteptr == wps->dsd.endptr) |
147 | 200 | return FALSE; |
148 | | |
149 | 4.07k | history_bits = *wps->dsd.byteptr++; |
150 | | |
151 | 4.07k | if (wps->dsd.byteptr == wps->dsd.endptr || history_bits > MAX_HISTORY_BITS) |
152 | 397 | return FALSE; |
153 | | |
154 | 3.67k | wps->dsd.history_bins = 1 << history_bits; |
155 | | |
156 | 3.67k | free_dsd_tables (wps); |
157 | 3.67k | lb_ptr = wps->dsd.lookup_buffer = (unsigned char *)malloc (wps->dsd.history_bins * MAX_BYTES_PER_BIN); |
158 | 3.67k | wps->dsd.value_lookup = (unsigned char **)malloc (sizeof (*wps->dsd.value_lookup) * wps->dsd.history_bins); |
159 | 3.67k | memset (wps->dsd.value_lookup, 0, sizeof (*wps->dsd.value_lookup) * wps->dsd.history_bins); |
160 | 3.67k | wps->dsd.summed_probabilities = (uint16_t (*)[256])malloc (sizeof (*wps->dsd.summed_probabilities) * wps->dsd.history_bins); |
161 | 3.67k | wps->dsd.probabilities = (unsigned char (*)[256])malloc (sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins); |
162 | | |
163 | 3.67k | max_probability = *wps->dsd.byteptr++; |
164 | | |
165 | 3.67k | if (max_probability < 0xff) { |
166 | 3.17k | unsigned char *outptr = (unsigned char *) wps->dsd.probabilities; |
167 | 3.17k | unsigned char *outend = outptr + sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins; |
168 | | |
169 | 48.3k | while (outptr < outend && wps->dsd.byteptr < wps->dsd.endptr) { |
170 | 45.3k | int code = *wps->dsd.byteptr++; |
171 | | |
172 | 45.3k | if (code > max_probability) { |
173 | 21.7k | int zcount = code - max_probability; |
174 | | |
175 | 1.94M | while (outptr < outend && zcount--) |
176 | 1.92M | *outptr++ = 0; |
177 | 21.7k | } |
178 | 23.6k | else if (code) |
179 | 23.4k | *outptr++ = code; |
180 | 224 | else |
181 | 224 | break; |
182 | 45.3k | } |
183 | | |
184 | 3.17k | if (outptr < outend || (wps->dsd.byteptr < wps->dsd.endptr && *wps->dsd.byteptr++)) |
185 | 494 | return FALSE; |
186 | 3.17k | } |
187 | 502 | else if (wps->dsd.endptr - wps->dsd.byteptr > (int) sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins) { |
188 | 218 | memcpy (wps->dsd.probabilities, wps->dsd.byteptr, sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins); |
189 | 218 | wps->dsd.byteptr += sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins; |
190 | 218 | } |
191 | 284 | else |
192 | 284 | return FALSE; |
193 | | |
194 | 10.2k | for (bi = 0; bi < wps->dsd.history_bins; ++bi) { |
195 | 7.71k | int32_t sum_values; |
196 | | |
197 | 1.98M | for (sum_values = i = 0; i < 256; ++i) |
198 | 1.97M | wps->dsd.summed_probabilities [bi] [i] = sum_values += wps->dsd.probabilities [bi] [i]; |
199 | | |
200 | 7.71k | if (sum_values) { |
201 | 4.51k | if ((total_summed_probabilities += sum_values) > wps->dsd.history_bins * MAX_BYTES_PER_BIN) |
202 | 396 | return FALSE; |
203 | | |
204 | 4.11k | wps->dsd.value_lookup [bi] = lb_ptr; |
205 | | |
206 | 1.05M | for (i = 0; i < 256; i++) { |
207 | 1.05M | int c = wps->dsd.probabilities [bi] [i]; |
208 | | |
209 | 2.72M | while (c--) |
210 | 1.67M | *lb_ptr++ = i; |
211 | 1.05M | } |
212 | 4.11k | } |
213 | 7.71k | } |
214 | | |
215 | 2.50k | if (wps->dsd.endptr - wps->dsd.byteptr < 4 || total_summed_probabilities > wps->dsd.history_bins * MAX_BYTES_PER_BIN) |
216 | 991 | return FALSE; |
217 | | |
218 | 7.56k | for (i = 4; i--;) |
219 | 6.05k | wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; |
220 | | |
221 | 1.51k | wps->dsd.p0 = wps->dsd.p1 = 0; |
222 | 1.51k | wps->dsd.low = 0; wps->dsd.high = 0xffffffff; |
223 | 1.51k | wps->dsd.ready = 1; |
224 | | |
225 | 1.51k | return TRUE; |
226 | 2.50k | } |
227 | | |
228 | | static int decode_fast (WavpackStream *wps, int32_t *output, int sample_count) |
229 | 6.06k | { |
230 | 6.06k | int total_samples = sample_count; |
231 | | |
232 | 6.06k | if (!(wps->wphdr.flags & MONO_DATA)) |
233 | 1.87k | total_samples *= 2; |
234 | | |
235 | 8.00M | while (total_samples--) { |
236 | 8.00M | unsigned int mult, index, code, i; |
237 | | |
238 | 8.00M | if (!wps->dsd.summed_probabilities [wps->dsd.p0] [255]) |
239 | 598 | return 0; |
240 | | |
241 | 8.00M | mult = (wps->dsd.high - wps->dsd.low) / wps->dsd.summed_probabilities [wps->dsd.p0] [255]; |
242 | | |
243 | 8.00M | if (!mult) { |
244 | 526k | if (wps->dsd.endptr - wps->dsd.byteptr >= 4) |
245 | 2.95k | for (i = 4; i--;) |
246 | 2.36k | wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; |
247 | | |
248 | 526k | wps->dsd.low = 0; |
249 | 526k | wps->dsd.high = 0xffffffff; |
250 | 526k | mult = wps->dsd.high / wps->dsd.summed_probabilities [wps->dsd.p0] [255]; |
251 | | |
252 | 526k | if (!mult) |
253 | 0 | return 0; |
254 | 526k | } |
255 | | |
256 | 8.00M | index = (wps->dsd.value - wps->dsd.low) / mult; |
257 | | |
258 | 8.00M | if (index >= wps->dsd.summed_probabilities [wps->dsd.p0] [255]) |
259 | 364 | return 0; |
260 | | |
261 | 8.00M | if ((*output++ = code = wps->dsd.value_lookup [wps->dsd.p0] [index])) |
262 | 5.43M | wps->dsd.low += wps->dsd.summed_probabilities [wps->dsd.p0] [code-1] * mult; |
263 | | |
264 | 8.00M | wps->dsd.high = wps->dsd.low + wps->dsd.probabilities [wps->dsd.p0] [code] * mult - 1; |
265 | 8.00M | wps->crc += (wps->crc << 1) + code; |
266 | | |
267 | 8.00M | if (wps->wphdr.flags & MONO_DATA) |
268 | 4.34M | wps->dsd.p0 = code & (wps->dsd.history_bins-1); |
269 | 3.65M | else { |
270 | 3.65M | wps->dsd.p0 = wps->dsd.p1; |
271 | 3.65M | wps->dsd.p1 = code & (wps->dsd.history_bins-1); |
272 | 3.65M | } |
273 | | |
274 | 8.00M | while (DSD_BYTE_READY (wps->dsd.high, wps->dsd.low) && wps->dsd.byteptr < wps->dsd.endptr) { |
275 | 7.37k | wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; |
276 | 7.37k | wps->dsd.high = (wps->dsd.high << 8) | 0xff; |
277 | 7.37k | wps->dsd.low <<= 8; |
278 | 7.37k | } |
279 | 8.00M | } |
280 | | |
281 | 5.10k | return sample_count; |
282 | 6.06k | } |
283 | | |
284 | | /*------------------------------------------------------------------------------------------------------------------------*/ |
285 | | |
286 | 182M | #define PTABLE_BITS 8 |
287 | 182M | #define PTABLE_BINS (1<<PTABLE_BITS) |
288 | 181M | #define PTABLE_MASK (PTABLE_BINS-1) |
289 | | |
290 | 180M | #define UP 0x010000fe |
291 | 11.9M | #define DOWN 0x00010000 |
292 | 191M | #define DECAY 8 |
293 | | |
294 | 545M | #define PRECISION 20 |
295 | 363M | #define VALUE_ONE (1 << PRECISION) |
296 | 181M | #define PRECISION_USE 12 |
297 | | |
298 | 4.11k | #define RATE_S 20 |
299 | | |
300 | | static void init_ptable (int *table, int rate_i, int rate_s) |
301 | 3.90k | { |
302 | 3.90k | int value = 0x808000, rate = rate_i << 8, c, i; |
303 | | |
304 | 621k | for (c = (rate + 128) >> 8; c--;) |
305 | 618k | value += (DOWN - value) >> DECAY; |
306 | | |
307 | 503k | for (i = 0; i < PTABLE_BINS/2; ++i) { |
308 | 499k | table [i] = value; |
309 | 499k | table [PTABLE_BINS-1-i] = 0x100ffff - value; |
310 | | |
311 | 499k | if (value > 0x010000) { |
312 | 95.7k | rate += (rate * rate_s + 128) >> 8; |
313 | | |
314 | 9.70M | for (c = (rate + 64) >> 7; c--;) |
315 | 9.61M | value += (DOWN - value) >> DECAY; |
316 | 95.7k | } |
317 | 499k | } |
318 | 3.90k | } |
319 | | |
320 | | static int init_dsd_block_high (WavpackStream *wps, WavpackMetadata *wpmd) |
321 | 4.48k | { |
322 | 4.48k | uint32_t flags = wps->wphdr.flags; |
323 | 4.48k | int channel, rate_i, rate_s, i; |
324 | | |
325 | 4.48k | if (wps->dsd.endptr - wps->dsd.byteptr < ((flags & MONO_DATA) ? 13 : 20)) |
326 | 367 | return FALSE; |
327 | | |
328 | 4.11k | rate_i = *wps->dsd.byteptr++; |
329 | 4.11k | rate_s = *wps->dsd.byteptr++; |
330 | | |
331 | 4.11k | if (rate_s != RATE_S) |
332 | 213 | return FALSE; |
333 | | |
334 | 3.90k | if (!wps->dsd.ptable) |
335 | 3.27k | wps->dsd.ptable = (int32_t *)malloc (PTABLE_BINS * sizeof (*wps->dsd.ptable)); |
336 | | |
337 | 3.90k | init_ptable (wps->dsd.ptable, rate_i, rate_s); |
338 | | |
339 | 9.02k | for (channel = 0; channel < ((flags & MONO_DATA) ? 1 : 2); ++channel) { |
340 | 5.12k | DSDfilters *sp = wps->dsd.filters + channel; |
341 | | |
342 | 5.12k | sp->filter1 = *wps->dsd.byteptr++ << (PRECISION - 8); |
343 | 5.12k | sp->filter2 = *wps->dsd.byteptr++ << (PRECISION - 8); |
344 | 5.12k | sp->filter3 = *wps->dsd.byteptr++ << (PRECISION - 8); |
345 | 5.12k | sp->filter4 = *wps->dsd.byteptr++ << (PRECISION - 8); |
346 | 5.12k | sp->filter5 = *wps->dsd.byteptr++ << (PRECISION - 8); |
347 | 5.12k | sp->filter6 = 0; |
348 | 5.12k | sp->factor = *wps->dsd.byteptr++ & 0xff; |
349 | 5.12k | sp->factor |= (*wps->dsd.byteptr++ << 8) & 0xff00; |
350 | 5.12k | sp->factor = (int32_t)((uint32_t)sp->factor << 16) >> 16; |
351 | 5.12k | } |
352 | | |
353 | 3.90k | wps->dsd.high = 0xffffffff; |
354 | 3.90k | wps->dsd.low = 0x0; |
355 | | |
356 | 19.5k | for (i = 4; i--;) |
357 | 15.6k | wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; |
358 | | |
359 | 3.90k | wps->dsd.ready = 1; |
360 | | |
361 | 3.90k | return TRUE; |
362 | 4.11k | } |
363 | | |
364 | | static int decode_high (WavpackStream *wps, int32_t *output, int sample_count) |
365 | 15.8k | { |
366 | 15.8k | int total_samples = sample_count, stereo = (wps->wphdr.flags & MONO_DATA) ? 0 : 1; |
367 | 15.8k | DSDfilters *sp = wps->dsd.filters; |
368 | | |
369 | 16.3M | while (total_samples--) { |
370 | 16.3M | int bitcount = 8; |
371 | | |
372 | 16.3M | sp [0].value = sp [0].filter1 - sp [0].filter5 + ((sp [0].filter6 * sp [0].factor) >> 2); |
373 | | |
374 | 16.3M | if (stereo) |
375 | 6.41M | sp [1].value = sp [1].filter1 - sp [1].filter5 + ((sp [1].filter6 * sp [1].factor) >> 2); |
376 | | |
377 | 146M | while (bitcount--) { |
378 | 130M | int32_t *pp = wps->dsd.ptable + ((sp [0].value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK); |
379 | 130M | uint32_t split = wps->dsd.low + ((wps->dsd.high - wps->dsd.low) >> 8) * (*pp >> 16); |
380 | | |
381 | 130M | if (wps->dsd.value <= split) { |
382 | 129M | wps->dsd.high = split; |
383 | 129M | *pp += (UP - *pp) >> DECAY; |
384 | 129M | sp [0].filter0 = -1; |
385 | 129M | } |
386 | 1.20M | else { |
387 | 1.20M | wps->dsd.low = split + 1; |
388 | 1.20M | *pp += (DOWN - *pp) >> DECAY; |
389 | 1.20M | sp [0].filter0 = 0; |
390 | 1.20M | } |
391 | | |
392 | 130M | while (DSD_BYTE_READY (wps->dsd.high, wps->dsd.low) && wps->dsd.byteptr < wps->dsd.endptr) { |
393 | 15.5k | wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; |
394 | 15.5k | wps->dsd.high = (wps->dsd.high << 8) | 0xff; |
395 | 15.5k | wps->dsd.low <<= 8; |
396 | 15.5k | } |
397 | | |
398 | 130M | sp [0].value += sp [0].filter6 * 8; |
399 | 130M | sp [0].byte = (sp [0].byte << 1) | (sp [0].filter0 & 1); |
400 | 130M | sp [0].factor += (((sp [0].value ^ sp [0].filter0) >> 31) | 1) & ((sp [0].value ^ (sp [0].value - (sp [0].filter6 * 16))) >> 31); |
401 | 130M | sp [0].filter1 += ((sp [0].filter0 & VALUE_ONE) - sp [0].filter1) >> 6; |
402 | 130M | sp [0].filter2 += ((sp [0].filter0 & VALUE_ONE) - sp [0].filter2) >> 4; |
403 | 130M | sp [0].filter3 += (sp [0].filter2 - sp [0].filter3) >> 4; |
404 | 130M | sp [0].filter4 += (sp [0].filter3 - sp [0].filter4) >> 4; |
405 | 130M | sp [0].value = (sp [0].filter4 - sp [0].filter5) >> 4; |
406 | 130M | sp [0].filter5 += sp [0].value; |
407 | 130M | sp [0].filter6 += (sp [0].value - sp [0].filter6) >> 3; |
408 | 130M | sp [0].value = sp [0].filter1 - sp [0].filter5 + ((sp [0].filter6 * sp [0].factor) >> 2); |
409 | | |
410 | 130M | if (!stereo) |
411 | 79.0M | continue; |
412 | | |
413 | 51.3M | pp = wps->dsd.ptable + ((sp [1].value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK); |
414 | 51.3M | split = wps->dsd.low + ((wps->dsd.high - wps->dsd.low) >> 8) * (*pp >> 16); |
415 | | |
416 | 51.3M | if (wps->dsd.value <= split) { |
417 | 50.8M | wps->dsd.high = split; |
418 | 50.8M | *pp += (UP - *pp) >> DECAY; |
419 | 50.8M | sp [1].filter0 = -1; |
420 | 50.8M | } |
421 | 503k | else { |
422 | 503k | wps->dsd.low = split + 1; |
423 | 503k | *pp += (DOWN - *pp) >> DECAY; |
424 | 503k | sp [1].filter0 = 0; |
425 | 503k | } |
426 | | |
427 | 51.3M | while (DSD_BYTE_READY (wps->dsd.high, wps->dsd.low) && wps->dsd.byteptr < wps->dsd.endptr) { |
428 | 9.66k | wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; |
429 | 9.66k | wps->dsd.high = (wps->dsd.high << 8) | 0xff; |
430 | 9.66k | wps->dsd.low <<= 8; |
431 | 9.66k | } |
432 | | |
433 | 51.3M | sp [1].value += sp [1].filter6 * 8; |
434 | 51.3M | sp [1].byte = (sp [1].byte << 1) | (sp [1].filter0 & 1); |
435 | 51.3M | sp [1].factor += (((sp [1].value ^ sp [1].filter0) >> 31) | 1) & ((sp [1].value ^ (sp [1].value - (sp [1].filter6 * 16))) >> 31); |
436 | 51.3M | sp [1].filter1 += ((sp [1].filter0 & VALUE_ONE) - sp [1].filter1) >> 6; |
437 | 51.3M | sp [1].filter2 += ((sp [1].filter0 & VALUE_ONE) - sp [1].filter2) >> 4; |
438 | 51.3M | sp [1].filter3 += (sp [1].filter2 - sp [1].filter3) >> 4; |
439 | 51.3M | sp [1].filter4 += (sp [1].filter3 - sp [1].filter4) >> 4; |
440 | 51.3M | sp [1].value = (sp [1].filter4 - sp [1].filter5) >> 4; |
441 | 51.3M | sp [1].filter5 += sp [1].value; |
442 | 51.3M | sp [1].filter6 += (sp [1].value - sp [1].filter6) >> 3; |
443 | 51.3M | sp [1].value = sp [1].filter1 - sp [1].filter5 + ((sp [1].filter6 * sp [1].factor) >> 2); |
444 | 51.3M | } |
445 | | |
446 | 16.3M | wps->crc += (wps->crc << 1) + (*output++ = sp [0].byte & 0xff); |
447 | 16.3M | sp [0].factor -= (sp [0].factor + 512) >> 10; |
448 | | |
449 | 16.3M | if (stereo) { |
450 | 6.41M | wps->crc += (wps->crc << 1) + (*output++ = wps->dsd.filters [1].byte & 0xff); |
451 | 6.41M | wps->dsd.filters [1].factor -= (wps->dsd.filters [1].factor + 512) >> 10; |
452 | 6.41M | } |
453 | 16.3M | } |
454 | | |
455 | 15.8k | return sample_count; |
456 | 15.8k | } |
457 | | |
458 | | /*------------------------------------------------------------------------------------------------------------------------*/ |
459 | | |
460 | | #if 0 |
461 | | |
462 | | // 80 term DSD decimation filter |
463 | | // < 1 dB down at 20 kHz |
464 | | // > 108 dB stopband attenuation (fs/16) |
465 | | |
466 | | static const int32_t decm_filter [] = { |
467 | | 4, 17, 56, 147, 336, 693, 1320, 2359, |
468 | | 4003, 6502, 10170, 15392, 22623, 32389, 45275, 61920, |
469 | | 82994, 109174, 141119, 179431, 224621, 277068, 336983, 404373, |
470 | | 479004, 560384, 647741, 740025, 835917, 933849, 1032042, 1128551, |
471 | | 1221329, 1308290, 1387386, 1456680, 1514425, 1559128, 1589610, 1605059, |
472 | | 1605059, 1589610, 1559128, 1514425, 1456680, 1387386, 1308290, 1221329, |
473 | | 1128551, 1032042, 933849, 835917, 740025, 647741, 560384, 479004, |
474 | | 404373, 336983, 277068, 224621, 179431, 141119, 109174, 82994, |
475 | | 61920, 45275, 32389, 22623, 15392, 10170, 6502, 4003, |
476 | | 2359, 1320, 693, 336, 147, 56, 17, 4, |
477 | | }; |
478 | | |
479 | | #define NUM_FILTER_TERMS 80 |
480 | | |
481 | | #else |
482 | | |
483 | | // 56 term decimation filter |
484 | | // < 0.5 dB down at 20 kHz |
485 | | // > 100 dB stopband attenuation (fs/12) |
486 | | |
487 | | static const int32_t decm_filter [] = { |
488 | | 4, 17, 56, 147, 336, 692, 1315, 2337, |
489 | | 3926, 6281, 9631, 14216, 20275, 28021, 37619, 49155, |
490 | | 62616, 77870, 94649, 112551, 131049, 149507, 167220, 183448, |
491 | | 197472, 208636, 216402, 220385, 220385, 216402, 208636, 197472, |
492 | | 183448, 167220, 149507, 131049, 112551, 94649, 77870, 62616, |
493 | | 49155, 37619, 28021, 20275, 14216, 9631, 6281, 3926, |
494 | | 2337, 1315, 692, 336, 147, 56, 17, 4, |
495 | | }; |
496 | | |
497 | 2.60M | #define NUM_FILTER_TERMS 56 |
498 | | |
499 | | #endif |
500 | | |
501 | 2.49M | #define HISTORY_BYTES ((NUM_FILTER_TERMS+7)/8) |
502 | | |
503 | | typedef struct { |
504 | | unsigned char delay [HISTORY_BYTES]; |
505 | | } DecimationChannel; |
506 | | |
507 | | typedef struct { |
508 | | int32_t conv_tables [HISTORY_BYTES] [256]; |
509 | | DecimationChannel *chans; |
510 | | int num_channels, reset; |
511 | | } DecimationContext; |
512 | | |
513 | | static void extrapolate_pcm (int32_t *samples, int samples_to_extrapolate, int samples_visible, int num_channels); |
514 | | |
515 | | void *decimate_dsd_init (int num_channels) |
516 | 978 | { |
517 | 978 | DecimationContext *context = (DecimationContext *)malloc (sizeof (DecimationContext)); |
518 | 978 | double filter_sum = 0, filter_scale; |
519 | 978 | int skipped_terms, i, j; |
520 | | |
521 | 978 | if (!context) |
522 | 0 | return context; |
523 | | |
524 | 978 | memset (context, 0, sizeof (*context)); |
525 | 978 | context->num_channels = num_channels; |
526 | 978 | context->chans = (DecimationChannel *)malloc (num_channels * sizeof (DecimationChannel)); |
527 | | |
528 | 978 | if (!context->chans) { |
529 | 0 | free (context); |
530 | 0 | return NULL; |
531 | 0 | } |
532 | | |
533 | 55.7k | for (i = 0; i < NUM_FILTER_TERMS; ++i) |
534 | 54.7k | filter_sum += decm_filter [i]; |
535 | | |
536 | 978 | filter_scale = ((1 << 23) - 1) / filter_sum * 16.0; |
537 | | // fprintf (stderr, "convolution, %d terms, %f sum, %f scale\n", NUM_FILTER_TERMS, filter_sum, filter_scale); |
538 | | |
539 | 55.7k | for (skipped_terms = i = 0; i < NUM_FILTER_TERMS; ++i) { |
540 | 54.7k | int scaled_term = (int) floor (decm_filter [i] * filter_scale + 0.5); |
541 | | |
542 | 54.7k | if (scaled_term) { |
543 | 14.0M | for (j = 0; j < 256; ++j) |
544 | 14.0M | if (j & (0x80 >> (i & 0x7))) |
545 | 7.01M | context->conv_tables [i >> 3] [j] += scaled_term; |
546 | 7.01M | else |
547 | 7.01M | context->conv_tables [i >> 3] [j] -= scaled_term; |
548 | 54.7k | } |
549 | 0 | else |
550 | 0 | skipped_terms++; |
551 | 54.7k | } |
552 | | |
553 | | // fprintf (stderr, "%d terms skipped\n", skipped_terms); |
554 | | |
555 | 978 | decimate_dsd_reset (context); |
556 | | |
557 | 978 | return context; |
558 | 978 | } |
559 | | |
560 | | void decimate_dsd_reset (void *decimate_context) |
561 | 1.51k | { |
562 | 1.51k | DecimationContext *context = (DecimationContext *) decimate_context; |
563 | 1.51k | int chan = 0, i; |
564 | | |
565 | 1.51k | if (!context) |
566 | 0 | return; |
567 | | |
568 | 312k | for (chan = 0; chan < context->num_channels; ++chan) |
569 | 2.49M | for (i = 0; i < HISTORY_BYTES; ++i) |
570 | 2.17M | context->chans [chan].delay [i] = 0x55; |
571 | | |
572 | 1.51k | context->reset = 1; |
573 | 1.51k | } |
574 | | |
575 | | void decimate_dsd_run (void *decimate_context, int32_t *samples, int num_samples) |
576 | 23.8k | { |
577 | 23.8k | DecimationContext *context = (DecimationContext *) decimate_context; |
578 | 23.8k | int chan = 0, scount = num_samples; |
579 | 23.8k | int32_t *samptr = samples; |
580 | | |
581 | 23.8k | if (!context) |
582 | 0 | return; |
583 | | |
584 | 150M | while (scount) { |
585 | 150M | DecimationChannel *sp = context->chans + chan; |
586 | 150M | int32_t sum = 0; |
587 | | |
588 | | #if (HISTORY_BYTES == 10) |
589 | | sum += context->conv_tables [0] [sp->delay [0] = sp->delay [1]]; |
590 | | sum += context->conv_tables [1] [sp->delay [1] = sp->delay [2]]; |
591 | | sum += context->conv_tables [2] [sp->delay [2] = sp->delay [3]]; |
592 | | sum += context->conv_tables [3] [sp->delay [3] = sp->delay [4]]; |
593 | | sum += context->conv_tables [4] [sp->delay [4] = sp->delay [5]]; |
594 | | sum += context->conv_tables [5] [sp->delay [5] = sp->delay [6]]; |
595 | | sum += context->conv_tables [6] [sp->delay [6] = sp->delay [7]]; |
596 | | sum += context->conv_tables [7] [sp->delay [7] = sp->delay [8]]; |
597 | | sum += context->conv_tables [8] [sp->delay [8] = sp->delay [9]]; |
598 | | sum += context->conv_tables [9] [sp->delay [9] = *samptr]; |
599 | | #elif (HISTORY_BYTES == 7) |
600 | 150M | sum += context->conv_tables [0] [sp->delay [0] = sp->delay [1]]; |
601 | 150M | sum += context->conv_tables [1] [sp->delay [1] = sp->delay [2]]; |
602 | 150M | sum += context->conv_tables [2] [sp->delay [2] = sp->delay [3]]; |
603 | 150M | sum += context->conv_tables [3] [sp->delay [3] = sp->delay [4]]; |
604 | 150M | sum += context->conv_tables [4] [sp->delay [4] = sp->delay [5]]; |
605 | 150M | sum += context->conv_tables [5] [sp->delay [5] = sp->delay [6]]; |
606 | 150M | sum += context->conv_tables [6] [sp->delay [6] = *samptr]; |
607 | | #else |
608 | | int i; |
609 | | |
610 | | for (i = 0; i < HISTORY_BYTES-1; ++i) |
611 | | sum += context->conv_tables [i] [sp->delay [i] = sp->delay [i+1]]; |
612 | | |
613 | | sum += context->conv_tables [i] [sp->delay [i] = *samptr]; |
614 | | #endif |
615 | | |
616 | 150M | *samptr++ = (sum + 8) >> 4; |
617 | | |
618 | 150M | if (++chan == context->num_channels) { |
619 | 22.5M | scount--; |
620 | 22.5M | chan = 0; |
621 | 22.5M | } |
622 | 150M | } |
623 | | |
624 | 23.8k | if (context->reset) { |
625 | 1.46k | extrapolate_pcm (samples, HISTORY_BYTES - 1, num_samples, context->num_channels); |
626 | 1.46k | context->reset = 0; |
627 | 1.46k | } |
628 | 23.8k | } |
629 | | |
630 | | // This function is used to linearly extrapolate some samples at the beginning of the first |
631 | | // decoded frame because we don't have the previous DSD data to prefill the decimation filter. |
632 | | // Currently we only extrapolate at the beginning of the file because we have an implicit |
633 | | // delay in the decimation. It might be better, but more complicated, to have zero delay in |
634 | | // the decimation and split the extrapolated samples between the beginning and end of the |
635 | | // file. |
636 | | |
637 | | static void extrapolate_pcm (int32_t *samples, int samples_to_extrapolate, int samples_visible, int num_channels) |
638 | 1.46k | { |
639 | 1.46k | int scount = num_channels, min_period = 5, max_period = 10; |
640 | | |
641 | 1.46k | if (samples_visible < samples_to_extrapolate + min_period * 2) |
642 | 627 | return; |
643 | | |
644 | 842 | if (samples_visible < samples_to_extrapolate + max_period * 2) |
645 | 128 | max_period = (samples_visible - samples_to_extrapolate) / 2; |
646 | | |
647 | 134k | while (scount--) { |
648 | 133k | float left_value_ave = 0.0, right_value_ave = 0.0, slope; |
649 | 133k | int period, i; |
650 | | |
651 | 337k | for (period = min_period; period <= max_period; ++period) { |
652 | 204k | float left_ratio = (samples_to_extrapolate + period / 2.0F) / period, right_ratio = (period / 2.0F) / period; |
653 | 204k | int32_t *sam1 = samples + samples_to_extrapolate * num_channels, *sam2 = sam1 + period * num_channels; |
654 | 204k | float ave1 = 0.0, ave2 = 0.0; |
655 | 204k | int i; |
656 | | |
657 | 1.43M | for (i = 0; i < period; ++i) { |
658 | 1.23M | ave1 += (float) sam1 [i * num_channels] / period; |
659 | 1.23M | ave2 += (float) sam2 [i * num_channels] / period; |
660 | 1.23M | } |
661 | | |
662 | 204k | left_value_ave += ave1 + (ave1 - ave2) * left_ratio; |
663 | 204k | right_value_ave += ave1 + (ave1 - ave2) * right_ratio; |
664 | 204k | } |
665 | | |
666 | 133k | right_value_ave /= (max_period - min_period + 1); |
667 | 133k | left_value_ave /= (max_period - min_period + 1); |
668 | 133k | slope = (right_value_ave - left_value_ave) / (samples_to_extrapolate - 1); |
669 | | |
670 | 936k | for (i = 0; i < samples_to_extrapolate; ++i) |
671 | 802k | samples [i * num_channels] = (int32_t) (left_value_ave + i * slope + 0.5); |
672 | | |
673 | 133k | samples++; |
674 | 133k | } |
675 | 842 | } |
676 | | |
677 | | void decimate_dsd_destroy (void *decimate_context) |
678 | 978 | { |
679 | 978 | DecimationContext *context = (DecimationContext *) decimate_context; |
680 | | |
681 | 978 | if (!context) |
682 | 0 | return; |
683 | | |
684 | 978 | if (context->chans) |
685 | 978 | free (context->chans); |
686 | | |
687 | 978 | free (context); |
688 | 978 | } |
689 | | |
690 | | #endif // ENABLE_DSD |