bluefireteam / audioplayers

A Flutter package to play multiple audio files simultaneously (Android/iOS/web/Linux/Windows/macOS)
https://pub.dartlang.org/packages/audioplayers
MIT License
1.98k stars 843 forks source link

Low latency is still high #398

Closed Noxxys closed 4 years ago

Noxxys commented 4 years ago

Hi, I'm using the AudioCache in an attempt to make a music instrument app, which uses assets that can be played simultaneously and with low latency. The problem is that the latency is very perceptible, sometimes up to half a second. I've also tested it on my Samsung Galaxy S10+ in release mode.

I'm using Flutter version 1.12.13+hotfix.5 and Audioplayers version 0.13.7.

Here's my code:

import 'package:audioplayers/audio_cache.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';

void main() => runApp(Xylophone());

class Xylophone extends StatefulWidget {
  @override
  _XylophoneState createState() => _XylophoneState();
}

class _XylophoneState extends State<Xylophone> {
  AudioCache audioPlayer;

  @override
  void initState() {
    super.initState();
    audioPlayer = AudioCache();

    var fileNames = [
      'note1.wav',
      'note2.wav',
      'note3.wav',
      'note4.wav',
      'note5.wav',
      'note6.wav',
      'note7.wav'
    ];

    audioPlayer.loadAll(fileNames);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: createKeys(),
          ),
        ),
      ),
    );
  }

  List<Widget> createKeys() {
    var colors = [
      Colors.red,
      Colors.orange,
      Colors.yellow,
      Colors.green,
      Colors.teal,
      Colors.blue,
      Colors.purple
    ];

    var widgets = <Widget>[];

    for (var i = 0; i < 7; i++) {
      widgets.add(createKey(colors[i], i + 1));
    }

    return widgets;
  }

  Widget createKey(MaterialColor color, int note) {
    return Expanded(
      child: Container(
        color: color,
        child: InkWell(
          enableFeedback: false,
          onTap: () {
            audioPlayer.play('note$note.wav', mode: PlayerMode.LOW_LATENCY);
          },
        ),
      ),
    );
  }
}
luanpotter commented 4 years ago

Flame provides a tool called AudioPool that might give some idea as how to improve latency: https://github.com/flame-engine/flame/blob/master/lib/audio_pool.dart

we use that in our games but even with regular AP instances we notice no major delay (at least for a game perspective, probably your real time instrument app requires even more perspective)

as an example, take a look at gravity runner using audiopools to play the coin sounds, it's pretty instantaneous as far as I can tell:

https://github.com/fireslime/gravitational_waves/blob/master/game/lib/game/audio.dart

Noxxys commented 4 years ago

I just discovered that the delay was caused by my bluetooth headset. When I use the phone's speakers, there's barely any perceptible delay. My apologies.