public CDImageLayout TocFromCDEntry(CDEntry cdEntry) { CDImageLayout tocFromCDEntry = new CDImageLayout(); for (int i = 0; i < cdEntry.Tracks.Count; i++) { if (i >= _toc.TrackCount) break; tocFromCDEntry.AddTrack(new CDTrack((uint)i + 1, (uint)cdEntry.Tracks[i].FrameOffset - 150, (i + 1 < cdEntry.Tracks.Count) ? (uint)(cdEntry.Tracks[i + 1].FrameOffset - cdEntry.Tracks[i].FrameOffset) : _toc[i + 1].Length, _toc[i + 1].IsAudio, false/*preEmphasis*/)); } if (tocFromCDEntry.TrackCount > 0 && tocFromCDEntry[1].IsAudio) tocFromCDEntry[1][0].Start = 0; return tocFromCDEntry; }
public static CDImageLayout CUE2TOC(string cue, int fileTimeLengthFrames) { CDImageLayout toc = new CDImageLayout(); bool seenFirstFileIndex = false; int absoluteFileStartTime = 0; int trackStart = -1; try { using (TextReader sr = new StringReader(cue)) { string lineStr; while ((lineStr = sr.ReadLine()) != null) { CUELine line = new CUELine(lineStr); if (line.Params.Count > 0) { string command = line.Params[0].ToUpper(); if (command == "TRACK") { if (line.Params[2].ToUpper() != "AUDIO") return null; } else if (command == "INDEX") { int index = int.Parse(line.Params[1]); int timeRelativeToFileStart = CDImageLayout.TimeFromString(line.Params[2]); if (!seenFirstFileIndex) { if (timeRelativeToFileStart != 0) return null; seenFirstFileIndex = true; } else { if (timeRelativeToFileStart > fileTimeLengthFrames) return null; if (Int32.TryParse(line.Params[1], out index) && index == 1 && trackStart >= 0) toc.AddTrack(new CDTrack((uint)toc.TrackCount + 1, (uint)trackStart, (uint)(absoluteFileStartTime + timeRelativeToFileStart - trackStart), true, false)); } if (index == 1) trackStart = absoluteFileStartTime + timeRelativeToFileStart; } else if (command == "PREGAP") { if (seenFirstFileIndex) return null; int pregapLength = CDImageLayout.TimeFromString(line.Params[1]); absoluteFileStartTime += pregapLength; } } } sr.Close(); } } catch { return null; } toc.AddTrack(new CDTrack((uint)toc.TrackCount + 1, (uint)trackStart, (uint)(absoluteFileStartTime + fileTimeLengthFrames - trackStart), true, false)); toc[1][0].Start = 0; return toc; }
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; }
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 Open(char Drive) { Device.CommandStatus st; m_inqury_result = null; // Open the base device m_device_letter = Drive; if (m_device != null) Close(); m_device = new Device(m_logger); if (!m_device.Open(m_device_letter)) throw new ReadCDException(Resource1.DeviceOpenError, Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error())); //throw new ReadCDException(Resource1.DeviceOpenError + ": " + WinDev.Win32ErrorToString(m_device.LastError)); // Get device info st = m_device.Inquiry(out m_inqury_result); if (st != Device.CommandStatus.Success) throw new SCSIException(Resource1.DeviceInquiryError, m_device, st); if (!m_inqury_result.Valid || m_inqury_result.PeripheralQualifier != 0 || m_inqury_result.PeripheralDeviceType != Device.MMCDeviceType) throw new ReadCDException(Resource1.DeviceNotMMC); m_max_sectors = Math.Min(NSECTORS, m_device.MaximumTransferLength / CB_AUDIO - 1); //// Open/Initialize the driver //Drive m_drive = new Drive(dev); //DiskOperationError status = m_drive.Initialize(); //if (status != null) // throw new Exception("SCSI error"); // { //Drive.FeatureState readfeature = m_drive.GetFeatureState(Feature.FeatureType.CDRead); //if (readfeature == Drive.FeatureState.Error || readfeature == Drive.FeatureState.NotPresent) // throw new Exception("SCSI error"); // }{ //st = m_device.GetConfiguration(Device.GetConfigType.OneFeature, 0, out flist); //if (st != Device.CommandStatus.Success) // return CreateErrorObject(st, m_device); //Feature f = flist.Features[0]; //ParseProfileList(f.Data); // } //SpeedDescriptorList speed_list; //st = m_device.GetSpeed(out speed_list); //if (st != Device.CommandStatus.Success) // throw new Exception("GetSpeed failed: SCSI error"); //m_device.SetCdSpeed(Device.RotationalControl.CLVandNonPureCav, (ushort)(0x7fff), (ushort)(0x7fff)); //int bytesPerSec = 4 * 588 * 75 * (pass > 8 ? 4 : pass > 4 ? 8 : pass > 0 ? 16 : 32); //Device.CommandStatus st = m_device.SetStreaming(Device.RotationalControl.CLVandNonPureCav, start, end, bytesPerSec, 1, bytesPerSec, 1); //if (st != Device.CommandStatus.Success) // System.Console.WriteLine("SetStreaming: ", (st == Device.CommandStatus.DeviceFailed ? Device.LookupSenseError(m_device.GetSenseAsc(), m_device.GetSenseAscq()) : st.ToString())); //st = m_device.SetCdSpeed(Device.RotationalControl.CLVandNonPureCav, (ushort)(bytesPerSec / 1024), (ushort)(bytesPerSec / 1024)); //if (st != Device.CommandStatus.Success) // System.Console.WriteLine("SetCdSpeed: ", (st == Device.CommandStatus.DeviceFailed ? Device.LookupSenseError(m_device.GetSenseAsc(), m_device.GetSenseAscq()) : st.ToString())); //st = m_device.SetCdSpeed(Device.RotationalControl.CLVandNonPureCav, 32767/*Device.OptimumSpeed*/, Device.OptimumSpeed); //if (st != Device.CommandStatus.Success) // throw new Exception("SetCdSpeed failed: SCSI error"); IList<TocEntry> toc; st = m_device.ReadToc((byte)0, false, out toc); if (st != Device.CommandStatus.Success) throw new SCSIException(Resource1.ReadTOCError, m_device, st); //throw new Exception("ReadTOC: " + (st == Device.CommandStatus.DeviceFailed ? Device.LookupSenseError(m_device.GetSenseAsc(), m_device.GetSenseAscq()) : st.ToString())); //byte[] qdata = null; //st = m_device.ReadPMA(out qdata); //if (st != Device.CommandStatus.Success) // throw new SCSIException("ReadPMA", m_device, st); //st = m_device.ReadCDText(out cdtext, _timeout); // new CDTextEncoderDecoder _toc2 = null; _toc = new CDImageLayout(); for (int iTrack = 0; iTrack < toc.Count - 1; iTrack++) _toc.AddTrack(new CDTrack((uint)iTrack + 1, toc[iTrack].StartSector, toc[iTrack + 1].StartSector - toc[iTrack].StartSector - ((toc[iTrack + 1].Control < 4 || iTrack + 1 == toc.Count - 1) ? 0U : 152U * 75U), toc[iTrack].Control < 4, (toc[iTrack].Control & 1) == 1)); if (_toc.AudioLength > 0) { if (_toc[1].IsAudio) _toc[1][0].Start = 0; Position = 0; } else throw new ReadCDException(Resource1.NoAudio); UserData = new long[MSECTORS, 2, 4 * 588]; C2Count = new byte[MSECTORS, 294]; 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; }