#include #include #include #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(x + (x>=0 ? 0.5f : -0.5f)); } template struct id { typedef T type; }; template inline T clip( typename id::type min, T v, typename id::type max) { if (vmax) 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 \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 dxds (channels); vector ns; if (bits==16) { ns.resize(channels, noise_shaper(my_ns_soscount, my_ns_coeffs) ); } vector dsd_data (block * channels); vector float_data (block); vector pcm_data (block * channels * bytespersample); char * const dsd_in = reinterpret_cast(&dsd_data[0]); char * const pcm_out = reinterpret_cast(&pcm_data[0]); while (cin.read(dsd_in,block * channels)) { for (int c=0; c