flutter_pcm_sound 3.2.5
flutter_pcm_sound: ^3.2.5 copied to clipboard
Send real-time PCM audio (16-bit integer) to your device speakers
Send real-time PCM audio (16-bit integer) to your device speakers, from your Flutter app!
No Dependencies #
FlutterPcmSound has zero dependencies besides Flutter, Android, iOS, and MacOS themselves.
Web #
Web support is available on this fork by @keyur2maru
Not for Audio Files #
Unlike other plugins, flutter_pcm_sound does not use audio files (For example: sound_pool).
Instead, flutter_pcm_sound is for apps that generate audio in realtime a few milliseconds before you hear it. For example, using dart_melty_soundfont.
Callback Based, For Real-Time Audio #
In contrast to raw_sound, FlutterPcmSound uses a callback setFeedCallback to signal when to feed more samples.
You can lower the feed threshold using setFeedThreshold to achieve real time audio, or increase it to have a cushy buffer.
Event Based Feeding #
Your feed callback is invoked once for each of these events:
- Low-buffer event – when the number of buffered frames falls below the threshold set with
setFeedThreshold. - Zero event – when the buffer is fully drained (
remainingFrames == 0).
Note: once means once per feed() — every time you feed new data, it allows the plugin to trigger another low-buffer or zero event.
🧠 Why event-based feeding? You might wonder why
flutter_pcm_sounddoesn’t just use a timer to request more samples every few milliseconds like every other audio library. The problem is asynchronous timing. Whether the timer runs on the Dart or native side, your feed callbacks get bunched up behind Dart UI work, leading to audio delays, pops, & excess work, and means it's not really a reliable "timer". Event-based better reflects the reality of Dart timing, and is more efficient.
💡 Tip: You can still emulate timer-style feeding by setting a very large feed threshold so that
flutter_pcm_soundcalls your feed callback regularly. From there, you can also optionally run a Dart-sideTimer.periodic(...)orTickerand estimateremainingFramesfrom your last callback + the elapsed time since it fired.
One-Pedal Driving #
To play audio, just keep calling feed.
To stop audio, just stop calling feed.
💡 How to think about it: In a traditional sound library you’d call
start(), which begins invoking your feed callback, and later callstop()to end it.flutter_pcm_soundworks almost the same way — you can still call thestart()convenience function if you want. The difference is that you don’t need an explicitstop(): if you stop feeding samples,flutter_pcm_soundwill naturally stop invoking your feed callback once the buffer runs out. When that happens, your callback will seeremainingFrames = 0, which indicates playback has ended. This is conserves power and CPU performance.
Is Playing? #
When your feed callback hits remainingFrames=0 you know playing stopped.
Usage #
// for testing purposes, a C-Major scale
MajorScale scale = MajorScale(sampleRate: 44100, noteDuration: 0.25);
// invoked whenever we need to feed more samples to the platform
void onFeed(int remainingFrames) async {
// you could use 'remainingFrames' to feed very precisely.
// But here we just load a few thousand samples everytime we run low.
List<int> frame = scale.generate(periods: 20);
await FlutterPcmSound.feed(PcmArrayInt16.fromList(frame));
}
await FlutterPcmSound.setup(sampleRate: 44100, channelCount: 1);
await FlutterPcmSound.setFeedThreshold(8000);
FlutterPcmSound.setFeedCallback(onFeed);
FlutterPcmSound.start(); // for convenience. Equivalent to calling onFeed(0);
⭐ Stars ⭐ #
Please star this repo & on pub.dev. We all benefit from having a larger community.
Example App #
Enable the platforms you need.
cd ./example
flutter config --enable-macos-desktop
flutter config --enable-android
flutter config --enable-ios
flutter create .
flutter run