Exemplo n.º 1
0
        public void CreateMonoIEEE()
        {
            var properties = new AudioProperties(1, 44100, 16, AudioFormat.IEEE);
            var stream     = new MemoryWriterStream(new System.IO.MemoryStream(), properties);

            new OLA(stream, 1000, 500);
        }
Exemplo n.º 2
0
        public void MonoOverlapAddRectangle()
        {
            var properties   = new AudioProperties(1, 44100, 32, AudioFormat.IEEE);
            var sourceStream = new SineGeneratorStream(44100, 440, TimeSpan.FromSeconds(1));
            var targetStream = new MemoryWriterStream(new System.IO.MemoryStream(), properties);

            // Rectangular window (samples unchanged) with no overlap should just reconstruct the original stream
            int windowSize = 100;
            int hopSize    = 100;
            var window     = WindowType.Rectangle;

            var sw  = new StreamWindower(sourceStream, windowSize, hopSize, window);
            var ola = new OLA(targetStream, windowSize, hopSize);

            var frameBuffer = new float[windowSize];

            while (sw.HasNext())
            {
                sw.ReadFrame(frameBuffer);
                ola.WriteFrame(frameBuffer);
            }
            ola.Flush();

            Assert.AreEqual(sourceStream.Length, targetStream.Length);

            // Validate ola target stream content
            sourceStream.Position = targetStream.Position = 0;
            long similarFloats = StreamUtil.CompareFloats(sourceStream, targetStream);

            Assert.AreEqual(sourceStream.Length / sourceStream.SampleBlockSize, similarFloats);
        }
Exemplo n.º 3
0
        public void CreateOverlapTooLarge()
        {
            var properties = new AudioProperties(1, 44100, 16, AudioFormat.IEEE);
            var stream     = new MemoryWriterStream(new System.IO.MemoryStream(), properties);

            new OLA(stream, 1000, 1001);
        }
Exemplo n.º 4
0
        public void MonoOverlapAddHann()
        {
            var                properties   = new AudioProperties(1, 44100, 32, AudioFormat.IEEE);
            IAudioStream       sourceStream = new SineGeneratorStream(44100, 440, TimeSpan.FromSeconds(1));
            IAudioWriterStream targetStream = new MemoryWriterStream(new System.IO.MemoryStream(), properties);

            // 50% overlap with a Hann window is an optimal combination, Hann window is optimally uneven with a 1 as middle point
            int windowSize = 21;
            int hopSize    = 11;
            var window     = WindowType.Hann;

            // Adjust source length to window/hop size so no samples remain at the end
            // (a potential last incomplete frame is not returned by the stream windower)
            // With remaining samples, the source and target length cannot be compared
            sourceStream = new CropStream(sourceStream, 0,
                                          sourceStream.Length
                                          - (sourceStream.Length - windowSize * sourceStream.SampleBlockSize)
                                          % (hopSize * sourceStream.SampleBlockSize));

            var sw  = new StreamWindower(sourceStream, windowSize, hopSize, window);
            var ola = new OLA(targetStream, windowSize, hopSize);

            var frameBuffer = new float[windowSize];

            while (sw.HasNext())
            {
                sw.ReadFrame(frameBuffer);
                ola.WriteFrame(frameBuffer);
            }
            ola.Flush();

            Assert.AreEqual(sourceStream.Length, targetStream.Length);

            // Validate ola target stream content
            // Crop the streams to ignore windowed start and end when no overlap-add is performed and content definitely differs

            var sourceStreamCropped = new CropStream(sourceStream,
                                                     hopSize * sourceStream.SampleBlockSize * 2,
                                                     sourceStream.Length - hopSize * sourceStream.SampleBlockSize);

            var targetStreamCropped = new CropStream(targetStream,
                                                     hopSize * sourceStream.SampleBlockSize * 2,
                                                     sourceStream.Length - hopSize * sourceStream.SampleBlockSize);

            sourceStreamCropped.Position = targetStreamCropped.Position = 0;

            long similarFloats = StreamUtil.CompareFloats(sourceStreamCropped, targetStreamCropped);

            Assert.AreEqual(sourceStreamCropped.Length / sourceStreamCropped.SampleBlockSize, similarFloats);
        }
        public void Write()
        {
            var stream     = new MemoryStream();
            var properties = new AudioProperties(2, 44100, 16, AudioFormat.IEEE);
            var writer     = new MemoryWriterStream(stream, properties);

            Assert.AreEqual(0, writer.Length);

            int size = writer.SampleBlockSize * 1000;

            writer.Write(new byte[size], 0, size);

            Assert.AreEqual(size, writer.Length);
        }
        /// <summary>
        /// Creates a Wave format proxy file in the same directory and with the same name as the specified file,
        /// if no storage directory is specified (i.e. if it is null). If a storage directory is specified, the proxy
        /// file will be stored in the specified directory with a hashed file name to avoid name collisions and
        /// file overwrites. The story directory option is convenient for the usage of temporary or working directories.
        /// </summary>
        /// <param name="fileInfo">the file for which a proxy file should be created</param>
        /// <param name="storageDirectory">optional directory where the proxy file will be stored, can be null</param>
        /// <returns>the FileInfo of the proxy file</returns>
        public static FileInfo CreateWaveProxy(FileInfo fileInfo, DirectoryInfo storageDirectory)
        {
            FileInfo outputFileInfo;

            if (storageDirectory == null)
            {
                // Without a storage directory, store the proxy file beside the original file
                outputFileInfo = new FileInfo(fileInfo.FullName + ".ffproxy.wav");
            }
            else
            {
                // With a storage directory specified, store the proxy file with a hashed name
                // (to avoid name collision / overwrites) in the target directory (e.g. a temp or working directory)
                using (var sha256 = SHA256.Create()) {
                    byte[] hash       = sha256.ComputeHash(Encoding.Unicode.GetBytes(fileInfo.FullName));
                    string hashString = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
                    outputFileInfo = new FileInfo(Path.Combine(storageDirectory.FullName, hashString + ".ffproxy.wav"));
                }
            }


            if (outputFileInfo.Exists)
            {
                Console.WriteLine("Proxy already existing, using " + outputFileInfo.Name);
                return(outputFileInfo);
            }

            var reader = new FFmpegReader(fileInfo, FFmpeg.Type.Audio);

            var writer = new MemoryWriterStream(new AudioProperties(
                                                    reader.AudioOutputConfig.format.channels,
                                                    reader.AudioOutputConfig.format.sample_rate,
                                                    reader.AudioOutputConfig.format.sample_size * 8,
                                                    reader.AudioOutputConfig.format.sample_size == 4 ? AudioFormat.IEEE : AudioFormat.LPCM));

            int output_buffer_size = reader.AudioOutputConfig.frame_size * writer.SampleBlockSize;

            byte[] output_buffer = new byte[output_buffer_size];

            int  samplesRead;
            long timestamp;

            FFmpeg.Type type;

            // sequentially read samples from decoder and write it to wav file
            while ((samplesRead = reader.ReadFrame(out timestamp, output_buffer, output_buffer_size, out type)) > 0)
            {
                int bytesRead = samplesRead * writer.SampleBlockSize;
                writer.Write(output_buffer, 0, bytesRead);
            }

            reader.Dispose();

            writer.Position = 0;

            AudioStreamFactory.WriteToFile(writer, outputFileInfo.FullName);

            writer.Close();

            return(outputFileInfo);
        }