diff --git a/Outputs/Speaker/Implementation/CompoundSource.hpp b/Outputs/Speaker/Implementation/CompoundSource.hpp index eb53d95a3..99acee946 100644 --- a/Outputs/Speaker/Implementation/CompoundSource.hpp +++ b/Outputs/Speaker/Implementation/CompoundSource.hpp @@ -31,19 +31,22 @@ template class CompoundSource: public Outputs::Speaker::SampleSo A CompoundSource adds together the sound generated by multiple individual SampleSources. It's an instance of template metaprogramming; this is the recursive case. */ -template class CompoundSource: public Outputs::Speaker::SampleSource { +template class CompoundSource: + public Outputs::Speaker::SampleSource { public: CompoundSource(T &source, R &...next) : source_(source), next_source_(next...) {} void get_samples(std::size_t number_of_samples, std::int16_t *target) { - // This is an ugly solution: get whatever the next source supplies and add the local - // results to it, with the degenerate case performing a memset to supply an array of 0. - // TODO: do better. Might need some alteration of SampleSource. - int16_t next_samples[number_of_samples]; - next_source_.get_samples(number_of_samples, next_samples); - source_.get_samples(number_of_samples, target); - while(number_of_samples--) { - target[number_of_samples] += next_samples[number_of_samples]; + if(source_.is_silent()) { + source_.skip_samples(number_of_samples); + next_source_.get_samples(number_of_samples, target); + } else { + int16_t next_samples[number_of_samples]; + next_source_.get_samples(number_of_samples, next_samples); + source_.get_samples(number_of_samples, target); + while(number_of_samples--) { + target[number_of_samples] += next_samples[number_of_samples]; + } } } @@ -53,6 +56,7 @@ template class CompoundSource: public Outpu } private: + bool is_sleeping_ = false; T &source_; CompoundSource next_source_; }; diff --git a/Outputs/Speaker/Implementation/SampleSource.hpp b/Outputs/Speaker/Implementation/SampleSource.hpp index 4235f2125..b3a43c798 100644 --- a/Outputs/Speaker/Implementation/SampleSource.hpp +++ b/Outputs/Speaker/Implementation/SampleSource.hpp @@ -37,6 +37,15 @@ class SampleSource { std::int16_t scratch_pad[number_of_samples]; get_samples(number_of_samples, scratch_pad); } + + /*! + @returns @c true if it is trivially true that a call to get_samples would just + fill the target with zeroes; @c false if a call might return all zeroes or + might not. + */ + bool is_silent() { + return false; + } }; }