Asterisk - The Open Source Telephony Project GIT-master-4c84066
Loading...
Searching...
No Matches
Data Structures | Macros | Functions | Variables
test_codec_translations.c File Reference

Codec Translation Roundtrip Tests. More...

#include "asterisk.h"
#include <math.h>
#include "asterisk/module.h"
#include "asterisk/test.h"
#include "asterisk/translate.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
#include "asterisk/format_cache.h"
#include "asterisk/codec.h"
#include "asterisk/frame.h"
#include "asterisk/slin.h"
#include "asterisk/logger.h"
#include "asterisk/utils.h"
Include dependency graph for test_codec_translations.c:

Go to the source code of this file.

Data Structures

struct  codec_test_entry
 Codec roundtrip entry: table of codecs to test. More...
 

Macros

#define CHUNK_MS   20
 
#define MAX_SAMPLE_ERR_LOSSLESS   256
 
#define MIN_DECODED_RATIO   0.90
 
#define MIN_SNR_LOSSY_DB   15.0
 
#define TEST_DURATION_SECS   2
 

Functions

 AST_MODULE_INFO_STANDARD_EXTENDED (ASTERISK_GPL_KEY, "Codec Translation Roundtrip Tests")
 
 AST_TEST_DEFINE (codec_translate_roundtrip)
 
static enum ast_test_result_state check_codec (struct ast_test *test, struct ast_format *slin_fmt, struct ast_format *target_fmt, const int16_t *orig_buf, int total_samples, int sample_rate, int is_lossy, double min_snr_db)
 Attempt a roundtrip encode/decode for one codec format.
 
static int compute_max_error (const int16_t *orig, const int16_t *roundtrip, int samples)
 Compute maximum absolute per-sample error.
 
static double compute_snr (const int16_t *orig, const int16_t *roundtrip, int samples)
 Compute Signal-to-Noise Ratio between original and roundtripped signal.
 
static double compute_snr_aligned (const int16_t *orig, const int16_t *decoded, int samples, int max_delay, int *delay_out)
 Compute SNR after aligning the decoded signal via cross-correlation.
 
static void generate_speech_signal (int16_t *buf, int samples, int sample_rate)
 Generate a synthetic speech-like test signal in linear sample.
 
static int load_module (void)
 
static int unload_module (void)
 

Variables

static const struct codec_test_entry codec_table []
 

Detailed Description

Codec Translation Roundtrip Tests.

Author
Sebastian Jennen sebas.nosp@m.tian.nosp@m..t.je.nosp@m.nnen.nosp@m.@gmai.nosp@m.l.co.nosp@m.m

Tests that encoding sample frames through a codec and decoding them back to slin produces output that is (almost) identical to the original input. This verifies that each codec translator pair (slin -> codec -> slin) does not corrupt or destroy the audio signal.

For near-lossless codecs (alaw, ulaw) the tolerance is very tight. For lossy codecs (adpcm, g726, gsm, g722, speex, ilbc, opus, g729, etc.) a Signal-to-Noise Ratio (SNR) threshold is used since some degradation is inherent to the compression algorithm. Wideband codecs are tested with a matching slin16/slin32/slin48 signal at the codec's native sample rate.

Definition in file test_codec_translations.c.

Macro Definition Documentation

◆ CHUNK_MS

#define CHUNK_MS   20

Chunk duration in milliseconds to feed chunks to the coders

Definition at line 61 of file test_codec_translations.c.

◆ MAX_SAMPLE_ERR_LOSSLESS

#define MAX_SAMPLE_ERR_LOSSLESS   256

Maximum per-sample absolute error for near-lossless codecs (ulaw/alaw). μ-law/A-law quantisation can reach a max error of 256.

Definition at line 69 of file test_codec_translations.c.

◆ MIN_DECODED_RATIO

#define MIN_DECODED_RATIO   0.90

Minimum fraction of input samples that must survive the roundtrip. Codec lookahead + trailing partial frame may consume some samples; require at least 90 % to call the test valid.

Definition at line 74 of file test_codec_translations.c.

◆ MIN_SNR_LOSSY_DB

#define MIN_SNR_LOSSY_DB   15.0

Minimum acceptable SNR in dB for lossy codecs. Most telephony codecs at 8 kHz should exceed ~20 dB

Definition at line 65 of file test_codec_translations.c.

◆ TEST_DURATION_SECS

#define TEST_DURATION_SECS   2

Duration of the test signal in seconds

Definition at line 58 of file test_codec_translations.c.

Function Documentation

◆ AST_MODULE_INFO_STANDARD_EXTENDED()

AST_MODULE_INFO_STANDARD_EXTENDED ( ASTERISK_GPL_KEY  ,
"Codec Translation Roundtrip Tests"   
)

◆ AST_TEST_DEFINE()

AST_TEST_DEFINE ( codec_translate_roundtrip  )

Definition at line 435 of file test_codec_translations.c.

436{
437 int i;
438 int tested = 0;
439 int failed = 0;
441
442 switch (cmd) {
443 case TEST_INIT:
444 info->name = "codec_translations";
445 info->category = "/main/codec/";
446 info->summary = "Roundtrip encode/decode test and quality check for various codecs referenced in this test and present in the installation";
447 info->description =
448 "Generates a synthetic speech-like signal (200 Hz +\n"
449 "800 Hz with 4 Hz AM envelope) at the codec's native sample\n"
450 "rate, feeds it through the codec and back,\n"
451 "then verifies the output quality over the full duration.\n"
452 "For near-lossless codecs (ulaw, alaw) it checks that the\n"
453 "maximum per-sample error is within a tight bound.\n"
454 "For lossy codecs it checks that the SNR exceeds a per-codec\n"
455 "minimum threshold. Vocoders use a near-zero threshold\n"
456 "(smoke test).";
457 return AST_TEST_NOT_RUN;
458 case TEST_EXECUTE:
459 break;
460 }
461
463 "Starting codec roundtrip tests (%d codecs, %d seconds of audio)\n",
465
466 for (i = 0; i < (int)ARRAY_LEN(codec_table); i++) {
467 struct ast_format *slin_fmt;
468 struct ast_format *target_fmt;
469 int16_t *orig_buf;
470 enum ast_test_result_state res;
471 int rate = codec_table[i].sample_rate > 0
472 ? codec_table[i].sample_rate : 8000;
473 int total_samples = rate * TEST_DURATION_SECS;
474
475 /* Select the slin format for this codec's native rate */
476 switch (rate) {
477 case 16000:
478 slin_fmt = ast_format_slin16;
479 break;
480 case 32000:
481 slin_fmt = ast_format_slin32;
482 break;
483 case 48000:
484 slin_fmt = ast_format_slin48;
485 break;
486 default:
487 slin_fmt = ast_format_slin;
488 break;
489 }
490
491 target_fmt = ast_format_cache_get(codec_table[i].format_name);
492 if (!target_fmt
493 || ast_translate_path_steps(target_fmt, slin_fmt) == -1) {
495 " %s: no translation path available, skipping\n",
496 codec_table[i].format_name);
497 ao2_cleanup(target_fmt);
498 continue;
499 }
500
501 orig_buf = ast_malloc(total_samples * sizeof(int16_t));
502 if (!orig_buf) {
503 ao2_ref(target_fmt, -1);
504 overall = AST_TEST_FAIL;
505 break;
506 }
507
508 generate_speech_signal(orig_buf, total_samples, rate);
509
510 res = check_codec(
511 test, slin_fmt, target_fmt, orig_buf,
512 total_samples, rate,
513 codec_table[i].is_lossy,
514 codec_table[i].min_snr_db != 0.0
515 ? codec_table[i].min_snr_db : MIN_SNR_LOSSY_DB);
516
517 ast_free(orig_buf);
518 ao2_ref(target_fmt, -1);
519
520 tested++;
521 if (res == AST_TEST_FAIL) {
522 failed++;
523 overall = AST_TEST_FAIL;
524 }
525 }
526
528 "\nCodec roundtrip summary: %d tested, %d passed, %d failed\n",
529 tested, tested - failed, failed);
530
531 if (tested == 0) {
533 "WARNING: No codecs were available to test. "
534 "Ensure codec modules are loaded.\n");
535 }
536
537 return overall;
538}
#define ast_free(a)
Definition astmm.h:180
#define ast_malloc(len)
A wrapper for malloc()
Definition astmm.h:191
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
struct ast_format * ast_format_slin32
Built-in cached signed linear 32kHz format.
struct ast_format * ast_format_slin16
Built-in cached signed linear 16kHz format.
struct ast_format * ast_format_slin48
Built-in cached signed linear 48kHz format.
#define ast_format_cache_get(name)
Retrieve a named format from the cache.
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition of a media format.
Definition format.c:43
int sample_rate
@ TEST_INIT
Definition test.h:200
@ TEST_EXECUTE
Definition test.h:201
#define ast_test_status_update(a, b, c...)
Definition test.h:129
ast_test_result_state
Definition test.h:193
@ AST_TEST_PASS
Definition test.h:195
@ AST_TEST_FAIL
Definition test.h:196
@ AST_TEST_NOT_RUN
Definition test.h:194
static void generate_speech_signal(int16_t *buf, int samples, int sample_rate)
Generate a synthetic speech-like test signal in linear sample.
#define MIN_SNR_LOSSY_DB
static enum ast_test_result_state check_codec(struct ast_test *test, struct ast_format *slin_fmt, struct ast_format *target_fmt, const int16_t *orig_buf, int total_samples, int sample_rate, int is_lossy, double min_snr_db)
Attempt a roundtrip encode/decode for one codec format.
#define TEST_DURATION_SECS
static const struct codec_test_entry codec_table[]
unsigned int ast_translate_path_steps(struct ast_format *dest, struct ast_format *src)
Returns the number of steps required to convert from 'src' to 'dest'.
Definition translate.c:1810
#define ARRAY_LEN(a)
Definition utils.h:706

References ao2_cleanup, ao2_ref, ARRAY_LEN, ast_format_cache_get, ast_format_slin, ast_format_slin16, ast_format_slin32, ast_format_slin48, ast_free, ast_malloc, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_translate_path_steps(), check_codec(), codec_table, generate_speech_signal(), MIN_SNR_LOSSY_DB, codec_test_entry::sample_rate, TEST_DURATION_SECS, TEST_EXECUTE, and TEST_INIT.

◆ check_codec()

static enum ast_test_result_state check_codec ( struct ast_test *  test,
struct ast_format slin_fmt,
struct ast_format target_fmt,
const int16_t *  orig_buf,
int  total_samples,
int  sample_rate,
int  is_lossy,
double  min_snr_db 
)
static

Attempt a roundtrip encode/decode for one codec format.

Feeds the original slin signal through the encoder and decoder in 20 ms chunks (matching the universal VoIP frame duration), accumulates the decoded output, and compares the full result against the original. This naturally respects every codec's internal buffer sizes and frame granularity without needing per-codec sample-count overrides.

Parameters
[in]testTest framework handle (for status messages)
[in]slin_fmtThe slin format appropriate for the codec's sample rate
[in]target_fmtThe codec format to test
[in]orig_bufOriginal slin sample buffer
[in]total_samplesNumber of samples in orig_buf
[in]sample_rateSample rate in Hz
[in]is_lossyIf non-zero, use SNR-based comparison; otherwise use max-error
[in]min_snr_dbMinimum acceptable SNR for lossy check (ignored when !is_lossy)
Return values
AST_TEST_PASSon success
AST_TEST_FAILon failure

Definition at line 228 of file test_codec_translations.c.

237{
238 struct ast_trans_pvt *encode_path = NULL;
239 struct ast_trans_pvt *decode_path = NULL;
240 int16_t *decoded_buf = NULL;
241 int total_decoded = 0;
242 int chunk_samples = sample_rate * CHUNK_MS / 1000;
243 int buf_capacity;
244 int offset;
246 const char *codec_name;
247
248 codec_name = ast_format_get_name(target_fmt);
249
250 /* --- Build encoder path: slin -> codec --- */
251 encode_path = ast_translator_build_path(target_fmt, slin_fmt);
252 if (!encode_path) {
254 "Skipping %s: no translation path from slin to %s\n",
255 codec_name, codec_name);
256 return AST_TEST_PASS;
257 }
258
259 /* --- Build decoder path: codec -> slin --- */
260 decode_path = ast_translator_build_path(slin_fmt, target_fmt);
261 if (!decode_path) {
263 "FAIL %s: found encoder but no decoder path back to slin\n",
264 codec_name);
265 goto cleanup;
266 }
267
268 /* Allocate output buffer with some headroom for codec expansion */
269 buf_capacity = total_samples + chunk_samples;
270 decoded_buf = ast_calloc(buf_capacity, sizeof(int16_t));
271 if (!decoded_buf) {
272 goto cleanup;
273 }
274
275 /* --- Feed audio in CHUNK_MS chunks through encode -> decode --- */
276 for (offset = 0; offset < total_samples; offset += chunk_samples) {
277 struct ast_frame input_frame;
278 struct ast_frame *encoded;
279 struct ast_frame *decoded;
280 struct ast_frame *cur;
281 int feed = total_samples - offset;
282 if (feed > chunk_samples) {
283 feed = chunk_samples;
284 }
285
286 memset(&input_frame, 0, sizeof(input_frame));
287 input_frame.frametype = AST_FRAME_VOICE;
288 input_frame.subclass.format = slin_fmt;
289 input_frame.datalen = feed * sizeof(int16_t);
290 input_frame.samples = feed;
291 input_frame.data.ptr = (void *)(orig_buf + offset);
292 input_frame.mallocd = 0;
293 input_frame.src = "test_codec_translations";
294
295 /* Encode: slin -> codec. NULL means the encoder is buffering. */
296 encoded = ast_translate(encode_path, &input_frame, 0);
297 if (!encoded) {
298 continue;
299 }
300
301 /* Decode: codec -> slin. ast_translate follows the frame linked
302 * list internally, so passing the head feeds all encoded frames. */
303 decoded = ast_translate(decode_path, encoded, 0);
304 if (!decoded) {
305 continue;
306 }
307
308 /* Copy decoded samples into our accumulation buffer.
309 * Walk the linked list in case frameout produced multiple frames. */
310 for (cur = decoded; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
311 int copy;
312 if (cur->frametype != AST_FRAME_VOICE || !cur->data.ptr
313 || cur->samples <= 0) {
314 continue;
315 }
316 copy = cur->samples;
317 if (total_decoded + copy > buf_capacity) {
318 copy = buf_capacity - total_decoded;
319 }
320 memcpy(decoded_buf + total_decoded, cur->data.ptr,
321 copy * sizeof(int16_t));
322 total_decoded += copy;
323 }
324 }
325
326 /* --- Verify we got enough decoded audio --- */
327 if (total_decoded < (int)(total_samples * MIN_DECODED_RATIO)) {
329 "FAIL %s: decoded only %d of %d samples (%.0f%%)\n",
330 codec_name, total_decoded, total_samples,
331 100.0 * total_decoded / total_samples);
332 goto cleanup;
333 }
334
335 /* --- Compare original vs decoded --- */
336 {
337 int cmp_samples = total_decoded < total_samples
338 ? total_decoded : total_samples;
339
340 if (is_lossy) {
341 int max_delay = sample_rate * 20 / 1000; /* 20 ms search */
342 int delay = 0;
343 double snr = compute_snr_aligned(orig_buf, decoded_buf,
344 cmp_samples, max_delay, &delay);
345
347 " %s (lossy): SNR = %.1f dB (threshold %.1f dB)"
348 " [%d/%d samples, delay=%d/%.1fms]\n",
349 codec_name, snr, min_snr_db,
350 cmp_samples, total_samples,
351 delay, 1000.0 * delay / sample_rate);
352
353 if (snr < min_snr_db) {
355 "FAIL %s: SNR %.1f dB is below minimum %.1f dB\n",
356 codec_name, snr, min_snr_db);
357 goto cleanup;
358 }
359 } else {
360 int max_err = compute_max_error(orig_buf, decoded_buf, cmp_samples);
361 double snr = compute_snr(orig_buf, decoded_buf, cmp_samples);
362
364 " %s (lossless): max_err = %d (limit %d),"
365 " SNR = %.1f dB [%d/%d samples]\n",
366 codec_name, max_err, MAX_SAMPLE_ERR_LOSSLESS, snr,
367 cmp_samples, total_samples);
368
369 if (max_err > MAX_SAMPLE_ERR_LOSSLESS) {
371 "FAIL %s: max sample error %d exceeds limit %d\n",
372 codec_name, max_err, MAX_SAMPLE_ERR_LOSSLESS);
373 goto cleanup;
374 }
375 }
376 }
377
379
380cleanup:
381 ast_free(decoded_buf);
382 if (encode_path) {
383 ast_translator_free_path(encode_path);
384 }
385 if (decode_path) {
386 ast_translator_free_path(decode_path);
387 }
388
389 return result;
390}
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
static PGresult * result
Definition cel_pgsql.c:84
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition format.c:334
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
static void cleanup(void)
Clean up any old apps that we don't need any more.
Definition res_stasis.c:327
#define NULL
Definition resample.c:96
Data structure associated with a single frame of data.
enum ast_frame_type frametype
union ast_frame::@235 data
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition translate.h:213
static double compute_snr_aligned(const int16_t *orig, const int16_t *decoded, int samples, int max_delay, int *delay_out)
Compute SNR after aligning the decoded signal via cross-correlation.
#define MIN_DECODED_RATIO
#define CHUNK_MS
static double compute_snr(const int16_t *orig, const int16_t *roundtrip, int samples)
Compute Signal-to-Noise Ratio between original and roundtripped signal.
#define MAX_SAMPLE_ERR_LOSSLESS
static int compute_max_error(const int16_t *orig, const int16_t *roundtrip, int samples)
Compute maximum absolute per-sample error.
struct ast_frame * ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume)
translates one or more frames Apply an input frame into the translator and receive zero or one output...
Definition translate.c:623
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition translate.c:533
struct ast_trans_pvt * ast_translator_build_path(struct ast_format *dest, struct ast_format *source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition translate.c:543

References ast_calloc, ast_format_get_name(), AST_FRAME_VOICE, ast_free, AST_LIST_NEXT, AST_TEST_FAIL, AST_TEST_PASS, ast_test_status_update, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), CHUNK_MS, cleanup(), compute_max_error(), compute_snr(), compute_snr_aligned(), copy(), ast_frame::data, ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, ast_frame::mallocd, MAX_SAMPLE_ERR_LOSSLESS, MIN_DECODED_RATIO, NULL, ast_frame::offset, ast_frame::ptr, result, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

Referenced by AST_TEST_DEFINE().

◆ compute_max_error()

static int compute_max_error ( const int16_t *  orig,
const int16_t *  roundtrip,
int  samples 
)
static

Compute maximum absolute per-sample error.

Definition at line 193 of file test_codec_translations.c.

194{
195 int max_err = 0;
196 int i;
197
198 for (i = 0; i < samples; i++) {
199 int err = abs((int)orig[i] - (int)roundtrip[i]);
200 if (err > max_err) {
201 max_err = err;
202 }
203 }
204 return max_err;
205}
#define abs(x)
Definition f2c.h:195

References abs.

Referenced by check_codec().

◆ compute_snr()

static double compute_snr ( const int16_t *  orig,
const int16_t *  roundtrip,
int  samples 
)
static

Compute Signal-to-Noise Ratio between original and roundtripped signal.

Parameters
[in]origOriginal sample buffer
[in]roundtripDecoded (roundtripped) sample buffer
[in]samplesNumber of samples
Returns
SNR in dB

Definition at line 109 of file test_codec_translations.c.

110{
111 double signal_power = 0.0;
112 double noise_power = 0.0;
113 int i;
114
115 for (i = 0; i < samples; i++) {
116 double s = (double)orig[i];
117 double n = (double)(orig[i] - roundtrip[i]);
118 signal_power += s * s;
119 noise_power += n * n;
120 }
121
122 if (signal_power < 1.0) {
123 return -100.0; /* degenerate signal */
124 }
125 if (noise_power < 1.0) {
126 return 999.0; /* essentially perfect */
127 }
128
129 return 10.0 * log10(signal_power / noise_power);
130}

Referenced by check_codec(), and compute_snr_aligned().

◆ compute_snr_aligned()

static double compute_snr_aligned ( const int16_t *  orig,
const int16_t *  decoded,
int  samples,
int  max_delay,
int *  delay_out 
)
static

Compute SNR after aligning the decoded signal via cross-correlation.

Some codecs (e.g. speex, opus) introduce an algorithmic lookahead delay: the decoded signal is time-shifted by a fixed number of samples relative to the original. Computing SNR without compensating for this shift yields a near-zero result even when the codec works perfectly.

This function searches delays d = 0..max_delay, finds the integer shift that maximises the cross-correlation sum orig[i]·decoded[i+d], then returns the SNR computed at that optimal alignment.

Parameters
[in]origOriginal sample buffer (must hold at least samples values)
[in]decodedDecoded sample buffer (must hold at least samples values)
[in]samplesNumber of samples available in each buffer
[in]max_delaySearch range: delays 0..max_delay are tested
[out]delay_outReceives the best-fit delay found; may be NULL
Returns
SNR in dB at the best-fit alignment, or the unaligned SNR when samples <= max_delay

Definition at line 153 of file test_codec_translations.c.

155{
156 double best_corr = -1e300;
157 int best_delay = 0;
158 int d;
159
160 if (delay_out) {
161 *delay_out = 0;
162 }
163
164 /* Need enough samples for a meaningful search */
165 if (samples <= max_delay || max_delay <= 0) {
166 return compute_snr(orig, decoded, samples);
167 }
168
169 for (d = 0; d <= max_delay; d++) {
170 int n = samples - d;
171 double corr = 0.0;
172 int i;
173 for (i = 0; i < n; i++) {
174 corr += (double)orig[i] * (double)decoded[i + d];
175 }
176 if (corr > best_corr) {
177 best_corr = corr;
178 best_delay = d;
179 }
180 }
181
182 if (delay_out) {
183 *delay_out = best_delay;
184 }
185
186 /* Compute SNR at the best alignment */
187 return compute_snr(orig, decoded + best_delay, samples - best_delay);
188}
static struct test_val d

References compute_snr(), and d.

Referenced by check_codec().

◆ generate_speech_signal()

static void generate_speech_signal ( int16_t *  buf,
int  samples,
int  sample_rate 
)
static

Generate a synthetic speech-like test signal in linear sample.

a mix of a 200 Hz fundamental and an 800 Hz harmonic with a slow 4 Hz amplitude-modulation envelope, loosely inspired by ITU-T P.50 artificial voice.

Parameters
[out]bufBuffer to fill (must hold at least samples int16 values)
[in]samplesNumber of samples to generate
[in]sample_rateSampling rate in Hz (used to scale time correctly)

Definition at line 87 of file test_codec_translations.c.

88{
89 int i;
90 for (i = 0; i < samples; i++) {
91 double t = (double)i / sample_rate;
92 double sig = 0.6 * sin(2.0 * M_PI * 200.0 * t)
93 + 0.4 * sin(2.0 * M_PI * 800.0 * t);
94 /* Slow AM at 4 Hz to simulate syllable rhythm */
95 sig *= 0.5 * (1.0 + sin(2.0 * M_PI * 4.0 * t));
96 buf[i] = (int16_t)(sig * 16000.0);
97 }
98}
char buf[BUFSIZE]
Definition eagi_proxy.c:66
#define M_PI
Definition resample.c:83

References buf, and M_PI.

Referenced by AST_TEST_DEFINE().

◆ load_module()

static int load_module ( void  )
static

Definition at line 546 of file test_codec_translations.c.

547{
548 AST_TEST_REGISTER(codec_translate_roundtrip);
550}
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
#define AST_TEST_REGISTER(cb)
Definition test.h:127

References AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 540 of file test_codec_translations.c.

541{
542 AST_TEST_UNREGISTER(codec_translate_roundtrip);
543 return 0;
544}
#define AST_TEST_UNREGISTER(cb)
Definition test.h:128

References AST_TEST_UNREGISTER.

Variable Documentation

◆ codec_table

const struct codec_test_entry codec_table[]
static

Table of codecs to roundtrip-test.

Definition at line 403 of file test_codec_translations.c.

403 {
404 /* Near-lossless narrowband (8 kHz) — verified with max per-sample error */
405 { "ulaw", 0 },
406 { "alaw", 0 },
407
408 /* Lossy narrowband (8 kHz) — verified with SNR threshold */
409 { "adpcm", 1 }, /* ADPCM: ~20 dB SNR, lossy by design */
410 { "g726", 1 }, /* G.726 ADPCM: ~28 dB SNR, lossy by design */
411 { "g726aal2", 1 }, /* G.726 AAL2 ADPCM: same as g726 */
412 { "gsm", 1 },
413 { "speex", 1, 7.0 }, /* speex is quite lossy */
414 { "ilbc", 1, 7.0 }, /* 30 ms frames: coarser quantisation lowers SNR floor */
415 { "codec2", 1, -2.0 }, /* vocoder: snr is really low, smoke-test only */
416 { "lpc10", 1, -2.0 }, /* vocoder: snr is really low, smoke-test only */
417
418 /* { "g729", 1 }, UNTESTED yet */
419 /* { "silk8", 1 }, UNTESTED yet */
420 /* { "silk12", 1 }, UNTESTED yet */
421 /* { "silk16", 1 }, UNTESTED yet */
422 /* { "silk24", 1 }, UNTESTED yet */
423
424 /* Wideband (16 kHz) — tested with slin16 signal. */
425 { "g722", 1, 0.0, 16000 },
426 { "speex16", 1, 5.0, 16000 },
427
428 /* Ultra-wideband (32 kHz) — tested with slin32 signal */
429 { "speex32", 1, 5.0, 32000 },
430
431 /* Opus native rate is 48 kHz */
432 { "opus", 1, 8.0, 48000 },
433};

Referenced by AST_TEST_DEFINE().