private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker     = sender as BackgroundWorker;
            Parameters       parameters = (Parameters)e.Argument;

            var streams = parameters.SourceFiles.Select(fi => AudioStreamFactory.FromFileInfo(fi));

            // load source stream
            var sourceStream = new ConcatenationStream(streams.ToArray());

            var    firstFile            = parameters.SourceFiles.First();
            string targetFileNamePrefix = firstFile.FullName.Remove(firstFile.FullName.Length - firstFile.Extension.Length);
            string targetFileNameSuffix = firstFile.Extension;

            int        partCount  = 0;
            Random     random     = new Random();
            CropStream cropStream = new CropStream(sourceStream, 0, 0);

            while (sourceStream.Position < sourceStream.Length)
            {
                partCount++;
                int  length     = random.Next(parameters.MinLength, parameters.MaxLength); // length in seconds of the current part to write
                long byteLength = TimeUtil.TimeSpanToBytes(new TimeSpan(TimeUtil.SECS_TO_TICKS * length), cropStream.Properties);

                Debug.WriteLine("writing part " + partCount + " (" + length + " secs = " + byteLength + " bytes)");
                Debug.WriteLine("before: " + cropStream.Begin + " / " + cropStream.End + " / " + cropStream.Position + " / " + sourceStream.Position);
                cropStream.Begin    = cropStream.End;
                cropStream.End     += sourceStream.Length - cropStream.Begin < byteLength ? sourceStream.Length - cropStream.Begin : byteLength;
                cropStream.Position = 0;
                Debug.WriteLine("after : " + cropStream.Begin + " / " + cropStream.End + " / " + cropStream.Position + " / " + sourceStream.Position);
                AudioStreamFactory.WriteToFile(cropStream, String.Format("{0}.part{1:000}{2}", targetFileNamePrefix, partCount, targetFileNameSuffix));

                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    Debug.WriteLine("canceled");
                    return;
                }
                worker.ReportProgress((int)((double)sourceStream.Position / sourceStream.Length * 100));
            }
            Debug.WriteLine("finished");
        }
示例#2
0
        static void Process(Dictionary <string, double> mapping, DirectoryInfo indir, DirectoryInfo outdir)
        {
            Dictionary <FileInfo, double> fileMapping = new Dictionary <FileInfo, double>();

            foreach (string fileNamePattern in mapping.Keys)
            {
                double factor = mapping[fileNamePattern];
                foreach (FileInfo fileInfo in indir.EnumerateFiles(fileNamePattern))
                {
                    fileMapping.Add(fileInfo, factor);
                }
            }

            Parallel.ForEach <FileInfo>(fileMapping.Keys, (fileInfo) => {
                double factor           = fileMapping[fileInfo];
                FileInfo outputFileInfo = new FileInfo(Path.Combine(outdir.FullName, fileInfo.Name));

                if (outputFileInfo.Exists)
                {
                    Console.WriteLine(fileInfo.Name + " SKIP (file already existing)");
                    return;
                }

                Console.WriteLine(fileInfo.Name);
                try
                {
                    IAudioStream inputStream          = AudioStreamFactory.FromFileInfoIeee32(fileInfo);
                    IAudioStream resamplingStream     = new ResamplingStream(inputStream, ResamplingQuality.VeryHigh, factor);
                    MixerStream sampleRateResetStream = new MixerStream(resamplingStream.Properties.Channels, inputStream.Properties.SampleRate);
                    sampleRateResetStream.Add(resamplingStream);

                    IAudioStream outputStream = sampleRateResetStream;

                    AudioStreamFactory.WriteToFile(outputStream, outputFileInfo.FullName);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error processing " + fileInfo.Name + ": " + e.Message);
                }
            });
        }
        /// <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);
        }