Coverage Report

Created: 2025-07-23 06:51

/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