drain method

MirrorDrain drain(
  1. int writeCursor, {
  2. int? maxFrames,
})

Copy out everything readable and advance the read cursor.

writeCursor MUST come from an atomic (acquire) load by the caller — the samples it advertises are only guaranteed visible through that load.

Implementation

MirrorDrain drain(int writeCursor, {int? maxFrames}) {
  var n = available(writeCursor);
  if (maxFrames != null && maxFrames >= 0 && n > maxFrames) n = maxFrames;

  final totalOverrun = header[MirrorHeader.overrunFrames];
  final newOverrun = (totalOverrun - _lastOverrun) & 0xFFFFFFFF;
  _lastOverrun = totalOverrun;

  if (n == 0) return MirrorDrain(Float32List(0), newOverrun);

  final r = header[MirrorHeader.readCursor];
  final off = r % capacityFrames;
  final first = (off + n > capacityFrames) ? capacityFrames - off : n;

  final out = Float32List(n * channels);
  out.setRange(0, first * channels, samples, off * channels);
  if (first < n) {
    out.setRange(first * channels, n * channels, samples, 0);
  }

  header[MirrorHeader.readCursor] = (r + n) & 0xFFFFFFFF;
  return MirrorDrain(out, newOverrun);
}