aboutsummaryrefslogtreecommitdiffstats
path: root/alc/effects/vmorpher.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'alc/effects/vmorpher.cpp')
-rw-r--r--alc/effects/vmorpher.cpp43
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;
}