flutter_tiny_wavpack_decoder 1.0.4 copy "flutter_tiny_wavpack_decoder: ^1.0.4" to clipboard
flutter_tiny_wavpack_decoder: ^1.0.4 copied to clipboard

Decode WavPack (.wv) audio to PCM .wav on-device via the tiny dependency-free WavPack decoder over Dart FFI. Android, iOS, macOS, Linux, Windows.

flutter_tiny_wavpack_decoder #

pub package CI License: MIT Sponsor

A Flutter plugin that decodes WavPack (.wv) audio files to PCM .wav files on-device, powered by the tiny, dependency-free WavPack 4.40 "tiny decoder" C library called directly through dart:ffi.

It is the Flutter counterpart of react-native-tiny-wavpack-decoder and shares the exact same, unmodified C decoder.

Features #

  • Decode .wv to .wav (PCM, canonical 44-byte header) fully on-device.
  • Live decode progress callback reporting values from 0.0 to 1.0.
  • Output bit depth selection: 8, 16, 24, or 32 bits per sample.
  • Optional maxSamples cap for partial decodes.
  • Decoding runs in a worker isolate, so the UI thread never blocks.
  • Pure dart:ffi: no method channels and no platform bridge code.
  • Concurrent calls are safe; decodes are automatically serialized.

Platform support #

Android iOS macOS Linux Windows
Yes Yes Yes Yes Yes

Requirements #

  • Flutter 3.27.0 or newer.
  • Dart SDK 3.9.0 or newer.

Installation #

flutter pub add flutter_tiny_wavpack_decoder

Usage #

import 'package:flutter_tiny_wavpack_decoder/flutter_tiny_wavpack_decoder.dart';

final decoder = TinyWavpackDecoder();

try {
  await decoder.decode(
    inputPath: '/path/to/audio.wv',
    outputPath: '/path/to/audio.wav',
    // Optional:
    bitsPerSample: 16, // 8, 16 (default), 24, or 32
    maxSamples: -1,    // -1 (default) decodes the whole file
    onProgress: (progress) {
      print('Decoding: ${(progress * 100).toStringAsFixed(0)}%');
    },
  );
  print('Done');
} on WavpackDecodeException catch (e) {
  print('Decode failed: ${e.message}');
}

See the example/ app for a complete UI with a progress bar.

Testing your own code #

The TinyWavpackDecoder constructor accepts a custom NativeDecodeRunner, so you can fake the native layer in widget and unit tests without loading any native library:

class FakeRunner implements NativeDecodeRunner {
  @override
  Future<NativeDecodeResult> run(
    NativeDecodeRequest request,
    void Function(double) onProgress,
  ) async {
    onProgress(1.0);
    return const NativeDecodeResult(success: true, error: '');
  }
}

final decoder = TinyWavpackDecoder(runner: FakeRunner());

API #

TinyWavpackDecoder.decode(...) #

Parameter Type Default Description
inputPath String required Path of the .wv file to decode.
outputPath String required Path of the .wav file to write (overwritten if present).
maxSamples int -1 Max samples per channel to decode; -1 decodes the entire file.
bitsPerSample int 16 Output bit depth: 8, 16, 24, or 32.
onProgress void Function(double)? null Progress callback on the caller's isolate.

Returns a Future<void> that completes once the WAV file is fully written.

Invalid bitsPerSample or maxSamples throw ArgumentError immediately. Runtime failures (missing input, invalid or corrupt WavPack data, CRC errors, unwritable output) throw WavpackDecodeException carrying the native decoder's message.

Progress values are strictly increasing within the range 0.0 to 1.0, a final 1.0 is always delivered on success, and no callback fires after the returned future completes. Granularity is one callback per 4096 decoded frames.

Because the bundled C decoder keeps static state and is not reentrant, all decodes in the process run through one queue. Concurrent decode() calls are safe but execute one at a time.

Limitations #

Inherited from the WavPack 4.40 tiny decoder (see src/tiny-wavpack/lib/readme.txt):

  • Only the first two channels of multichannel files are decoded.
  • No correction (.wvc) file support; plain lossy or lossless .wv only.
  • WavPack stream versions 4.2 to 4.10 only (no pre-4.0 files).
  • Floating-point audio is returned clipped to 24-bit integer data.
  • Output WAV is limited to less than 4 GiB (32-bit RIFF sizes).

Development #

# Run the pure-Dart unit tests (no native build needed):
flutter test test/unit

# Build the native library for the host, then run the full suite including
# the real-C integration tests (golden byte-exact round-trip, error paths):
tool/build_host_lib.sh
flutter test

# Run the example on desktop:
cd example && flutter run -d macos   # or -d linux / -d windows

The C sources under src/tiny-wavpack/ are vendored byte-identical from the original project and are never modified; see src/tiny-wavpack/UPSTREAM.md.

Releasing #

Releases are fully automated from GitHub Actions using Conventional Commits. There is no manual step: just merge commits to main.

  • .github/workflows/release.yml runs tool/release.dart on every push to main. It reads the commits since the last tag and decides the bump (feat -> minor, fix/perf -> patch, !/BREAKING CHANGE -> major; anything else releases nothing).
  • When a release is warranted it bumps pubspec.yaml, prepends a CHANGELOG.md section, commits chore(release): vX.Y.Z, and pushes the vX.Y.Z tag.
  • The tag push triggers .github/workflows/publish.yml, which publishes to pub.dev over OIDC. The publish job skips a version already on pub.dev, so it is idempotent.

One-time setup:

  • Add a repository secret RELEASE_TOKEN, a Personal Access Token with contents: write. It pushes the tag so the tag push can trigger publishing (a tag pushed with the default GITHUB_TOKEN does not trigger other workflows). Until the secret exists, release.yml stays green and idle.
  • Enable automated publishing on pub.dev (package Admin > Automated publishing > GitHub Actions, tag pattern v{{version}}). The very first release is published manually with dart pub publish.

Credits #

License #

MIT (c) Jairaj Jangle. The bundled WavPack tiny decoder is BSD-licensed (see THIRD_PARTY_LICENSES.md).

Support the project #

Paypal_Donation_Button           GitHub_Sponsor_Button           Liberapay_Donation_Button

3
likes
160
points
122
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Decode WavPack (.wv) audio to PCM .wav on-device via the tiny dependency-free WavPack decoder over Dart FFI. Android, iOS, macOS, Linux, Windows.

Repository (GitHub)
View/report issues

Topics

#audio #wavpack #codec #decoder #ffi

License

MIT (license)

Dependencies

ffi, flutter, meta

More

Packages that depend on flutter_tiny_wavpack_decoder

Packages that implement flutter_tiny_wavpack_decoder