- Implemented the algorithm according to the W3C Web Audio API Specification to compute FFT
- added
setFftDecibelRangeto set the decibel range for FFT magnitude normalization
- removed ".github" for the possible location to install skills
- Rename agent skills to hyphenated names for Zed compatibility. Thanks to @Kunstderfug #60
- Added agent skills:
# Install or update the skills in your project by running: dart run flutter_recorder:skills # To check whether installed skills are up to date without modifying any files: dart run flutter_recorder:skills --check
- breaking change: audio visualization overhaul: Replaced legacy FFT engine with SIMD-accelerated PFFFT, Blackman windowing, and miniaudio channel converter downmixing.
- Real-time audio visualization is now delivered via
Recorder.instance.audioVisualizationEventsstream yieldingAudioVisualizationDatawith mono (merged) and multi-channel support. - Added
setVisualizationEnabled,getVisualizationEnabled,setFftSmoothing,VisualizationKind, andVisualizationChannel. Replaced legacygetFft,getWave,getTexture, andgetTexture2Dpolling methods. - breaking change: build system migration to Dart build hooks (https://dart.dev/tools/hooks):
- Android, iOS, macOS, Linux and Windows native code is now compiled by
hook/build.dart(package:hooks+package:native_toolchain_c) instead of per-platform plumbing.
- Android, iOS, macOS, Linux and Windows native code is now compiled by
- breaking change: Bumped minimum iOS SDK to 15 and MacOS to 12.
- Add SpeexDSP Acoustic Echo Cancellation (
echoCancellationFilter) with configurable filter length and residual denoise suppression. - Add
setLoopbackfor zero-latency native duplex monitoring andfeedPlaybackDatafor external playback reference (e.g.flutter_soloudmixer capture). - Multi-Threaded WebAssembly (AudioWorklet):
- Added multi-threaded WASM build running audio capture on dedicated Web Audio
AudioWorklet/pthreadthreads. - Offloads audio capture, DSP filtering, and Opus encoding off the browser main thread for high-performance, glitch-free audio without UI jank.
- Added multi-threaded WASM build running audio capture on dedicated Web Audio
- Platform Hardware & Browser Input Presets:
- Added
IosInputPresetto configure Apple hardwareAVAudioSessionvoice processing (e.g.voiceCommunicationwith hardware AEC/AGC,unprocessedmeasurement mode). - Added
WebInputPresettoRecorder.instance.init()to configure browsergetUserMediapreprocessing constraints (unprocessed,voiceCommunication,voiceRecognition,noiseSuppression,echoCancellation) at stream initialization time.
- Added
- Microphone & Device State Notifications:
- Added
Recorder.instance.deviceNotificationEventsbroadcast stream yieldingRecorderDeviceNotificationevents (started,stopped,rerouted,interruptionBegan,interruptionEnded,unlocked). - Enables listening to hardware mic state changes, audio route updates, device disconnections, and OS audio interruptions (e.g. incoming calls or Siri on iOS).
- Added
- fix Android OpenSL capture shutdown blocking indefinitely when a stalled input queue cannot drain #51. Thanks to @Avejack #52
- fix native capture callbacks reading non-float PCM input with float sample width, which could overrun guarded Android AAudio buffers. Thanks to @Avejack #52
- android fix: opus lib not found #49
- add Opus encoding for
startRecording(Ogg Opus) andstartStreamingData(Opus packets) through the newRecordingFormatandStreamingFormatenums. - build: vendored Ogg/Opus libraries renamed to
libfr_ogg/libfr_opuson Android to avoid conflicts with other plugins such asflutter_soloud. - build: macOS now uses project-specific vendored static libraries; iOS uses vendored XCFrameworks to avoid CocoaPods symbol collisions.
- build: updated WASM compile script to support Ogg/Opus sources and avoid picking up host macOS/iOS SDK headers.
- improve native Auto Gain with stateful RMS tracking, noise-floor gating, headroom limiting, PCM-safe clipping, and runtime telemetry #46. Thanks to @Avejack.
- add Auto Gain
noiseFloorDbandheadroomDbparameters plus read-only metrics for current gain, input RMS, output peak, limiter counts, and last callback frame count #46. Thanks to @Avejack.
- add Android input preset selection for recorder initialization #45. Thanks to @Avejack
- fix compilation issue on macOS #43
- fix issue when using together with flutter_soloud
- updated loopback example using audio_session
- miniaudio backend updated
- fix: macOS cross-compilation #39 by @Vild
- fix building issue with XCode 16.3 #32
- fix:
listPlaybackDevicesfails to retrieve devices when the device prefix contains Chinese characters #35 by @WHYBBE - fix: some legitimate paths are unavailable on Windows #38 by @WHYBBE
- 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 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.
- better FFT data for a better visualization.
- added getTexture and a check for all get* methods to know if the current data is the same audio data computed previously.
- better FFT data
- update WASM lib
- resolved conflicts with flutter_soloud #25
- detailed exception when passing an invalid file name to
startRecording#23 - removed deprecated
dart:js_util
- fixed choppy PCM playback on macOS #18.
- fix
startRecordingempty path on the web
- fixed mic permission iOS example
- fixed
listCaptureDeviceswhen there are not input devices - update doc
- added
autoGainfilter - breaking changes:
- the
initmethod is now async FilterTyperenamed toRecorderFilterType- an additional script must be added for the web platform. Now it looks like:
<script src="assets/packages/flutter_recorder/web/libflutter_recorder_plugin.js" defer></script> <script src="assets/packages/flutter_recorder/web/init_recorder_module.dart.js" defer></script> - the
- fix: the stop was instead einit the device
- fix: removed dialog when stopping stream in the example
- breaking changes:
- renamed
startListentostart - renamed
stopListentostop - renamed
isDeviceStartedListentoisDeviceStarted
- renamed