diff options
author | Chris Robinson <[email protected]> | 2017-03-10 04:35:32 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2017-03-10 04:35:32 -0800 |
commit | 583d431947be540a33843d68feb5f1456671c298 (patch) | |
tree | 0f85220f58dd446d9732cb3a70bf7917585619c8 /Alc/mixer.c | |
parent | d9b1995e95ac3d838566500f1e5496ae71d832e0 (diff) |
Implement NFC filters for Ambisonic rendering
NFC filters currently only work when rendering to ambisonic buffers, which
includes HQ rendering and ambisonic output. There are two new config options:
'decoder/nfc' (default on) enables or disables use of NFC filters globally, and
'decoder/nfc-ref-delay' (default 0) specifies the reference delay parameter for
NFC-HOA rendering with ambisonic output (a value of 0 disables NFC).
Currently, NFC filters rely on having an appropriate value set for
AL_METERS_PER_UNIT to get the correct scaling. HQ rendering uses the averaged
speaker distances as a control/reference, and currently doesn't correct for
individual speaker distances (if the speakers are all equidistant, this is
fine, otherwise per-speaker correction should be done as well).
Diffstat (limited to 'Alc/mixer.c')
-rw-r--r-- | Alc/mixer.c | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/Alc/mixer.c b/Alc/mixer.c index 1c503a92..961c8f31 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -545,15 +545,60 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei &parms->LowPass, &parms->HighPass, Device->FilteredData, ResampledData, DstBufferSize, parms->FilterType ); - if(!voice->IsHrtf) + if(!(voice->Flags&VOICE_IS_HRTF)) { if(!Counter) memcpy(parms->Gains.Current, parms->Gains.Target, sizeof(parms->Gains.Current)); - MixSamples(samples, voice->Direct.Channels, voice->Direct.Buffer, - parms->Gains.Current, parms->Gains.Target, Counter, OutPos, - DstBufferSize - ); + if(!(voice->Flags&VOICE_HAS_NFC)) + MixSamples(samples, voice->Direct.Channels, voice->Direct.Buffer, + parms->Gains.Current, parms->Gains.Target, Counter, OutPos, + DstBufferSize + ); + else + { + ALfloat *nfcsamples = Device->NFCtrlData; + ALsizei chanoffset = 0; + MixSamples(samples, + voice->Direct.ChannelsPerOrder[0], voice->Direct.Buffer, + parms->Gains.Current, parms->Gains.Target, Counter, OutPos, + DstBufferSize + ); + chanoffset += voice->Direct.ChannelsPerOrder[0]; + if(voice->Direct.ChannelsPerOrder[1] > 0) + { + NfcFilterUpdate1(&parms->NFCtrlFilter[0], nfcsamples, samples, + DstBufferSize); + MixSamples(nfcsamples, + voice->Direct.ChannelsPerOrder[1], voice->Direct.Buffer+chanoffset, + parms->Gains.Current+chanoffset, parms->Gains.Target+chanoffset, + Counter, OutPos, DstBufferSize + ); + chanoffset += voice->Direct.ChannelsPerOrder[1]; + } + if(voice->Direct.ChannelsPerOrder[2] > 0) + { + NfcFilterUpdate2(&parms->NFCtrlFilter[1], nfcsamples, samples, + DstBufferSize); + MixSamples(nfcsamples, + voice->Direct.ChannelsPerOrder[2], voice->Direct.Buffer+chanoffset, + parms->Gains.Current+chanoffset, parms->Gains.Target+chanoffset, + Counter, OutPos, DstBufferSize + ); + chanoffset += voice->Direct.ChannelsPerOrder[2]; + } + if(voice->Direct.ChannelsPerOrder[3] > 0) + { + NfcFilterUpdate3(&parms->NFCtrlFilter[2], nfcsamples, samples, + DstBufferSize); + MixSamples(nfcsamples, + voice->Direct.ChannelsPerOrder[3], voice->Direct.Buffer+chanoffset, + parms->Gains.Current+chanoffset, parms->Gains.Target+chanoffset, + Counter, OutPos, DstBufferSize + ); + chanoffset += voice->Direct.ChannelsPerOrder[3]; + } + } } else { |