Files
cuetools.net/CUETools.eac3to/Program.cs

490 lines
27 KiB
C#
Raw Normal View History

using CUETools.CDImage;
2018-02-17 20:35:34 -05:00
using CUETools.Codecs;
using CUETools.CTDB;
using CUETools.Processor;
using System;
using System.Collections.Generic;
2018-04-29 16:53:55 -04:00
using System.ComponentModel;
using System.IO;
2018-02-18 15:57:27 -05:00
using System.Text;
2018-02-17 20:35:34 -05:00
namespace CUETools.eac3to
{
class Program
{
static void Usage()
{
Bump copyright year to 2020 The copyright year was last time updated in 2018. There is some cleanup involved in this commit and the next copyright year update is supposed to be simpler (i.e. substitute "-2020"). - Substitute occurrences of "-2018" with "-2020" using: git grep -I -l -e '-2018' -- ':(exclude)*.bak' | xargs \ sed -b -i -e 's/-2018/-2020/g' - Update special cases: CUEPlayer git grep -I -l -e 'Grigory Chudov 2010' -- | xargs \ sed -b -i -e 's/Grigory Chudov 2010/2010-2020 Grigory Chudov/g' CUERipper git grep -I -l -e '2008-2009' -- | xargs \ sed -b -i -e 's/2008-2009/2008-2020/g' CUETools, CUETools.FLACCL.cmd git grep -I -l -e '2008-2010' -- ':(exclude)*FlaCuda*' | xargs \ sed -b -i -e 's/2008-2010/2008-2020/g' git grep -I -l -e '2010-2013' -- | xargs \ sed -b -i -e 's/2010-2013/2010-2020/g' CUETools.ChaptersToCue git grep -I -l -e 'Grigory Chudov 2017' -- | xargs \ sed -b -i -e 's/Grigory Chudov 2017/2017-2020 Grigory Chudov/g' CUETools.CTDB.EACPlugin git grep -I -l -e 'Grigory Chudov 2012' -- | xargs \ sed -b -i -e 's/Grigory Chudov 2012/2012-2020 Grigory Chudov/g' git grep -I -l -e '2011-12' -- | xargs \ sed -b -i -e 's/2011-12/2011-2020/g' CUETools.Codecs.FLACCL git grep -I -l -e '2009-2010' -- ':(exclude)*FlaCuda*' | xargs \ sed -b -i -e 's/2009-2010/2009-2020/g' CUETools.eac3ui (BluTools) git grep -I -l -e '© 2018' -- | xargs \ sed -b -i -e 's/© 2018/© 2018-2020 Grigory Chudov/g' CUETools.Flake git grep -I -l -e ' 2009-2014 Gr' -- | xargs \ sed -b -i -e 's/ 2009-2014 Gr/ 2009-2020 Gr/g' CUETools.Processor git grep -I -l -e ' 2008-2013 Gr' -- | xargs \ sed -b -i -e 's/ 2008-2013 Gr/ 2008-2020 Gr/g' CUETools.Ripper.Console git grep -I -l -e ' 2008-10 Gr' -- | xargs \ sed -b -i -e 's/ 2008-10 Gr/ 2008-2020 Gr/g' CUETools.Ripper.Console, CUETools.Ripper.SCSI git grep -I -l -e ' 2008-13 Gr' -- | xargs \ sed -b -i -e 's/ 2008-13 Gr/ 2008-2020 Gr/g' Single year entries: 2008, 2009, 2010, 2011, 2017, 2018 git grep -I -l -e ' 2008 Gr' -- | xargs \ sed -b -i -e 's/ 2008 Gr/ 2008-2020 Gr/g' git grep -I -l -e ' 2009 Gr' -- ':(exclude)*FlaCuda*' | xargs \ sed -b -i -e 's/ 2009 Gr/ 2009-2020 Gr/g' git grep -I -l -e ' 2010 Gr' -- | xargs \ sed -b -i -e 's/ 2010 Gr/ 2010-2020 Gr/g' git grep -I -l -e ' 2011 Gr' -- | xargs \ sed -b -i -e 's/ 2011 Gr/ 2011-2020 Gr/g' git grep -I -l -e ' 2017 Gr' -- | xargs \ sed -b -i -e 's/ 2017 Gr/ 2017-2020 Gr/g' git grep -I -l -e ' 2018 Gr' -- | xargs \ sed -b -i -e 's/ 2018 Gr/ 2018-2020 Gr/g' Fix typo in copyright year of CUETools.Codecs.WMA/AudioDecoder.cs: Copyright (c) 20139 Grigory Chudov git grep -I -lw -e '20139' -- | xargs \ sed -b -i -e 's/20139/2013-2020/g'
2020-01-30 18:13:46 +01:00
Console.Error.WriteLine("CUETools.eac3to, Copyright (C) 2018-2020 Grigory Chudov.");
2018-02-17 20:35:34 -05:00
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.");
Console.Error.WriteLine();
Console.Error.WriteLine("Usage : CUETools.eac3to.exe [options] <sourcefile> [trackno:] [destfile]");
Console.Error.WriteLine();
Console.Error.WriteLine("Options:");
Console.Error.WriteLine();
Console.Error.WriteLine(" --ctdb Query CTDB for metadata.");
2018-02-17 20:35:34 -05:00
Console.Error.WriteLine(" --encoder <name> Use non-default encoder.");
Console.Error.WriteLine(" --encoder-format <ext> Use encoder format different from file extension.");
Console.Error.WriteLine(" --lossy Use lossy encoder/mode.");
Console.Error.WriteLine(" --lossless Use lossless encoder/mode (default).");
Console.Error.WriteLine(" -p # Padding bytes.");
Console.Error.WriteLine(" -m <mode> Encoder mode (0..8 for flac, V0..V9 for mp3, etc)");
Console.Error.WriteLine();
}
public static AudioEncoderSettingsViewModel GetEncoder(CUEToolsCodecsConfig config, CUEToolsFormat fmt, bool lossless, string chosenEncoder)
2018-02-17 20:35:34 -05:00
{
AudioEncoderSettingsViewModel tmpEncoder;
2018-02-17 20:35:34 -05:00
return chosenEncoder != null ?
(config.encodersViewModel.TryGetValue(fmt.extension, lossless, chosenEncoder, out tmpEncoder) ? tmpEncoder : null) :
2018-02-17 20:35:34 -05:00
(lossless ? fmt.encoderLossless : fmt.encoderLossy);
}
static int Main(string[] args)
{
bool ok = true;
string sourceFile = null, destFile = null;
int padding = 8192;
int stream = 0;
string encoderMode = null;
string encoderName = null;
string encoderFormat = null;
AudioEncoderType audioEncoderType = AudioEncoderType.NoAudio;
2018-04-29 16:53:55 -04:00
var decoderOptions = new Dictionary<string, string>();
bool queryMeta = false;
2018-02-17 20:35:34 -05:00
for (int arg = 0; arg < args.Length; arg++)
{
if (args[arg].Length == 0)
ok = false;
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);
2018-04-29 16:53:55 -04:00
else if ((args[arg] == "-m" || args[arg] == "--mode") && arg + 1 < args.Length)
encoderMode = args[++arg];
2018-02-17 20:35:34 -05:00
else if (args[arg] == "--lossy")
audioEncoderType = AudioEncoderType.Lossy;
else if (args[arg] == "--lossless")
audioEncoderType = AudioEncoderType.Lossless;
else if (args[arg] == "--ctdb")
queryMeta = true;
2018-04-29 16:53:55 -04:00
else if (args[arg] == "--decoder-option" && arg + 2 < args.Length)
{
var optionName = args[++arg];
var optionValue = args[++arg];
decoderOptions.Add(optionName, optionValue);
}
2018-02-17 20:35:34 -05:00
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];
var x = destFile.Split(':');
if (x.Length > 1)
{
stream = int.Parse(x[0]);
if (x[1] != "")
{
destFile = x[1];
}
else
{
arg++;
if (arg >= args.Length)
{
ok = false;
break;
}
destFile = args[arg];
}
}
}
else
ok = false;
if (!ok)
break;
}
if (!ok || sourceFile == null)
{
Usage();
return 22;
}
if (destFile != null && destFile != "-" && destFile != "nul" && File.Exists(destFile))
{
Console.Error.WriteLine("Error: file {0} already exists.", destFile);
return 17;
}
DateTime start = DateTime.Now;
TimeSpan lastPrint = TimeSpan.FromMilliseconds(0);
var config = new CUEConfigAdvanced();
config.Init();
2018-02-17 20:35:34 -05:00
#if !DEBUG
try
#endif
{
2018-03-16 00:12:34 -04:00
IAudioSource audioSource = null;
2018-04-30 22:32:49 -04:00
IAudioTitleSet audioContainer = null;
2018-02-17 20:35:34 -05:00
IAudioDest audioDest = null;
var videos = new List<Codecs.MPEG.MPLS.MPLSStream>();
2018-04-30 22:32:49 -04:00
List<IAudioTitle> audios = null;
2018-04-29 16:53:55 -04:00
List<TimeSpan> chapters = null;
2018-02-17 20:35:34 -05:00
TagLib.UserDefined.AdditionalFileTypes.Config = config;
2018-04-07 13:55:01 -04:00
#if !DEBUG
2018-02-17 20:35:34 -05:00
try
2018-04-07 13:55:01 -04:00
#endif
2018-02-17 20:35:34 -05:00
{
2018-03-16 00:12:34 -04:00
if (true)
2018-02-17 20:35:34 -05:00
{
2018-04-29 16:53:55 -04:00
IAudioDecoderSettings decoderSettings = null;
if (Path.GetExtension(sourceFile) == ".mpls")
{
decoderSettings = new Codecs.MPEG.MPLS.DecoderSettings();
} else
{
decoderSettings = new Codecs.MPEG.ATSI.DecoderSettings();
}
foreach (var decOpt in decoderOptions)
{
var property = TypeDescriptor.GetProperties(decoderSettings).Find(decOpt.Key, true);
if (property == null)
throw new Exception($"{decoderSettings.Name} {decoderSettings.Extension} decoder settings object (of type {decoderSettings.GetType().FullName}) doesn't have a property named {decOpt.Key}.");
property.SetValue(decoderSettings,
TypeDescriptor.GetConverter(property.PropertyType).ConvertFromString(decOpt.Value));
}
audioSource = decoderSettings.Open(sourceFile);
2018-04-30 22:32:49 -04:00
audioContainer = audioSource as IAudioTitleSet;
if (audioContainer == null) audioContainer = new SingleAudioTitleSet(audioSource);
2018-03-16 00:12:34 -04:00
Console.ForegroundColor = ConsoleColor.White;
int frameRate = 0;
bool interlaced = false;
2018-04-30 22:32:49 -04:00
audios = audioContainer.AudioTitles;
audios.ForEach(t => chapters = t.Chapters);
2018-04-29 16:53:55 -04:00
if (audioSource is Codecs.MPEG.MPLS.AudioDecoder)
{
var mpls = audioSource as Codecs.MPEG.MPLS.AudioDecoder;
mpls.MPLSHeader.play_item.ForEach(i => i.video.ForEach(v => { if (!videos.Exists(v1 => v1.pid == v.pid)) videos.Add(v); }));
}
2018-03-16 00:12:34 -04:00
videos.ForEach(v => { frameRate = v.FrameRate; interlaced = v.Interlaced; });
2018-04-29 16:53:55 -04:00
Console.Error.Write($@"M2TS, {
videos.Count} video track{(videos.Count != 1 ? "s" : "")}, {
audios.Count} audio track{(audios.Count != 1 ? "s" : "")}, {
2018-04-30 22:32:49 -04:00
CDImageLayout.TimeToString(audios[0].GetDuration(), "{0:0}:{1:00}:{2:00}")}, {
2018-04-29 16:53:55 -04:00
(frameRate * (interlaced ? 2 : 1))}{
(interlaced ? "i" : "p")}");
Console.Error.WriteLine();
2018-03-16 00:12:34 -04:00
//foreach (var item in mpls.MPLSHeader.play_item)
//Console.Error.WriteLine("{0}.m2ts", item.clip_id);
2018-02-17 20:35:34 -05:00
{
Console.ForegroundColor = ConsoleColor.Gray;
2018-03-16 00:12:34 -04:00
int id = 1;
if (chapters.Count > 1)
{
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write(id++);
Console.Error.Write(": ");
Console.ForegroundColor = ConsoleColor.Gray;
Console.Error.WriteLine("Chapters, {0} chapters", chapters.Count - 1);
}
foreach (var video in videos)
{
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write(id++);
Console.Error.Write(": ");
Console.ForegroundColor = ConsoleColor.Gray;
Console.Error.WriteLine("{0}, {1}{2}", video.CodecString, video.FormatString, video.FrameRate * (video.Interlaced ? 2 : 1));
}
foreach (var audio in audios)
{
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write(id++);
Console.Error.Write(": ");
Console.ForegroundColor = ConsoleColor.Gray;
2018-04-30 22:32:49 -04:00
Console.Error.WriteLine("{0}, {1}, {2}, {3}", audio.Codec, audio.Language, audio.GetFormatString(), audio.GetRateString());
2018-03-16 00:12:34 -04:00
}
2018-02-17 20:35:34 -05:00
}
}
if (destFile == null)
return 0;
string strtoc = "";
for (int i = 0; i < chapters.Count; i++)
2018-04-29 16:53:55 -04:00
strtoc += string.Format(" {0}", (int)Math.Round((chapters[i].TotalSeconds * 75)));
strtoc = strtoc.Substring(1);
CDImageLayout toc = new CDImageLayout(strtoc);
CTDBResponseMeta meta = null;
if (queryMeta)
{
var ctdb = new CUEToolsDB(toc, null);
Console.Error.WriteLine("Contacting CTDB...");
ctdb.ContactDB(null, "CUETools.eac3to 2.1.7", "", false, true, CTDBMetadataSearch.Extensive);
foreach (var imeta in ctdb.Metadata)
{
meta = imeta;
break;
}
}
2018-02-17 20:35:34 -05:00
if (stream > 0)
{
2018-02-18 11:05:48 -05:00
int chapterStreams = chapters.Count > 1 ? 1 : 0;
if (stream <= chapterStreams)
2018-02-17 20:35:34 -05:00
{
2018-02-18 15:57:27 -05:00
if (destFile == "-" || destFile == "nul")
{
encoderFormat = "txt";
}
else
{
string extension = Path.GetExtension(destFile).ToLower();
if (!extension.StartsWith("."))
{
2018-02-18 15:57:27 -05:00
encoderFormat = destFile;
if (meta == null || meta.artist == null || meta.album == null)
destFile = string.Format("{0}.{1}", Path.GetFileNameWithoutExtension(sourceFile), destFile);
else
destFile = string.Format("{0} - {1} - {2}.{3}", meta.artist, meta.year, meta.album, destFile);
}
2018-02-18 15:57:27 -05:00
else
encoderFormat = extension.Substring(1);
if (encoderFormat != "txt" && encoderFormat != "cue")
throw new Exception(string.Format("Unsupported chapters file format \"{0}\"", encoderFormat));
2018-02-18 15:57:27 -05:00
}
Console.Error.WriteLine("Creating file \"{0}\"...", destFile);
2018-02-17 20:35:34 -05:00
2018-02-18 11:05:48 -05:00
if (encoderFormat == "txt")
{
2018-02-18 15:57:27 -05:00
using (TextWriter sw = destFile == "nul" ? (TextWriter)new StringWriter() : destFile == "-" ? Console.Out : (TextWriter)new StreamWriter(destFile))
2018-02-17 20:35:34 -05:00
{
2018-02-18 11:05:48 -05:00
for (int i = 0; i < chapters.Count - 1; i++)
2018-02-17 20:35:34 -05:00
{
2018-02-18 11:05:48 -05:00
sw.WriteLine("CHAPTER{0:00}={1}", i + 1,
2018-04-29 16:53:55 -04:00
CDImageLayout.TimeToString(chapters[i]));
if (meta != null && meta.track.Length >= toc[i + 1].Number)
sw.WriteLine("CHAPTER{0:00}NAME={1}", i + 1, meta.track[(int)toc[i + 1].Number - 1].name);
2018-02-18 15:57:27 -05:00
else
sw.WriteLine("CHAPTER{0:00}NAME=", i + 1);
2018-02-17 20:35:34 -05:00
}
}
2018-02-18 11:05:48 -05:00
Console.BackgroundColor = ConsoleColor.DarkGreen;
Console.Error.Write("Done.");
Console.BackgroundColor = ConsoleColor.Black;
Console.Error.WriteLine();
return 0;
}
2018-02-17 20:35:34 -05:00
2018-02-18 11:05:48 -05:00
if (encoderFormat == "cue")
{
2018-02-18 15:57:27 -05:00
using (StreamWriter cueWriter = new StreamWriter(destFile, false, Encoding.UTF8))
2018-02-18 11:05:48 -05:00
{
cueWriter.WriteLine("REM COMMENT \"{0}\"", "Created by CUETools.eac3to");
if (meta != null && meta.year != null)
cueWriter.WriteLine("REM DATE {0}", meta.year);
else
cueWriter.WriteLine("REM DATE XXXX");
if (meta != null)
2018-02-17 20:35:34 -05:00
{
2018-02-18 11:05:48 -05:00
cueWriter.WriteLine("PERFORMER \"{0}\"", meta.artist);
cueWriter.WriteLine("TITLE \"{0}\"", meta.album);
}
else
{
cueWriter.WriteLine("PERFORMER \"\"");
cueWriter.WriteLine("TITLE \"\"");
}
if (meta != null)
{
//cueWriter.WriteLine("FILE \"{0}\" WAVE", Path.GetFileNameWithoutExtension(destFile) + (extension ?? ".wav"));
cueWriter.WriteLine("FILE \"{0}\" WAVE", Path.GetFileNameWithoutExtension(destFile) + (".wav"));
}
else
{
cueWriter.WriteLine("FILE \"{0}\" WAVE", "");
}
for (int track = 1; track <= toc.TrackCount; track++)
if (toc[track].IsAudio)
2018-02-17 20:35:34 -05:00
{
2018-02-18 11:05:48 -05:00
cueWriter.WriteLine(" TRACK {0:00} AUDIO", toc[track].Number);
if (meta != null && meta.track.Length >= toc[track].Number)
2018-02-17 20:35:34 -05:00
{
2018-02-18 11:05:48 -05:00
cueWriter.WriteLine(" TITLE \"{0}\"", meta.track[(int)toc[track].Number - 1].name);
if (meta.track[(int)toc[track].Number - 1].artist != null)
cueWriter.WriteLine(" PERFORMER \"{0}\"", meta.track[(int)toc[track].Number - 1].artist);
2018-02-17 20:35:34 -05:00
}
2018-02-18 11:05:48 -05:00
else
{
cueWriter.WriteLine(" TITLE \"\"");
}
if (toc[track].ISRC != null)
cueWriter.WriteLine(" ISRC {0}", toc[track].ISRC);
for (int index = toc[track].Pregap > 0 ? 0 : 1; index <= toc[track].LastIndex; index++)
cueWriter.WriteLine(" INDEX {0:00} {1}", index, toc[track][index].MSF);
}
2018-02-17 20:35:34 -05:00
}
2018-02-18 11:05:48 -05:00
Console.BackgroundColor = ConsoleColor.DarkGreen;
Console.Error.Write("Done.");
Console.BackgroundColor = ConsoleColor.Black;
Console.Error.WriteLine();
2018-02-17 20:35:34 -05:00
return 0;
}
2018-02-18 11:05:48 -05:00
2018-02-18 15:57:27 -05:00
throw new Exception("Unknown encoder format: " + destFile);
2018-02-17 20:35:34 -05:00
}
2018-04-29 16:53:55 -04:00
if (stream - chapterStreams <= videos.Count)
throw new Exception("Video extraction not supported.");
if (stream - chapterStreams - videos.Count > audios.Count)
throw new Exception(string.Format("The source file doesn't contain a track with the number {0}.", stream));
int streamId = audios[stream - chapterStreams - videos.Count - 1].StreamId;
if (audioSource is Codecs.MPEG.MPLS.AudioDecoder)
2018-03-16 00:12:34 -04:00
{
2018-04-29 16:53:55 -04:00
(audioSource.Settings as Codecs.MPEG.MPLS.DecoderSettings).StreamId = streamId;
2018-03-16 00:12:34 -04:00
}
2018-02-17 20:35:34 -05:00
}
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,
audioSource.Duration);
2018-02-17 20:35:34 -05:00
CUEToolsFormat fmt;
if (encoderFormat == null)
{
if (destFile == "-" || destFile == "nul")
encoderFormat = "wav";
else
{
string extension = Path.GetExtension(destFile).ToLower();
if (!extension.StartsWith("."))
{
encoderFormat = destFile;
if (meta == null || meta.artist == null || meta.album == null)
destFile = string.Format("{0} - {1}.{2}", Path.GetFileNameWithoutExtension(sourceFile), stream, destFile);
else
destFile = string.Format("{0} - {1} - {2}.{3}", meta.artist, meta.year, meta.album, destFile);
}
else
encoderFormat = extension.Substring(1);
if (File.Exists(destFile))
throw new Exception(string.Format("Error: file {0} already exists.", destFile));
2018-02-17 20:35:34 -05:00
}
}
if (!config.formats.TryGetValue(encoderFormat, out fmt))
throw new Exception("Unsupported encoder format: " + encoderFormat);
AudioEncoderSettingsViewModel encoder =
2018-02-17 20:35:34 -05:00
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<AudioEncoderSettingsViewModel>(config.encodersViewModel).FindAll(
e => e.Extension == fmt.extension && (audioEncoderType == AudioEncoderType.NoAudio || audioEncoderType == (e.Lossless ? AudioEncoderType.Lossless : AudioEncoderType.Lossy))).
2018-02-17 20:35:34 -05:00
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())));
}
Console.Error.WriteLine("Output {0} : {1}", stream, destFile);
var settings = encoder.Settings.Clone();
2018-02-17 20:35:34 -05:00
settings.PCM = audioSource.PCM;
settings.Padding = padding;
settings.EncoderMode = encoderMode ?? settings.EncoderMode;
object o = null;
try
{
2018-04-07 13:55:01 -04:00
o = destFile == "-" ? Activator.CreateInstance(settings.EncoderType, settings, "", Console.OpenStandardOutput()) :
destFile == "nul" ? Activator.CreateInstance(settings.EncoderType, settings, "", new NullStream()) :
Activator.CreateInstance(settings.EncoderType, settings, destFile, null);
2018-02-17 20:35:34 -05:00
}
catch (System.Reflection.TargetInvocationException ex)
{
throw ex.InnerException;
}
if (o == null || !(o is IAudioDest))
throw new Exception("Unsupported audio type: " + destFile + ": " + settings.EncoderType.FullName);
2018-02-17 20:35:34 -05:00
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)
{
var duration = audioSource.Duration;
var position = TimeSpan.FromSeconds((double)audioSource.Position / audioSource.PCM.SampleRate);
if (duration < position) duration = position;
if (duration < TimeSpan.FromSeconds(1)) duration = TimeSpan.FromSeconds(1);
2018-02-17 20:35:34 -05:00
Console.Error.Write("\rProgress : {0:00}%; {1:0.00}x; {2}/{3}",
100.0 * position.TotalSeconds / duration.TotalSeconds,
position.TotalSeconds / elapsed.TotalSeconds,
2018-02-17 20:35:34 -05:00
elapsed,
TimeSpan.FromSeconds(elapsed.TotalSeconds / position.TotalSeconds * duration.TotalSeconds)
2018-02-17 20:35:34 -05:00
);
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
);
}
2018-04-07 13:55:01 -04:00
#if !DEBUG
2018-02-17 20:35:34 -05:00
catch (Exception ex)
{
if (audioSource != null) audioSource.Close();
if (audioDest != null) audioDest.Delete();
throw ex;
}
2018-04-07 13:55:01 -04:00
#endif
2018-02-17 20:35:34 -05:00
audioSource.Close();
audioDest.Close();
if (sourceFile != "-" && destFile != "-" && destFile != "nul")
{
//TagLib.File destInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(destFile));
//NameValueCollection tags;
//if (Tagging.UpdateTags(destInfo, tags, config, false))
//{
// destInfo.Save();
//}
}
}
#if !DEBUG
catch (Exception ex)
{
Console.Error.Write("\r \r");
Console.BackgroundColor = ConsoleColor.DarkRed;
Console.Error.Write("Error : {0}", ex.Message);
Console.BackgroundColor = ConsoleColor.Black;
Console.Error.WriteLine();
2018-02-17 20:35:34 -05:00
return 1;
//Console.WriteLine("{0}", ex.StackTrace);
}
#endif
return 0;
}
}
}