aboutsummaryrefslogtreecommitdiffstats
path: root/core/voice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/voice.cpp')
-rw-r--r--core/voice.cpp56
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)
{