public List<object> LookupAlbumInfo(bool useCache, bool useCUE, bool useCTDB, CTDBMetadataSearch metadataSearch) { List<object> Releases = new List<object>(); CUEMetadata dbmeta = null; if (useCache && _localDB != null) { List<string> fullAudioPaths = this.SourcePaths.ConvertAll(p => CUEToolsLocalDBEntry.NormalizePath(p)); var myEntry = _localDB.Find(e => e.Equals(this.TOC, fullAudioPaths)); if (myEntry != null) dbmeta = myEntry.Metadata; } if (dbmeta != null) Releases.Add(new CUEMetadataEntry(dbmeta, TOC, "local")); //if (useCache) //{ // try // { // CUEMetadata cache = CUEMetadata.Load(TOC.TOCID); // if (cache != null) // Releases.Add(new CUEMetadataEntry(cache, TOC, "local")); // } // catch (Exception ex) // { // System.Diagnostics.Trace.WriteLine(ex.Message); // } //} if (useCUE) { if (dbmeta == null || !dbmeta.Contains(cueMetadata)) { if (cueMetadata.Contains(taglibMetadata) || !taglibMetadata.Contains(cueMetadata)) Releases.Add(new CUEMetadataEntry(new CUEMetadata(cueMetadata), TOC, "cue")); } if (dbmeta == null || !dbmeta.Contains(taglibMetadata)) { if (!cueMetadata.Contains(taglibMetadata)) Releases.Add(new CUEMetadataEntry(new CUEMetadata(taglibMetadata), TOC, "tags")); } } if (useCache && _localDB != null) { foreach (var entry in _localDB) if (entry.DiscID == TOC.TOCID && entry.Metadata != null && (dbmeta == null || !dbmeta.Contains(entry.Metadata))) Releases.Add(new CUEMetadataEntry(entry.Metadata, TOC, "local")); } bool ctdbFound = false; if (useCTDB) { ShowProgress("Looking up album via CTDB...", 0.0, null, null); var ctdb = new CUEToolsDB(TOC, proxy); ctdb.ContactDB(_config.advanced.CTDBServer, "CUETools " + CUEToolsVersion, null, false, false, metadataSearch); foreach (var meta in ctdb.Metadata) { CUEMetadata metadata = new CUEMetadata(TOC.TOCID, (int)TOC.AudioTracks); metadata.FillFromCtdb(meta, TOC.FirstAudio - 1); CDImageLayout toc = TOC; // TocFromCDEntry(meta); Releases.Add(new CUEMetadataEntry(metadata, toc, meta.source)); ctdbFound = true; } } if (!ctdbFound && metadataSearch == CTDBMetadataSearch.Extensive) { ShowProgress("Looking up album via Freedb...", 0.0, null, null); FreedbHelper m_freedb = new FreedbHelper(); m_freedb.Proxy = proxy; m_freedb.UserName = _config.advanced.FreedbUser; m_freedb.Hostname = _config.advanced.FreedbDomain; m_freedb.ClientName = "CUETools"; m_freedb.Version = CUEToolsVersion; m_freedb.SetDefaultSiteAddress("freedb.org"); QueryResult queryResult; QueryResultCollection coll; string code = string.Empty; try { CDEntry cdEntry = null; code = m_freedb.Query(AccurateRipVerify.CalculateCDDBQuery(_toc), out queryResult, out coll); if (code == FreedbHelper.ResponseCodes.CODE_200) { ShowProgress("Looking up album via Freedb... " + queryResult.Discid, 0.5, null, null); code = m_freedb.Read(queryResult, out cdEntry); if (code == FreedbHelper.ResponseCodes.CODE_210) { CUEMetadata metadata = new CUEMetadata(TOC.TOCID, (int)TOC.AudioTracks); metadata.FillFromFreedb(cdEntry, TOC.FirstAudio - 1); CDImageLayout toc = TocFromCDEntry(cdEntry); Releases.Add(new CUEMetadataEntry(metadata, toc, "freedb")); } } else if (code == FreedbHelper.ResponseCodes.CODE_210 || code == FreedbHelper.ResponseCodes.CODE_211) { int i = 0; foreach (QueryResult qr in coll) { ShowProgress("Looking up album via freedb... " + qr.Discid, (++i + 0.0) / coll.Count, null, null); CheckStop(); code = m_freedb.Read(qr, out cdEntry); if (code == FreedbHelper.ResponseCodes.CODE_210) { CUEMetadata metadata = new CUEMetadata(TOC.TOCID, (int)TOC.AudioTracks); metadata.FillFromFreedb(cdEntry, TOC.FirstAudio - 1); CDImageLayout toc = TocFromCDEntry(cdEntry); Releases.Add(new CUEMetadataEntry(metadata, toc, "freedb")); } } } } catch (Exception ex) { if (ex is StopException) throw ex; } } ShowProgress("", 0, null, null); return Releases; }
public void UseCUEToolsDB(string userAgent, string driveName, bool fuzzy, CTDBMetadataSearch metadataSearch) { ShowProgress((string)"Contacting CUETools database...", 0, null, null); _CUEToolsDB = new CUEToolsDB(_toc, proxy); _CUEToolsDB.UploadHelper.onProgress += new EventHandler<Krystalware.UploadHelper.UploadProgressEventArgs>(UploadProgress); _CUEToolsDB.ContactDB(_config.advanced.CTDBServer, userAgent, driveName, true, fuzzy, metadataSearch); if (!_isCD && !_toc[_toc.TrackCount].IsAudio && DataTrackLength == 0) foreach (DBEntry e in _CUEToolsDB.Entries) if (e.toc.TrackCount == _toc.TrackCount && e.toc.AudioLength == _toc.AudioLength && !e.toc[e.toc.TrackCount].IsAudio) { DataTrackLength = e.toc[e.toc.TrackCount].Length; break; } ShowProgress("", 0.0, null, null); isUsingCUEToolsDB = true; }
static void Main(string[] args) { Console.SetOut(Console.Error); Console.WriteLine("CUERipper v2.1.4 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.4", 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 WAVWriter(destFile, null, audioSource.PCM); 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.ErrorsCount, 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.Errors[(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 }
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.4", 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 (!string.IsNullOrEmpty(meta.releasedate)) extra += "Release date: " + meta.releasedate + "\r\n"; if (!string.IsNullOrEmpty(meta.country)) extra += "Release country: " + meta.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; }
// Now to the audio transfer functions, the sequence how // the functions are called is: // StartNewSession // StartNewTransfer // TransferAudio // ... // TransferAudio // TransferFinshed // Then perhaps repeating StartNewTransfer to TransferFinished // (e.g. when extracting several tracks), and finally // EndOfSession // This is called just before the log window will be // shown. You can return a log output in that stage (or // even display a window of your own - even though it should // not annoy the user) // StartNewSession is called once at the very beginning of an // extraction session. It receives the CD metadata, the // name of the used drive, the used read offset and whether // the offset was setted by AccurateRip (so having a comparable // offset value) public void StartNewSession(IMetadataLookup data, string drivename, int offset, bool aroffset, int mode) { // Copy the CD metadata to the object m_data = data; #if DEBUG m_trace = new StringWriter(); #endif var parts = drivename.Split(' '); m_drivename = parts[0].PadRight(8, ' ') + " -"; for (int i = 1; i < parts.Length; i++) m_drivename += " " + parts[i]; TOC = new CDImageLayout(); for (int i = 0; i < m_data.NumberOfTracks; i++) { uint start = m_data.GetTrackStartPosition(i); uint next = m_data.GetTrackEndPosition(i); TOC.AddTrack(new CDTrack( (uint)i + 1, start, next - start, !m_data.GetTrackDataTrack(i), m_data.GetTrackPreemphasis(i))); } TOC[1][0].Start = 0U; ar = new AccurateRipVerify(TOC, null); arTest = new AccurateRipVerify(TOC, null); ctdb = new CUEToolsDB(TOC, null); #if USEAR ArId = AccurateRipVerify.CalculateAccurateRipId(TOC); ar.ContactAccurateRip(ArId); #endif ctdb.Init(ar); this.sequence_ok = true; this.m_start_pos = 0; this.m_length = 0; this.m_test_mode = false; this.is_offset_set = aroffset; this.is_secure_mode = mode >= 2; }