DPDFNet C API
This page describes how to use DPDFNet with the C API of sherpa-onnx.
Please refer to C API for how to build sherpa-onnx.
Offline speech enhancement
sherpa-onnx contains a ready-to-build example named
speech-enhancement-dpdfnet-c-api.c.
cd /tmp
git clone https://github.com/k2-fsa/sherpa-onnx
cd sherpa-onnx
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/dpdfnet2.onnx
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/speech-enhancement-models/inp_16k.wav
mkdir build
cd build
cmake \
-DSHERPA_ONNX_ENABLE_C_API=ON \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=./install \
..
make -j2 install
cd ..
gcc -o speech-enhancement-dpdfnet-c-api \
./c-api-examples/speech-enhancement-dpdfnet-c-api.c \
-I ./build/install/include \
-L ./build/install/lib \
-l sherpa-onnx-c-api \
-l onnxruntime
export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH
./speech-enhancement-dpdfnet-c-api
The example source is available at
The core offline configuration is shown below:
#include <stdio.h>
#include <string.h>
#include "sherpa-onnx/c-api/c-api.h"
int32_t main() {
SherpaOnnxOfflineSpeechDenoiserConfig config;
memset(&config, 0, sizeof(config));
config.model.dpdfnet.model = "./dpdfnet2.onnx";
config.model.num_threads = 1;
config.model.debug = 0;
config.model.provider = "cpu";
const SherpaOnnxOfflineSpeechDenoiser *sd =
SherpaOnnxCreateOfflineSpeechDenoiser(&config);
const SherpaOnnxWave *wave = SherpaOnnxReadWave("./inp_16k.wav");
const SherpaOnnxDenoisedAudio *denoised =
SherpaOnnxOfflineSpeechDenoiserRun(
sd, wave->samples, wave->num_samples, wave->sample_rate);
SherpaOnnxWriteWave(
denoised->samples, denoised->n, denoised->sample_rate,
"./enhanced.wav");
SherpaOnnxDestroyDenoisedAudio(denoised);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOfflineSpeechDenoiser(sd);
return 0;
}
Streaming speech enhancement
DPDFNet is also available through the streaming denoiser API:
SherpaOnnxOnlineSpeechDenoiserConfig
SherpaOnnxCreateOnlineSpeechDenoiser()
SherpaOnnxOnlineSpeechDenoiserRun()
SherpaOnnxOnlineSpeechDenoiserFlush()
SherpaOnnxOnlineSpeechDenoiserReset()
The following example processes a wave file frame by frame and writes the
streaming output to enhanced-streaming.wav:
#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 **buffer, int32_t *size,
int32_t *capacity, const float *samples,
int32_t n) {
if (*size + n > *capacity) {
int32_t new_capacity = *capacity == 0 ? n : *capacity * 2;
while (new_capacity < *size + n) {
new_capacity *= 2;
}
float *new_buffer =
(float *)realloc(*buffer, new_capacity * sizeof(float));
if (new_buffer == NULL) {
return 0;
}
*buffer = new_buffer;
*capacity = new_capacity;
}
memcpy(*buffer + *size, samples, n * sizeof(float));
*size += n;
return 1;
}
int32_t main() {
SherpaOnnxOnlineSpeechDenoiserConfig config;
memset(&config, 0, sizeof(config));
config.model.dpdfnet.model = "./dpdfnet2.onnx";
config.model.num_threads = 1;
config.model.debug = 0;
config.model.provider = "cpu";
const SherpaOnnxOnlineSpeechDenoiser *sd =
SherpaOnnxCreateOnlineSpeechDenoiser(&config);
if (sd == NULL) {
fprintf(stderr, "Failed to create online speech denoiser\n");
return -1;
}
const SherpaOnnxWave *wave = SherpaOnnxReadWave("./inp_16k.wav");
if (wave == NULL) {
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
fprintf(stderr, "Failed to read input wave\n");
return -1;
}
const int32_t frame_shift =
SherpaOnnxOnlineSpeechDenoiserGetFrameShiftInSamples(sd);
float *enhanced = NULL;
int32_t num_enhanced = 0;
int32_t capacity = 0;
for (int32_t start = 0; start < wave->num_samples; start += frame_shift) {
int32_t n = wave->num_samples - start;
if (n > frame_shift) {
n = frame_shift;
}
const SherpaOnnxDenoisedAudio *chunk =
SherpaOnnxOnlineSpeechDenoiserRun(
sd, wave->samples + start, n, wave->sample_rate);
if (chunk == NULL) {
continue;
}
if (!AppendSamples(&enhanced, &num_enhanced, &capacity,
chunk->samples, chunk->n)) {
fprintf(stderr, "Failed to grow output buffer\n");
SherpaOnnxDestroyDenoisedAudio(chunk);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
free(enhanced);
return -1;
}
SherpaOnnxDestroyDenoisedAudio(chunk);
}
const SherpaOnnxDenoisedAudio *tail =
SherpaOnnxOnlineSpeechDenoiserFlush(sd);
if (tail != NULL) {
AppendSamples(&enhanced, &num_enhanced, &capacity,
tail->samples, tail->n);
SherpaOnnxDestroyDenoisedAudio(tail);
}
SherpaOnnxWriteWave(
enhanced, num_enhanced,
SherpaOnnxOnlineSpeechDenoiserGetSampleRate(sd),
"./enhanced-streaming.wav");
free(enhanced);
SherpaOnnxFreeWave(wave);
SherpaOnnxDestroyOnlineSpeechDenoiser(sd);
return 0;
}
Note
SherpaOnnxOnlineSpeechDenoiserRun() can return NULL until enough
input audio has been buffered. Call
SherpaOnnxOnlineSpeechDenoiserFlush() at the end of the stream to
retrieve the final tail samples and reset the denoiser state.