Files
BPI-CM9-Linux/aml-comp/vendor/amlogic/bluez-alsa/test/test-msbc.c
T

198 lines
4.1 KiB
C
Raw Normal View History

2026-08-13 11:28:40 +08:00
/*
* test-msbc.c
* SPDX-FileCopyrightText: 2016-2025 BlueALSA developers
* SPDX-License-Identifier: MIT
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <check.h>
#include <glib.h>
#include "codec-msbc.h"
#include "shared/defs.h"
#include "shared/ffb.h"
#include "shared/log.h"
#include "inc/check.inc"
#include "inc/sine.inc"
CK_START_TEST(test_msbc_init) {
struct esco_msbc msbc = { .initialized = false };
ck_assert_int_eq(msbc_init(&msbc), 0);
ck_assert_int_eq(msbc.initialized, true);
ck_assert_int_eq(ffb_len_out(&msbc.pcm), 0);
ffb_seek(&msbc.pcm, 16);
ck_assert_int_eq(ffb_len_out(&msbc.pcm), 16);
ck_assert_int_eq(msbc_init(&msbc), 0);
ck_assert_int_eq(msbc.initialized, true);
ck_assert_int_eq(ffb_len_out(&msbc.pcm), 0);
msbc_finish(&msbc);
} CK_END_TEST
CK_START_TEST(test_msbc_encode_decode) {
int16_t sine[8 * MSBC_CODESAMPLES];
snd_pcm_sine_s16_2le(sine, 1, ARRAYSIZE(sine), 1.0 / 128, 0);
uint8_t data[sizeof(sine)];
uint8_t *data_tail = data;
struct esco_msbc msbc = { 0 };
size_t len;
size_t i;
int rv;
msbc.initialized = false;
ck_assert_int_eq(msbc_init(&msbc), 0);
for (rv = 1, i = 0; rv > 0;) {
len = MIN(ARRAYSIZE(sine) - i, ffb_len_in(&msbc.pcm));
memcpy(msbc.pcm.tail, &sine[i], len * msbc.pcm.size);
ffb_seek(&msbc.pcm, len);
i += len;
rv = msbc_encode(&msbc);
len = ffb_blen_out(&msbc.data);
memcpy(data_tail, msbc.data.data, len);
ffb_rewind(&msbc.data);
data_tail += len;
}
ck_assert_int_eq(data_tail - data, 480);
msbc_finish(&msbc);
int16_t pcm[sizeof(sine)];
int16_t *pcm_tail = pcm;
msbc.initialized = false;
ck_assert_int_eq(msbc_init(&msbc), 0);
for (rv = 1, i = 0; rv > 0; ) {
len = MIN((data_tail - data) - i, ffb_blen_in(&msbc.data));
memcpy(msbc.data.tail, &data[i], len);
ffb_seek(&msbc.data, len);
i += len;
rv = msbc_decode(&msbc);
len = ffb_len_out(&msbc.pcm);
memcpy(pcm_tail, msbc.pcm.data, len * msbc.pcm.size);
ffb_rewind(&msbc.pcm);
pcm_tail += len;
}
ck_assert_int_eq(pcm_tail - pcm, 8 * MSBC_CODESAMPLES);
msbc_finish(&msbc);
} CK_END_TEST
CK_START_TEST(test_msbc_decode_plc) {
int16_t sine[18 * MSBC_CODESAMPLES];
snd_pcm_sine_s16_2le(sine, 1, ARRAYSIZE(sine), 1.0 / 128, 0);
struct esco_msbc msbc = { .initialized = false };
ck_assert_int_eq(msbc_init(&msbc), 0);
uint8_t data[sizeof(sine)];
uint8_t *data_tail = data;
debug("Simulating eSCO packet loss events");
int rv;
size_t counter, i;
for (rv = 1, counter = i = 0; rv > 0; counter++) {
bool packet_error = false;
size_t len = MIN(ARRAYSIZE(sine) - i, ffb_len_in(&msbc.pcm));
memcpy(msbc.pcm.tail, &sine[i], len * msbc.pcm.size);
ffb_seek(&msbc.pcm, len);
i += len;
rv = msbc_encode(&msbc);
len = ffb_blen_out(&msbc.data);
memcpy(data_tail, msbc.data.data, len);
ffb_rewind(&msbc.data);
/* simulate packet loss */
if (counter == 2 ||
(6 <= counter && counter <= 8) ||
/* 4 packets (undetectable) */
(12 <= counter && counter <= 15)) {
fprintf(stderr, "_");
continue;
}
/* simulate packet error */
if (counter == 4) {
data_tail[5] *= 0x07;
packet_error = true;
}
fprintf(stderr, packet_error ? "e" : "x");
data_tail += len;
}
fprintf(stderr, "\n");
/* reinitialize encoder/decoder handler */
ck_assert_int_eq(msbc_init(&msbc), 0);
size_t samples = 0;
for (rv = 1, i = 0; rv > 0; ) {
size_t len = MIN((data_tail - data) - i, ffb_blen_in(&msbc.data));
memcpy(msbc.data.tail, &data[i], len);
ffb_seek(&msbc.data, len);
i += len;
rv = msbc_decode(&msbc);
samples += ffb_len_out(&msbc.pcm);
ffb_rewind(&msbc.pcm);
}
/* we should recover all except consecutive 4 frames */
ck_assert_int_eq(samples, (18 - 4) * MSBC_CODESAMPLES);
msbc_finish(&msbc);
} CK_END_TEST
int main(void) {
Suite *s = suite_create(__FILE__);
TCase *tc = tcase_create(__FILE__);
SRunner *sr = srunner_create(s);
suite_add_tcase(s, tc);
tcase_add_test(tc, test_msbc_init);
tcase_add_test(tc, test_msbc_encode_decode);
tcase_add_test(tc, test_msbc_decode_plc);
srunner_run_all(sr, CK_ENV);
int nf = srunner_ntests_failed(sr);
srunner_free(sr);
return nf == 0 ? 0 : 1;
}