diff options
author | Chris Robinson <[email protected]> | 2022-10-21 10:33:41 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2022-10-21 10:33:41 -0700 |
commit | ee40a2e7e4867a769765d447a15ac88832eb8aa0 (patch) | |
tree | 0ff9157bc237db41795d27dd731b0191289bb5e2 /core/voice.cpp | |
parent | 53b63f329c3daa82f3c02ed43b67338af3a3d77d (diff) |
Add an IIR filter option for UHJ encoding/decoding
This uses the reversed-allpass trick to maintain linear phase. with a 256-
sample look-ahead/delay to minimize distortion. This should better preserve low
frequencies while maintaining a proper phase response.
Diffstat (limited to 'core/voice.cpp')
-rw-r--r-- | core/voice.cpp | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/core/voice.cpp b/core/voice.cpp index 74363fc1..ae8582da 100644 --- a/core/voice.cpp +++ b/core/voice.cpp @@ -852,37 +852,44 @@ void Voice::prepare(DeviceBase *device) mPrevSamples.reserve(maxu(2, num_channels)); mPrevSamples.resize(num_channels); + mDecoder = nullptr; + mDecoderPadding = 0; if(mFmtChannels == FmtSuperStereo) { - if(UhjQuality >= UhjLengthHq) - { - mDecoder = std::make_unique<UhjStereoDecoder<UhjLengthHq>>(); - mDecoderPadding = UhjStereoDecoder<UhjLengthHq>::sFilterDelay; - } - else + switch(UhjQuality) { + case UhjQualityType::IIR: + mDecoder = std::make_unique<UhjStereoDecoderIIR>(); + mDecoderPadding = UhjStereoDecoderIIR::sFilterDelay; + break; + case UhjQualityType::FIR256: mDecoder = std::make_unique<UhjStereoDecoder<UhjLengthLq>>(); mDecoderPadding = UhjStereoDecoder<UhjLengthLq>::sFilterDelay; + break; + case UhjQualityType::FIR512: + mDecoder = std::make_unique<UhjStereoDecoder<UhjLengthHq>>(); + mDecoderPadding = UhjStereoDecoder<UhjLengthHq>::sFilterDelay; + break; } } else if(IsUHJ(mFmtChannels)) { - if(UhjQuality >= UhjLengthHq) - { - mDecoder = std::make_unique<UhjDecoder<UhjLengthHq>>(); - mDecoderPadding = UhjDecoder<UhjLengthHq>::sFilterDelay; - } - else + switch(UhjQuality) { + case UhjQualityType::IIR: + mDecoder = std::make_unique<UhjDecoderIIR>(); + mDecoderPadding = UhjDecoderIIR::sFilterDelay; + break; + case UhjQualityType::FIR256: mDecoder = std::make_unique<UhjDecoder<UhjLengthLq>>(); mDecoderPadding = UhjDecoder<UhjLengthLq>::sFilterDelay; + break; + case UhjQualityType::FIR512: + mDecoder = std::make_unique<UhjDecoder<UhjLengthHq>>(); + mDecoderPadding = UhjDecoder<UhjLengthHq>::sFilterDelay; + break; } } - else - { - mDecoder = nullptr; - mDecoderPadding = 0; - } /* Clear the stepping value explicitly so the mixer knows not to mix this * until the update gets applied. @@ -925,11 +932,11 @@ void Voice::prepare(DeviceBase *device) if(mFmtChannels == FmtUHJ2) { mChans[0].mAmbiHFScale = 1.0f; - mChans[0].mAmbiLFScale = UhjDecoder<UhjLengthStd>::sWLFScale; + mChans[0].mAmbiLFScale = DecoderBase::sWLFScale; mChans[1].mAmbiHFScale = 1.0f; - mChans[1].mAmbiLFScale = UhjDecoder<UhjLengthStd>::sXYLFScale; + mChans[1].mAmbiLFScale = DecoderBase::sXYLFScale; mChans[2].mAmbiHFScale = 1.0f; - mChans[2].mAmbiLFScale = UhjDecoder<UhjLengthStd>::sXYLFScale; + mChans[2].mAmbiLFScale = DecoderBase::sXYLFScale; } mFlags.set(VoiceIsAmbisonic); } @@ -949,9 +956,9 @@ void Voice::prepare(DeviceBase *device) chandata.mDryParams.NFCtrlFilter = device->mNFCtrlFilter; std::fill_n(chandata.mWetParams.begin(), device->NumAuxSends, SendParams{}); } - mChans[0].mAmbiLFScale = UhjDecoder<UhjLengthStd>::sWLFScale; - mChans[1].mAmbiLFScale = UhjDecoder<UhjLengthStd>::sXYLFScale; - mChans[2].mAmbiLFScale = UhjDecoder<UhjLengthStd>::sXYLFScale; + mChans[0].mAmbiLFScale = DecoderBase::sWLFScale; + mChans[1].mAmbiLFScale = DecoderBase::sXYLFScale; + mChans[2].mAmbiLFScale = DecoderBase::sXYLFScale; mFlags.set(VoiceIsAmbisonic); } else |