2018-03-11 17:07:48 -04:00
using CUETools.CDImage ;
2018-02-17 20:35:34 -05:00
using CUETools.Codecs ;
using CUETools.CTDB ;
2018-03-11 17:07:48 -04:00
using CUETools.Processor ;
using System ;
using System.Collections.Generic ;
2018-04-29 16:53:55 -04:00
using System.ComponentModel ;
2018-03-11 17:07:48 -04:00
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 ( )
{
2021-01-05 20:19:53 +01:00
Console . Error . WriteLine ( "CUETools.eac3to, Copyright (C) 2018-2021 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 ( ) ;
2018-02-20 20:41:40 -05:00
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 ( ) ;
}
2018-03-23 19:26:26 -04:00
public static AudioEncoderSettingsViewModel GetEncoder ( CUEToolsCodecsConfig config , CUEToolsFormat fmt , bool lossless , string chosenEncoder )
2018-02-17 20:35:34 -05:00
{
2018-03-23 19:26:26 -04:00
AudioEncoderSettingsViewModel tmpEncoder ;
2018-02-17 20:35:34 -05:00
return chosenEncoder ! = null ?
2018-03-24 12:15:49 -04:00
( 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 > ( ) ;
2018-02-20 20:41:40 -05:00
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 ;
2018-02-20 20:41:40 -05:00
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 ) ;
2018-03-24 12:15:49 -04:00
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 ;
2018-04-07 21:09:28 -04:00
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 ;
2018-02-20 20:41:40 -05:00
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 ) ) ) ;
2018-02-20 20:41:40 -05:00
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..." ) ;
2021-04-28 21:40:15 +02:00
ctdb . ContactDB ( null , "CUETools.eac3to 2.1.9" , "" , false , true , CTDBMetadataSearch . Extensive ) ;
2018-02-20 20:41:40 -05:00
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-20 20:41:40 -05:00
{
2018-02-18 15:57:27 -05:00
encoderFormat = destFile ;
2018-02-20 20:41:40 -05:00
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" )
2018-02-20 20:41:40 -05:00
throw new Exception ( string . Format ( "Unsupported chapters file format \"{0}\"" , encoderFormat ) ) ;
2018-02-18 15:57:27 -05:00
}
2018-02-20 20:41:40 -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 ;
2018-04-07 21:09:28 -04:00
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 ,
2018-04-07 23:02:01 -04:00
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 ( "." ) )
2018-02-20 20:41:40 -05:00
{
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 ) ;
2018-03-23 19:26:26 -04:00
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 )
{
2018-03-24 12:15:49 -04:00
var lst = new List < AudioEncoderSettingsViewModel > ( config . encodersViewModel ) . FindAll (
2018-03-23 19:26:26 -04:00
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 ( ) ) ) ) ;
}
2018-02-20 20:41:40 -05:00
Console . Error . WriteLine ( "Output {0} : {1}" , stream , destFile ) ;
2018-03-24 12:15:49 -04:00
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 ) )
2018-03-23 19:26:26 -04:00
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 )
{
2018-04-07 23:02:01 -04:00
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}" ,
2018-04-07 23:02:01 -04:00
100.0 * position . TotalSeconds / duration . TotalSeconds ,
position . TotalSeconds / elapsed . TotalSeconds ,
2018-02-17 20:35:34 -05:00
elapsed ,
2018-04-07 23:02:01 -04:00
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" ) ;
2018-02-20 20:41:40 -05:00
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 ;
}
}
}