diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.cpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.cpp index 1465771e0..eb833a0c6 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.cpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.cpp @@ -54,6 +54,12 @@ bool MultiSpeaker::get_is_stereo() { return false; } +void MultiSpeaker::set_output_volume(float volume) { + for(const auto &speaker: speakers_) { + speaker->set_output_volume(volume); + } +} + void MultiSpeaker::set_delegate(Outputs::Speaker::Speaker::Delegate *delegate) { delegate_ = delegate; } diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.hpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.hpp index 3c75654db..f48bc639c 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.hpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.hpp @@ -42,6 +42,7 @@ class MultiSpeaker: public Outputs::Speaker::Speaker, Outputs::Speaker::Speaker: void set_computed_output_rate(float cycles_per_second, int buffer_size, bool stereo) override; void set_delegate(Outputs::Speaker::Speaker::Delegate *delegate) override; bool get_is_stereo() override; + void set_output_volume(float) override; private: void speaker_did_complete_samples(Speaker *speaker, const std::vector &buffer) final; diff --git a/Outputs/Speaker/Implementation/LowpassSpeaker.hpp b/Outputs/Speaker/Implementation/LowpassSpeaker.hpp index 94d3a4b12..89ab38268 100644 --- a/Outputs/Speaker/Implementation/LowpassSpeaker.hpp +++ b/Outputs/Speaker/Implementation/LowpassSpeaker.hpp @@ -31,9 +31,16 @@ namespace Speaker { template class LowpassSpeaker: public Speaker { public: LowpassSpeaker(SampleSource &sample_source) : sample_source_(sample_source) { + // Propagate an initial volume level. sample_source.set_sample_volume_range(32767); } + void set_output_volume(float volume) final { + // Clamp to the acceptable range, and set. + volume = std::min(std::max(0.0f, volume), 1.0f); + sample_source_.set_sample_volume_range(int16_t(32767.0f * volume)); + } + // Implemented as per Speaker. float get_ideal_clock_rate_in_range(float minimum, float maximum) final { std::lock_guard lock_guard(filter_parameters_mutex_); diff --git a/Outputs/Speaker/Speaker.hpp b/Outputs/Speaker/Speaker.hpp index 2f5da46ca..13a67e674 100644 --- a/Outputs/Speaker/Speaker.hpp +++ b/Outputs/Speaker/Speaker.hpp @@ -45,6 +45,9 @@ class Speaker { compute_output_rate(); } + /// Sets the output volume, in the range [0, 1]. + virtual void set_output_volume(float) = 0; + /*! Speeds a speed multiplier for this machine, e.g. that it is currently being run at 2.0x its normal rate. This will affect the number of input samples that are combined to produce one output sample. @@ -79,6 +82,8 @@ class Speaker { delegate_ = delegate; } + + // This is primarily exposed for MultiSpeaker et al; it's not for general callers. virtual void set_computed_output_rate(float cycles_per_second, int buffer_size, bool stereo) = 0; protected: