sonora-ffi 0.2.0

C API (FFI) for the sonora audio processing library
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
#ifndef WAP_AUDIO_PROCESSING_H
#define WAP_AUDIO_PROCESSING_H

/* Warning: this file is auto-generated by cbindgen. Do not edit. */

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

/**
 * Downmix method for multi-channel capture.
 */
enum WapDownmixMethod
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
  : int32_t
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
 {
  AverageChannels = 0,
  UseFirstChannel = 1,
};
#ifndef __cplusplus
#if __STDC_VERSION__ >= 202311L
typedef enum WapDownmixMethod WapDownmixMethod;
#else
typedef int32_t WapDownmixMethod;
#endif // __STDC_VERSION__ >= 202311L
#endif // __cplusplus

/**
 * Noise suppression aggressiveness level.
 */
enum WapNoiseSuppressionLevel
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
  : int32_t
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
 {
  Low = 0,
  Moderate = 1,
  High = 2,
  VeryHigh = 3,
};
#ifndef __cplusplus
#if __STDC_VERSION__ >= 202311L
typedef enum WapNoiseSuppressionLevel WapNoiseSuppressionLevel;
#else
typedef int32_t WapNoiseSuppressionLevel;
#endif // __STDC_VERSION__ >= 202311L
#endif // __cplusplus

/**
 * Error codes returned by C API functions.
 *
 * `0` = success, negative = error.
 */
enum WapError
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
  : int32_t
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
 {
  /**
   * Operation succeeded.
   */
  None = 0,
  /**
   * Null pointer passed to a function that requires non-null.
   */
  NullPointer = -1,
  /**
   * Internal error (panic caught at FFI boundary).
   */
  Internal = -2,
  /**
   * Bad sample rate.
   */
  BadSampleRate = -3,
  /**
   * Bad number of channels.
   */
  BadNumberChannels = -4,
  /**
   * A stream parameter was out of range and was clamped.
   */
  BadStreamParameter = -5,
  /**
   * Invalid data length.
   */
  BadDataLength = -6,
};
#ifndef __cplusplus
#if __STDC_VERSION__ >= 202311L
typedef enum WapError WapError;
#else
typedef int32_t WapError;
#endif // __STDC_VERSION__ >= 202311L
#endif // __cplusplus

/**
 * Opaque handle to the audio processing engine.
 *
 * Created via `wap_create()` or `wap_create_with_config()`.
 * Destroyed via `wap_destroy()`.
 *
 * **NOT thread-safe**: all calls on the same handle must be serialized.
 */
typedef struct WapAudioProcessing WapAudioProcessing;

/**
 * Flat configuration struct for the audio processing pipeline.
 *
 * Obtain a default-initialized instance via `wap_config_default()`.
 */
typedef struct WapConfig {
  int32_t pipeline_maximum_internal_processing_rate;
  bool pipeline_multi_channel_render;
  bool pipeline_multi_channel_capture;
  WapDownmixMethod pipeline_capture_downmix_method;
  bool pre_amplifier_enabled;
  float pre_amplifier_fixed_gain_factor;
  bool capture_level_adjustment_enabled;
  float capture_level_adjustment_pre_gain_factor;
  float capture_level_adjustment_post_gain_factor;
  bool analog_mic_gain_emulation_enabled;
  int32_t analog_mic_gain_emulation_initial_level;
  bool high_pass_filter_enabled;
  bool high_pass_filter_apply_in_full_band;
  bool echo_canceller_enabled;
  bool echo_canceller_enforce_high_pass_filtering;
  bool noise_suppression_enabled;
  WapNoiseSuppressionLevel noise_suppression_level;
  bool noise_suppression_analyze_linear_aec_output_when_available;
  bool gain_controller2_enabled;
  float gain_controller2_fixed_digital_gain_db;
  bool gain_controller2_adaptive_digital_enabled;
  float gain_controller2_adaptive_digital_headroom_db;
  float gain_controller2_adaptive_digital_max_gain_db;
  float gain_controller2_adaptive_digital_initial_gain_db;
  float gain_controller2_adaptive_digital_max_gain_change_db_per_second;
  float gain_controller2_adaptive_digital_max_output_noise_level_dbfs;
  bool gain_controller2_input_volume_controller_enabled;
} WapConfig;

/**
 * Audio stream configuration (sample rate and channel count).
 */
typedef struct WapStreamConfig {
  int32_t sample_rate_hz;
  int32_t num_channels;
} WapStreamConfig;

/**
 * Audio processing statistics.
 *
 * Each statistic has a `has_*` boolean. When `false`, the corresponding
 * value field is meaningless.
 */
typedef struct WapStats {
  bool has_echo_return_loss;
  double echo_return_loss;
  bool has_echo_return_loss_enhancement;
  double echo_return_loss_enhancement;
  bool has_divergent_filter_fraction;
  double divergent_filter_fraction;
  bool has_delay_median_ms;
  int32_t delay_median_ms;
  bool has_delay_standard_deviation_ms;
  int32_t delay_standard_deviation_ms;
  bool has_residual_echo_likelihood;
  double residual_echo_likelihood;
  bool has_residual_echo_likelihood_recent_max;
  double residual_echo_likelihood_recent_max;
  bool has_delay_ms;
  int32_t delay_ms;
} WapStats;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

/**
 * Returns a pointer to a static null-terminated version string.
 *
 * The returned pointer is valid for the lifetime of the process.
 */
 const char *wap_version(void);

/**
 * Returns a default-initialized configuration.
 */
 struct WapConfig wap_config_default(void);

/**
 * Creates a new audio processing instance with default configuration.
 *
 * Returns `NULL` on allocation failure or internal error.
 * The caller owns the returned pointer and must free it with
 * [`wap_destroy()`].
 */
 struct WapAudioProcessing *wap_create(void);

/**
 * Creates a new audio processing instance with the given configuration.
 *
 * Returns `NULL` on allocation failure or internal error.
 * The caller owns the returned pointer and must free it with
 * [`wap_destroy()`].
 */
 struct WapAudioProcessing *wap_create_with_config(struct WapConfig config);

/**
 * Destroys an audio processing instance and frees its memory.
 *
 * Passing `NULL` is a safe no-op. After this call the pointer is invalid.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 * After this call the pointer is invalid and must not be used again.
 */
 void wap_destroy(struct WapAudioProcessing *apm);

/**
 * Applies a new configuration to the audio processing instance.
 *
 * Returns `WapError::NullPointer` if `apm` is null.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 */
 WapError wap_apply_config(struct WapAudioProcessing *apm, struct WapConfig config);

/**
 * Retrieves the current configuration.
 *
 * Returns `WapError::NullPointer` if `apm` or `config_out` is null.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 * All pointer arguments must be valid and properly aligned.
 */
 WapError wap_get_config(const struct WapAudioProcessing *apm, struct WapConfig *config_out);

/**
 * Initializes the processing pipeline with explicit stream configurations.
 *
 * Sets sample rates and channel counts for all four audio paths (capture
 * input, capture output, reverse input, reverse output) atomically,
 * triggering a full reinitialisation of internal buffers and submodules.
 *
 * Returns `WapError::NullPointer` if `apm` is null.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 */

WapError wap_initialize(struct WapAudioProcessing *apm,
                        struct WapStreamConfig input_config,
                        struct WapStreamConfig output_config,
                        struct WapStreamConfig reverse_input_config,
                        struct WapStreamConfig reverse_output_config);

/**
 * Processes a capture audio frame (float, deinterleaved).
 *
 * - `src`: array of `input_config.num_channels` pointers, each pointing
 *   to `input_config.sample_rate_hz / 100` samples.
 * - `dest`: array of `output_config.num_channels` pointers (output buffers).
 *
 * Returns `WapError::None` on success.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 * `src` and `dest` channel pointer arrays must have the correct number
 * of channels and each channel pointer must point to at least the
 * required number of frames.
 */

WapError wap_process_stream_f32(struct WapAudioProcessing *apm,
                                const float *const *src,
                                struct WapStreamConfig input_config,
                                struct WapStreamConfig output_config,
                                float *const *dest);

/**
 * Processes a reverse (render / far-end) audio frame (float, deinterleaved).
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 * `src` and `dest` channel pointer arrays must have the correct number
 * of channels and each channel pointer must point to at least the
 * required number of frames.
 */

WapError wap_process_reverse_stream_f32(struct WapAudioProcessing *apm,
                                        const float *const *src,
                                        struct WapStreamConfig input_config,
                                        struct WapStreamConfig output_config,
                                        float *const *dest);

/**
 * Processes a capture audio frame (int16, interleaved).
 *
 * - `src`: pointer to `num_frames * num_channels` interleaved i16 samples.
 * - `dest`: pointer to output buffer of same size.
 * - Input and output configs must have native rates (8k/16k/32k/48k) and
 *   matching rates and channel counts.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 * `src` and `dest` must point to at least the specified number of samples.
 */

WapError wap_process_stream_i16(struct WapAudioProcessing *apm,
                                const int16_t *src,
                                int32_t src_len,
                                struct WapStreamConfig input_config,
                                struct WapStreamConfig output_config,
                                int16_t *dest,
                                int32_t dest_len);

/**
 * Processes a reverse (render / far-end) audio frame (int16, interleaved).
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 * `src` and `dest` must point to at least the specified number of samples.
 */

WapError wap_process_reverse_stream_i16(struct WapAudioProcessing *apm,
                                        const int16_t *src,
                                        int32_t src_len,
                                        struct WapStreamConfig input_config,
                                        struct WapStreamConfig output_config,
                                        int16_t *dest,
                                        int32_t dest_len);

/**
 * Sets the applied input volume (e.g. from the OS mixer).
 *
 * Must be called before [`wap_process_stream_f32()`] if the input volume
 * controller is enabled. Value should be in range `[0, 255]`.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 */
 WapError wap_set_stream_analog_level(struct WapAudioProcessing *apm, int32_t level);

/**
 * Returns the recommended analog level from AGC.
 *
 * Should be called after [`wap_process_stream_f32()`] to obtain the
 * recommended new analog level. Returns 0 if `apm` is null.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 */
 int32_t wap_recommended_stream_analog_level(const struct WapAudioProcessing *apm);

/**
 * Sets the delay in ms between render and capture.
 *
 * The delay is clamped to `[0, 500]`. Returns `WapError::BadStreamParameter`
 * if clamping was necessary (processing still proceeds).
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 */
 WapError wap_set_stream_delay_ms(struct WapAudioProcessing *apm, int32_t delay);

/**
 * Returns the current stream delay in ms. Returns 0 if `apm` is null.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 */
 int32_t wap_stream_delay_ms(const struct WapAudioProcessing *apm);

/**
 * Sets the capture pre-gain factor via runtime setting.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 */
 WapError wap_set_capture_pre_gain(struct WapAudioProcessing *apm, float gain);

/**
 * Sets the capture post-gain factor via runtime setting.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 */
 WapError wap_set_capture_post_gain(struct WapAudioProcessing *apm, float gain);

/**
 * Sets the fixed post-gain in dB via runtime setting (range: 0..=90).
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 */
 WapError wap_set_capture_fixed_post_gain(struct WapAudioProcessing *apm, float gain_db);

/**
 * Notifies of a playout volume change via runtime setting.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 */
 WapError wap_set_playout_volume(struct WapAudioProcessing *apm, int32_t volume);

/**
 * Notifies of a playout audio device change via runtime setting.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 */

WapError wap_set_playout_audio_device(struct WapAudioProcessing *apm,
                                      int32_t device_id,
                                      int32_t max_volume);

/**
 * Sets whether the capture output is used via runtime setting.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 */
 WapError wap_set_capture_output_used(struct WapAudioProcessing *apm, bool used);

/**
 * Retrieves current processing statistics.
 *
 * Returns `WapError::NullPointer` if `apm` or `stats_out` is null.
 *
 * # Safety
 *
 * `apm` must be a valid pointer returned by [`wap_create`] or
 * [`wap_create_with_config`] and must not be concurrently accessed.
 * All pointer arguments must be valid and properly aligned.
 */
 WapError wap_get_statistics(const struct WapAudioProcessing *apm, struct WapStats *stats_out);

#ifdef __cplusplus
}  // extern "C"
#endif  // __cplusplus

#endif  /* WAP_AUDIO_PROCESSING_H */