public void ApplyAsync(bool custom, Action callback) { if (song.UsesFamiTrackerTempo) { if (patternIdx == -1) { if (famitrackerTempoPropIdx >= 0) { song.FamitrackerTempo = props.GetPropertyValue <int>(famitrackerTempoPropIdx); song.FamitrackerSpeed = props.GetPropertyValue <int>(famitrackerSpeedPropIdx); } song.SetBeatLength(props.GetPropertyValue <int>(notesPerBeatPropIdx)); song.SetDefaultPatternLength(props.GetPropertyValue <int>(notesPerPatternPropIdx)); } else { for (int i = minPatternIdx; i <= maxPatternIdx; i++) { var beatLength = props.GetPropertyValue <int>(notesPerBeatPropIdx); var patternLength = props.GetPropertyValue <int>(notesPerPatternPropIdx); if (custom) { song.SetPatternCustomSettings(i, patternLength, beatLength); } else { song.ClearPatternCustomSettings(i); } } } FinishApply(callback); } else { var tempoIndex = Array.IndexOf(tempoStrings, props.GetPropertyValue <string>(famistudioBpmPropIdx)); var tempoInfo = tempoList[tempoIndex]; var beatLength = props.GetPropertyValue <int>(notesPerBeatPropIdx); var patternLength = props.GetPropertyValue <int>(notesPerPatternPropIdx); var noteLength = Utils.Min(tempoInfo.groove); var grooveIndex = Array.IndexOf(grooveStrings, props.GetPropertyValue <string>(groovePropIdx)); var groovePadMode = GroovePaddingType.GetValueForName(props.GetPropertyValue <string>(groovePadPropIdx)); var grooveList = FamiStudioTempoUtils.GetAvailableGrooves(tempoInfo.groove); var groove = grooveList[grooveIndex]; props.UpdateIntegerRange(notesPerPatternPropIdx, 1, Pattern.MaxLength / noteLength); props.SetLabelText(framesPerNotePropIdx, noteLength.ToString()); if (patternIdx == -1) { ShowConvertTempoDialogAsync(noteLength != originalNoteLength, (c) => { song.ChangeFamiStudioTempoGroove(groove, c); song.SetBeatLength(beatLength * song.NoteLength); song.SetDefaultPatternLength(patternLength * song.NoteLength); song.SetGroovePaddingMode(groovePadMode); FinishApply(callback); }); } else { var actualNoteLength = song.NoteLength; var actualPatternLength = song.PatternLength; var actualBeatLength = song.BeatLength; if (custom) { actualNoteLength = noteLength; actualBeatLength = beatLength * noteLength; actualPatternLength = patternLength * noteLength; } var patternsToResize = new List <int>(); for (int i = minPatternIdx; i <= maxPatternIdx; i++) { if (actualNoteLength != song.GetPatternNoteLength(patternIdx)) { patternsToResize.Add(i); } } ShowConvertTempoDialogAsync(patternsToResize.Count > 0, (c) => { if (c) { foreach (var p in patternsToResize) { song.ResizePatternNotes(p, actualNoteLength); } } for (int i = minPatternIdx; i <= maxPatternIdx; i++) { if (custom) { song.SetPatternCustomSettings(i, actualPatternLength, actualBeatLength, groove, groovePadMode); } else { song.ClearPatternCustomSettings(i); } } FinishApply(callback); }); } } }