// ****************************************************************************
//
// CUE Tools
// Copyright (C) 2006-2007 Moitah (moitah@yahoo.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// ****************************************************************************
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Globalization;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Threading;
using System.Xml;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using HDCDDotNet;
using CUETools.Codecs;
using CUETools.Codecs.LossyWAV;
using CUETools.CDImage;
using CUETools.AccurateRip;
using CUETools.Ripper.SCSI;
using MusicBrainz;
using Freedb;
#if !MONO
using UnRarDotNet;
using CUETools.Codecs.FLAC;
#endif
using ICSharpCode.SharpZipLib.Zip;
using CSScriptLibrary;
namespace CUETools.Processor
{
public enum AudioEncoderType
{
Lossless,
Hybrid,
Lossy,
///
/// No Audio
///
NoAudio,
}
public enum CUEAction
{
Convert,
Verify,
VerifyAndConvert,
CreateDummyCUE,
CorrectFilenames
}
public enum CUEStyle
{
///
/// Single file with embedded CUE
///
SingleFileWithCUE,
///
/// Single file with external CUE
///
SingleFile,
///
/// Gaps prepended file-per-track
///
GapsPrepended,
///
/// Gaps appended (noncompliant) file-per-track
///
GapsAppended,
///
/// Gaps left out file-per-track
///
GapsLeftOut
}
public static class General {
public static CUELine FindCUELine(List list, string command) {
command = command.ToUpper();
foreach (CUELine line in list) {
if (line.Params[0].ToUpper() == command) {
return line;
}
}
return null;
}
public static CUELine FindCUELine(List list, string command, string command2)
{
command = command.ToUpper();
command2 = command2.ToUpper();
foreach (CUELine line in list)
{
if (line.Params.Count > 1 && line.Params[0].ToUpper() == command && line.Params[1].ToUpper() == command2)
{
return line;
}
}
return null;
}
//public static CUELine FindCUELine(List list, string [] commands)
//{
// foreach (CUELine line in list)
// {
// if (line.Params.Count < commands.Length)
// continue;
// for (int i = 0; i < commands.Length; i++)
// {
// if (line.Params[i].ToUpper() != commands[i].ToUpper())
// break;
// if (i == commands.Length - 1)
// return line;
// }
// }
// return null;
//}
public static void SetCUELine(List list, string command, string value, bool quoted)
{
CUELine line = General.FindCUELine(list, command);
if (line == null)
{
line = new CUELine();
line.Params.Add(command); line.IsQuoted.Add(false);
line.Params.Add(value); line.IsQuoted.Add(quoted);
list.Add(line);
}
else
{
while (line.Params.Count > 1)
{
line.Params.RemoveAt(1);
line.IsQuoted.RemoveAt(1);
}
line.Params.Add(value); line.IsQuoted.Add(quoted);
}
}
public static void SetCUELine(List list, string command, string command2, string value, bool quoted)
{
CUELine line = General.FindCUELine(list, command, command2);
if (line == null)
{
line = new CUELine();
line.Params.Add(command); line.IsQuoted.Add(false);
line.Params.Add(command2); line.IsQuoted.Add(false);
line.Params.Add(value); line.IsQuoted.Add(quoted);
list.Add(line);
}
else
{
while (line.Params.Count > 2)
{
line.Params.RemoveAt(2);
line.IsQuoted.RemoveAt(2);
}
line.Params.Add(value); line.IsQuoted.Add(quoted);
}
}
public static void DelCUELine(List list, string command, string command2)
{
CUELine line = General.FindCUELine(list, command, command2);
if (line == null)
return;
list.Remove(line);
}
public static void DelCUELine(List list, string command)
{
CUELine line = General.FindCUELine(list, command);
if (line == null)
return;
list.Remove(line);
}
public static string ReplaceMultiple(string s, List find, List replace)
{
if (find.Count != replace.Count)
{
throw new ArgumentException();
}
StringBuilder sb;
int iChar, iFind;
string f;
bool found;
sb = new StringBuilder();
for (iChar = 0; iChar < s.Length; iChar++)
{
found = false;
for (iFind = 0; iFind < find.Count; iFind++)
{
f = find[iFind];
if ((f.Length <= (s.Length - iChar)) && (s.Substring(iChar, f.Length) == f))
{
if (replace[iFind] == null)
{
return null;
}
sb.Append(replace[iFind]);
iChar += f.Length - 1;
found = true;
break;
}
}
if (!found)
{
sb.Append(s[iChar]);
}
}
return sb.ToString();
}
public static string EmptyStringToNull(string s)
{
return ((s != null) && (s.Length == 0)) ? null : s;
}
}
public enum CUEToolsTagger
{
TagLibSharp = 0,
APEv2 = 1,
ID3v2 = 2,
}
public class CUEToolsFormat
{
public CUEToolsFormat(
string _extension,
CUEToolsTagger _tagger,
bool _allowLossless,
bool _allowLossy,
bool _allowLossyWAV,
bool _allowEmbed,
bool _builtin,
string _encoderLossless,
string _encoderLossy,
string _decoder)
{
extension = _extension;
tagger = _tagger;
allowLossless = _allowLossless;
allowLossy = _allowLossy;
allowLossyWAV = _allowLossyWAV;
allowEmbed = _allowEmbed;
builtin = _builtin;
encoderLossless = _encoderLossless;
encoderLossy = _encoderLossy;
decoder = _decoder;
}
public override string ToString()
{
return extension;
}
public string extension;
public string encoderLossless;
public string encoderLossy;
public string decoder;
public CUEToolsTagger tagger;
public bool allowLossless, allowLossy, allowLossyWAV, allowEmbed, builtin;
}
public class CUEToolsUDC
{
public CUEToolsUDC(
string _name,
string _extension,
bool _lossless,
string _path,
string _parameters
)
{
name = _name;
extension = _extension;
lossless = _lossless;
path = _path;
parameters = _parameters;
className = null;
}
public CUEToolsUDC(
string _name,
string _extension,
bool _lossless,
string _className)
{
name = _name;
extension = _extension;
lossless = _lossless;
path = null;
parameters = null;
className = _className;
}
public override string ToString()
{
return name;
}
public string name;
public string extension;
public string path;
public string parameters;
public string className;
public bool lossless;
}
public class CUEToolsScript
{
public CUEToolsScript(string _name, bool _builtin, IEnumerable _conditions, string _code)
{
name = _name;
builtin = _builtin;
conditions = new List();
foreach(CUEAction condition in _conditions)
conditions.Add(condition);
code = _code;
}
public override string ToString()
{
return name;
}
public string name;
public bool builtin;
public List conditions;
public string code;
}
public class CUEConfig {
public uint fixOffsetMinimumConfidence;
public uint fixOffsetMinimumTracksPercent;
public uint encodeWhenConfidence;
public uint encodeWhenPercent;
public bool encodeWhenZeroOffset;
public bool writeArTagsOnVerify;
public bool writeArLogOnVerify;
public bool writeArTagsOnConvert;
public bool writeArLogOnConvert;
public bool fixOffset;
public bool noUnverifiedOutput;
public bool autoCorrectFilenames;
public bool flacVerify;
public uint flacCompressionLevel;
public uint apeCompressionLevel;
public bool preserveHTOA;
public int wvCompressionMode;
public int wvExtraMode;
public bool wvStoreMD5;
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 createTOC;
public bool createCUEFileWhenEmbedded;
public bool truncate4608ExtraSamples;
public int lossyWAVQuality;
public bool decodeHDCDtoLW16;
public bool decodeHDCDto24bit;
public bool disableAsm;
public bool oneInstance;
public string language;
public Dictionary formats;
public Dictionary encoders;
public Dictionary decoders;
public Dictionary scripts;
public string defaultVerifyScript;
public string defaultConvertScript;
public string defaultVerifyAndConvertScript;
public bool writeBasicTagsFromCUEData;
public bool copyBasicTags;
public bool copyUnknownTags;
public bool copyAlbumArt;
public bool embedAlbumArt;
//public bool extractAlbumArt;
public bool arLogToSourceFolder;
public bool arLogVerbose;
public bool fixOffsetToNearest;
public int maxAlbumArtSize;
public string arLogExtension;
public CUEConfig()
{
fixOffsetMinimumConfidence = 2;
fixOffsetMinimumTracksPercent = 51;
encodeWhenConfidence = 2;
encodeWhenPercent = 100;
encodeWhenZeroOffset = false;
fixOffset = false;
noUnverifiedOutput = false;
writeArTagsOnConvert = true;
writeArLogOnConvert = true;
writeArTagsOnVerify = false;
writeArLogOnVerify = true;
autoCorrectFilenames = true;
flacVerify = false;
flacCompressionLevel = 8;
apeCompressionLevel = 2;
preserveHTOA = true;
wvCompressionMode = 1;
wvExtraMode = 0;
wvStoreMD5 = false;
keepOriginalFilenames = false;
trackFilenameFormat = "%N. %T";
singleFilenameFormat = "%F";
removeSpecial = false;
specialExceptions = "-()";
replaceSpaces = false;
embedLog = true;
extractLog = true;
fillUpCUE = true;
overwriteCUEData = false;
filenamesANSISafe = true;
bruteForceDTL = false;
createEACLOG = false;
detectHDCD = true;
wait750FramesForHDCD = true;
decodeHDCD = false;
createM3U = false;
createTOC = false;
createCUEFileWhenEmbedded = true;
truncate4608ExtraSamples = true;
lossyWAVQuality = 5;
decodeHDCDtoLW16 = false;
decodeHDCDto24bit = true;
disableAsm = false;
oneInstance = true;
writeBasicTagsFromCUEData = true;
copyBasicTags = true;
copyUnknownTags = true;
copyAlbumArt = true;
embedAlbumArt = true;
maxAlbumArtSize = 300;
arLogToSourceFolder = false;
arLogVerbose = true;
fixOffsetToNearest = true;
arLogExtension = ".accurip";
language = Thread.CurrentThread.CurrentUICulture.Name;
formats = new Dictionary();
formats.Add("flac", new CUEToolsFormat("flac", CUEToolsTagger.TagLibSharp, true, false, true, true, true, "libFLAC", null, "libFLAC"));
formats.Add("wv", new CUEToolsFormat("wv", CUEToolsTagger.TagLibSharp, true, false, true, true, true, "libwavpack", null, "libwavpack"));
formats.Add("ape", new CUEToolsFormat("ape", CUEToolsTagger.TagLibSharp, true, false, false, true, true, "MAC_SDK", null, "MAC_SDK"));
formats.Add("tta", new CUEToolsFormat("tta", CUEToolsTagger.APEv2, true, false, false, false, true, "ttalib", null, "ttalib"));
formats.Add("wav", new CUEToolsFormat("wav", CUEToolsTagger.TagLibSharp, true, false, true, false, true, "builtin wav", null, "builtin wav"));
formats.Add("tak", new CUEToolsFormat("tak", CUEToolsTagger.APEv2, true, false, true, true, true, "takc", null, "takc"));
formats.Add("m4a", new CUEToolsFormat("m4a", CUEToolsTagger.TagLibSharp, true, true, false, false, true, "ffmpeg alac", "nero aac", "builtin alac"));
formats.Add("mp3", new CUEToolsFormat("mp3", CUEToolsTagger.TagLibSharp, false, true, false, false, true, null, "lame -V0", null));
formats.Add("ogg", new CUEToolsFormat("ogg", CUEToolsTagger.TagLibSharp, false, true, false, false, true, null, "oggenc", null));
encoders = new Dictionary();
#if !MONO
encoders.Add("libFLAC", new CUEToolsUDC("libFLAC", "flac", true, "FLACWriter"));
encoders.Add("libwavpack", new CUEToolsUDC("libwavpack", "wv", true, "WavPackWriter"));
encoders.Add("MAC_SDK", new CUEToolsUDC("MAC_SDK", "ape", true, "APEWriter"));
encoders.Add("ttalib", new CUEToolsUDC("ttalib", "tta", true, "TTAWriter"));
#endif
encoders.Add("builtin wav", new CUEToolsUDC("builtin wav", "wav", true, "WAVWriter"));
encoders.Add("flake", new CUEToolsUDC("flake", "flac", true, "flake.exe", "-10 - -o %O"));
encoders.Add("takc", new CUEToolsUDC("takc", "tak", true, "takc.exe", "-e -p4m -overwrite - %O"));
encoders.Add("ffmpeg alac", new CUEToolsUDC("ffmpeg alac", "m4a", true, "ffmpeg.exe", "-i - -f ipod -acodec alac -y %O"));
encoders.Add("lame -V2", new CUEToolsUDC("lame -V2", "mp3", false, "lame.exe", "--vbr-new -V2 - %O"));
encoders.Add("lame -V0", new CUEToolsUDC("lame -V0", "mp3", false, "lame.exe", "--vbr-new -V0 - %O"));
encoders.Add("lame 256", new CUEToolsUDC("lame 256", "mp3", false, "lame.exe", "-m s -q 0 -b 256 --noreplaygain - %O"));
encoders.Add("lame 320", new CUEToolsUDC("lame 320", "mp3", false, "lame.exe", "-m s -q 0 -b 320 --noreplaygain - %O"));
encoders.Add("oggenc", new CUEToolsUDC("oggenc", "ogg", false, "oggenc.exe", "-q 3 - -o %O"));
encoders.Add("nero aac", new CUEToolsUDC("nero aac", "m4a", false, "neroAacEnc.exe", "-q 0.4 -if - -of %O"));
decoders = new Dictionary();
#if !MONO
decoders.Add("libFLAC", new CUEToolsUDC("libFLAC", "flac", true, "FLACReader"));
decoders.Add("libwavpack", new CUEToolsUDC("libwavpack", "wv", true, "WavPackReader"));
decoders.Add("MAC_SDK", new CUEToolsUDC("MAC_SDK", "ape", true, "APEReader"));
decoders.Add("ttalib", new CUEToolsUDC("ttalib", "tta", true, "TTAReader"));
#endif
decoders.Add("builtin wav", new CUEToolsUDC("builtin wav", "wav", true, "WAVReader"));
decoders.Add("builtin alac", new CUEToolsUDC("builtin alac", "m4a", true, "ALACReader"));
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 -"));
scripts = new Dictionary();
scripts.Add("default", new CUEToolsScript("default", true,
new CUEAction[] { CUEAction.VerifyAndConvert, CUEAction.Verify, CUEAction.Convert },
"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.VerifyAndConvert },
@"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.VerifyAndConvert;
//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.VerifyAndConvert },
@"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.VerifyAndConvert;
return processor.Go();
"));
defaultVerifyScript = "default";
defaultConvertScript = "default";
defaultVerifyAndConvertScript = "default";
}
public void Save (SettingsWriter sw)
{
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", writeArTagsOnConvert);
sw.Save("ArWriteLog", writeArLogOnConvert);
sw.Save("ArWriteTagsOnVerify", writeArTagsOnVerify);
sw.Save("ArWriteLogOnVerify", writeArLogOnVerify);
sw.Save("PreserveHTOA", preserveHTOA);
sw.Save("AutoCorrectFilenames", autoCorrectFilenames);
sw.Save("FLACCompressionLevel", flacCompressionLevel);
sw.Save("APECompressionLevel", apeCompressionLevel);
sw.Save("FLACVerify", flacVerify);
sw.Save("WVCompressionMode", wvCompressionMode);
sw.Save("WVExtraMode", wvExtraMode);
sw.Save("WVStoreMD5", wvStoreMD5);
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);
if (createEACLOG) sw.Save("CreateEACLOG", createEACLOG);
sw.Save("DetectHDCD", detectHDCD);
sw.Save("Wait750FramesForHDCD", wait750FramesForHDCD);
sw.Save("DecodeHDCD", decodeHDCD);
sw.Save("CreateM3U", createM3U);
sw.Save("CreateTOC", createTOC);
sw.Save("CreateCUEFileWhenEmbedded", createCUEFileWhenEmbedded);
sw.Save("Truncate4608ExtraSamples", truncate4608ExtraSamples);
sw.Save("LossyWAVQuality", lossyWAVQuality);
sw.Save("DecodeHDCDToLossyWAV16", decodeHDCDtoLW16);
sw.Save("DecodeHDCDTo24bit", decodeHDCDto24bit);
sw.Save("DisableAsm", disableAsm);
sw.Save("OneInstance", oneInstance);
sw.Save("Language", language);
sw.Save("WriteBasicTagsFromCUEData", writeBasicTagsFromCUEData);
sw.Save("CopyBasicTags", copyBasicTags);
sw.Save("CopyUnknownTags", copyUnknownTags);
sw.Save("CopyAlbumArt", copyAlbumArt);
sw.Save("EmbedAlbumArt", embedAlbumArt);
sw.Save("MaxAlbumArtSize", maxAlbumArtSize);
sw.Save("ArLogToSourceFolder", arLogToSourceFolder);
sw.Save("ArLogVerbose", arLogVerbose);
sw.Save("FixOffsetToNearest", fixOffsetToNearest);
sw.Save("ArLogExtension", arLogExtension);
int nEncoders = 0;
foreach (KeyValuePair encoder in encoders)
if (encoder.Value.path != null)
{
sw.Save(string.Format("ExternalEncoder{0}Name", nEncoders), encoder.Key);
sw.Save(string.Format("ExternalEncoder{0}Extension", nEncoders), encoder.Value.extension);
sw.Save(string.Format("ExternalEncoder{0}Path", nEncoders), encoder.Value.path);
sw.Save(string.Format("ExternalEncoder{0}Parameters", nEncoders), encoder.Value.parameters);
sw.Save(string.Format("ExternalEncoder{0}Lossless", nEncoders), encoder.Value.lossless);
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);
sw.Save(string.Format("CustomFormat{0}EncoderLossy", nFormats), format.Value.encoderLossy);
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("DefaultConvertScript", defaultConvertScript);
sw.Save("DefaultVerifyAndConvertScript", defaultVerifyAndConvertScript);
}
public void Load(SettingsReader sr)
{
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;
writeArTagsOnConvert = sr.LoadBoolean("ArWriteCRC") ?? true;
writeArLogOnConvert = sr.LoadBoolean("ArWriteLog") ?? true;
writeArTagsOnVerify = sr.LoadBoolean("ArWriteTagsOnVerify") ?? false;
writeArLogOnVerify = sr.LoadBoolean("ArWriteLogOnVerify") ?? true;
preserveHTOA = sr.LoadBoolean("PreserveHTOA") ?? true;
autoCorrectFilenames = sr.LoadBoolean("AutoCorrectFilenames") ?? true;
flacCompressionLevel = sr.LoadUInt32("FLACCompressionLevel", 0, 8) ?? 8;
flacVerify = sr.LoadBoolean("FLACVerify") ?? false;
apeCompressionLevel = sr.LoadUInt32("APECompressionLevel", 1, 5) ?? 2;
wvCompressionMode = sr.LoadInt32("WVCompressionMode", 0, 3) ?? 1;
wvExtraMode = sr.LoadInt32("WVExtraMode", 0, 6) ?? 0;
wvStoreMD5 = sr.LoadBoolean("WVStoreMD5") ?? false;
keepOriginalFilenames = sr.LoadBoolean("KeepOriginalFilenames") ?? false;
singleFilenameFormat = sr.Load("SingleFilenameFormat") ?? "%F";
trackFilenameFormat = sr.Load("TrackFilenameFormat") ?? "%N. %T";
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") ?? false;
detectHDCD = sr.LoadBoolean("DetectHDCD") ?? true;
wait750FramesForHDCD = sr.LoadBoolean("Wait750FramesForHDCD") ?? true;
decodeHDCD = sr.LoadBoolean("DecodeHDCD") ?? false;
createM3U = sr.LoadBoolean("CreateM3U") ?? false;
createTOC = sr.LoadBoolean("CreateTOC") ?? 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;
disableAsm = sr.LoadBoolean("DisableAsm") ?? false;
oneInstance = sr.LoadBoolean("OneInstance") ?? 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;
maxAlbumArtSize = sr.LoadInt32("MaxAlbumArtSize", 100, 3000) ?? maxAlbumArtSize;
arLogToSourceFolder = sr.LoadBoolean("ArLogToSourceFolder") ?? arLogToSourceFolder;
arLogVerbose = sr.LoadBoolean("ArLogVerbose") ?? arLogVerbose;
fixOffsetToNearest = sr.LoadBoolean("FixOffsetToNearest") ?? fixOffsetToNearest;
arLogExtension = sr.Load("ArLogExtension") ?? arLogExtension;
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;
CUEToolsUDC encoder;
if (!encoders.TryGetValue(name, out encoder))
encoders.Add(name, new CUEToolsUDC(name, extension, lossless, path, parameters));
else
{
if (encoder.path != null)
{
encoder.extension = extension;
encoder.path = path;
encoder.parameters = parameters;
encoder.lossless = lossless;
}
}
}
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;
if (!formats.TryGetValue(extension, out format))
formats.Add(extension, new CUEToolsFormat(extension, tagger, allowLossless, allowLossy, allowLossyWav, allowEmbed, false, encoderLossless, encoderLossy, decoder));
else
{
format.encoderLossless = encoderLossless;
format.encoderLossy = encoderLossy;
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))
scripts.Add(name, new CUEToolsScript(name, false, conditions, code));
else
{
if (!script.builtin)
{
script.code = code;
script.conditions = conditions;
}
}
}
defaultVerifyScript = sr.Load("DefaultVerifyScript") ?? "default";
defaultConvertScript = sr.Load("DefaultConvertScript") ?? "default";
defaultVerifyAndConvertScript = sr.Load("DefaultVerifyAndConvertScript") ?? "default";
language = sr.Load("Language") ?? Thread.CurrentThread.CurrentUICulture.Name;
}
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();
}
}
public class CUEToolsProgressEventArgs
{
public string status = string.Empty;
public double percentTrck = 0;
public double percentDisk = 0.0;
public string input = string.Empty;
public string output = string.Empty;
}
public class ArchivePasswordRequiredEventArgs
{
public string Password = string.Empty;
public bool ContinueOperation = true;
}
public class CUEToolsSourceFile
{
public string path;
public string contents;
public bool isEAC;
public CUEToolsSourceFile(string _path, StreamReader reader)
{
path = _path;
contents = reader.ReadToEnd();
reader.Close();
}
}
public class CUEToolsSelectionEventArgs
{
public object[] choices;
public int selection = -1;
}
public delegate void CUEToolsSelectionHandler(object sender, CUEToolsSelectionEventArgs e);
public delegate void CUEToolsProgressHandler(object sender, CUEToolsProgressEventArgs e);
public delegate void ArchivePasswordRequiredHandler(object sender, ArchivePasswordRequiredEventArgs e);
public class CUESheet {
private bool _stop, _pause;
private List _attributes;
private List _tracks;
private 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;
private uint? _minDataTrackLength;
private string _accurateRipId;
private string _eacLog;
private string _inputPath, _inputDir;
private string _outputPath;
private string[] _destPaths;
private TagLib.File _fileInfo;
private const int _arOffsetRange = 5 * 588 - 1;
private HDCDDotNet.HDCDDotNet 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 CDDriveReader _ripper;
private bool _isArchive;
private List _archiveContents;
private string _archiveCUEpath;
private string _archivePath;
private string _archivePassword;
private CUEToolsProgressEventArgs _progress;
private AccurateRipVerify _arVerify;
private CDImageLayout _toc;
public event ArchivePasswordRequiredHandler PasswordRequired;
public event CUEToolsProgressHandler CUEToolsProgress;
public event CUEToolsSelectionHandler CUEToolsSelection;
public CUESheet(CUEConfig config)
{
_config = config;
_progress = new CUEToolsProgressEventArgs();
_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.Convert;
_appliedWriteOffset = false;
_minDataTrackLength = null;
hdcdDecoder = null;
_hasEmbeddedCUESheet = false;
_isArchive = false;
_isCD = false;
}
public void OpenCD(CDDriveReader 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());
}
_arVerify = new AccurateRipVerify(_toc);
_isCD = true;
SourceInfo cdInfo;
cdInfo.Path = _ripper.ARName;
cdInfo.Offset = 0;
cdInfo.Length = _toc.AudioLength * 588;
_sources.Add(cdInfo);
_ripper.ReadProgress += new EventHandler(CDReadProgress);
}
public void Close()
{
if (_ripper != null)
_ripper.Close();
_ripper = null;
}
public AccurateRipVerify ArVerify
{
get
{
return _arVerify;
}
}
public CDDriveReader CDRipper
{
get
{
return _ripper;
}
set
{
_ripper = value;
}
}
public void FillFromMusicBrainz(MusicBrainz.Release release)
{
Year = release.GetEvents().Count > 0 ? release.GetEvents()[0].Date.Substring(0, 4) : "";
Artist = release.GetArtist();
Title = release.GetTitle();
//Catalog = release.GetEvents().Count > 0 ? release.GetEvents()[0].Barcode : "";
for (int i = 1; i <= _toc.AudioTracks; i++)
{
MusicBrainz.Track track = release.GetTracks()[(int)_toc[i].Number - 1]; // !!!!!! - _toc.FirstAudio
Tracks[i - 1].Title = track.GetTitle();
Tracks[i - 1].Artist = track.GetArtist();
}
}
public void FillFromFreedb(Freedb.CDEntry cdEntry)
{
Year = cdEntry.Year;
Genre = cdEntry.Genre;
Artist = cdEntry.Artist;
Title = cdEntry.Title;
for (int i = 0; i < _toc.AudioTracks; i++)
{
Tracks[i].Title = cdEntry.Tracks[i].Title;
Tracks[i].Artist = cdEntry.Artist;
}
}
public List