X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/a714861cc1fa2e06c5f5509880fcbfbc334c2812..d000dd6f4b976894558613f69bdad2974cce7d1e:/src/pulse/channelmap.c diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c index fe14df24..9b516262 100644 --- a/src/pulse/channelmap.c +++ b/src/pulse/channelmap.c @@ -30,9 +30,11 @@ #include #include + #include #include #include +#include #include "channelmap.h" @@ -217,11 +219,11 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p case 6: m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; - m->map[1] = PA_CHANNEL_POSITION_REAR_LEFT; + m->map[1] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER; m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER; m->map[3] = PA_CHANNEL_POSITION_FRONT_RIGHT; - m->map[4] = PA_CHANNEL_POSITION_REAR_RIGHT; - m->map[5] = PA_CHANNEL_POSITION_LFE; + m->map[4] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER; + m->map[5] = PA_CHANNEL_POSITION_REAR_CENTER; return m; case 5: @@ -245,7 +247,7 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p m->map[0] = PA_CHANNEL_POSITION_LEFT; m->map[1] = PA_CHANNEL_POSITION_CENTER; m->map[2] = PA_CHANNEL_POSITION_RIGHT; - m->map[3] = PA_CHANNEL_POSITION_LFE; + m->map[3] = PA_CHANNEL_POSITION_REAR_CENTER; return m; default: @@ -297,6 +299,8 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p case PA_CHANNEL_MAP_WAVEEX: + /* Following http://www.microsoft.com/whdc/device/audio/multichaud.mspx#EKLAC */ + switch (channels) { case 1: m->map[0] = PA_CHANNEL_POSITION_MONO; @@ -449,6 +453,10 @@ int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) { pa_assert(b); pa_return_val_if_fail(pa_channel_map_valid(a), 0); + + if (PA_UNLIKELY(a == b)) + return 1; + pa_return_val_if_fail(pa_channel_map_valid(b), 0); if (a->channels != b->channels) @@ -491,6 +499,27 @@ char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) { return s; } +pa_channel_position_t pa_channel_position_from_string(const char *p) { + pa_channel_position_t i; + pa_assert(p); + + /* Some special aliases */ + if (pa_streq(p, "left")) + return PA_CHANNEL_POSITION_LEFT; + else if (pa_streq(p, "right")) + return PA_CHANNEL_POSITION_RIGHT; + else if (pa_streq(p, "center")) + return PA_CHANNEL_POSITION_CENTER; + else if (pa_streq(p, "subwoofer")) + return PA_CHANNEL_POSITION_SUBWOOFER; + + for (i = 0; i < PA_CHANNEL_POSITION_MAX; i++) + if (pa_streq(p, table[i])) + return i; + + return PA_CHANNEL_POSITION_INVALID; +} + pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) { const char *state; pa_channel_map map; @@ -559,36 +588,19 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) { map.channels = 0; while ((p = pa_split(s, ",", &state))) { + pa_channel_position_t f; if (map.channels >= PA_CHANNELS_MAX) { pa_xfree(p); return NULL; } - /* Some special aliases */ - if (pa_streq(p, "left")) - map.map[map.channels++] = PA_CHANNEL_POSITION_LEFT; - else if (pa_streq(p, "right")) - map.map[map.channels++] = PA_CHANNEL_POSITION_RIGHT; - else if (pa_streq(p, "center")) - map.map[map.channels++] = PA_CHANNEL_POSITION_CENTER; - else if (pa_streq(p, "subwoofer")) - map.map[map.channels++] = PA_CHANNEL_POSITION_SUBWOOFER; - else { - pa_channel_position_t i; - - for (i = 0; i < PA_CHANNEL_POSITION_MAX; i++) - if (strcmp(p, table[i]) == 0) { - map.map[map.channels++] = i; - break; - } - - if (i >= PA_CHANNEL_POSITION_MAX) { - pa_xfree(p); - return NULL; - } + if ((f = pa_channel_position_from_string(p)) == PA_CHANNEL_POSITION_INVALID) { + pa_xfree(p); + return NULL; } + map.map[map.channels++] = f; pa_xfree(p); } @@ -627,107 +639,48 @@ int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *s } int pa_channel_map_superset(const pa_channel_map *a, const pa_channel_map *b) { - pa_bitset_t in_a[PA_BITSET_ELEMENTS(PA_CHANNEL_POSITION_MAX)]; - unsigned i; + pa_channel_position_mask_t am, bm; pa_assert(a); pa_assert(b); pa_return_val_if_fail(pa_channel_map_valid(a), 0); - pa_return_val_if_fail(pa_channel_map_valid(b), 0); - memset(in_a, 0, sizeof(in_a)); + if (PA_UNLIKELY(a == b)) + return 1; - for (i = 0; i < a->channels; i++) - pa_bitset_set(in_a, a->map[i], TRUE); + pa_return_val_if_fail(pa_channel_map_valid(b), 0); - for (i = 0; i < b->channels; i++) - if (!pa_bitset_get(in_a, b->map[i])) - return 0; + am = pa_channel_map_mask(a); + bm = pa_channel_map_mask(b); - return 1; + return (bm & am) == bm; } int pa_channel_map_can_balance(const pa_channel_map *map) { - unsigned c; - pa_bool_t left = FALSE, right = FALSE; + pa_channel_position_mask_t m; pa_assert(map); - pa_return_val_if_fail(pa_channel_map_valid(map), 0); - for (c = 0; c < map->channels; c++) { - - switch (map->map[c]) { - case PA_CHANNEL_POSITION_LEFT: - case PA_CHANNEL_POSITION_REAR_LEFT: - case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER: - case PA_CHANNEL_POSITION_SIDE_LEFT: - case PA_CHANNEL_POSITION_TOP_FRONT_LEFT: - case PA_CHANNEL_POSITION_TOP_REAR_LEFT: - left = TRUE; - break; - - case PA_CHANNEL_POSITION_RIGHT: - case PA_CHANNEL_POSITION_REAR_RIGHT: - case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: - case PA_CHANNEL_POSITION_SIDE_RIGHT: - case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT: - case PA_CHANNEL_POSITION_TOP_REAR_RIGHT: - right = TRUE; - break; - - default: - ; - } - - if (left && right) - return 1; - } + m = pa_channel_map_mask(map); - return 0; + return + (PA_CHANNEL_POSITION_MASK_LEFT & m) && + (PA_CHANNEL_POSITION_MASK_RIGHT & m); } int pa_channel_map_can_fade(const pa_channel_map *map) { - unsigned c; - pa_bool_t front = FALSE, rear = FALSE; + pa_channel_position_mask_t m; pa_assert(map); - pa_return_val_if_fail(pa_channel_map_valid(map), 0); - for (c = 0; c < map->channels; c++) { - - switch (map->map[c]) { - case PA_CHANNEL_POSITION_FRONT_LEFT: - case PA_CHANNEL_POSITION_FRONT_RIGHT: - case PA_CHANNEL_POSITION_FRONT_CENTER: - case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER: - case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: - case PA_CHANNEL_POSITION_TOP_FRONT_LEFT: - case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT: - case PA_CHANNEL_POSITION_TOP_FRONT_CENTER: - front = TRUE; - break; - - case PA_CHANNEL_POSITION_REAR_LEFT: - case PA_CHANNEL_POSITION_REAR_RIGHT: - case PA_CHANNEL_POSITION_REAR_CENTER: - case PA_CHANNEL_POSITION_TOP_REAR_LEFT: - case PA_CHANNEL_POSITION_TOP_REAR_RIGHT: - case PA_CHANNEL_POSITION_TOP_REAR_CENTER: - rear = TRUE; - break; - - default: - ; - } - - if (front && rear) - return 1; - } + m = pa_channel_map_mask(map); - return 0; + return + (PA_CHANNEL_POSITION_MASK_FRONT & m) && + (PA_CHANNEL_POSITION_MASK_REAR & m); } const char* pa_channel_map_to_name(const pa_channel_map *map) { @@ -852,3 +805,15 @@ int pa_channel_map_has_position(const pa_channel_map *map, pa_channel_position_t return 0; } + +pa_channel_position_mask_t pa_channel_map_mask(const pa_channel_map *map) { + unsigned c; + pa_channel_position_mask_t r = 0; + + pa_return_val_if_fail(pa_channel_map_valid(map), 0); + + for (c = 0; c < map->channels; c++) + r |= PA_CHANNEL_POSITION_MASK(map->map[c]); + + return r; +}