flutter_nnnoiseless 1.1.0 copy "flutter_nnnoiseless: ^1.1.0" to clipboard
flutter_nnnoiseless: ^1.1.0 copied to clipboard

Recurrent neural network for audio noise reduction .

Flutter NNNoiseless #

Real-time and batch audio noise reduction for Flutter. A port of the nnnoiseless Rust crate (RNNoise), powered by Flutter Rust Bridge.

pub Buy Me A Coffee

Features #

  • Real-time denoising of raw PCM audio streams, such as microphone input
  • Voice activity detection (VAD): a speech probability for every 10ms frame
  • Batch denoising of WAV files (16/24/32-bit int and 32-bit float)
  • Multiple concurrent sessions, each with fully isolated state
  • Built-in streaming resampling: feed any sample rate, get the same rate back
  • Adjustable suppression strength via a dry/wet mix parameter
  • No Rust toolchain required: prebuilt, signed native libraries are downloaded automatically at build time

Supported platforms #

Platform Supported Minimum version
Android SDK 23
iOS 11.0
macOS 10.15
Windows Windows 10
Linux In progress -

Requires Flutter 3.0.0 or higher.

Installation #

flutter pub add flutter_nnnoiseless

No further setup is needed in most cases. If a prebuilt binary is not available for your platform, the build falls back to compiling from source, which requires a Rust installation.

Usage #

Real-time denoising #

Create a NoiselessSession per audio stream. Each session owns its own denoiser state, so multiple sessions can run concurrently and nothing leaks between recordings.

The simplest way is to pipe a raw 16-bit PCM mono stream (for example from the record package) through the session's transformer:

final session = await NoiselessSession.create(sampleRate: 48000);

micStream.transform(session.transformer).listen(playOrSave);

Alternatively, process chunks yourself:

final result = await session.process(chunk);
save(result.audio); // denoised PCM at your sample rate

At the end of a recording:

final tail = await session.flush(); // drain buffered audio
await session.reset();              // reuse for the next recording...
session.dispose();                  // ...or release it

Sample rates other than 48000Hz are resampled internally and the denoised audio is returned at your input rate. The wet parameter of NoiselessSession.create (0.0 to 1.0) controls how aggressive the suppression is.

Voice activity detection #

process returns the RNNoise speech probability for every 10ms frame:

final result = await session.process(chunk);

print(result.voiceProbability);   // 0.0 to 1.0, max over the chunk
print(result.voiceProbabilities); // per-frame values

if (result.isVoice()) {
  showSpeakingIndicator();
}

Denoising a file #

await Noiseless.instance.denoiseFile(
  inputPathStr: 'assets/noise.wav',
  outputPathStr: 'assets/output.wav',
);

Input can be 16/24/32-bit int or 32-bit float WAV at any sample rate. The output is written as 16-bit WAV at the input's sample rate.

Saving PCM output as WAV #

await Noiseless.instance.pcmToWav(
  pcmData: denoisedBytes,
  outputPath: '/path/to/output', // '.wav' is appended automatically
  sampleRate: 48000,
);

How it works #

The heavy lifting is done in Rust by nnnoiseless, a rewrite of the RNNoise recurrent neural network. Audio is processed in 480-sample frames at 48kHz; other sample rates are converted on the fly with a streaming resampler, so chunk boundaries stay artifact-free.

Native libraries for each platform are built in CI, signed, and attached to GitHub Releases. At build time cargokit downloads the binary for your target, verifies its signature, and links it into your app. If no prebuilt binary matches, it compiles the crate locally instead.

Example #

The example app records from the microphone, denoises the stream in real time, logs the voice probability, and saves both the raw and denoised audio as WAV files for comparison.

License #

Distributed under the LGPL-3.0 license. See LICENSE for details.