private void SmoothFamiStudioScrolling(VideoFrameMetadata[] frames, Song song) { var patternIndices = new int[frames.Length]; var absoluteNoteIndices = new float[frames.Length]; // Keep copy of original pattern/notes. for (int i = 0; i < frames.Length; i++) { patternIndices[i] = frames[i].playPattern; absoluteNoteIndices[i] = song.GetPatternStartAbsoluteNoteIndex(frames[i].playPattern, (int)frames[i].playNote); } // Do moving average to smooth the movement. for (int i = 0; i < frames.Length; i++) { var averageSize = (Utils.Max(song.GetPatternGroove(patternIndices[i])) + 1) / 2; averageSize = Math.Min(averageSize, i); averageSize = Math.Min(averageSize, absoluteNoteIndices.Length - i - 1); var sum = 0.0f; var cnt = 0; for (int j = i - averageSize; j <= i + averageSize; j++) { if (j >= 0 && j < absoluteNoteIndices.Length) { sum += absoluteNoteIndices[j]; cnt++; } } sum /= cnt; frames[i].playPattern = song.PatternIndexFromAbsoluteNoteIndex((int)sum); frames[i].playNote = sum - song.GetPatternStartAbsoluteNoteIndex(frames[i].playPattern); } }