private static SampleBlock[] ReadSamples <T>(EndianBinaryReader reader, int numWAVISlots) where T : IWavInfo { long waviChunkOffset = FindChunk(reader, "wavi"); long pcmdChunkOffset = FindChunk(reader, "pcmd"); if (waviChunkOffset == -1 || pcmdChunkOffset == -1) { throw new InvalidDataException(); } else { waviChunkOffset += 0x10; pcmdChunkOffset += 0x10; var samples = new SampleBlock[numWAVISlots]; for (int i = 0; i < numWAVISlots; i++) { ushort offset = reader.ReadUInt16(waviChunkOffset + (2 * i)); if (offset != 0) { T wavInfo = reader.ReadObject <T>(offset + waviChunkOffset); samples[i] = new SampleBlock { WavInfo = wavInfo, Data = reader.ReadBytes((int)((wavInfo.LoopStart + wavInfo.LoopEnd) * 4), pcmdChunkOffset + wavInfo.SampleOffset) }; } } return(samples); } }
public override int Read(byte[] buffer, int offset, int count) { if (this.currentBlockNode == null || this.currentBlockNode.Value == null) { return(0); } SampleBlock block = this.currentBlockNode.Value; int bytesAvailableInCurrentBlock = block.BytesInUse - this.positionInBlock; int bytesCopied = Math.Min(bytesAvailableInCurrentBlock, count); block.CopyTo(this.positionInBlock, buffer, offset, bytesCopied); this.positionInBlock += bytesCopied; this.position += bytesCopied; if (block.BytesInUse <= this.positionInBlock) { this.currentBlockNode = this.currentBlockNode.Next; this.positionInBlock = 0; int bytesRemainingToCopy = count - bytesAvailableInCurrentBlock; if (bytesRemainingToCopy > 0) { bytesCopied += this.Read(buffer, offset + bytesCopied, bytesRemainingToCopy); } } return(bytesCopied); }
public SampleBuffer(WaveStream stream) : this(stream.WaveFormat.SampleRate, stream.WaveFormat.BitsPerSample, stream.WaveFormat.Channels) { byte[] buffer = new byte[CrossTimeConstant.SampleBlockSizeInBytes]; SampleType sampleType = SampleTypeExtensions.FromBitsPerSample(stream.WaveFormat.BitsPerSample); while (stream.CanRead) { int bytesRead = stream.Read(buffer, 0, buffer.Length); if (bytesRead < 1) { // workaround for NAudio bug: WaveStream.CanRead is hard coded to true regardless of position break; } SampleBlock block = new SampleBlock(buffer, bytesRead, sampleType); this.Blocks.AddLast(block); this.length += block.BytesInUse; } }
public unsafe void SampleBlockConversions() { SampleBlock reference16Bit; using (MediaFoundationReader reference16BitReader = new MediaFoundationReader(TestConstant.ReferenceFilePath16Bit)) { byte[] buffer16Bit = new byte[reference16BitReader.Length]; int bytesRead = reference16BitReader.Read(buffer16Bit, 0, buffer16Bit.Length); reference16Bit = new SampleBlock(buffer16Bit, bytesRead, SampleTypeExtensions.FromBitsPerSample(reference16BitReader.WaveFormat.BitsPerSample)); } SampleBlock reference24Bit; using (MediaFoundationReader reference24BitReader = new MediaFoundationReader(TestConstant.ReferenceFilePath24Bit)) { byte[] buffer24Bit = new byte[reference24BitReader.Length]; int bytesRead = reference24BitReader.Read(buffer24Bit, 0, buffer24Bit.Length); reference24Bit = new SampleBlock(buffer24Bit, bytesRead, SampleTypeExtensions.FromBitsPerSample(reference24BitReader.WaveFormat.BitsPerSample)); } Assert.IsTrue(reference16Bit.Int16Samples == reference24Bit.SamplesInUse); SampleBlock reference16BitAsDouble = reference16Bit.ConvertTo(SampleType.Double); SampleBlock reference16BitAsQ31 = reference16Bit.ConvertTo(SampleType.Int32); SampleBlock reference24BitAsDouble = reference24Bit.ConvertTo(SampleType.Double); SampleBlock reference24BitAsQ31 = reference24Bit.ConvertTo(SampleType.Int32); Assert.IsTrue(reference16Bit.Int16Samples == reference16BitAsDouble.DoubleSamples); Assert.IsTrue(reference16Bit.Int16Samples == reference16BitAsQ31.Int32Samples); Assert.IsTrue(reference16Bit.Int16Samples == reference24BitAsDouble.DoubleSamples); Assert.IsTrue(reference16Bit.Int16Samples == reference24BitAsQ31.Int32Samples); for (int sample = 0; sample < reference16Bit.Int16Samples; ++sample) { Assert.IsTrue(((int)reference16Bit.Int16s[sample] << TestConstant.ShiftBetween16BitSamplesAndQ31) == reference16BitAsQ31.Int32s[sample]); Assert.IsTrue((int)reference16BitAsDouble.Doubles[sample] == reference16BitAsQ31.Int32s[sample]); Assert.IsTrue((reference24Bit.GetInt24AsInt32(sample) << TestConstant.ShiftBetween24BitSamplesAndQ31) == reference24BitAsQ31.Int32s[sample]); Assert.IsTrue((int)reference24BitAsDouble.Doubles[sample] == reference24BitAsQ31.Int32s[sample]); } }
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)); } } }
public Sample GetSample(Sample prevSample) { TotalSamples++; if (!warmUpcomplete) { var wmsample = new Sample(this); var rx = wmsample.GetLazyValue(); var ry = wmsample.GetLazyValue(); wmsample.imageX = rx * screenWidth; wmsample.imageY = ry * screenHeight; warmUpcomplete = TotalSamples >= screenWidth * screenHeight * WarmupPasses; return wmsample; } #if VERBOSE if (TotalSamples == screenWidth * screenHeight * WarmupPasses+1) { Tracer.TraceLine("T{0} Warmup complete", tIdx); var sampleBlocks = new HashSet<SampleBlock>(); foreach (var sampleBlock in blocks) { if (!sampleBlocks.Contains(sampleBlock) && (sampleBlock.BlockError(Film) > ErrorStop)) { sampleBlock.CachedError = sampleBlock.BlockError(Film); sampleBlocks.Add(sampleBlock); } } this.blocks = sampleBlocks.ToList(); Tracer.TraceLine("T{0} duplicate removal complete", tIdx); Classify(blocks); Tracer.TraceLine("T{0} classification complete", tIdx); } #endif CurrentBlock.TotalSamples++; if (blocks.Count == 0) { this.Init(Width, Height); Tracer.TraceLine("Adaptive sampling complete! Start another iteration"); return null; } currentBlockSample++; if (currentBlockSample >= CurrentBlock.SamplesInBlock(ImportantBlockSamples)) { blockIndex++; currentBlockSample= 0; } if (blockIndex >= blocks.Count) { blockIndex = Math.Min(tIdx, blocks.Count - 1); } CurrentBlock = blocks[blockIndex]; if (CurrentBlock.TotalSamples >= CurrentBlock.SamplesPerIteration * CurrentBlock.BlockWidth * CurrentBlock.BlockHeight) { var blockError = CurrentBlock.BlockError(this.Film); if (blockError > ErrorSplit) { this.SplitBlock(CurrentBlock); } else if (blockError < ErrorStop) { #if VERBOSE Tracer.TraceLine("{0} Block is ready", blockIndex); Tracer.TraceLine("Rem block {0} block error {1} ", blocks[blockIndex].ToString(), blockError, blocks[blockIndex].BlockWidth, blocks[blockIndex].BlockHeight); #endif this.TotalSamples += this.CurrentBlock.SamplerPerBlock; #if VERBOSE Tracer.TraceLine("Block Count " + blocks.Count); #endif } else if (subBlocks.Count < 65535) { foreach (var block in blocks) { var proposalB = block.Split(block.SamplesPerIteration); foreach (var proposalBlock in proposalB) { if (proposalBlock.BlockError(Film) > block.BlockError(Film)) { //this.blocks.AddRange(proposalBlock.Split(CurrentBlock.SamplesPerIteration)); subBlocks.Add(proposalBlock); } else { //this.blocks.Add(proposalBlock); //this.blocks.AddRange(proposalBlock.Split(proposalBlock.SamplesPerIteration * 2)); subBlocks.AddRange(proposalBlock.Split(proposalBlock.SamplesPerIteration)); //foreach (var block in blocks) //{ // Film.StatsRect(block.Xstart, block.Ystart, block.BlockWidth, block.BlockHeight, blockIndex); //} } } } } #if VERBOSE //Tracer.TraceLine("T{4}- Removing {2}/{3} block {1} error {0}", blockError, CurrentBlock.ToString(), blocks.Count, blockIndex, tIdx); #endif this.blocks.Remove(CurrentBlock); if (blocks.Count == 0 && this.subBlocks.Count > 0) { Tracer.TraceLine("T{0} Dicing", tIdx); generation++; this.blocks = this.subBlocks.ToList(); this.subBlocks.Clear(); var sampleBlocks = new HashSet<SampleBlock>(); foreach (var sampleBlock in blocks) { if (!sampleBlocks.Contains(sampleBlock) && (sampleBlock.BlockError(Film) > ErrorStop)) { sampleBlock.CachedError = sampleBlock.BlockError(Film); sampleBlocks.Add(sampleBlock); } } #if VERBOSE Tracer.TraceLine("Removing {0} duplicates", this.blocks.Count - sampleBlocks.Count); Tracer.TraceLine("T{0} Generation {1} sampling", tIdx, generation); #endif Classify(blocks); } if (blockIndex >= this.blocks.Count) { this.blockIndex = 0; } this.CurrentBlock = this.blocks[blockIndex]; this.EvalCurrentBlock(); pass += CurrentBlock.SamplesPerIteration; #if VERBOSE2 for (int index = 0; index < blocks.Count; index++) { var block = blocks[index]; //bool remove = false; //if ((block.Xstart + block.BlockWidth) > screenWidth) //{ // Tracer.TraceLine("Invalid block Width " + (block.Xstart + block.BlockWidth)); // remove = true; //} //if ((block.Ystart + block.BlockHeight) > screenHeight) //{ // Tracer.TraceLine("Invalid block Height " + (block.Ystart + block.BlockHeight)); // remove = true; //} Film.StatsRect(block.Xstart, block.Ystart, block.BlockWidth, block.BlockHeight, blockIndex); //if (remove) //{ // blocks.RemoveAt(index); // Tracer.TraceLine("Removing invalid block {0} block size {2}x{3}", blockIndex, blockError, blocks[blockIndex].BlockWidth, blocks[blockIndex].BlockHeight); //} } #endif } CurrentBlock = blocks[blockIndex]; Sample sample = CurrentBlock.GetSample(this); return sample; }
private void SplitBlock(SampleBlock blockToSplit) { var index = subBlocks.IndexOf(blockToSplit); if (((blockToSplit.BlockWidth / 2) <= 1) || (blockToSplit.BlockHeight / 2) <= 1) { subBlocks.Remove(blockToSplit); return; } this.subBlocks.InsertRange(Math.Max(0, index - 1), blockToSplit.Split(blockToSplit.SamplesPerIteration)); subBlocks.Remove(blockToSplit); ///blocks.AddRange(blockToSplit.Split(blockToSplit.SamplesPerIteration)); }
public void Init(int width, int height) { rnd.Reinitialise((int)DateTime.Now.Ticks); if (screenWidth == 0 && screenHeight == 0) { Width = screenWidth = width; Height = screenHeight = height; //screenWidth = width; //screenHeight = height; } screenStartLine = Math.Max(0, screenStartLine); _currentSampleScreenY = Math.Max(0, screenStartLine); pass = 0; TotalSamples = 0; blockIndex = tIdx; //var tx = 1; //var ty = 1; /* var tWidth = Width / tx; var tHeight = Height / ty; for (int y = 0; y < Height-tHeight; y += tHeight) { for (int x = 0; x < Width-tWidth; x += tWidth) { var block = new Block() { BlockWidth = tWidth, BlockHeight = tHeight, SamplesPerIteration = SamplesPerPass, Xstart = x, Ystart = y }; blocks.Add(block); } } CurrentBlock = blocks[0];*/ CurrentBlock = new SampleBlock() { BlockWidth = screenWidth, BlockHeight = screenHeight, SamplesPerIteration = SamplesPerPass }; //this.blocks.Add(CurrentBlock); this.blocks.AddRange(CurrentBlock.MassSplit(4, SamplesPerPass)); //this.blocks.Sort((a, b) => a.CachedError.CompareTo(b.CachedError)); //this.blocks.ForEach(item => { item.Important = this.blocks.IndexOf(item) > this.blocks.Count / 2; }); }
private unsafe void VerifyWaveFilesEquivalent(string actualFilePath, string expectedFilePath, double expectedToActualScaleFactor, double sampleMatchTolerance, bool verifySampleSize) { // load data in files SampleBlock actual; WaveFormat actualFormat; using (MediaFoundationReader actualReader = new MediaFoundationReader(actualFilePath)) { byte[] buffer = new byte[actualReader.Length]; int bytesRead = actualReader.Read(buffer, 0, buffer.Length); actual = new SampleBlock(buffer, bytesRead, SampleTypeExtensions.FromBitsPerSample(actualReader.WaveFormat.BitsPerSample)); actualFormat = actualReader.WaveFormat; } SampleBlock expected; WaveFormat expectedFormat; using (MediaFoundationReader expectedReader = new MediaFoundationReader(expectedFilePath)) { byte[] buffer = new byte[expectedReader.Length]; int bytesRead = expectedReader.Read(buffer, 0, buffer.Length); expected = new SampleBlock(buffer, bytesRead, SampleTypeExtensions.FromBitsPerSample(expectedReader.WaveFormat.BitsPerSample)); expectedFormat = expectedReader.WaveFormat; } // check data format matches Assert.IsTrue(actual.SamplesInUse == expected.SamplesInUse); if (verifySampleSize) { Assert.IsTrue(actual.SampleType == expected.SampleType); Assert.IsTrue(actualFormat.AverageBytesPerSecond == expectedFormat.AverageBytesPerSecond); Assert.IsTrue(actualFormat.BitsPerSample == expectedFormat.BitsPerSample); Assert.IsTrue(actualFormat.BlockAlign == expectedFormat.BlockAlign); } Assert.IsTrue(actualFormat.Channels == expectedFormat.Channels); Assert.IsTrue(actualFormat.Encoding == expectedFormat.Encoding); Assert.IsTrue(actualFormat.ExtraSize == expectedFormat.ExtraSize); Assert.IsTrue(actualFormat.SampleRate == expectedFormat.SampleRate); double largestMismatch = 0.0; double maxExpectedValue = Math.Pow(2.0, expected.SampleType.BitsPerSample() - 1) - 1; double minExpectedValue = -Math.Pow(2.0, expected.SampleType.BitsPerSample() - 1); double mismatchStandardDevation = 0.0; using (FileStream samplesStream = new FileStream(String.Format("{0} - {1}.csv", Path.GetFileNameWithoutExtension(actualFilePath), Path.GetFileNameWithoutExtension(expectedFilePath)), FileMode.Create)) { using (StreamWriter samplesWriter = new StreamWriter(samplesStream)) { samplesWriter.WriteLine("actual,expected"); int clippedSamples = 0; int mismatchedSamples = 0; int samples = expected.SamplesInUse; for (int sample = 0; sample < samples; ++sample) { // read samples as ints and convert to doubles regardless of sample type in files double actualSample; switch (actual.SampleType) { case SampleType.Int16: actualSample = actual.Int16s[sample]; break; case SampleType.Int24: actualSample = actual.GetInt24AsInt32(sample); break; case SampleType.Int32: actualSample = actual.Int32s[sample]; break; default: throw new NotSupportedException(String.Format("Unhandled sample type {0}.", expected.SampleType)); } actualSample = actualSample / expectedToActualScaleFactor; double expectedSample; switch (expected.SampleType) { case SampleType.Int16: expectedSample = expected.Int16s[sample]; break; case SampleType.Int24: expectedSample = expected.GetInt24AsInt32(sample); break; case SampleType.Int32: expectedSample = expected.Int32s[sample]; break; default: throw new NotSupportedException(String.Format("Unhandled sample type {0}.", expected.SampleType)); } samplesWriter.WriteLine("{0},{1}", actualSample, expectedSample); // it's OK if the expected data is clipped and the actual data isn't if (expectedSample >= maxExpectedValue && actualSample > expectedSample) { ++clippedSamples; continue; } if (expectedSample <= minExpectedValue && actualSample < expectedSample) { ++clippedSamples; continue; } // check samples for equivalence // standard deviation calculation is naive as it assumes the average mismatch is zero double mismatch = Math.Abs(expectedSample - actualSample); mismatchStandardDevation += mismatch * mismatch; if (mismatch > largestMismatch) { largestMismatch = mismatch; } if (mismatch > sampleMatchTolerance) { ++mismatchedSamples; } } mismatchStandardDevation = Math.Sqrt(mismatchStandardDevation / (double)expected.SamplesInUse); this.TestContext.WriteLine("Largest mismatch in samples between {0} and {1} was {2:0.0} with a standard deviation of {3:0.0}.", actualFilePath, expectedFilePath, largestMismatch, mismatchStandardDevation); this.TestContext.WriteLine(">>> {0} samples exceeded threshold of {1:0.0}.", mismatchedSamples, sampleMatchTolerance); Assert.IsTrue(mismatchedSamples == 0, "{0} of {1} ({2:#0.0%}) samples did not match within tolerance {3}.", mismatchedSamples, samples, (double)mismatchedSamples / (double)samples, sampleMatchTolerance); if (verifySampleSize) { Assert.IsTrue(clippedSamples < 0.0001 * samples, "{0} (1:#0.000%) samples were clipped; this is unexpectedly high.", clippedSamples, (double)clippedSamples / (double)samples); } } } // check metadata Tag actualMetadata; using (FileStream inputMetadataStream = new FileStream(actualFilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (TagFile inputTagFile = TagFile.Create(new StreamFileAbstraction(inputMetadataStream.Name, inputMetadataStream, inputMetadataStream))) { actualMetadata = inputTagFile.Tag; } } Tag expectedMetadata; using (FileStream outputMetadataStream = new FileStream(expectedFilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (TagFile outputTagFile = TagFile.Create(new StreamFileAbstraction(outputMetadataStream.Name, outputMetadataStream, outputMetadataStream))) { expectedMetadata = outputTagFile.Tag; } } Assert.AreEqual(expectedMetadata.Album, actualMetadata.Album, String.Format("Expected artist '{0}' but got '{1}'.", expectedMetadata.Album, actualMetadata.Album)); Assert.AreEqual(expectedMetadata.AmazonId, actualMetadata.AmazonId, String.Format("Expected Amazon ID '{0}' but got '{1}'.", expectedMetadata.AmazonId, actualMetadata.AmazonId)); Assert.AreEqual(expectedMetadata.Conductor, actualMetadata.Conductor, String.Format("Expected conductor '{0}' but got '{1}'.", expectedMetadata.Conductor, actualMetadata.Conductor)); Assert.AreEqual(expectedMetadata.Copyright, actualMetadata.Copyright, String.Format("Expected copyright '{0}' but got '{1}'.", expectedMetadata.Copyright, actualMetadata.Copyright)); Assert.AreEqual(expectedMetadata.Disc, actualMetadata.Disc, String.Format("Expected disc '{0}' but got '{1}'.", expectedMetadata.Disc, actualMetadata.Disc)); Assert.AreEqual(expectedMetadata.DiscCount, actualMetadata.DiscCount, String.Format("Expected disc count '{0}' but got '{1}'.", expectedMetadata.DiscCount, actualMetadata.DiscCount)); Assert.AreEqual(expectedMetadata.Grouping, actualMetadata.Grouping, String.Format("Expected grouping '{0}' but got '{1}'.", expectedMetadata.Grouping, actualMetadata.Grouping)); Assert.AreEqual(expectedMetadata.Lyrics, actualMetadata.Lyrics, String.Format("Expected lyrics '{0}' but got '{1}'.", expectedMetadata.Lyrics, actualMetadata.Lyrics)); Assert.AreEqual(expectedMetadata.JoinedAlbumArtists, actualMetadata.JoinedAlbumArtists, String.Format("Expected artists '{0}' but got '{1}'.", expectedMetadata.JoinedAlbumArtists, actualMetadata.JoinedAlbumArtists)); Assert.AreEqual(expectedMetadata.JoinedComposers, actualMetadata.JoinedComposers, String.Format("Expected composers '{0}' but got '{1}'.", expectedMetadata.JoinedComposers, actualMetadata.JoinedComposers)); Assert.AreEqual(expectedMetadata.JoinedGenres, actualMetadata.JoinedGenres, String.Format("Expected genres '{0}' but got '{1}'.", expectedMetadata.JoinedGenres, actualMetadata.JoinedGenres)); Assert.AreEqual(expectedMetadata.JoinedPerformersSort, actualMetadata.JoinedPerformersSort, String.Format("Expected performers '{0}' but got '{1}'.", expectedMetadata.JoinedPerformersSort, actualMetadata.JoinedPerformersSort)); // Pictures is not checked Assert.AreEqual(expectedMetadata.Title, actualMetadata.Title, String.Format("Expected title '{0}' but got '{1}'.", expectedMetadata.Title, actualMetadata.Title)); Assert.AreEqual(expectedMetadata.Track, actualMetadata.Track, String.Format("Expected track '{0}' but got '{1}'.", expectedMetadata.Track, actualMetadata.Track)); Assert.AreEqual(expectedMetadata.TrackCount, actualMetadata.TrackCount, String.Format("Expected track count '{0}' but got '{1}'.", expectedMetadata.TrackCount, actualMetadata.TrackCount)); Assert.AreEqual(expectedMetadata.Year, actualMetadata.Year, String.Format("Expected year '{0}' but got '{1}'.", expectedMetadata.Year, actualMetadata.Year)); }
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); }
public ActionResult SampleBlock(SampleBlock block) { // Do something here with your block instance and return a result that should be rendered by the Page Builder. return(View(block)); }