Coverage Report

Created: 2023-06-07 06:30

/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