Efficiently loading many short audio files for playback with just_audio

81 views Asked by At

I'm trying to use just_audio to play a series of chords from a list of ~60 samples (one note each). The chords are generated randomly, so I don't know exactly which notes will be played the next time, but I know that each of the notes will be played several times.

However, I'm not sure of the best practice to do this, while ensuring fluidity and reducing memory usage.

(This is my use case, but it could also apply for example to recurring sound effects in a game)

I tried these (assuming I have a list sampleName containing the name of all my samples) :

1. Preloading all sounds

// Load all samples in a list of AudioPlayers
var players = <AudioPlayer>[];
for (var i=0; i<60; i++) {
  players.add(AudioPlayer());
  await players[i].setAsset('assets/sounds/${sampleName[i]}');
}

// Generate a list of sample indices and play it
void playRandomChord() {
  var randomChord = [Random().nextInt(60), Random().nextInt(60), Random().nextInt(60)];
  players[randomChord[0]].play();
  players[randomChord[1]].play();
  players[randomChord[3]].play();
}

playRandomChord();

However, I have found that this was not very stable ; maybe too much memory usage even if my samples are short and in mp3 ?

2. Loading the samples as needed

// Create only 3 AudioPlayers
var player1 = AudioPlayer();
var player2 = AudioPlayer();
var player3 = AudioPlayer();

// Generate the needed indices, load the associated samples and play it
void playRandomChord() async {
  var randomChord = [Random().nextInt(60), Random().nextInt(60), Random().nextInt(60)];
  await player1.setAsset('assets/sounds/${sampleName[randomChord[0]]}');
  await player2.setAsset('assets/sounds/${sampleName[randomChord[1]]}');
  await player3.setAsset('assets/sounds/${sampleName[randomChord[2]]}');
  player1.play();
  player2.play();
  player3.play();
}

playRandomChord();

However, this doesn't seem optimal because it means reading the files from the assets everytime I need to play a chord.

3. Other alternatives I have considered

  • I could load once a large file that would contain all the sounds at specific times, and jump to the right timestamp with AudioPlayer.seek()
  • I could create AudioPlayers on the go, instead of having only 3 in the last example → load them in advance and cache them for repeated notes

Which is the right way to go with just_audio? Maybe something else entirely, with a Stream? In general, should there be a limited amount of AudioPlayers that load the right files as needed, or should there be one AudioPlayer by available sound?

0

There are 0 answers