private void ExtendSongForLooping(Song song, int loopCount) { // For looping, we simply extend the song by copying pattern instances. if (loopCount > 1 && song.LoopPoint >= 0 && song.LoopPoint < song.Length) { var originalLength = song.Length; var loopSectionLength = originalLength - song.LoopPoint; song.SetLength(Math.Min(Song.MaxLength, originalLength + loopSectionLength * (loopCount - 1))); var srcPatIdx = song.LoopPoint; for (var i = originalLength; i < song.Length; i++) { foreach (var c in song.Channels) { c.PatternInstances[i] = c.PatternInstances[srcPatIdx]; } if (song.PatternHasCustomSettings(srcPatIdx)) { var customSettings = song.GetPatternCustomSettings(srcPatIdx); song.SetPatternCustomSettings(i, customSettings.patternLength, customSettings.beatLength, customSettings.groove, customSettings.groovePaddingMode); } if (++srcPatIdx >= originalLength) { srcPatIdx = song.LoopPoint; } } } }
protected void ApplyHaltEffect(Song s, Dictionary<Pattern, RowFxData[,]> patternFxData) { // Find the first Cxx effect and truncate the song. for (int p = 0; p < s.Length; p++) { for (int c = 0; c < s.Channels.Length; c++) { var pattern = s.Channels[c].PatternInstances[p]; var patternLength = s.GetPatternLength(p); if (patternFxData.TryGetValue(pattern, out var fxData)) { for (int i = 0; i < fxData.GetLength(0) && i < patternLength; i++) { for (int j = 0; j < fxData.GetLength(1); j++) { var fx = fxData[i, j]; if (fx.fx == Effect_Halt) { if (s.PatternHasCustomSettings(p)) s.GetPatternCustomSettings(p).patternLength = i + 1; else s.SetPatternCustomSettings(p, i + 1, s.BeatLength); s.SetLength(p + 1); s.SetLoopPoint(-1); return; } } } } } } }
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); }); } } }