syncClipsToBeats method

int syncClipsToBeats({
  1. required double bpm,
  2. double strength = 1.0,
  3. Duration firstBeat = Duration.zero,
})

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;
}