1
#include "util/bit_reverse.h"
8
#define HTAPS 48 /* number of FIR constants */
9
#define FIFOSIZE 16 /* must be a power of two */
10
#define FIFOMASK (FIFOSIZE-1) /* bit mask for FIFO offsets */
11
#define CTABLES ((HTAPS+7)/8) /* number of "8 MACs" lookup tables */
13
#if FIFOSIZE*8 < HTAPS*2
14
#error "FIFOSIZE too small"
18
* Properties of this 96-tap lowpass filter when applied on a signal
19
* with sampling rate of 44100*64 Hz:
21
* () has a delay of 17 microseconds.
23
* () flat response up to 48 kHz
25
* () if you downsample afterwards by a factor of 8, the
26
* spectrum below 70 kHz is practically alias-free.
28
* () stopband rejection is about 160 dB
30
* The coefficient tables ("ctables") take only 6 Kibi Bytes and
31
* should fit into a modern processor's fast cache.
35
* The 2nd half (48 coeffs) of a 96-tap symmetric lowpass filter
37
static const double htaps[HTAPS] = {
48
-0.003284703416210726,
49
-0.008080250212687497,
53
-0.009007905078766049,
54
-0.006828859761015335,
55
-0.004535184322001496,
56
-0.002425035959059578,
57
-0.0006922187080790708,
58
0.0005700762133516592,
64
0.0008704322683580222,
65
0.0005381636200535649,
67
7.002968738383528e-05,
68
-5.279407053811266e-05,
69
-0.0001140625650874684,
70
-0.0001304796361231895,
71
-0.0001189970287491285,
72
-9.396247155265073e-05,
73
-6.577634378272832e-05,
74
-4.07492895872535e-05,
75
-2.17407957554587e-05,
76
-9.163058931391722e-06,
77
-2.017460145032201e-06,
78
1.249721855219005e-06,
79
2.166655190537392e-06,
80
1.930520892991082e-06,
81
1.319400334374195e-06,
82
7.410039764949091e-07,
83
3.423230509967409e-07,
84
1.244182214744588e-07,
88
static float ctables[CTABLES][256];
89
static int precalculated = 0;
91
static void precalc(void)
95
if (precalculated) return;
96
for (t=0; t<CTABLES; ++t) {
99
for (e=0; e<256; ++e) {
101
for (m=0; m<k; ++m) {
102
acc += (((e >> (7-m)) & 1)*2-1) * htaps[t*8+m];
104
ctables[CTABLES-1-t][e] = (float)acc;
112
unsigned char fifo[FIFOSIZE];
116
extern dsd2pcm_ctx* dsd2pcm_init(void)
119
if (!precalculated) precalc();
120
ptr = (dsd2pcm_ctx*) malloc(sizeof(dsd2pcm_ctx));
121
if (ptr) dsd2pcm_reset(ptr);
125
extern void dsd2pcm_destroy(dsd2pcm_ctx* ptr)
130
extern dsd2pcm_ctx* dsd2pcm_clone(dsd2pcm_ctx* ptr)
133
p2 = (dsd2pcm_ctx*) malloc(sizeof(dsd2pcm_ctx));
135
memcpy(p2,ptr,sizeof(dsd2pcm_ctx));
140
extern void dsd2pcm_reset(dsd2pcm_ctx* ptr)
143
for (i=0; i<FIFOSIZE; ++i)
144
ptr->fifo[i] = 0x69; /* my favorite silence pattern */
147
* This pattern "on repeat" makes a low energy 352.8 kHz tone
148
* and a high energy 1.0584 MHz tone which should be filtered
149
* out completely by any playback system --> silence
153
extern void dsd2pcm_translate(
156
const unsigned char *src, ptrdiff_t src_stride,
158
float *dst, ptrdiff_t dst_stride)
162
unsigned bite1, bite2;
167
while (samples-- > 0) {
168
bite1 = *src & 0xFFu;
169
if (lsbf) bite1 = bit_reverse(bite1);
170
ptr->fifo[ffp] = bite1; src += src_stride;
171
p = ptr->fifo + ((ffp-CTABLES) & FIFOMASK);
172
*p = bit_reverse(*p);
174
for (i=0; i<CTABLES; ++i) {
175
bite1 = ptr->fifo[(ffp -i) & FIFOMASK] & 0xFF;
176
bite2 = ptr->fifo[(ffp-(CTABLES*2-1)+i) & FIFOMASK] & 0xFF;
177
acc += ctables[i][bite1] + ctables[i][bite2];
179
*dst = (float)acc; dst += dst_stride;
180
ffp = (ffp + 1) & FIFOMASK;