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 
init_dsd_block(WavpackContext * wpc,WavpackMetadata * wpmd)30 int init_dsd_block (WavpackContext *wpc, WavpackMetadata *wpmd)
31 {
32     WavpackStream *wps = wpc->streams [wpc->current_stream];
33 
34     if (wpmd->byte_length < 2)
35         return FALSE;
36 
37     wps->dsd.byteptr = (unsigned char *)wpmd->data;
38     wps->dsd.endptr = wps->dsd.byteptr + wpmd->byte_length;
39 
40     if (*wps->dsd.byteptr > 31)
41         return FALSE;
42 
43     wpc->dsd_multiplier = 1U << *wps->dsd.byteptr++;
44     wps->dsd.mode = *wps->dsd.byteptr++;
45 
46     if (!wps->dsd.mode) {
47         if (wps->dsd.endptr - wps->dsd.byteptr != wps->wphdr.block_samples * (wps->wphdr.flags & MONO_DATA ? 1 : 2)) {
48             return FALSE;
49         }
50 
51         wps->dsd.ready = 1;
52         return TRUE;
53     }
54 
55     if (wps->dsd.mode == 1)
56         return init_dsd_block_fast (wps, wpmd);
57     else if (wps->dsd.mode == 3)
58         return init_dsd_block_high (wps, wpmd);
59     else
60         return FALSE;
61 }
62 
unpack_dsd_samples(WavpackContext * wpc,int32_t * buffer,uint32_t sample_count)63 int32_t unpack_dsd_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count)
64 {
65     WavpackStream *wps = wpc->streams [wpc->current_stream];
66     uint32_t flags = wps->wphdr.flags;
67 
68     // don't attempt to decode past the end of the block, but watch out for overflow!
69 
70     if (wps->sample_index + sample_count > GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples &&
71         (uint32_t) (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index) < sample_count)
72             sample_count = (uint32_t) (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index);
73 
74     if (GET_BLOCK_INDEX (wps->wphdr) > wps->sample_index || wps->wphdr.block_samples < sample_count)
75         wps->mute_error = TRUE;
76 
77     if (!wps->mute_error) {
78         if (!wps->dsd.mode) {
79             int total_samples = sample_count * ((flags & MONO_DATA) ? 1 : 2);
80             int32_t *bptr = buffer;
81 
82             if (wps->dsd.endptr - wps->dsd.byteptr < total_samples)
83                 total_samples = (int)(wps->dsd.endptr - wps->dsd.byteptr);
84 
85             while (total_samples--)
86                 wps->crc += (wps->crc << 1) + (*bptr++ = *wps->dsd.byteptr++);
87         }
88         else if (wps->dsd.mode == 1) {
89             if (!decode_fast (wps, buffer, sample_count))
90                 wps->mute_error = TRUE;
91         }
92         else if (!decode_high (wps, buffer, sample_count))
93             wps->mute_error = TRUE;
94     }
95 
96     if (wps->mute_error) {
97         int samples_to_null;
98         if (wpc->reduced_channels == 1 || wpc->config.num_channels == 1 || (flags & MONO_FLAG))
99             samples_to_null = sample_count;
100         else
101             samples_to_null = sample_count * 2;
102 
103         while (samples_to_null--)
104             *buffer++ = 0x55;
105 
106         wps->sample_index += sample_count;
107         return sample_count;
108     }
109 
110     if (flags & FALSE_STEREO) {
111         int32_t *dptr = buffer + sample_count * 2;
112         int32_t *sptr = buffer + sample_count;
113         int32_t c = sample_count;
114 
115         while (c--) {
116             *--dptr = *--sptr;
117             *--dptr = *sptr;
118         }
119     }
120 
121     wps->sample_index += sample_count;
122 
123     return sample_count;
124 }
125 
126 /*------------------------------------------------------------------------------------------------------------------------*/
127 
128 // #define DSD_BYTE_READY(low,high) (((low) >> 24) == ((high) >> 24))
129 // #define DSD_BYTE_READY(low,high) (!(((low) ^ (high)) >> 24))
130 #define DSD_BYTE_READY(low,high) (!(((low) ^ (high)) & 0xff000000))
131 
init_dsd_block_fast(WavpackStream * wps,WavpackMetadata * wpmd)132 static int init_dsd_block_fast (WavpackStream *wps, WavpackMetadata *wpmd)
133 {
134     unsigned char history_bits, max_probability, *lb_ptr;
135     int total_summed_probabilities = 0, bi, i;
136 
137     if (wps->dsd.byteptr == wps->dsd.endptr)
138         return FALSE;
139 
140     history_bits = *wps->dsd.byteptr++;
141 
142     if (wps->dsd.byteptr == wps->dsd.endptr || history_bits > MAX_HISTORY_BITS)
143         return FALSE;
144 
145     wps->dsd.history_bins = 1 << history_bits;
146 
147     free_dsd_tables (wps);
148     lb_ptr = wps->dsd.lookup_buffer = (unsigned char *)malloc (wps->dsd.history_bins * MAX_BYTES_PER_BIN);
149     wps->dsd.value_lookup = (unsigned char **)malloc (sizeof (*wps->dsd.value_lookup) * wps->dsd.history_bins);
150     memset (wps->dsd.value_lookup, 0, sizeof (*wps->dsd.value_lookup) * wps->dsd.history_bins);
151     wps->dsd.summed_probabilities = (uint16_t (*)[256])malloc (sizeof (*wps->dsd.summed_probabilities) * wps->dsd.history_bins);
152     wps->dsd.probabilities = (unsigned char (*)[256])malloc (sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins);
153 
154     max_probability = *wps->dsd.byteptr++;
155 
156     if (max_probability < 0xff) {
157         unsigned char *outptr = (unsigned char *) wps->dsd.probabilities;
158         unsigned char *outend = outptr + sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins;
159 
160         while (outptr < outend && wps->dsd.byteptr < wps->dsd.endptr) {
161             int code = *wps->dsd.byteptr++;
162 
163             if (code > max_probability) {
164                 int zcount = code - max_probability;
165 
166                 while (outptr < outend && zcount--)
167                     *outptr++ = 0;
168             }
169             else if (code)
170                 *outptr++ = code;
171             else
172                 break;
173         }
174 
175         if (outptr < outend || (wps->dsd.byteptr < wps->dsd.endptr && *wps->dsd.byteptr++))
176             return FALSE;
177     }
178     else if (wps->dsd.endptr - wps->dsd.byteptr > (int) sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins) {
179         memcpy (wps->dsd.probabilities, wps->dsd.byteptr, sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins);
180         wps->dsd.byteptr += sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins;
181     }
182     else
183         return FALSE;
184 
185     for (bi = 0; bi < wps->dsd.history_bins; ++bi) {
186         int32_t sum_values;
187 
188         for (sum_values = i = 0; i < 256; ++i)
189             wps->dsd.summed_probabilities [bi] [i] = sum_values += wps->dsd.probabilities [bi] [i];
190 
191         if (sum_values) {
192             if ((total_summed_probabilities += sum_values) > wps->dsd.history_bins * MAX_BYTES_PER_BIN)
193                 return FALSE;
194 
195             wps->dsd.value_lookup [bi] = lb_ptr;
196 
197             for (i = 0; i < 256; i++) {
198                 int c = wps->dsd.probabilities [bi] [i];
199 
200                 while (c--)
201                     *lb_ptr++ = i;
202             }
203         }
204     }
205 
206     if (wps->dsd.endptr - wps->dsd.byteptr < 4 || total_summed_probabilities > wps->dsd.history_bins * MAX_BYTES_PER_BIN)
207         return FALSE;
208 
209     for (i = 4; i--;)
210         wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++;
211 
212     wps->dsd.p0 = wps->dsd.p1 = 0;
213     wps->dsd.low = 0; wps->dsd.high = 0xffffffff;
214     wps->dsd.ready = 1;
215 
216     return TRUE;
217 }
218 
decode_fast(WavpackStream * wps,int32_t * output,int sample_count)219 static int decode_fast (WavpackStream *wps, int32_t *output, int sample_count)
220 {
221     int total_samples = sample_count;
222 
223     if (!(wps->wphdr.flags & MONO_DATA))
224         total_samples *= 2;
225 
226     while (total_samples--) {
227         unsigned int mult, index, code, i;
228 
229         if (!wps->dsd.summed_probabilities [wps->dsd.p0] [255])
230             return 0;
231 
232         mult = (wps->dsd.high - wps->dsd.low) / wps->dsd.summed_probabilities [wps->dsd.p0] [255];
233 
234         if (!mult) {
235             if (wps->dsd.endptr - wps->dsd.byteptr >= 4)
236                 for (i = 4; i--;)
237                     wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++;
238 
239             wps->dsd.low = 0;
240             wps->dsd.high = 0xffffffff;
241             mult = wps->dsd.high / wps->dsd.summed_probabilities [wps->dsd.p0] [255];
242 
243             if (!mult)
244                 return 0;
245         }
246 
247         index = (wps->dsd.value - wps->dsd.low) / mult;
248 
249         if (index >= wps->dsd.summed_probabilities [wps->dsd.p0] [255])
250             return 0;
251 
252         if ((*output++ = code = wps->dsd.value_lookup [wps->dsd.p0] [index]))
253             wps->dsd.low += wps->dsd.summed_probabilities [wps->dsd.p0] [code-1] * mult;
254 
255         wps->dsd.high = wps->dsd.low + wps->dsd.probabilities [wps->dsd.p0] [code] * mult - 1;
256         wps->crc += (wps->crc << 1) + code;
257 
258         if (wps->wphdr.flags & MONO_DATA)
259             wps->dsd.p0 = code & (wps->dsd.history_bins-1);
260         else {
261             wps->dsd.p0 = wps->dsd.p1;
262             wps->dsd.p1 = code & (wps->dsd.history_bins-1);
263         }
264 
265         while (DSD_BYTE_READY (wps->dsd.high, wps->dsd.low) && wps->dsd.byteptr < wps->dsd.endptr) {
266             wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++;
267             wps->dsd.high = (wps->dsd.high << 8) | 0xff;
268             wps->dsd.low <<= 8;
269         }
270     }
271 
272     return sample_count;
273 }
274 
275 /*------------------------------------------------------------------------------------------------------------------------*/
276 
277 #define PTABLE_BITS 8
278 #define PTABLE_BINS (1<<PTABLE_BITS)
279 #define PTABLE_MASK (PTABLE_BINS-1)
280 
281 #define UP   0x010000fe
282 #define DOWN 0x00010000
283 #define DECAY 8
284 
285 #define PRECISION 20
286 #define VALUE_ONE (1 << PRECISION)
287 #define PRECISION_USE 12
288 
289 #define RATE_S 20
290 
init_ptable(int * table,int rate_i,int rate_s)291 static void init_ptable (int *table, int rate_i, int rate_s)
292 {
293     int value = 0x808000, rate = rate_i << 8, c, i;
294 
295     for (c = (rate + 128) >> 8; c--;)
296         value += (DOWN - value) >> DECAY;
297 
298     for (i = 0; i < PTABLE_BINS/2; ++i) {
299         table [i] = value;
300         table [PTABLE_BINS-1-i] = 0x100ffff - value;
301 
302         if (value > 0x010000) {
303             rate += (rate * rate_s + 128) >> 8;
304 
305             for (c = (rate + 64) >> 7; c--;)
306                 value += (DOWN - value) >> DECAY;
307         }
308     }
309 }
310 
init_dsd_block_high(WavpackStream * wps,WavpackMetadata * wpmd)311 static int init_dsd_block_high (WavpackStream *wps, WavpackMetadata *wpmd)
312 {
313     uint32_t flags = wps->wphdr.flags;
314     int channel, rate_i, rate_s, i;
315 
316     if (wps->dsd.endptr - wps->dsd.byteptr < ((flags & MONO_DATA) ? 13 : 20))
317         return FALSE;
318 
319     rate_i = *wps->dsd.byteptr++;
320     rate_s = *wps->dsd.byteptr++;
321 
322     if (rate_s != RATE_S)
323         return FALSE;
324 
325     if (!wps->dsd.ptable)
326         wps->dsd.ptable = (int32_t *)malloc (PTABLE_BINS * sizeof (*wps->dsd.ptable));
327 
328     init_ptable (wps->dsd.ptable, rate_i, rate_s);
329 
330     for (channel = 0; channel < ((flags & MONO_DATA) ? 1 : 2); ++channel) {
331         DSDfilters *sp = wps->dsd.filters + channel;
332 
333         sp->filter1 = *wps->dsd.byteptr++ << (PRECISION - 8);
334         sp->filter2 = *wps->dsd.byteptr++ << (PRECISION - 8);
335         sp->filter3 = *wps->dsd.byteptr++ << (PRECISION - 8);
336         sp->filter4 = *wps->dsd.byteptr++ << (PRECISION - 8);
337         sp->filter5 = *wps->dsd.byteptr++ << (PRECISION - 8);
338         sp->filter6 = 0;
339         sp->factor = *wps->dsd.byteptr++ & 0xff;
340         sp->factor |= (*wps->dsd.byteptr++ << 8) & 0xff00;
341         sp->factor = (int32_t)((uint32_t)sp->factor << 16) >> 16;
342     }
343 
344     wps->dsd.high = 0xffffffff;
345     wps->dsd.low = 0x0;
346 
347     for (i = 4; i--;)
348         wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++;
349 
350     wps->dsd.ready = 1;
351 
352     return TRUE;
353 }
354 
decode_high(WavpackStream * wps,int32_t * output,int sample_count)355 static int decode_high (WavpackStream *wps, int32_t *output, int sample_count)
356 {
357     int total_samples = sample_count, stereo = (wps->wphdr.flags & MONO_DATA) ? 0 : 1;
358     DSDfilters *sp = wps->dsd.filters;
359 
360     while (total_samples--) {
361         int bitcount = 8;
362 
363         sp [0].value = sp [0].filter1 - sp [0].filter5 + ((sp [0].filter6 * sp [0].factor) >> 2);
364 
365         if (stereo)
366             sp [1].value = sp [1].filter1 - sp [1].filter5 + ((sp [1].filter6 * sp [1].factor) >> 2);
367 
368         while (bitcount--) {
369             int32_t *pp = wps->dsd.ptable + ((sp [0].value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK);
370             uint32_t split = wps->dsd.low + ((wps->dsd.high - wps->dsd.low) >> 8) * (*pp >> 16);
371 
372             if (wps->dsd.value <= split) {
373                 wps->dsd.high = split;
374                 *pp += (UP - *pp) >> DECAY;
375                 sp [0].filter0 = -1;
376             }
377             else {
378                 wps->dsd.low = split + 1;
379                 *pp += (DOWN - *pp) >> DECAY;
380                 sp [0].filter0 = 0;
381             }
382 
383             while (DSD_BYTE_READY (wps->dsd.high, wps->dsd.low) && wps->dsd.byteptr < wps->dsd.endptr) {
384                 wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++;
385                 wps->dsd.high = (wps->dsd.high << 8) | 0xff;
386                 wps->dsd.low <<= 8;
387             }
388 
389             sp [0].value += sp [0].filter6 * 8;
390             sp [0].byte = (sp [0].byte << 1) | (sp [0].filter0 & 1);
391             sp [0].factor += (((sp [0].value ^ sp [0].filter0) >> 31) | 1) & ((sp [0].value ^ (sp [0].value - (sp [0].filter6 * 16))) >> 31);
392             sp [0].filter1 += ((sp [0].filter0 & VALUE_ONE) - sp [0].filter1) >> 6;
393             sp [0].filter2 += ((sp [0].filter0 & VALUE_ONE) - sp [0].filter2) >> 4;
394             sp [0].filter3 += (sp [0].filter2 - sp [0].filter3) >> 4;
395             sp [0].filter4 += (sp [0].filter3 - sp [0].filter4) >> 4;
396             sp [0].value = (sp [0].filter4 - sp [0].filter5) >> 4;
397             sp [0].filter5 += sp [0].value;
398             sp [0].filter6 += (sp [0].value - sp [0].filter6) >> 3;
399             sp [0].value = sp [0].filter1 - sp [0].filter5 + ((sp [0].filter6 * sp [0].factor) >> 2);
400 
401             if (!stereo)
402                 continue;
403 
404             pp = wps->dsd.ptable + ((sp [1].value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK);
405             split = wps->dsd.low + ((wps->dsd.high - wps->dsd.low) >> 8) * (*pp >> 16);
406 
407             if (wps->dsd.value <= split) {
408                 wps->dsd.high = split;
409                 *pp += (UP - *pp) >> DECAY;
410                 sp [1].filter0 = -1;
411             }
412             else {
413                 wps->dsd.low = split + 1;
414                 *pp += (DOWN - *pp) >> DECAY;
415                 sp [1].filter0 = 0;
416             }
417 
418             while (DSD_BYTE_READY (wps->dsd.high, wps->dsd.low) && wps->dsd.byteptr < wps->dsd.endptr) {
419                 wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++;
420                 wps->dsd.high = (wps->dsd.high << 8) | 0xff;
421                 wps->dsd.low <<= 8;
422             }
423 
424             sp [1].value += sp [1].filter6 * 8;
425             sp [1].byte = (sp [1].byte << 1) | (sp [1].filter0 & 1);
426             sp [1].factor += (((sp [1].value ^ sp [1].filter0) >> 31) | 1) & ((sp [1].value ^ (sp [1].value - (sp [1].filter6 * 16))) >> 31);
427             sp [1].filter1 += ((sp [1].filter0 & VALUE_ONE) - sp [1].filter1) >> 6;
428             sp [1].filter2 += ((sp [1].filter0 & VALUE_ONE) - sp [1].filter2) >> 4;
429             sp [1].filter3 += (sp [1].filter2 - sp [1].filter3) >> 4;
430             sp [1].filter4 += (sp [1].filter3 - sp [1].filter4) >> 4;
431             sp [1].value = (sp [1].filter4 - sp [1].filter5) >> 4;
432             sp [1].filter5 += sp [1].value;
433             sp [1].filter6 += (sp [1].value - sp [1].filter6) >> 3;
434             sp [1].value = sp [1].filter1 - sp [1].filter5 + ((sp [1].filter6 * sp [1].factor) >> 2);
435         }
436 
437         wps->crc += (wps->crc << 1) + (*output++ = sp [0].byte & 0xff);
438         sp [0].factor -= (sp [0].factor + 512) >> 10;
439 
440         if (stereo) {
441             wps->crc += (wps->crc << 1) + (*output++ = wps->dsd.filters [1].byte & 0xff);
442             wps->dsd.filters [1].factor -= (wps->dsd.filters [1].factor + 512) >> 10;
443         }
444     }
445 
446     return sample_count;
447 }
448 
449 /*------------------------------------------------------------------------------------------------------------------------*/
450 
451 #if 0
452 
453 // 80 term DSD decimation filter
454 // < 1 dB down at 20 kHz
455 // > 108 dB stopband attenuation (fs/16)
456 
457 static const int32_t decm_filter [] = {
458     4, 17, 56, 147, 336, 693, 1320, 2359,
459     4003, 6502, 10170, 15392, 22623, 32389, 45275, 61920,
460     82994, 109174, 141119, 179431, 224621, 277068, 336983, 404373,
461     479004, 560384, 647741, 740025, 835917, 933849, 1032042, 1128551,
462     1221329, 1308290, 1387386, 1456680, 1514425, 1559128, 1589610, 1605059,
463     1605059, 1589610, 1559128, 1514425, 1456680, 1387386, 1308290, 1221329,
464     1128551, 1032042, 933849, 835917, 740025, 647741, 560384, 479004,
465     404373, 336983, 277068, 224621, 179431, 141119, 109174, 82994,
466     61920, 45275, 32389, 22623, 15392, 10170, 6502, 4003,
467     2359, 1320, 693, 336, 147, 56, 17, 4,
468 };
469 
470 #define NUM_FILTER_TERMS 80
471 
472 #else
473 
474 // 56 term decimation filter
475 // < 0.5 dB down at 20 kHz
476 // > 100 dB stopband attenuation (fs/12)
477 
478 static const int32_t decm_filter [] = {
479     4, 17, 56, 147, 336, 692, 1315, 2337,
480     3926, 6281, 9631, 14216, 20275, 28021, 37619, 49155,
481     62616, 77870, 94649, 112551, 131049, 149507, 167220, 183448,
482     197472, 208636, 216402, 220385, 220385, 216402, 208636, 197472,
483     183448, 167220, 149507, 131049, 112551, 94649, 77870, 62616,
484     49155, 37619, 28021, 20275, 14216, 9631, 6281, 3926,
485     2337, 1315, 692, 336, 147, 56, 17, 4,
486 };
487 
488 #define NUM_FILTER_TERMS 56
489 
490 #endif
491 
492 #define HISTORY_BYTES ((NUM_FILTER_TERMS+7)/8)
493 
494 typedef struct {
495     unsigned char delay [HISTORY_BYTES];
496 } DecimationChannel;
497 
498 typedef struct {
499     int32_t conv_tables [HISTORY_BYTES] [256];
500     DecimationChannel *chans;
501     int num_channels;
502 } DecimationContext;
503 
decimate_dsd_init(int num_channels)504 void *decimate_dsd_init (int num_channels)
505 {
506     DecimationContext *context = (DecimationContext *)malloc (sizeof (DecimationContext));
507     double filter_sum = 0, filter_scale;
508     int skipped_terms, i, j;
509 
510     if (!context)
511         return context;
512 
513     memset (context, 0, sizeof (*context));
514     context->num_channels = num_channels;
515     context->chans = (DecimationChannel *)malloc (num_channels * sizeof (DecimationChannel));
516 
517     if (!context->chans) {
518         free (context);
519         return NULL;
520     }
521 
522     for (i = 0; i < NUM_FILTER_TERMS; ++i)
523         filter_sum += decm_filter [i];
524 
525     filter_scale = ((1 << 23) - 1) / filter_sum * 16.0;
526     // fprintf (stderr, "convolution, %d terms, %f sum, %f scale\n", NUM_FILTER_TERMS, filter_sum, filter_scale);
527 
528     for (skipped_terms = i = 0; i < NUM_FILTER_TERMS; ++i) {
529         int scaled_term = (int) floor (decm_filter [i] * filter_scale + 0.5);
530 
531         if (scaled_term) {
532             for (j = 0; j < 256; ++j)
533                 if (j & (0x80 >> (i & 0x7)))
534                     context->conv_tables [i >> 3] [j] += scaled_term;
535                 else
536                     context->conv_tables [i >> 3] [j] -= scaled_term;
537         }
538         else
539             skipped_terms++;
540     }
541 
542     // fprintf (stderr, "%d terms skipped\n", skipped_terms);
543 
544     decimate_dsd_reset (context);
545 
546     return context;
547 }
548 
decimate_dsd_reset(void * decimate_context)549 void decimate_dsd_reset (void *decimate_context)
550 {
551     DecimationContext *context = (DecimationContext *) decimate_context;
552     int chan = 0, i;
553 
554     if (!context)
555         return;
556 
557     for (chan = 0; chan < context->num_channels; ++chan)
558         for (i = 0; i < HISTORY_BYTES; ++i)
559             context->chans [chan].delay [i] = 0x55;
560 }
561 
decimate_dsd_run(void * decimate_context,int32_t * samples,int num_samples)562 void decimate_dsd_run (void *decimate_context, int32_t *samples, int num_samples)
563 {
564     DecimationContext *context = (DecimationContext *) decimate_context;
565     int chan = 0;
566 
567     if (!context)
568         return;
569 
570     while (num_samples) {
571         DecimationChannel *sp = context->chans + chan;
572         int sum = 0;
573 
574 #if (HISTORY_BYTES == 10)
575         sum += context->conv_tables [0] [sp->delay [0] = sp->delay [1]];
576         sum += context->conv_tables [1] [sp->delay [1] = sp->delay [2]];
577         sum += context->conv_tables [2] [sp->delay [2] = sp->delay [3]];
578         sum += context->conv_tables [3] [sp->delay [3] = sp->delay [4]];
579         sum += context->conv_tables [4] [sp->delay [4] = sp->delay [5]];
580         sum += context->conv_tables [5] [sp->delay [5] = sp->delay [6]];
581         sum += context->conv_tables [6] [sp->delay [6] = sp->delay [7]];
582         sum += context->conv_tables [7] [sp->delay [7] = sp->delay [8]];
583         sum += context->conv_tables [8] [sp->delay [8] = sp->delay [9]];
584         sum += context->conv_tables [9] [sp->delay [9] = *samples];
585 #elif (HISTORY_BYTES == 7)
586         sum += context->conv_tables [0] [sp->delay [0] = sp->delay [1]];
587         sum += context->conv_tables [1] [sp->delay [1] = sp->delay [2]];
588         sum += context->conv_tables [2] [sp->delay [2] = sp->delay [3]];
589         sum += context->conv_tables [3] [sp->delay [3] = sp->delay [4]];
590         sum += context->conv_tables [4] [sp->delay [4] = sp->delay [5]];
591         sum += context->conv_tables [5] [sp->delay [5] = sp->delay [6]];
592         sum += context->conv_tables [6] [sp->delay [6] = *samples];
593 #else
594         int i;
595 
596         for (i = 0; i < HISTORY_BYTES-1; ++i)
597             sum += context->conv_tables [i] [sp->delay [i] = sp->delay [i+1]];
598 
599         sum += context->conv_tables [i] [sp->delay [i] = *samples];
600 #endif
601 
602         *samples++ = sum >> 4;
603 
604         if (++chan == context->num_channels) {
605             num_samples--;
606             chan = 0;
607         }
608     }
609 }
610 
decimate_dsd_destroy(void * decimate_context)611 void decimate_dsd_destroy (void *decimate_context)
612 {
613     DecimationContext *context = (DecimationContext *) decimate_context;
614 
615     if (!context)
616         return;
617 
618     if (context->chans)
619         free (context->chans);
620 
621     free (context);
622 }
623 
624 #endif      // ENABLE_DSD
625