public bool EqualLayouts(CDImageLayout layout) { return this.TrackCount == layout.TrackCount && this.AudioTracks == layout.AudioTracks && this.FirstAudio == layout.FirstAudio && this.TrackOffsets == layout.TrackOffsets; }
public AccurateRipVerify(CDImageLayout toc, IWebProxy proxy) { this.proxy = proxy; _accDisks = new List<AccDisk>(); _hasLogCRC = false; _CRCLOG = new uint[toc.AudioTracks + 1]; ExceptionStatus = WebExceptionStatus.Pending; Init(toc); }
public TestImageGenerator(TestImageGenerator copy) { this.toc = copy.toc; this.seed = copy.seed; this.offset = copy.offset; this.start = copy.start; this.end = copy.end; this.errors = copy.errors; this.maxStrideErrors = copy.maxStrideErrors; }
public CUEToolsDB(CDImageLayout toc, IWebProxy proxy) { this.toc = toc; this.length = (int)toc.AudioLength * 588; this.proxy = proxy; this.uploadHelper = new HttpUploadHelper(); this.QueryExceptionStatus = WebExceptionStatus.Pending; this.connectTimeout = 15000; this.socketTimeout = 30000; }
public TestImageGenerator(CDImageLayout toc, int seed, int offset, int errors, int maxStrideErrors, int start, int end) { this.toc = toc; this.seed = seed; this.offset = offset; this.start = start; this.end = end; this.errors = errors; this.maxStrideErrors = maxStrideErrors; }
public static CDRepairEncode VerifyNoise(CDImageLayout toc, int seed, int offset, int start, int end, int errors, bool do_verify, bool do_encode) { if (start < 0 || start > end || end > toc.AudioLength * 588) throw new ArgumentOutOfRangeException(); var src = new NoiseAndErrorsGenerator(AudioPCMConfig.RedBook, end - start, seed, offset + start, errors); var buff = new AudioBuffer(src, 588 * 100); var ar = new AccurateRipVerify(toc, null); var encode = new CDRepairEncode(ar, stride, npar, do_verify, do_encode); var rnd = new Random(seed); ar.Position = start; while (src.Remaining > 0) { src.Read(buff, rnd.Next(1, buff.Size)); ar.Write(buff); } ar.Close(); return encode; }
public static void MyClassInitialize(TestContext testContext) { toc = new CDImageLayout(1, 1, 1, string.Format("0 {0}", (finalSampleCount / 588).ToString())); ar = new AccurateRipVerify(toc, null); ar2 = new AccurateRipVerify(toc, null); ar3 = new AccurateRipVerify(toc, null); new Random(2423).NextBytes(wav); new Random(2423).NextBytes(wav2); Random rnd = new Random(987); for (int i = 0; i < stride / 4; i++ ) wav2[(int)(rnd.NextDouble() * (wav2.Length - 1))] = (byte)(rnd.NextDouble() * 255); AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 0); CDRepairEncode encode = new CDRepairEncode(ar, stride, npar, false, true); buff.Prepare(wav, finalSampleCount); ar.Init(toc); ar.Write(buff); ar.Close(); parity = encode.Parity; crc = encode.CRC; decode = new CDRepairEncode(ar2, stride, npar, true, false); buff.Prepare(wav2, finalSampleCount); ar2.Init(toc); ar2.Write(buff); ar2.Close(); int actualOffset; bool hasErrors; decode.FindOffset(npar, parity, 0, crc, out actualOffset, out hasErrors); fix = decode.VerifyParity(parity, actualOffset); decode2 = new CDRepairEncode(ar3, stride, npar, true, false); ar3.Init(toc); buff.Prepare(new byte[offset * 4], offset); ar3.Write(buff); buff.Prepare(wav2, finalSampleCount - offset); ar3.Write(buff); ar3.Close(); decode2.FindOffset(npar, parity, 0, crc, out actualOffset, out hasErrors); fix2 = decode2.VerifyParity(parity, actualOffset); }
public DBEntry(CTDBResponseEntry ctdbRespEntry) { this.syndrome = ctdbRespEntry.syndrome == null ? ParityToSyndrome.Parity2Syndrome(1, 1, 8, 8, Convert.FromBase64String(ctdbRespEntry.parity)) : ParityToSyndrome.Bytes2Syndrome(1, Math.Min(AccurateRipVerify.maxNpar, ctdbRespEntry.npar), Convert.FromBase64String(ctdbRespEntry.syndrome)); this.conf = ctdbRespEntry.confidence; this.stride = ctdbRespEntry.stride * 2; this.crc = uint.Parse(ctdbRespEntry.crc32, NumberStyles.HexNumber); this.id = ctdbRespEntry.id; this.toc = CDImageLayout.FromString(ctdbRespEntry.toc); this.hasParity = ctdbRespEntry.hasparity; if (ctdbRespEntry.trackcrcs != null) { var crcs = ctdbRespEntry.trackcrcs.Split(' '); if (crcs.Length == this.toc.AudioTracks) { this.trackcrcs = new uint[crcs.Length]; for (int i = 0; i < this.trackcrcs.Length; i++) { this.trackcrcs[i] = uint.Parse(crcs[i], NumberStyles.HexNumber); } } } }
public void UseAccurateRip() { ShowProgress((string)"Contacting AccurateRip database...", 0, null, null); if (!_toc[_toc.TrackCount].IsAudio && DataTrackLength == 0 && _minDataTrackLength.HasValue && _accurateRipId == null && _config.bruteForceDTL) { uint minDTL = _minDataTrackLength.Value; CDImageLayout toc2 = new CDImageLayout(_toc); for (uint dtl = minDTL; dtl < minDTL + 75; dtl++) { toc2[toc2.TrackCount].Length = dtl; _arVerify.ContactAccurateRip(AccurateRipVerify.CalculateAccurateRipId(toc2)); if (_arVerify.ExceptionStatus == WebExceptionStatus.Success) { DataTrackLength = dtl; break; } if (_arVerify.ExceptionStatus != WebExceptionStatus.ProtocolError || _arVerify.ResponseStatus != HttpStatusCode.NotFound) break; ShowProgress((string)"Contacting AccurateRip database...", (dtl - minDTL) / 75.0, null, null); CheckStop(); } } else { _arVerify.ContactAccurateRip(_accurateRipId ?? AccurateRipVerify.CalculateAccurateRipId(_toc)); } isUsingAccurateRip = true; }
public bool Equals(CDImageLayout layout, List<string> fullAudioPaths) { return EqualLayouts(layout) && EqualAudioPaths(fullAudioPaths); }
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 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); }
public void Close() { UserData = null; C2Count = null; if (m_device != null) m_device.Close(); m_device = null; _toc = null; _toc2 = null; gapsDetected = false; readCommandFound = false; _currentStart = -1; _currentEnd = -1; }
public CUESheet(CUEConfig config) { _config = config; _progress = new CUEToolsProgressEventArgs(); _progress.cueSheet = this; _attributes = new List<CUELine>(); _tracks = new List<TrackInfo>(); _trackFilenames = new List<string>(); _toc = new CDImageLayout(); _sources = new List<SourceInfo>(); _sourcePaths = new List<string>(); _stop = false; _pause = false; _outputPath = null; _paddedToFrame = false; _truncated4608 = false; _usePregapForFirstTrackInSingleFile = false; _action = CUEAction.Encode; _appliedWriteOffset = false; _minDataTrackLength = null; hdcdDecoder = null; _hasEmbeddedCUESheet = false; _isArchive = false; _isCD = false; _useLocalDB = false; proxy = _config.GetProxy(); }
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 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; }
public void Init(CDImageLayout toc) { _toc = toc; _finalSampleCount = _toc.AudioLength * 588; _CRCMASK = new uint[_toc.AudioTracks + 1]; _CRCMASK[0] = 0xffffffff ^ Crc32.Combine(0xffffffff, 0, (int)_finalSampleCount * 4); for (int iTrack = 1; iTrack <= _toc.AudioTracks; iTrack++) _CRCMASK[iTrack] = 0xffffffff ^ Crc32.Combine(0xffffffff, 0, (int)_toc[iTrack + _toc.FirstAudio - 1].Length * 588 * 4); maxOffset = Math.Max(4096 * 2, calcParity ? stride + laststride : 0); if (maxOffset % 588 != 0) maxOffset += 588 - maxOffset % 588; _CRCAR = new uint[_toc.AudioTracks + 1, 3 * maxOffset]; _CRCSM = new uint[_toc.AudioTracks + 1, 3 * maxOffset]; _CRC32 = new uint[_toc.AudioTracks + 1, 3 * maxOffset]; _CacheCRC32 = new uint[_toc.AudioTracks + 1, 3 * maxOffset]; _CRCWN = new uint[_toc.AudioTracks + 1, 3 * maxOffset]; _CacheCRCWN = new uint[_toc.AudioTracks + 1, 3 * maxOffset]; _CRCNL = new int[_toc.AudioTracks + 1, 3 * maxOffset]; _CRCV2 = new uint[_toc.AudioTracks + 1, 3 * maxOffset]; _Peak = new int[_toc.AudioTracks + 1]; parity = null; if (calcParity) { parity = new byte[stride * maxNpar * 2]; encodeTable = Galois16.instance.makeEncodeTable(maxNpar); } int leadin_len = Math.Max(4096 * 4, calcParity ? stride * 2 : 0); int leadout_len = Math.Max(4096 * 4, calcParity ? stride + laststride : 0); leadin = new ushort[leadin_len]; leadout = new ushort[leadout_len]; _currentTrack = 0; Position = 0; // NOT _toc[_toc.FirstAudio][0].Start * 588; }
public static string CalculateCDDBId(CDImageLayout toc) { uint cddbDiscId = 0; for (int iTrack = 1; iTrack <= toc.TrackCount; iTrack++) cddbDiscId += sumDigits(toc[iTrack].Start / 75 + 2); // !!!!!!!!!!!!!!!!! %255 !! return string.Format("{0:X8}", (((cddbDiscId % 255) << 24) + ((toc.Length / 75 - toc[1].Start / 75) << 8) + (uint)toc.TrackCount) & 0xFFFFFFFF); }
public static string CalculateAccurateRipId(CDImageLayout toc) { // Calculate the three disc ids used by AR uint discId1 = 0; uint discId2 = 0; uint num = 0; for (int iTrack = 1; iTrack <= toc.TrackCount; iTrack++) if (toc[iTrack].IsAudio) { discId1 += toc[iTrack].Start; discId2 += Math.Max(toc[iTrack].Start, 1) * (++num); } discId1 += toc.Length; discId2 += Math.Max(toc.Length, 1) * (++num); discId1 &= 0xFFFFFFFF; discId2 &= 0xFFFFFFFF; return string.Format("{0:x8}-{1:x8}-{2}", discId1, discId2, CalculateCDDBId(toc).ToLower()); }
public static string CalculateCDDBQuery(CDImageLayout toc) { StringBuilder query = new StringBuilder(CalculateCDDBId(toc)); query.AppendFormat("+{0}", toc.TrackCount); for (int iTrack = 1; iTrack <= toc.TrackCount; iTrack++) query.AppendFormat("+{0}", toc[iTrack].Start + 150); query.AppendFormat("+{0}", toc.Length / 75 + 2); return query.ToString(); }
public CUEMetadataEntry(CDImageLayout TOC, string key) : this(new CUEMetadata(TOC.TOCID, (int)TOC.AudioTracks), TOC, key) { }
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) { }
private void DetectGaps() { if (!_isCD) throw new Exception("not a CD"); if (_config.detectGaps) { try { _ripper.DetectGaps(); } catch (Exception ex) { if (ex is StopException) throw ex; } } if (!_ripper.GapsDetected) return; _toc = (CDImageLayout)_ripper.TOC.Clone(); if (_toc.Barcode != null) Metadata.Barcode = _toc.Barcode; for (int iTrack = 0; iTrack < _toc.AudioTracks; iTrack++) { if (_toc[_toc.FirstAudio + iTrack].ISRC != null) Metadata.Tracks[iTrack].ISRC = _toc[_toc.FirstAudio + iTrack].ISRC; //General.SetCUELine(_tracks[iTrack].Attributes, "ISRC", _toc[_toc.FirstAudio + iTrack].ISRC, false); if (_toc[_toc.FirstAudio + iTrack].DCP || _toc[_toc.FirstAudio + iTrack].PreEmphasis) _tracks[iTrack].Attributes.Add(new CUELine("FLAGS" + (_toc[_toc.FirstAudio + iTrack].PreEmphasis ? " PRE" : "") + (_toc[_toc.FirstAudio + iTrack].DCP ? " DCP" : ""))); } }
public CDImageLayout(CDImageLayout src) { _barcode = src._barcode; _audioTracks = src._audioTracks; _firstAudio = src._firstAudio; _tracks = new List<CDTrack>(); for (int i = 0; i < src.TrackCount; i++) _tracks.Add(new CDTrack(src._tracks[i])); }
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 CUEMetadataEntry(CUEMetadata metadata, CDImageLayout TOC, string key) { this.metadata = new CUEMetadata(metadata); this.TOC = TOC; this.ImageKey = key; }
public void OpenCD(ICDRipper 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()); } cueMetadata = new CUEMetadata(TOC.TOCID, (int)TOC.AudioTracks); _arVerify = new AccurateRipVerify(_toc, proxy); _isCD = true; SourceInfo cdInfo; cdInfo.Path = _ripper.ARName; cdInfo.Offset = 0; cdInfo.Length = _toc.AudioLength * 588; _sources.Add(cdInfo); // Causes memory leak, so had to disable! //_ripper.ReadProgress += new EventHandler<ReadProgressArgs>(CDReadProgress); _padding += TrackCount * 200; _padding += _config.embedLog ? 500 + TrackCount * 200 : 0; }
public unsafe bool DetectGaps() { if (!TestReadCommand()) throw new ReadCDException(Resource1.AutodetectReadCommandFailed + ":\n" + _autodetectResult); if (_gapDetection == GapDetectionMethod.None) { gapsDetected = false; return false; } if (gapsDetected) return true; _toc2 = (CDImageLayout)_toc.Clone(); if (_gapDetection == GapDetectionMethod.ReadSubchannel) { Device.CommandStatus st = m_device.ReadSubChannel42(2, 0, ref _subchannelBuffer, 0, _timeout); if (st == Device.CommandStatus.Success) if (_subchannelBuffer[0] == 0 && _subchannelBuffer[2] == 0 && _subchannelBuffer[3] == 20 && _subchannelBuffer[4] == 2 && _subchannelBuffer[8] == 0x80) { string catalog = Encoding.ASCII.GetString(_subchannelBuffer, 9, 13); if (catalog.ToString() != "0000000000000") _toc2.Barcode = catalog.ToString(); } } int sec0 = (int)_toc2[_toc2.FirstAudio][0].Start, disc1 = (int)(_toc2[_toc2.FirstAudio][0].Start + _toc2.AudioLength) - 1; for (int iTrack = _toc2.FirstAudio; iTrack < _toc2.FirstAudio + _toc2.AudioTracks; iTrack++) { if (ReadProgress != null) { progressArgs.Action = Resource1.StatusDetectingGaps; progressArgs.Pass = -1; progressArgs.Position = (iTrack - _toc2.FirstAudio) * 3; progressArgs.PassStart = 0; progressArgs.PassEnd = _toc2.TrackCount * 3 - 1; progressArgs.ErrorsCount = 0; progressArgs.PassTime = DateTime.Now; ReadProgress(this, progressArgs); } int sec1, idx1 = 1; LocateLastSector(sec0, Math.Min(disc1, (int)_toc[iTrack].End + 16), iTrack, -1, ref idx1, out sec1); int isec0 = sec0; for (int idx = 0; idx <= idx1; idx++) { int isec1 = sec1, iidx1 = 1; if (idx < idx1) { if (ReadProgress != null) { progressArgs.Position = (iTrack - _toc2.FirstAudio) * 3 + 1; progressArgs.PassTime = DateTime.Now; ReadProgress(this, progressArgs); } LocateLastSector(isec0, sec1, iTrack, idx, ref iidx1, out isec1); } if (isec1 > isec0) { if (idx == 0 && iTrack > 1) _toc2[iTrack][0].Start = _toc2[iTrack].Start - (uint)(isec1 - isec0 + 1); if (idx > 1) _toc2[iTrack].AddIndex(new CDTrackIndex((uint)idx, (uint)(_toc2[iTrack][0].Start + isec0 - sec0))); } isec0 = isec1 + 1; } if (ReadProgress != null) { progressArgs.Position = (iTrack - _toc2.FirstAudio) * 3 + 2; progressArgs.PassTime = DateTime.Now; ReadProgress(this, progressArgs); } if (_gapDetection == GapDetectionMethod.ReadSubchannel) { Device.CommandStatus st = m_device.ReadSubChannel42(3, iTrack, ref _subchannelBuffer, 0, _timeout); if (st == Device.CommandStatus.Success) if (_subchannelBuffer[0] == 0 && _subchannelBuffer[2] == 0 && _subchannelBuffer[3] == 20 && _subchannelBuffer[4] == 3 && _subchannelBuffer[8] == 0x80) //&& _subchannelBuffer[6] == iTrack) { string isrc = Encoding.ASCII.GetString(_subchannelBuffer, 9, 12); if (!isrc.ToString().Contains("#") && isrc.ToString() != "000000000000") _toc2[iTrack].ISRC = isrc.ToString(); } } if (_gapDetection == GapDetectionMethod.ReadCD) { Device.CommandStatus st = m_device.ReadSubChannel(2, _toc2[iTrack].Start + 16, 100, ref _subchannelBuffer, _timeout); if (st == Device.CommandStatus.Success) { for (int offs = 0; offs < 100 * 16; offs += 16) { int ctl = _subchannelBuffer[offs + 0] >> 4; int adr = _subchannelBuffer[offs + 0] & 7; if (adr != 2 && adr != 3) continue; ushort crc = _crc.ComputeChecksum(_subchannelBuffer, offs, 10); crc ^= 0xffff; ushort scrc = (ushort)((_subchannelBuffer[offs + 10] << 8) | _subchannelBuffer[offs + 11]); if (scrc != 0 && scrc != crc) continue; if (adr == 3 && _toc2[iTrack].ISRC == null) { StringBuilder isrc = new StringBuilder(); isrc.Append(from6bit(_subchannelBuffer[offs + 1] >> 2)); isrc.Append(from6bit(((_subchannelBuffer[offs + 1] & 0x3) << 4) + (0x0f & (_subchannelBuffer[offs + 2] >> 4)))); isrc.Append(from6bit(((_subchannelBuffer[offs + 2] & 0xf) << 2) + (0x03 & (_subchannelBuffer[offs + 3] >> 6)))); isrc.Append(from6bit((_subchannelBuffer[offs + 3] & 0x3f))); isrc.Append(from6bit(_subchannelBuffer[offs + 4] >> 2)); isrc.Append(from6bit(((_subchannelBuffer[offs + 4] & 0x3) << 4) + (0x0f & (_subchannelBuffer[offs + 5] >> 4)))); isrc.AppendFormat("{0:x}", _subchannelBuffer[offs + 5] & 0xf); isrc.AppendFormat("{0:x2}", _subchannelBuffer[offs + 6]); isrc.AppendFormat("{0:x2}", _subchannelBuffer[offs + 7]); isrc.AppendFormat("{0:x}", _subchannelBuffer[offs + 8] >> 4); if (!isrc.ToString().Contains("#") && isrc.ToString() != "000000000000") _toc2[iTrack].ISRC = isrc.ToString(); } if (adr == 2 && _toc2.Barcode == null) { StringBuilder barcode = new StringBuilder(); for (int i = 1; i < 8; i++) barcode.AppendFormat("{0:x2}", _subchannelBuffer[offs + i]); if (barcode.ToString(0, 13) != "0000000000000") _toc2.Barcode = barcode.ToString(0, 13); } } } } sec0 = sec1 + 1; } gapsDetected = true; 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; }
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; }