diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index dbffda04..34b98c8d 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -241,6 +241,10 @@ struct Voice::Impl std::vector> lfos_; std::vector> flexEGs_; + std::unique_ptr lfoAmplitude_; + std::unique_ptr lfoPitch_; + std::unique_ptr lfoFilter_; + ADSREnvelope egAmplitude_; std::unique_ptr egPitch_; std::unique_ptr egFilter_; @@ -595,6 +599,12 @@ void Voice::setSampleRate(float sampleRate) noexcept for (auto& lfo : impl.lfos_) lfo->setSampleRate(sampleRate); + if (auto* lfo = impl.lfoAmplitude_.get()) + lfo->setSampleRate(sampleRate); + if (auto* lfo = impl.lfoPitch_.get()) + lfo->setSampleRate(sampleRate); + if (auto* lfo = impl.lfoFilter_.get()) + lfo->setSampleRate(sampleRate); for (auto& filter : impl.filters_) filter.setSampleRate(sampleRate); @@ -1640,6 +1650,45 @@ void Voice::setFilterEGEnabledPerVoice(bool haveFilterEG) impl.egFilter_.reset(); } +void Voice::setAmplitudeLFOEnabledPerVoice(bool haveAmplitudeLFO) +{ + Impl& impl = *impl_; + Resources& res = impl.resources_; + if (haveAmplitudeLFO) { + LFO* lfo = new LFO(res.bufferPool, &res.beatClock, &res.modMatrix); + impl.lfoAmplitude_.reset(lfo); + lfo->setSampleRate(impl.sampleRate_); + } + else + impl.lfoAmplitude_.reset(); +} + +void Voice::setPitchLFOEnabledPerVoice(bool havePitchLFO) +{ + Impl& impl = *impl_; + Resources& res = impl.resources_; + if (havePitchLFO) { + LFO* lfo = new LFO(res.bufferPool, &res.beatClock, &res.modMatrix); + impl.lfoPitch_.reset(lfo); + lfo->setSampleRate(impl.sampleRate_); + } + else + impl.lfoPitch_.reset(); +} + +void Voice::setFilterLFOEnabledPerVoice(bool haveFilterLFO) +{ + Impl& impl = *impl_; + Resources& res = impl.resources_; + if (haveFilterLFO) { + LFO* lfo = new LFO(res.bufferPool, &res.beatClock, &res.modMatrix); + impl.lfoFilter_.reset(lfo); + lfo->setSampleRate(impl.sampleRate_); + } + else + impl.lfoFilter_.reset(); +} + void Voice::Impl::setupOscillatorUnison() { const int m = region_->oscillatorMulti; @@ -1855,6 +1904,24 @@ Duration Voice::getLastPanningDuration() const noexcept return impl.panningDuration_; } +LFO* Voice::getAmplitudeLFO() +{ + Impl& impl = *impl_; + return impl.lfoAmplitude_.get(); +} + +LFO* Voice::getPitchLFO() +{ + Impl& impl = *impl_; + return impl.lfoPitch_.get(); +} + +LFO* Voice::getFilterLFO() +{ + Impl& impl = *impl_; + return impl.lfoFilter_.get(); +} + ADSREnvelope* Voice::getAmplitudeEG() { Impl& impl = *impl_; diff --git a/src/sfizz/Voice.h b/src/sfizz/Voice.h index 34885cbb..595bf1c1 100644 --- a/src/sfizz/Voice.h +++ b/src/sfizz/Voice.h @@ -305,6 +305,24 @@ public: * @param haveFilterEG */ void setFilterEGEnabledPerVoice(bool haveFilterEG); + /** + * @brief Set whether SFZv1 amplitude LFO is enabled on this voice + * + * @param haveAmplitudeLFO + */ + void setAmplitudeLFOEnabledPerVoice(bool haveAmplitudeLFO); + /** + * @brief Set whether SFZv1 pitch LFO is enabled on this voice + * + * @param havePitchLFO + */ + void setPitchLFOEnabledPerVoice(bool havePitchLFO); + /** + * @brief Set whether SFZv1 filter LFO is enabled on this voice + * + * @param haveFilterLFO + */ + void setFilterLFOEnabledPerVoice(bool haveFilterLFO); /** * @brief Release the voice after a given delay * @@ -333,6 +351,19 @@ public: Duration getLastFilterDuration() const noexcept; Duration getLastPanningDuration() const noexcept; + /** + * @brief Get the SFZv1 amplitude LFO, if existing + */ + LFO* getAmplitudeLFO(); + /** + * @brief Get the SFZv1 pitch LFO, if existing + */ + LFO* getPitchLFO(); + /** + * @brief Get the SFZv1 filter LFO, if existing + */ + LFO* getFilterLFO(); + /** * @brief Get the SFZv1 amplitude EG, if existing */