aboutsummaryrefslogtreecommitdiffstats
path: root/core/voice.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2022-10-21 10:33:41 -0700
committerChris Robinson <[email protected]>2022-10-21 10:33:41 -0700
commitee40a2e7e4867a769765d447a15ac88832eb8aa0 (patch)
tree0ff9157bc237db41795d27dd731b0191289bb5e2 /core/voice.cpp
parent53b63f329c3daa82f3c02ed43b67338af3a3d77d (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.cpp53
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