public DsdiffProcessor(DsdiffReader reader, DsdiffWriter writer, DsdiffFilters filters)
        {
            _dsdiffReader  = reader;
            _dsdiffWriter  = writer;
            _dsdiffFilters = filters;

            InitBitTranslator();
        }
        public void Process()
        {
            Console.WriteLine("> Processing DSD file: {0}", Path.GetFileName(InputFile));

            try
            {
                if (InputLogFile != "")
                {
                    try
                    {
                        Console.WriteLine("> Writing log for input file into: {0}", InputLogFile);
                        var result = Analysis.GetFileResponse(InputFile, InfoFile, 1024);

                        var logOutFile = new StreamWriter(InputLogFile);

                        foreach (var r in result)
                        {
                            logOutFile.Write("{0};{1}\n", r.Item1, r.Item2);
                        }

                        logOutFile.Close();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error: Unable to write input file log - " + ex.Message + "\n" + ex.StackTrace);
                    }
                }

                if (LogOnly.ToLower() == "true")
                {
                    return;
                }

                // Reader
                var inFileStream = File.Open(InputFile, FileMode.Open);

                var reader = new DsdiffReader(inFileStream);

                if (reader.CompressionType != "DSD ")
                {
                    throw new Exception("Invalid compression type - only DSD files supported");
                }

                if (reader.ChannelsCount != 2)
                {
                    throw new Exception(
                              string.Format("Invalid number of channels in DSDIFF file: {0}. Only 2-channel files supported",
                                            reader.ChannelsCount));
                }

                // Writer
                var outFileStream = File.Open(OutputFile, FileMode.Create);

                using (var filters = new DsdiffFilters(ConfigFile, 2822400))
                    using (var writer = new DsdiffWriter(outFileStream, (ushort)filters.Count))
                        using (var processor = new DsdiffProcessor(reader, writer, filters))
                        {
                            //_globalProcessor = processor;
                            processor.Go();
                        }

                //_globalProcessor = null;

                inFileStream.Close();
                inFileStream.Dispose();

                outFileStream.Close();
                outFileStream.Dispose();

                Console.WriteLine("Successfully shutted down\n");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: {0}\n{1}", ex.Message, ex.StackTrace);
            }
        }
Exemple #3
0
        public static List <Tuple <double, double> > GetFileResponse(string inputFile, string infoFile, int downsampleToPoints)
        {
            var bitTranslateTable = new byte[256][];

            InitBitTranslateTable(ref bitTranslateTable);

            var inFileStream = File.Open(inputFile, FileMode.Open);

            var reader = new DsdiffReader(inFileStream);

            if (reader.CompressionType != "DSD ")
            {
                throw new Exception("Invalid compression type - only DSD files supported");
            }

            var channels          = reader.ChannelsCount;
            var samplesPerChannel = (ulong)reader.SamplesPerChannel;

            ////////////////////////////////////////////////////////
            try
            {
                var outText = "channels: " + channels +
                              "\nsamples_per_channel: " + samplesPerChannel +
                              "\nsamplerate: " + reader.SampleRate;
                File.WriteAllText(infoFile, outText);
            }
            catch {}
            ////////////////////////////////////////////////////////

            const int fftBlockSize = 512 * 1024;

            var inputs = new double[channels][];

            // Fill inputs with data
            for (var c = 0; c < channels; c++)
            {
                inputs[c] = new double[fftBlockSize * 8];

                var bitSamples = reader.GetSamplesBlock(
                    reader.SamplesPosition + (long)(samplesPerChannel / 2), c, fftBlockSize);

                for (var m = 0; m < fftBlockSize; m++)
                {
                    var bits        = bitSamples[m];
                    var byteSamples = bitTranslateTable[bits];

                    for (var j = 0; j < 8; j++)
                    {
                        inputs[c][m * 8 + j] = byteSamples[j] == 0 ? -1 : 1;
                    }
                }
            }

            inFileStream.Close();

            var targetFreq         = new double[fftBlockSize * 4 + 1];
            var targetPhase        = new double[fftBlockSize * 4 + 1];
            var targetAverageFreq  = new double[fftBlockSize * 4 + 1];
            var targetAveragePhase = new double[fftBlockSize * 4 + 1];

            // Convert channels
            for (var c = 0; c < channels; c++)
            {
                FilterBackendWrap.FftForward(inputs[c], targetFreq, targetPhase, fftBlockSize * 8);
                for (var n = 0; n < fftBlockSize * 4; n++)
                {
                    targetAverageFreq[n]  += targetFreq[n];
                    targetAveragePhase[n] += targetFreq[n];
                }
            }

            for (var n = 0; n < fftBlockSize * 4; n++)
            {
                targetAverageFreq[n]  /= channels;
                targetAveragePhase[n] /= channels;
            }

            // Downsample
            var preResult = new double[downsampleToPoints];

            var samplesPerPoint = fftBlockSize * 4 / downsampleToPoints;
            var waitForPoint    = samplesPerPoint;

            var accFreq     = 0.0;
            var accPhase    = 0.0;
            var pointNumber = 0;

            for (var n = 0; n < fftBlockSize * 4; n++)
            {
                accFreq  += targetAverageFreq[n];
                accPhase += targetAveragePhase[n];

                if (n >= waitForPoint)
                {
                    waitForPoint += samplesPerPoint;

                    accFreq  /= samplesPerPoint;
                    accPhase /= samplesPerPoint;

                    accFreq = Math.Sqrt(Math.Pow(accFreq, 2) + Math.Pow(accPhase, 2));
                    preResult[pointNumber++] = accFreq;

                    accFreq  = 0.0;
                    accPhase = 0.0;
                }
            }

            accFreq  /= samplesPerPoint;
            accPhase /= samplesPerPoint;
            accFreq   = Math.Sqrt(Math.Pow(accFreq, 2) + Math.Pow(accPhase, 2));
            preResult[pointNumber] = accFreq;

            // Filter result
            var result = new List <Tuple <double, double> >();

            var       average    = 0.0;
            const int filterSize = 100;

            for (var n = 0; n < preResult.Length + filterSize; n++)
            {
                var value = 0.0;
                value = n >= preResult.Length ? preResult[preResult.Length - 1] : preResult[n];

                average += value;

                if (n >= filterSize)
                {
                    var output = average / filterSize;
                    result.Add(new Tuple <double, double>(n - filterSize, output));

                    average -= preResult[n - filterSize];
                }
            }

            return(result);
        }