public string GetFingerprint(IDiscToc toc) { int cksum = toc.TrackEntries.Sum(entry => UpdateCddbSum(entry.StartTime)); var trackCount = toc.EndTrack; var firstEntry = toc.TrackEntries.First(); var totaltime = toc.LeadOutEntry.StartTime - firstEntry.StartTime; var s = new StringWriter(); // discid uint id = ((uint)(cksum % 0xff) << 24) | (uint)(totaltime << 8) | (uint)trackCount; s.Write("{0:x8} ", id); // number of tracks s.Write(trackCount); // frame offsets foreach (var entry in toc.TrackEntries) { s.Write(" {0}", entry.StartFrame); } // length (in s) of disc s.Write(" {0}", toc.LeadOutEntry.StartTime); return(s.ToString()); }
static void Run(Options o) { IDiscToc toc = null; if (o.PerformTests) { toc = TestData.ReadToc(o.Device); } else { toc = CdRom.ReadToc(o.Device); } if (o.All || o.PrintToc) { Console.WriteLine($"first: {toc.StartTrack}"); Console.WriteLine($"last: {toc.EndTrack}"); foreach (var e in toc.TrackEntries) { Console.WriteLine("track: {0,3} lba: {1,9} {5:00}:{6:00}:{7:00} adr: {2} control: {3} mode: {4}", e.TrackNumber, e.Lba, e.Adr, e.Control, e.Mode, e.M, e.S, e.F); } var l = toc.LeadOutEntry; Console.WriteLine("track:lout lba: {0,9} {3:00}:{4:00}:{5:00} adr: {1} control: {2}", l.Lba, l.Adr, l.Control, l.M, l.S, l.F); } if (o.All || o.PrintFreeDbDiscID) { var freeDbDiscID = new FreeDbDiscID(); var fingerprint = freeDbDiscID.GetFingerprint(toc); Console.WriteLine("FreeDB DISC ID:\r\n {0}", fingerprint); var s = new FreeDBService(); var results = s.Query(fingerprint); foreach (var r in results) { Console.WriteLine($"{r.Category} {r.Discid} {r.Artist} / {r.Title}"); var data = s.Read(r); foreach (var track in data.Tracks) { Console.WriteLine("T{0:00} - {1}", track.Number, track.Title); } } } if (o.All || o.PrintMusicBrainzDiscID) { var musicBrainzDiscID = new MusicBrainzDiscID(); Console.WriteLine("MusicBrainz DISC ID:\r\n {0}", musicBrainzDiscID.GetFingerprint(toc)); } }
public string GetFingerprint(IDiscToc toc) { var encoding = System.Text.Encoding.ASCII; var ba = new byte[(1 + 1 + 4 + 99 * 4) * 2]; // First track number (normally one): 1 byte var s = String.Format("{0:X2}", (byte)toc.StartTrack); Array.Copy(encoding.GetBytes(s), 0, ba, 0, 2); // Last track number: 1 byte s = String.Format("{0:X2}", (byte)toc.EndTrack); Array.Copy(encoding.GetBytes(s), 0, ba, 2, 2); // in sum we have 100 offsets, Lead out + 99 tracks var offsets = new int[100]; offsets[0] = toc.LeadOutEntry.StartFrame; int i = 1; foreach (var e in toc.TrackEntries) { offsets[i++] = e.StartFrame; } // Add the hex representation of all these for (i = 0; i < 100; i++) { s = String.Format("{0:X8}", offsets[i]); Array.Copy(encoding.GetBytes(s), 0, ba, 4 + 8 * i, 8); } var sha1 = new SHA1Managed(); var hash = sha1.ComputeHash(ba); var id = Convert.ToBase64String(hash); // +, /, and = characters, all of which are special HTTP/URL characters. // To avoid the problems with dealing with that, MusicBrainz uses ., _, and - id = id.Replace('+', '.'); id = id.Replace('/', '_'); id = id.Replace('=', '-'); return(id); }