diff options
Diffstat (limited to 'core/voice.cpp')
-rw-r--r-- | core/voice.cpp | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/core/voice.cpp b/core/voice.cpp index 15330012..5263202e 100644 --- a/core/voice.cpp +++ b/core/voice.cpp @@ -892,20 +892,52 @@ void Voice::prepare(DeviceBase *device) /* Make sure the sample history is cleared. */ std::fill(mPrevSamples.begin(), mPrevSamples.end(), HistoryLine{}); - /* 2-channel UHJ needs different shelf filters. However, we can't just use - * different shelf filters after mixing it, given any old speaker setup the - * user has. To make this work, we apply the expected shelf filters for - * decoding UHJ2 to quad (only needs LF scaling), and act as if those 4 - * quad channels are encoded right back into B-Format. - * - * This isn't perfect, but without an entirely separate and limited UHJ2 - * path, it's better than nothing. - * - * Do not apply the shelf filter with UHJ output. UHJ2->B-Format->UHJ2 is - * identity, so don't mess with it. + /* Don't need to set the VoiceIsAmbisonic flag if the device is not higher + * order than the voice. No HF scaling is necessary to mix it. */ - if(mFmtChannels == FmtUHJ2 && !device->mUhjEncoder) + if(mAmbiOrder && device->mAmbiOrder > mAmbiOrder) { + const uint8_t *OrderFromChan{Is2DAmbisonic(mFmtChannels) ? + AmbiIndex::OrderFrom2DChannel().data() : AmbiIndex::OrderFromChannel().data()}; + const auto scales = AmbiScale::GetHFOrderScales(mAmbiOrder, !Is2DAmbisonic(mFmtChannels)); + + const BandSplitter splitter{device->mXOverFreq / static_cast<float>(device->Frequency)}; + for(auto &chandata : mChans) + { + chandata.mAmbiHFScale = scales[*(OrderFromChan++)]; + chandata.mAmbiLFScale = 1.0f; + chandata.mAmbiSplitter = splitter; + chandata.mDryParams = DirectParams{}; + chandata.mDryParams.NFCtrlFilter = device->mNFCtrlFilter; + std::fill_n(chandata.mWetParams.begin(), device->NumAuxSends, SendParams{}); + } + /* 2-channel UHJ needs different shelf filters. However, we can't just + * use different shelf filters after mixing it and with any old speaker + * setup the user has. To make this work, we apply the expected shelf + * filters for decoding UHJ2 to quad (only needs LF scaling), and act + * as if those 4 quad channels are encoded right back onto higher-order + * B-Format. + * + * This isn't perfect, but without an entirely separate and limited + * UHJ2 path, it's better than nothing. + */ + if(mFmtChannels == FmtUHJ2) + { + mChans[0].mAmbiHFScale = 1.0f; + mChans[0].mAmbiLFScale = UhjDecoder<UhjLengthStd>::sWLFScale; + mChans[1].mAmbiHFScale = 1.0f; + mChans[1].mAmbiLFScale = UhjDecoder<UhjLengthStd>::sXYLFScale; + mChans[2].mAmbiHFScale = 1.0f; + mChans[2].mAmbiLFScale = UhjDecoder<UhjLengthStd>::sXYLFScale; + } + mFlags.set(VoiceIsAmbisonic); + } + else if(mFmtChannels == FmtUHJ2 && !device->mUhjEncoder) + { + /* 2-channel UHJ with first-order output also needs the shelf filter + * correction applied, except with UHJ output (UHJ2->B-Format->UHJ2 is + * identity, so don't mess with it). + */ const BandSplitter splitter{device->mXOverFreq / static_cast<float>(device->Frequency)}; for(auto &chandata : mChans) { |