flutterflutter-dependenciesaudio-playermetronome

Flutter Audioplayers sound plays with delay


I'd like to write a metronome app in Flutter using the metronome class from quiver async and the audioplayers package. However, the click sound from the audioplayer always plays delayed. Sometimes there are several bars without sound, followed by a bar where all missed clicks are played at once. It sounds like the metronome is accelerating, deccelerating or pausing randomly. The timing is a lot better when using

SystemSound.play(SystemSoundType.click);

instead of the Audioplayer (allthough the sound is still slightly delayed at higher tempos).

Here is the relevant code snippet from the FloatingActionButton widget (when pressed, the _play function is executed; the _cacheAudio function is executed earlier):

import 'package:audioplayers/audio_cache.dart';
import 'package:quiver/async.dart';

AudioCache _cache = AudioCache();
int _beatCounter;
int _millisecondsPerTick;
var _timer;

void _cacheAudio() {
  _cache.load('Metronome.wav');
  _cache.load('MetronomeUp.wav');
}

void _play() {
  _millisecondsPerTick = 60000 ~/ bpm;
  _beatCounter = 1;
  _timer = new Metronome.epoch(new Duration(milliseconds: _millisecondsPerTick))
      .listen(_tick);
}

void _tick(DateTime t) async {
  if (_beatCounter > 4) {
    _beatCounter = 1;
  }
  if (_beatCounter == 1) {
    _cache.play('MetronomeUp.wav');
  } else {
    _cache.play('Metronome.wav');
  }
  _beatCounter++;
}

What can I do so that the sounds play exactly in the desired interval?

Thanks for your help.


Solution

  • In case this helps someone: I solved the problem by switching to the soundpool package which caches audio tracks in memory and thus minimizes latency; I also replaced the quiver Metronome with a regular dart Stream.

    There are still some slight latency issues, but it works well enough for my purposes. Here is the relevant code from the finished app.