diff --git a/CUERipper/Program.cs b/CUERipper/Program.cs
index 9591669..8140a4b 100644
--- a/CUERipper/Program.cs
+++ b/CUERipper/Program.cs
@@ -1,11 +1,11 @@
using System;
-using System.Collections.Generic;
using System.Deployment.Application;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using CUETools.Processor;
+using CUETools.Processor.Settings;
namespace CUERipper
{
diff --git a/CUERipper/frmCUERipper.cs b/CUERipper/frmCUERipper.cs
index e098e12..ccc5c2f 100644
--- a/CUERipper/frmCUERipper.cs
+++ b/CUERipper/frmCUERipper.cs
@@ -1,24 +1,18 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
-using System.Collections.ObjectModel;
using System.ComponentModel;
-using System.Data;
using System.Drawing;
using System.IO;
using System.Net;
-using System.Text;
using System.Threading;
using System.Windows.Forms;
-using System.Configuration;
-using System.Drawing.Drawing2D;
+using CUEControls;
using CUETools.AccurateRip;
using CUETools.CTDB;
-using CUETools.CDImage;
-using CUETools.Codecs;
using CUETools.Processor;
+using CUETools.Processor.Settings;
using CUETools.Ripper;
-using CUEControls;
using Freedb;
namespace CUERipper
diff --git a/CUETools.Converter/Program.cs b/CUETools.Converter/Program.cs
index a5d9c95..e665efe 100644
--- a/CUETools.Converter/Program.cs
+++ b/CUETools.Converter/Program.cs
@@ -1,10 +1,8 @@
using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Text;
using System.IO;
using CUETools.Codecs;
using CUETools.Processor;
+using CUETools.Processor.Settings;
namespace CUETools.Converter
{
diff --git a/CUETools.Processor/ArchiveFileAbstraction.cs b/CUETools.Processor/ArchiveFileAbstraction.cs
new file mode 100644
index 0000000..9a6f1de
--- /dev/null
+++ b/CUETools.Processor/ArchiveFileAbstraction.cs
@@ -0,0 +1,36 @@
+using System.IO;
+
+namespace CUETools.Processor
+{
+ public class ArchiveFileAbstraction : TagLib.File.IFileAbstraction
+ {
+ private string name;
+ private CUESheet _cueSheet;
+
+ public string Name
+ {
+ get { return name; }
+ }
+
+ public Stream ReadStream
+ {
+ get { return _cueSheet.OpenArchive(Name, true); }
+ }
+
+ public Stream WriteStream
+ {
+ get { return null; }
+ }
+
+ public ArchiveFileAbstraction(CUESheet cueSheet, string file)
+ {
+ name = file;
+ _cueSheet = cueSheet;
+ }
+
+ public void CloseStream(Stream stream)
+ {
+ stream.Close();
+ }
+ }
+}
diff --git a/CUETools.Processor/AudioEncoderType.cs b/CUETools.Processor/AudioEncoderType.cs
new file mode 100644
index 0000000..08b4472
--- /dev/null
+++ b/CUETools.Processor/AudioEncoderType.cs
@@ -0,0 +1,13 @@
+namespace CUETools.Processor
+{
+ public enum AudioEncoderType
+ {
+ Lossless,
+ Hybrid,
+ Lossy,
+ ///
+ /// No Audio
+ ///
+ NoAudio,
+ }
+}
diff --git a/CUETools.Processor/AudioReadWrite.cs b/CUETools.Processor/AudioReadWrite.cs
index ec64b16..584ed8b 100644
--- a/CUETools.Processor/AudioReadWrite.cs
+++ b/CUETools.Processor/AudioReadWrite.cs
@@ -3,7 +3,6 @@ using System.IO;
using CUETools.CDImage;
using CUETools.Codecs;
using CUETools.Codecs.LossyWAV;
-using System.Xml.Serialization;
namespace CUETools.Processor
{
diff --git a/CUETools.Processor/CUEAction.cs b/CUETools.Processor/CUEAction.cs
new file mode 100644
index 0000000..372350e
--- /dev/null
+++ b/CUETools.Processor/CUEAction.cs
@@ -0,0 +1,10 @@
+namespace CUETools.Processor
+{
+ public enum CUEAction
+ {
+ Encode = 0,
+ Verify = 1,
+ CreateDummyCUE = 2,
+ CorrectFilenames = 3
+ }
+}
diff --git a/CUETools.Processor/CUEConfig.cs b/CUETools.Processor/CUEConfig.cs
new file mode 100644
index 0000000..dce7648
--- /dev/null
+++ b/CUETools.Processor/CUEConfig.cs
@@ -0,0 +1,651 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Threading;
+using System.Xml;
+using System.Xml.Serialization;
+using CUETools.Codecs;
+using CUETools.Processor.Settings;
+
+namespace CUETools.Processor
+{
+ public class CUEConfig
+ {
+ public readonly static XmlSerializerNamespaces xmlEmptyNamespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] { XmlQualifiedName.Empty });
+ public readonly static XmlWriterSettings xmlEmptySettings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true };
+
+ public uint fixOffsetMinimumConfidence;
+ public uint fixOffsetMinimumTracksPercent;
+ public uint encodeWhenConfidence;
+ public uint encodeWhenPercent;
+ public bool encodeWhenZeroOffset;
+ public bool writeArTagsOnVerify;
+ public bool writeArLogOnVerify;
+ public bool writeArTagsOnEncode;
+ public bool writeArLogOnConvert;
+ public bool fixOffset;
+ public bool noUnverifiedOutput;
+ public bool autoCorrectFilenames;
+ public bool preserveHTOA;
+ public bool keepOriginalFilenames;
+ public string trackFilenameFormat;
+ public string singleFilenameFormat;
+ public bool removeSpecial;
+ public string specialExceptions;
+ public bool replaceSpaces;
+ public bool embedLog;
+ public bool extractLog;
+ public bool fillUpCUE;
+ public bool overwriteCUEData;
+ public bool filenamesANSISafe;
+ public bool bruteForceDTL;
+ public bool createEACLOG;
+ public bool detectHDCD;
+ public bool decodeHDCD;
+ public bool wait750FramesForHDCD;
+ public bool createM3U;
+ public bool createCUEFileWhenEmbedded;
+ public bool truncate4608ExtraSamples;
+ public int lossyWAVQuality;
+ public bool decodeHDCDtoLW16;
+ public bool decodeHDCDto24bit;
+ public bool oneInstance;
+ public bool checkForUpdates;
+ public string language;
+ public Dictionary formats;
+ public CUEToolsUDCList encoders;
+ public Dictionary decoders;
+ public Dictionary scripts;
+ public string defaultVerifyScript;
+ public string defaultEncodeScript;
+ public bool writeBasicTagsFromCUEData;
+ public bool copyBasicTags;
+ public bool copyUnknownTags;
+ public bool embedAlbumArt;
+ public bool extractAlbumArt;
+ public bool arLogToSourceFolder;
+ public bool arLogVerbose;
+ public bool fixOffsetToNearest;
+ public int maxAlbumArtSize;
+ public CUEStyle gapsHandling;
+ public bool separateDecodingThread;
+
+ public CUEConfigAdvanced advanced { get; private set; }
+ public bool CopyAlbumArt { get; set; }
+ public string ArLogFilenameFormat { get; set; }
+ public string AlArtFilenameFormat { get; set; }
+ public CUEToolsUDCList Encoders
+ {
+ get { return encoders; }
+ }
+
+ public CUEConfig()
+ {
+ fixOffsetMinimumConfidence = 2;
+ fixOffsetMinimumTracksPercent = 51;
+ encodeWhenConfidence = 2;
+ encodeWhenPercent = 100;
+ encodeWhenZeroOffset = false;
+ fixOffset = false;
+ noUnverifiedOutput = false;
+ writeArTagsOnEncode = true;
+ writeArLogOnConvert = true;
+ writeArTagsOnVerify = false;
+ writeArLogOnVerify = false;
+
+ autoCorrectFilenames = true;
+ preserveHTOA = true;
+ keepOriginalFilenames = false;
+ trackFilenameFormat = "%tracknumber%. %title%";
+ singleFilenameFormat = "%filename%";
+ removeSpecial = false;
+ specialExceptions = "-()";
+ replaceSpaces = false;
+ embedLog = true;
+ extractLog = true;
+ fillUpCUE = true;
+ overwriteCUEData = false;
+ filenamesANSISafe = true;
+ bruteForceDTL = false;
+ createEACLOG = true;
+ detectHDCD = true;
+ wait750FramesForHDCD = true;
+ decodeHDCD = false;
+ createM3U = false;
+ createCUEFileWhenEmbedded = true;
+ truncate4608ExtraSamples = true;
+ lossyWAVQuality = 5;
+ decodeHDCDtoLW16 = false;
+ decodeHDCDto24bit = true;
+
+ oneInstance = true;
+ checkForUpdates = true;
+
+ writeBasicTagsFromCUEData = true;
+ copyBasicTags = true;
+ copyUnknownTags = true;
+ CopyAlbumArt = true;
+ embedAlbumArt = true;
+ extractAlbumArt = true;
+ maxAlbumArtSize = 300;
+
+ arLogToSourceFolder = false;
+ arLogVerbose = true;
+ fixOffsetToNearest = true;
+ ArLogFilenameFormat = "%filename%.accurip";
+ AlArtFilenameFormat = "folder.jpg";
+
+ separateDecodingThread = true;
+
+ gapsHandling = CUEStyle.GapsAppended;
+
+ advanced = new CUEConfigAdvanced();
+
+ language = Thread.CurrentThread.CurrentUICulture.Name;
+
+ encoders = new CUEToolsUDCList();
+ foreach (Type type in CUEProcessorPlugins.encs)
+ foreach (AudioEncoderClass enc in Attribute.GetCustomAttributes(type, typeof(AudioEncoderClass)))
+ encoders.Add(new CUEToolsUDC(enc, type));
+ decoders = new Dictionary();
+ foreach (Type type in CUEProcessorPlugins.decs)
+ {
+ AudioDecoderClass dec = Attribute.GetCustomAttribute(type, typeof(AudioDecoderClass)) as AudioDecoderClass;
+ decoders.Add(dec.DecoderName, new CUEToolsUDC(dec, type));
+ }
+ if (Type.GetType("Mono.Runtime", false) == null)
+ {
+ encoders.Add(new CUEToolsUDC("flake", "flac", true, "0 1 2 3 4 5 6 7 8 9 10 11 12", "8", "flake.exe", "-%M - -o %O -p %P"));
+ encoders.Add(new CUEToolsUDC("takc", "tak", true, "0 1 2 2e 2m 3 3e 3m 4 4e 4m", "2", "takc.exe", "-e -p%M -overwrite - %O"));
+ encoders.Add(new CUEToolsUDC("ffmpeg alac", "m4a", true, "", "", "ffmpeg.exe", "-i - -f ipod -acodec alac -y %O"));
+ encoders.Add(new CUEToolsUDC("lame vbr", "mp3", false, "V9 V8 V7 V6 V5 V4 V3 V2 V1 V0", "V2", "lame.exe", "--vbr-new -%M - %O"));
+ encoders.Add(new CUEToolsUDC("lame cbr", "mp3", false, "96 128 192 256 320", "256", "lame.exe", "-m s -q 0 -b %M --noreplaygain - %O"));
+ encoders.Add(new CUEToolsUDC("oggenc", "ogg", false, "-1 -0.5 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7 7.5 8", "3", "oggenc.exe", "-q %M - -o %O"));
+ encoders.Add(new CUEToolsUDC("nero aac", "m4a", false, "0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9", "0.4", "neroAacEnc.exe", "-q %M -if - -of %O"));
+ encoders.Add(new CUEToolsUDC("qaac tvbr", "m4a", false, "10 20 30 40 50 60 70 80 90 100 110 127", "80", "qaac.exe", "-s -V %M -q 2 - -o %O"));
+
+ decoders.Add("takc", new CUEToolsUDC("takc", "tak", true, "", "", "takc.exe", "-d %I -"));
+ decoders.Add("ffmpeg alac", new CUEToolsUDC("ffmpeg alac", "m4a", true, "", "", "ffmpeg.exe", "%I -f wav -"));
+ }
+ else
+ {
+ // !!!
+ }
+
+ formats = new Dictionary();
+ formats.Add("flac", new CUEToolsFormat("flac", CUEToolsTagger.TagLibSharp, true, false, true, true, true, encoders.GetDefault("flac", true), null, GetDefaultDecoder("flac")));
+ formats.Add("wv", new CUEToolsFormat("wv", CUEToolsTagger.TagLibSharp, true, false, true, true, true, encoders.GetDefault("wv", true), null, GetDefaultDecoder("wv")));
+ formats.Add("ape", new CUEToolsFormat("ape", CUEToolsTagger.TagLibSharp, true, false, false, true, true, encoders.GetDefault("ape", true), null, GetDefaultDecoder("ape")));
+ formats.Add("tta", new CUEToolsFormat("tta", CUEToolsTagger.APEv2, true, false, false, false, true, encoders.GetDefault("tta", true), null, GetDefaultDecoder("tta")));
+ formats.Add("wav", new CUEToolsFormat("wav", CUEToolsTagger.TagLibSharp, true, false, true, false, true, encoders.GetDefault("wav", true), null, GetDefaultDecoder("wav")));
+ formats.Add("m4a", new CUEToolsFormat("m4a", CUEToolsTagger.TagLibSharp, true, true, false, false, true, encoders.GetDefault("m4a", true), encoders.GetDefault("m4a", false), GetDefaultDecoder("m4a")));
+ formats.Add("tak", new CUEToolsFormat("tak", CUEToolsTagger.APEv2, true, false, true, true, true, encoders.GetDefault("tak", true), null, "takc"));
+ formats.Add("mp3", new CUEToolsFormat("mp3", CUEToolsTagger.TagLibSharp, false, true, false, false, true, null, encoders.GetDefault("mp3", false), null));
+ formats.Add("ogg", new CUEToolsFormat("ogg", CUEToolsTagger.TagLibSharp, false, true, false, false, true, null, encoders.GetDefault("ogg", false), null));
+
+ scripts = new Dictionary();
+ scripts.Add("default", new CUEToolsScript("default", true,
+ new CUEAction[] { CUEAction.Verify, CUEAction.Encode },
+ "return processor.Go();"));
+ scripts.Add("only if found", new CUEToolsScript("only if found", true,
+ new CUEAction[] { CUEAction.Verify },
+@"if (processor.ArVerify.AccResult != HttpStatusCode.OK)
+ return processor.WriteReport();
+return processor.Go();"));
+ scripts.Add("fix offset", new CUEToolsScript("fix offset", true,
+ new CUEAction[] { CUEAction.Encode },
+@"if (processor.ArVerify.AccResult != HttpStatusCode.OK)
+ return processor.WriteReport();
+processor.WriteOffset = 0;
+processor.Action = CUEAction.Verify;
+string status = processor.Go();
+uint tracksMatch;
+int bestOffset;
+processor.FindBestOffset(processor.Config.fixOffsetMinimumConfidence, !processor.Config.fixOffsetToNearest, out tracksMatch, out bestOffset);
+if (tracksMatch * 100 < processor.Config.fixOffsetMinimumTracksPercent * processor.TrackCount)
+ return status;
+processor.WriteOffset = bestOffset;
+processor.Action = CUEAction.Encode;
+//MessageBox.Show(null, processor.AccurateRipLog, " + "\"Done\"" + @"MessageBoxButtons.OK, MessageBoxIcon.Information);
+return processor.Go();
+"));
+ scripts.Add("encode if verified", new CUEToolsScript("encode if verified", true,
+ new CUEAction[] { CUEAction.Encode },
+@"if (processor.ArVerify.AccResult != HttpStatusCode.OK)
+ return processor.WriteReport();
+processor.Action = CUEAction.Verify;
+string status = processor.Go();
+uint tracksMatch;
+int bestOffset;
+processor.FindBestOffset(processor.Config.encodeWhenConfidence, false, out tracksMatch, out bestOffset);
+if (tracksMatch * 100 < processor.Config.encodeWhenPercent * processor.TrackCount || (processor.Config.encodeWhenZeroOffset && bestOffset != 0))
+ return status;
+processor.Action = CUEAction.Encode;
+return processor.Go();
+"));
+ scripts.Add("repair", new CUEToolsScript("repair", true,
+ new CUEAction[] { CUEAction.Encode },
+@"
+processor.UseCUEToolsDB();
+processor.Action = CUEAction.Verify;
+if (processor.CTDB.DBStatus != null)
+ return CTDB.DBStatus;
+processor.Go();
+processor.CTDB.DoVerify();
+if (!processor.CTDB.Verify.HasErrors)
+ return ""nothing to fix"";
+if (!processor.CTDB.Verify.CanRecover)
+ return ""cannot fix"";
+processor._useCUEToolsDBFix = true;
+processor.Action = CUEAction.Encode;
+return processor.Go();
+"));
+ defaultVerifyScript = "default";
+ defaultEncodeScript = "default";
+ }
+
+ public void Save(SettingsWriter sw)
+ {
+ sw.Save("Version", 203);
+ sw.Save("ArFixWhenConfidence", fixOffsetMinimumConfidence);
+ sw.Save("ArFixWhenPercent", fixOffsetMinimumTracksPercent);
+ sw.Save("ArEncodeWhenConfidence", encodeWhenConfidence);
+ sw.Save("ArEncodeWhenPercent", encodeWhenPercent);
+ sw.Save("ArEncodeWhenZeroOffset", encodeWhenZeroOffset);
+ sw.Save("ArNoUnverifiedOutput", noUnverifiedOutput);
+ sw.Save("ArFixOffset", fixOffset);
+ sw.Save("ArWriteCRC", writeArTagsOnEncode);
+ sw.Save("ArWriteLog", writeArLogOnConvert);
+ sw.Save("ArWriteTagsOnVerify", writeArTagsOnVerify);
+ sw.Save("ArWriteLogOnVerify", writeArLogOnVerify);
+
+ sw.Save("PreserveHTOA", preserveHTOA);
+ sw.Save("AutoCorrectFilenames", autoCorrectFilenames);
+ sw.Save("KeepOriginalFilenames", keepOriginalFilenames);
+ sw.Save("SingleFilenameFormat", singleFilenameFormat);
+ sw.Save("TrackFilenameFormat", trackFilenameFormat);
+ sw.Save("RemoveSpecialCharacters", removeSpecial);
+ sw.Save("SpecialCharactersExceptions", specialExceptions);
+ sw.Save("ReplaceSpaces", replaceSpaces);
+ sw.Save("EmbedLog", embedLog);
+ sw.Save("ExtractLog", extractLog);
+ sw.Save("FillUpCUE", fillUpCUE);
+ sw.Save("OverwriteCUEData", overwriteCUEData);
+ sw.Save("FilenamesANSISafe", filenamesANSISafe);
+ if (bruteForceDTL) sw.Save("BruteForceDTL", bruteForceDTL);
+ sw.Save("CreateEACLOG", createEACLOG);
+ sw.Save("DetectHDCD", detectHDCD);
+ sw.Save("Wait750FramesForHDCD", wait750FramesForHDCD);
+ sw.Save("DecodeHDCD", decodeHDCD);
+ sw.Save("CreateM3U", createM3U);
+ sw.Save("CreateCUEFileWhenEmbedded", createCUEFileWhenEmbedded);
+ sw.Save("Truncate4608ExtraSamples", truncate4608ExtraSamples);
+ sw.Save("LossyWAVQuality", lossyWAVQuality);
+ sw.Save("DecodeHDCDToLossyWAV16", decodeHDCDtoLW16);
+ sw.Save("DecodeHDCDTo24bit", decodeHDCDto24bit);
+ sw.Save("OneInstance", oneInstance);
+ sw.Save("CheckForUpdates", checkForUpdates);
+ sw.Save("Language", language);
+
+ sw.Save("SeparateDecodingThread", separateDecodingThread);
+
+ sw.Save("WriteBasicTagsFromCUEData", writeBasicTagsFromCUEData);
+ sw.Save("CopyBasicTags", copyBasicTags);
+ sw.Save("CopyUnknownTags", copyUnknownTags);
+ sw.Save("CopyAlbumArt", CopyAlbumArt);
+ sw.Save("EmbedAlbumArt", embedAlbumArt);
+ sw.Save("ExtractAlbumArt", extractAlbumArt);
+ sw.Save("MaxAlbumArtSize", maxAlbumArtSize);
+
+ sw.Save("ArLogToSourceFolder", arLogToSourceFolder);
+ sw.Save("ArLogVerbose", arLogVerbose);
+ sw.Save("FixOffsetToNearest", fixOffsetToNearest);
+
+ sw.Save("ArLogFilenameFormat", ArLogFilenameFormat);
+ sw.Save("AlArtFilenameFormat", AlArtFilenameFormat);
+
+ using (TextWriter tw = new StringWriter())
+ using (XmlWriter xw = XmlTextWriter.Create(tw, xmlEmptySettings))
+ {
+ CUEConfigAdvanced.serializer.Serialize(xw, advanced, xmlEmptyNamespaces);
+ sw.SaveText("Advanced", tw.ToString());
+ }
+
+ int nEncoders = 0;
+ foreach (CUEToolsUDC encoder in encoders)
+ {
+ sw.Save(string.Format("ExternalEncoder{0}Name", nEncoders), encoder.name);
+ sw.Save(string.Format("ExternalEncoder{0}Modes", nEncoders), encoder.supported_modes);
+ sw.Save(string.Format("ExternalEncoder{0}Mode", nEncoders), encoder.default_mode);
+ if (encoder.path != null)
+ {
+ sw.Save(string.Format("ExternalEncoder{0}Extension", nEncoders), encoder.extension);
+ sw.Save(string.Format("ExternalEncoder{0}Path", nEncoders), encoder.path);
+ sw.Save(string.Format("ExternalEncoder{0}Lossless", nEncoders), encoder.lossless);
+ sw.Save(string.Format("ExternalEncoder{0}Parameters", nEncoders), encoder.parameters);
+ }
+ else
+ {
+ if (encoder.settingsSerializer != null)
+ {
+ using (TextWriter tw = new StringWriter())
+ using (XmlWriter xw = XmlTextWriter.Create(tw, xmlEmptySettings))
+ {
+ encoder.settingsSerializer.Serialize(xw, encoder.settings, xmlEmptyNamespaces);
+ sw.SaveText(string.Format("ExternalEncoder{0}Parameters", nEncoders), tw.ToString());
+ }
+ }
+ }
+ nEncoders++;
+ }
+ sw.Save("ExternalEncoders", nEncoders);
+
+ int nDecoders = 0;
+ foreach (KeyValuePair decoder in decoders)
+ if (decoder.Value.path != null)
+ {
+ sw.Save(string.Format("ExternalDecoder{0}Name", nDecoders), decoder.Key);
+ sw.Save(string.Format("ExternalDecoder{0}Extension", nDecoders), decoder.Value.extension);
+ sw.Save(string.Format("ExternalDecoder{0}Path", nDecoders), decoder.Value.path);
+ sw.Save(string.Format("ExternalDecoder{0}Parameters", nDecoders), decoder.Value.parameters);
+ nDecoders++;
+ }
+ sw.Save("ExternalDecoders", nDecoders);
+
+ int nFormats = 0;
+ foreach (KeyValuePair format in formats)
+ {
+ sw.Save(string.Format("CustomFormat{0}Name", nFormats), format.Key);
+ sw.Save(string.Format("CustomFormat{0}EncoderLossless", nFormats), format.Value.encoderLossless == null ? "" : format.Value.encoderLossless.Name);
+ sw.Save(string.Format("CustomFormat{0}EncoderLossy", nFormats), format.Value.encoderLossy == null ? "" : format.Value.encoderLossy.Name);
+ sw.Save(string.Format("CustomFormat{0}Decoder", nFormats), format.Value.decoder);
+ sw.Save(string.Format("CustomFormat{0}Tagger", nFormats), (int)format.Value.tagger);
+ sw.Save(string.Format("CustomFormat{0}AllowLossless", nFormats), format.Value.allowLossless);
+ sw.Save(string.Format("CustomFormat{0}AllowLossy", nFormats), format.Value.allowLossy);
+ sw.Save(string.Format("CustomFormat{0}AllowLossyWAV", nFormats), format.Value.allowLossyWAV);
+ sw.Save(string.Format("CustomFormat{0}AllowEmbed", nFormats), format.Value.allowEmbed);
+ nFormats++;
+ }
+ sw.Save("CustomFormats", nFormats);
+
+ int nScripts = 0;
+ foreach (KeyValuePair script in scripts)
+ {
+ sw.Save(string.Format("CustomScript{0}Name", nScripts), script.Key);
+ sw.SaveText(string.Format("CustomScript{0}Code", nScripts), script.Value.code);
+ int nCondition = 0;
+ foreach (CUEAction action in script.Value.conditions)
+ sw.Save(string.Format("CustomScript{0}Condition{1}", nScripts, nCondition++), (int)action);
+ sw.Save(string.Format("CustomScript{0}Conditions", nScripts), nCondition);
+ nScripts++;
+ }
+ sw.Save("CustomScripts", nScripts);
+ sw.Save("DefaultVerifyScript", defaultVerifyScript);
+ sw.Save("DefaultVerifyAndConvertScript", defaultEncodeScript);
+
+ sw.Save("GapsHandling", (int)gapsHandling);
+ }
+
+ 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") ?? true;
+ writeArLogOnConvert = sr.LoadBoolean("ArWriteLog") ?? true;
+ writeArTagsOnVerify = sr.LoadBoolean("ArWriteTagsOnVerify") ?? false;
+ writeArLogOnVerify = sr.LoadBoolean("ArWriteLogOnVerify") ?? false;
+
+ preserveHTOA = sr.LoadBoolean("PreserveHTOA") ?? 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;
+ lossyWAVQuality = sr.LoadInt32("LossyWAVQuality", 0, 10) ?? 5;
+ 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 path = sr.Load(string.Format("ExternalEncoder{0}Path", nEncoders));
+ string parameters = sr.Load(string.Format("ExternalEncoder{0}Parameters", nEncoders));
+ bool lossless = sr.LoadBoolean(string.Format("ExternalEncoder{0}Lossless", nEncoders)) ?? true;
+ string supported_modes = sr.Load(string.Format("ExternalEncoder{0}Modes", nEncoders)) ?? "";
+ string default_mode = sr.Load(string.Format("ExternalEncoder{0}Mode", nEncoders)) ?? "";
+ CUEToolsUDC encoder;
+ if (name == null) continue;
+ if (!encoders.TryGetValue(name, out encoder))
+ {
+ if (path == null || parameters == null || extension == null) continue;
+ encoders.Add(new CUEToolsUDC(name, extension, lossless, supported_modes, default_mode, path, parameters));
+ }
+ else if (version == 203)
+ {
+ if (encoder.path != null)
+ {
+ if (path == null || parameters == null || extension == null) continue;
+ encoder.extension = extension;
+ encoder.path = path;
+ encoder.lossless = lossless;
+ encoder.parameters = parameters;
+ }
+ else
+ {
+ if (encoder.settingsSerializer != null && parameters != "")
+ try
+ {
+ using (TextReader reader = new StringReader(parameters))
+ encoder.settings = encoder.settingsSerializer.Deserialize(reader);
+ }
+ catch
+ {
+ }
+ }
+ encoder.supported_modes = supported_modes;
+ encoder.default_mode = default_mode;
+ }
+ }
+
+ 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(name, out decoder))
+ decoders.Add(name, new CUEToolsUDC(name, extension, true, "", "", 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 allowLossyWav = sr.LoadBoolean(string.Format("CustomFormat{0}AllowLossyWAV", nFormats)) ?? false;
+ bool allowEmbed = sr.LoadBoolean(string.Format("CustomFormat{0}AllowEmbed", nFormats)) ?? false;
+ CUEToolsFormat format;
+ CUEToolsUDC udcLossless, udcLossy;
+ if (encoderLossless == "" || !encoders.TryGetValue(encoderLossless, out udcLossless))
+ udcLossless = null;
+ if (encoderLossy == "" || !encoders.TryGetValue(encoderLossy, out udcLossy))
+ udcLossy = null;
+ if (!formats.TryGetValue(extension, out format))
+ formats.Add(extension, new CUEToolsFormat(extension, tagger, allowLossless, allowLossy, allowLossyWav, allowEmbed, false, udcLossless, udcLossy, decoder));
+ else
+ {
+ format.encoderLossless = udcLossless;
+ format.encoderLossy = udcLossy;
+ format.decoder = decoder;
+ if (!format.builtin)
+ {
+ format.tagger = tagger;
+ format.allowLossless = allowLossless;
+ format.allowLossy = allowLossy;
+ format.allowLossyWAV = allowLossyWav;
+ format.allowEmbed = allowEmbed;
+ }
+ }
+ }
+
+ int totalScripts = sr.LoadInt32("CustomScripts", 0, null) ?? 0;
+ for (int nScripts = 0; nScripts < totalScripts; nScripts++)
+ {
+ string name = sr.Load(string.Format("CustomScript{0}Name", nScripts));
+ string code = sr.Load(string.Format("CustomScript{0}Code", nScripts));
+ List conditions = new List();
+ int totalConditions = sr.LoadInt32(string.Format("CustomScript{0}Conditions", nScripts), 0, null) ?? 0;
+ for (int nCondition = 0; nCondition < totalConditions; nCondition++)
+ conditions.Add((CUEAction)sr.LoadInt32(string.Format("CustomScript{0}Condition{1}", nScripts, nCondition), 0, null));
+ CUEToolsScript script;
+ if (!scripts.TryGetValue(name, out script))
+ {
+ if (name != "submit")
+ scripts.Add(name, new CUEToolsScript(name, false, conditions, code));
+ }
+ else
+ {
+ if (!script.builtin)
+ {
+ script.code = code;
+ script.conditions = conditions;
+ }
+ }
+ }
+
+ 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%";
+ }
+
+ public string GetDefaultDecoder(string extension)
+ {
+ CUEToolsUDC result = null;
+ foreach (KeyValuePair decoder in decoders)
+ if (decoder.Value.Extension == extension && (result == null || result.priority < decoder.Value.priority))
+ result = decoder.Value;
+ return result == null ? null : result.Name;
+ }
+
+ public IWebProxy GetProxy()
+ {
+ IWebProxy proxy = null;
+ switch (advanced.UseProxyMode)
+ {
+ case CUEConfigAdvanced.ProxyMode.System:
+ proxy = WebRequest.GetSystemWebProxy();
+ break;
+ case CUEConfigAdvanced.ProxyMode.Custom:
+ proxy = new WebProxy(advanced.ProxyServer, advanced.ProxyPort);
+ if (advanced.ProxyUser != "")
+ proxy.Credentials = new NetworkCredential(advanced.ProxyUser, advanced.ProxyPassword);
+ break;
+ }
+ return proxy;
+ }
+
+ public string CleanseString(string s)
+ {
+ StringBuilder sb = new StringBuilder();
+ char[] invalid = Path.GetInvalidFileNameChars();
+
+ if (filenamesANSISafe)
+ s = Encoding.Default.GetString(Encoding.Default.GetBytes(s));
+
+ for (int i = 0; i < s.Length; i++)
+ {
+ char ch = s[i];
+ if (filenamesANSISafe && removeSpecial && specialExceptions.IndexOf(ch) < 0 && !(
+ ((ch >= 'a') && (ch <= 'z')) ||
+ ((ch >= 'A') && (ch <= 'Z')) ||
+ ((ch >= '0') && (ch <= '9')) ||
+ (ch == ' ') || (ch == '_')))
+ ch = '_';
+ if ((Array.IndexOf(invalid, ch) >= 0) || (replaceSpaces && ch == ' '))
+ sb.Append("_");
+ else
+ sb.Append(ch);
+ }
+
+ return sb.ToString();
+ }
+ }
+}
diff --git a/CUETools.Processor/CUEConfigAdvanced.cs b/CUETools.Processor/CUEConfigAdvanced.cs
new file mode 100644
index 0000000..de99c76
--- /dev/null
+++ b/CUETools.Processor/CUEConfigAdvanced.cs
@@ -0,0 +1,72 @@
+using System;
+using System.ComponentModel;
+using System.Xml.Serialization;
+
+namespace CUETools.Processor
+{
+ [Serializable]
+ public class CUEConfigAdvanced
+ {
+ public enum ProxyMode
+ {
+ None,
+ System,
+ Custom
+ }
+
+ public CUEConfigAdvanced()
+ {
+ // Iterate through each property and call ResetValue()
+ foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this))
+ {
+ property.ResetValue(this);
+ }
+ }
+
+ internal static XmlSerializer serializer = new XmlSerializer(typeof(CUEConfigAdvanced));
+ [DefaultValue("i"), Category("Freedb"), DisplayName("Email user")]
+ public string FreedbUser { get; set; }
+
+ [DefaultValue("wont.tell"), Category("Freedb"), DisplayName("Email domain")]
+ public string FreedbDomain { get; set; }
+
+ [DefaultValue(ProxyMode.System), Category("Proxy"), DisplayName("Proxy mode")]
+ public ProxyMode UseProxyMode { get; set; }
+
+ [DefaultValue("127.0.0.1"), Category("Proxy"), DisplayName("Proxy server host")]
+ public string ProxyServer { get; set; }
+
+ [DefaultValue(8080), Category("Proxy"), DisplayName("Proxy server port")]
+ public int ProxyPort { get; set; }
+
+ [DefaultValue(""), Category("Proxy"), DisplayName("Proxy auth user")]
+ public string ProxyUser { get; set; }
+
+ [DefaultValue(""), Category("Proxy"), DisplayName("Proxy auth password")]
+ public string ProxyPassword { get; set; }
+
+ [DefaultValue(true), Category("Cache"), DisplayName("Cache metadata")]
+ public bool CacheMetadata { get; set; }
+
+ [DefaultValue(new string[] { "folder.jpg", "cover.jpg", "albumart.jpg", "thumbnail.jpg", "albumartlarge.jpg", "front.jpg", "%album%.jpg" })]
+ [Category("Cover Art"), DisplayName("Cover Art Files")]
+ public string[] CoverArtFiles { get; set; }
+
+ [DefaultValue(true)]
+ [Category("Cover Art"), DisplayName("Cover Art Extended Search")]
+ public bool CoverArtSearchSubdirs { get; set; }
+
+ [DefaultValue(false)]
+ [DisplayName("Create TOC files")]
+ public bool CreateTOC { get; set; }
+
+ [DefaultValue(true), Category("CTDB"), DisplayName("Submit to CTDB")]
+ public bool CTDBSubmit { get; set; }
+
+ [DefaultValue(true), Category("CTDB"), DisplayName("Ask before submitting")]
+ public bool CTDBAsk { get; set; }
+
+ [DefaultValue("db.cuetools.net"), Category("CTDB"), DisplayName("CTDB Server")]
+ public string CTDBServer { get; set; }
+ }
+}
diff --git a/CUETools.Processor/CUELine.cs b/CUETools.Processor/CUELine.cs
new file mode 100644
index 0000000..de2801b
--- /dev/null
+++ b/CUETools.Processor/CUELine.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CUETools.Processor
+{
+ public class CUELine
+ {
+ private List _params;
+ private List _quoted;
+
+ public CUELine()
+ {
+ _params = new List();
+ _quoted = new List();
+ }
+
+ public CUELine(string line)
+ {
+ int start, end, lineLen;
+ bool isQuoted;
+
+ _params = new List();
+ _quoted = new List();
+
+ start = 0;
+ lineLen = line.Length;
+
+ while (true)
+ {
+ while ((start < lineLen) && (line[start] == ' '))
+ {
+ start++;
+ }
+ if (start >= lineLen)
+ {
+ break;
+ }
+
+ isQuoted = (line[start] == '"');
+ if (isQuoted)
+ {
+ start++;
+ }
+
+ end = line.IndexOf(isQuoted ? '"' : ' ', start);
+ if (end == -1)
+ {
+ end = lineLen;
+ }
+
+ _params.Add(line.Substring(start, end - start));
+ _quoted.Add(isQuoted);
+
+ start = isQuoted ? end + 1 : end;
+ }
+ }
+
+ public List Params
+ {
+ get
+ {
+ return _params;
+ }
+ }
+
+ public List IsQuoted
+ {
+ get
+ {
+ return _quoted;
+ }
+ }
+
+ public override string ToString()
+ {
+ if (_params.Count != _quoted.Count)
+ {
+ throw new Exception("Parameter and IsQuoted lists must match.");
+ }
+
+ StringBuilder sb = new StringBuilder();
+ int last = _params.Count - 1;
+
+ for (int i = 0; i <= last; i++)
+ {
+ if (_quoted[i] || _params[i].Contains(" ")) sb.Append('"');
+ sb.Append(_params[i].Replace('"', '\''));
+ if (_quoted[i] || _params[i].Contains(" ")) sb.Append('"');
+ if (i < last) sb.Append(' ');
+ }
+
+ return sb.ToString();
+ }
+ }
+}
diff --git a/CUETools.Processor/CUEMetadata.cs b/CUETools.Processor/CUEMetadata.cs
index a1ec19f..82c138d 100644
--- a/CUETools.Processor/CUEMetadata.cs
+++ b/CUETools.Processor/CUEMetadata.cs
@@ -4,7 +4,7 @@ using System.ComponentModel;
using System.IO;
using System.Text;
using System.Xml.Serialization;
-using CUETools.CDImage;
+using CUETools.Processor.Settings;
namespace CUETools.Processor
{
@@ -330,48 +330,4 @@ namespace CUETools.Processor
return isVarious;
}
}
-
- public class CUETrackMetadata
- {
- public CUETrackMetadata()
- {
- Artist = "";
- Title = "";
- ISRC = "";
- }
- [DefaultValue("")]
- public string Artist { get; set; }
- [DefaultValue("")]
- public string Title { get; set; }
- [DefaultValue("")]
- public string ISRC { get; set; }
- }
-
- public class CUEMetadataEntry
- {
- public CUEMetadata metadata { get; set; }
- public CDImageLayout TOC { get; set; }
- public string ImageKey { get; set; }
-
- public CUEMetadataEntry(CUEMetadata metadata, CDImageLayout TOC, string key)
- {
- this.metadata = new CUEMetadata(metadata);
- this.TOC = TOC;
- this.ImageKey = key;
- }
-
- public CUEMetadataEntry(CDImageLayout TOC, string key)
- : this(new CUEMetadata(TOC.TOCID, (int)TOC.AudioTracks), TOC, key)
- {
- }
-
- public override string ToString()
- {
- return string.Format("{0}{1} - {2}{3}{4}", metadata.Year != "" ? metadata.Year + ": " : "",
- metadata.Artist == "" ? "Unknown Artist" : metadata.Artist,
- metadata.Title == "" ? "Unknown Title" : metadata.Title,
- metadata.DiscNumberAndName == "" ? "" : " (disc " + metadata.DiscNumberAndName + ")",
- metadata.ReleaseDateAndLabel == "" ? "" : " (" + metadata.ReleaseDateAndLabel + ")");
- }
- }
}
diff --git a/CUETools.Processor/CUEMetadataEntry.cs b/CUETools.Processor/CUEMetadataEntry.cs
new file mode 100644
index 0000000..668b2e6
--- /dev/null
+++ b/CUETools.Processor/CUEMetadataEntry.cs
@@ -0,0 +1,32 @@
+using CUETools.CDImage;
+
+namespace CUETools.Processor
+{
+ public class CUEMetadataEntry
+ {
+ public CUEMetadata metadata { get; set; }
+ public CDImageLayout TOC { get; set; }
+ public string ImageKey { get; set; }
+
+ public CUEMetadataEntry(CUEMetadata metadata, CDImageLayout TOC, string key)
+ {
+ this.metadata = new CUEMetadata(metadata);
+ this.TOC = TOC;
+ this.ImageKey = key;
+ }
+
+ public CUEMetadataEntry(CDImageLayout TOC, string key)
+ : this(new CUEMetadata(TOC.TOCID, (int)TOC.AudioTracks), TOC, key)
+ {
+ }
+
+ public override string ToString()
+ {
+ return string.Format("{0}{1} - {2}{3}{4}", metadata.Year != "" ? metadata.Year + ": " : "",
+ metadata.Artist == "" ? "Unknown Artist" : metadata.Artist,
+ metadata.Title == "" ? "Unknown Title" : metadata.Title,
+ metadata.DiscNumberAndName == "" ? "" : " (disc " + metadata.DiscNumberAndName + ")",
+ metadata.ReleaseDateAndLabel == "" ? "" : " (" + metadata.ReleaseDateAndLabel + ")");
+ }
+ }
+}
diff --git a/CUETools.Processor/CUEProcessorPlugins.cs b/CUETools.Processor/CUEProcessorPlugins.cs
new file mode 100644
index 0000000..ef13cea
--- /dev/null
+++ b/CUETools.Processor/CUEProcessorPlugins.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using CUETools.Codecs;
+using CUETools.Compression;
+using CUETools.Ripper;
+
+namespace CUETools.Processor
+{
+ public static class CUEProcessorPlugins
+ {
+ public static List encs;
+ public static List decs;
+ public static List arcp;
+ public static List arcp_fmt;
+ public static Type hdcd;
+ public static Type ripper;
+
+ static CUEProcessorPlugins()
+ {
+ encs = new List();
+ decs = new List();
+ arcp = new List();
+ arcp_fmt = new List();
+
+ encs.Add(typeof(CUETools.Codecs.WAVWriter));
+ decs.Add(typeof(CUETools.Codecs.WAVReader));
+
+ //ApplicationSecurityInfo asi = new ApplicationSecurityInfo(AppDomain.CurrentDomain.ActivationContext);
+ //string arch = asi.ApplicationId.ProcessorArchitecture;
+ //ActivationContext is null most of the time :(
+
+ string arch = Type.GetType("Mono.Runtime", false) != null ? "mono" : Marshal.SizeOf(typeof(IntPtr)) == 8 ? "x64" : "Win32";
+ string plugins_path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Plugins (" + arch + ")");
+ if (Directory.Exists(plugins_path))
+ AddPluginDirectory(plugins_path);
+ plugins_path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Plugins");
+ if (Directory.Exists(plugins_path))
+ AddPluginDirectory(plugins_path);
+ }
+
+ private static void AddPluginDirectory(string plugins_path)
+ {
+ foreach (string plugin_path in Directory.GetFiles(plugins_path, "*.dll", SearchOption.TopDirectoryOnly))
+ {
+ try
+ {
+ AddPlugin(plugin_path);
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Trace.WriteLine(ex.Message);
+ }
+ }
+ }
+
+ private static void AddPlugin(string plugin_path)
+ {
+ AssemblyName name = AssemblyName.GetAssemblyName(plugin_path);
+ Assembly assembly = Assembly.Load(name, Assembly.GetEntryAssembly().Evidence);
+ System.Diagnostics.Trace.WriteLine("Loaded " + assembly.FullName);
+ foreach (Type type in assembly.GetExportedTypes())
+ {
+ try
+ {
+ if (Attribute.GetCustomAttribute(type, typeof(AudioDecoderClass)) != null)
+ {
+ decs.Add(type);
+ }
+ //if (type.IsClass && !type.IsAbstract && typeof(IAudioDest).IsAssignableFrom(type))
+ if (Attribute.GetCustomAttributes(type, typeof(AudioEncoderClass)).Length > 0)
+ {
+ encs.Add(type);
+ }
+ CompressionProviderClass archclass = Attribute.GetCustomAttribute(type, typeof(CompressionProviderClass)) as CompressionProviderClass;
+ if (archclass != null)
+ {
+ arcp.Add(type);
+ if (!arcp_fmt.Contains(archclass.Extension))
+ arcp_fmt.Add(archclass.Extension);
+ }
+ if (type.Name == "HDCDDotNet")
+ {
+ hdcd = type;
+ }
+ if (type.IsClass && !type.IsAbstract && typeof(ICDRipper).IsAssignableFrom(type))
+ {
+ ripper = type;
+ }
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Trace.WriteLine(ex.Message);
+ }
+ }
+ }
+ }
+}
diff --git a/CUETools.Processor/CUESheet.cs b/CUETools.Processor/CUESheet.cs
new file mode 100644
index 0000000..be3b979
--- /dev/null
+++ b/CUETools.Processor/CUESheet.cs
@@ -0,0 +1,4496 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Globalization;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Threading;
+using CSScriptLibrary;
+using CUETools.AccurateRip;
+using CUETools.CDImage;
+using CUETools.CTDB;
+using CUETools.Codecs;
+using CUETools.Compression;
+using CUETools.Ripper;
+using Freedb;
+
+namespace CUETools.Processor
+{
+ public class CUESheet
+ {
+ private bool _stop, _pause;
+ private List _attributes;
+ private List _tracks;
+ internal List _sources;
+ private List _sourcePaths, _trackFilenames;
+ private string _htoaFilename, _singleFilename;
+ private bool _hasHTOAFilename = false, _hasTrackFilenames = false, _hasSingleFilename = false, _appliedWriteOffset;
+ private bool _hasEmbeddedCUESheet;
+ private bool _paddedToFrame, _truncated4608, _usePregapForFirstTrackInSingleFile;
+ private int _writeOffset;
+ private CUEAction _action;
+ internal bool _useAccurateRip = false;
+ internal bool _useCUEToolsDB = false;
+ private bool _useCUEToolsDBFix = false;
+ private bool _processed = false;
+ private uint? _minDataTrackLength;
+ private string _accurateRipId;
+ private string _eacLog;
+ private string _defaultLog;
+ private List _logFiles;
+ private string _inputPath, _inputDir;
+ private string _outputPath;
+ private string[] _destPaths;
+ private TagLib.File _fileInfo;
+ private const int _arOffsetRange = 5 * 588 - 1;
+ private IAudioDest hdcdDecoder;
+ private AudioEncoderType _audioEncoderType = AudioEncoderType.Lossless;
+ private bool _outputLossyWAV = false;
+ private string _outputFormat = "wav";
+ private CUEStyle _outputStyle = CUEStyle.SingleFile;
+ private CUEConfig _config;
+ private string _cddbDiscIdTag;
+ private bool _isCD;
+ private string _ripperLog;
+ private ICDRipper _ripper;
+ private bool _isArchive;
+ private List _archiveContents;
+ private string _archiveCUEpath;
+ private ICompressionProvider _archive;
+ private string _archivePassword;
+ private CUEToolsProgressEventArgs _progress;
+ private AccurateRipVerify _arVerify;
+ private CUEToolsDB _CUEToolsDB;
+ private CDImageLayout _toc;
+ private string _arLogFileName, _alArtFileName;
+ private List _albumArt = new List();
+ private int _padding = 8192;
+ private IWebProxy proxy;
+ private CUEMetadata taglibMetadata;
+ private CUEMetadata cueMetadata;
+ private bool _useLocalDB;
+ private CUEToolsLocalDB _localDB;
+
+ public event EventHandler PasswordRequired;
+ public event EventHandler CUEToolsProgress;
+ public event EventHandler CUEToolsSelection;
+
+ public CUESheet(CUEConfig config)
+ {
+ _config = config;
+ _progress = new CUEToolsProgressEventArgs();
+ _progress.cueSheet = this;
+ _attributes = new List();
+ _tracks = new List();
+ _trackFilenames = new List();
+ _toc = new CDImageLayout();
+ _sources = new List();
+ _sourcePaths = new List();
+ _stop = false;
+ _pause = false;
+ _outputPath = null;
+ _paddedToFrame = false;
+ _truncated4608 = false;
+ _usePregapForFirstTrackInSingleFile = false;
+ _action = CUEAction.Encode;
+ _appliedWriteOffset = false;
+ _minDataTrackLength = null;
+ hdcdDecoder = null;
+ _hasEmbeddedCUESheet = false;
+ _isArchive = false;
+ _isCD = false;
+ _useLocalDB = false;
+ proxy = _config.GetProxy();
+ }
+
+ public void OpenCD(ICDRipper ripper)
+ {
+ _ripper = ripper;
+ _toc = (CDImageLayout)_ripper.TOC.Clone();
+ for (int iTrack = 0; iTrack < _toc.AudioTracks; iTrack++)
+ {
+ _trackFilenames.Add(string.Format("{0:00}.wav", iTrack + 1));
+ _tracks.Add(new TrackInfo());
+ }
+ cueMetadata = new CUEMetadata(TOC.TOCID, (int)TOC.AudioTracks);
+ _arVerify = new AccurateRipVerify(_toc, proxy);
+ _isCD = true;
+ SourceInfo cdInfo;
+ cdInfo.Path = _ripper.ARName;
+ cdInfo.Offset = 0;
+ cdInfo.Length = _toc.AudioLength * 588;
+ _sources.Add(cdInfo);
+ // Causes memory leak, so had to disable!
+ //_ripper.ReadProgress += new EventHandler(CDReadProgress);
+ _padding += TrackCount * 200;
+ _padding += _config.embedLog ? 500 + TrackCount * 200 : 0;
+ }
+
+ public void Close()
+ {
+ if (_progress != null)
+ {
+ _progress.cueSheet = null;
+ _progress = null;
+ }
+ if (_archive != null)
+ _archive.Close();
+ _archive = null;
+ if (_ripper != null)
+ {
+ //_ripper.ReadProgress -= new EventHandler(CDReadProgress);
+ _ripper.Close();
+ }
+ _ripper = null;
+ }
+
+ public string InputPath
+ {
+ get
+ {
+ return _inputPath;
+ }
+ }
+
+ public AccurateRipVerify ArVerify
+ {
+ get
+ {
+ return _arVerify;
+ }
+ }
+
+ public CUEToolsDB CTDB
+ {
+ get
+ {
+ return _CUEToolsDB;
+ }
+ }
+
+ public ICDRipper CDRipper
+ {
+ get
+ {
+ return _ripper;
+ }
+ set
+ {
+ _ripper = value;
+ }
+ }
+
+ public void CopyMetadata(CUEMetadata metadata)
+ {
+ if (this.cueMetadata == null)
+ this.cueMetadata = new CUEMetadata(TOC.TOCID, (int)TOC.AudioTracks);
+ this.cueMetadata.CopyMetadata(metadata);
+ }
+
+ public CUEMetadata Metadata
+ {
+ get
+ {
+ return cueMetadata;
+ }
+ }
+
+ protected void ReportProgress(string status, double percent)
+ {
+ ShowProgress(status, percent, null, null);
+ }
+
+ public void ScanLocalDB(string folder)
+ {
+ var results = new List();
+
+ int n = 2, j = 0;
+ foreach (var fmt in _config.formats)
+ if (fmt.Value.allowLossless)
+ n++;
+
+ CheckStop();
+ ReportProgress("Scanning *.cue", (double)(j++) / n);
+ results.AddRange(Directory.GetFiles(folder, "*.cue", SearchOption.AllDirectories));
+
+ CheckStop();
+ ReportProgress("Scanning *.m3u", (double)(j++) / n);
+ results.AddRange(Directory.GetFiles(folder, "*.m3u", SearchOption.AllDirectories));
+
+ foreach (var fmt in _config.formats)
+ if (fmt.Value.allowLossless)
+ {
+ CheckStop();
+ ReportProgress("Scanning *." + fmt.Key, (double)(j++) / n);
+ results.AddRange(Directory.GetFiles(folder, "*." + fmt.Key, SearchOption.AllDirectories));
+ }
+
+ int i = 0;
+ foreach (var result in results)
+ {
+ CheckStop();
+
+ var path = CUEToolsLocalDBEntry.NormalizePath(result);
+ var pathextension = Path.GetExtension(path).ToLower();
+ bool skip = false;
+ if (_localDB.Find(
+ item => item.HasPath(path) ||
+ (item.AudioPaths != null &&
+ item.AudioPaths.Count > 1 &&
+ item.AudioPaths.Contains(path))
+ ) != null)
+ skip = true;
+ if (!skip && pathextension == ".m3u")
+ {
+ var contents = new List();
+ using (StreamReader m3u = new StreamReader(path))
+ {
+ do
+ {
+ string line = m3u.ReadLine();
+ if (line == null) break;
+ if (line == "" || line[0] == '#') continue;
+ //if (line.IndexOfAny(Path.GetInvalidPathChars()) >= 0)
+ // continue;
+ try
+ {
+ string extension = Path.GetExtension(line);
+ CUEToolsFormat fmt1;
+ if (!extension.StartsWith(".") || !_config.formats.TryGetValue(extension.ToLower().Substring(1), out fmt1) || !fmt1.allowLossless)
+ {
+ skip = true;
+ break;
+ }
+ string fullpath = CUEToolsLocalDBEntry.NormalizePath(Path.Combine(Path.GetDirectoryName(path), line));
+ if (!File.Exists(fullpath))
+ {
+ skip = true;
+ break;
+ }
+ contents.Add(fullpath);
+ }
+ catch
+ {
+ skip = true;
+ break;
+ }
+ } while (!skip);
+ }
+ if (!skip && _localDB.Find(item => item.EqualAudioPaths(contents)) != null)
+ skip = true;
+ }
+ if (!skip && pathextension != ".cue" && pathextension != ".m3u")
+ {
+ if (_localDB.Find(item =>
+ item.AudioPaths != null &&
+ item.AudioPaths.Count == 1 &&
+ item.AudioPaths[0] == path
+ ) != null)
+ {
+ CUEToolsFormat fmt;
+ if (!pathextension.StartsWith(".") || !_config.formats.TryGetValue(pathextension.Substring(1), out fmt) || !fmt.allowLossless || !fmt.allowEmbed)
+ skip = true;
+ else
+ {
+ TagLib.File fileInfo;
+ TagLib.UserDefined.AdditionalFileTypes.Config = _config;
+ TagLib.File.IFileAbstraction file = (TagLib.File.IFileAbstraction)new TagLib.File.LocalFileAbstraction(path);
+ fileInfo = TagLib.File.Create(file);
+ NameValueCollection tags = Tagging.Analyze(fileInfo);
+ if (tags.Get("CUESHEET") == null)
+ skip = true;
+ }
+ }
+ }
+ if (skip)
+ {
+ ReportProgress("Skipping " + path, (double)(i++) / results.Count);
+ }
+ else
+ {
+ ReportProgress("Checking " + path, (double)(i++) / results.Count);
+ var cueSheet = new CUESheet(_config);
+ cueSheet.UseLocalDB(_localDB);
+ //cueSheet.PasswordRequired += new EventHandler(PasswordRequired);
+ //cueSheet.CUEToolsProgress += new EventHandler(SetStatus);
+ //cueSheet.CUEToolsSelection += new EventHandler(MakeSelection);
+ try
+ {
+ cueSheet.Open(path);
+ cueSheet.OpenLocalDBEntry();
+ }
+ catch (Exception)
+ {
+ }
+ cueSheet.Close();
+ }
+ }
+ _localDB.Save();
+ }
+
+ public List