Support "enum" choices for sample rates with PipeWire

This commit is contained in:
Chris Robinson 2021-11-14 05:58:39 -08:00
parent 3b9c831c30
commit cf85ffd22f

View File

@ -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;
}
}
}