Exemplo n.º 1
0
        public static IAudioDest GetAudioDest(AudioEncoderType audioEncoderType, string path, AudioPCMConfig pcm, long finalSampleCount, int padding, string extension, CUEConfig config)
        {
            IAudioDest dest;

            if (audioEncoderType == AudioEncoderType.NoAudio || extension == ".dummy")
            {
                return new DummyWriter(path, new AudioEncoderSettings(pcm))
                       {
                           FinalSampleCount = finalSampleCount
                       }
            }
            ;
            CUEToolsFormat fmt;

            if (!extension.StartsWith(".") || !config.formats.TryGetValue(extension.Substring(1), out fmt))
            {
                throw new Exception("Unsupported audio type: " + path);
            }
            CUEToolsUDC encoder = audioEncoderType == AudioEncoderType.Lossless ? fmt.encoderLossless :
                                  audioEncoderType == AudioEncoderType.Lossy ? fmt.encoderLossy :
                                  null;

            if (encoder == null)
            {
                throw new Exception("Unsupported audio type: " + path);
            }
            var settings = encoder.settings.Clone();

            settings.PCM     = pcm;
            settings.Padding = padding;
            object o;

            try
            {
                o = Activator.CreateInstance(encoder.type, path, settings);
            }
            catch (System.Reflection.TargetInvocationException ex)
            {
                throw ex.InnerException;
            }
            if (o == null || !(o is IAudioDest))
            {
                throw new Exception("Unsupported audio type: " + path + ": " + encoder.type.FullName);
            }
            dest = o as IAudioDest;
            dest.FinalSampleCount = finalSampleCount;
            return(dest);
        }
    }
Exemplo n.º 2
0
        private void buttonEncoderDelete_Click(object sender, EventArgs e)
        {
            CUEToolsUDC encoder = encodersBindingSource.Current as CUEToolsUDC;

            if (encoder == null || !encoder.CanBeDeleted)
            {
                return;
            }
            if (_config.formats[encoder.extension].encoderLossless == encoder)
            {
                _config.formats[encoder.extension].encoderLossless = null;
            }
            if (_config.formats[encoder.extension].encoderLossy == encoder)
            {
                _config.formats[encoder.extension].encoderLossy = null;
            }
            encodersBindingSource.RemoveCurrent();
        }
Exemplo n.º 3
0
        private void encodersBindingSource_CurrentItemChanged(object sender, EventArgs e)
        {
            CUEToolsUDC encoder = encodersBindingSource.Current as CUEToolsUDC;

            if (encoder == null)
            {
                labelEncoderExtension.Visible                           =
                    comboBoxEncoderExtension.Visible                    =
                        comboBoxEncoderExtension.Enabled                =
                            groupBoxExternalEncoder.Visible             =
                                checkBoxEncoderLossless.Enabled         =
                                    propertyGridEncoderSettings.Visible = false;
                propertyGridEncoderSettings.SelectedObject              = null;
            }
            else
            {
                CUEToolsFormat format = _config.formats[encoder.extension];                 // _config.formats.TryGetValue(encoder.extension, out format)
                labelEncoderExtension.Visible              = true;
                comboBoxEncoderExtension.Visible           = true;
                comboBoxEncoderExtension.Enabled           = encoder.CanBeDeleted;
                groupBoxExternalEncoder.Visible            = encoder.CanBeDeleted;
                checkBoxEncoderLossless.Enabled            = format != null && format.allowLossless && format.allowLossy;
                propertyGridEncoderSettings.Visible        = !encoder.CanBeDeleted && encoder.settings.HasBrowsableAttributes();
                propertyGridEncoderSettings.SelectedObject = encoder.CanBeDeleted ? null : encoder.settings;
                if (!checkBoxEncoderLossless.Enabled && format != null && encoder.Lossless != format.allowLossless)
                {
                    encoder.Lossless = format.allowLossless;
                }
                foreach (KeyValuePair <string, CUEToolsFormat> fmtEntry in _config.formats)
                {
                    CUEToolsFormat fmt = fmtEntry.Value;
                    if (fmt.encoderLossless == encoder && (fmt.extension != encoder.extension || !encoder.Lossless))
                    {
                        fmt.encoderLossless = null;
                    }
                    if (fmt.encoderLossy == encoder && (fmt.extension != encoder.extension || encoder.Lossless))
                    {
                        fmt.encoderLossy = null;
                    }
                }
            }
        }
Exemplo n.º 4
0
 public CUEToolsFormat(
     string _extension,
     CUEToolsTagger _tagger,
     bool _allowLossless,
     bool _allowLossy,
     bool _allowEmbed,
     bool _builtin,
     CUEToolsUDC _encoderLossless,
     CUEToolsUDC _encoderLossy,
     CUEToolsUDC _decoder)
 {
     extension = _extension;
     tagger = _tagger;
     allowLossless = _allowLossless;
     allowLossy = _allowLossy;
     allowEmbed = _allowEmbed;
     builtin = _builtin;
     encoderLossless = _encoderLossless;
     encoderLossy = _encoderLossy;
     decoder = _decoder;
 }
Exemplo n.º 5
0
 public CUEToolsFormat(
     string _extension,
     CUEToolsTagger _tagger,
     bool _allowLossless,
     bool _allowLossy,
     bool _allowEmbed,
     bool _builtin,
     CUEToolsUDC _encoderLossless,
     CUEToolsUDC _encoderLossy,
     CUEToolsUDC _decoder)
 {
     extension       = _extension;
     tagger          = _tagger;
     allowLossless   = _allowLossless;
     allowLossy      = _allowLossy;
     allowEmbed      = _allowEmbed;
     builtin         = _builtin;
     encoderLossless = _encoderLossless;
     encoderLossy    = _encoderLossy;
     decoder         = _decoder;
 }
Exemplo n.º 6
0
 public frmSettings(CUEToolsUDC encoder)
 {
     InitializeComponent();
     m_encoder = encoder;
 }
Exemplo n.º 7
0
        public void Load(SettingsReader sr)
        {
            int version = sr.LoadInt32("Version", null, null) ?? 202;

            fixOffsetMinimumConfidence    = sr.LoadUInt32("ArFixWhenConfidence", 1, 1000) ?? 2;
            fixOffsetMinimumTracksPercent = sr.LoadUInt32("ArFixWhenPercent", 1, 100) ?? 51;
            encodeWhenConfidence          = sr.LoadUInt32("ArEncodeWhenConfidence", 1, 1000) ?? 2;
            encodeWhenPercent             = sr.LoadUInt32("ArEncodeWhenPercent", 1, 100) ?? 100;
            encodeWhenZeroOffset          = sr.LoadBoolean("ArEncodeWhenZeroOffset") ?? false;
            noUnverifiedOutput            = sr.LoadBoolean("ArNoUnverifiedOutput") ?? false;
            fixOffset           = sr.LoadBoolean("ArFixOffset") ?? false;
            writeArTagsOnEncode = sr.LoadBoolean("ArWriteCRC") ?? writeArTagsOnEncode;
            writeArLogOnConvert = sr.LoadBoolean("ArWriteLog") ?? true;
            writeArTagsOnVerify = sr.LoadBoolean("ArWriteTagsOnVerify") ?? false;
            writeArLogOnVerify  = sr.LoadBoolean("ArWriteLogOnVerify") ?? false;

            preserveHTOA          = sr.LoadBoolean("PreserveHTOA") ?? true;
            detectGaps            = sr.LoadBoolean("DetectGaps") ?? true;
            autoCorrectFilenames  = sr.LoadBoolean("AutoCorrectFilenames") ?? true;
            keepOriginalFilenames = sr.LoadBoolean("KeepOriginalFilenames") ?? false;
            singleFilenameFormat  = sr.Load("SingleFilenameFormat") ?? singleFilenameFormat;
            trackFilenameFormat   = sr.Load("TrackFilenameFormat") ?? trackFilenameFormat;
            removeSpecial         = sr.LoadBoolean("RemoveSpecialCharacters") ?? false;
            specialExceptions     = sr.Load("SpecialCharactersExceptions") ?? "-()";
            replaceSpaces         = sr.LoadBoolean("ReplaceSpaces") ?? false;
            embedLog                  = sr.LoadBoolean("EmbedLog") ?? true;
            extractLog                = sr.LoadBoolean("ExtractLog") ?? true;
            fillUpCUE                 = sr.LoadBoolean("FillUpCUE") ?? true;
            overwriteCUEData          = sr.LoadBoolean("OverwriteCUEData") ?? false;
            filenamesANSISafe         = sr.LoadBoolean("FilenamesANSISafe") ?? true;
            bruteForceDTL             = sr.LoadBoolean("BruteForceDTL") ?? false;
            createEACLOG              = sr.LoadBoolean("CreateEACLOG") ?? createEACLOG;
            detectHDCD                = sr.LoadBoolean("DetectHDCD") ?? true;
            wait750FramesForHDCD      = sr.LoadBoolean("Wait750FramesForHDCD") ?? true;
            decodeHDCD                = sr.LoadBoolean("DecodeHDCD") ?? false;
            createM3U                 = sr.LoadBoolean("CreateM3U") ?? false;
            createCUEFileWhenEmbedded = sr.LoadBoolean("CreateCUEFileWhenEmbedded") ?? true;
            truncate4608ExtraSamples  = sr.LoadBoolean("Truncate4608ExtraSamples") ?? true;
            decodeHDCDtoLW16          = sr.LoadBoolean("DecodeHDCDToLossyWAV16") ?? false;
            decodeHDCDto24bit         = sr.LoadBoolean("DecodeHDCDTo24bit") ?? true;

            oneInstance     = sr.LoadBoolean("OneInstance") ?? true;
            checkForUpdates = sr.LoadBoolean("CheckForUpdates") ?? true;

            writeBasicTagsFromCUEData = sr.LoadBoolean("WriteBasicTagsFromCUEData") ?? true;
            copyBasicTags             = sr.LoadBoolean("CopyBasicTags") ?? true;
            copyUnknownTags           = sr.LoadBoolean("CopyUnknownTags") ?? true;
            CopyAlbumArt    = sr.LoadBoolean("CopyAlbumArt") ?? true;
            embedAlbumArt   = sr.LoadBoolean("EmbedAlbumArt") ?? true;
            extractAlbumArt = sr.LoadBoolean("ExtractAlbumArt") ?? true;
            maxAlbumArtSize = sr.LoadInt32("MaxAlbumArtSize", 100, 10000) ?? maxAlbumArtSize;

            arLogToSourceFolder = sr.LoadBoolean("ArLogToSourceFolder") ?? arLogToSourceFolder;
            arLogVerbose        = sr.LoadBoolean("ArLogVerbose") ?? arLogVerbose;
            fixOffsetToNearest  = sr.LoadBoolean("FixOffsetToNearest") ?? fixOffsetToNearest;
            ArLogFilenameFormat = sr.Load("ArLogFilenameFormat") ?? ArLogFilenameFormat;
            AlArtFilenameFormat = sr.Load("AlArtFilenameFormat") ?? AlArtFilenameFormat;

            separateDecodingThread = sr.LoadBoolean("SeparateDecodingThread") ?? separateDecodingThread;

            try
            {
                using (TextReader reader = new StringReader(sr.Load("Advanced")))
                    advanced = CUEConfigAdvanced.serializer.Deserialize(reader) as CUEConfigAdvanced;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.Message);
            }

            int totalEncoders = sr.LoadInt32("ExternalEncoders", 0, null) ?? 0;

            for (int nEncoders = 0; nEncoders < totalEncoders; nEncoders++)
            {
                string      name      = sr.Load(string.Format("ExternalEncoder{0}Name", nEncoders));
                string      extension = sr.Load(string.Format("ExternalEncoder{0}Extension", nEncoders));
                string      settings  = sr.Load(string.Format("ExternalEncoder{0}Settings", nEncoders));
                bool        lossless  = sr.LoadBoolean(string.Format("ExternalEncoder{0}Lossless", nEncoders)) ?? true;
                CUEToolsUDC encoder;
                if (name == null || extension == null)
                {
                    continue;
                }
                if (!encoders.TryGetValue(extension, lossless, name, out encoder))
                {
                    encoder = new CUEToolsUDC(name, extension, lossless, "", "", "", "");
                    encoders.Add(encoder);
                }
                try
                {
                    using (TextReader reader = new StringReader(settings))
                        encoder.settings = encoder.settingsSerializer.Deserialize(reader) as AudioEncoderSettings;
                    if (encoder.settings is UserDefinedEncoderSettings && (encoder.settings as UserDefinedEncoderSettings).Path == "")
                    {
                        throw new Exception();
                    }
                }
                catch
                {
                    if (version == 203 && encoder.settings is UserDefinedEncoderSettings)
                    {
                        (encoder.settings as UserDefinedEncoderSettings).SupportedModes = sr.Load(string.Format("ExternalEncoder{0}Modes", nEncoders));
                        (encoder.settings as UserDefinedEncoderSettings).EncoderMode    = sr.Load(string.Format("ExternalEncoder{0}Mode", nEncoders));
                        (encoder.settings as UserDefinedEncoderSettings).Path           = sr.Load(string.Format("ExternalEncoder{0}Path", nEncoders));
                        (encoder.settings as UserDefinedEncoderSettings).Parameters     = sr.Load(string.Format("ExternalEncoder{0}Parameters", nEncoders));
                    }
                    else
                    {
                        encoders.Remove(encoder);
                    }
                }
            }

            int totalDecoders = sr.LoadInt32("ExternalDecoders", 0, null) ?? 0;

            for (int nDecoders = 0; nDecoders < totalDecoders; nDecoders++)
            {
                string      name       = sr.Load(string.Format("ExternalDecoder{0}Name", nDecoders));
                string      extension  = sr.Load(string.Format("ExternalDecoder{0}Extension", nDecoders));
                string      path       = sr.Load(string.Format("ExternalDecoder{0}Path", nDecoders));
                string      parameters = sr.Load(string.Format("ExternalDecoder{0}Parameters", nDecoders));
                CUEToolsUDC decoder;
                if (!decoders.TryGetValue(extension, true, name, out decoder))
                {
                    decoders.Add(new CUEToolsUDC(name, extension, path, parameters));
                }
                else
                {
                    decoder.extension  = extension;
                    decoder.path       = path;
                    decoder.parameters = parameters;
                }
            }

            int totalFormats = sr.LoadInt32("CustomFormats", 0, null) ?? 0;

            for (int nFormats = 0; nFormats < totalFormats; nFormats++)
            {
                string         extension       = sr.Load(string.Format("CustomFormat{0}Name", nFormats));
                string         encoderLossless = sr.Load(string.Format("CustomFormat{0}EncoderLossless", nFormats)) ?? "";
                string         encoderLossy    = sr.Load(string.Format("CustomFormat{0}EncoderLossy", nFormats)) ?? "";
                string         decoder         = sr.Load(string.Format("CustomFormat{0}Decoder", nFormats));
                CUEToolsTagger tagger          = (CUEToolsTagger)(sr.LoadInt32(string.Format("CustomFormat{0}Tagger", nFormats), 0, 2) ?? 0);
                bool           allowLossless   = sr.LoadBoolean(string.Format("CustomFormat{0}AllowLossless", nFormats)) ?? false;
                bool           allowLossy      = sr.LoadBoolean(string.Format("CustomFormat{0}AllowLossy", nFormats)) ?? false;
                bool           allowEmbed      = sr.LoadBoolean(string.Format("CustomFormat{0}AllowEmbed", nFormats)) ?? false;
                CUEToolsFormat format;
                CUEToolsUDC    udcLossless, udcLossy, udcDecoder;
                if (encoderLossless == "" || !encoders.TryGetValue(extension, true, encoderLossless, out udcLossless))
                {
                    udcLossless = encoders.GetDefault(extension, true);
                }
                if (encoderLossy == "" || !encoders.TryGetValue(extension, false, encoderLossy, out udcLossy))
                {
                    udcLossy = encoders.GetDefault(extension, false);
                }
                if (decoder == "" || !decoders.TryGetValue(extension, true, decoder, out udcDecoder))
                {
                    udcDecoder = decoders.GetDefault(extension, true);
                }
                if (!formats.TryGetValue(extension, out format))
                {
                    formats.Add(extension, new CUEToolsFormat(extension, tagger, allowLossless, allowLossy, allowEmbed, false, udcLossless, udcLossy, udcDecoder));
                }
                else
                {
                    format.encoderLossless = udcLossless;
                    format.encoderLossy    = udcLossy;
                    format.decoder         = udcDecoder;
                    if (!format.builtin)
                    {
                        format.tagger        = tagger;
                        format.allowLossless = allowLossless;
                        format.allowLossy    = allowLossy;
                        format.allowEmbed    = allowEmbed;
                    }
                }
            }

            defaultVerifyScript = sr.Load("DefaultVerifyScript") ?? "default";
            defaultEncodeScript = sr.Load("DefaultVerifyAndConvertScript") ?? "default";

            gapsHandling = (CUEStyle?)sr.LoadInt32("GapsHandling", null, null) ?? gapsHandling;

            language = sr.Load("Language") ?? Thread.CurrentThread.CurrentUICulture.Name;

            if (ArLogFilenameFormat.Contains("%F"))
            {
                ArLogFilenameFormat = "%filename%.accurip";
            }
            if (singleFilenameFormat.Contains("%F"))
            {
                singleFilenameFormat = "%filename%";
            }
            if (trackFilenameFormat.Contains("%N"))
            {
                trackFilenameFormat = "%tracknumber%. %title%";
            }
        }
Exemplo n.º 8
0
        static int Main(string[] args)
        {
            bool             ok = true;
            string           sourceFile = null, destFile = null;
            int              padding            = 8192;
            string           encoderMode        = null;
            string           decoderName        = null;
            string           encoderName        = null;
            string           encoderFormat      = null;
            bool             ignore_chunk_sizes = false;
            AudioEncoderType audioEncoderType   = AudioEncoderType.NoAudio;

            for (int arg = 0; arg < args.Length; arg++)
            {
                if (args[arg].Length == 0)
                {
                    ok = false;
                }
                else if (args[arg] == "--ignore-chunk-sizes")
                {
                    ignore_chunk_sizes = true;
                }
                else if (args[arg] == "--decoder" && ++arg < args.Length)
                {
                    decoderName = args[arg];
                }
                else if (args[arg] == "--encoder" && ++arg < args.Length)
                {
                    encoderName = args[arg];
                }
                else if (args[arg] == "--encoder-format" && ++arg < args.Length)
                {
                    encoderFormat = args[arg];
                }
                else if ((args[arg] == "-p" || args[arg] == "--padding") && ++arg < args.Length)
                {
                    ok = int.TryParse(args[arg], out padding);
                }
                else if ((args[arg] == "-m" || args[arg] == "--mode") && ++arg < args.Length)
                {
                    encoderMode = args[arg];
                }
                else if (args[arg] == "--lossy")
                {
                    audioEncoderType = AudioEncoderType.Lossy;
                }
                else if (args[arg] == "--lossless")
                {
                    audioEncoderType = AudioEncoderType.Lossless;
                }
                else if ((args[arg][0] != '-' || args[arg] == "-") && sourceFile == null)
                {
                    sourceFile = args[arg];
                }
                else if ((args[arg][0] != '-' || args[arg] == "-") && sourceFile != null && destFile == null)
                {
                    destFile = args[arg];
                }
                else
                {
                    ok = false;
                }
                if (!ok)
                {
                    break;
                }
            }

            Console.Error.WriteLine("CUETools.Converter, Copyright (C) 2009-2013 Grigory Chudov.");
            Console.Error.WriteLine("This is free software under the GNU GPLv3+ license; There is NO WARRANTY, to");
            Console.Error.WriteLine("the extent permitted by law. <http://www.gnu.org/licenses/> for details.");
            if (!ok || sourceFile == null || destFile == null)
            {
                Usage();
                return(22);
            }

            if (destFile != "-" && destFile != "nul" && File.Exists(destFile))
            {
                Console.Error.WriteLine("Error: file already exists.");
                return(17);
            }

            DateTime             start     = DateTime.Now;
            TimeSpan             lastPrint = TimeSpan.FromMilliseconds(0);
            CUEToolsCodecsConfig config    = new CUEConfig();

#if !DEBUG
            try
#endif
            {
                IAudioSource audioSource = null;
                IAudioDest   audioDest   = null;
                TagLib.UserDefined.AdditionalFileTypes.Config = config;
                TagLib.File sourceInfo = sourceFile == "-" ? null : TagLib.File.Create(new TagLib.File.LocalFileAbstraction(sourceFile));

                try
                {
                    audioSource = Program.GetAudioSource(config, sourceFile, decoderName, ignore_chunk_sizes);
                    AudioBuffer buff = new AudioBuffer(audioSource, 0x10000);
                    Console.Error.WriteLine("Filename  : {0}", sourceFile);
                    Console.Error.WriteLine("File Info : {0}kHz; {1} channel; {2} bit; {3}", audioSource.PCM.SampleRate, audioSource.PCM.ChannelCount, audioSource.PCM.BitsPerSample, TimeSpan.FromSeconds(audioSource.Length * 1.0 / audioSource.PCM.SampleRate));

                    CUEToolsFormat fmt;
                    if (encoderFormat == null)
                    {
                        if (destFile == "-" || destFile == "nul")
                        {
                            encoderFormat = "wav";
                        }
                        else
                        {
                            string extension = Path.GetExtension(destFile).ToLower();
                            if (!extension.StartsWith("."))
                            {
                                throw new Exception("Unknown encoder format: " + destFile);
                            }
                            encoderFormat = extension.Substring(1);
                        }
                    }
                    if (!config.formats.TryGetValue(encoderFormat, out fmt))
                    {
                        throw new Exception("Unsupported encoder format: " + encoderFormat);
                    }
                    CUEToolsUDC encoder =
                        audioEncoderType == AudioEncoderType.Lossless ? Program.GetEncoder(config, fmt, true, encoderName) :
                        audioEncoderType == AudioEncoderType.Lossy ? Program.GetEncoder(config, fmt, false, encoderName) :
                        Program.GetEncoder(config, fmt, true, encoderName) ?? Program.GetEncoder(config, fmt, false, encoderName);
                    if (encoder == null)
                    {
                        var lst = new List <CUEToolsUDC>(config.encoders).FindAll(
                            e => e.extension == fmt.extension && (audioEncoderType == AudioEncoderType.NoAudio || audioEncoderType == (e.Lossless ? AudioEncoderType.Lossless : AudioEncoderType.Lossy))).
                                  ConvertAll(e => e.Name + (e.Lossless ? " (lossless)" : " (lossy)"));
                        throw new Exception("Encoders available for format " + fmt.extension + ": " + (lst.Count == 0 ? "none" : string.Join(", ", lst.ToArray())));
                    }
                    var settings = encoder.settings.Clone();
                    settings.PCM         = audioSource.PCM;
                    settings.Padding     = padding;
                    settings.EncoderMode = encoderMode ?? settings.EncoderMode;
                    object o = null;
                    try
                    {
                        o = destFile == "-" ? Activator.CreateInstance(encoder.type, "", Console.OpenStandardOutput(), settings) :
                            destFile == "nul" ? Activator.CreateInstance(encoder.type, "", new NullStream(), settings) :
                            Activator.CreateInstance(encoder.type, destFile, settings);
                    }
                    catch (System.Reflection.TargetInvocationException ex)
                    {
                        throw ex.InnerException;
                    }
                    if (o == null || !(o is IAudioDest))
                    {
                        throw new Exception("Unsupported audio type: " + destFile + ": " + encoder.type.FullName);
                    }
                    audioDest = o as IAudioDest;
                    audioDest.FinalSampleCount = audioSource.Length;

                    bool keepRunning = true;
                    Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
                    {
                        keepRunning = false;
                        if (e.SpecialKey == ConsoleSpecialKey.ControlC)
                        {
                            e.Cancel = true;
                        }
                        else
                        {
                            audioDest.Delete();
                        }
                    };

                    while (audioSource.Read(buff, -1) != 0)
                    {
                        audioDest.Write(buff);
                        TimeSpan elapsed = DateTime.Now - start;
                        if ((elapsed - lastPrint).TotalMilliseconds > 60)
                        {
                            long length = audioSource.Length;
                            if (length < 0 && sourceInfo != null)
                            {
                                length = (long)(sourceInfo.Properties.Duration.TotalMilliseconds * audioSource.PCM.SampleRate / 1000);
                            }
                            if (length < audioSource.Position)
                            {
                                length = audioSource.Position;
                            }
                            if (length < 1)
                            {
                                length = 1;
                            }
                            Console.Error.Write("\rProgress  : {0:00}%; {1:0.00}x; {2}/{3}",
                                                100.0 * audioSource.Position / length,
                                                audioSource.Position / elapsed.TotalSeconds / audioSource.PCM.SampleRate,
                                                elapsed,
                                                TimeSpan.FromMilliseconds(elapsed.TotalMilliseconds / audioSource.Position * length)
                                                );
                            lastPrint = elapsed;
                        }
                        if (!keepRunning)
                        {
                            throw new Exception("Aborted");
                        }
                    }

                    TimeSpan totalElapsed = DateTime.Now - start;
                    Console.Error.Write("\r                                                                         \r");
                    Console.Error.WriteLine("Results   : {0:0.00}x; {1}",
                                            audioSource.Position / totalElapsed.TotalSeconds / audioSource.PCM.SampleRate,
                                            totalElapsed
                                            );
                }
                catch (Exception ex)
                {
                    if (audioSource != null)
                    {
                        audioSource.Close();
                    }
                    if (audioDest != null)
                    {
                        audioDest.Delete();
                    }
                    throw ex;
                }
                audioSource.Close();
                audioDest.Close();

                if (sourceFile != "-" && destFile != "-" && destFile != "nul")
                {
                    TagLib.File destInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(destFile));
                    if (Tagging.UpdateTags(destInfo, Tagging.Analyze(sourceInfo), config, false))
                    {
                        sourceInfo.Tag.CopyTo(destInfo.Tag, true);
                        destInfo.Tag.Pictures = sourceInfo.Tag.Pictures;
                        destInfo.Save();
                    }
                }
            }
#if !DEBUG
            catch (Exception ex)
            {
                Console.Error.Write("\r                                                                         \r");
                Console.Error.WriteLine("Error     : {0}", ex.Message);
                return(1);
                //Console.WriteLine("{0}", ex.StackTrace);
            }
#endif
            return(0);
        }