From 5880516076843edb60c96ea622f966ca2fb4e9e6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Aug 2008 18:40:53 +0200 Subject: add new API function pa_cvolume_remap() --- src/pulse/volume.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pulse/volume.h | 4 +++ 2 files changed, 89 insertions(+) (limited to 'src') diff --git a/src/pulse/volume.c b/src/pulse/volume.c index 70d6f86a..625eb19a 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -176,3 +176,88 @@ int pa_cvolume_valid(const pa_cvolume *v) { return 1; } + +static pa_bool_t on_left(pa_channel_position_t p) { + + return + p == PA_CHANNEL_POSITION_FRONT_LEFT || + p == PA_CHANNEL_POSITION_REAR_LEFT || + p == PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER || + p == PA_CHANNEL_POSITION_SIDE_LEFT || + p == PA_CHANNEL_POSITION_TOP_FRONT_LEFT || + p == PA_CHANNEL_POSITION_TOP_REAR_LEFT; +} + +static pa_bool_t on_right(pa_channel_position_t p) { + + return + p == PA_CHANNEL_POSITION_FRONT_RIGHT || + p == PA_CHANNEL_POSITION_REAR_RIGHT || + p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER || + p == PA_CHANNEL_POSITION_SIDE_RIGHT || + p == PA_CHANNEL_POSITION_TOP_FRONT_RIGHT || + p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT; +} + +static pa_bool_t on_center(pa_channel_position_t p) { + + return + p == PA_CHANNEL_POSITION_FRONT_CENTER || + p == PA_CHANNEL_POSITION_REAR_CENTER || + p == PA_CHANNEL_POSITION_TOP_CENTER || + p == PA_CHANNEL_POSITION_TOP_FRONT_CENTER || + p == PA_CHANNEL_POSITION_TOP_REAR_CENTER; +} + +static pa_bool_t on_lfe(pa_channel_position_t p) { + return + p == PA_CHANNEL_POSITION_LFE; +} + +pa_cvolume *pa_cvolume_remap(pa_cvolume *v, pa_channel_map *from, pa_channel_map *to) { + int a, b; + pa_cvolume result; + + pa_assert(v); + pa_assert(from); + pa_assert(to); + pa_assert(v->channels == from->channels); + + if (pa_channel_map_equal(from, to)) + return v; + + result.channels = to->channels; + + for (b = 0; b < to->channels; b++) { + pa_volume_t k = 0; + int n = 0; + + for (a = 0; a < from->channels; a++) + if (from->map[a] == to->map[b]) { + k += v->values[a]; + n ++; + } + + if (n <= 0) { + for (a = 0; a < from->channels; a++) + if ((on_left(from->map[a]) && on_left(to->map[b])) || + (on_right(from->map[a]) && on_right(to->map[b])) || + (on_center(from->map[a]) && on_center(to->map[b])) || + (on_lfe(from->map[a]) && on_lfe(to->map[b]))) { + + k += v->values[a]; + n ++; + } + } + + if (n <= 0) + k = pa_cvolume_avg(v); + else + k /= n; + + result.values[b] = k; + } + + *v = result; + return v; +} diff --git a/src/pulse/volume.h b/src/pulse/volume.h index 3befb1da..4fdbf658 100644 --- a/src/pulse/volume.h +++ b/src/pulse/volume.h @@ -28,6 +28,7 @@ #include #include #include +#include /** \page volume Volume Control * @@ -170,6 +171,9 @@ double pa_sw_volume_to_linear(pa_volume_t v) PA_GCC_CONST; #define PA_DECIBEL_MININFTY ((double) -200.0) #endif +/** Remap a volume from one channel mapping to a different channel mapping. \since 0.9.12 */ +pa_cvolume *pa_cvolume_remap(pa_cvolume *v, pa_channel_map *from, pa_channel_map *to); + PA_C_DECL_END #endif -- cgit