Пример #1
0
        public int Convolve(double *src, int srcLength, double *dst, int dstLength)
        {
            var    input = new UnionBuffer(delayData.Data, delay * Size, (IntPtr)src, srcLength * Size);
            int    kernelLength = kernel.Length, offset = 0, step, copyLength;
            int    outLen = Math.Max(Math.Min(delay + srcLength - (kernelLength - 1), dstLength), 0);
            IntPtr tempInput;
            bool   fast = fft != null;

            if (fast)
            {
                copyLength = fft.FFTSize;
                tempInput  = fftIn;
                step       = kernelLength + 1;
            }
            else
            {
                copyLength = FixedStep + kernelLength - 1;
                tempBuffer.Resize(copyLength * Size);
                tempInput = tempBuffer.data;
                step      = FixedStep;
            }

            for (; outLen >= step; outLen -= step, offset += step)
            {
                input.CopyTo(offset * Size, tempInput, copyLength * Size);
                ConvolveOnce(tempInput, dst + offset, step, fast);
            }
            if (outLen > 0)
            {
                input.CopyTo(offset * Size, tempInput, (outLen + kernelLength - 1) * Size);
                ConvolveOnce(tempInput, dst + offset, outLen, fast);
                offset += outLen;
            }

            delay = Math.Min(Math.Max(kernelLength - 1, delay + srcLength - dstLength), delay + srcLength);
            tempBuffer.Resize(delay * Size);
            input.CopyTo(offset * Size, tempBuffer.Data, delay * Size);

            var temp = tempBuffer;

            tempBuffer = delayData;
            delayData  = temp;

            return(offset);
        }
Пример #2
0
        private unsafe void ReadCallback(int frameCountMin, int frameCountMax)
        {
            int         writeFrames = frameCountMax;
            int         framesLeft  = writeFrames;
            UnionBuffer unionBuffer = new UnionBuffer();

            for (; ;)
            {
                int frameCount = framesLeft;

                var areas = _instream.BeginRead(ref frameCount);

                if (frameCount == 0)
                {
                    break;
                }

                if (areas.IsEmpty)
                {
                    // Due to an overflow there is a hole. Fill the ring buffer with
                    // silence for the size of the hole.
                    Console.Error.WriteLine("Dropped {0} frames due to internal overflow", frameCount);
                }
                else
                {
                    for (int frame = 0; frame < frameCount; frame += 1)
                    {
                        int chCount  = _instream.Layout.ChannelCount;
                        int copySize = _instream.BytesPerSample;
                        unionBuffer.Bytes = new byte[copySize];

                        fixed(byte *buffer = unionBuffer.Bytes)
                        {
                            for (int ch = 0; ch < chCount; ch += 1)
                            {
                                var area = areas.GetArea(ch);
                                Buffer.MemoryCopy((void *)area.Pointer, buffer, copySize, copySize);
                                _ringBuffer.Enqueue(unionBuffer.Bytes, 0, copySize);
                                area.Pointer += area.Step;
                            }
                        }
                    }
                }

                _instream.EndRead();

                framesLeft -= frameCount;
                if (framesLeft <= 0)
                {
                    break;
                }
            }

            int length = (int)_ringBuffer.GetLength();

            if (length >= FlushCount)
            {
                if (_flushBuffer == null || _flushBuffer.Length != length)
                {
                    _flushBuffer = new byte[length];
                }

                _ringBuffer.Dequeue(_flushBuffer);
                Filled?.Invoke(this, new FillEventArgs(_flushBuffer, 0, length));
            }
        }