Exemplo n.º 1
0
        private void FilterStream(CrossTimeDspConfiguration configuration, SampleBuffer inputBuffer, SampleType dataPathSampleType, SampleType outputSampleType)
        {
            // setup
            FilterBank filters = new FilterBank(configuration.Engine.Precision, inputBuffer.WaveFormat.SampleRate, inputBuffer.WaveFormat.Channels, configuration.Engine.Q31Adaptive.Q31_32x64_Threshold, configuration.Engine.Q31Adaptive.Q31_64x64_Threshold);

            foreach (Filter filter in configuration.Filters)
            {
                filter.AddTo(filters);
            }

            // time duration of reverse time pass
            DateTime filteringStartedUtc = DateTime.UtcNow;

            using (SampleBuffer reverseTimeBuffer = new SampleBuffer(inputBuffer.WaveFormat.SampleRate, outputSampleType.BitsPerSample(), inputBuffer.WaveFormat.Channels))
            {
                SampleBlock recirculatingDataPathBlock = null;
                for (LinkedListNode <SampleBlock> blockNode = inputBuffer.Blocks.Last; blockNode != null; blockNode = blockNode.Previous)
                {
                    SampleBlock filteredBlock = filters.FilterReverse(blockNode.Value, dataPathSampleType, outputSampleType, ref recirculatingDataPathBlock);
                    reverseTimeBuffer.Blocks.AddFirst(filteredBlock);
                }
                if (recirculatingDataPathBlock != null)
                {
                    recirculatingDataPathBlock.Dispose();
                }
                reverseTimeBuffer.RecalculateBlocks();

                DateTime filteringStoppedUtc = DateTime.UtcNow;
                if (filters.TimingAvailable)
                {
                    this.TestContext.WriteLine("{0} ({1} {2} {3})", (filteringStoppedUtc - filteringStartedUtc).ToString(Constant.ElapsedTimeFormat), filters.ToDataPathTime.ToString(Constant.ElapsedTimeFormat), filters.FilterTime.ToString(Constant.ElapsedTimeFormat), filters.ToOutputTime.ToString(Constant.ElapsedTimeFormat));
                }
                else
                {
                    this.TestContext.WriteLine("{0}", (filteringStoppedUtc - filteringStartedUtc).ToString(Constant.ElapsedTimeFormat));
                }
            }
        }
Exemplo n.º 2
0
        private WaveStream FilterStream(WaveStream inputStream, out StreamPerformance performance)
        {
            performance = new StreamPerformance();

            // populate filters
            FilterBank forwardTimeFilters = new FilterBank(this.Configuration.Engine.Precision, inputStream.WaveFormat.SampleRate, inputStream.WaveFormat.Channels, this.Configuration.Engine.Q31Adaptive.Q31_32x64_Threshold, this.Configuration.Engine.Q31Adaptive.Q31_64x64_Threshold);
            FilterBank reverseTimeFilters = new FilterBank(this.Configuration.Engine.Precision, inputStream.WaveFormat.SampleRate, inputStream.WaveFormat.Channels, this.Configuration.Engine.Q31Adaptive.Q31_32x64_Threshold, this.Configuration.Engine.Q31Adaptive.Q31_64x64_Threshold);

            foreach (Filter filter in this.Configuration.Filters)
            {
                switch (filter.TimeDirection)
                {
                case TimeDirection.Forward:
                    filter.AddTo(forwardTimeFilters);
                    break;

                case TimeDirection.Reverse:
                    filter.AddTo(reverseTimeFilters);
                    break;

                default:
                    throw new NotSupportedException(String.Format("Unhandled time direction {0}.", filter.TimeDirection));
                }
            }

            // do reverse time pass
            // If the only reverse time filter is the anti-clipping gain then there's nothing to do.
            SampleType dataPathSampleType    = this.Configuration.Engine.Precision == FilterPrecision.Double ? SampleType.Double : SampleType.Int32;
            bool       hasForwardTimeFilters = forwardTimeFilters.FilterCount > 0;
            SampleType outputSampleType      = SampleTypeExtensions.FromBitsPerSample(this.Configuration.Output.BitsPerSample);

            if (reverseTimeFilters.FilterCount > 0 && (this.Stopping == false))
            {
                using (SampleBuffer inputBuffer = new SampleBuffer(inputStream))
                {
                    // set up buffer for output of reverse time pass and dispose input stream as it's no longer needed
                    performance.ReverseBufferCompleteUtc = DateTime.UtcNow;
                    SampleType   reverseTimeSampleType = hasForwardTimeFilters ? dataPathSampleType : outputSampleType;
                    SampleBuffer reverseTimeBuffer     = new SampleBuffer(inputStream.WaveFormat.SampleRate, reverseTimeSampleType.BitsPerSample(), inputStream.WaveFormat.Channels);
                    inputStream.Dispose();

                    // input blocks are disposed as they're processed to limit peak memory consumption (and removed from the input buffer for completeness)
                    SampleBlock recirculatingDataPathBlock = null;
                    for (LinkedListNode <SampleBlock> blockNode = inputBuffer.Blocks.Last; blockNode != null; blockNode = blockNode.Previous, inputBuffer.Blocks.RemoveLast())
                    {
                        using (SampleBlock block = blockNode.Value)
                        {
                            SampleBlock filteredBlock = reverseTimeFilters.FilterReverse(block, dataPathSampleType, reverseTimeSampleType, ref recirculatingDataPathBlock);
                            reverseTimeBuffer.Blocks.AddFirst(filteredBlock);
                        }

                        if (this.Stopping)
                        {
                            break;
                        }
                    }
                    if (recirculatingDataPathBlock != null)
                    {
                        recirculatingDataPathBlock.Dispose();
                    }

                    // prepare to apply forward time pass to output of reverse time pass or just to write output
                    reverseTimeBuffer.RecalculateBlocks();
                    inputStream = reverseTimeBuffer;
                    performance.ReverseTimeCompleteUtc = DateTime.UtcNow;
                }
            }

            // do forward time pass
            if (hasForwardTimeFilters && (this.Stopping == false))
            {
                SampleBuffer outputStream = new SampleBuffer(inputStream.WaveFormat.SampleRate, outputSampleType.BitsPerSample(), inputStream.WaveFormat.Channels);
                SampleBlock  recirculatingDataPathBlock = null;
                if (inputStream is SampleBuffer)
                {
                    SampleBuffer inputBlocks = (SampleBuffer)inputStream;
                    for (LinkedListNode <SampleBlock> blockNode = inputBlocks.Blocks.First; blockNode != null; blockNode = blockNode.Next, inputBlocks.Blocks.RemoveFirst())
                    {
                        using (SampleBlock block = blockNode.Value)
                        {
                            SampleBlock filteredBlock = forwardTimeFilters.Filter(block, dataPathSampleType, outputSampleType, ref recirculatingDataPathBlock);
                            outputStream.Blocks.AddLast(filteredBlock);
                        }

                        if (this.Stopping)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    byte[] inputBuffer = new byte[Constant.SampleBlockSizeInBytes];
                    while (inputStream.CanRead)
                    {
                        int bytesRead = inputStream.Read(inputBuffer, 0, inputBuffer.Length);
                        if (bytesRead < 1)
                        {
                            // workaround for NAudio bug: WaveStream.CanRead is hard coded to true regardless of position
                            break;
                        }

                        using (SampleBlock block = new SampleBlock(inputBuffer, bytesRead, SampleTypeExtensions.FromBitsPerSample(inputStream.WaveFormat.BitsPerSample)))
                        {
                            SampleBlock filteredBlock = forwardTimeFilters.Filter(block, dataPathSampleType, outputSampleType, ref recirculatingDataPathBlock);
                            outputStream.Blocks.AddLast(filteredBlock);
                        }

                        if (this.Stopping)
                        {
                            return(null);
                        }
                    }
                }
                if (recirculatingDataPathBlock != null)
                {
                    recirculatingDataPathBlock.Dispose();
                }

                // release input stream as it's no longer needed and complete output
                inputStream.Dispose();
                outputStream.RecalculateBlocks();
                inputStream = outputStream;
            }

            forwardTimeFilters.Dispose();
            reverseTimeFilters.Dispose();

            performance.CompleteTimeUtc = DateTime.UtcNow;
            return(inputStream);
        }