diff options
author | Chris Robinson <[email protected]> | 2021-11-14 05:58:39 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2021-11-14 05:58:39 -0800 |
commit | cf85ffd22fceeb4221a96b310f574f29a4b404ea (patch) | |
tree | 9ff564ed4872447d5afce2a0193241d862877a29 /alc/backends/pipewire.cpp | |
parent | 3b9c831c300e8191539eae69995caf023f8fff7a (diff) |
Support "enum" choices for sample rates with PipeWire
Diffstat (limited to 'alc/backends/pipewire.cpp')
-rw-r--r-- | alc/backends/pipewire.cpp | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp index 0e99fdc4..68e6f527 100644 --- a/alc/backends/pipewire.cpp +++ b/alc/backends/pipewire.cpp @@ -579,6 +579,23 @@ uint32_t get_param_range(const spa_pod *value, const al::span<Pod_t<T>,3> vals) return 0; } +template<uint32_t T> +std::vector<Pod_t<T>> get_param_enum(const spa_pod *value) +{ + std::vector<Pod_t<T>> vals; + + uint32_t nvals{}, choice{}; + value = spa_pod_get_values(value, &nvals, &choice); + + if(get_pod_type(value) == T && nvals > 0 && choice == SPA_CHOICE_Enum) + { + vals.resize(nvals); + std::copy_n(get_pod_body<Pod_t<T>>(value), vals.size(), vals.begin()); + } + + return vals; +} + template<uint32_t T, size_t N> uint32_t get_param_array(const spa_pod *value, const al::span<Pod_t<T>,N> vals) { @@ -596,20 +613,43 @@ al::optional<Pod_t<T>> get_param(const spa_pod *value) void parse_srate(DeviceNode *node, const spa_pod *value) { - /* TODO: Can this be anything else? An "enum" choice? Floats? Or will the - * sample rate always be a range choice between ints? + /* TODO: Can this be anything else? Floats? Will the sample rate always be + * a range or enum choice of ints? */ if(get_pod_type(value) == SPA_TYPE_Choice) { int32_t srate[3]{}; - if(get_param_range<SPA_TYPE_Int>(value, al::span<int32_t,3>{srate}) < 1) + if(get_param_range<SPA_TYPE_Int>(value, al::span<int32_t,3>{srate}) > 0) + { + /* [0] is the default, [1] is the min, and [2] is the max. */ + TRACE("Device ID %u sample rate: %d (range: %d -> %d)\n", node->mId, srate[0], srate[1], + srate[2]); + srate[0] = clampi(srate[0], MIN_OUTPUT_RATE, MAX_OUTPUT_RATE); + node->mSampleRate = static_cast<uint>(srate[0]); return; + } - /* [0] is the default, [1] is the min, and [2] is the max. */ - TRACE("Device ID %u sample rate: %d (range: %d -> %d)\n", node->mId, srate[0], srate[1], - srate[2]); - srate[0] = clampi(srate[0], MIN_OUTPUT_RATE, MAX_OUTPUT_RATE); - node->mSampleRate = static_cast<uint>(srate[0]); + auto srates = get_param_enum<SPA_TYPE_Int>(value); + if(!srates.empty()) + { + /* [0] is the default, [1...size()-1] are available selections. */ + std::string others{(srates.size() > 1) ? std::to_string(srates[1]) : std::string{}}; + for(size_t i{2};i < srates.size();++i) + { + others += ", "; + others += std::to_string(srates[i]); + } + TRACE("Device ID %u sample rate: %d (%s)\n", node->mId, srates[0], others.c_str()); + for(const auto &rate : srates) + { + if(rate >= MIN_OUTPUT_RATE && rate <= MAX_OUTPUT_RATE) + { + node->mSampleRate = static_cast<uint>(rate); + break; + } + } + return; + } } } |