1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-16 19:08:08 +00:00

Require good ordering.

This commit is contained in:
Thomas Harte 2024-02-09 14:34:59 -05:00
parent 9909146c59
commit 25085cb5af

View File

@ -26,6 +26,20 @@ template <typename... S> constexpr bool is_stereo() {
return is_stereo; return is_stereo;
} }
/// @returns @c true if the variadic template arguments are ordered as all stereo sources followed by
/// all mono; @c false otherwise.
template <typename... S> constexpr bool are_properly_ordered() {
bool is_ordered = true;
bool is_stereo = true;
([&] {
if(S::is_stereo && !is_stereo) {
is_ordered = false;
}
is_stereo &= S::is_stereo;
}(), ...);
return is_ordered;
}
/*! /*!
A CompoundSource adds together the sound generated by multiple individual SampleSources. A CompoundSource adds together the sound generated by multiple individual SampleSources.
An owner may optionally assign relative volumes. An owner may optionally assign relative volumes.
@ -59,7 +73,7 @@ template <typename... T> class CompoundSource:
static constexpr bool is_stereo = S::is_stereo || CompoundSourceHolder<R...>::is_stereo; static constexpr bool is_stereo = S::is_stereo || CompoundSourceHolder<R...>::is_stereo;
// TODO: fix below for mixed mono/stereo sources. // TODO: fix below for potential stereo -> mono conversion.
template <bool output_stereo> template <bool output_stereo>
void get_samples(std::size_t number_of_samples, typename SampleT<output_stereo>::type *target) { void get_samples(std::size_t number_of_samples, typename SampleT<output_stereo>::type *target) {
// Get the rest of the output. // Get the rest of the output.
@ -121,6 +135,9 @@ template <typename... T> class CompoundSource:
}; };
public: public:
// To ensure at most one mono to stereo conversion, require appropriate source ordering.
static_assert(are_properly_ordered<T...>(), "Sources should be listed with all stereo sources before all mono sources");
CompoundSource(T &... sources) : source_holder_(sources...) { CompoundSource(T &... sources) : source_holder_(sources...) {
// Default: give all sources equal volume. // Default: give all sources equal volume.
const auto volume = 1.0 / double(source_holder_.size()); const auto volume = 1.0 / double(source_holder_.size());