syncClipsToBeats method
Cuts the clips on the beat grid of bpm.
Beats are laid out in project time from firstBeat (the music track's
first downbeat). Every strength beats a cut is made, skipping cuts
that would leave a sliver shorter than 200ms. All cuts are one undo
step. Returns the number of cuts made.
Implementation
int syncClipsToBeats({
required double bpm,
double strength = 1.0,
Duration firstBeat = Duration.zero,
}) {
if (bpm <= 0 || clips.isEmpty) return 0;
final beatMs = (60000 / bpm) * strength.clamp(0.25, 8.0);
if (beatMs < 150) return 0;
final total = totalDuration;
const minGap = Duration(milliseconds: 200);
final beatTimes = <Duration>[];
for (var t = firstBeat.inMilliseconds.toDouble();
t < total.inMilliseconds;
t += beatMs) {
if (t > 0) beatTimes.add(Duration(milliseconds: t.round()));
}
// Cut from the end backwards: earlier clips keep their project offsets.
var cuts = 0;
for (final beat in beatTimes.reversed) {
final index = clipIndexAt(beat);
if (index == -1) continue;
final start = clipStartTime(index);
final local = beat - start;
final length = clips[index].effectiveDuration;
if (local < minGap || length - local < minGap) continue;
final before = clips.length;
splitClip(index, local, record: false);
if (clips.length > before) cuts++;
}
if (cuts > 0) {
_saveState();
notifyListeners();
}
return cuts;
}