Usage Examples for the Revoize SDK in C
Example #1: Processing a Single Audio File
This example shows the full flow in C: get model params by name, initialize the SDK, read a WAV file, process it in chunks, and write the enhanced audio. Minimal and self-contained so you can drop it into your project and adjust paths or model name as needed.
WARNING
The input and output file paths and model name are hardcoded in this example. You may need to modify the input file path to match the location of your audio file. The input WAV file must be at the sample rate required by the chosen model (see params->input_sample_rate). Audio is processed in chunks whose size is params->input_chunk_size_samples (this varies by model; e.g. Capella uses 480).
Here's a general sequence diagram for this example:
Include Statements
First, we need to include the necessary header files to use the Revoize SDK and process audio files. We'll use sndfile.h for reading and writing WAV files.
#include "revoize_sdk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sndfile.h>The most important line from the Revoize SDK usage perspective is:
#include "revoize_sdk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sndfile.h>We use revoize_get_model_params(name) to get model parameters (chunk sizes and sample rates), then revoize_init(params) and revoize_process(...).
Helper Functions
Before we start processing audio, we need some helper functions to read and write WAV files.
float* read_wav_file(const char* filename, size_t* num_samples) {
SF_INFO sf_info;
SNDFILE* file = sf_open(filename, SFM_READ, &sf_info);
if (!file) {
fprintf(stderr, "Could not open file: %s\n", filename);
fprintf(stderr, "Error: %s\n", sf_strerror(NULL));
exit(1);
}
float* samples = (float*)malloc(sf_info.frames * sizeof(float));
if (!samples) {
sf_close(file);
fprintf(stderr, "Failed to allocate memory for samples\n");
exit(1);
}
sf_count_t frames_read = sf_readf_float(file, samples, sf_info.frames);
if (frames_read != sf_info.frames) {
free(samples);
sf_close(file);
fprintf(stderr, "Failed to read audio data\n");
exit(1);
}
*num_samples = frames_read;
sf_close(file);
return samples;
}
void write_wav_file(const char* filename, const float* samples, size_t num_samples, unsigned int sample_rate) {
SF_INFO sf_info;
sf_info.samplerate = sample_rate;
sf_info.channels = 1;
sf_info.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
SNDFILE* file = sf_open(filename, SFM_WRITE, &sf_info);
if (!file) {
fprintf(stderr, "Could not create file: %s\n", filename);
fprintf(stderr, "Error: %s\n", sf_strerror(NULL));
exit(1);
}
sf_count_t frames_written = sf_writef_float(file, samples, num_samples);
if (frames_written != num_samples) {
sf_close(file);
fprintf(stderr, "Failed to write audio data\n");
exit(1);
}
sf_close(file);
}Get model parameters and define paths
We get model parameters by name with revoize_get_model_params("Capella"). You can use revoize_list_names() to discover available names. The parameters define input/output chunk sizes and sample rates.
const char* input_file = "input.wav";
const char* output_file = "output.wav";
const RevoizeModelParams* params = revoize_get_model_params("Capella");
if (!params) {
fprintf(stderr, "Model not available\n");
exit(1);
}Initialize the Revoize SDK
We initialize the SDK with the pointer returned from revoize_get_model_params.
int result = revoize_init(params);
if (result != 0) {
fprintf(stderr, "Failed to initialize SDK\n");
exit(1);
}The input WAV file should be at params->input_sample_rate. Output will have params->output_chunk_size_samples per chunk at params->output_sample_rate.
Load the Input WAV File
Next, we need to load the input WAV file from disk. We use the read_wav_file helper function to read the WAV file.
// Read input WAV file
size_t num_samples;
float* input_samples = read_wav_file(input_file, &num_samples);
if (input_samples == NULL) {
fprintf(stderr, "Failed to read input WAV file\n");
exit(1);
}The read_wav_file function returns both the audio samples and the number of samples. The samples are stored as float values to make them compatible with the Revoize SDK's revoize_process function.
Process the Audio in Chunks
We process the audio in chunks of params->input_chunk_size_samples. Each chunk produces params->output_chunk_size_samples output samples.
// Process the audio in chunks
float* processed_audio = NULL;
size_t total_processed_samples = 0;
const size_t input_chunk_size = params->input_chunk_size_samples;
const size_t output_chunk_size = params->output_chunk_size_samples;
size_t num_chunks = num_samples / input_chunk_size;
for (size_t i = 0; i < num_chunks; i++) {
size_t start = i * input_chunk_size;
// Allocate output buffer for this chunk
float* output_chunk = (float*)malloc(output_chunk_size * sizeof(float));
if (output_chunk == NULL) {
if (processed_audio != NULL) {
free(processed_audio);
}
free(input_samples);
fprintf(stderr, "Failed to allocate output buffer for chunk\n");
exit(1);
}
// Process the current chunk
size_t output_len = output_chunk_size;
result = revoize_process(&input_samples[start], input_chunk_size, output_chunk, &output_len);
if (result != 0 || output_len != output_chunk_size) {
free(output_chunk);
if (processed_audio != NULL) {
free(processed_audio);
}
free(input_samples);
fprintf(stderr, "Failed to process audio chunk\n");
exit(1);
}
// Reallocate and append processed chunk to the result
float* new_processed_audio = (float*)realloc(processed_audio,
(total_processed_samples + output_len) * sizeof(float));
if (new_processed_audio == NULL) {
free(output_chunk);
if (processed_audio != NULL) {
free(processed_audio);
}
free(input_samples);
fprintf(stderr, "Failed to reallocate processed audio buffer\n");
exit(1);
}
processed_audio = new_processed_audio;
memcpy(&processed_audio[total_processed_samples], output_chunk, output_len * sizeof(float));
total_processed_samples += output_len;
// Free the chunk buffer
free(output_chunk);
}The revoize_process function takes an input audio chunk, processes it, and stores the enhanced samples in the output buffer. We store all processed chunks in a dynamically growing buffer called processed_audio.
Save the Processed Audio to a New WAV File
Finally, we save the processed audio to a new WAV file using the write_wav_file helper function.
// Write output WAV file (use model's output sample rate)
write_wav_file(output_file, processed_audio, total_processed_samples, params->output_sample_rate);
// Clean up
free(input_samples);
free(processed_audio);Full Code Example
Below is the complete minimal source code example that demonstrates how to process a single audio file using the Revoize SDK.
#include "revoize_sdk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sndfile.h>
float* read_wav_file(const char* filename, size_t* num_samples) {
SF_INFO sf_info;
SNDFILE* file = sf_open(filename, SFM_READ, &sf_info);
if (!file) {
fprintf(stderr, "Could not open file: %s\n", filename);
fprintf(stderr, "Error: %s\n", sf_strerror(NULL));
exit(1);
}
float* samples = (float*)malloc(sf_info.frames * sizeof(float));
if (!samples) {
sf_close(file);
fprintf(stderr, "Failed to allocate memory for samples\n");
exit(1);
}
sf_count_t frames_read = sf_readf_float(file, samples, sf_info.frames);
if (frames_read != sf_info.frames) {
free(samples);
sf_close(file);
fprintf(stderr, "Failed to read audio data\n");
exit(1);
}
*num_samples = frames_read;
sf_close(file);
return samples;
}
void write_wav_file(const char* filename, const float* samples, size_t num_samples, unsigned int sample_rate) {
SF_INFO sf_info;
sf_info.samplerate = sample_rate;
sf_info.channels = 1;
sf_info.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
SNDFILE* file = sf_open(filename, SFM_WRITE, &sf_info);
if (!file) {
fprintf(stderr, "Could not create file: %s\n", filename);
fprintf(stderr, "Error: %s\n", sf_strerror(NULL));
exit(1);
}
sf_count_t frames_written = sf_writef_float(file, samples, num_samples);
if (frames_written != num_samples) {
sf_close(file);
fprintf(stderr, "Failed to write audio data\n");
exit(1);
}
sf_close(file);
}
int main() {
// -------------------------------------------------
// 1. Get model parameters and initialize
// -------------------------------------------------
const char* input_file = "input.wav";
const char* output_file = "output.wav";
const RevoizeModelParams* params = revoize_get_model_params("Capella");
if (!params) {
fprintf(stderr, "Model not available\n");
exit(1);
}
int result = revoize_init(params);
if (result != 0) {
fprintf(stderr, "Failed to initialize SDK\n");
exit(1);
}
// -------------------------------------------------
// 2. Load the input WAV file
// -------------------------------------------------
size_t num_samples;
float* input_samples = read_wav_file(input_file, &num_samples);
if (input_samples == NULL) {
fprintf(stderr, "Failed to read input WAV file\n");
exit(1);
}
// -------------------------------------------------
// 3. Process the audio in chunks
// -------------------------------------------------
float* processed_audio = NULL;
size_t total_processed_samples = 0;
const size_t input_chunk_size = params->input_chunk_size_samples;
const size_t output_chunk_size = params->output_chunk_size_samples;
size_t num_chunks = num_samples / input_chunk_size;
for (size_t i = 0; i < num_chunks; i++) {
size_t start = i * input_chunk_size;
float* output_chunk = (float*)malloc(output_chunk_size * sizeof(float));
if (output_chunk == NULL) {
if (processed_audio != NULL) {
free(processed_audio);
}
free(input_samples);
fprintf(stderr, "Failed to allocate output buffer for chunk\n");
exit(1);
}
// Process the current chunk
size_t output_len = output_chunk_size;
result = revoize_process(&input_samples[start], input_chunk_size, output_chunk, &output_len);
if (result != 0 || output_len != output_chunk_size) {
free(output_chunk);
if (processed_audio != NULL) {
free(processed_audio);
}
free(input_samples);
fprintf(stderr, "Failed to process audio chunk\n");
exit(1);
}
// Reallocate and append processed chunk to the result
float* new_processed_audio = (float*)realloc(processed_audio,
(total_processed_samples + output_len) * sizeof(float));
if (new_processed_audio == NULL) {
free(output_chunk);
if (processed_audio != NULL) {
free(processed_audio);
}
free(input_samples);
fprintf(stderr, "Failed to reallocate processed audio buffer\n");
exit(1);
}
processed_audio = new_processed_audio;
memcpy(&processed_audio[total_processed_samples], output_chunk, output_len * sizeof(float));
total_processed_samples += output_len;
// Free the chunk buffer
free(output_chunk);
}
// -------------------------------------------------
// 4. Save the processed audio to a new WAV file
// -------------------------------------------------
write_wav_file(output_file, processed_audio, total_processed_samples, params->output_sample_rate);
// Clean up
free(input_samples);
free(processed_audio);
return 0;
}Example #2: Real-time Speech Enhancement
Coming Soon.