Beispiel #1
0
        /// <summary>
        /// Implements convolution over a plain rectangular array of data values
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dest"></param>
        /// <param name="convolver"></param>
        public override void Convolve(T[,] source, T[,] dest, IConvolver <T> convolver)
        {
            var majorDimSource = source.GetLength(0);
            var minorDimSource = source.GetLength(1);

            var majorDimDest = dest.GetLength(0);
            var minorDimDest = dest.GetLength(1);

            var nullValue = convolver.Accumulator.NullValue;

            if (majorDimSource != majorDimDest || minorDimSource != minorDimDest)
            {
                throw new ArgumentException("Dimensions of source and destination data are not the same");
            }

            convolver.Convolve(majorDimSource, minorDimSource,
                               (x, y) =>
            {
                if (x < 0 || y < 0 || x >= majorDimSource || y >= minorDimSource)
                {
                    return(nullValue);
                }

                return(source[x, y]);
            },
                               (x, y, v) => dest[x, y] = v);
        }
Beispiel #2
0
        public WicConvolution(IWICBitmapSource source, KernelMap <TWeight> mapx, KernelMap <TWeight> mapy, bool bufferSource = false) : base(source)
        {
            if (Format.FormatGuid == Consts.GUID_WICPixelFormat32bppPBGRA)
            {
                Processor = new Convolver4ChanByte();
            }
            else if (Format.FormatGuid == Consts.GUID_WICPixelFormat32bppBGRA)
            {
                Processor = new ConvolverBgraByte();
            }
            else if (Format.FormatGuid == Consts.GUID_WICPixelFormat24bppBGR)
            {
                Processor = new ConvolverBgrByte();
            }
            else if (Format.FormatGuid == Consts.GUID_WICPixelFormat16bppCbCr)
            {
                Processor = new Convolver2ChanByte();
            }
            else if (Format.FormatGuid == Consts.GUID_WICPixelFormat8bppGray || Format.FormatGuid == Consts.GUID_WICPixelFormat8bppY)
            {
                Processor = new Convolver1ChanByte();
            }
            else if (Format == PixelFormat.Pbgra64BppLinearUQ15)
            {
                Processor = new Convolver4ChanUQ15();
            }
            else if (Format == PixelFormat.Bgra64BppLinearUQ15)
            {
                Processor = new ConvolverBgraUQ15();
            }
            else if (Format == PixelFormat.Bgr48BppLinearUQ15)
            {
                Processor = new ConvolverBgrUQ15();
            }
            else if (Format == PixelFormat.Grey16BppLinearUQ15 || Format == PixelFormat.Y16BppLinearUQ15)
            {
                Processor = new Convolver1ChanUQ15();
            }
            else if (Format == PixelFormat.Pbgra128BppLinearFloat || Format == PixelFormat.Pbgra128BppFloat)
            {
                Processor = new Convolver4ChanFloat();
            }
            else if (Format == PixelFormat.Bgr96BppLinearFloat || Format == PixelFormat.Bgr96BppFloat)
            {
                Processor = new Convolver3ChanFloat();
            }
            else if (Format == PixelFormat.CbCr64BppFloat)
            {
                Processor = new Convolver2ChanFloat();
            }
            else if (Format == PixelFormat.Grey32BppLinearFloat || Format.FormatGuid == Consts.GUID_WICPixelFormat32bppGrayFloat || Format == PixelFormat.Y32BppLinearFloat || Format == PixelFormat.Y32BppFloat)
            {
                Processor = new Convolver1ChanFloat();
            }
            else
            {
                throw new NotSupportedException("Unsupported pixel format");
            }

            BufferSource = bufferSource;
            OutWidth     = (uint)mapx.OutPixels;
            OutHeight    = (uint)mapy.OutPixels;
            SourceRect   = new WICRect {
                Width = (int)Width, Height = 1
            };
            XMap = mapx;
            YMap = mapy;

            IntBpp       = Bpp / Unsafe.SizeOf <TPixel>() * Unsafe.SizeOf <TWeight>();
            IntStride    = mapy.Samples * IntBpp;
            IntStartLine = -mapy.Samples;

            int lineBuffLen = (bufferSource ? mapy.Samples : 1) * (int)Stride;
            int intBuffLen  = mapx.OutPixels * IntStride;

            LineBuff = new ArraySegment <byte>(ArrayPool <byte> .Shared.Rent(lineBuffLen), 0, lineBuffLen);
            IntBuff  = new ArraySegment <byte>(ArrayPool <byte> .Shared.Rent(intBuffLen), 0, intBuffLen);
        }
Beispiel #3
0
        protected ConvolutionTransform(PixelSource source, KernelMap <TWeight> mapx, KernelMap <TWeight> mapy, bool lumaMode = false) : base(source)
        {
            var infmt   = source.Format;
            var workfmt = infmt;

            if (lumaMode)
            {
                if (infmt.ColorRepresentation != PixelColorRepresentation.Grey && infmt.ColorRepresentation != PixelColorRepresentation.Bgr)
                {
                    throw new NotSupportedException("Unsupported pixel format: " + infmt.Name);
                }

                workfmt = infmt.NumericRepresentation == PixelNumericRepresentation.Float ? PixelFormat.Grey32BppFloat :
                          infmt.NumericRepresentation == PixelNumericRepresentation.Fixed ? PixelFormat.Grey16BppUQ15 :
                          infmt.NumericRepresentation == PixelNumericRepresentation.UnsignedInteger ? PixelFormat.Grey8Bpp :
                          throw new NotSupportedException("Unsupported pixel format: " + infmt.Name);
            }

            if (!ProcessorMap.TryGetValue(workfmt, out XProcessor !))
            {
                throw new NotSupportedException("Unsupported pixel format: " + workfmt.Name);
            }

            if (workfmt == PixelFormat.Bgr96BppLinearFloat)
            {
                Format = workfmt = PixelFormat.Bgrx128BppLinearFloat;
            }
            else if (workfmt == PixelFormat.Bgr96BppFloat)
            {
                Format = workfmt = PixelFormat.Bgrx128BppFloat;
            }
            else
            {
                Format = infmt;
            }

            YProcessor = ProcessorMap[workfmt];

            if (HWIntrinsics.IsSupported && (mapx.Samples * mapx.Channels & 3) == 0 && XProcessor is IVectorConvolver vcx)
            {
                XProcessor = vcx.IntrinsicImpl;
            }
            if (HWIntrinsics.IsSupported && (mapy.Samples * mapy.Channels & 3) == 0 && YProcessor is IVectorConvolver vcy)
            {
                YProcessor = vcy.IntrinsicImpl;
            }

            XMap = mapx;
            YMap = mapy;

            if (XMap.Channels != XProcessor.MapChannels || YMap.Channels != YProcessor.MapChannels)
            {
                throw new NotSupportedException("Map and Processor channel counts don't match");
            }

            Width  = mapx.Pixels;
            Height = mapy.Pixels;

            int bpp = workfmt.BytesPerPixel / Unsafe.SizeOf <TPixel>() * Unsafe.SizeOf <TWeight>();

            IntBuff = new PixelBuffer(mapy.Samples, bpp, true, mapy.Samples * mapx.Pixels * bpp);

            if (bufferSource = lumaMode)
            {
                SrcBuff = new PixelBuffer(mapy.Samples, BufferStride, true);

                if (workfmt.IsBinaryCompatibleWith(infmt))
                {
                    WorkBuff = SrcBuff;
                }
                else
                {
                    WorkBuff = new PixelBuffer(mapy.Samples, MathUtil.PowerOfTwoCeiling(source.Width * workfmt.BytesPerPixel, IntPtr.Size), true);
                }
            }
            else
            {
                lineBuff = BufferPool.Rent(BufferStride, true);
            }
        }
 public UnsharpMaskTransform(PixelSource source, KernelMap <TWeight> mapx, KernelMap <TWeight> mapy, UnsharpMaskSettings ss) : base(source, mapx, mapy, true)
 {
     sharpenSettings = ss;
     processor       = ProcessorMap[Format.FormatGuid];
     blurBuff        = new ArraySegment <byte>(ArrayPool <byte> .Shared.Rent(WorkStride), 0, WorkStride);
 }
Beispiel #5
0
 public virtual void Convolve(GenericLeafSubGrid <T> leaf, GenericLeafSubGrid <T> smoothedLeaf, IConvolver <T> convolver)
 {
     throw new NotImplementedException($"Convolve({nameof(GenericLeafSubGrid<T>)} leaf, ...) not implemented in this convolution tools class");
 }
Beispiel #6
0
 public virtual void Convolve(T[,] source, T[,] dest, IConvolver <T> convolver)
 {
     throw new NotImplementedException("Convolve(T[,] source, ...) not implemented in this convolution tools class");
 }
Beispiel #7
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();
            }
        }
Beispiel #8
0
        /// <summary>
        /// Implements convolution over a sub grid tree in <T>
        /// </summary>
        /// <param name="leaf"></param>
        /// <param name="smoothedLeaf"></param>
        /// <param name="convolver"></param>
        public override void Convolve(GenericLeafSubGrid <T> leaf, GenericLeafSubGrid <T> smoothedLeaf, IConvolver <T> convolver)
        {
            var context = new ConvolutionSubGridContext <GenericLeafSubGrid <T>, T>(leaf, convolver.Accumulator.NullValue);

            convolver.Convolve(SubGridTreeConsts.SubGridTreeDimension, SubGridTreeConsts.SubGridTreeDimension,
                               (x, y) => context.Value(x, y), (x, y, v) => smoothedLeaf.Items[x, y] = v);
        }