diff options
Diffstat (limited to 'alc/effects/vmorpher.cpp')
-rw-r--r-- | alc/effects/vmorpher.cpp | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/alc/effects/vmorpher.cpp b/alc/effects/vmorpher.cpp index 9834c335..869c004e 100644 --- a/alc/effects/vmorpher.cpp +++ b/alc/effects/vmorpher.cpp @@ -143,12 +143,14 @@ struct FormantFilter struct VmorpherState final : public EffectState { struct { + uint mTargetChannel{INVALID_CHANNEL_INDEX}; + /* Effect parameters */ - FormantFilter Formants[NUM_FILTERS][NUM_FORMANTS]; + FormantFilter mFormants[NUM_FILTERS][NUM_FORMANTS]; /* Effect gains for each channel */ - float CurrentGains[MaxAmbiChannels]{}; - float TargetGains[MaxAmbiChannels]{}; + float mCurrentGain{}; + float mTargetGain{}; } mChans[MaxAmbiChannels]; void (*mGetSamples)(float*RESTRICT, uint, const uint, size_t){}; @@ -229,11 +231,12 @@ void VmorpherState::deviceUpdate(const DeviceBase*, const Buffer&) { for(auto &e : mChans) { - std::for_each(std::begin(e.Formants[VOWEL_A_INDEX]), std::end(e.Formants[VOWEL_A_INDEX]), + e.mTargetChannel = INVALID_CHANNEL_INDEX; + std::for_each(std::begin(e.mFormants[VOWEL_A_INDEX]), std::end(e.mFormants[VOWEL_A_INDEX]), std::mem_fn(&FormantFilter::clear)); - std::for_each(std::begin(e.Formants[VOWEL_B_INDEX]), std::end(e.Formants[VOWEL_B_INDEX]), + std::for_each(std::begin(e.mFormants[VOWEL_B_INDEX]), std::end(e.mFormants[VOWEL_B_INDEX]), std::mem_fn(&FormantFilter::clear)); - std::fill(std::begin(e.CurrentGains), std::end(e.CurrentGains), 0.0f); + e.mCurrentGain = 0.0f; } } @@ -265,14 +268,17 @@ void VmorpherState::update(const ContextBase *context, const EffectSlot *slot, /* Copy the filter coefficients to the input channels. */ for(size_t i{0u};i < slot->Wet.Buffer.size();++i) { - std::copy(vowelA.begin(), vowelA.end(), std::begin(mChans[i].Formants[VOWEL_A_INDEX])); - std::copy(vowelB.begin(), vowelB.end(), std::begin(mChans[i].Formants[VOWEL_B_INDEX])); + std::copy(vowelA.begin(), vowelA.end(), std::begin(mChans[i].mFormants[VOWEL_A_INDEX])); + std::copy(vowelB.begin(), vowelB.end(), std::begin(mChans[i].mFormants[VOWEL_B_INDEX])); } mOutTarget = target.Main->Buffer; - auto set_gains = [slot,target](auto &chan, al::span<const float,MaxAmbiChannels> coeffs) - { ComputePanGains(target.Main, coeffs.data(), slot->Gain, chan.TargetGains); }; - SetAmbiPanIdentity(std::begin(mChans), slot->Wet.Buffer.size(), set_gains); + auto set_channel = [this](size_t idx, uint target, float gain) + { + mChans[idx].mTargetChannel = target; + mChans[idx].mTargetGain = gain; + }; + target.Main->setAmbiMixParams(slot->Wet, slot->Gain, set_channel); } void VmorpherState::process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn, const al::span<FloatBufferLine> samplesOut) @@ -291,8 +297,15 @@ void VmorpherState::process(const size_t samplesToDo, const al::span<const Float auto chandata = std::begin(mChans); for(const auto &input : samplesIn) { - auto& vowelA = chandata->Formants[VOWEL_A_INDEX]; - auto& vowelB = chandata->Formants[VOWEL_B_INDEX]; + const size_t outidx{chandata->mTargetChannel}; + if(outidx == INVALID_CHANNEL_INDEX) + { + ++chandata; + continue; + } + + auto& vowelA = chandata->mFormants[VOWEL_A_INDEX]; + auto& vowelB = chandata->mFormants[VOWEL_B_INDEX]; /* Process first vowel. */ std::fill_n(std::begin(mSampleBufferA), td, 0.0f); @@ -313,8 +326,8 @@ void VmorpherState::process(const size_t samplesToDo, const al::span<const Float blended[i] = lerpf(mSampleBufferA[i], mSampleBufferB[i], mLfo[i]); /* Now, mix the processed sound data to the output. */ - MixSamples({blended, td}, samplesOut, chandata->CurrentGains, chandata->TargetGains, - samplesToDo-base, base); + MixSamples({blended, td}, {&samplesOut[outidx], 1}, &chandata->mCurrentGain, + &chandata->mTargetGain, samplesToDo-base, base); ++chandata; } |