public CUEMetadataEntry(CDImageLayout TOC, string key) : this(new CUEMetadata(TOC.TOCID, (int)TOC.AudioTracks), TOC, key) { }
static void Main(string[] args) { Console.SetOut(Console.Error); Console.WriteLine("CUERipper v2.1.7 Copyright (C) 2008-10 Grigory Chudov"); Console.WriteLine("This is free software under the GNU GPLv3+ license; There is NO WARRANTY, to"); Console.WriteLine("the extent permitted by law. <http://www.gnu.org/licenses/> for details."); int correctionQuality = 1; string driveLetter = null; int driveOffset = 0; bool test = false; bool forceD8 = false, forceBE = false, quiet = false; for (int arg = 0; arg < args.Length; arg++) { bool ok = true; if (args[arg] == "-P" || args[arg] == "--paranoid") { correctionQuality = 2; } else if (args[arg] == "-S" || args[arg] == "--secure") { correctionQuality = 1; } else if (args[arg] == "-B" || args[arg] == "--burst") { correctionQuality = 0; } else if (args[arg] == "-T" || args[arg] == "--test") { test = true; } else if (args[arg] == "--d8") { forceD8 = true; } else if (args[arg] == "--be") { forceBE = true; } else if (args[arg] == "-Q" || args[arg] == "--quiet") { quiet = true; } else if ((args[arg] == "-D" || args[arg] == "--drive") && ++arg < args.Length) { driveLetter = args[arg]; } else if ((args[arg] == "-O" || args[arg] == "--offset") && ++arg < args.Length) { ok = int.TryParse(args[arg], out driveOffset); } else { ok = false; } if (!ok) { Usage(); return; } } char[] drives; if (driveLetter == null || driveLetter.Length < 1) { drives = CDDrivesList.DrivesAvailable(); if (drives.Length < 1) { Console.WriteLine("No CD drives found."); return; } } else { drives = new char[1]; drives[0] = driveLetter[0]; } #if !DEBUG try #endif { CDDriveReader audioSource = new CDDriveReader(); audioSource.Open(drives[0]); if (audioSource.TOC.AudioTracks < 1) { Console.WriteLine("{0}: CD does not contain any audio tracks.", audioSource.Path); audioSource.Close(); return; } if (driveOffset == 0) { if (!AccurateRipVerify.FindDriveReadOffset(audioSource.ARName, out driveOffset)) { Console.WriteLine("Unknown read offset for drive {0}!!!", audioSource.Path); } } //throw new Exception("Failed to find drive read offset for drive" + audioSource.ARName); audioSource.DriveOffset = driveOffset; audioSource.CorrectionQuality = correctionQuality; audioSource.DebugMessages = !quiet; if (forceD8) { audioSource.ForceD8 = true; } if (forceBE) { audioSource.ForceBE = true; } string readCmd = audioSource.AutoDetectReadCommand; if (test) { Console.Write(readCmd); return; } AccurateRipVerify arVerify = new AccurateRipVerify(audioSource.TOC, WebRequest.GetSystemWebProxy()); AudioBuffer buff = new AudioBuffer(audioSource, 0x10000); string CDDBId = AccurateRipVerify.CalculateCDDBId(audioSource.TOC); string ArId = AccurateRipVerify.CalculateAccurateRipId(audioSource.TOC); var ctdb = new CUEToolsDB(audioSource.TOC, null); ctdb.Init(arVerify); ctdb.ContactDB(null, "CUETools.ConsoleRipper 2.1.7", audioSource.ARName, true, false, CTDBMetadataSearch.Fast); arVerify.ContactAccurateRip(ArId); CTDBResponseMeta meta = null; foreach (var imeta in ctdb.Metadata) { meta = imeta; break; } //string destFile = (release == null) ? "cdimage.flac" : release.GetArtist() + " - " + release.GetTitle() + ".flac"; string destFile = (meta == null) ? "cdimage.wav" : meta.artist + " - " + meta.album + ".wav"; Console.WriteLine("Drive : {0}", audioSource.Path); Console.WriteLine("Read offset : {0}", audioSource.DriveOffset); Console.WriteLine("Read cmd : {0}", audioSource.CurrentReadCommand); Console.WriteLine("Secure mode : {0}", audioSource.CorrectionQuality); Console.WriteLine("Filename : {0}", destFile); Console.WriteLine("Disk length : {0}", CDImageLayout.TimeToString(audioSource.TOC.AudioLength)); Console.WriteLine("AccurateRip : {0}", arVerify.ARStatus == null ? "ok" : arVerify.ARStatus); Console.WriteLine("MusicBrainz : {0}", meta == null ? "not found" : meta.artist + " - " + meta.album); ProgressMeter meter = new ProgressMeter(); audioSource.ReadProgress += new EventHandler <ReadProgressArgs>(meter.ReadProgress); audioSource.DetectGaps(); StringWriter cueWriter = new StringWriter(); cueWriter.WriteLine("REM DISCID {0}", CDDBId); cueWriter.WriteLine("REM ACCURATERIPID {0}", ArId); cueWriter.WriteLine("REM COMMENT \"{0}\"", audioSource.RipperVersion); if (meta != null && meta.year != "") { cueWriter.WriteLine("REM DATE {0}", meta.year); } if (audioSource.TOC.Barcode != null) { cueWriter.WriteLine("CATALOG {0}", audioSource.TOC.Barcode); } if (meta != null) { cueWriter.WriteLine("PERFORMER \"{0}\"", meta.artist); cueWriter.WriteLine("TITLE \"{0}\"", meta.album); } cueWriter.WriteLine("FILE \"{0}\" WAVE", destFile); for (int track = 1; track <= audioSource.TOC.TrackCount; track++) { if (audioSource.TOC[track].IsAudio) { cueWriter.WriteLine(" TRACK {0:00} AUDIO", audioSource.TOC[track].Number); if (meta != null && meta.track.Length >= audioSource.TOC[track].Number) { cueWriter.WriteLine(" TITLE \"{0}\"", meta.track[(int)audioSource.TOC[track].Number - 1].name); cueWriter.WriteLine(" PERFORMER \"{0}\"", meta.track[(int)audioSource.TOC[track].Number - 1].artist); } if (audioSource.TOC[track].ISRC != null) { cueWriter.WriteLine(" ISRC {0}", audioSource.TOC[track].ISRC); } if (audioSource.TOC[track].DCP || audioSource.TOC[track].PreEmphasis) { cueWriter.WriteLine(" FLAGS{0}{1}", audioSource.TOC[track].PreEmphasis ? " PRE" : "", audioSource.TOC[track].DCP ? " DCP" : ""); } for (int index = audioSource.TOC[track].Pregap > 0 ? 0 : 1; index <= audioSource.TOC[track].LastIndex; index++) { cueWriter.WriteLine(" INDEX {0:00} {1}", index, audioSource.TOC[track][index].MSF); } } } cueWriter.Close(); StreamWriter cueFile = new StreamWriter(Path.ChangeExtension(destFile, ".cue")); cueFile.Write(cueWriter.ToString()); cueFile.Close(); //IAudioDest audioDest = new FLACWriter(destFile, audioSource.BitsPerSample, audioSource.ChannelCount, audioSource.SampleRate); IAudioDest audioDest = new Codecs.WAV.AudioEncoder(new Codecs.WAV.EncoderSettings(audioSource.PCM), destFile); audioDest.FinalSampleCount = audioSource.Length; while (audioSource.Read(buff, -1) != 0) { arVerify.Write(buff); audioDest.Write(buff); } TimeSpan totalElapsed = DateTime.Now - meter.realStart; Console.Write("\r \r"); Console.WriteLine("Results : {0:0.00}x; {1:d5} errors; {2:d2}:{3:d2}:{4:d2}", audioSource.Length / totalElapsed.TotalSeconds / audioSource.PCM.SampleRate, audioSource.FailedSectors.PopulationCount(), totalElapsed.Hours, totalElapsed.Minutes, totalElapsed.Seconds ); audioDest.Close(); StringWriter logWriter = new StringWriter(); logWriter.WriteLine("{0}", audioSource.RipperVersion); logWriter.WriteLine("Extraction logfile from {0}", DateTime.Now); logWriter.WriteLine("Used drive : {0}", audioSource.Path); logWriter.WriteLine("Read offset correction : {0}", audioSource.DriveOffset); bool wereErrors = false; for (int iTrack = 1; iTrack <= audioSource.TOC.AudioTracks; iTrack++) { for (uint iSector = audioSource.TOC[iTrack].Start; iSector <= audioSource.TOC[iTrack].End; iSector++) { if (audioSource.FailedSectors[(int)iSector]) { if (!wereErrors) { logWriter.WriteLine(); logWriter.WriteLine("Errors detected"); logWriter.WriteLine(); } wereErrors = true; logWriter.WriteLine("Track {0} contains errors", iTrack); break; } } } logWriter.WriteLine(); logWriter.WriteLine("TOC of the extracted CD"); logWriter.WriteLine(); logWriter.WriteLine(" Track | Start | Length | Start sector | End sector"); logWriter.WriteLine(" ---------------------------------------------------------"); for (int track = 1; track <= audioSource.TOC.TrackCount; track++) { logWriter.WriteLine("{0,9} | {1,8} | {2,8} | {3,9} | {4,9}", audioSource.TOC[track].Number, audioSource.TOC[track].StartMSF, audioSource.TOC[track].LengthMSF, audioSource.TOC[track].Start, audioSource.TOC[track].End); } logWriter.WriteLine(); logWriter.WriteLine("AccurateRip summary"); logWriter.WriteLine(); arVerify.GenerateFullLog(logWriter, true, ArId); logWriter.WriteLine(); logWriter.WriteLine("End of status report"); logWriter.Close(); StreamWriter logFile = new StreamWriter(Path.ChangeExtension(destFile, ".log")); logFile.Write(logWriter.ToString()); logFile.Close(); audioSource.Close(); //FLACReader tagger = new FLACReader(destFile, null); //tagger.Tags.Add("CUESHEET", cueWriter.ToString()); //tagger.Tags.Add("LOG", logWriter.ToString()); //tagger.UpdateTags(false); } #if !DEBUG catch (Exception ex) { Console.WriteLine(); Console.WriteLine("Error: {0}", ex.Message); Console.WriteLine("{0}", ex.StackTrace); } #endif }
static void Main(string[] args) { TextWriter stdout = Console.Out; Console.SetOut(Console.Error); Console.WriteLine("CUETools.ChaptersToCue v2.1.7 Copyright (C) 2017 Grigory Chudov"); Console.WriteLine("This is free software under the GNU GPLv3+ license; There is NO WARRANTY, to"); Console.WriteLine("the extent permitted by law. <http://www.gnu.org/licenses/> for details."); bool queryMeta = false; bool celltimes = false; int fps_mul = 0; int fps_div = 1; string inputPath = "-"; string outputPath = null; string tracksPath = null; string imagePath = null; for (int arg = 0; arg < args.Length; arg++) { bool ok = true; if ((args[arg] == "-i" || args[arg] == "--input") && ++arg < args.Length) { inputPath = args[arg]; } else if ((args[arg] == "-o" || args[arg] == "--output") && ++arg < args.Length) { outputPath = args[arg]; } else if ((args[arg] == "-t" || args[arg] == "--tracks") && ++arg < args.Length) { tracksPath = args[arg]; } else if (args[arg] == "--image" && ++arg < args.Length) { imagePath = args[arg]; } else if (args[arg] == "-m" || args[arg] == "--meta") { queryMeta = true; } else if (args[arg] == "--celltimes" && ++arg < args.Length) { celltimes = true; ok = int.TryParse(args[arg], out fps_mul); if (ok && fps_mul == 30) { fps_mul = 30000; fps_div = 1001; } } else { ok = false; } if (!ok) { Usage(); return; } } string strtoc = ""; string extension = null; if (tracksPath != null) { //CUEToolsCodecsConfig config = new CUEConfig(); //TagLib.UserDefined.AdditionalFileTypes.Config = config; TimeSpan pos = new TimeSpan(0); using (TextReader sr = tracksPath == "-" ? Console.In : new StreamReader(tracksPath)) { while (sr.Peek() >= 0) { string line = sr.ReadLine(); extension = Path.GetExtension(line); TagLib.File sourceInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(line)); strtoc += string.Format(" {0}", (int)(pos.TotalSeconds * 75)); pos += sourceInfo.Properties.Duration; } } strtoc += string.Format(" {0}", (int)(pos.TotalSeconds * 75)); } else { using (TextReader sr = inputPath == "-" ? Console.In : new StreamReader(inputPath)) { if (celltimes) { strtoc += string.Format(" {0}", 0); while (sr.Peek() >= 0) { string line = sr.ReadLine(); strtoc += string.Format(" {0}", long.Parse(line) * 75 * fps_div / fps_mul); } } else { while (sr.Peek() >= 0) { string line = sr.ReadLine(); Regex r = new Regex(@"^CHAPTER(?<number>\d\d)(?<option>[^=]*)=((?<hour>\d+):(?<minute>\d+):(?<second>\d+)\.(?<millisecond>\d+)|(?<text>))"); Match m = r.Match(line); if (!m.Success) { Console.Error.WriteLine("Invalid input format: {0}", line); return; } var option = m.Result("${option}"); if (option != "") { continue; } var chapter = int.Parse(m.Result("${number}")); var hour = int.Parse(m.Result("${hour}")); var minute = int.Parse(m.Result("${minute}")); var second = int.Parse(m.Result("${second}")); var millisecond = int.Parse(m.Result("${millisecond}")); strtoc += string.Format(" {0}", ((hour * 60 + minute) * 60 + second) * 75 + millisecond * 75 / 1000); } if (imagePath != null) { TagLib.File sourceInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(imagePath)); strtoc += string.Format(" {0}", (int)(sourceInfo.Properties.Duration.TotalSeconds * 75)); } else { strtoc += string.Format(" {0}", (int)(75 * 60 * 60 * 2)); //strtoc += string.Format(" {0}", (int)(75 * 259570688.0 / 96000)); } } } } strtoc = strtoc.Substring(1); CDImageLayout toc = new CDImageLayout(strtoc); CTDBResponseMeta meta = null; if (queryMeta) { var ctdb = new CUEToolsDB(toc, null); ctdb.ContactDB(null, "CUETools.ChaptersToCue 2.1.7", "", false, true, CTDBMetadataSearch.Extensive); foreach (var imeta in ctdb.Metadata) { meta = imeta; break; } } if (outputPath == null) { if (meta != null) { outputPath = string.Format("{0} - {1} - {2}.cue", meta.artist ?? "Unknown Artist", meta.year ?? "XXXX", meta.album ?? "Unknown Album"); } else { outputPath = "unknown.cue"; } } StringWriter cueWriter = new StringWriter(); cueWriter.WriteLine("REM COMMENT \"{0}\"", "Created by ChaptersToCue"); if (meta != null && meta.year != null) { cueWriter.WriteLine("REM DATE {0}", meta.year); } else { cueWriter.WriteLine("REM DATE XXXX"); } if (meta != null) { 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(outputPath) + (extension ?? ".wav")); } else { cueWriter.WriteLine("FILE \"{0}\" WAVE", ""); } for (int track = 1; track <= toc.TrackCount; track++) { if (toc[track].IsAudio) { cueWriter.WriteLine(" TRACK {0:00} AUDIO", toc[track].Number); if (meta != null && meta.track.Length >= toc[track].Number) { 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); } } 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); } } } cueWriter.Close(); if (outputPath == "-") { stdout.Write(cueWriter.ToString()); } else { try { using (var ofs = new FileStream(outputPath, FileMode.CreateNew, FileAccess.Write)) using (var cueFile = new StreamWriter(ofs)) { cueFile.Write(cueWriter.ToString()); cueFile.Close(); } } catch (System.IO.IOException ex) { Console.Error.WriteLine("{0}", ex.Message); } } }
public CUEMetadataEntry(CUEMetadata metadata, CDImageLayout TOC, string key) { this.metadata = new CUEMetadata(metadata); this.TOC = TOC; this.ImageKey = key; }
public bool GetCDInformation(CCDMetadata data, bool cdinfo, bool cover, bool lyrics) { var TOC = new CDImageLayout(); for (int i = 0; i < data.NumberOfTracks; i++) { uint start = data.GetTrackStartPosition(i); uint next = data.GetTrackEndPosition(i); TOC.AddTrack(new CDTrack( (uint)i + 1, start, next - start, !data.GetTrackDataTrack(i), data.GetTrackPreemphasis(i))); } TOC[1][0].Start = 0U; var form = new Form1(); form.ShowDialog(); var meta = form.Meta; int year, disccount, discnumber; string extra = meta.extra ?? ""; if (!string.IsNullOrEmpty(meta.discname)) { extra += "Disc name: " + meta.discname + "\r\n"; } if (!string.IsNullOrEmpty(meta.infourl)) { extra += "Info URL: " + meta.infourl + "\r\n"; } if (!string.IsNullOrEmpty(meta.barcode)) { extra += "Barcode: " + meta.barcode + "\r\n"; } if (meta.release != null) { foreach (var release in meta.release) { if (!string.IsNullOrEmpty(release.date)) { extra += "Release date: " + release.date + "\r\n"; } if (!string.IsNullOrEmpty(release.country)) { extra += "Release country: " + release.country + "\r\n"; } } } if (meta.label != null) { foreach (var label in meta.label) { if (!string.IsNullOrEmpty(label.name)) { extra += "Release label: " + label.name + "\r\n"; } if (!string.IsNullOrEmpty(label.catno)) { extra += "Release catalog#: " + label.catno + "\r\n"; } } } if (meta.track != null) { int firstAudio = meta.track.Length == TOC.AudioTracks ? TOC.FirstAudio - 1 : 0; for (int track = 0; track < data.NumberOfTracks; track++) { if (track - firstAudio >= 0 && track - firstAudio < meta.track.Length) { SetCDInfo(data, track - firstAudio, meta.track); } else if (!TOC[track + 1].IsAudio) { data.SetTrackTitle(track, "[data track]"); if (!string.IsNullOrEmpty(meta.artist)) { data.SetTrackArtist(track, meta.artist); } data.SetExtendedTrackInformation(track, ""); } else { SetCDInfo(data, track, meta.track); } /*if (!string.IsNullOrEmpty(meta.artist)) * data.SetTrackComposer(track, meta.artist);*/ } } data.Year = meta.year != null && int.TryParse(meta.year, out year) ? year : -1; data.TotalNumberOfCDs = meta.disccount != null && int.TryParse(meta.disccount, out disccount) ? disccount : 1; data.CDNumber = meta.discnumber != null && int.TryParse(meta.discnumber, out discnumber) ? discnumber : 1; data.FirstTrackNumber = 1; data.AlbumTitle = meta.album ?? ""; data.AlbumArtist = meta.artist ?? ""; if (!string.IsNullOrEmpty(extra)) { data.ExtendedDiscInformation = extra; } data.Revision = -1; if (cover) { data.CoverImage = null; data.CoverImageURL = ""; if (form.Image != null) { data.CoverImage = form.Image.Data; } } return(true); }
public static CDRepairEncode VerifyNoise(string trackoffsets, int seed, int offset, int errors, bool do_verify, bool do_encode) { var toc = new CDImageLayout(trackoffsets); return(VerifyNoise(toc, seed, offset, 0, (int)toc.AudioLength * 588, errors, do_verify, do_encode)); }
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; var decoderOptions = new Dictionary <string, string>(); bool queryMeta = false; 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); } else if ((args[arg] == "-m" || args[arg] == "--mode") && arg + 1 < args.Length) { encoderMode = args[++arg]; } else if (args[arg] == "--lossy") { audioEncoderType = AudioEncoderType.Lossy; } else if (args[arg] == "--lossless") { audioEncoderType = AudioEncoderType.Lossless; } else if (args[arg] == "--ctdb") { queryMeta = true; } else if (args[arg] == "--decoder-option" && arg + 2 < args.Length) { var optionName = args[++arg]; var optionValue = args[++arg]; decoderOptions.Add(optionName, optionValue); } else if ((args[arg][0] != '-' || args[arg] == "-") && sourceFile == null) { sourceFile = args[arg]; } else if ((args[arg][0] != '-' || args[arg] == "-") && sourceFile != null && destFile == null) { destFile = args[arg]; var x = destFile.Split(':'); if (x.Length > 1) { stream = int.Parse(x[0]); if (x[1] != "") { destFile = x[1]; } else { arg++; if (arg >= args.Length) { ok = false; break; } destFile = args[arg]; } } } else { ok = false; } if (!ok) { break; } } if (!ok || sourceFile == null) { Usage(); return(22); } if (destFile != null && destFile != "-" && destFile != "nul" && File.Exists(destFile)) { Console.Error.WriteLine("Error: file {0} already exists.", destFile); return(17); } DateTime start = DateTime.Now; TimeSpan lastPrint = TimeSpan.FromMilliseconds(0); var config = new CUEConfigAdvanced(); config.Init(); #if !DEBUG try #endif { IAudioSource audioSource = null; IAudioTitleSet audioContainer = null; IAudioDest audioDest = null; var videos = new List <Codecs.MPEG.MPLS.MPLSStream>(); List <IAudioTitle> audios = null; List <TimeSpan> chapters = null; TagLib.UserDefined.AdditionalFileTypes.Config = config; #if !DEBUG try #endif { if (true) { 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); audioContainer = audioSource as IAudioTitleSet; if (audioContainer == null) { audioContainer = new SingleAudioTitleSet(audioSource); } Console.ForegroundColor = ConsoleColor.White; int frameRate = 0; bool interlaced = false; audios = audioContainer.AudioTitles; audios.ForEach(t => chapters = t.Chapters); 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); } })); } videos.ForEach(v => { frameRate = v.FrameRate; interlaced = v.Interlaced; }); Console.Error.Write($@"M2TS, { videos.Count} video track{(videos.Count != 1 ? "s" : "")}, { audios.Count} audio track{(audios.Count != 1 ? "s" : "")}, { CDImageLayout.TimeToString(audios[0].GetDuration(), "{0:0}:{1:00}:{2:00}")}, { (frameRate * (interlaced ? 2 : 1))}{ (interlaced ? "i" : "p")}"); Console.Error.WriteLine(); //foreach (var item in mpls.MPLSHeader.play_item) //Console.Error.WriteLine("{0}.m2ts", item.clip_id); { Console.ForegroundColor = ConsoleColor.Gray; 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; Console.Error.WriteLine("{0}, {1}, {2}, {3}", audio.Codec, audio.Language, audio.GetFormatString(), audio.GetRateString()); } } } if (destFile == null) { return(0); } string strtoc = ""; for (int i = 0; i < chapters.Count; i++) { strtoc += string.Format(" {0}", (int)Math.Round((chapters[i].TotalSeconds * 75))); } strtoc = strtoc.Substring(1); CDImageLayout toc = new CDImageLayout(strtoc); CTDBResponseMeta meta = null; if (queryMeta) { var ctdb = new CUEToolsDB(toc, null); Console.Error.WriteLine("Contacting CTDB..."); ctdb.ContactDB(null, "CUETools.eac3to 2.1.8", "", false, true, CTDBMetadataSearch.Extensive); foreach (var imeta in ctdb.Metadata) { meta = imeta; break; } } if (stream > 0) { int chapterStreams = chapters.Count > 1 ? 1 : 0; if (stream <= chapterStreams) { if (destFile == "-" || destFile == "nul") { encoderFormat = "txt"; } else { string extension = Path.GetExtension(destFile).ToLower(); if (!extension.StartsWith(".")) { encoderFormat = destFile; if (meta == null || meta.artist == null || meta.album == null) { destFile = string.Format("{0}.{1}", Path.GetFileNameWithoutExtension(sourceFile), destFile); } else { destFile = string.Format("{0} - {1} - {2}.{3}", meta.artist, meta.year, meta.album, destFile); } } else { encoderFormat = extension.Substring(1); } if (encoderFormat != "txt" && encoderFormat != "cue") { throw new Exception(string.Format("Unsupported chapters file format \"{0}\"", encoderFormat)); } } Console.Error.WriteLine("Creating file \"{0}\"...", destFile); if (encoderFormat == "txt") { using (TextWriter sw = destFile == "nul" ? (TextWriter) new StringWriter() : destFile == "-" ? Console.Out : (TextWriter) new StreamWriter(destFile)) { for (int i = 0; i < chapters.Count - 1; i++) { sw.WriteLine("CHAPTER{0:00}={1}", i + 1, 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); } else { sw.WriteLine("CHAPTER{0:00}NAME=", i + 1); } } } Console.BackgroundColor = ConsoleColor.DarkGreen; Console.Error.Write("Done."); Console.BackgroundColor = ConsoleColor.Black; Console.Error.WriteLine(); return(0); } if (encoderFormat == "cue") { using (StreamWriter cueWriter = new StreamWriter(destFile, false, Encoding.UTF8)) { 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) { 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) { cueWriter.WriteLine(" TRACK {0:00} AUDIO", toc[track].Number); if (meta != null && meta.track.Length >= toc[track].Number) { 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); } } 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); } } } } Console.BackgroundColor = ConsoleColor.DarkGreen; Console.Error.Write("Done."); Console.BackgroundColor = ConsoleColor.Black; Console.Error.WriteLine(); return(0); } throw new Exception("Unknown encoder format: " + destFile); } if (stream - chapterStreams <= videos.Count) { throw new Exception("Video extraction not supported."); } if (stream - chapterStreams - videos.Count > audios.Count) { throw new Exception(string.Format("The source file doesn't contain a track with the number {0}.", stream)); } int streamId = audios[stream - chapterStreams - videos.Count - 1].StreamId; if (audioSource is Codecs.MPEG.MPLS.AudioDecoder) { (audioSource.Settings as Codecs.MPEG.MPLS.DecoderSettings).StreamId = streamId; } } AudioBuffer buff = new AudioBuffer(audioSource, 0x10000); Console.Error.WriteLine("Filename : {0}", sourceFile); Console.Error.WriteLine("File Info : {0}kHz; {1} channel; {2} bit; {3}", audioSource.PCM.SampleRate, audioSource.PCM.ChannelCount, audioSource.PCM.BitsPerSample, audioSource.Duration); CUEToolsFormat fmt; if (encoderFormat == null) { if (destFile == "-" || destFile == "nul") { encoderFormat = "wav"; } else { string extension = Path.GetExtension(destFile).ToLower(); if (!extension.StartsWith(".")) { encoderFormat = destFile; if (meta == null || meta.artist == null || meta.album == null) { destFile = string.Format("{0} - {1}.{2}", Path.GetFileNameWithoutExtension(sourceFile), stream, destFile); } else { destFile = string.Format("{0} - {1} - {2}.{3}", meta.artist, meta.year, meta.album, destFile); } } else { encoderFormat = extension.Substring(1); } if (File.Exists(destFile)) { throw new Exception(string.Format("Error: file {0} already exists.", destFile)); } } } if (!config.formats.TryGetValue(encoderFormat, out fmt)) { throw new Exception("Unsupported encoder format: " + encoderFormat); } AudioEncoderSettingsViewModel encoder = audioEncoderType == AudioEncoderType.Lossless ? Program.GetEncoder(config, fmt, true, encoderName) : audioEncoderType == AudioEncoderType.Lossy ? Program.GetEncoder(config, fmt, false, encoderName) : Program.GetEncoder(config, fmt, true, encoderName) ?? Program.GetEncoder(config, fmt, false, encoderName); if (encoder == null) { var lst = new List <AudioEncoderSettingsViewModel>(config.encodersViewModel).FindAll( e => e.Extension == fmt.extension && (audioEncoderType == AudioEncoderType.NoAudio || audioEncoderType == (e.Lossless ? AudioEncoderType.Lossless : AudioEncoderType.Lossy))). ConvertAll(e => e.Name + (e.Lossless ? " (lossless)" : " (lossy)")); throw new Exception("Encoders available for format " + fmt.extension + ": " + (lst.Count == 0 ? "none" : string.Join(", ", lst.ToArray()))); } Console.Error.WriteLine("Output {0} : {1}", stream, destFile); var settings = encoder.Settings.Clone(); settings.PCM = audioSource.PCM; settings.Padding = padding; settings.EncoderMode = encoderMode ?? settings.EncoderMode; object o = null; try { o = destFile == "-" ? Activator.CreateInstance(settings.EncoderType, settings, "", Console.OpenStandardOutput()) : destFile == "nul" ? Activator.CreateInstance(settings.EncoderType, settings, "", new NullStream()) : Activator.CreateInstance(settings.EncoderType, settings, destFile, null); } catch (System.Reflection.TargetInvocationException ex) { throw ex.InnerException; } if (o == null || !(o is IAudioDest)) { throw new Exception("Unsupported audio type: " + destFile + ": " + settings.EncoderType.FullName); } audioDest = o as IAudioDest; audioDest.FinalSampleCount = audioSource.Length; bool keepRunning = true; Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { keepRunning = false; if (e.SpecialKey == ConsoleSpecialKey.ControlC) { e.Cancel = true; } else { audioDest.Delete(); } }; while (audioSource.Read(buff, -1) != 0) { audioDest.Write(buff); TimeSpan elapsed = DateTime.Now - start; if ((elapsed - lastPrint).TotalMilliseconds > 60) { 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); } Console.Error.Write("\rProgress : {0:00}%; {1:0.00}x; {2}/{3}", 100.0 * position.TotalSeconds / duration.TotalSeconds, position.TotalSeconds / elapsed.TotalSeconds, elapsed, TimeSpan.FromSeconds(elapsed.TotalSeconds / position.TotalSeconds * duration.TotalSeconds) ); 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 ); } #if !DEBUG catch (Exception ex) { if (audioSource != null) { audioSource.Close(); } if (audioDest != null) { audioDest.Delete(); } throw ex; } #endif audioSource.Close(); audioDest.Close(); if (sourceFile != "-" && destFile != "-" && destFile != "nul") { //TagLib.File destInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(destFile)); //NameValueCollection tags; //if (Tagging.UpdateTags(destInfo, tags, config, false)) //{ // destInfo.Save(); //} } } #if !DEBUG catch (Exception ex) { Console.Error.Write("\r \r"); Console.BackgroundColor = ConsoleColor.DarkRed; Console.Error.Write("Error : {0}", ex.Message); Console.BackgroundColor = ConsoleColor.Black; Console.Error.WriteLine(); return(1); //Console.WriteLine("{0}", ex.StackTrace); } #endif return(0); }
public bool GetCDInformation(CCDMetadata data, bool cdinfo, bool cover, bool lyrics) { if (Options.CoversSearch == CTDBCoversSearch.None) { cover = false; } if (!cdinfo && !cover) { return(false); } var TOC = new CDImageLayout(); for (int i = 0; i < data.NumberOfTracks; i++) { uint start = data.GetTrackStartPosition(i); uint next = data.GetTrackEndPosition(i); TOC.AddTrack(new CDTrack( (uint)i + 1, start, next - start, !data.GetTrackDataTrack(i), data.GetTrackPreemphasis(i))); } TOC[1][0].Start = 0U; var ctdb = new CUEToolsDB(TOC, null); var form = new CUETools.CTDB.EACPlugin.FormMetadata(ctdb, "EAC" + data.HostVersion + " CTDB 2.1.8", cdinfo, cover); form.ShowDialog(); var meta = form.Meta; if (meta == null) { return(false); } if (cdinfo) { int year, disccount, discnumber; string extra = meta.extra ?? ""; if (!string.IsNullOrEmpty(meta.discname)) { extra += "Disc name: " + meta.discname + "\r\n"; } if (!string.IsNullOrEmpty(meta.infourl)) { extra += "Info URL: " + meta.infourl + "\r\n"; } if (!string.IsNullOrEmpty(meta.barcode)) { extra += "Barcode: " + meta.barcode + "\r\n"; } if (meta.release != null) { foreach (var release in meta.release) { if (!string.IsNullOrEmpty(release.date)) { extra += "Release date: " + release.date + "\r\n"; } if (!string.IsNullOrEmpty(release.country)) { extra += "Release country: " + release.country + "\r\n"; } } } if (meta.label != null) { foreach (var label in meta.label) { if (!string.IsNullOrEmpty(label.name)) { extra += "Release label: " + label.name + "\r\n"; } if (!string.IsNullOrEmpty(label.catno)) { extra += "Release catalog#: " + label.catno + "\r\n"; } } } data.Year = meta.year != null && int.TryParse(meta.year, out year) ? year : -1; data.TotalNumberOfCDs = meta.disccount != null && int.TryParse(meta.disccount, out disccount) ? disccount : 1; data.CDNumber = meta.discnumber != null && int.TryParse(meta.discnumber, out discnumber) ? discnumber : 1; data.FirstTrackNumber = 1; data.AlbumTitle = meta.album ?? ""; data.AlbumArtist = meta.artist ?? ""; data.MP3V2Type = meta.genre ?? ""; data.CDDBMusicType = GetFreeDBMusicType(meta); data.MP3Type = GetMP3MusicType(data.CDDBMusicType); data.ExtendedDiscInformation = extra; data.Revision = -1; // TODO: meta.id? rock/ffffffff/16? if (meta.track != null) { int firstAudio = meta.track.Length == TOC.AudioTracks ? TOC.FirstAudio - 1 : 0; for (int track = 0; track < data.NumberOfTracks; track++) { if (track - firstAudio >= 0 && track - firstAudio < meta.track.Length) { data.SetTrackTitle(track, meta.track[track - firstAudio].name ?? ""); data.SetTrackArtist(track, meta.track[track - firstAudio].artist ?? meta.artist ?? ""); data.SetExtendedTrackInformation(track, meta.track[track - firstAudio].extra ?? ""); } else if (!TOC[track + 1].IsAudio) { data.SetTrackTitle(track, "[data track]"); data.SetTrackArtist(track, meta.artist ?? ""); data.SetExtendedTrackInformation(track, ""); } else { data.SetTrackTitle(track, ""); data.SetTrackArtist(track, meta.artist ?? ""); data.SetExtendedTrackInformation(track, ""); } data.SetTrackComposer(track, ""); } } } if (cover) { data.CoverImage = null; data.CoverImageURL = ""; if (form.Image != null) { data.CoverImage = form.Image.Data; data.CoverImageURL = form.Image.URL; } } return(true); }
public void GenerateLog(TextWriter sw, bool old) { if (this.DBStatus != null || this.Total == 0) { return; } if (old) { sw.WriteLine(" [ CTDBID ] Status"); foreach (DBEntry entry in this.Entries) { string confFormat = (this.Total < 10) ? "{0:0}/{1:0}" : (this.Total < 100) ? "{0:00}/{1:00}" : "{0:000}/{1:000}"; string conf = string.Format(confFormat, entry.conf, this.Total); string dataTrackInfo = !entry.toc[entry.toc.TrackCount].IsAudio && this.toc[this.toc.TrackCount].IsAudio ? string.Format("CD-Extra data track length {0}", entry.toc[entry.toc.TrackCount].LengthMSF) : !entry.toc[1].IsAudio && this.toc[1].IsAudio ? string.Format("Playstation type data track length {0}", entry.toc[entry.toc.FirstAudio].StartMSF) : (entry.toc[1].IsAudio && !this.toc[1].IsAudio) || (entry.toc[entry.toc.TrackCount].IsAudio && !this.toc[this.toc.TrackCount].IsAudio) ? "Has no data track" : ""; if (entry.toc.Pregap != this.toc.Pregap) { dataTrackInfo = dataTrackInfo + (dataTrackInfo == "" ? "" : ", ") + string.Format("Has pregap length {0}", CDImageLayout.TimeToString(entry.toc.Pregap)); } string status = entry.toc.AudioLength - entry.toc.Pregap != this.TOC.AudioLength - this.TOC.Pregap ? string.Format("Has audio length {0}", CDImageLayout.TimeToString(entry.toc.AudioLength)) : ((entry.toc.TrackOffsets != this.TOC.TrackOffsets) ? dataTrackInfo + ", " : "") + ((!entry.hasErrors) ? "Accurately ripped" : //((!entry.hasErrors) ? string.Format("Accurately ripped, offset {0}", -entry.offset) : entry.canRecover ? string.Format("Differs in {0} samples @{1}", entry.repair.CorrectableErrors, entry.repair.AffectedSectors) : (entry.httpStatus == 0 || entry.httpStatus == HttpStatusCode.OK) ? "No match" : entry.httpStatus.ToString()); sw.WriteLine(" [{0:x8}] ({1}) {2}", entry.crc, conf, status); } } const int _arOffsetRange = 5 * 588 - 1; sw.WriteLine("Track | CTDB Status"); string ifmt = this.Total < 10 ? "1" : this.Total < 100 ? "2" : "3"; for (int iTrack = 0; iTrack < this.TOC.AudioTracks; iTrack++) { int coalesce = 2 * 588 * 5; string line; do { int conf = 0; List <int> resConfidence = new List <int>(); List <string> resStatus = new List <string>(); foreach (DBEntry entry in this.Entries) { if (!entry.hasErrors) { conf += entry.conf; continue; } if (entry.canRecover) { var tri = this.TOC[this.TOC.FirstAudio + iTrack]; var tr0 = this.TOC[this.TOC.FirstAudio]; var min = (int)(tri.Start - tr0.Start) * 588; var max = (int)(tri.End + 1 - tr0.Start) * 588; var diffCount = entry.repair.GetAffectedSectorsCount(min, max); if (diffCount == 0) { conf += entry.conf; continue; } resConfidence.Add(entry.conf); if (coalesce >= 64 * 588 * 5) { resStatus.Add(string.Format("differs in {0} samples", diffCount)); } else { resStatus.Add(string.Format("differs in {0} samples @{1}", diffCount, entry.repair.GetAffectedSectors(min, max, min, coalesce))); } continue; } if (entry.trackcrcs != null) { if (this.verify.TrackCRC(iTrack + 1, -entry.offset) == entry.trackcrcs[iTrack]) { conf += entry.conf; continue; } for (int oi = -_arOffsetRange; oi <= _arOffsetRange; oi++) { if (this.verify.TrackCRC(iTrack + 1, oi) == entry.trackcrcs[iTrack]) { conf += entry.conf; break; } } } } if (conf > 0) { resConfidence.Insert(0, conf); resStatus.Insert(0, "accurately ripped"); } if (resStatus.Count == 0) { resConfidence.Add(0); resStatus.Add("no match"); } resStatus[0] = string.Format("({0," + ifmt + "}/{1}) {2}", resConfidence[0], this.Total, char.ToUpper(resStatus[0][0]) + resStatus[0].Substring(1)); for (int i = 1; i < resStatus.Count; i++) { resStatus[i] = string.Format("({0}/{1}) {2}", resConfidence[i], this.Total, resStatus[i]); } coalesce *= 2; line = string.Join(", or ", resStatus.ToArray()); }while (line.Length > 1024 && coalesce < 128 * 588 * 5); if (line.Length > 1024) { line = line.Substring(0, 1024) + "..."; } sw.WriteLine(string.Format(" {0,2} | {1}", iTrack + 1, line)); } }
public TestImageGenerator(CDImageLayout toc, int seed, int offset, int errors = 0, int maxStrideErrors = 0) : this(toc, seed, offset, errors, maxStrideErrors, 0, (int)toc.AudioLength * 588) { }
public static string GetRipperLog(CUESheet sheet) { StringWriter logWriter = new StringWriter(CultureInfo.InvariantCulture); logWriter.WriteLine("{0}", sheet.CDRipper.RipperVersion); logWriter.WriteLine("Extraction logfile from : {0}", DateTime.Now); logWriter.WriteLine("Used drive : {0}", sheet.CDRipper.ARName); logWriter.WriteLine("Read offset correction : {0}", sheet.CDRipper.DriveOffset); logWriter.WriteLine("Read command : {0}", sheet.CDRipper.CurrentReadCommand); logWriter.WriteLine("Secure mode : {0}", sheet.CDRipper.CorrectionQuality); logWriter.WriteLine("Disk length : {0}", CDImageLayout.TimeToString(sheet.TOC.AudioLength)); logWriter.WriteLine("AccurateRip : {0}", sheet.ArVerify.ARStatus == null ? "ok" : sheet.ArVerify.ARStatus); if (sheet.HDCDDecoder != null && string.Format("{0:s}", sheet.HDCDDecoder) != "") { logWriter.WriteLine("HDCD : {0:f}", sheet.HDCDDecoder); } logWriter.WriteLine(); logWriter.WriteLine("TOC of the extracted CD"); logWriter.WriteLine(); logWriter.Write(GetTOCContents(sheet)); logWriter.WriteLine(); logWriter.WriteLine(" Track | Pregap | Indexes"); logWriter.WriteLine(" ---------------------------------------------------------"); for (int track = 1; track <= sheet.TOC.TrackCount; track++) { logWriter.WriteLine("{0,9} | {1,8} | {2,2}", sheet.TOC[track].Number, CDImageLayout.TimeToString(sheet.TOC[track].Pregap + (track == 1 ? 150U : 0U)), sheet.TOC[track].LastIndex); } logWriter.WriteLine(); logWriter.WriteLine("Destination files"); foreach (string path in sheet.DestPaths) { logWriter.WriteLine(" {0}", path); } bool wereErrors = sheet.PrintErrors(logWriter, sheet.TOC[sheet.TOC.FirstAudio][0].Start, sheet.TOC.AudioLength); if (wereErrors) { logWriter.WriteLine(); if (wereErrors) { logWriter.WriteLine("There were errors"); } else { logWriter.WriteLine("No errors occurred"); } } if (sheet.IsUsingCUEToolsDB) { logWriter.WriteLine(); sheet.GenerateCTDBLog(logWriter); } if (sheet.IsUsingAccurateRip) { logWriter.WriteLine(); logWriter.WriteLine("AccurateRip summary"); logWriter.WriteLine(); sheet.ArVerify.GenerateFullLog(logWriter, true, AccurateRipVerify.CalculateAccurateRipId(sheet.TOC)); } logWriter.WriteLine(); logWriter.WriteLine("End of status report"); logWriter.Close(); return(logWriter.ToString()); }
public static string GetExactAudioCopyLog(CUESheet sheet) { StringWriter logWriter = new StringWriter(CultureInfo.InvariantCulture); string eacHeader = "{7}\r\n" + "\r\n" + "EAC extraction logfile from {0:d'.' MMMM yyyy', 'H':'mm}\r\n" + "\r\n" + "{1} / {2}\r\n" + "\r\n" + "Used drive : {3} Adapter: 1 ID: 0\r\n" + "\r\n" + "Read mode : {4}\r\n" + "Utilize accurate stream : Yes\r\n" + "Defeat audio cache : Yes\r\n" + "Make use of C2 pointers : No\r\n" + "\r\n" + "Read offset correction : {5}\r\n" + "Overread into Lead-In and Lead-Out : No\r\n" + "Fill up missing offset samples with silence : Yes\r\n" + "Delete leading and trailing silent blocks : No\r\n" + "Null samples used in CRC calculations : Yes\r\n" + "Used interface : Native Win32 interface for Win NT & 2000\r\n" + "{6}" + "\r\n" + "Used output format : Internal WAV Routines\r\n" + "Sample format : 44.100 Hz; 16 Bit; Stereo\r\n"; logWriter.WriteLine(eacHeader, DateTime.Now, sheet.Metadata.Artist, sheet.Metadata.Title, sheet.CDRipper.EACName, sheet.CDRipper.CorrectionQuality > 0 ? "Secure" : "Burst", sheet.CDRipper.DriveOffset, (sheet.OutputStyle == CUEStyle.SingleFile || sheet.OutputStyle == CUEStyle.SingleFileWithCUE) ? "" : "Gap handling : " + (sheet.CDRipper.GapsDetected ? "Appended to previous track\r\n" : "Not detected, thus appended to previous track\r\n"), sheet.CDRipper.RipperVersion); // "Exact Audio Copy V0.99 prebeta 4 from 23. January 2008" logWriter.WriteLine(); logWriter.WriteLine("TOC of the extracted CD"); logWriter.WriteLine(); logWriter.Write(GetTOCContents(sheet)); logWriter.WriteLine(); bool htoaToFile = ((sheet.OutputStyle == CUEStyle.GapsAppended) && sheet.Config.preserveHTOA && (sheet.TOC.Pregap != 0)); int accurateTracks = 0, knownTracks = 0; bool wereErrors = false; if (sheet.OutputStyle != CUEStyle.SingleFile && sheet.OutputStyle != CUEStyle.SingleFileWithCUE) { logWriter.WriteLine(); for (int track = 0; track < sheet.TOC.AudioTracks; track++) { logWriter.WriteLine("Track {0,2}", track + 1); logWriter.WriteLine(); logWriter.WriteLine(" Filename {0}", Path.ChangeExtension(Path.GetFullPath(sheet.DestPaths[track + (htoaToFile ? 1 : 0)]), ".wav")); if (sheet.TOC[track + sheet.TOC.FirstAudio].Pregap > 0 || track + sheet.TOC.FirstAudio == 1) { logWriter.WriteLine(); logWriter.WriteLine(" Pre-gap length 0:{0}.{1:00}", CDImageLayout.TimeToString("{0:00}:{1:00}", sheet.TOC[track + sheet.TOC.FirstAudio].Pregap + (track + sheet.TOC.FirstAudio == 1 ? 150U : 0U)), (sheet.TOC[track + sheet.TOC.FirstAudio].Pregap % 75) * 100 / 75); } wereErrors |= sheet.PrintErrors(logWriter, sheet.TOC[track + sheet.TOC.FirstAudio].Start, sheet.TOC[track + sheet.TOC.FirstAudio].Length); logWriter.WriteLine(); logWriter.WriteLine(" Peak level {0:F1} %", (sheet.ArVerify.PeakLevel(track + 1) * 1000 / 65534) * 0.1); logWriter.WriteLine(" Track quality {0:F1} %", GetRangeQuality(sheet, sheet.TOC[track + sheet.TOC.FirstAudio].Start, sheet.TOC[track + sheet.TOC.FirstAudio].Length)); if (sheet.ArTestVerify != null) { logWriter.WriteLine(" Test CRC {0:X8}", sheet.ArTestVerify.CRC32(track + 1)); } logWriter.WriteLine(" Copy CRC {0:X8}", sheet.ArVerify.CRC32(track + 1)); if (sheet.ArVerify.Total(track) == 0) { logWriter.WriteLine(" Track not present in AccurateRip database"); } else { knownTracks++; if (sheet.ArVerify.Confidence(track) == 0) { logWriter.WriteLine(" Cannot be verified as accurate (confidence {0}) [{1:X8}], AccurateRip returned [{2:X8}]", sheet.ArVerify.Total(track), sheet.ArVerify.CRC(track), sheet.ArVerify.DBCRC(track)); } else { logWriter.WriteLine(" Accurately ripped (confidence {0}) [{1:X8}]", sheet.ArVerify.Confidence(track), sheet.ArVerify.CRC(track)); accurateTracks++; } } logWriter.WriteLine(" Copy OK"); logWriter.WriteLine(); } } else { logWriter.WriteLine(); logWriter.WriteLine("Range status and errors"); logWriter.WriteLine(); logWriter.WriteLine("Selected range"); logWriter.WriteLine(); logWriter.WriteLine(" Filename {0}", Path.ChangeExtension(Path.GetFullPath(sheet.DestPaths[0]), ".wav")); wereErrors = sheet.PrintErrors(logWriter, sheet.TOC[sheet.TOC.FirstAudio][0].Start, sheet.TOC.AudioLength); logWriter.WriteLine(); logWriter.WriteLine(" Peak level {0:F1} %", (sheet.ArVerify.PeakLevel() * 1000 / 65535) * 0.1); logWriter.WriteLine(" Range quality {0:F1} %", GetRangeQuality(sheet, sheet.TOC[sheet.TOC.FirstAudio][0].Start, sheet.TOC.AudioLength)); if (sheet.ArTestVerify != null) { logWriter.WriteLine(" Test CRC {0:X8}", sheet.ArTestVerify.CRC32(0)); } logWriter.WriteLine(" Copy CRC {0:X8}", sheet.ArVerify.CRC32(0)); logWriter.WriteLine(" Copy OK"); logWriter.WriteLine(); if (wereErrors) { logWriter.WriteLine("There were errors"); } else { logWriter.WriteLine("No errors occurred"); } logWriter.WriteLine(); logWriter.WriteLine(); logWriter.WriteLine("AccurateRip summary"); logWriter.WriteLine(); for (int track = 0; track < sheet.TOC.AudioTracks; track++) { if (sheet.ArVerify.Total(track) == 0) { logWriter.WriteLine("Track {0,2} not present in database", track + 1); } else { knownTracks++; if (sheet.ArVerify.Confidence(track) == 0) { logWriter.WriteLine("Track {3,2} cannot be verified as accurate (confidence {0}) [{1:X8}], AccurateRip returned [{2:X8}]", sheet.ArVerify.Total(track), sheet.ArVerify.CRC(track), sheet.ArVerify.DBCRC(track), track + 1); } else { logWriter.WriteLine("Track {2,2} accurately ripped (confidence {0}) [{1:X8}]", sheet.ArVerify.Confidence(track), sheet.ArVerify.CRC(track), track + 1); accurateTracks++; } } } } logWriter.WriteLine(); if (knownTracks == 0) { logWriter.WriteLine("None of the tracks are present in the AccurateRip database"); } else if (accurateTracks == 0) { logWriter.WriteLine("No tracks could be verified as accurate"); logWriter.WriteLine("You may have a different pressing from the one(s) in the database"); } else if (accurateTracks == sheet.TrackCount) { logWriter.WriteLine("All tracks accurately ripped"); } else { logWriter.WriteLine("{0,2} track(s) accurately ripped", accurateTracks); if (sheet.TrackCount - knownTracks > 0) { logWriter.WriteLine("{0,2} track(s) not present in the AccurateRip database", sheet.TrackCount - knownTracks); } logWriter.WriteLine(); logWriter.WriteLine("Some tracks could not be verified as accurate"); } logWriter.WriteLine(); if (sheet.OutputStyle != CUEStyle.SingleFile && sheet.OutputStyle != CUEStyle.SingleFileWithCUE) { if (wereErrors) { logWriter.WriteLine("There were errors"); } else { logWriter.WriteLine("No errors occurred"); } logWriter.WriteLine(); } logWriter.WriteLine("End of status report"); logWriter.Close(); return(logWriter.ToString()); }
public static void WriteAccurateRipLog(CUESheet sheet, TextWriter writer) { writer.WriteLine("[CUETools log; Date: {0}; Version: {1}]", DateTime.Now, CUESheet.CUEToolsVersion); if (sheet.PreGapLength != 0) { writer.WriteLine("Pregap length {0}.", sheet.PreGapLengthMSF); } if (!sheet.TOC[1].IsAudio) { writer.WriteLine("Playstation type data track length {0}.", sheet.TOC[sheet.TOC.FirstAudio].StartMSF); } if (!sheet.TOC[sheet.TOC.TrackCount].IsAudio) { writer.WriteLine("CD-Extra data track length {0}.", sheet.TOC[sheet.TOC.TrackCount].Length == 0 && sheet.MinDataTrackLength.HasValue ? CDImageLayout.TimeToString(sheet.MinDataTrackLength.Value) + " - " + CDImageLayout.TimeToString(sheet.MinDataTrackLength.Value + 74) : sheet.TOC[sheet.TOC.TrackCount].LengthMSF); } if (sheet.CDDBDiscIdTag != null && AccurateRipVerify.CalculateCDDBId(sheet.TOC).ToUpper() != sheet.CDDBDiscIdTag.ToUpper() && !sheet.MinDataTrackLength.HasValue) { writer.WriteLine("CDDBId mismatch: {0} vs {1}", sheet.CDDBDiscIdTag.ToUpper(), AccurateRipVerify.CalculateCDDBId(sheet.TOC).ToUpper()); } if (sheet.AccurateRipId != null && AccurateRipVerify.CalculateAccurateRipId(sheet.TOC) != sheet.AccurateRipId) { writer.WriteLine("Using preserved id, actual id is {0}.", AccurateRipVerify.CalculateAccurateRipId(sheet.TOC)); } if (sheet.Truncated4608) { writer.WriteLine("Truncated 4608 extra samples in some input files."); } if (sheet.PaddedToFrame) { writer.WriteLine("Padded some input files to a frame boundary."); } if (!sheet.Processed) { if (sheet.IsUsingCUEToolsDB) { sheet.GenerateCTDBLog(writer); } if (sheet.IsUsingAccurateRip) { writer.WriteLine("[AccurateRip ID: {0}] {1}.", sheet.AccurateRipId ?? AccurateRipVerify.CalculateAccurateRipId(sheet.TOC), sheet.ArVerify.ARStatus ?? "found"); } return; } if (sheet.HDCDDecoder != null && string.Format("{0:s}", sheet.HDCDDecoder) != "") { writer.WriteLine("HDCD: {0:f}", sheet.HDCDDecoder); } if (0 != sheet.WriteOffset) { writer.WriteLine("Offset applied: {0}", sheet.WriteOffset); } if (sheet.IsUsingCUEToolsDBFix)// && _CUEToolsDB.SelectedEntry != null) { writer.WriteLine("CUETools DB: corrected {0} errors.", sheet.CTDB.SelectedEntry.repair.CorrectableErrors); } else if (sheet.IsUsingCUEToolsDB) { sheet.GenerateCTDBLog(writer); } sheet.ArVerify.GenerateFullLog(writer, sheet.Config.arLogVerbose, sheet.AccurateRipId ?? AccurateRipVerify.CalculateAccurateRipId(sheet.TOC)); }
public static CDImageLayout LogToToc(CDImageLayout toc, string eacLog) { CDImageLayout tocFromLog = new CDImageLayout(); using (StringReader sr = new StringReader(eacLog)) { bool isEACLog = false; bool iscdda2wavlog = false; string lineStr; int prevTrNo = 1, prevTrStart = 0; uint firstPreGap = 0; while ((lineStr = sr.ReadLine()) != null) { if (isEACLog) { string[] n = lineStr.Split('|'); uint trNo, trStart, trEnd; if (n.Length == 5 && uint.TryParse(n[0], out trNo) && uint.TryParse(n[3], out trStart) && uint.TryParse(n[4], out trEnd) && trNo == tocFromLog.TrackCount + 1) { bool isAudio = true; if (tocFromLog.TrackCount >= toc.TrackCount && trStart == tocFromLog[tocFromLog.TrackCount].End + 1U + 152U * 75U ) { isAudio = false; } if (tocFromLog.TrackCount < toc.TrackCount && !toc[tocFromLog.TrackCount + 1].IsAudio ) { isAudio = false; } tocFromLog.AddTrack(new CDTrack(trNo, trStart, trEnd + 1 - trStart, isAudio, false)); } else { string[] sepTrack = { "Track" }; string[] sepGap = { "Pre-gap length" }; string[] partsTrack = lineStr.Split(sepTrack, StringSplitOptions.None); if (partsTrack.Length == 2 && uint.TryParse(partsTrack[1], out trNo)) { prevTrNo = (int)trNo; continue; } string[] partsGap = lineStr.Split(sepGap, StringSplitOptions.None); if (partsGap.Length == 2) { string[] n1 = partsGap[1].Split(':', '.'); int h, m, s, f; if (n1.Length == 4 && int.TryParse(n1[0], out h) && int.TryParse(n1[1], out m) && int.TryParse(n1[2], out s) && int.TryParse(n1[3], out f)) { uint gap = (uint)((f * 3 + 2) / 4 + 75 * (s + 60 * (m + 60 * h))); if (prevTrNo == 1) { gap -= 150; } if (prevTrNo == 1) { firstPreGap = gap - toc[1].Start; } //else //firstPreGap += gap; while (prevTrNo > tocFromLog.TrackCount && toc.TrackCount > tocFromLog.TrackCount) { tocFromLog.AddTrack(new CDTrack((uint)tocFromLog.TrackCount + 1, toc[tocFromLog.TrackCount + 1].Start + firstPreGap, toc[tocFromLog.TrackCount + 1].Length, toc[tocFromLog.TrackCount + 1].IsAudio, false)); } if (prevTrNo <= tocFromLog.TrackCount) { tocFromLog[prevTrNo].Pregap = gap; } } } } } else if (iscdda2wavlog) { foreach (string entry in lineStr.Split(',')) { string[] n = entry.Split('('); if (n.Length < 2) { continue; } // assert n.Length == 2; string key = n[0].Trim(' ', '.'); int trStart = int.Parse(n[1].Trim(' ', ')')); bool isAudio = true; // !!! if (key != "1") { tocFromLog.AddTrack(new CDTrack((uint)prevTrNo, (uint)prevTrStart, (uint)(trStart - prevTrStart), isAudio, false)); } if (key == "lead-out") { iscdda2wavlog = false; break; } prevTrNo = int.Parse(key); prevTrStart = trStart; } } else if (lineStr.StartsWith("TOC of the extracted CD") || lineStr.StartsWith("Exact Audio Copy") || lineStr.StartsWith("EAC extraction logfile") || lineStr.StartsWith("CUERipper") || lineStr.StartsWith(" Track | Start | Length | Start sector | End sector") ) { isEACLog = true; } else if (lineStr.StartsWith("Table of Contents: starting sectors")) { iscdda2wavlog = true; } } } if (tocFromLog.TrackCount == 0) { return(null); } tocFromLog[1][0].Start = 0; return(tocFromLog); }
public bool Equals(CDImageLayout layout, List <string> fullAudioPaths) { return(EqualLayouts(layout) && EqualAudioPaths(fullAudioPaths)); }