NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #1051 most downloaded on pub.dev
A low-level audio plugin for Flutter, mainly meant for games and immersive apps. Based on the SoLoud (C++) audio engine.
Last release 5 days ago
02 Oct 2026
Ships on a steady schedule
a new release about every 1 weeks
Nearly every release is documented
notes for 59 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
3 years old
119 releases · first in 2023
One column per quarter.
iOS fix: update build_iOS.sh to make fat libraries #315. Thanks to @kumamotone
win fix: compilation error #309
fix sample rate detection for Opus and Vorbis audio streams
use of dr_mp3.h instead of minimp3 for streaming MP3
fix seek a buffer stream actually seeks at half the wanted position #296
fixed stuttering with MP3 streams #301
- fix win: fix build error #292
Deprecate BufferType.opus in favor of BufferType.auto
web_radio.dart example to demonstrate how to receive an audio stream (ie, an icecast stream) and then add the audio chunks to BufferStreamBufferType.auto to auto detect ogg/opus/vorbis/mp3 streamsBufferType.opus in favor of BufferType.autoicy-metaint (obtained from the header of the online stream) before adding audio chunks to the BufferStream. New metadata is notified by the onMetadata callback of setBufferStreamfeat: allow to specify NO_OPUS_OGG_LIBS in Android build config #282. Thanks to @ekuleshov
Nothing published for this version
macos fix: abseil not found when using this plugin with some other native plugins like firebase #280. Thanks to @jochy.
abseil not found when using this plugin with some other native plugins like firebase #280. Thanks to @jochy.ios fix: abseil not found when using this plugin with some other native plugins like firebase #271
abseil not found when using this plugin with some other native plugins like firebase #271fix 16 KB native library alignment on Android #248
seek method was causing inconsistent behavior when using BufferStream in BufferingType.released mode. It is now supported in BufferingType.preserved mode.OGG is now also supported using readSamplesFrom* methods.
readSamplesFrom* methods.fix #104, #245, #249. It is now possible to use a 3rd party plugin like audio_session to manage audio context.
audio_session to manage audio context.example/lib/audio_context/audio_context.dart.Nothing published for this version
added getStreamTimeConsumed() to get the time consumed by a buffer stream of kind BufferingType.released. Since the position of this kind of stream is
getStreamTimeConsumed() to get the time consumed by a buffer stream of kind BufferingType.released. Since the position of this kind of stream is always 0, this method is useful to know the time already played.buffer_stream/simple_noise_stream.dart example.fix: Loading the same AudioSource twice (in parallel) crashes #247
fix: Setting pan doesn't cancel pan oscillation #239
fix: disposeSource crash on Android #240
disposeSource crash on Android #240fix: adding audio data to an unended BufferStream throws error #235
docs: clarify docs regarding semitones and shift parameters of the pitchShiftFilter #233 by @bemain
semitones and shift parameters of the pitchShiftFilter #233 by @bemainreadSamplesFrom*() works againreadSamplesFrom*fix: passing a group handle to seek() throws error #228
seek() throws error #228listPlaybackDevices fails to retrieve devices when the device prefix contains Chinese characters #227 by @WHYBBEfix: when the speed is changed, after seeking, the getPosition() returns the wrong position #223
getPosition() returns the wrong position #223fix building issue with XCode 16.3 #217
fix listPlaybackDevices on Web #214
listPlaybackDevices on Web #214maxActiveVoiceCountReached exception with Level.INFO #212enhanced documentation clarity and organization by moving it to the dedicated flutter_soloud_docs repo. Powered by docs.page from Invertase and can be
fix: Sounds seemingly "backed up in a queue" when playing too many at once #204
when calling AudioData.getAudioData is now possible to check if the audio data is the same as before. Useful to visualize waveforms. This is because A
AudioData.getAudioData is now possible to check if the audio data is the same as before. Useful to visualize waveforms. This is because AudioData.getAudioData returns the current data in the buffer and if it is called before the buffer has been updated, it will return the previous data.resetBufferStream method to SoLoud. It happens that when playing a stream, maybe from the web, it is necessary to change it to another source. The player continues to play the already added audio data to the buffer. This method can be used to reset the buffer and start with the new audio data.it's now possible to choose to not link opus and ogg libraries (see NO_OPUS_OGG_LIBS.md). Fix for #191 and #192.
NO_OPUS_OGG_LIBS.md). Fix for #191 and #192.fixed crash when trying to play a sound after deactivating its active filter #189
fix: error while calling listPlaybackDevices() #186.
breaking change: splitted [maxBufferSize] to [maxBufferSizeBytes] and [maxBufferSizeDuration] in SoLoud.setBufferStream. This gives the user a way to…
BufferStream now supports 2 type of buffering:
BufferingType.preserved (default): preserve the data already in the buffer while playing.BufferingType.released: free the memory of the already played data for longer playback.SoLoud.setBufferStream. This gives the user a way to choose the maximum buffer size using bytes or time.initialized getter in favor of isInitializedtimeout parameter in SoLoud.init.filter_params.dart.frequency default parameter #179isInitialized returns false on MacOS after the engine starts with no error #177loadMem will crash the application #174.fix: clicks and pops when changing waveform frequency #156.
Limiter and Compressor filters (see example/lib/filters/).s8 signed 8 bits16le signed 16 bit little endians32le signed 32 bit little endianf32le float 32 bit little endianopus Opus codec compressed audio with Ogg container. Useful for streaming from the Web (ie using OpenAI APIs).LoadMode.disk on the Web platform, which in some cases caused the allInstancesFinished event to not be emitted.index.html:<script src="assets/packages/flutter_soloud/web/libflutter_soloud_plugin.js" defer></script>
<script src="assets/packages/flutter_soloud/web/init_module.dart.js" defer></script>
added listPlaybackDevices to get all the OS output devices available.
listPlaybackDevices to get all the OS output devices available.deviceId parameter to the init() method. You can choose which device is delegated to output the audio.changeDevice method to change the output playback device on-the-fly.fixed a bug that caused an error when loading a sound more than twice.
added readSamplesFrom*() methods to read N audio data within a time range from a file or memory #75. Example in example/lib/wave_data/wave_data.dart.
readSamplesFrom*() methods to read N audio data within a time range from a file or memory #75. Example in example/lib/wave_data/wave_data.dart.fixed waveform generation, which somehow oscillates frequencies after some time #129.
added compatibility for Web platform in the pubspec.
bug fix when loading multiple audio files asynchronously.
added bool isActive and int index getters to filters.
bool isActive and int index getters to filters.timeStretch() method to the single pitchshift filter.added support for the Web platform.
getPan(), setPan() and setPanAbsolute().loadMem() to read the given audio file bytes buffer (not RAW data). Useful for the Web platform.getFilterParamNames().AudioData class to manage audio samples.SoLoud.filters and AudioSource.filters to use global and single sound filters.Fixed wrong exception raised by setVolume() when a handle is no more valid.
setVolume() when a handle is no more valid.- Fix init error on hot restart.
A giant leap forward from the previous version (many thanks to Filip Hráček).
A giant leap forward from the previous version (many thanks to Filip Hráček).
Major changes to API. There are quick fixes (dart fix) to automatically rename many changed APIs.
SoLoud methods now throw instead of returning a PlayerErrors object.
added getActiveVoiceCount() to get concurrent sounds that are playing at the moment.
added countAudioSource() to get concurrent sounds that are playing a specific audio source.
added getVoiceCount() to get the number of voices the application has told SoLoud to play.
added getMaxActiveVoiceCount() to get the current maximum active voice count.
added setMaxActiveVoiceCount() to set the current maximum active voice count.
added setProtectVoice() and getProtectVoice() to get/set the protect voice flag.
SoLoud.activeSounds is now an Iterable instead of a List.
All time-related parameters and return values are now Duration type.
Before, they were double.
Added new (experimental) AudioSource.allInstancesFinished stream.
This can be used to more easily await times when it's safe to dispose
the sound. For example:
final source = soloud.loadAsset('...');
// Wait for the first time all the instances of the sound are finished
// (finished playing or were stopped with soloud.stop()).
source.allInstancesFinished.first.then(
// Dispose of the sound.
(_) => soloud.disposeSound(source)
);
soloud.play(source);
added looping and loopingStartAt properties to SoLoud.play() and SoLoud.play3d().
added SoLoud.getLooping() to retrieve the looping state of a sound.
added SoLoud.getLoopPoint() and SoLoud.setLoopPoint() to get and set the looping start position of a sound.
New methods SoLoud.loadAsset() and SoLoud.loadUrl() to load audio from assets and URLs, respectively.
added mode property to SoLoud.loadFile() and SoloudTools.loadFrom* to prevent to load the whole audio data into memory:
Switched from print() logging to using the standard package:logging.
See README.md to learn how to capture log messages and how to filter them.
The capture feature is on experimental stage to be fine-tuned in the near future. All methods related to audio capture have been extracted to a separate class. So now, there are two classes:
SoLoud for playing audioSoLoudCapture for capturing audioThe Web platform is a work in progress, stay tuned!
Switched LICENSE from Apache-2.0 to MIT.
getLoopPoint now returns Duration.
SoLoud.disposeSound to SoLoud.disposeSource.
Quick fix available.SoLoud.disposeAllSound to SoLoud.disposeAllSources.
Quick fix available.AudioSource.keys property.- some little fixes.
Deprecated shutdown(). Replaced with the synchronous deinit(). Quick fix available.
added getActiveVoiceCount() to get concurrent sounds that are playing at the moment.
added countAudioSource() to get concurrent sounds that are playing a specific audio source.
added getVoiceCount() to get the number of voices the application has told SoLoud to play.
added getMaxActiveVoiceCount() to get the current maximum active voice count.
added setMaxActiveVoiceCount() to set the current maximum active voice count.
added setProtectVoice() and getProtectVoice() to get/set the protect voice flag.
All time-related parameters and return values are now Duration type.
Before, they were double.
Fixed velocity computation bug in example/.
Renamed SoundEvent to SoundEventType. Quick fix available.
SoundProps.soundEvents is now a Stream, not a StreamController
SoundProps.soundEvents stream is now closed automatically when
SoLoud.disposeSound() is called.
SoLoud.activeSounds is now an Iterable instead of a List
(therefore, it cannot be modified from outside the package).
Renamed SoLoud.getFxParams to SoLoud.getFilterParameter.
This mimics the C++ API name.
Quick fix available.
Renamed SoLoud.setFxParams to SoLoud.setFilterParameter.
This mimics the C++ API name.
Quick fix available.
Renamed SoundProps to AudioSource. Quick fix available.
Added new (experimental) AudioSource.allInstancesFinished stream.
This can be used to more easily await times when it's safe to dispose
the sound. For example:
final source = soloud.loadAsset('...');
// Wait for the first time all the instances of the sound are finished
// (finished playing or were stopped with soloud.stop()).
source.allInstancesFinished.first.then(
// Dispose of the sound.
(_) => soloud.disposeSound(source)
);
soloud.play(source);
Deprecated shutdown(). Replaced with the synchronous deinit().
Quick fix available.
Renamed initialize() to init(), in order to come closer to the original
C++ API, and also to have a symmetry (init/deinit).
Quick fix available.
SoLoud methods now throw instead of returning a PlayerErrors object. This is a massive breaking change, but it makes the package API more idiomatic an…
NOTE: This version is much more breaking than the ones before it.
It might be worth it to first upgrade your code to 2.0.0-pre.1,
use the quick fixes to rename the methods, and only then upgrade
to 2.0.0-pre.2 and beyond.
SoLoud methods now throw instead of returning a PlayerErrors object.
This is a massive breaking change, but it makes the package API
more idiomatic and easier to use.
Before:
final ret = await SoLoud.play(sound);
if (ret.error != PlayerErrors.noError) {
print('Oh no! ${ret.error}');
} else {
print('Playing sound with new handle: ${ret.newHandle}');
}
After:
try {
final handle = await SoLoud.play(sound);
print('Playing sound with new handle: $handle');
} on SoLoudException catch (e) {
print('Oh no! $e');
}
These replace the old SoloudTools.loadFrom* methods (which are now deprecated).
looping and loopingStartAt properties to SoLoud.play() and SoLoud.play3d().SoLoud.getLooping() to retrieve the looping state of a sound.SoLoud.getLoopPoint() and SoLoud.setLoopPoint() to get and set the looping start position of a sound.SoLoud.loadAsset() and SoLoud.loadUrl() to load audio
from assets and URLs, respectively. These replace the old
SoloudTools.loadFrom* methods (which are now deprecated).
SoloudTools to SoLoudTools for consistency. (Quick fix available.)SoLoudTools.initSounds to SoLoudTools.createNotes for clarity.
(Quick fix available.)All fields of SoundProps marked final. This is a breaking change but unlikely to have an effect (as most users hopefully don't assign to these fields)…
bool SoLoud.getVisualizationEnabled() to get the current state of the visualization.mode property to SoLoud.loadFile() and SoloudTools.loadFrom* to prevent loading the whole audio data into memory:
print() logging to using the standard package:logging.
See README.md to learn how to capture log messages and how to filter
them.SoLoud.startIsolate() to SoLoud.initialize()SoLoud.stopIsolate() to SoLoud.shutdown()SoLoud.initEngine() (it shouldn't be called manually)@deprecated. There is a quick fix (dart fix)
to automatically rename them.SoLoud.instance.
Accessing it through SoLoud() is now deprecated.
SoLoud() with SoLoud.instance
in your code.SoLoud for playing audioSoLoudCapture for capturing audioSoLoud class is now an interface class.
This means you can implement it (e.g. for mocking in tests) but you can't
extend it. This reduces the
fragile base class problem
and makes the API easier to evolve.SoLoud.initialized (returns a future, safe to check during initialization)
SoLoud.audioEvents and waiting for
the isolateStarted event.SoLoud.isInitialized (returns synchronously)isPlayerInited and isIsolateRunning())
are now deprecatedSoLoud.initialize() can now be safely called during engine
shutdown. It will wait for the engine to shut down before
re-initializing it. Same for SoLoud.shutdown(), which will
wait for the engine to initialize before shutting it down,
to avoid various race conditions.SoundHandle and SoundHash
instead of raw integers.
This prevents erroneously passing a sound handle as a sound hash,
for example. This is a breaking API change, but, in practice, shouldn't
be much of a problem, since these objects were always meant as
identifiers (to be taken from some API calls and put into others).SoundProps.handle renamed to SoundProps.handles (because it's a Set)
and also disallowed modifying it from outside the package.SoundProps marked final. This is a breaking change
but unlikely to have an effect (as most users hopefully don't assign
to these fields).updated mp3, flac and wav decoders
fixed compilation on Windows
fixed compilation on Windows
fixed compilation on iOS and macOS
waveform example page updated with sound FXs
- added waveform generator - added a test page for waveform - added some tests in tests dir - miniaudio updated to v0.11.18
tests dirbreaking change: *Soloud().stopSound* has been renamed to *Soloud().disposeSound*
breaking change: Soloud().stopSound has been renamed to Soloud().disposeSound
SoloudLoadingTool.loadFromAssets()
added load sound tools:
added also a spin around example
- added 3D audio with example
Your coding agent can read these notes before it upgrades. Set up the MCP server →