MatchingCopyPattern internalFindMatchingCopyPattern( FindMatchingPatternConfig findConfig, CopyPatternPreset replaceConfig) { var ret = new MatchingCopyPattern(); bool matchG5Lengths = replaceConfig.MatchLengths5; bool matchG6Lengths = replaceConfig.MatchLengths6; bool matchSpacing = replaceConfig.MatchSpacing; bool matchBeat = replaceConfig.MatchBeat; TickPair ticks; if (!getPatternMatchTicks(out ticks)) return ret; var track5 = EditorG5.GuitarTrack; var track6 = EditorPro.GuitarTrack; var chords5 = track5.Messages.Chords.ToArray(); var nchords6 = track6.Messages.Chords.ToArray(); var matchChords5 = track5.Messages.Chords.GetBetweenTick(ticks).ToArray(); if (matchChords5.Length == 0) return ret; var oChords6 = track6.Messages.Chords.GetBetweenTick(ticks).ToArray(); if (oChords6.Length == 0) return ret; if (replaceConfig.ForwardOnly && !findConfig.FindPrevious) { chords5 = chords5.Where(x => x.DownTick >= ticks.Up).ToArray(); nchords6 = nchords6.Where(x => x.DownTick >= ticks.Up).ToArray(); } int minMatchTick5 = matchChords5.GetMinTick(); int minMatchTick6 = oChords6.GetMinTick(); int maxMatchTick6 = oChords6.GetMaxTick(); ret.DeltaTimeStart = track6.TickToTime(minMatchTick6) - track5.TickToTime(minMatchTick5); if (matchChords5.Any() == false) return ret; int numMatchChords5 = matchChords5.Count(); int numMatchChords6 = oChords6.Count(); ret.OriginalChords6 = oChords6.ToArray(); ret.StartTick = ticks.Down; ret.EndTick = ticks.Up; var checkStrings = new cmpNoteFunc( (n1, n2) => { return n1.NoteString != n2.NoteString; }); var checkData1 = new cmpNoteFunc( (n1, n2) => { return n1.NoteFretDown != n2.NoteFretDown; }); var checkLength = new cmpNoteFunc( (n1, n2) => { return Utility.IsCloseTick(n1.TickLength, n2.TickLength) == false; }); var checkNull = new cmpNoteFunc((a, b) => { return ((a == null) || (b == null)); }); var testBeat = new cmpChordFunc((co, cn) => { var ob32 = ProGuitarTrack.GetTempo(co.DownTick).SecondsPerThirtySecondNote; var ob = ProGuitarTrack.GetTempo(co.DownTick).SecondsPerQuarterNote; var nb = ProGuitarTrack.GetTempo(cn.DownTick).SecondsPerQuarterNote; var diff = Math.Abs(ob - nb); if (diff > ob32) { return false; } return true; }); var chordsEqual = new cmpChordFunc( (a, b) => { if (matchBeat && testBeat(a, b) == false) return false; for (int x = 0; x < 6; x++) { var an = a.Notes[x]; var bn = b.Notes[x]; if (an == null && bn == null) continue; if (checkNull(an, bn) || checkData1(an, bn) || checkStrings(an, bn) || (matchG5Lengths && checkLength(an, bn))) { return false; } } return true; }); var testSpacing = new matchFunc((mfmatch, mfmca) => { for (int y = 0; y < mfmca.Length - 1; y++) { var nc = mfmatch[y]; var oc = mfmca[y]; var timeTillNext5 = track5.TickToTime(mfmca[y + 1].DownTick) - track5.TickToTime(oc.UpTick); var timeTillNext52 = track5.TickToTime(mfmatch[y + 1].DownTick) - track5.TickToTime(nc.UpTick); var diff = Math.Abs(timeTillNext52 - timeTillNext5); double spb = ProGuitarTrack.GetTempo(oc.DownTick).SecondsPerThirtySecondNote; if (diff > spb) { return false; } } return true; }); var mca = matchChords5.ToArray(); var match = new GuitarChord[mca.Length]; var matches = new List<GuitarChord[]>(); for (int ci = 0; ci < chords5.Length - mca.Length; ci++) { for (int mc = 0; mc < mca.Length; mc++) { var cc = chords5[ci + mc]; if (cc.DownTick < mca[mca.Length - 1].UpTick && cc.UpTick > mca[0].DownTick) { break; } if (chordsEqual(cc, mca[mc])) { match[mc] = cc; if (mc == mca.Length - 1) { if (matchSpacing) { if (testSpacing(match, mca) == true) { matches.Add(match.ToArray()); ci += mca.Length - 1; } } else { matches.Add(match.ToArray()); ci += mca.Length - 1; } } } else { break; } } } var goodMatches = new List<GuitarChord[]>(); foreach (var m in matches) { var c6 = track6.Messages.Chords.GetBetweenTick(m.GetTickPair()).ToArray(); bool matching = true; if (replaceConfig.MatchLengths6) { if (c6.Length == oChords6.Length) { for (int x = 0; x < c6.Length; x++) { if (!Utility.IsCloseTick(c6[x].TickPair.TickLength, oChords6[x].TickPair.TickLength)) { matching = false; break; } } } else { matching = false; } } if (matching) { goodMatches.Add(c6); } } foreach (var m in goodMatches) { ret.Matches.Add(m); } return ret; }
MatchingCopyPattern FindMatchingCopyPattern(FindMatchingPatternConfig config, CopyPatternPreset replaceConfig = null) { MatchingCopyPattern ret = null; try { if (replaceConfig == null) { replaceConfig = GetNewCopyPatternPresetFromScreen(); } ret = internalFindMatchingCopyPattern(config, replaceConfig); if (ret == null) return ret; var matches = ret.Matches.ToArray(); ret.Matches.Clear(); matches.ToList().For((x, i) => matches[i] = x.SortTicks().ToArray()); if (config.FindNext && config.FindPrevious) { if (config.FirstMatchOnly) { ret.Matches.Add(matches.FirstOrDefault()); } else { foreach (var itm in matches) { ret.Matches.Add(itm); } } } else if (config.FindNext) { var next = matches.Where(n => n.GetMinTick() > SelectedChord.DownTick); if (next != null && next.Any()) { if (config.FirstMatchOnly) { ret.Matches.Add(next.FirstOrDefault()); } else { foreach (var itm in next) { ret.Matches.Add(itm); } } } } else if (config.FindPrevious) { var next = matches.Where(n => n.GetMinTick() < SelectedChord.DownTick); if (next != null && next.Any()) { if (config.FirstMatchOnly) { ret.Matches.Add(next.LastOrDefault()); } else { ret.Matches.AddRange(next); } } } } catch { } return ret; }