Inheritance: SoundObj
        static ISoundObj Splice(string infileL, int peakPosL, string infileR, int peakPosR, string outfile)
        {
            //int tmp1;
            //bool tmp2;
            WaveReader reader1 = new WaveReader(infileL, WaveFormat.IEEE_FLOAT, 32, 1);
            //            reader1.Skip(peakPosL, out tmp1, out tmp2);
            SoundBuffer buff1 = new SoundBuffer(reader1);
            buff1.ReadAll();

            // Normalize loudness for each channel
            double g = Loudness.WeightedVolume(buff1);
            buff1.ApplyGain(1/g);

            WaveReader reader2 = new WaveReader(infileR, WaveFormat.IEEE_FLOAT, 32, 1);
            //            reader2.Skip(peakPosR, out tmp1, out tmp2);
            SoundBuffer buff2 = new SoundBuffer(reader2);
            buff2.ReadAll();

            g = Loudness.WeightedVolume(buff2);
            buff2.ApplyGain(1/g);

            ChannelSplicer splicer = new ChannelSplicer();
            splicer.Add(buff1);
            splicer.Add(buff2);

            // General-purpose:
            // Find the extremities of the DRC impulse,
            // window asymmetrically.
            //
            // But, since we specifically used linear-phase filters on target and mic,
            // we know that the impulse is centered.
            // We want an impulse length (_filterLen)
            // so window the 2048 samples at each end (which are pretty low to begin with - less than -100dB)

            ISoundObj output;
            int nCount = (int)(buff1.Count / 2);
            if (nCount > _filterLen/2)
            {
                BlackmanHarris bhw = new BlackmanHarris(nCount, 2048, (nCount / 2) - 2048);
                bhw.Input = splicer;
                SampleBuffer sb = new SampleBuffer(bhw);
                output = sb.Subset(_filterLen/2, _filterLen);
            }
            else
            {
                output = splicer;
            }

            ISoundObj result = output;
            if (!_noSkew)
            {
                // Apply skew to compensate for time alignment in the impulse responses
                Skewer skewer = new Skewer(true);
                skewer.Input = output;
                skewer.Skew = peakPosL - peakPosR;
                result = skewer;
            }

            WaveWriter writer = new WaveWriter(outfile);
            writer.Input = result;
            writer.Dither = DitherType.NONE;
            writer.Format = WaveFormat.IEEE_FLOAT;
            writer.BitsPerSample = 32;
            writer.SampleRate = _sampleRate;
            writer.NumChannels = splicer.NumChannels;
            if (Double.IsNaN(_gain))
            {
                writer.Normalization = 0;
            }
            else
            {
                writer.Gain = MathUtil.gain(_gain);
            }
            writer.Run();
            writer.Close();
            reader1.Close();
            reader2.Close();

            return result;
        }
Exemple #2
0
        static void InguzDSP(bool doRun)
        {
            DateTime dtStartRun = DateTime.Now;
            string sigdesc = null;

            // We need a few convolvers, of course
            if (_slow)
            {
                _MatrixConvolver = new SlowConvolver();
                _MainConvolver = new SlowConvolver();
                _EQConvolver = new SlowConvolver();
            }
            else
            {
                _MatrixConvolver = new FastConvolver();
                _MainConvolver = new FastConvolver();
                _EQConvolver = new FastConvolver();
            }

            // Shuffler
            _widthShuffler = new Shuffler();

            // Two skewers
            _depthSkewer = new Skewer(true);
            _skewSkewer = new Skewer(true);

            // Writer
            if (_outPath == null)
            {
                _writer = new WaveWriter();  // stdout
            }
            else
            {
                _writer = new WaveWriter(_outPath);
            }
            _writer.NumChannels = _outChannels;
            if (_debug)
            {
                TimeSpan ts = DateTime.Now.Subtract(dtStartRun);
                Trace.WriteLine("Setup " + ts.TotalMilliseconds);
            }

            /*
            DateTime exp = DSPUtil.DSPUtil.EXPIRY;
            if (exp != null)
            {
                if (DateTime.Now.CompareTo(exp) >= 0)
                {
                    Trace.WriteLine("**** THIS EVALUATION VERSION EXPIRED {0}", DSPUtil.DSPUtil.EXPIRY);
                    Trace.WriteLine("**** SEE http://www.inguzaudio.com/DSP/ FOR DETAILS");
                    _MatrixConvolver.Enabled = false;
                    _MainConvolver.Enabled = false;
                    _EQConvolver.Enabled = false;
                    Show("", "InguzDSP has expired.", 2);
                }
                else
                {
                    Trace.WriteLine("This evaluation version will expire {0}", DSPUtil.DSPUtil.EXPIRY);
                }
            }
            */

            // Read the configuration file
            doRun = LoadConfig2();

            // Do any cleanup required before we start
            CleanUp();

            // The main convolver should persist and re-use its leftovers between invocations
            // under this user's (=squeezebox's) ID
            _MainConvolver.partitions = _partitions;
            if (_tail && !IsSigGenNonEQ())
            {
                _MainConvolver.PersistPath = _tempFolder;
                _MainConvolver.PersistTail = _userID;
            }

            // Construct a second convolver for the "tone" (EQ) control.
            _EQConvolver.partitions = _partitions;
            if (_tail && !IsSigGenNonEQ())
            {
                _EQConvolver.PersistPath = _tempFolder;
                _EQConvolver.PersistTail = _userID + ".eq";
            }

            // Make a reader
            // _inPath is the data stream
            WaveReader inputReader = null;
            bool ok = false;
            try
            {
                if (_inStream != null)
                {
                    inputReader = new WaveReader(_inStream);
                }
                else if (_isRawIn)
                {
                    inputReader = new WaveReader(_inPath, _rawtype, _rawbits, _rawchan, _startTime);
                }
                else
                {
                    inputReader = new WaveReader(_inPath, _startTime);
                }
                inputReader.BigEndian = _bigEndian;
                ok = true;
            }
            catch (Exception e)
            {
                Trace.WriteLine("Unable to read: " + e.Message);
                // Just stop (no need to report the stack)
            }

            if (ok)
            {
                if (inputReader.IsSPDIF)
                {
                    // The wave file is just a SPDIF (IEC61937) stream, we shouldn't touch it
                    _inputSPDIF = true;
                    _isBypass = true;
                }
                if (_isBypass)
                {
                    // The settings file says bypass, we shouldn't touch it
                    _gain = 0;
                    _dither = DitherType.NONE;
                }

                uint sr = _inputSampleRate; // Yes, the commandline overrides the source-file...
                if (sr == 0)
                {
                    sr = inputReader.SampleRate;
                }
                if (sr == 0)
                {
                    sr = 44100;
                }
                _inputSampleRate = sr;

                if (WaveFormatEx.AMBISONIC_B_FORMAT_IEEE_FLOAT.Equals(inputReader.FormatEx) ||
                    WaveFormatEx.AMBISONIC_B_FORMAT_PCM.Equals(inputReader.FormatEx))
                {
                    _isBFormat = true;
                }

            }

            ISoundObj source = inputReader;
            if (IsSigGen())
            {
                // Signal-generator source instead of music.
                _isBFormat = false;
                source = GetSignalGenerator(-12, out sigdesc);
                Show("Test signal", sigdesc, 20);
            }

            if (IsSigGenNonEQ() || _isBypass)
            {
                // Signal-generator mode.  Overrides everything else!
                _writer.Input = source;
            }
            else
            {
                if (ok)
                {
                    // Load the room correction impulse to the convolver
                    // (NB: don't do this until we've created the reader, otherwise we can't be user of the samplerate yet...)
                    LoadImpulse();
                    GC.Collect();
                }

                if (ok && _isBFormat)
                {
                    source = DecodeBFormat(source);
                }

                if (ok)
                {
                    ISoundObj nextSrc;

                    // Perform width (matrix) processing on the signal
                    // - Shuffle the channels
                    // - Convolve if there's a filter
                    // - Apply gain to boost or cut the 'side' channel
                    // - Shuffle back
                    _widthShuffler.Input = source;
                    nextSrc = _widthShuffler;

                    // Use a convolver for the matrix filter
                    if (_matrixFilter != null)
                    {
                        LoadMatrixFilter();
                        _MatrixConvolver.Input = TwoChannel(nextSrc);
                        nextSrc = _MatrixConvolver as ISoundObj;
                    }

                    //                if (_depth != 0)
                    //                {
                    //                    // Time-alignment between the LR and MS
                    //                    _depthSkewer.Input = nextSrc;
                    //                    nextSrc = _depthSkewer;
                    //                }

                    // Shuffle back again
                    Shuffler shMSLR = new Shuffler();
                    shMSLR.Input = nextSrc;
                    nextSrc = shMSLR;

                    // Do the room-correction convolution
                    _MainConvolver.Input = TwoChannel(shMSLR);
                    nextSrc = _MainConvolver;

                    if (_skew != 0)
                    {
                        // time-alignment between left and right
                        _skewSkewer.Input = nextSrc;
                        nextSrc = _skewSkewer;
                    }

                    // Splice EQ and non-EQ channels
                    if (IsSigGenEQ())
                    {
                        ChannelSplicer splice = new ChannelSplicer();
                        if (IsSigGenEQL())
                        {
                            splice.Add(new SingleChannel(nextSrc, 0));
                        }
                        else
                        {
                            splice.Add(new SingleChannel(source, 0));
                        }
                        if (IsSigGenEQR())
                        {
                            splice.Add(new SingleChannel(nextSrc, 1));
                        }
                        else
                        {
                            splice.Add(new SingleChannel(source, 1));
                        }
                        nextSrc = splice;
                    }

                    // Process externally with aften or equivalent?
                    if (_aftenNeeded && !_isBypass)
                    {
                        nextSrc = AftenProcess(nextSrc);
                        _outFormat = WaveFormat.PCM;
                        _outBits = 16;
                        _dither = DitherType.NONE;
                    }

                    // Finally pipe this to the writer
                    _writer.Input = nextSrc;
                }
            }
            if (ok)
            {
                //dt = System.DateTime.Now;       // time to here is approx 300ms

                // Dither and output raw-format override anything earlier in the chain
                _writer.Dither = _isBypass ? DitherType.NONE : _dither;
                _writer.Raw = _isRawOut;
                _writer.Format = (_outFormat == WaveFormat.ANY) ? inputReader.Format : _outFormat;
                _writer.BitsPerSample = (_outBits == 0 || _isBypass) ? inputReader.BitsPerSample : _outBits;
                _writer.SampleRate = (_outRate == 0 || _isBypass) ? _inputSampleRate : _outRate;
                SetWriterGain();
                if (IsSigGen())
                {
                    Trace.WriteLine("Test signal: {0}, -12dBfs, {1}/{2} {3} {4}", sigdesc, _writer.BitsPerSample, _writer.SampleRate, _writer.Format, _writer.Dither);
                }
                string amb1 = "";
                string amb2 = "";
                if(_isBFormat)
                {
                    amb1 = "B-Format ";
                    amb2 = _ambiType + " ";
                }
                string big = inputReader.BigEndian ? "(Big-Endian) " : "";
                if (_inputSPDIF)
                {
                    Trace.WriteLine("Stream is SPDIF-wrapped; passing through");
                }
                else if (_isBypass)
                {
                    Trace.WriteLine("Processing is disabled; passing through");
                }
                Trace.WriteLine("{0}/{1} {2}{3} {4}=> {5}/{6} {7}{8} {9}, gain {10} dB", inputReader.BitsPerSample, _inputSampleRate, amb1, inputReader.Format, big, _writer.BitsPerSample, _writer.SampleRate, amb2, _writer.Format, _writer.Dither, _gain);

                TimeSpan elapsedInit = System.DateTime.Now.Subtract(dtStartRun);
                int n = _writer.Run();

                TimeSpan elapsedTotal = System.DateTime.Now.Subtract(dtStartRun);
                double realtime = n / _writer.SampleRate;
                double runtime = elapsedTotal.TotalMilliseconds / 1000;
                Trace.WriteLine("{0} samples, {1} ms ({2} init), {3} * realtime, peak {4} dBfs", n, elapsedTotal.TotalMilliseconds, elapsedInit.TotalMilliseconds, Math.Round(realtime / runtime, 4), Math.Round(_writer.dbfsPeak, 4));

                StopConfigListening();

                _writer.Close();
            }
        }