public void AddProperties() { firstPropIdx = props.PropertyCount; if (song.UsesFamiTrackerTempo) { if (patternIdx < 0) { famitrackerTempoPropIdx = props.AddNumericUpDown("Tempo :", song.FamitrackerTempo, 32, 255, TempoTooltip); // 0 famitrackerSpeedPropIdx = props.AddNumericUpDown("Speed :", song.FamitrackerSpeed, 1, 31, SpeedTooltip); // 1 } var notesPerBeat = patternIdx < 0 ? song.BeatLength : song.GetPatternBeatLength(patternIdx); var notesPerPattern = patternIdx < 0 ? song.PatternLength : song.GetPatternLength(patternIdx); var bpm = Song.ComputeFamiTrackerBPM(song.Project.PalMode, song.FamitrackerSpeed, song.FamitrackerTempo, notesPerBeat); notesPerBeatPropIdx = props.AddNumericUpDown("Notes per Beat :", notesPerBeat, 1, 256, NotesPerBeatTooltip); // 2 notesPerPatternPropIdx = props.AddNumericUpDown("Notes per Pattern :", notesPerPattern, 1, Pattern.MaxLength, NotesPerPatternTooltip); // 3 bpmLabelPropIdx = props.AddLabel("BPM :", bpm.ToString("n1"), false, BPMTooltip); // 4 props.ShowWarnings = true; UpdateWarnings(); } else { var noteLength = (patternIdx < 0 ? song.NoteLength : song.GetPatternNoteLength(patternIdx)); var notesPerBeat = (patternIdx < 0 ? song.BeatLength : song.GetPatternBeatLength(patternIdx)); var notesPerPattern = (patternIdx < 0 ? song.PatternLength : song.GetPatternLength(patternIdx)); var groove = (patternIdx < 0 ? song.Groove : song.GetPatternGroove(patternIdx)); tempoList = FamiStudioTempoUtils.GetAvailableTempos(song.Project.PalMode, notesPerBeat / noteLength); var tempoIndex = FamiStudioTempoUtils.FindTempoFromGroove(tempoList, groove); Debug.Assert(tempoIndex >= 0); tempoStrings = tempoList.Select(t => t.bpm.ToString("n1") + (t.groove.Length == 1 ? " *": "")).ToArray(); var grooveList = FamiStudioTempoUtils.GetAvailableGrooves(tempoList[tempoIndex].groove); var grooveIndex = Array.FindIndex(grooveList, g => Utils.CompareArrays(g, groove) == 0); Debug.Assert(grooveIndex >= 0); grooveStrings = grooveList.Select(g => string.Join("-", g)).ToArray(); famistudioBpmPropIdx = props.AddDropDownList("BPM : ", tempoStrings, tempoStrings[tempoIndex], BPMTooltip); // 0 notesPerBeatPropIdx = props.AddNumericUpDown("Notes per Beat : ", notesPerBeat / noteLength, 1, 256, NotesPerBeatTooltip); // 1 notesPerPatternPropIdx = props.AddNumericUpDown("Notes per Pattern : ", notesPerPattern / noteLength, 1, Pattern.MaxLength / noteLength, NotesPerPatternTooltip); // 2 framesPerNotePropIdx = props.AddLabel("Frames per Note :", noteLength.ToString(), false, FramesPerNoteTooltip); // 3 props.ShowWarnings = true; props.BeginAdvancedProperties(); groovePropIdx = props.AddDropDownList("Groove : ", grooveStrings, grooveStrings[grooveIndex], GrooveTooltip); // 4 groovePadPropIdx = props.AddDropDownList("Groove Padding : ", GroovePaddingType.Names, GroovePaddingType.Names[song.GroovePaddingMode], GroovePaddingTooltip); // 5 originalNoteLength = noteLength; originalNotesPerBeat = notesPerBeat; UpdateWarnings(); } }
private void ResetFamiStudioTempo() { if (!famitrackerTempo) { var newGroove = song.GetPatternGroove(playLocation.PatternIndex); var newGroovePadMode = song.GetPatternGroovePaddingMode(playLocation.PatternIndex); FamiStudioTempoUtils.ValidateGroove(newGroove); grooveIterator = new GrooveIterator(newGroove, newGroovePadMode); tempoEnvelope = FamiStudioTempoUtils.GetTempoEnvelope(newGroove, newGroovePadMode, song.Project.PalMode); tempoEnvelopeCounter = tempoEnvelope[0]; tempoEnvelopeIndex = 0; } }
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); } }