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