432 lines
16 KiB
C
432 lines
16 KiB
C
/*
|
|
* test-a2dp.c
|
|
* SPDX-FileCopyrightText: 2016-2025 BlueALSA developers
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#if HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include <errno.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <check.h>
|
|
#include <glib.h>
|
|
|
|
#include "a2dp.h"
|
|
#include "a2dp-aac.h"
|
|
#include "a2dp-aptx.h"
|
|
#include "a2dp-faststream.h"
|
|
#include "a2dp-sbc.h"
|
|
#include "ba-config.h"
|
|
#include "codec-sbc.h"
|
|
#include "error.h"
|
|
#include "shared/a2dp-codecs.h"
|
|
#include "shared/defs.h"
|
|
#include "shared/log.h"
|
|
|
|
#include "inc/check.inc"
|
|
|
|
CK_START_TEST(test_a2dp_codecs_codec_id_from_string) {
|
|
ck_assert_uint_eq(a2dp_codecs_codec_id_from_string("SBC"), A2DP_CODEC_SBC);
|
|
ck_assert_uint_eq(a2dp_codecs_codec_id_from_string("apt-x"),
|
|
A2DP_CODEC_VENDOR_ID(APTX_VENDOR_ID, APTX_CODEC_ID));
|
|
ck_assert_uint_eq(a2dp_codecs_codec_id_from_string("unknown"), 0xFFFFFFFF);
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_codecs_codec_id_to_string) {
|
|
ck_assert_str_eq(a2dp_codecs_codec_id_to_string(A2DP_CODEC_SBC), "SBC");
|
|
const uint32_t vendor_codec_id = A2DP_CODEC_VENDOR_ID(APTX_VENDOR_ID, APTX_CODEC_ID);
|
|
ck_assert_str_eq(a2dp_codecs_codec_id_to_string(vendor_codec_id), "aptX");
|
|
ck_assert_ptr_eq(a2dp_codecs_codec_id_to_string(0xFFFFFFFF), NULL);
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_codecs_get_canonical_name) {
|
|
ck_assert_str_eq(a2dp_codecs_get_canonical_name("apt-x"), "aptX");
|
|
ck_assert_str_eq(a2dp_codecs_get_canonical_name("Foo-Bar"), "Foo-Bar");
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_type) {
|
|
ck_assert_int_eq(A2DP_SOURCE, !A2DP_SINK);
|
|
ck_assert_int_eq(!A2DP_SOURCE, A2DP_SINK);
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_seps_init) {
|
|
a2dp_seps_init();
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_sep_ptr_cmp) {
|
|
|
|
struct a2dp_sep c1 = { .config = { .type = A2DP_SOURCE, .codec_id = A2DP_CODEC_SBC } };
|
|
struct a2dp_sep c2 = { .config = { .type = A2DP_SOURCE, .codec_id = A2DP_CODEC_MPEG24 } };
|
|
struct a2dp_sep c3 = { .config = {
|
|
.type = A2DP_SOURCE,
|
|
.codec_id = A2DP_CODEC_VENDOR_ID(APTX_VENDOR_ID, APTX_CODEC_ID) } };
|
|
struct a2dp_sep c4 = { .config = { .type = A2DP_SINK, .codec_id = A2DP_CODEC_SBC } };
|
|
struct a2dp_sep c5 = { .config = {
|
|
.type = A2DP_SINK,
|
|
.codec_id = A2DP_CODEC_VENDOR_ID(APTX_VENDOR_ID, APTX_CODEC_ID) } };
|
|
struct a2dp_sep c6 = { .config = {
|
|
.type = A2DP_SINK,
|
|
.codec_id = A2DP_CODEC_VENDOR_ID(LDAC_VENDOR_ID, LDAC_CODEC_ID) } };
|
|
struct a2dp_sep c7 = { .config = { .type = A2DP_SINK, .codec_id = 0xFFFFFFFF } };
|
|
|
|
struct a2dp_sep * codecs[] = { &c3, &c1, &c6, &c4, &c7, &c5, &c2 };
|
|
qsort(codecs, ARRAYSIZE(codecs), sizeof(*codecs), QSORT_COMPAR(a2dp_sep_ptr_cmp));
|
|
|
|
ck_assert_ptr_eq(codecs[0], &c1);
|
|
ck_assert_ptr_eq(codecs[1], &c2);
|
|
ck_assert_ptr_eq(codecs[2], &c3);
|
|
ck_assert_ptr_eq(codecs[3], &c4);
|
|
ck_assert_ptr_eq(codecs[4], &c5);
|
|
ck_assert_ptr_eq(codecs[5], &c6);
|
|
ck_assert_ptr_eq(codecs[6], &c7);
|
|
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_sep_lookup) {
|
|
ck_assert_ptr_eq(a2dp_sep_lookup(A2DP_SOURCE, A2DP_CODEC_SBC), &a2dp_sbc_source);
|
|
ck_assert_ptr_eq(a2dp_sep_lookup(A2DP_SOURCE, 0xFFFFFFFF), NULL);
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_get_vendor_codec_id) {
|
|
|
|
uint8_t cfg0[4] = { 0xDE, 0xAD, 0xB0, 0xBE };
|
|
ck_assert_int_eq(a2dp_get_vendor_codec_id(cfg0, sizeof(cfg0)), 0xFFFFFFFF);
|
|
ck_assert_int_eq(errno, EINVAL);
|
|
|
|
a2dp_aptx_t cfg1 = { A2DP_VENDOR_INFO_INIT(APTX_VENDOR_ID, APTX_CODEC_ID), 0, 0 };
|
|
ck_assert_int_eq(
|
|
a2dp_get_vendor_codec_id(&cfg1, sizeof(cfg1)),
|
|
A2DP_CODEC_VENDOR_ID(APTX_VENDOR_ID, APTX_CODEC_ID));
|
|
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_check_configuration) {
|
|
|
|
const a2dp_sbc_t cfg_valid = {
|
|
.sampling_freq = SBC_SAMPLING_FREQ_44100,
|
|
.channel_mode = SBC_CHANNEL_MODE_STEREO,
|
|
.block_length = SBC_BLOCK_LENGTH_8,
|
|
.subbands = SBC_SUBBANDS_8,
|
|
.allocation_method = SBC_ALLOCATION_SNR,
|
|
.min_bitpool = 42,
|
|
.max_bitpool = 62,
|
|
};
|
|
|
|
ck_assert_int_eq(a2dp_check_configuration(&a2dp_sbc_source,
|
|
&cfg_valid, sizeof(cfg_valid) + 1), ERROR_CODE_INVALID_SIZE);
|
|
|
|
ck_assert_int_eq(a2dp_check_configuration(&a2dp_sbc_source,
|
|
&cfg_valid, sizeof(cfg_valid)), ERROR_CODE_OK);
|
|
|
|
const a2dp_sbc_t cfg_invalid = {
|
|
.sampling_freq = SBC_SAMPLING_FREQ_16000 | SBC_SAMPLING_FREQ_44100,
|
|
.channel_mode = SBC_CHANNEL_MODE_STEREO | SBC_CHANNEL_MODE_JOINT_STEREO,
|
|
.block_length = SBC_BLOCK_LENGTH_8,
|
|
.allocation_method = SBC_ALLOCATION_SNR,
|
|
};
|
|
|
|
ck_assert_int_eq(a2dp_check_configuration(&a2dp_sbc_source,
|
|
&cfg_invalid, sizeof(cfg_invalid)), ERROR_CODE_A2DP_INVALID_SAMPLE_RATE);
|
|
|
|
#if ENABLE_AAC
|
|
a2dp_aac_t cfg_aac_invalid = {
|
|
/* FDK-AAC encoder does not support AAC Long Term Prediction */
|
|
.object_type = AAC_OBJECT_TYPE_MPEG4_LTP,
|
|
A2DP_AAC_INIT_SAMPLING_FREQ(AAC_SAMPLING_FREQ_44100)
|
|
.channel_mode = AAC_CHANNEL_MODE_MONO };
|
|
ck_assert_int_eq(a2dp_check_configuration(&a2dp_aac_source,
|
|
&cfg_aac_invalid, sizeof(cfg_aac_invalid)), ERROR_CODE_A2DP_INVALID_OBJECT_TYPE);
|
|
#endif
|
|
|
|
#if ENABLE_FASTSTREAM
|
|
|
|
a2dp_faststream_t cfg_faststream = {
|
|
.info = A2DP_VENDOR_INFO_INIT(FASTSTREAM_VENDOR_ID, FASTSTREAM_CODEC_ID) };
|
|
|
|
/* FastStream codec requires at least one direction to be set. */
|
|
ck_assert_int_eq(a2dp_check_configuration(&a2dp_faststream_source,
|
|
&cfg_faststream, sizeof(cfg_faststream)), ERROR_CODE_A2DP_INVALID_DIRECTIONS);
|
|
|
|
/* Check for valid unidirectional configuration. */
|
|
cfg_faststream.direction |= FASTSTREAM_DIRECTION_MUSIC;
|
|
cfg_faststream.sampling_freq_music = FASTSTREAM_SAMPLING_FREQ_MUSIC_44100;
|
|
ck_assert_int_eq(a2dp_check_configuration(&a2dp_faststream_source,
|
|
&cfg_faststream, sizeof(cfg_faststream)), ERROR_CODE_OK);
|
|
|
|
/* Check for valid bidirectional configuration. */
|
|
cfg_faststream.direction |= FASTSTREAM_DIRECTION_VOICE;
|
|
cfg_faststream.sampling_freq_voice = FASTSTREAM_SAMPLING_FREQ_VOICE_16000;
|
|
ck_assert_int_eq(a2dp_check_configuration(&a2dp_faststream_source,
|
|
&cfg_faststream, sizeof(cfg_faststream)), ERROR_CODE_OK);
|
|
|
|
#endif
|
|
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_caps) {
|
|
|
|
struct a2dp_sep * const * seps = a2dp_seps;
|
|
for (const struct a2dp_sep *sep = *seps; sep != NULL; sep = *++seps) {
|
|
debug("%s", sep->name);
|
|
|
|
/* Check whether all capability helpers are set. */
|
|
|
|
ck_assert_ptr_ne(sep->caps_helpers, NULL);
|
|
ck_assert_ptr_ne(sep->caps_helpers->intersect, NULL);
|
|
ck_assert_ptr_ne(sep->caps_helpers->has_stream, NULL);
|
|
ck_assert_ptr_ne(sep->caps_helpers->foreach_channel_mode, NULL);
|
|
ck_assert_ptr_ne(sep->caps_helpers->foreach_sample_rate, NULL);
|
|
ck_assert_ptr_ne(sep->caps_helpers->select_channel_mode, NULL);
|
|
ck_assert_ptr_ne(sep->caps_helpers->select_sample_rate, NULL);
|
|
|
|
/* Run smoke tests for all capability helpers. */
|
|
|
|
a2dp_t caps = sep->config.capabilities;
|
|
sep->caps_helpers->intersect(&caps, &sep->config.capabilities);
|
|
|
|
/* All our SEPs shall support the MAIN stream. The BACKCHANNEL
|
|
* stream is optional, though. */
|
|
|
|
ck_assert_uint_eq(sep->caps_helpers->has_stream(&caps, A2DP_MAIN), true);
|
|
sep->caps_helpers->has_stream(&caps, A2DP_BACKCHANNEL);
|
|
|
|
unsigned int channel_mode = 0;
|
|
sep->caps_helpers->foreach_channel_mode(&caps, A2DP_MAIN,
|
|
a2dp_bit_mapping_foreach_get_best_channel_mode, &channel_mode);
|
|
sep->caps_helpers->foreach_channel_mode(&caps, A2DP_BACKCHANNEL,
|
|
a2dp_bit_mapping_foreach_get_best_channel_mode, &channel_mode);
|
|
|
|
unsigned int sampling_freq = 0;
|
|
sep->caps_helpers->foreach_sample_rate(&caps, A2DP_MAIN,
|
|
a2dp_bit_mapping_foreach_get_best_sample_rate, &sampling_freq);
|
|
sep->caps_helpers->foreach_sample_rate(&caps, A2DP_BACKCHANNEL,
|
|
a2dp_bit_mapping_foreach_get_best_sample_rate, &sampling_freq);
|
|
|
|
sep->caps_helpers->select_channel_mode(&caps, A2DP_MAIN, 2);
|
|
sep->caps_helpers->select_channel_mode(&caps, A2DP_BACKCHANNEL, 1);
|
|
|
|
sep->caps_helpers->select_sample_rate(&caps, A2DP_MAIN, 48000);
|
|
sep->caps_helpers->select_sample_rate(&caps, A2DP_BACKCHANNEL, 16000);
|
|
|
|
}
|
|
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_caps_intersect) {
|
|
|
|
a2dp_sbc_t caps_sbc = {
|
|
.sampling_freq = SBC_SAMPLING_FREQ_44100,
|
|
.channel_mode = SBC_CHANNEL_MODE_MONO | SBC_CHANNEL_MODE_STEREO,
|
|
.block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8,
|
|
.subbands = SBC_SUBBANDS_4,
|
|
.allocation_method = SBC_ALLOCATION_SNR,
|
|
.min_bitpool = 42,
|
|
.max_bitpool = 255,
|
|
};
|
|
|
|
#if ENABLE_APTX
|
|
a2dp_aptx_t caps_aptx = {
|
|
.info = A2DP_VENDOR_INFO_INIT(APTX_VENDOR_ID, APTX_CODEC_ID),
|
|
.sampling_freq = APTX_SAMPLING_FREQ_32000 | APTX_SAMPLING_FREQ_44100,
|
|
.channel_mode = APTX_CHANNEL_MODE_MONO | APTX_CHANNEL_MODE_STEREO,
|
|
};
|
|
#endif
|
|
|
|
hexdump("Capabilities A", &caps_sbc, sizeof(caps_sbc));
|
|
hexdump("Capabilities B", &a2dp_sbc_source.config.capabilities, sizeof(caps_sbc));
|
|
a2dp_sbc_source.caps_helpers->intersect(&caps_sbc, &a2dp_sbc_source.config.capabilities);
|
|
|
|
hexdump("Intersection", &caps_sbc, sizeof(caps_sbc));
|
|
ck_assert_int_eq(caps_sbc.sampling_freq, SBC_SAMPLING_FREQ_44100);
|
|
ck_assert_int_eq(caps_sbc.channel_mode, SBC_CHANNEL_MODE_MONO | SBC_CHANNEL_MODE_STEREO);
|
|
ck_assert_int_eq(caps_sbc.block_length, SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8);
|
|
ck_assert_int_eq(caps_sbc.subbands, SBC_SUBBANDS_4);
|
|
ck_assert_int_eq(caps_sbc.allocation_method, SBC_ALLOCATION_SNR);
|
|
ck_assert_int_eq(caps_sbc.min_bitpool, MAX(SBC_MIN_BITPOOL, 42));
|
|
ck_assert_int_eq(caps_sbc.max_bitpool, MIN(SBC_MAX_BITPOOL, 255));
|
|
|
|
#if ENABLE_APTX
|
|
/* Check whether generic bitwise AND intersection works correctly. */
|
|
hexdump("Capabilities A", &caps_aptx, sizeof(caps_aptx));
|
|
hexdump("Capabilities B", &a2dp_aptx_source.config.capabilities, sizeof(caps_aptx));
|
|
a2dp_aptx_source.caps_helpers->intersect(&caps_aptx, &a2dp_aptx_source.config.capabilities);
|
|
hexdump("Intersection", &caps_aptx, sizeof(caps_aptx));
|
|
ck_assert_int_eq(caps_aptx.sampling_freq, APTX_SAMPLING_FREQ_32000 | APTX_SAMPLING_FREQ_44100);
|
|
ck_assert_int_eq(caps_aptx.channel_mode, APTX_CHANNEL_MODE_STEREO);
|
|
#endif
|
|
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_caps_foreach_get_best) {
|
|
|
|
a2dp_sbc_t caps_sbc = {
|
|
.sampling_freq = SBC_SAMPLING_FREQ_16000 | SBC_SAMPLING_FREQ_44100,
|
|
.channel_mode = SBC_CHANNEL_MODE_MONO | SBC_CHANNEL_MODE_STEREO,
|
|
};
|
|
|
|
unsigned int channel_mode = 0;
|
|
ck_assert_int_eq(a2dp_sbc_source.caps_helpers->foreach_channel_mode(&caps_sbc,
|
|
A2DP_MAIN, a2dp_bit_mapping_foreach_get_best_channel_mode, &channel_mode), ERROR_CODE_OK);
|
|
ck_assert_uint_eq(channel_mode, SBC_CHANNEL_MODE_STEREO);
|
|
|
|
unsigned int sampling_freq = 0;
|
|
ck_assert_int_eq(a2dp_sbc_source.caps_helpers->foreach_sample_rate(&caps_sbc,
|
|
A2DP_MAIN, a2dp_bit_mapping_foreach_get_best_sample_rate, &sampling_freq), ERROR_CODE_OK);
|
|
ck_assert_uint_eq(sampling_freq, SBC_SAMPLING_FREQ_44100);
|
|
|
|
#if ENABLE_AAC
|
|
|
|
/* Check default internal limits for selecting number of channels (up to
|
|
* 2 channels) and sample rate (up to 48 kHz). */
|
|
|
|
a2dp_aac_t caps_aac = {
|
|
A2DP_AAC_INIT_SAMPLING_FREQ(AAC_SAMPLING_FREQ_48000 | AAC_SAMPLING_FREQ_96000)
|
|
.channel_mode = AAC_CHANNEL_MODE_MONO | AAC_CHANNEL_MODE_STEREO | AAC_CHANNEL_MODE_5_1,
|
|
};
|
|
|
|
channel_mode = 0;
|
|
ck_assert_int_eq(a2dp_aac_source.caps_helpers->foreach_channel_mode(&caps_aac,
|
|
A2DP_MAIN, a2dp_bit_mapping_foreach_get_best_channel_mode, &channel_mode), ERROR_CODE_OK);
|
|
ck_assert_uint_eq(channel_mode, AAC_CHANNEL_MODE_STEREO);
|
|
|
|
sampling_freq = 0;
|
|
ck_assert_int_eq(a2dp_aac_source.caps_helpers->foreach_sample_rate(&caps_aac,
|
|
A2DP_MAIN, a2dp_bit_mapping_foreach_get_best_sample_rate, &sampling_freq), ERROR_CODE_OK);
|
|
ck_assert_uint_eq(sampling_freq, AAC_SAMPLING_FREQ_48000);
|
|
|
|
#endif
|
|
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_caps_select_channels_and_sampling) {
|
|
|
|
a2dp_sbc_t caps_sbc = {
|
|
.sampling_freq = SBC_SAMPLING_FREQ_16000 | SBC_SAMPLING_FREQ_44100,
|
|
.channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL | SBC_CHANNEL_MODE_STEREO,
|
|
};
|
|
|
|
a2dp_sbc_source.caps_helpers->select_channel_mode(&caps_sbc, A2DP_MAIN, 2);
|
|
ck_assert_uint_eq(caps_sbc.channel_mode, SBC_CHANNEL_MODE_STEREO);
|
|
|
|
a2dp_sbc_source.caps_helpers->select_sample_rate(&caps_sbc, A2DP_MAIN, 16000);
|
|
ck_assert_uint_eq(caps_sbc.sampling_freq, SBC_SAMPLING_FREQ_16000);
|
|
|
|
} CK_END_TEST
|
|
|
|
CK_START_TEST(test_a2dp_select_configuration) {
|
|
|
|
a2dp_sbc_t cfg;
|
|
const a2dp_sbc_t cfg_ = {
|
|
.sampling_freq = SBC_SAMPLING_FREQ_16000 | SBC_SAMPLING_FREQ_44100 | SBC_SAMPLING_FREQ_48000,
|
|
.channel_mode = SBC_CHANNEL_MODE_MONO | SBC_CHANNEL_MODE_DUAL_CHANNEL | SBC_CHANNEL_MODE_STEREO,
|
|
.block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8,
|
|
.subbands = SBC_SUBBANDS_4 | SBC_SUBBANDS_8,
|
|
.allocation_method = SBC_ALLOCATION_SNR | SBC_ALLOCATION_LOUDNESS,
|
|
.min_bitpool = 42,
|
|
.max_bitpool = 255,
|
|
};
|
|
|
|
cfg = cfg_;
|
|
ck_assert_int_eq(a2dp_select_configuration(&a2dp_sbc_source, &cfg, sizeof(cfg) + 1),
|
|
ERROR_CODE_INVALID_SIZE);
|
|
|
|
cfg = cfg_;
|
|
ck_assert_int_eq(a2dp_select_configuration(&a2dp_sbc_source, &cfg, sizeof(cfg)), ERROR_CODE_OK);
|
|
ck_assert_int_eq(cfg.sampling_freq, SBC_SAMPLING_FREQ_48000);
|
|
ck_assert_int_eq(cfg.channel_mode, SBC_CHANNEL_MODE_STEREO);
|
|
ck_assert_int_eq(cfg.block_length, SBC_BLOCK_LENGTH_8);
|
|
ck_assert_int_eq(cfg.subbands, SBC_SUBBANDS_8);
|
|
ck_assert_int_eq(cfg.allocation_method, SBC_ALLOCATION_LOUDNESS);
|
|
ck_assert_int_eq(cfg.min_bitpool, 42);
|
|
ck_assert_int_eq(cfg.max_bitpool, 250);
|
|
|
|
cfg = cfg_;
|
|
config.a2dp.force_mono = true;
|
|
ck_assert_int_eq(a2dp_select_configuration(&a2dp_sbc_source, &cfg, sizeof(cfg)), ERROR_CODE_OK);
|
|
ck_assert_int_eq(cfg.channel_mode, SBC_CHANNEL_MODE_MONO);
|
|
|
|
cfg = cfg_;
|
|
config.a2dp.force_mono = false;
|
|
config.a2dp.force_44100 = true;
|
|
config.sbc_quality = SBC_QUALITY_XQ;
|
|
ck_assert_int_eq(a2dp_select_configuration(&a2dp_sbc_source, &cfg, sizeof(cfg)), ERROR_CODE_OK);
|
|
ck_assert_int_eq(cfg.sampling_freq, SBC_SAMPLING_FREQ_44100);
|
|
ck_assert_int_eq(cfg.channel_mode, SBC_CHANNEL_MODE_DUAL_CHANNEL);
|
|
ck_assert_int_eq(cfg.block_length, SBC_BLOCK_LENGTH_8);
|
|
ck_assert_int_eq(cfg.subbands, SBC_SUBBANDS_8);
|
|
ck_assert_int_eq(cfg.allocation_method, SBC_ALLOCATION_LOUDNESS);
|
|
ck_assert_int_eq(cfg.min_bitpool, 42);
|
|
ck_assert_int_eq(cfg.max_bitpool, 250);
|
|
|
|
#if ENABLE_AAC
|
|
|
|
a2dp_aac_t cfg_aac;
|
|
const a2dp_aac_t cfg_aac_ = {
|
|
.object_type = AAC_OBJECT_TYPE_MPEG2_LC | AAC_OBJECT_TYPE_MPEG4_LC,
|
|
A2DP_AAC_INIT_SAMPLING_FREQ(AAC_SAMPLING_FREQ_44100 | AAC_SAMPLING_FREQ_96000)
|
|
.channel_mode = AAC_CHANNEL_MODE_MONO,
|
|
.vbr = 1 };
|
|
|
|
cfg_aac = cfg_aac_;
|
|
ck_assert_int_eq(a2dp_select_configuration(&a2dp_aac_source, &cfg_aac, sizeof(cfg_aac)),
|
|
ERROR_CODE_OK);
|
|
ck_assert_int_eq(cfg_aac.object_type, AAC_OBJECT_TYPE_MPEG4_LC);
|
|
ck_assert_int_eq(A2DP_AAC_GET_SAMPLING_FREQ(cfg_aac), AAC_SAMPLING_FREQ_44100);
|
|
ck_assert_int_eq(cfg_aac.channel_mode, AAC_CHANNEL_MODE_MONO);
|
|
ck_assert_int_eq(cfg_aac.vbr, 0);
|
|
|
|
cfg_aac = cfg_aac_;
|
|
config.aac_prefer_vbr = true;
|
|
ck_assert_int_eq(a2dp_select_configuration(&a2dp_aac_source, &cfg_aac, sizeof(cfg_aac)),
|
|
ERROR_CODE_OK);
|
|
ck_assert_int_eq(cfg_aac.vbr, 1);
|
|
|
|
cfg_aac = cfg_aac_;
|
|
/* FDK-AAC encoder does not support AAC Long Term Prediction */
|
|
cfg_aac.object_type = AAC_OBJECT_TYPE_MPEG4_LTP;
|
|
ck_assert_int_eq(a2dp_select_configuration(&a2dp_aac_source, &cfg_aac, sizeof(cfg_aac)),
|
|
ERROR_CODE_A2DP_NOT_SUPPORTED_OBJECT_TYPE);
|
|
|
|
#endif
|
|
|
|
} 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_a2dp_codecs_codec_id_from_string);
|
|
tcase_add_test(tc, test_a2dp_codecs_codec_id_to_string);
|
|
tcase_add_test(tc, test_a2dp_codecs_get_canonical_name);
|
|
|
|
tcase_add_test(tc, test_a2dp_type);
|
|
tcase_add_test(tc, test_a2dp_seps_init);
|
|
tcase_add_test(tc, test_a2dp_sep_ptr_cmp);
|
|
tcase_add_test(tc, test_a2dp_sep_lookup);
|
|
tcase_add_test(tc, test_a2dp_get_vendor_codec_id);
|
|
|
|
tcase_add_test(tc, test_a2dp_caps);
|
|
tcase_add_test(tc, test_a2dp_caps_intersect);
|
|
tcase_add_test(tc, test_a2dp_caps_foreach_get_best);
|
|
tcase_add_test(tc, test_a2dp_caps_select_channels_and_sampling);
|
|
|
|
tcase_add_test(tc, test_a2dp_check_configuration);
|
|
tcase_add_test(tc, test_a2dp_select_configuration);
|
|
|
|
srunner_run_all(sr, CK_ENV);
|
|
int nf = srunner_ntests_failed(sr);
|
|
srunner_free(sr);
|
|
|
|
return nf == 0 ? 0 : 1;
|
|
}
|