aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/mixer.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-03-10 04:35:32 -0800
committerChris Robinson <[email protected]>2017-03-10 04:35:32 -0800
commit583d431947be540a33843d68feb5f1456671c298 (patch)
tree0f85220f58dd446d9732cb3a70bf7917585619c8 /Alc/mixer.c
parentd9b1995e95ac3d838566500f1e5496ae71d832e0 (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.c55
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
{