Add C/CXX API for VoxLock (#4104)

This commit is contained in:
Fangjun Kuang authored and GitHub committed 2026-10-26 17:21:30 +08:00
1 parent cc92083394
commit 1ec9807f1e
17 files changed
+1217 -1

No files matched your search

+168
View File
@@ -1717,3 +1717,171 @@ jobs:
ls -lh
./run.sh
rm -rf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20
test-speech-enhancement:
name: Test Speech Enhancement ${{ matrix.os }}
needs: build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, ubuntu-22.04-arm]
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: build-${{ matrix.os }}
path: build/install
- name: Set up library path
shell: bash
run: |
echo "LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV
echo "DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH" >> $GITHUB_ENV
- name: Test version
shell: bash
run: |
name=version-c-api
gcc -o $name ./c-api-examples/$name.c \
-I ./build/install/include \
-L ./build/install/lib/ \
-l sherpa-onnx-c-api \
-l onnxruntime
ls -lh $name
./$name
- name: Test speech enhancement (VoxLock)
shell: bash
run: |
name=speech-enhancement-voxlock-c-api
gcc -o $name ./c-api-examples/$name.c \
-I ./build/install/include \
-L ./build/install/lib/ \
-l sherpa-onnx-c-api \
-l onnxruntime
ls -lh $name
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
rm sherpa-onnx-voxlock-int8.tar.bz2
export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH
./$name
rm $name
mkdir -p $name
mv -v voxlock-enhanced-16k.wav $name/
cp -v sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav $name/
rm -rf sherpa-onnx-voxlock-int8
- name: Test speech enhancement (VoxLock, with voice sample)
shell: bash
run: |
name=speech-enhancement-voxlock-with-voice-sample-c-api
gcc -o $name ./c-api-examples/$name.c \
-I ./build/install/include \
-L ./build/install/lib/ \
-l sherpa-onnx-c-api \
-l onnxruntime
ls -lh $name
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
rm sherpa-onnx-voxlock-int8.tar.bz2
export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH
./$name
rm $name
mkdir -p $name
mv -v voxlock-enhanced-with-voice-sample-16k.wav $name/
cp -v sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav $name/
cp -v sherpa-onnx-voxlock-int8/test_wavs/en-voice-sample-f.wav $name/
rm -rf sherpa-onnx-voxlock-int8
- name: Test online speech enhancement (VoxLock)
shell: bash
run: |
name=online-speech-enhancement-voxlock-c-api
gcc -o $name ./c-api-examples/$name.c \
-I ./build/install/include \
-L ./build/install/lib/ \
-l sherpa-onnx-c-api \
-l onnxruntime
ls -lh $name
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
rm sherpa-onnx-voxlock-int8.tar.bz2
export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH
./$name
rm $name
mkdir -p $name
mv -v voxlock-enhanced-online-16k.wav $name/
cp -v sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav $name/
rm -rf sherpa-onnx-voxlock-int8
- name: Test online speech enhancement (VoxLock, with voice sample)
shell: bash
run: |
name=online-speech-enhancement-voxlock-with-voice-sample-c-api
gcc -o $name ./c-api-examples/$name.c \
-I ./build/install/include \
-L ./build/install/lib/ \
-l sherpa-onnx-c-api \
-l onnxruntime
ls -lh $name
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
rm sherpa-onnx-voxlock-int8.tar.bz2
export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH
./$name
rm $name
mkdir -p $name
mv -v voxlock-enhanced-online-with-voice-sample-16k.wav $name/
cp -v sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav $name/
cp -v sherpa-onnx-voxlock-int8/test_wavs/en-voice-sample-f.wav $name/
rm -rf sherpa-onnx-voxlock-int8
- uses: actions/upload-artifact@v4
with:
name: speech-enhancement-voxlock-c-api-${{ matrix.os }}
path: speech-enhancement-voxlock-c-api
- uses: actions/upload-artifact@v4
with:
name: speech-enhancement-voxlock-with-voice-sample-c-api-${{ matrix.os }}
path: speech-enhancement-voxlock-with-voice-sample-c-api
- uses: actions/upload-artifact@v4
with:
name: online-speech-enhancement-voxlock-c-api-${{ matrix.os }}
path: online-speech-enhancement-voxlock-c-api
- uses: actions/upload-artifact@v4
with:
name: online-speech-enhancement-voxlock-with-voice-sample-c-api-${{ matrix.os }}
path: online-speech-enhancement-voxlock-with-voice-sample-c-api
+161
View File
@@ -1430,3 +1430,164 @@ jobs:
rm -rf sherpa-onnx-whisper-tiny
rm -v ./$name
test-speech-enhancement:
name: Test Speech Enhancement ${{ matrix.os }}
needs: build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, ubuntu-22.04-arm]
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: build-${{ matrix.os }}
path: build/install
- name: Set up library path
shell: bash
run: |
echo "LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV
echo "DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH" >> $GITHUB_ENV
- name: Test version
shell: bash
run: |
name=version-cxx-api
g++ -std=c++17 -o $name ./cxx-api-examples/$name.cc \
-I ./build/install/include \
-L ./build/install/lib/ \
-l sherpa-onnx-cxx-api \
-l sherpa-onnx-c-api \
-l onnxruntime
ls -lh $name
./$name
- name: Test Speech Enhancement (VoxLock)
shell: bash
run: |
name=speech-enhancement-voxlock-cxx-api
g++ -std=c++17 -o $name ./cxx-api-examples/$name.cc \
-I ./build/install/include \
-L ./build/install/lib/ \
-l sherpa-onnx-cxx-api \
-l sherpa-onnx-c-api \
-l onnxruntime
ls -lh $name
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
rm sherpa-onnx-voxlock-int8.tar.bz2
./$name
rm $name
mkdir -p $name
mv -v voxlock-enhanced-16k.wav $name/
cp -v sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav $name/
rm -rf sherpa-onnx-voxlock-int8
- name: Test Speech Enhancement (VoxLock, with voice sample)
shell: bash
run: |
name=speech-enhancement-voxlock-with-voice-sample-cxx-api
g++ -std=c++17 -o $name ./cxx-api-examples/$name.cc \
-I ./build/install/include \
-L ./build/install/lib/ \
-l sherpa-onnx-cxx-api \
-l sherpa-onnx-c-api \
-l onnxruntime
ls -lh $name
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
rm sherpa-onnx-voxlock-int8.tar.bz2
./$name
rm $name
mkdir -p $name
mv -v voxlock-enhanced-with-voice-sample-16k.wav $name/
cp -v sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav $name/
cp -v sherpa-onnx-voxlock-int8/test_wavs/en-voice-sample-f.wav $name/
rm -rf sherpa-onnx-voxlock-int8
- name: Test Online Speech Enhancement (VoxLock)
shell: bash
run: |
name=online-speech-enhancement-voxlock-cxx-api
g++ -std=c++17 -o $name ./cxx-api-examples/$name.cc \
-I ./build/install/include \
-L ./build/install/lib/ \
-l sherpa-onnx-cxx-api \
-l sherpa-onnx-c-api \
-l onnxruntime
ls -lh $name
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
rm sherpa-onnx-voxlock-int8.tar.bz2
./$name
rm $name
mkdir -p $name
mv -v voxlock-enhanced-online-16k.wav $name/
cp -v sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav $name/
rm -rf sherpa-onnx-voxlock-int8
- name: Test Online Speech Enhancement (VoxLock, with voice sample)
shell: bash
run: |
name=online-speech-enhancement-voxlock-with-voice-sample-cxx-api
g++ -std=c++17 -o $name ./cxx-api-examples/$name.cc \
-I ./build/install/include \
-L ./build/install/lib/ \
-l sherpa-onnx-cxx-api \
-l sherpa-onnx-c-api \
-l onnxruntime
ls -lh $name
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
rm sherpa-onnx-voxlock-int8.tar.bz2
./$name
rm $name
mkdir -p $name
mv -v voxlock-enhanced-online-with-voice-sample-16k.wav $name/
cp -v sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav $name/
cp -v sherpa-onnx-voxlock-int8/test_wavs/en-voice-sample-f.wav $name/
rm -rf sherpa-onnx-voxlock-int8
- uses: actions/upload-artifact@v4
with:
name: speech-enhancement-voxlock-cxx-api-${{ matrix.os }}
path: speech-enhancement-voxlock-cxx-api
- uses: actions/upload-artifact@v4
with:
name: speech-enhancement-voxlock-with-voice-sample-cxx-api-${{ matrix.os }}
path: speech-enhancement-voxlock-with-voice-sample-cxx-api
- uses: actions/upload-artifact@v4
with:
name: online-speech-enhancement-voxlock-cxx-api-${{ matrix.os }}
path: online-speech-enhancement-voxlock-cxx-api
- uses: actions/upload-artifact@v4
with:
name: online-speech-enhancement-voxlock-with-voice-sample-cxx-api-${{ matrix.os }}
path: online-speech-enhancement-voxlock-with-voice-sample-cxx-api
+18
View File
@@ -28,6 +28,24 @@ add_executable(online-speech-enhancement-dpdfnet-c-api
online-speech-enhancement-dpdfnet-c-api.c)
target_link_libraries(online-speech-enhancement-dpdfnet-c-api sherpa-onnx-c-api)
add_executable(speech-enhancement-voxlock-c-api
speech-enhancement-voxlock-c-api.c)
target_link_libraries(speech-enhancement-voxlock-c-api sherpa-onnx-c-api)
add_executable(speech-enhancement-voxlock-with-voice-sample-c-api
speech-enhancement-voxlock-with-voice-sample-c-api.c)
target_link_libraries(speech-enhancement-voxlock-with-voice-sample-c-api
sherpa-onnx-c-api)
add_executable(online-speech-enhancement-voxlock-c-api
online-speech-enhancement-voxlock-c-api.c)
target_link_libraries(online-speech-enhancement-voxlock-c-api sherpa-onnx-c-api)
add_executable(online-speech-enhancement-voxlock-with-voice-sample-c-api
online-speech-enhancement-voxlock-with-voice-sample-c-api.c)
target_link_libraries(online-speech-enhancement-voxlock-with-voice-sample-c-api
sherpa-onnx-c-api)
if(SHERPA_ONNX_ENABLE_TTS)
add_executable(offline-tts-c-api offline-tts-c-api.c)
target_link_libraries(offline-tts-c-api sherpa-onnx-c-api)
@@ -0,0 +1,130 @@
// c-api-examples/online-speech-enhancement-voxlock-c-api.c
//
// Copyright (c) 2026 Xiaomi Corporation
//
// VoxLock is a target-speaker voice isolation model. It keeps the voice of
// one speaker, e.g., the caller in a phone call, and removes the other
// voices.
//
// The model is from https://github.com/arbazsiddiqui/voxlock
//
// This example does not provide a voice sample, so VoxLock passes the audio
// through unchanged until it has heard 3 seconds of speech, takes that speech
// as the speaker to keep, and isolates from then on. See
// ./online-speech-enhancement-voxlock-with-voice-sample-c-api.c if you have a
// voice sample of the speaker.
//
// We assume you have pre-downloaded the model from
// https://github.com/k2-fsa/sherpa-onnx/releases/tag/speech-enhancement-models
//
// An example command to download
// clang-format off
/*
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
*/
// clang-format on
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sherpa-onnx/c-api/c-api.h"
static int32_t AppendSamples(float **samples, int32_t *num_samples,
const SherpaOnnxDenoisedAudio *audio) {
float *p = NULL;
if (!audio || audio->n == 0) {
return 1;
}
p = (float *)realloc(*samples, sizeof(float) * (*num_samples + audio->n));
if (!p) {
fprintf(stderr, "Failed to allocate memory for output samples\n");
return 0;
}
memcpy(p + *num_samples, audio->samples, sizeof(float) * audio->n);
*samples = p;
*num_samples += audio->n;
return 1;
}
int32_t main() {
SherpaOnnxOnlineSpeechDenoiserConfig config;
const char *enroll_model = "./sherpa-onnx-voxlock-int8/enroll.onnx";
const char *chunk_model = "./sherpa-onnx-voxlock-int8/chunk_int8.onnx";
const char *wav_filename =
"./sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav";
const char *out_wave_filename = "./voxlock-enhanced-online-16k.wav";
float *samples = NULL;
int32_t num_samples = 0;
memset(&config, 0, sizeof(config));
config.model.voxlock.enroll_model = enroll_model;
config.model.voxlock.chunk_model = chunk_model;
const SherpaOnnxOnlineSpeechDenoiser *sd =
SherpaOnnxCreateOnlineSpeechDenoiser(&config);
if (!sd) {
fprintf(stderr, "Please check your config\n");
return -1;
}
const SherpaOnnxWave *wave = SherpaOnnxReadWave(wav_filename);
if (!wave) {
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
fprintf(stderr, "Failed to read %s\n", wav_filename);
return -1;
}
int32_t frame_shift = SherpaOnnxOnlineSpeechDenoiserGetFrameShiftInSamples(sd);
for (int32_t start = 0; start < wave->num_samples; start += frame_shift) {
int32_t n = frame_shift;
if (start + n > wave->num_samples) {
n = wave->num_samples - start;
}
const SherpaOnnxDenoisedAudio *audio = SherpaOnnxOnlineSpeechDenoiserRun(
sd, wave->samples + start, n, wave->sample_rate);
int32_t ok = AppendSamples(&samples, &num_samples, audio);
SherpaOnnxDestroyDenoisedAudio(audio);
if (!ok) {
free(samples);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
return -1;
}
}
const SherpaOnnxDenoisedAudio *tail = SherpaOnnxOnlineSpeechDenoiserFlush(sd);
int32_t sample_rate = tail ? tail->sample_rate
: SherpaOnnxOnlineSpeechDenoiserGetSampleRate(sd);
int32_t ok = AppendSamples(&samples, &num_samples, tail);
SherpaOnnxDestroyDenoisedAudio(tail);
if (!ok) {
free(samples);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
return -1;
}
if (num_samples == 0) {
fprintf(stderr, "No denoised samples were produced\n");
free(samples);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
return -1;
}
SherpaOnnxWriteWave(samples, num_samples, sample_rate, out_wave_filename);
free(samples);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
fprintf(stdout, "Saved to %s\n", out_wave_filename);
return 0;
}
@@ -0,0 +1,135 @@
// c-api-examples/online-speech-enhancement-voxlock-with-voice-sample-c-api.c
//
// Copyright (c) 2026 Xiaomi Corporation
//
// VoxLock is a target-speaker voice isolation model. It keeps the voice of
// one speaker, e.g., the caller in a phone call, and removes the other
// voices.
//
// The model is from https://github.com/arbazsiddiqui/voxlock
//
// This example provides a voice sample of the speaker to keep, so VoxLock
// isolates that speaker from the first sample. The voice sample must have at
// least 3 seconds of the speaker's voice; from a longer file, VoxLock uses
// the loudest 3 seconds within its first 30 seconds. See
// ./online-speech-enhancement-voxlock-c-api.c if you don't have a voice
// sample.
//
// We assume you have pre-downloaded the model from
// https://github.com/k2-fsa/sherpa-onnx/releases/tag/speech-enhancement-models
//
// An example command to download
// clang-format off
/*
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
*/
// clang-format on
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sherpa-onnx/c-api/c-api.h"
static int32_t AppendSamples(float **samples, int32_t *num_samples,
const SherpaOnnxDenoisedAudio *audio) {
float *p = NULL;
if (!audio || audio->n == 0) {
return 1;
}
p = (float *)realloc(*samples, sizeof(float) * (*num_samples + audio->n));
if (!p) {
fprintf(stderr, "Failed to allocate memory for output samples\n");
return 0;
}
memcpy(p + *num_samples, audio->samples, sizeof(float) * audio->n);
*samples = p;
*num_samples += audio->n;
return 1;
}
int32_t main() {
SherpaOnnxOnlineSpeechDenoiserConfig config;
const char *enroll_model = "./sherpa-onnx-voxlock-int8/enroll.onnx";
const char *chunk_model = "./sherpa-onnx-voxlock-int8/chunk_int8.onnx";
const char *voice_sample =
"./sherpa-onnx-voxlock-int8/test_wavs/en-voice-sample-f.wav";
const char *wav_filename =
"./sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav";
const char *out_wave_filename =
"./voxlock-enhanced-online-with-voice-sample-16k.wav";
float *samples = NULL;
int32_t num_samples = 0;
memset(&config, 0, sizeof(config));
config.model.voxlock.enroll_model = enroll_model;
config.model.voxlock.chunk_model = chunk_model;
config.model.voxlock.voice_sample = voice_sample;
const SherpaOnnxOnlineSpeechDenoiser *sd =
SherpaOnnxCreateOnlineSpeechDenoiser(&config);
if (!sd) {
fprintf(stderr, "Please check your config\n");
return -1;
}
const SherpaOnnxWave *wave = SherpaOnnxReadWave(wav_filename);
if (!wave) {
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
fprintf(stderr, "Failed to read %s\n", wav_filename);
return -1;
}
int32_t frame_shift = SherpaOnnxOnlineSpeechDenoiserGetFrameShiftInSamples(sd);
for (int32_t start = 0; start < wave->num_samples; start += frame_shift) {
int32_t n = frame_shift;
if (start + n > wave->num_samples) {
n = wave->num_samples - start;
}
const SherpaOnnxDenoisedAudio *audio = SherpaOnnxOnlineSpeechDenoiserRun(
sd, wave->samples + start, n, wave->sample_rate);
int32_t ok = AppendSamples(&samples, &num_samples, audio);
SherpaOnnxDestroyDenoisedAudio(audio);
if (!ok) {
free(samples);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
return -1;
}
}
const SherpaOnnxDenoisedAudio *tail = SherpaOnnxOnlineSpeechDenoiserFlush(sd);
int32_t sample_rate = tail ? tail->sample_rate
: SherpaOnnxOnlineSpeechDenoiserGetSampleRate(sd);
int32_t ok = AppendSamples(&samples, &num_samples, tail);
SherpaOnnxDestroyDenoisedAudio(tail);
if (!ok) {
free(samples);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
return -1;
}
if (num_samples == 0) {
fprintf(stderr, "No denoised samples were produced\n");
free(samples);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
return -1;
}
SherpaOnnxWriteWave(samples, num_samples, sample_rate, out_wave_filename);
free(samples);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
fprintf(stdout, "Saved to %s\n", out_wave_filename);
return 0;
}
@@ -0,0 +1,68 @@
// c-api-examples/speech-enhancement-voxlock-c-api.c
//
// Copyright (c) 2026 Xiaomi Corporation
//
// VoxLock is a target-speaker voice isolation model. It keeps the voice of
// one speaker, e.g., the caller in a phone call, and removes the other
// voices.
//
// The model is from https://github.com/arbazsiddiqui/voxlock
//
// This example does not provide a voice sample, so VoxLock takes the loudest
// 3 seconds in the first 15 seconds of the input as the speaker to keep. See
// ./speech-enhancement-voxlock-with-voice-sample-c-api.c if you have a voice
// sample of the speaker.
//
// We assume you have pre-downloaded the model from
// https://github.com/k2-fsa/sherpa-onnx/releases/tag/speech-enhancement-models
//
// An example command to download
// clang-format off
/*
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
*/
// clang-format on
#include <stdio.h>
#include <string.h>
#include "sherpa-onnx/c-api/c-api.h"
int32_t main() {
SherpaOnnxOfflineSpeechDenoiserConfig config;
const char *enroll_model = "./sherpa-onnx-voxlock-int8/enroll.onnx";
const char *chunk_model = "./sherpa-onnx-voxlock-int8/chunk_int8.onnx";
const char *wav_filename =
"./sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav";
const char *out_wave_filename = "./voxlock-enhanced-16k.wav";
memset(&config, 0, sizeof(config));
config.model.voxlock.enroll_model = enroll_model;
config.model.voxlock.chunk_model = chunk_model;
const SherpaOnnxOfflineSpeechDenoiser *sd =
SherpaOnnxCreateOfflineSpeechDenoiser(&config);
if (!sd) {
fprintf(stderr, "Please check your config");
return -1;
}
const SherpaOnnxWave *wave = SherpaOnnxReadWave(wav_filename);
if (wave == NULL) {
SherpaOnnxDestroyOfflineSpeechDenoiser(sd);
fprintf(stderr, "Failed to read %s\n", wav_filename);
return -1;
}
const SherpaOnnxDenoisedAudio *denoised = SherpaOnnxOfflineSpeechDenoiserRun(
sd, wave->samples, wave->num_samples, wave->sample_rate);
SherpaOnnxWriteWave(denoised->samples, denoised->n, denoised->sample_rate,
out_wave_filename);
SherpaOnnxDestroyDenoisedAudio(denoised);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOfflineSpeechDenoiser(sd);
fprintf(stdout, "Saved to %s\n", out_wave_filename);
}
@@ -0,0 +1,73 @@
// c-api-examples/speech-enhancement-voxlock-with-voice-sample-c-api.c
//
// Copyright (c) 2026 Xiaomi Corporation
//
// VoxLock is a target-speaker voice isolation model. It keeps the voice of
// one speaker, e.g., the caller in a phone call, and removes the other
// voices.
//
// The model is from https://github.com/arbazsiddiqui/voxlock
//
// This example provides a voice sample of the speaker to keep, so VoxLock
// isolates that speaker from the first sample. The voice sample must have at
// least 3 seconds of the speaker's voice; from a longer file, VoxLock uses
// the loudest 3 seconds within its first 30 seconds. See
// ./speech-enhancement-voxlock-c-api.c if you don't have a voice sample.
//
// We assume you have pre-downloaded the model from
// https://github.com/k2-fsa/sherpa-onnx/releases/tag/speech-enhancement-models
//
// An example command to download
// clang-format off
/*
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
*/
// clang-format on
#include <stdio.h>
#include <string.h>
#include "sherpa-onnx/c-api/c-api.h"
int32_t main() {
SherpaOnnxOfflineSpeechDenoiserConfig config;
const char *enroll_model = "./sherpa-onnx-voxlock-int8/enroll.onnx";
const char *chunk_model = "./sherpa-onnx-voxlock-int8/chunk_int8.onnx";
const char *voice_sample =
"./sherpa-onnx-voxlock-int8/test_wavs/en-voice-sample-f.wav";
const char *wav_filename =
"./sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav";
const char *out_wave_filename =
"./voxlock-enhanced-with-voice-sample-16k.wav";
memset(&config, 0, sizeof(config));
config.model.voxlock.enroll_model = enroll_model;
config.model.voxlock.chunk_model = chunk_model;
config.model.voxlock.voice_sample = voice_sample;
const SherpaOnnxOfflineSpeechDenoiser *sd =
SherpaOnnxCreateOfflineSpeechDenoiser(&config);
if (!sd) {
fprintf(stderr, "Please check your config");
return -1;
}
const SherpaOnnxWave *wave = SherpaOnnxReadWave(wav_filename);
if (wave == NULL) {
SherpaOnnxDestroyOfflineSpeechDenoiser(sd);
fprintf(stderr, "Failed to read %s\n", wav_filename);
return -1;
}
const SherpaOnnxDenoisedAudio *denoised = SherpaOnnxOfflineSpeechDenoiserRun(
sd, wave->samples, wave->num_samples, wave->sample_rate);
SherpaOnnxWriteWave(denoised->samples, denoised->n, denoised->sample_rate,
out_wave_filename);
SherpaOnnxDestroyDenoisedAudio(denoised);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOfflineSpeechDenoiser(sd);
fprintf(stdout, "Saved to %s\n", out_wave_filename);
}
+19
View File
@@ -37,6 +37,25 @@ add_executable(online-speech-enhancement-dpdfnet-cxx-api
target_link_libraries(online-speech-enhancement-dpdfnet-cxx-api
sherpa-onnx-cxx-api)
add_executable(speech-enhancement-voxlock-cxx-api
./speech-enhancement-voxlock-cxx-api.cc)
target_link_libraries(speech-enhancement-voxlock-cxx-api sherpa-onnx-cxx-api)
add_executable(speech-enhancement-voxlock-with-voice-sample-cxx-api
./speech-enhancement-voxlock-with-voice-sample-cxx-api.cc)
target_link_libraries(speech-enhancement-voxlock-with-voice-sample-cxx-api
sherpa-onnx-cxx-api)
add_executable(online-speech-enhancement-voxlock-cxx-api
./online-speech-enhancement-voxlock-cxx-api.cc)
target_link_libraries(online-speech-enhancement-voxlock-cxx-api
sherpa-onnx-cxx-api)
add_executable(online-speech-enhancement-voxlock-with-voice-sample-cxx-api
./online-speech-enhancement-voxlock-with-voice-sample-cxx-api.cc)
target_link_libraries(online-speech-enhancement-voxlock-with-voice-sample-cxx-api
sherpa-onnx-cxx-api)
add_executable(kws-cxx-api ./kws-cxx-api.cc)
target_link_libraries(kws-cxx-api sherpa-onnx-cxx-api)
@@ -0,0 +1,96 @@
// cxx-api-examples/online-speech-enhancement-voxlock-cxx-api.cc
//
// Copyright (c) 2026 Xiaomi Corporation
//
// VoxLock is a target-speaker voice isolation model. It keeps the voice of
// one speaker, e.g., the caller in a phone call, and removes the other
// voices.
//
// The model is from https://github.com/arbazsiddiqui/voxlock
//
// This example does not provide a voice sample, so VoxLock passes the audio
// through unchanged until it has heard 3 seconds of speech, takes that speech
// as the speaker to keep, and isolates from then on. See
// ./online-speech-enhancement-voxlock-with-voice-sample-cxx-api.cc if you
// have a voice sample of the speaker.
//
// We assume you have pre-downloaded the model from
// https://github.com/k2-fsa/sherpa-onnx/releases/tag/speech-enhancement-models
//
// An example command to download:
// clang-format off
/*
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
*/
// clang-format on
#include <algorithm>
#include <chrono> // NOLINT
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include "sherpa-onnx/c-api/cxx-api.h"
int32_t main() {
using namespace sherpa_onnx::cxx; // NOLINT
OnlineSpeechDenoiserConfig config;
std::string enroll_model = "./sherpa-onnx-voxlock-int8/enroll.onnx";
std::string chunk_model = "./sherpa-onnx-voxlock-int8/chunk_int8.onnx";
std::string wav_filename =
"./sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav";
std::string out_wave_filename = "./voxlock-enhanced-online-16k.wav";
config.model.voxlock.enroll_model = enroll_model;
config.model.voxlock.chunk_model = chunk_model;
auto sd = OnlineSpeechDenoiser::Create(config);
if (!sd.Get()) {
std::cerr << "Please check your config\n";
return -1;
}
Wave wave = ReadWave(wav_filename);
if (wave.samples.empty()) {
std::cerr << "Failed to read: '" << wav_filename << "'\n";
return -1;
}
std::vector<float> samples;
auto frame_shift = sd.GetFrameShiftInSamples();
std::cout << "Started\n";
const auto begin = std::chrono::steady_clock::now();
for (int32_t start = 0; start < static_cast<int32_t>(wave.samples.size());
start += frame_shift) {
int32_t n = std::min<int32_t>(frame_shift, wave.samples.size() - start);
auto denoised = sd.Run(wave.samples.data() + start, n, wave.sample_rate);
samples.insert(samples.end(), denoised.samples.begin(),
denoised.samples.end());
}
auto tail = sd.Flush();
samples.insert(samples.end(), tail.samples.begin(), tail.samples.end());
const auto end = std::chrono::steady_clock::now();
std::cout << "Done\n";
WriteWave(out_wave_filename, {samples, sd.GetSampleRate()});
const float elapsed_seconds =
std::chrono::duration_cast<std::chrono::milliseconds>(end - begin)
.count() /
1000.;
float duration = wave.samples.size() / static_cast<float>(wave.sample_rate);
float rtf = elapsed_seconds / duration;
std::cout << "Saved to " << out_wave_filename << "\n";
printf("Duration: %.3fs\n", duration);
printf("Elapsed seconds: %.3fs\n", elapsed_seconds);
printf("(Real time factor) RTF = %.3f / %.3f = %.3f\n", elapsed_seconds,
duration, rtf);
return 0;
}
@@ -0,0 +1,101 @@
// cxx-api-examples/online-speech-enhancement-voxlock-with-voice-sample-cxx-api.cc
//
// Copyright (c) 2026 Xiaomi Corporation
//
// VoxLock is a target-speaker voice isolation model. It keeps the voice of
// one speaker, e.g., the caller in a phone call, and removes the other
// voices.
//
// The model is from https://github.com/arbazsiddiqui/voxlock
//
// This example provides a voice sample of the speaker to keep, so VoxLock
// isolates that speaker from the first sample. The voice sample must have at
// least 3 seconds of the speaker's voice; from a longer file, VoxLock uses
// the loudest 3 seconds within its first 30 seconds. See
// ./online-speech-enhancement-voxlock-cxx-api.cc if you don't have a voice
// sample.
//
// We assume you have pre-downloaded the model from
// https://github.com/k2-fsa/sherpa-onnx/releases/tag/speech-enhancement-models
//
// An example command to download:
// clang-format off
/*
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
*/
// clang-format on
#include <algorithm>
#include <chrono> // NOLINT
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include "sherpa-onnx/c-api/cxx-api.h"
int32_t main() {
using namespace sherpa_onnx::cxx; // NOLINT
OnlineSpeechDenoiserConfig config;
std::string enroll_model = "./sherpa-onnx-voxlock-int8/enroll.onnx";
std::string chunk_model = "./sherpa-onnx-voxlock-int8/chunk_int8.onnx";
std::string voice_sample =
"./sherpa-onnx-voxlock-int8/test_wavs/en-voice-sample-f.wav";
std::string wav_filename =
"./sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav";
std::string out_wave_filename =
"./voxlock-enhanced-online-with-voice-sample-16k.wav";
config.model.voxlock.enroll_model = enroll_model;
config.model.voxlock.chunk_model = chunk_model;
config.model.voxlock.voice_sample = voice_sample;
auto sd = OnlineSpeechDenoiser::Create(config);
if (!sd.Get()) {
std::cerr << "Please check your config\n";
return -1;
}
Wave wave = ReadWave(wav_filename);
if (wave.samples.empty()) {
std::cerr << "Failed to read: '" << wav_filename << "'\n";
return -1;
}
std::vector<float> samples;
auto frame_shift = sd.GetFrameShiftInSamples();
std::cout << "Started\n";
const auto begin = std::chrono::steady_clock::now();
for (int32_t start = 0; start < static_cast<int32_t>(wave.samples.size());
start += frame_shift) {
int32_t n = std::min<int32_t>(frame_shift, wave.samples.size() - start);
auto denoised = sd.Run(wave.samples.data() + start, n, wave.sample_rate);
samples.insert(samples.end(), denoised.samples.begin(),
denoised.samples.end());
}
auto tail = sd.Flush();
samples.insert(samples.end(), tail.samples.begin(), tail.samples.end());
const auto end = std::chrono::steady_clock::now();
std::cout << "Done\n";
WriteWave(out_wave_filename, {samples, sd.GetSampleRate()});
const float elapsed_seconds =
std::chrono::duration_cast<std::chrono::milliseconds>(end - begin)
.count() /
1000.;
float duration = wave.samples.size() / static_cast<float>(wave.sample_rate);
float rtf = elapsed_seconds / duration;
std::cout << "Saved to " << out_wave_filename << "\n";
printf("Duration: %.3fs\n", duration);
printf("Elapsed seconds: %.3fs\n", elapsed_seconds);
printf("(Real time factor) RTF = %.3f / %.3f = %.3f\n", elapsed_seconds,
duration, rtf);
return 0;
}
@@ -0,0 +1,80 @@
// cxx-api-examples/speech-enhancement-voxlock-cxx-api.cc
//
// Copyright (c) 2026 Xiaomi Corporation
//
// VoxLock is a target-speaker voice isolation model. It keeps the voice of
// one speaker, e.g., the caller in a phone call, and removes the other
// voices.
//
// The model is from https://github.com/arbazsiddiqui/voxlock
//
// This example does not provide a voice sample, so VoxLock takes the loudest
// 3 seconds in the first 15 seconds of the input as the speaker to keep. See
// ./speech-enhancement-voxlock-with-voice-sample-cxx-api.cc if you have a
// voice sample of the speaker.
//
// We assume you have pre-downloaded the model from
// https://github.com/k2-fsa/sherpa-onnx/releases/tag/speech-enhancement-models
//
// An example command to download:
// clang-format off
/*
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
*/
// clang-format on
#include <chrono> // NOLINT
#include <cstdio>
#include <iostream>
#include <string>
#include "sherpa-onnx/c-api/cxx-api.h"
int32_t main() {
using namespace sherpa_onnx::cxx; // NOLINT
OfflineSpeechDenoiserConfig config;
std::string enroll_model = "./sherpa-onnx-voxlock-int8/enroll.onnx";
std::string chunk_model = "./sherpa-onnx-voxlock-int8/chunk_int8.onnx";
std::string wav_filename =
"./sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav";
std::string out_wave_filename = "./voxlock-enhanced-16k.wav";
config.model.voxlock.enroll_model = enroll_model;
config.model.voxlock.chunk_model = chunk_model;
auto sd = OfflineSpeechDenoiser::Create(config);
if (!sd.Get()) {
std::cerr << "Please check your config\n";
return -1;
}
Wave wave = ReadWave(wav_filename);
if (wave.samples.empty()) {
std::cerr << "Failed to read: '" << wav_filename << "'\n";
return -1;
}
std::cout << "Started\n";
const auto begin = std::chrono::steady_clock::now();
auto denoised =
sd.Run(wave.samples.data(), wave.samples.size(), wave.sample_rate);
const auto end = std::chrono::steady_clock::now();
std::cout << "Done\n";
WriteWave(out_wave_filename, {denoised.samples, denoised.sample_rate});
const float elapsed_seconds =
std::chrono::duration_cast<std::chrono::milliseconds>(end - begin)
.count() /
1000.;
float duration = wave.samples.size() / static_cast<float>(wave.sample_rate);
float rtf = elapsed_seconds / duration;
std::cout << "Saved to " << out_wave_filename << "\n";
printf("Duration: %.3fs\n", duration);
printf("Elapsed seconds: %.3fs\n", elapsed_seconds);
printf("(Real time factor) RTF = %.3f / %.3f = %.3f\n", elapsed_seconds,
duration, rtf);
return 0;
}
@@ -0,0 +1,85 @@
// cxx-api-examples/speech-enhancement-voxlock-with-voice-sample-cxx-api.cc
//
// Copyright (c) 2026 Xiaomi Corporation
//
// VoxLock is a target-speaker voice isolation model. It keeps the voice of
// one speaker, e.g., the caller in a phone call, and removes the other
// voices.
//
// The model is from https://github.com/arbazsiddiqui/voxlock
//
// This example provides a voice sample of the speaker to keep, so VoxLock
// isolates that speaker from the first sample. The voice sample must have at
// least 3 seconds of the speaker's voice; from a longer file, VoxLock uses
// the loudest 3 seconds within its first 30 seconds. See
// ./speech-enhancement-voxlock-cxx-api.cc if you don't have a voice sample.
//
// We assume you have pre-downloaded the model from
// https://github.com/k2-fsa/sherpa-onnx/releases/tag/speech-enhancement-models
//
// An example command to download:
// clang-format off
/*
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/sherpa-onnx-voxlock-int8.tar.bz2
tar xvf sherpa-onnx-voxlock-int8.tar.bz2
*/
// clang-format on
#include <chrono> // NOLINT
#include <cstdio>
#include <iostream>
#include <string>
#include "sherpa-onnx/c-api/cxx-api.h"
int32_t main() {
using namespace sherpa_onnx::cxx; // NOLINT
OfflineSpeechDenoiserConfig config;
std::string enroll_model = "./sherpa-onnx-voxlock-int8/enroll.onnx";
std::string chunk_model = "./sherpa-onnx-voxlock-int8/chunk_int8.onnx";
std::string voice_sample =
"./sherpa-onnx-voxlock-int8/test_wavs/en-voice-sample-f.wav";
std::string wav_filename =
"./sherpa-onnx-voxlock-int8/test_wavs/en-combined.wav";
std::string out_wave_filename =
"./voxlock-enhanced-with-voice-sample-16k.wav";
config.model.voxlock.enroll_model = enroll_model;
config.model.voxlock.chunk_model = chunk_model;
config.model.voxlock.voice_sample = voice_sample;
auto sd = OfflineSpeechDenoiser::Create(config);
if (!sd.Get()) {
std::cerr << "Please check your config\n";
return -1;
}
Wave wave = ReadWave(wav_filename);
if (wave.samples.empty()) {
std::cerr << "Failed to read: '" << wav_filename << "'\n";
return -1;
}
std::cout << "Started\n";
const auto begin = std::chrono::steady_clock::now();
auto denoised =
sd.Run(wave.samples.data(), wave.samples.size(), wave.sample_rate);
const auto end = std::chrono::steady_clock::now();
std::cout << "Done\n";
WriteWave(out_wave_filename, {denoised.samples, denoised.sample_rate});
const float elapsed_seconds =
std::chrono::duration_cast<std::chrono::milliseconds>(end - begin)
.count() /
1000.;
float duration = wave.samples.size() / static_cast<float>(wave.sample_rate);
float rtf = elapsed_seconds / duration;
std::cout << "Saved to " << out_wave_filename << "\n";
printf("Duration: %.3fs\n", duration);
printf("Elapsed seconds: %.3fs\n", elapsed_seconds);
printf("(Real time factor) RTF = %.3f / %.3f = %.3f\n", elapsed_seconds,
duration, rtf);
return 0;
}
+1 -1
View File
@@ -6,7 +6,7 @@
#include "sherpa-onnx/c-api/cxx-api.h"
auto main() -> int {
int32_t main() {
std::cout << "sherpa-onnx version : " << sherpa_onnx::cxx::GetVersionStr()
<< "\n";
std::cout << "sherpa-onnx Git SHA1: " << sherpa_onnx::cxx::GetGitSha1()
+12
View File
@@ -3019,6 +3019,12 @@ static sherpa_onnx::OfflineSpeechDenoiserConfig GetOfflineSpeechDenoiserConfig(
c.model.dpdfnet.model = SHERPA_ONNX_OR(config->model.dpdfnet.model, "");
c.model.dpdfnet.attenuation_limit_db =
config->model.dpdfnet.attenuation_limit_db;
c.model.voxlock.enroll_model =
SHERPA_ONNX_OR(config->model.voxlock.enroll_model, "");
c.model.voxlock.chunk_model =
SHERPA_ONNX_OR(config->model.voxlock.chunk_model, "");
c.model.voxlock.voice_sample =
SHERPA_ONNX_OR(config->model.voxlock.voice_sample, "");
if (c.model.debug) {
#if __OHOS__
@@ -3236,6 +3242,12 @@ static sherpa_onnx::OnlineSpeechDenoiserConfig GetOnlineSpeechDenoiserConfig(
c.model.debug = config->model.debug;
c.model.provider = SHERPA_ONNX_OR(config->model.provider, "cpu");
c.model.dpdfnet.model = SHERPA_ONNX_OR(config->model.dpdfnet.model, "");
c.model.voxlock.enroll_model =
SHERPA_ONNX_OR(config->model.voxlock.enroll_model, "");
c.model.voxlock.chunk_model =
SHERPA_ONNX_OR(config->model.voxlock.chunk_model, "");
c.model.voxlock.voice_sample =
SHERPA_ONNX_OR(config->model.voxlock.voice_sample, "");
if (c.model.debug) {
#if __OHOS__
+44
View File
@@ -66,6 +66,10 @@
* - `offline-speaker-diarization-c-api.c` for diarization
* - `speech-enhancement-gtcrn-c-api.c` and
* `online-speech-enhancement-gtcrn-c-api.c` for speech enhancement
* - `speech-enhancement-voxlock-c-api.c` and
* `online-speech-enhancement-voxlock-c-api.c` for target-speaker voice
* isolation with VoxLock; the model is from
* https://github.com/arbazsiddiqui/voxlock
*/
#ifndef SHERPA_ONNX_C_API_C_API_H_
@@ -4262,6 +4266,44 @@ typedef struct SherpaOnnxOfflineSpeechDenoiserDpdfNetModelConfig {
float attenuation_limit_db;
} SherpaOnnxOfflineSpeechDenoiserDpdfNetModelConfig;
/**
* @brief VoxLock target-speaker voice isolation model configuration.
*
* VoxLock keeps the voice of one speaker (the caller) and removes other
* voices. The model is from https://github.com/arbazsiddiqui/voxlock
*/
typedef struct SherpaOnnxOfflineSpeechDenoiserVoxLockModelConfig {
/**
* Path to the VoxLock enroll model, e.g., `enroll.onnx`.
*
* It runs once on a voice sample of the speaker to keep. Download the
* models from
* https://github.com/arbazsiddiqui/voxlock/releases/tag/sherpa-onnx-models
*/
const char *enroll_model;
/**
* Path to the VoxLock chunk model, e.g., `chunk.onnx` or
* `chunk_int8.onnx`.
*
* It runs on each chunk of the audio.
*/
const char *chunk_model;
/**
* Optional. Path to a wave file with at least 3 seconds of the caller's
* voice. VoxLock keeps this voice and removes the others. From a longer
* file, it uses the loudest 3 seconds within the first 30 seconds. A file
* that is shorter or cannot be read is ignored, as if it were empty.
*
* If empty or ignored, the voice sample is taken from the input audio:
*
* - Offline denoiser: the loudest 3 seconds in the first 15 seconds of
* the input are used.
* - Online denoiser: the audio is passed through unchanged until 3 seconds
* of speech have been heard; that speech is used as the voice sample.
*/
const char *voice_sample;
} SherpaOnnxOfflineSpeechDenoiserVoxLockModelConfig;
/**
* @brief Speech denoiser model configuration shared by offline and online APIs.
*
@@ -4279,6 +4321,8 @@ typedef struct SherpaOnnxOfflineSpeechDenoiserModelConfig {
const char *provider;
/** DPDFNet model configuration. */
SherpaOnnxOfflineSpeechDenoiserDpdfNetModelConfig dpdfnet;
/** VoxLock model configuration. */
SherpaOnnxOfflineSpeechDenoiserVoxLockModelConfig voxlock;
} SherpaOnnxOfflineSpeechDenoiserModelConfig;
/** @brief Configuration for offline speech denoising. */
+3
View File
@@ -21,6 +21,9 @@ static void FillSpeechDenoiserModelConfig(
dst->gtcrn.model = src.gtcrn.model.c_str();
dst->dpdfnet.model = src.dpdfnet.model.c_str();
dst->dpdfnet.attenuation_limit_db = src.dpdfnet.attenuation_limit_db;
dst->voxlock.enroll_model = src.voxlock.enroll_model.c_str();
dst->voxlock.chunk_model = src.voxlock.chunk_model.c_str();
dst->voxlock.voice_sample = src.voxlock.voice_sample.c_str();
dst->num_threads = src.num_threads;
dst->provider = src.provider.c_str();
dst->debug = src.debug;
+23
View File
@@ -1287,6 +1287,27 @@ struct OfflineSpeechDenoiserDpdfNetModelConfig {
float attenuation_limit_db = 0.0f;
};
/**
* @brief VoxLock target-speaker voice isolation model configuration.
*
* VoxLock keeps the voice of one speaker (the caller) and removes other
* voices. The model is from https://github.com/arbazsiddiqui/voxlock
*/
struct OfflineSpeechDenoiserVoxLockModelConfig {
/** Path to the VoxLock enroll model, e.g., `enroll.onnx`. */
std::string enroll_model;
/** Path to the VoxLock chunk model, e.g., `chunk.onnx`. */
std::string chunk_model;
/**
* Optional. Path to a wave file with at least 3 seconds of the caller's
* voice. From a longer file, the loudest 3 seconds within the first 30
* seconds are used. A file that is shorter or cannot be read is ignored,
* as if it were empty. If empty or ignored, the voice sample is taken from
* the input audio; see the C API docs for the offline/online fallbacks.
*/
std::string voice_sample;
};
/**
* @brief Speech denoiser model configuration.
*
@@ -1298,6 +1319,8 @@ struct OfflineSpeechDenoiserModelConfig {
OfflineSpeechDenoiserGtcrnModelConfig gtcrn;
/** DPDFNet configuration. */
OfflineSpeechDenoiserDpdfNetModelConfig dpdfnet;
/** VoxLock configuration. */
OfflineSpeechDenoiserVoxLockModelConfig voxlock;
/** Number of inference threads. */
int32_t num_threads = 1;
/** Enable verbose debug logging. */