/// <summary> /// 将由UTF-16编码的EAC抓轨记录转换为EACLog类 /// </summary> /// <param name="log">表示一个完整的由UTF-16编码的EAC抓轨记录</param> /// <returns></returns> public EACLog ConvertfromString(string log) { #region Pre. string[] splitPoint = new string[] { ": " }; EACLog eACLog = new EACLog(); int head = 0; int range = 0; int trackcount = 0; List <string> sublist; List <string> loglines = log.Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList(); if (!loglines[0].StartsWith("Exact Audio Copy")) { throw new Exception("Error:000001");//Error:000001 表示该log不是EAC log } if (loglines.Exists((s) => s.Trim() == "Range status and errors" ? true : false)) { eACLog.IsRange = true; } #endregion Pre. #region Handle header eACLog.EACVision = (loglines[0].Substring(17).Split(new string[] { "from " }, StringSplitOptions.None))[0]; eACLog.CopyDate = (loglines[2].Split(new string[] { "from " }, StringSplitOptions.None))[1]; eACLog.LogCheckSum = loglines.Where(a => a.StartsWith("==== Log checksum")).ToList()[0].Split(' ')[3]; eACLog.TrackName = loglines[4]; eACLog.UsedDrive = SearchStringStartsWithinList("Used drive", loglines)?.Split(splitPoint, StringSplitOptions.None)[1].Replace("Adapter", ""); eACLog.Adapter = SearchStringStartsWithinList("Used drive", loglines)?.Split(splitPoint, StringSplitOptions.None)[2].Replace("ID", ""); eACLog.ID = SearchStringStartsWithinList("Used drive", loglines)?.Split(splitPoint, StringSplitOptions.None)[3]; eACLog.ReadMode = SearchStringStartsWithinList("Read mode", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.UtilizeAccurateStream = SearchStringStartsWithinList("Utilize accurate stream", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.DefeatAudioCache = SearchStringStartsWithinList("Defeat audio cache", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.MakeUseofC2Pointers = SearchStringStartsWithinList("Make use of C2 pointers", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.ReadOffsetCorrection = SearchStringStartsWithinList("Read offset correction", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.OverreadIntoLeadInandLeadOut = SearchStringStartsWithinList("Overread into Lead-In and Lead-Out", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.FillUpMissingOffsetSamplesWithSilence = SearchStringStartsWithinList("Fill up missing offset samples with silence", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.DeleteLeadingTrailingSilentBlocks = SearchStringStartsWithinList("Delete leading and trailing silent blocks", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.NullSamplesUsedinCRCCalculations = SearchStringStartsWithinList("Null samples used in CRC calculations", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.UsedInterface = SearchStringStartsWithinList("Used interface", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.GapHandling = SearchStringStartsWithinList("Gap handling", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.NormalizeTo = SearchStringStartsWithinList("Normalize to", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.UseCompressionOffset = loglines.Exists(a => a.Trim() == "Use compression offset"); eACLog.OutputFormat = SearchStringStartsWithinList("Used output format", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; if (eACLog.OutputFormat == "User Defined Encoder") { eACLog.SelectedBitrate = SearchStringStartsWithinList("Selected bitrate", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.Quality = SearchStringStartsWithinList("Quality", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.AddID3Tag = SearchStringStartsWithinList("Add ID3 tag", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.CommandLineCompressor = SearchStringStartsWithinList("Command line compressor", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; eACLog.AdditionalCommandLineOptions = SearchStringStartsWithinList("Additional command line options", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; } else if (eACLog.OutputFormat == "Internal WAV Routines") { eACLog.SimpleFormat = SearchStringStartsWithinList("Simple format", loglines)?.Split(splitPoint, StringSplitOptions.None)[1]; } eACLog.IsAllAccuratelyRipped = loglines.Exists(a => a.Trim() == "All tracks accurately ripped"); #endregion Handle header #region Handle TOC head = loglines.IndexOf("TOC of the extracted CD") + 4; range = 0; if (eACLog.IsRange) { range = loglines.IndexOf("Range status and errors") - 1 - head; } else { range = loglines.IndexOf("Track 1") - 1 - head; } sublist = loglines.GetRange(head, range); foreach (var item in sublist) { string[] subitem = item.Split('|'); if (int.TryParse(subitem[0].Trim(), out int a)) { EACTOCItem tempTOC = new EACTOCItem() { TrackNumber = subitem[0].Trim(), StartTime = subitem[1].Trim(), Length = subitem[2].Trim(), StartSector = subitem[3].Trim(), EndSector = subitem[4].Trim() }; eACLog.TOC.Add(tempTOC); } } #endregion Handle TOC #region Handle Track head = 0; range = 0; if (eACLog.IsRange) { head = loglines.IndexOf("Range status and errors"); range = loglines.IndexOf("End of status report") - 1 - head; } else { head = loglines.IndexOf("Track 1"); range = loglines.IndexOf("End of status report") - 1 - head; } sublist = loglines.GetRange(head, range); foreach (var item in sublist) { var itemt = item.Trim(); if (item.StartsWith("Track ") || item.StartsWith("Selected range")) { trackcount++; eACLog.TrackList.Add(new EACTrackItem()); eACLog.TrackList[trackcount - 1].TrackNumber = trackcount; } else if (itemt.StartsWith("Pre-gap length")) { eACLog.TrackList[trackcount - 1].PeakLevel = itemt.Substring(15); } else if (itemt.StartsWith("Filename")) { eACLog.TrackList[trackcount - 1].Filename = itemt.Substring(9); } else if (itemt.StartsWith("Peak level")) { eACLog.TrackList[trackcount - 1].PeakLevel = itemt.Substring(11); } else if (itemt.StartsWith("Extraction speed")) { eACLog.TrackList[trackcount - 1].ExtractionSpeed = itemt.Substring(17); } else if (itemt.StartsWith("Track quality")) { eACLog.TrackList[trackcount - 1].TrackQuality = itemt.Substring(14); } else if (itemt.StartsWith("Test CRC")) { eACLog.TrackList[trackcount - 1].TestCRC = itemt.Substring(9); } else if (itemt.StartsWith("Copy CRC")) { eACLog.TrackList[trackcount - 1].CopyCRC = itemt.Substring(9); } else if (itemt.StartsWith("Accurately ripped")) { eACLog.TrackList[trackcount - 1].AccuratelyRipped = itemt; } else if (itemt.StartsWith("Copy ")) { eACLog.TrackList[trackcount - 1].CopyStatus = itemt.Substring(5); } else if (itemt.StartsWith("Suspicious position")) { eACLog.TrackList[trackcount - 1].SuspiciousPosition.Add(itemt.Substring(20)); } else if (itemt.StartsWith("Timing problem")) { eACLog.TrackList[trackcount - 1].TimingProblem++; } else if (itemt.StartsWith("Missing sample")) { eACLog.TrackList[trackcount - 1].MissingSample++; } } #endregion Handle Track return(eACLog); }
/// <summary> /// 对一个EAC抓轨记录类进行评分 /// </summary> /// <param name="log">表示一个EAC抓轨记录类</param> /// <returns></returns> public Tuple <List <string>, int> GetScore(EACLog log) { #region Pre. int dealscore = 0; List <string> commentlist = new List <string>(); bool is095 = (new Regex("V0.95")).IsMatch(log.EACVision); #endregion Pre. #region Check Get if (!log.IsRange) { #region Check Tracks EACTrackItem trackItem; for (int i = 0; i < log.TrackList.Count; i++) { trackItem = log.TrackList[i]; if (trackItem.PreGapLength == null && i == 0 && is095) { dealscore += MasterRule["PreGapLength"].Score; commentlist.Add(TrackCommentBuild("PreGapLength", i + 1)); } if (trackItem.SuspiciousPositionCount > 0) { dealscore += MasterRule["SuspiciousPosition"].Score; commentlist.Add(TrackCommentBuild("SuspiciousPosition", i + 1)); } if (trackItem.MissingSample > 0) { dealscore += MasterRule["MissingSample"].Score; commentlist.Add(TrackCommentBuild("MissingSample", i + 1)); } if (trackItem.TimingProblem > 0) { dealscore += MasterRule["TimingProblem"].Score; commentlist.Add(TrackCommentBuild("TimingProblem", i + 1)); } if (trackItem.CopyStatus != "OK") { dealscore += MasterRule["CopyStatus"].Score; commentlist.Add(TrackCommentBuild("CopyStatus", i + 1)); } if (trackItem.TestCRC != null && trackItem.TestCRC != trackItem.CopyCRC) { if (log.ReadMode != "Secure") { dealscore += MasterRule["CRCUncertainAndNotSecure"].Score; commentlist.Add(TrackCommentBuild("CRCUncertainAndNotSecure", i + 1)); } else { dealscore += MasterRule["CRCUncertain"].Score; commentlist.Add(TrackCommentBuild("CRCUncertain", i + 1)); } } if (trackItem.AccuratelyRipped == null) { if (!log.IsAllAccuratelyRipped) { dealscore += MasterRule["NotAccuratelyRipped"].Score; commentlist.Add(TrackCommentBuild("NotAccuratelyRipped", i + 1)); } } else { if (is095) { dealscore += MasterRule["Fake"].Score; commentlist.Add(TrackCommentBuild("Fake", i + 1)); } } if (trackItem.TrackQuality == null && log.ReadMode == "Secure" && !is095) { dealscore += MasterRule["Fake"].Score; commentlist.Add(TrackCommentBuild("Fake", i + 1)); } } #endregion Check Tracks } else { dealscore += MasterRule["IsRange"].Score; commentlist.Add(MasterRule["IsRange"].Comment); } #endregion Check Get #region Check Header if (!log.IsAllAccuratelyRipped) { dealscore += MasterRule["IsNotAllAccuratelyRipped"].Score; commentlist.Add(MasterRule["IsNotAllAccuratelyRipped"].Comment); } if (log.NormalizeTo != null) { dealscore += MasterRule["NormalizeToOn"].Score; commentlist.Add(MasterRule["NormalizeToOn"].Comment); } if (log.UseCompressionOffset) { dealscore += MasterRule["UseCompressionOffset"].Score; commentlist.Add(MasterRule["UseCompressionOffset"].Comment); } if (log.MakeUseofC2Pointers == "Yes") { dealscore += MasterRule["UsedC2"].Score; commentlist.Add(MasterRule["UsedC2"].Comment); } if (log.FillUpMissingOffsetSamplesWithSilence != "Yes") { dealscore += MasterRule["NotFillUpMissingOffsetSamplesWithSilence"].Score; commentlist.Add(MasterRule["NotFillUpMissingOffsetSamplesWithSilence"].Comment); if (log.NullSamplesUsedinCRCCalculations != "Yes") { dealscore += MasterRule["NotNullSamplesUsedinCRCCalculations"].Score; commentlist.Add(MasterRule["NotNullSamplesUsedinCRCCalculations"].Comment); } } if (log.DeleteLeadingTrailingSilentBlocks == "Yes") { dealscore += MasterRule["DeleteLeadingTrailingSilentBlocks"].Score; commentlist.Add(MasterRule["DeleteLeadingTrailingSilentBlocks"].Comment); } if (log.GapHandling != "Appended to previous track" && !is095) { dealscore += MasterRule["NotGapHandle"].Score; commentlist.Add(MasterRule["NotGapHandle"].Comment); } if (log.AddID3Tag == "Yes") { dealscore += MasterRule["AddID3Tag"].Score; commentlist.Add(MasterRule["AddID3Tag"].Comment); } if (log.ReadMode != "Secure") { dealscore += MasterRule["InSecure"].Score; commentlist.Add(MasterRule["InSecure"].Comment); } if (log.DefeatAudioCache != "Yes" && log.ReadMode != "Burst") { dealscore += MasterRule["NoDefeatAudioCache"].Score; commentlist.Add(MasterRule["NoDefeatAudioCache"].Comment); } if ((new Regex("Generic DVD-ROM SCSI CdRom Device")).IsMatch(log.UsedDrive)) { dealscore += MasterRule["VirtualDriveUsed"].Score; commentlist.Add(MasterRule["VirtualDriveUsed"].Comment); } else { var drivename = ReplaceString(@"/[^0-9a-z]/i", ReplaceString(@"\s+", ReplaceString(@"\s+-\s", log.UsedDrive)).Trim()).Split(' '); var drive = drivename[drivename.Length - 1]; var q = from item in DriveDB where item?.Item1.IndexOf(drive) >= 0 select item.Item2; var list = q.ToList(); if (list.Count > 0 && list.Count <= 30 && list != null) { if (!list.Exists(a => a.Replace(" ", "") == log.ReadOffsetCorrection)) { dealscore += MasterRule["OffsetNotRight"].Score; commentlist.Add(MasterRule["OffsetNotRight"].Comment); } } else if (log.ReadOffsetCorrection == "0") { dealscore += MasterRule["OffsetNotFound"].Score; commentlist.Add(MasterRule["OffsetNotFound"].Comment); } else if (log.ReadOffsetCorrection != "0") { dealscore += MasterRule["OffsetNotInDB"].Score; commentlist.Add(MasterRule["OffsetNotInDB"].Comment); } } #endregion Check Header return(new Tuple <List <string>, int>(commentlist, 100 - dealscore)); }