1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#include <iostream>
#include <vector>
#include <cstring>
#include "dsd2pcm.hpp"
#include "noiseshape.hpp"
namespace {
const float my_ns_coeffs[] = {
// b1 b2 a1 a2
-1.62666423, 0.79410094, 0.61367127, 0.23311013, // section 1
-1.44870017, 0.54196219, 0.03373857, 0.70316556 // section 2
};
const int my_ns_soscount = sizeof(my_ns_coeffs)/(sizeof(my_ns_coeffs[0])*4);
inline long myround(float x)
{
return static_cast<long>(x + (x>=0 ? 0.5f : -0.5f));
}
template<typename T>
struct id { typedef T type; };
template<typename T>
inline T clip(
typename id<T>::type min,
T v,
typename id<T>::type max)
{
if (v<min) return min;
if (v>max) return max;
return v;
}
inline void write_intel16(unsigned char * ptr, unsigned word)
{
ptr[0] = word & 0xFF;
ptr[1] = (word >> 8) & 0xFF;
}
inline void write_intel24(unsigned char * ptr, unsigned long word)
{
ptr[0] = word & 0xFF;
ptr[1] = (word >> 8) & 0xFF;
ptr[2] = (word >> 16) & 0xFF;
}
} // anonymous namespace
using std::vector;
using std::cin;
using std::cout;
using std::cerr;
int main(int argc, char *argv[])
{
const int block = 16384;
int channels = -1;
int lsbitfirst = -1;
int bits = -1;
if (argc==4) {
if ('1'<=argv[1][0] && argv[1][0]<='9') channels = 1 + (argv[1][0]-'1');
if (argv[2][0]=='m' || argv[2][0]=='M') lsbitfirst=0;
if (argv[2][0]=='l' || argv[2][0]=='L') lsbitfirst=1;
if (!strcmp(argv[3],"16")) bits = 16;
if (!strcmp(argv[3],"24")) bits = 24;
}
if (channels<1 || lsbitfirst<0 || bits<0) {
cerr << "\n"
"DSD2PCM filter (raw DSD64 --> 352 kHz raw PCM)\n"
"(c) 2009 Sebastian Gesemann\n\n"
"(filter as in \"reads data from stdin and writes to stdout\")\n\n"
"Syntax: dsd2pcm <channels> <bitorder> <bitdepth>\n"
"channels = 1,2,3,...,9 (number of channels in DSD stream)\n"
"bitorder = L (lsb first), M (msb first) (DSD stream option)\n"
"bitdepth = 16 or 24 (intel byte order, output option)\n\n"
"Note: At 16 bits/sample a noise shaper kicks in that can preserve\n"
"a dynamic range of 135 dB below 30 kHz.\n\n";
return 1;
}
int bytespersample = bits/8;
vector<dxd> dxds (channels);
vector<noise_shaper> ns;
if (bits==16) {
ns.resize(channels, noise_shaper(my_ns_soscount, my_ns_coeffs) );
}
vector<unsigned char> dsd_data (block * channels);
vector<float> float_data (block);
vector<unsigned char> pcm_data (block * channels * bytespersample);
char * const dsd_in = reinterpret_cast<char*>(&dsd_data[0]);
char * const pcm_out = reinterpret_cast<char*>(&pcm_data[0]);
while (cin.read(dsd_in,block * channels)) {
for (int c=0; c<channels; ++c) {
dxds[c].translate(block,&dsd_data[0]+c,channels,
lsbitfirst,
&float_data[0],1);
unsigned char * out = &pcm_data[0] + c*bytespersample;
if (bits==16) {
for (int s=0; s<block; ++s) {
float r = float_data[s]*32768 + ns[c].get();
long smp = clip(-32768,myround(r),32767);
ns[c].update( clip(-1,smp-r,1) );
write_intel16(out,smp);
out += channels*bytespersample;
}
} else {
for (int s=0; s<block; ++s) {
float r = float_data[s]*8388608;
long smp = clip(-8388608,myround(r),8388607);
write_intel24(out,smp);
out += channels*bytespersample;
}
}
}
cout.write(pcm_out,block*channels*bytespersample);
}
}
|