Skip to content

Commit

Permalink
Remove duplicated channel count and channel maps
Browse files Browse the repository at this point in the history
  • Loading branch information
arkq committed Sep 4, 2024
1 parent d34d78d commit 99a101f
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 9 deletions.
4 changes: 2 additions & 2 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ then, to see a complete list of all options:

Dependencies:

- [alsa-lib](https://www.alsa-project.org/)
- [bluez](http://www.bluez.org/) >= 5.0
- [alsa-lib](https://www.alsa-project.org/) >= 1.0.27
- [bluez](http://www.bluez.org/) >= 5.51
- [glib](https://wiki.gnome.org/Projects/GLib) >= 2.58.2 with GIO support
- [sbc](https://git.kernel.org/cgit/bluetooth/sbc.git) >= 1.5
- [docutils](https://docutils.sourceforge.io) (when man pages build is enabled
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ AC_SEARCH_LIBS([pow], [m],
AC_SEARCH_LIBS([pthread_create], [pthread],
[], [AC_MSG_ERROR([pthread library not found])])

PKG_CHECK_MODULES([ALSA], [alsa])
PKG_CHECK_MODULES([ALSA], [alsa >= 1.0.27])
PKG_CHECK_MODULES([BLUEZ], [bluez >= 5.51])
PKG_CHECK_MODULES([DBUS1], [dbus-1 >= 1.6])
PKG_CHECK_MODULES([GIO2], [gio-unix-2.0])
Expand Down
32 changes: 26 additions & 6 deletions src/bluealsa-dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,23 +310,39 @@ static GVariant *ba_variant_new_pcm_volume(const struct ba_transport_pcm *pcm) {
return g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, volume, n, sizeof(*volume));
}

struct ba_populate_data {
GVariantBuilder *builder;
/* previously added value */
unsigned int value;
};

static int ba_populate_channels(struct a2dp_bit_mapping mapping, void *userdata) {
g_variant_builder_add_value(userdata, g_variant_new_byte(mapping.value));
struct ba_populate_data *data = userdata;
if (data->value == mapping.value)
return 0;
g_variant_builder_add_value(data->builder, g_variant_new_byte(mapping.value));
data->value = mapping.value;
return 0;
}

static int ba_populate_sampling(struct a2dp_bit_mapping mapping, void *userdata) {
g_variant_builder_add_value(userdata, g_variant_new_uint32(mapping.value));
struct ba_populate_data *data = userdata;
g_variant_builder_add_value(data->builder, g_variant_new_uint32(mapping.value));
return 0;
}

static int ba_populate_channel_map(struct a2dp_bit_mapping mapping, void *userdata) {
struct ba_populate_data *data = userdata;

if (data->value == mapping.ch.channels)
return 0;

const char *strv[16];
for (size_t i = 0; i < mapping.ch.channels; i++)
strv[i] = ba_transport_pcm_channel_to_string(mapping.ch.map[i]);

g_variant_builder_add_value(userdata, g_variant_new_strv(strv, mapping.ch.channels));
g_variant_builder_add_value(data->builder, g_variant_new_strv(strv, mapping.ch.channels));
data->value = mapping.ch.channels;
return 0;
}

Expand All @@ -337,23 +353,27 @@ static void ba_variant_populate_remote_sep(GVariantBuilder *props,
enum a2dp_stream stream) {

GVariantBuilder builder;
struct ba_populate_data data = { .builder = &builder };

a2dp_t caps = remote_sep_cfg->capabilities;
sep->caps_helpers->intersect(&caps, &sep->config.capabilities);

g_variant_builder_add(props, "{sv}", "Capabilities", g_variant_new_fixed_array(
G_VARIANT_TYPE_BYTE, &caps, remote_sep_cfg->caps_size, sizeof(uint8_t)));

data.value = 0;
g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
sep->caps_helpers->foreach_channel_mode(&caps, stream, ba_populate_channels, &builder);
sep->caps_helpers->foreach_channel_mode(&caps, stream, ba_populate_channels, &data);
g_variant_builder_add(props, "{sv}", "SupportedChannels", g_variant_builder_end(&builder));

data.value = 0;
g_variant_builder_init(&builder, G_VARIANT_TYPE("au"));
sep->caps_helpers->foreach_sampling_freq(&caps, stream, ba_populate_sampling, &builder);
sep->caps_helpers->foreach_sampling_freq(&caps, stream, ba_populate_sampling, &data);
g_variant_builder_add(props, "{sv}", "SupportedSampling", g_variant_builder_end(&builder));

data.value = 0;
g_variant_builder_init(&builder, G_VARIANT_TYPE("aas"));
sep->caps_helpers->foreach_channel_mode(&caps, stream, ba_populate_channel_map, &builder);
sep->caps_helpers->foreach_channel_mode(&caps, stream, ba_populate_channel_map, &data);
g_variant_builder_add(props, "{sv}", "ChannelMaps", g_variant_builder_end(&builder));

}
Expand Down
48 changes: 48 additions & 0 deletions test/test-alsa-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,53 @@ CK_START_TEST(ba_test_playback_hw_constraints) {

} CK_END_TEST

CK_START_TEST(ba_test_playback_channel_maps) {

if (pcm_device != NULL)
return;

unsigned int buffer_time = 200000;
unsigned int period_time = 25000;
struct spawn_process sp_ba_mock;
snd_pcm_chmap_query_t **ch_maps;
snd_pcm_chmap_t *ch_map;
snd_pcm_t *pcm = NULL;

ck_assert_int_eq(test_pcm_open(&sp_ba_mock, &pcm, SND_PCM_STREAM_PLAYBACK), 0);
ck_assert_int_eq(set_hw_params(pcm, pcm_format, pcm_channels, pcm_sampling,
&buffer_time, &period_time), 0);

/* get all supported channel maps */
ck_assert_ptr_nonnull(ch_maps = snd_pcm_query_chmaps(pcm));

size_t ch_maps_count = 0;
for (size_t i = 0; ch_maps[i] != NULL; i++)
ch_maps_count++;
/* SBC codec supports only mono and stereo */
ck_assert_uint_eq(ch_maps_count, 2);

ck_assert_uint_eq(ch_maps[0]->type, SND_CHMAP_TYPE_FIXED);
ck_assert_uint_eq(ch_maps[0]->map.channels, 1);
ck_assert_uint_eq(ch_maps[0]->map.pos[0], SND_CHMAP_MONO);

ck_assert_uint_eq(ch_maps[1]->type, SND_CHMAP_TYPE_FIXED);
ck_assert_uint_eq(ch_maps[1]->map.channels, 2);
ck_assert_uint_eq(ch_maps[1]->map.pos[0], SND_CHMAP_FL);
ck_assert_uint_eq(ch_maps[1]->map.pos[1], SND_CHMAP_FR);

/* get currently selected channel map */
ck_assert_ptr_nonnull(ch_map = snd_pcm_get_chmap(pcm));
/* stereo channel mode shall be selected by default */
ck_assert_uint_eq(ch_map->channels, 2);
ck_assert_uint_eq(ch_map->pos[0], SND_CHMAP_FL);
ck_assert_uint_eq(ch_map->pos[1], SND_CHMAP_FR);

free(ch_map);
snd_pcm_free_chmaps(ch_maps);
ck_assert_int_eq(test_pcm_close(&sp_ba_mock, pcm), 0);

} CK_END_TEST

CK_START_TEST(ba_test_playback_no_codec_selected) {

if (pcm_device != NULL)
Expand Down Expand Up @@ -1164,6 +1211,7 @@ int main(int argc, char *argv[]) {
TCase *tc = tcase_create("playback");
tcase_add_test(tc, dump_playback);
tcase_add_test(tc, ba_test_playback_hw_constraints);
tcase_add_test(tc, ba_test_playback_channel_maps);
tcase_add_test(tc, ba_test_playback_no_codec_selected);
tcase_add_test(tc, ba_test_playback_no_such_device);
tcase_add_test(tc, ba_test_playback_extra_setup);
Expand Down

0 comments on commit 99a101f

Please sign in to comment.