diff options
-rw-r--r-- | Alc/mixvoice.cpp | 6 | ||||
-rw-r--r-- | OpenAL32/Include/alu.h | 2 | ||||
-rw-r--r-- | OpenAL32/alSource.cpp | 27 |
3 files changed, 25 insertions, 10 deletions
diff --git a/Alc/mixvoice.cpp b/Alc/mixvoice.cpp index b087c4dc..4c8b2761 100644 --- a/Alc/mixvoice.cpp +++ b/Alc/mixvoice.cpp @@ -607,11 +607,7 @@ void MixSource(ALvoice *voice, const ALuint SourceID, ALCcontext *Context, const Device->ResampledData, DstBufferSize)}; if((voice->Flags&VOICE_IS_AMBISONIC)) { - /* TODO: Does not properly handle HOA sources. Currently only - * first-order sources are possible, but in the future it would - * be desirable. - */ - const ALfloat hfscale{(chan==0) ? voice->AmbiScales[0] : voice->AmbiScales[1]}; + const ALfloat hfscale{voice->AmbiScales[chan]}; /* Beware the evil const_cast. It's safe since it's pointing to * either SrcData or Device->ResampledData (both non-const), * but the resample method takes its input as const float* and diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 577b71f5..2b2432c4 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -256,7 +256,7 @@ struct ALvoice { InterpState ResampleState; - std::array<ALfloat,MAX_AMBI_ORDER+1> AmbiScales; + std::array<ALfloat,MAX_INPUT_CHANNELS> AmbiScales; BandSplitter AmbiSplitter[MAX_INPUT_CHANNELS]; struct { diff --git a/OpenAL32/alSource.cpp b/OpenAL32/alSource.cpp index 1163fae3..ed0b813f 100644 --- a/OpenAL32/alSource.cpp +++ b/OpenAL32/alSource.cpp @@ -2871,13 +2871,32 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) /* Don't need to set the VOICE_IS_AMBISONIC flag if the device is * mixing in first order. No HF scaling is necessary to mix it. */ - if(((*buffer)->mFmtChannels == FmtBFormat2D || (*buffer)->mFmtChannels == FmtBFormat3D) && + if((voice->Channels == FmtBFormat2D || voice->Channels == FmtBFormat3D) && device->mAmbiOrder > 1) { - voice->AmbiScales = BFormatDec::GetHFOrderScales(1, device->mAmbiOrder); + auto scales = BFormatDec::GetHFOrderScales(1, device->mAmbiOrder); + if(voice->Channels == FmtBFormat2D) + { + static constexpr int Order2DFromChan[MAX_AMBI2D_CHANNELS]{ + 0, 1,1, 2,2, 3,3 + }; + const size_t count{Ambi2DChannelsFromOrder(1u)}; + std::transform(Order2DFromChan, Order2DFromChan+count, voice->AmbiScales.begin(), + [&scales](size_t idx) -> ALfloat { return scales[idx]; }); + } + else + { + static constexpr int OrderFromChan[MAX_AMBI_CHANNELS]{ + 0, 1,1,1, 2,2,2,2,2, 3,3,3,3,3,3,3, + }; + const size_t count{Ambi2DChannelsFromOrder(1u)}; + std::transform(OrderFromChan, OrderFromChan+count, voice->AmbiScales.begin(), + [&scales](size_t idx) -> ALfloat { return scales[idx]; }); + } + voice->AmbiSplitter[0].init(400.0f / static_cast<ALfloat>(device->Frequency)); - for(ALsizei i{1};i < voice->NumChannels;++i) - voice->AmbiSplitter[i] = voice->AmbiSplitter[0]; + std::fill(std::begin(voice->AmbiSplitter)+1, + std::begin(voice->AmbiSplitter)+voice->NumChannels, voice->AmbiSplitter[0]); voice->Flags |= VOICE_IS_AMBISONIC; } |