~ubuntu-branches/ubuntu/utopic/mpd/utopic-proposed

« back to all changes in this revision

Viewing changes to src/dsd2pcm/dsd2pcm.c

  • Committer: Package Import Robot
  • Author(s): Steve Kowalik
  • Date: 2013-11-12 18:17:40 UTC
  • mfrom: (2.2.36 sid)
  • Revision ID: package-import@ubuntu.com-20131112181740-72aa4zihehoobedp
Tags: 0.18.3-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - Add libmp3lame-dev to Build-Depends, and enable LAME.
  - Read the user for the daemon from the config file in the init script.
  - Move avahi-daemon from Suggests to Recommends.
  - Added apport hook to include user configuration file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include "util/bit_reverse.h"
2
 
 
3
 
#include <stdlib.h>
4
 
#include <string.h>
5
 
 
6
 
#include "dsd2pcm.h"
7
 
 
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 */
12
 
 
13
 
#if FIFOSIZE*8 < HTAPS*2
14
 
#error "FIFOSIZE too small"
15
 
#endif
16
 
 
17
 
/*
18
 
 * Properties of this 96-tap lowpass filter when applied on a signal
19
 
 * with sampling rate of 44100*64 Hz:
20
 
 *
21
 
 * () has a delay of 17 microseconds.
22
 
 *
23
 
 * () flat response up to 48 kHz
24
 
 *
25
 
 * () if you downsample afterwards by a factor of 8, the
26
 
 *    spectrum below 70 kHz is practically alias-free.
27
 
 *
28
 
 * () stopband rejection is about 160 dB
29
 
 *
30
 
 * The coefficient tables ("ctables") take only 6 Kibi Bytes and
31
 
 * should fit into a modern processor's fast cache.
32
 
 */
33
 
 
34
 
/*
35
 
 * The 2nd half (48 coeffs) of a 96-tap symmetric lowpass filter
36
 
 */
37
 
static const double htaps[HTAPS] = {
38
 
  0.09950731974056658,
39
 
  0.09562845727714668,
40
 
  0.08819647126516944,
41
 
  0.07782552527068175,
42
 
  0.06534876523171299,
43
 
  0.05172629311427257,
44
 
  0.0379429484910187,
45
 
  0.02490921351762261,
46
 
  0.0133774746265897,
47
 
  0.003883043418804416,
48
 
 -0.003284703416210726,
49
 
 -0.008080250212687497,
50
 
 -0.01067241812471033,
51
 
 -0.01139427235000863,
52
 
 -0.0106813877974587,
53
 
 -0.009007905078766049,
54
 
 -0.006828859761015335,
55
 
 -0.004535184322001496,
56
 
 -0.002425035959059578,
57
 
 -0.0006922187080790708,
58
 
  0.0005700762133516592,
59
 
  0.001353838005269448,
60
 
  0.001713709169690937,
61
 
  0.001742046839472948,
62
 
  0.001545601648013235,
63
 
  0.001226696225277855,
64
 
  0.0008704322683580222,
65
 
  0.0005381636200535649,
66
 
  0.000266446345425276,
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,
85
 
  3.130441005359396e-08
86
 
};
87
 
 
88
 
static float ctables[CTABLES][256];
89
 
static int precalculated = 0;
90
 
 
91
 
static void precalc(void)
92
 
{
93
 
        int t, e, m, k;
94
 
        double acc;
95
 
        if (precalculated) return;
96
 
        for (t=0; t<CTABLES; ++t) {
97
 
                k = HTAPS - t*8;
98
 
                if (k>8) k=8;
99
 
                for (e=0; e<256; ++e) {
100
 
                        acc = 0.0;
101
 
                        for (m=0; m<k; ++m) {
102
 
                                acc += (((e >> (7-m)) & 1)*2-1) * htaps[t*8+m];
103
 
                        }
104
 
                        ctables[CTABLES-1-t][e] = (float)acc;
105
 
                }
106
 
        }
107
 
        precalculated = 1;
108
 
}
109
 
 
110
 
struct dsd2pcm_ctx_s
111
 
{
112
 
        unsigned char fifo[FIFOSIZE];
113
 
        unsigned fifopos;
114
 
};
115
 
 
116
 
extern dsd2pcm_ctx* dsd2pcm_init(void)
117
 
{
118
 
        dsd2pcm_ctx* ptr;
119
 
        if (!precalculated) precalc();
120
 
        ptr = (dsd2pcm_ctx*) malloc(sizeof(dsd2pcm_ctx));
121
 
        if (ptr) dsd2pcm_reset(ptr);
122
 
        return ptr;
123
 
}
124
 
 
125
 
extern void dsd2pcm_destroy(dsd2pcm_ctx* ptr)
126
 
{
127
 
        free(ptr);
128
 
}
129
 
 
130
 
extern dsd2pcm_ctx* dsd2pcm_clone(dsd2pcm_ctx* ptr)
131
 
{
132
 
        dsd2pcm_ctx* p2;
133
 
        p2 = (dsd2pcm_ctx*) malloc(sizeof(dsd2pcm_ctx));
134
 
        if (p2) {
135
 
                memcpy(p2,ptr,sizeof(dsd2pcm_ctx));
136
 
        }
137
 
        return p2;
138
 
}
139
 
 
140
 
extern void dsd2pcm_reset(dsd2pcm_ctx* ptr)
141
 
{
142
 
        int i;
143
 
        for (i=0; i<FIFOSIZE; ++i)
144
 
                ptr->fifo[i] = 0x69; /* my favorite silence pattern */
145
 
        ptr->fifopos = 0;
146
 
        /* 0x69 = 01101001
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
150
 
         */
151
 
}
152
 
 
153
 
extern void dsd2pcm_translate(
154
 
        dsd2pcm_ctx* ptr,
155
 
        size_t samples,
156
 
        const unsigned char *src, ptrdiff_t src_stride,
157
 
        int lsbf,
158
 
        float *dst, ptrdiff_t dst_stride)
159
 
{
160
 
        unsigned ffp;
161
 
        unsigned i;
162
 
        unsigned bite1, bite2;
163
 
        unsigned char* p;
164
 
        double acc;
165
 
        ffp = ptr->fifopos;
166
 
        lsbf = lsbf ? 1 : 0;
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);
173
 
                acc = 0;
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];
178
 
                }
179
 
                *dst = (float)acc; dst += dst_stride;
180
 
                ffp = (ffp + 1) & FIFOMASK;
181
 
        }
182
 
        ptr->fifopos = ffp;
183
 
}
184