diff options
author | Chris Robinson <[email protected]> | 2021-11-14 11:31:08 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2021-11-14 11:43:33 -0800 |
commit | eac427dff728bf7b503938b46ace06208c4f3bc7 (patch) | |
tree | e0b88df6e30b7cf862e164ad1faae01451d0e7c7 /alc/backends/pipewire.cpp | |
parent | bdc9d6955f4b5425a080d128b889704308fa9f63 (diff) |
Report unexpected types for the sample rate from PipeWire
Diffstat (limited to 'alc/backends/pipewire.cpp')
-rw-r--r-- | alc/backends/pipewire.cpp | 86 |
1 files changed, 44 insertions, 42 deletions
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp index 68e6f527..0b034e00 100644 --- a/alc/backends/pipewire.cpp +++ b/alc/backends/pipewire.cpp @@ -564,38 +564,6 @@ struct PodInfo<SPA_TYPE_Id> { template<uint32_t T> using Pod_t = typename PodInfo<T>::Type; -template<uint32_t T> -uint32_t get_param_range(const spa_pod *value, const al::span<Pod_t<T>,3> vals) -{ - uint32_t nvals{}, choice{}; - value = spa_pod_get_values(value, &nvals, &choice); - - if(get_pod_type(value) == T && nvals >= vals.size() && choice == SPA_CHOICE_Range) - { - std::copy_n(get_pod_body<Pod_t<T>>(value), vals.size(), vals.begin()); - return nvals; - } - - 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) { @@ -607,7 +575,7 @@ al::optional<Pod_t<T>> get_param(const spa_pod *value) { Pod_t<T> val{}; if(PodInfo<T>::get_value(value, &val) == 0) - return al::make_optional(val); + return val; return al::nullopt; } @@ -616,22 +584,48 @@ void parse_srate(DeviceNode *node, const spa_pod *value) /* 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) + const uint srateType{get_pod_type(value)}; + if(srateType == SPA_TYPE_Choice) { - int32_t srate[3]{}; - if(get_param_range<SPA_TYPE_Int>(value, al::span<int32_t,3>{srate}) > 0) + uint32_t nvals{}, choiceType{}; + value = spa_pod_get_values(value, &nvals, &choiceType); + + const uint podtype{get_pod_type(value)}; + if(podtype != SPA_TYPE_Int) + { + WARN("Unhandled sample rate POD type: %u\n", podtype); + return; + } + + if(choiceType == SPA_CHOICE_Range) { + if(nvals != 3) + { + WARN("Unexpected SPA_CHOICE_Range count: %u\n", nvals); + return; + } + std::array<int32_t,3> srates{}; + std::copy_n(get_pod_body<int32_t>(value), srates.size(), srates.begin()); + /* [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]); + TRACE("Device ID %u sample rate: %d (range: %d -> %d)\n", node->mId, srates[0], + srates[1], srates[2]); + srates[0] = clampi(srates[0], MIN_OUTPUT_RATE, MAX_OUTPUT_RATE); + node->mSampleRate = static_cast<uint>(srates[0]); return; } - auto srates = get_param_enum<SPA_TYPE_Int>(value); - if(!srates.empty()) + if(choiceType == SPA_CHOICE_Enum) { + if(nvals == 0) + { + WARN("Unexpected SPA_CHOICE_Enum count: %u\n", nvals); + return; + } + + auto srates = std::vector<int32_t>(nvals); + std::copy_n(get_pod_body<int32_t>(value), srates.size(), srates.begin()); + /* [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) @@ -640,6 +634,9 @@ void parse_srate(DeviceNode *node, const spa_pod *value) others += std::to_string(srates[i]); } TRACE("Device ID %u sample rate: %d (%s)\n", node->mId, srates[0], others.c_str()); + /* Pick the first rate listed that's within the allowed range + * (default rate if possible). + */ for(const auto &rate : srates) { if(rate >= MIN_OUTPUT_RATE && rate <= MAX_OUTPUT_RATE) @@ -650,7 +647,12 @@ void parse_srate(DeviceNode *node, const spa_pod *value) } return; } + + WARN("Unhandled sample rate choice type: %u\n", choiceType); + return; } + + WARN("Unhandled sample rate type: %u\n", srateType); } void parse_positions(DeviceNode *node, const spa_pod *value) |