diff options
author | Chris Robinson <[email protected]> | 2021-12-11 17:50:24 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2021-12-11 17:50:24 -0800 |
commit | 01dd34f305b9ad2c8e6bf0642cd976f9788fdf3a (patch) | |
tree | 75f50acecb284a587e13265efb14ed573af90245 /core/voice.cpp | |
parent | a75d35bbb06f74e58cb2232d4ca2ce47950f08cd (diff) |
Add an internal Super Stereo format
It's not available as an AL buffer format (yet) since I'm not sure how to
expose it. Internally it seems fine as a separate channel configuration, but
because OpenAL combines the channel configuration and sample type, a flag may
work better there.
Diffstat (limited to 'core/voice.cpp')
-rw-r--r-- | core/voice.cpp | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/core/voice.cpp b/core/voice.cpp index a8c5b281..923d7275 100644 --- a/core/voice.cpp +++ b/core/voice.cpp @@ -207,7 +207,7 @@ void LoadSamples(const al::span<DeviceBase::MixerBufferLine> dstSamples, const s #define HANDLE_FMT(T) case T: \ { \ constexpr size_t sampleSize{sizeof(al::FmtTypeTraits<T>::Type)}; \ - if(srcchans == FmtUHJ2) \ + if(srcchans == FmtUHJ2 || srcchans == FmtSuperStereo) \ { \ src += srcOffset*2u*sampleSize; \ al::LoadSampleArray<T>(dstSamples[0].data() + dstOffset, src, \ @@ -510,8 +510,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo Device->mSampleData.data() + Device->mSampleData.size() - mChans.size(), mChans.size()}; const uint PostPadding{MaxResamplerEdge + - ((mFmtChannels==FmtUHJ2 || mFmtChannels==FmtUHJ3 || mFmtChannels==FmtUHJ4) - ? uint{UhjDecoder::sFilterDelay} : 0u)}; + (mDecoder ? uint{UhjDecoder::sFilterDelay} : 0u)}; uint buffers_done{0u}; uint OutPos{0u}; do { @@ -628,7 +627,8 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo { const size_t srcOffset{(increment*DstBufferSize + DataPosFrac)>>MixerFracBits}; SrcBufferSize = SrcBufferSize - PostPadding + MaxResamplerEdge; - mDecoder->decode(MixingSamples, MaxResamplerEdge, SrcBufferSize, srcOffset); + ((*mDecoder).*mDecoderFunc)(MixingSamples, MaxResamplerEdge, SrcBufferSize, + srcOffset); } } @@ -814,10 +814,17 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo void Voice::prepare(DeviceBase *device) { - if((mFmtChannels == FmtUHJ2 || mFmtChannels == FmtUHJ3 || mFmtChannels==FmtUHJ4) && !mDecoder) + if(IsUHJ(mFmtChannels)) + { mDecoder = std::make_unique<UhjDecoder>(); - else if(mFmtChannels != FmtUHJ2 && mFmtChannels != FmtUHJ3 && mFmtChannels != FmtUHJ4) + mDecoderFunc = (mFmtChannels == FmtSuperStereo) ? &UhjDecoder::decodeStereo + : &UhjDecoder::decode; + } + else + { mDecoder = nullptr; + mDecoderFunc = nullptr; + } /* Clear the stepping value explicitly so the mixer knows not to mix this * until the update gets applied. @@ -833,7 +840,8 @@ void Voice::prepare(DeviceBase *device) if(mAmbiOrder && device->mAmbiOrder > mAmbiOrder) { const uint8_t *OrderFromChan{(mFmtChannels == FmtBFormat2D - || mFmtChannels == FmtUHJ2 || mFmtChannels == FmtUHJ3) ? + || mFmtChannels == FmtUHJ2 || mFmtChannels == FmtUHJ3 + || mFmtChannels == FmtSuperStereo) ? AmbiIndex::OrderFrom2DChannel().data() : AmbiIndex::OrderFromChannel().data()}; const auto scales = AmbiScale::GetHFOrderScales(mAmbiOrder, device->mAmbiOrder); @@ -850,9 +858,9 @@ void Voice::prepare(DeviceBase *device) * 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 channels are encoded back onto first-order B-Format, - * which then upsamples to higher order as normal (only needs HF - * scaling). + * as if those 4 quad channels are encoded right back onto first-order + * B-Format, which then upsamples to higher order as normal (only needs + * HF scaling). * * This isn't perfect, but without an entirely separate and limited * UHJ2 path, it's better than nothing. |