Fangjun Kuang
Committed by GitHub

Add Dart API for speech enhancement GTCRN models (#1993)

@@ -4,6 +4,12 @@ set -ex @@ -4,6 +4,12 @@ set -ex
4 4
5 cd dart-api-examples 5 cd dart-api-examples
6 6
  7 +pushd speech-enhancement-gtcrn
  8 +echo "speech enhancement with gtcrn models"
  9 +./run.sh
  10 +ls -lh
  11 +popd
  12 +
7 pushd tts 13 pushd tts
8 14
9 echo '----------matcha tts----------' 15 echo '----------matcha tts----------'
@@ -115,6 +115,7 @@ jobs: @@ -115,6 +115,7 @@ jobs:
115 cp scripts/dart/add-punctuations-pubspec.yaml dart-api-examples/add-punctuations/pubspec.yaml 115 cp scripts/dart/add-punctuations-pubspec.yaml dart-api-examples/add-punctuations/pubspec.yaml
116 cp scripts/dart/speaker-id-pubspec.yaml dart-api-examples/speaker-identification/pubspec.yaml 116 cp scripts/dart/speaker-id-pubspec.yaml dart-api-examples/speaker-identification/pubspec.yaml
117 cp scripts/dart/speaker-diarization-pubspec.yaml dart-api-examples/speaker-diarization/pubspec.yaml 117 cp scripts/dart/speaker-diarization-pubspec.yaml dart-api-examples/speaker-diarization/pubspec.yaml
  118 + cp scripts/dart/speech-enhancement-gtcrn-pubspec.yaml dart-api-examples/speech-enhancement-gtcrn/pubspec.yaml
118 119
119 cp scripts/dart/sherpa-onnx-pubspec.yaml flutter/sherpa_onnx/pubspec.yaml 120 cp scripts/dart/sherpa-onnx-pubspec.yaml flutter/sherpa_onnx/pubspec.yaml
120 121
@@ -19,6 +19,7 @@ https://pub.dev/packages/sherpa_onnx @@ -19,6 +19,7 @@ https://pub.dev/packages/sherpa_onnx
19 | [./tts](./tts)| Example for text to speech| 19 | [./tts](./tts)| Example for text to speech|
20 | [./vad-with-non-streaming-asr](./vad-with-non-streaming-asr)| Example for voice activity detection with non-streaming speech recognition. You can use it to generate subtitles.| 20 | [./vad-with-non-streaming-asr](./vad-with-non-streaming-asr)| Example for voice activity detection with non-streaming speech recognition. You can use it to generate subtitles.|
21 | [./vad](./vad)| Example for voice activity detection| 21 | [./vad](./vad)| Example for voice activity detection|
  22 +| [./speech-enhancement-gtcrn](./speech-enhancement-gtcrn)| Example for speech enhancement/denoising|
22 23
23 ## How to create an example in this folder 24 ## How to create an example in this folder
24 25
  1 +# https://dart.dev/guides/libraries/private-files
  2 +# Created by `dart pub`
  3 +.dart_tool/
  1 +## 1.0.0
  2 +
  3 +- Initial version.
  1 +A sample command-line application with an entrypoint in `bin/`, library code
  2 +in `lib/`, and example unit test in `test/`.
  1 +# This file configures the static analysis results for your project (errors,
  2 +# warnings, and lints).
  3 +#
  4 +# This enables the 'recommended' set of lints from `package:lints`.
  5 +# This set helps identify many issues that may lead to problems when running
  6 +# or consuming Dart code, and enforces writing Dart using a single, idiomatic
  7 +# style and format.
  8 +#
  9 +# If you want a smaller set of lints you can change this to specify
  10 +# 'package:lints/core.yaml'. These are just the most critical lints
  11 +# (the recommended set includes the core lints).
  12 +# The core lints are also what is used by pub.dev for scoring packages.
  13 +
  14 +include: package:lints/recommended.yaml
  15 +
  16 +# Uncomment the following section to specify additional rules.
  17 +
  18 +# linter:
  19 +# rules:
  20 +# - camel_case_types
  21 +
  22 +# analyzer:
  23 +# exclude:
  24 +# - path/to/excluded/files/**
  25 +
  26 +# For more information about the core and recommended set of lints, see
  27 +# https://dart.dev/go/core-lints
  28 +
  29 +# For additional information about configuring this file, see
  30 +# https://dart.dev/guides/language/analysis-options
  1 +// Copyright (c) 2025 Xiaomi Corporation
  2 +import 'dart:io';
  3 +
  4 +import 'package:args/args.dart';
  5 +import 'package:sherpa_onnx/sherpa_onnx.dart' as sherpa_onnx;
  6 +import './init.dart';
  7 +
  8 +void main(List<String> arguments) async {
  9 + await initSherpaOnnx();
  10 +
  11 + final parser = ArgParser()
  12 + ..addOption('model', help: 'Path to gtcrn onnx model')
  13 + ..addOption('input-wav', help: 'Path to input.wav')
  14 + ..addOption('output-wav', help: 'Path to output.wav');
  15 +
  16 + final res = parser.parse(arguments);
  17 + if (res['model'] == null ||
  18 + res['input-wav'] == null ||
  19 + res['output-wav'] == null) {
  20 + print(parser.usage);
  21 + exit(1);
  22 + }
  23 +
  24 + final model = res['model'] as String;
  25 + final inputWav = res['input-wav'] as String;
  26 + final outputWav = res['output-wav'] as String;
  27 +
  28 + final config = sherpa_onnx.OfflineSpeechDenoiserConfig(
  29 + model: sherpa_onnx.OfflineSpeechDenoiserModelConfig(
  30 + gtcrn: sherpa_onnx.OfflineSpeechDenoiserGtcrnModelConfig(model: model),
  31 + numThreads: 1,
  32 + debug: true,
  33 + provider: 'cpu',
  34 + ));
  35 +
  36 + final sd = sherpa_onnx.OfflineSpeechDenoiser(config);
  37 +
  38 + final waveData = sherpa_onnx.readWave(inputWav);
  39 +
  40 + final denoised =
  41 + sd.run(samples: waveData.samples, sampleRate: waveData.sampleRate);
  42 +
  43 + sd.free();
  44 +
  45 + sherpa_onnx.writeWave(
  46 + filename: outputWav,
  47 + samples: denoised.samples,
  48 + sampleRate: denoised.sampleRate);
  49 +
  50 + print('Saved to $outputWav');
  51 +}
  1 +name: speech_enhancement_gtcrn
  2 +
  3 +description: >
  4 + This example demonstrates how to use the Dart API for speech enhancement/denoising.
  5 +
  6 +version: 1.0.0
  7 +
  8 +environment:
  9 + sdk: ">=3.0.0 <4.0.0"
  10 +
  11 +# Add regular dependencies here.
  12 +dependencies:
  13 + sherpa_onnx: ^1.10.46
  14 + # sherpa_onnx:
  15 + # path: ../../flutter/sherpa_onnx
  16 + path: ^1.9.0
  17 + args: ^2.5.0
  18 +
  19 +dev_dependencies:
  20 + lints: ^3.0.0
  1 +#!/usr/bin/env bash
  2 +
  3 +set -ex
  4 +
  5 +dart pub get
  6 +
  7 +if [ ! -f ./gtcrn_simple.onnx ]; then
  8 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/gtcrn_simple.onnx
  9 +fi
  10 +
  11 +if [ ! -f ./inp_16k.wav ]; then
  12 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/inp_16k.wav
  13 +fi
  14 +
  15 +
  16 +dart run \
  17 + ./bin/speech_enhancement_gtcrn.dart \
  18 + --model ./gtcrn_simple.onnx \
  19 + --input-wav ./inp_16k.wav \
  20 + --output-wav ./enhanced-16k.wav
  21 +
  22 +ls -lh *.wav
@@ -9,6 +9,8 @@ @@ -9,6 +9,8 @@
9 9
10 ## Pure dart-examples 10 ## Pure dart-examples
11 11
  12 +Hint: All of the following functions can be used in Flutter, even if some of them are only provided in pure dart api examples.
  13 +
12 | Functions | URL | Supported Platforms| 14 | Functions | URL | Supported Platforms|
13 |---|---|---| 15 |---|---|---|
14 |Speaker diarization| [Address](https://github.com/k2-fsa/sherpa-onnx/tree/master/dart-api-examples/speaker-diarization)| macOS, Windows, Linux| 16 |Speaker diarization| [Address](https://github.com/k2-fsa/sherpa-onnx/tree/master/dart-api-examples/speaker-diarization)| macOS, Windows, Linux|
@@ -20,3 +22,5 @@ @@ -20,3 +22,5 @@
20 |Speaker identification and verification| [Address](https://github.com/k2-fsa/sherpa-onnx/tree/master/dart-api-examples/speaker-identification)| macOS, Windows, Linux| 22 |Speaker identification and verification| [Address](https://github.com/k2-fsa/sherpa-onnx/tree/master/dart-api-examples/speaker-identification)| macOS, Windows, Linux|
21 |Audio tagging| [Address](https://github.com/k2-fsa/sherpa-onnx/tree/master/dart-api-examples/audio-tagging)| macOS, Windows, Linux| 23 |Audio tagging| [Address](https://github.com/k2-fsa/sherpa-onnx/tree/master/dart-api-examples/audio-tagging)| macOS, Windows, Linux|
22 |Keyword spotter| [Address](https://github.com/k2-fsa/sherpa-onnx/tree/master/dart-api-examples/keyword-spotter)| macOS, Windows, Linux| 24 |Keyword spotter| [Address](https://github.com/k2-fsa/sherpa-onnx/tree/master/dart-api-examples/keyword-spotter)| macOS, Windows, Linux|
  25 +|Add punctuions| [Address](https://github.com/k2-fsa/sherpa-onnx/tree/master/dart-api-examples/add-punctuations)| macOS, Windows, Linux|
  26 +|Speech enhancement/denoising| [Address](https://github.com/k2-fsa/sherpa-onnx/tree/master/dart-api-examples/speech-enhancement-gtcrn)| macOS, Windows, Linux|
@@ -8,6 +8,7 @@ export 'src/keyword_spotter.dart'; @@ -8,6 +8,7 @@ export 'src/keyword_spotter.dart';
8 export 'src/offline_punctuation.dart'; 8 export 'src/offline_punctuation.dart';
9 export 'src/offline_recognizer.dart'; 9 export 'src/offline_recognizer.dart';
10 export 'src/offline_speaker_diarization.dart'; 10 export 'src/offline_speaker_diarization.dart';
  11 +export 'src/offline_speech_denoiser.dart';
11 export 'src/offline_stream.dart'; 12 export 'src/offline_stream.dart';
12 export 'src/online_punctuation.dart'; 13 export 'src/online_punctuation.dart';
13 export 'src/online_recognizer.dart'; 14 export 'src/online_recognizer.dart';
  1 +// Copyright (c) 2025 Xiaomi Corporation
  2 +import 'dart:ffi';
  3 +import 'dart:typed_data';
  4 +
  5 +import 'package:ffi/ffi.dart';
  6 +import './sherpa_onnx_bindings.dart';
  7 +
  8 +class OfflineSpeechDenoiserGtcrnModelConfig {
  9 + const OfflineSpeechDenoiserGtcrnModelConfig({
  10 + this.model = '',
  11 + });
  12 +
  13 + factory OfflineSpeechDenoiserGtcrnModelConfig.fromJson(
  14 + Map<String, dynamic> json) {
  15 + return OfflineSpeechDenoiserGtcrnModelConfig(
  16 + model: json['model'] as String? ?? '',
  17 + );
  18 + }
  19 +
  20 + @override
  21 + String toString() {
  22 + return 'OfflineSpeechDenoiserGtcrnModelConfig(model: $model)';
  23 + }
  24 +
  25 + Map<String, dynamic> toJson() => {
  26 + 'model': model,
  27 + };
  28 +
  29 + final String model;
  30 +}
  31 +
  32 +class OfflineSpeechDenoiserModelConfig {
  33 + const OfflineSpeechDenoiserModelConfig({
  34 + this.gtcrn = const OfflineSpeechDenoiserGtcrnModelConfig(),
  35 + this.numThreads = 1,
  36 + this.debug = true,
  37 + this.provider = 'cpu',
  38 + });
  39 +
  40 + factory OfflineSpeechDenoiserModelConfig.fromJson(Map<String, dynamic> json) {
  41 + return OfflineSpeechDenoiserModelConfig(
  42 + gtcrn: json['gtcrn'] != null
  43 + ? OfflineSpeechDenoiserGtcrnModelConfig.fromJson(
  44 + json['gtcrn'] as Map<String, dynamic>)
  45 + : const OfflineSpeechDenoiserGtcrnModelConfig(),
  46 + numThreads: json['numThreads'] as int? ?? 1,
  47 + debug: json['debug'] as bool? ?? true,
  48 + provider: json['provider'] as String? ?? 'cpu',
  49 + );
  50 + }
  51 +
  52 + @override
  53 + String toString() {
  54 + return 'OfflineSpeechDenoiserModelConfig(gtcrn: $gtcrn, numThreads: $numThreads, debug: $debug, provider: $provider)';
  55 + }
  56 +
  57 + Map<String, dynamic> toJson() => {
  58 + 'gtcrn': gtcrn.toJson(),
  59 + 'numThreads': numThreads,
  60 + 'debug': debug,
  61 + 'provider': provider,
  62 + };
  63 +
  64 + final OfflineSpeechDenoiserGtcrnModelConfig gtcrn;
  65 + final int numThreads;
  66 + final bool debug;
  67 + final String provider;
  68 +}
  69 +
  70 +class OfflineSpeechDenoiserConfig {
  71 + const OfflineSpeechDenoiserConfig({
  72 + this.model = const OfflineSpeechDenoiserModelConfig(),
  73 + });
  74 +
  75 + factory OfflineSpeechDenoiserConfig.fromJson(Map<String, dynamic> json) {
  76 + return OfflineSpeechDenoiserConfig(
  77 + model: json['model'] != null
  78 + ? OfflineSpeechDenoiserModelConfig.fromJson(
  79 + json['model'] as Map<String, dynamic>)
  80 + : const OfflineSpeechDenoiserModelConfig(),
  81 + );
  82 + }
  83 +
  84 + @override
  85 + String toString() {
  86 + return 'OfflineSpeechDenoiserConfig(model: $model)';
  87 + }
  88 +
  89 + Map<String, dynamic> toJson() => {
  90 + 'model': model.toJson(),
  91 + };
  92 +
  93 + final OfflineSpeechDenoiserModelConfig model;
  94 +}
  95 +
  96 +class DenoisedAudio {
  97 + DenoisedAudio({
  98 + required this.samples,
  99 + required this.sampleRate,
  100 + });
  101 +
  102 + final Float32List samples;
  103 + final int sampleRate;
  104 +}
  105 +
  106 +class OfflineSpeechDenoiser {
  107 + OfflineSpeechDenoiser.fromPtr({required this.ptr, required this.config});
  108 +
  109 + OfflineSpeechDenoiser._({required this.ptr, required this.config});
  110 +
  111 + /// The user is responsible to call the OfflineSpeechDenoiser.free()
  112 + /// method of the returned instance to avoid memory leak.
  113 + factory OfflineSpeechDenoiser(OfflineSpeechDenoiserConfig config) {
  114 + final c = calloc<SherpaOnnxOfflineSpeechDenoiserConfig>();
  115 + c.ref.model.gtcrn.model = config.model.gtcrn.model.toNativeUtf8();
  116 +
  117 + c.ref.model.numThreads = config.model.numThreads;
  118 + c.ref.model.debug = config.model.debug ? 1 : 0;
  119 + c.ref.model.provider = config.model.provider.toNativeUtf8();
  120 +
  121 + final ptr =
  122 + SherpaOnnxBindings.sherpaOnnxCreateOfflineSpeechDenoiser?.call(c) ??
  123 + nullptr;
  124 +
  125 + calloc.free(c.ref.model.provider);
  126 + calloc.free(c.ref.model.gtcrn.model);
  127 +
  128 + return OfflineSpeechDenoiser._(ptr: ptr, config: config);
  129 + }
  130 +
  131 + void free() {
  132 + SherpaOnnxBindings.sherpaOnnxDestroyOfflineSpeechDenoiser?.call(ptr);
  133 + ptr = nullptr;
  134 + }
  135 +
  136 + DenoisedAudio run({required Float32List samples, required int sampleRate}) {
  137 + final n = samples.length;
  138 + final Pointer<Float> psamples = calloc<Float>(n);
  139 +
  140 + final pList = psamples.asTypedList(n);
  141 + pList.setAll(0, samples);
  142 +
  143 + final p = SherpaOnnxBindings.sherpaOnnxOfflineSpeechDenoiserRun
  144 + ?.call(ptr, psamples, n, sampleRate) ??
  145 + nullptr;
  146 +
  147 + calloc.free(psamples);
  148 +
  149 + if (p == nullptr) {
  150 + return DenoisedAudio(samples: Float32List(0), sampleRate: 0);
  151 + }
  152 +
  153 + final denoisedSamples = p.ref.samples.asTypedList(p.ref.n);
  154 + final denoisedSampleRate = p.ref.sampleRate;
  155 + final newSamples = Float32List.fromList(denoisedSamples);
  156 +
  157 + SherpaOnnxBindings.sherpaOnnxDestroyDenoisedAudio?.call(p);
  158 +
  159 + return DenoisedAudio(samples: newSamples, sampleRate: denoisedSampleRate);
  160 + }
  161 +
  162 + int get sampleRate =>
  163 + SherpaOnnxBindings.sherpaOnnxOfflineSpeechDenoiserGetSampleRate
  164 + ?.call(ptr) ??
  165 + 0;
  166 +
  167 + Pointer<SherpaOnnxOfflineSpeechDenoiser> ptr;
  168 + OfflineSpeechDenoiserConfig config;
  169 +}
@@ -2,6 +2,36 @@ @@ -2,6 +2,36 @@
2 import 'dart:ffi'; 2 import 'dart:ffi';
3 import 'package:ffi/ffi.dart'; 3 import 'package:ffi/ffi.dart';
4 4
  5 +final class SherpaOnnxOfflineSpeechDenoiserGtcrnModelConfig extends Struct {
  6 + external Pointer<Utf8> model;
  7 +}
  8 +
  9 +final class SherpaOnnxOfflineSpeechDenoiserModelConfig extends Struct {
  10 + external SherpaOnnxOfflineSpeechDenoiserGtcrnModelConfig gtcrn;
  11 +
  12 + @Int32()
  13 + external int numThreads;
  14 +
  15 + @Int32()
  16 + external int debug;
  17 +
  18 + external Pointer<Utf8> provider;
  19 +}
  20 +
  21 +final class SherpaOnnxOfflineSpeechDenoiserConfig extends Struct {
  22 + external SherpaOnnxOfflineSpeechDenoiserModelConfig model;
  23 +}
  24 +
  25 +final class SherpaOnnxDenoisedAudio extends Struct {
  26 + external Pointer<Float> samples;
  27 +
  28 + @Int32()
  29 + external int n;
  30 +
  31 + @Int32()
  32 + external int sampleRate;
  33 +}
  34 +
5 final class SherpaOnnxSpeakerEmbeddingExtractorConfig extends Struct { 35 final class SherpaOnnxSpeakerEmbeddingExtractorConfig extends Struct {
6 external Pointer<Utf8> model; 36 external Pointer<Utf8> model;
7 37
@@ -517,6 +547,41 @@ final class SherpaOnnxOfflineSpeakerDiarization extends Opaque {} @@ -517,6 +547,41 @@ final class SherpaOnnxOfflineSpeakerDiarization extends Opaque {}
517 547
518 final class SherpaOnnxOfflineSpeakerDiarizationResult extends Opaque {} 548 final class SherpaOnnxOfflineSpeakerDiarizationResult extends Opaque {}
519 549
  550 +final class SherpaOnnxOfflineSpeechDenoiser extends Opaque {}
  551 +
  552 +typedef SherpaOnnxCreateOfflineSpeechDenoiserNative
  553 + = Pointer<SherpaOnnxOfflineSpeechDenoiser> Function(
  554 + Pointer<SherpaOnnxOfflineSpeechDenoiserConfig>);
  555 +
  556 +typedef SherpaOnnxCreateOfflineSpeechDenoiser
  557 + = SherpaOnnxCreateOfflineSpeechDenoiserNative;
  558 +
  559 +typedef SherpaOnnxDestroyOfflineSpeechDenoiserNative = Void Function(
  560 + Pointer<SherpaOnnxOfflineSpeechDenoiser>);
  561 +
  562 +typedef SherpaOnnxDestroyOfflineSpeechDenoiser = void Function(
  563 + Pointer<SherpaOnnxOfflineSpeechDenoiser>);
  564 +
  565 +typedef SherpaOnnxOfflineSpeechDenoiserGetSampleRateNative = Int32 Function(
  566 + Pointer<SherpaOnnxOfflineSpeechDenoiser>);
  567 +
  568 +typedef SherpaOnnxOfflineSpeechDenoiserGetSampleRate = int Function(
  569 + Pointer<SherpaOnnxOfflineSpeechDenoiser>);
  570 +
  571 +typedef SherpaOnnxOfflineSpeechDenoiserRunNative
  572 + = Pointer<SherpaOnnxDenoisedAudio> Function(
  573 + Pointer<SherpaOnnxOfflineSpeechDenoiser>, Pointer<Float>, Int32, Int32);
  574 +
  575 +typedef SherpaOnnxOfflineSpeechDenoiserRun
  576 + = Pointer<SherpaOnnxDenoisedAudio> Function(
  577 + Pointer<SherpaOnnxOfflineSpeechDenoiser>, Pointer<Float>, int, int);
  578 +
  579 +typedef SherpaOnnxDestroyDenoisedAudioNative = Void Function(
  580 + Pointer<SherpaOnnxDenoisedAudio>);
  581 +
  582 +typedef SherpaOnnxDestroyDenoisedAudio = void Function(
  583 + Pointer<SherpaOnnxDenoisedAudio>);
  584 +
520 typedef SherpaOnnxCreateOfflineSpeakerDiarizationNative 585 typedef SherpaOnnxCreateOfflineSpeakerDiarizationNative
521 = Pointer<SherpaOnnxOfflineSpeakerDiarization> Function( 586 = Pointer<SherpaOnnxOfflineSpeakerDiarization> Function(
522 Pointer<SherpaOnnxOfflineSpeakerDiarizationConfig>); 587 Pointer<SherpaOnnxOfflineSpeakerDiarizationConfig>);
@@ -1172,6 +1237,17 @@ typedef SherpaOnnxFreeWaveNative = Void Function(Pointer<SherpaOnnxWave>); @@ -1172,6 +1237,17 @@ typedef SherpaOnnxFreeWaveNative = Void Function(Pointer<SherpaOnnxWave>);
1172 typedef SherpaOnnxFreeWave = void Function(Pointer<SherpaOnnxWave>); 1237 typedef SherpaOnnxFreeWave = void Function(Pointer<SherpaOnnxWave>);
1173 1238
1174 class SherpaOnnxBindings { 1239 class SherpaOnnxBindings {
  1240 + static SherpaOnnxCreateOfflineSpeechDenoiser?
  1241 + sherpaOnnxCreateOfflineSpeechDenoiser;
  1242 +
  1243 + static SherpaOnnxDestroyOfflineSpeechDenoiser?
  1244 + sherpaOnnxDestroyOfflineSpeechDenoiser;
  1245 +
  1246 + static SherpaOnnxOfflineSpeechDenoiserGetSampleRate?
  1247 + sherpaOnnxOfflineSpeechDenoiserGetSampleRate;
  1248 + static SherpaOnnxOfflineSpeechDenoiserRun? sherpaOnnxOfflineSpeechDenoiserRun;
  1249 + static SherpaOnnxDestroyDenoisedAudio? sherpaOnnxDestroyDenoisedAudio;
  1250 +
1175 static SherpaOnnxCreateOfflineSpeakerDiarization? 1251 static SherpaOnnxCreateOfflineSpeakerDiarization?
1176 sherpaOnnxCreateOfflineSpeakerDiarization; 1252 sherpaOnnxCreateOfflineSpeakerDiarization;
1177 static SherpaOnnxDestroyOfflineSpeakerDiarization? 1253 static SherpaOnnxDestroyOfflineSpeakerDiarization?
@@ -1370,6 +1446,33 @@ class SherpaOnnxBindings { @@ -1370,6 +1446,33 @@ class SherpaOnnxBindings {
1370 static SherpaOnnxFreeWave? freeWave; 1446 static SherpaOnnxFreeWave? freeWave;
1371 1447
1372 static void init(DynamicLibrary dynamicLibrary) { 1448 static void init(DynamicLibrary dynamicLibrary) {
  1449 + sherpaOnnxCreateOfflineSpeechDenoiser ??= dynamicLibrary
  1450 + .lookup<NativeFunction<SherpaOnnxCreateOfflineSpeechDenoiserNative>>(
  1451 + 'SherpaOnnxCreateOfflineSpeechDenoiser')
  1452 + .asFunction();
  1453 +
  1454 + sherpaOnnxDestroyOfflineSpeechDenoiser ??= dynamicLibrary
  1455 + .lookup<NativeFunction<SherpaOnnxDestroyOfflineSpeechDenoiserNative>>(
  1456 + 'SherpaOnnxDestroyOfflineSpeechDenoiser')
  1457 + .asFunction();
  1458 +
  1459 + sherpaOnnxOfflineSpeechDenoiserGetSampleRate ??= dynamicLibrary
  1460 + .lookup<
  1461 + NativeFunction<
  1462 + SherpaOnnxOfflineSpeechDenoiserGetSampleRateNative>>(
  1463 + 'SherpaOnnxOfflineSpeechDenoiserGetSampleRate')
  1464 + .asFunction();
  1465 +
  1466 + sherpaOnnxOfflineSpeechDenoiserRun ??= dynamicLibrary
  1467 + .lookup<NativeFunction<SherpaOnnxOfflineSpeechDenoiserRunNative>>(
  1468 + 'SherpaOnnxOfflineSpeechDenoiserRun')
  1469 + .asFunction();
  1470 +
  1471 + sherpaOnnxDestroyDenoisedAudio ??= dynamicLibrary
  1472 + .lookup<NativeFunction<SherpaOnnxDestroyDenoisedAudioNative>>(
  1473 + 'SherpaOnnxDestroyDenoisedAudio')
  1474 + .asFunction();
  1475 +
1373 sherpaOnnxCreateOfflineSpeakerDiarization ??= dynamicLibrary 1476 sherpaOnnxCreateOfflineSpeakerDiarization ??= dynamicLibrary
1374 .lookup< 1477 .lookup<
1375 NativeFunction< 1478 NativeFunction<
  1 +name: speech_enhancement_gtcrn
  2 +
  3 +description: >
  4 + This example demonstrates how to use the Dart API for speech enhancement/denoising.
  5 +
  6 +version: 1.0.0
  7 +
  8 +environment:
  9 + sdk: ">=3.0.0 <4.0.0"
  10 +
  11 +dependencies:
  12 + sherpa_onnx:
  13 + path: ../../flutter/sherpa_onnx
  14 + path: ^1.9.0
  15 + args: ^2.5.0
  16 +
  17 +dev_dependencies:
  18 + lints: ^3.0.0