Exemple #1
0
        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);
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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));
        }
Exemple #10
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);
        }
 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));
 }