diff options
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/ALc.c | 6 | ||||
-rw-r--r-- | Alc/ALu.c | 30 | ||||
-rw-r--r-- | Alc/mixer.c | 4 | ||||
-rw-r--r-- | Alc/nfcfilter.c | 160 | ||||
-rw-r--r-- | Alc/nfcfilter.h | 32 |
5 files changed, 120 insertions, 112 deletions
@@ -2331,11 +2331,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC / (device->AvgSpeakerDist * device->Frequency); for(i = 0;i < voice->NumChannels;i++) - { - NfcFilterCreate1(&voice->Direct.Params[i].NFCtrlFilter[0], 0.0f, w1); - NfcFilterCreate2(&voice->Direct.Params[i].NFCtrlFilter[1], 0.0f, w1); - NfcFilterCreate3(&voice->Direct.Params[i].NFCtrlFilter[2], 0.0f, w1); - } + NfcFilterCreate(&voice->Direct.Params[i].NFCtrlFilter, 0.0f, w1); } } almtx_unlock(&context->SourceLock); @@ -601,9 +601,7 @@ static void CalcPanningAndFilters(ALvoice *voice, const ALfloat Distance, const w0 = minf(w0, w1*4.0f); /* Only need to adjust the first channel of a B-Format source. */ - NfcFilterAdjust1(&voice->Direct.Params[0].NFCtrlFilter[0], w0); - NfcFilterAdjust2(&voice->Direct.Params[0].NFCtrlFilter[1], w0); - NfcFilterAdjust3(&voice->Direct.Params[0].NFCtrlFilter[2], w0); + NfcFilterAdjust(&voice->Direct.Params[0].NFCtrlFilter, w0); for(i = 0;i < MAX_AMBI_ORDER+1;i++) voice->Direct.ChannelsPerOrder[i] = Device->Dry.NumChannelsPerOrder[i]; @@ -660,9 +658,7 @@ static void CalcPanningAndFilters(ALvoice *voice, const ALfloat Distance, const * is what we want for FOA input. The first channel may have * been previously re-adjusted if panned, so reset it. */ - NfcFilterAdjust1(&voice->Direct.Params[0].NFCtrlFilter[0], 0.0f); - NfcFilterAdjust2(&voice->Direct.Params[0].NFCtrlFilter[1], 0.0f); - NfcFilterAdjust3(&voice->Direct.Params[0].NFCtrlFilter[2], 0.0f); + NfcFilterAdjust(&voice->Direct.Params[0].NFCtrlFilter, 0.0f); voice->Direct.ChannelsPerOrder[0] = 1; voice->Direct.ChannelsPerOrder[1] = mini(voice->Direct.Channels-1, 3); @@ -896,6 +892,10 @@ static void CalcPanningAndFilters(ALvoice *voice, const ALfloat Distance, const */ w0 = minf(w0, w1*4.0f); + /* Adjust NFC filters. */ + for(c = 0;c < num_channels;c++) + NfcFilterAdjust(&voice->Direct.Params[c].NFCtrlFilter, w0); + for(i = 0;i < MAX_AMBI_ORDER+1;i++) voice->Direct.ChannelsPerOrder[i] = Device->Dry.NumChannelsPerOrder[i]; voice->Flags |= VOICE_HAS_NFC; @@ -915,14 +915,6 @@ static void CalcPanningAndFilters(ALvoice *voice, const ALfloat Distance, const for(c = 0;c < num_channels;c++) { - /* Adjust NFC filters if needed. */ - if((voice->Flags&VOICE_HAS_NFC)) - { - NfcFilterAdjust1(&voice->Direct.Params[c].NFCtrlFilter[0], w0); - NfcFilterAdjust2(&voice->Direct.Params[c].NFCtrlFilter[1], w0); - NfcFilterAdjust3(&voice->Direct.Params[c].NFCtrlFilter[2], w0); - } - /* Special-case LFE */ if(chans[c].channel == LFE) { @@ -979,6 +971,9 @@ static void CalcPanningAndFilters(ALvoice *voice, const ALfloat Distance, const w0 = SPEEDOFSOUNDMETRESPERSEC / (Device->AvgSpeakerDist * (ALfloat)Device->Frequency); + for(c = 0;c < num_channels;c++) + NfcFilterAdjust(&voice->Direct.Params[c].NFCtrlFilter, w0); + for(i = 0;i < MAX_AMBI_ORDER+1;i++) voice->Direct.ChannelsPerOrder[i] = Device->Dry.NumChannelsPerOrder[i]; voice->Flags |= VOICE_HAS_NFC; @@ -988,13 +983,6 @@ static void CalcPanningAndFilters(ALvoice *voice, const ALfloat Distance, const { ALfloat coeffs[MAX_AMBI_COEFFS]; - if((voice->Flags&VOICE_HAS_NFC)) - { - NfcFilterAdjust1(&voice->Direct.Params[c].NFCtrlFilter[0], w0); - NfcFilterAdjust2(&voice->Direct.Params[c].NFCtrlFilter[1], w0); - NfcFilterAdjust3(&voice->Direct.Params[c].NFCtrlFilter[2], w0); - } - /* Special-case LFE */ if(chans[c].channel == LFE) { diff --git a/Alc/mixer.c b/Alc/mixer.c index 11b721f1..eb4568b2 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -564,8 +564,8 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize #define APPLY_NFC_MIX(order) \ if(voice->Direct.ChannelsPerOrder[order] > 0) \ { \ - NfcFilterUpdate##order(&parms->NFCtrlFilter[order-1], nfcsamples, \ - samples, DstBufferSize); \ + NfcFilterUpdate##order(&parms->NFCtrlFilter, nfcsamples, samples, \ + DstBufferSize); \ MixSamples(nfcsamples, voice->Direct.ChannelsPerOrder[order], \ voice->Direct.Buffer+chanoffset, parms->Gains.Current+chanoffset, \ parms->Gains.Target+chanoffset, Counter, OutPos, DstBufferSize \ diff --git a/Alc/nfcfilter.c b/Alc/nfcfilter.c index 758863c9..57a3e28f 100644 --- a/Alc/nfcfilter.c +++ b/Alc/nfcfilter.c @@ -52,13 +52,11 @@ static const float B[4][3] = { /*{ 4.2076f, 11.4877f, 5.7924f, 9.1401f }*/ }; -void NfcFilterCreate1(NfcFilter *nfc, const float w0, const float w1) +static void NfcFilterCreate1(struct NfcFilter1 *nfc, const float w0, const float w1) { float b_00, g_0; float r; - memset(nfc, 0, sizeof(*nfc)); - nfc->g = 1.0f; nfc->coeffs[0] = 1.0f; @@ -80,7 +78,7 @@ void NfcFilterCreate1(NfcFilter *nfc, const float w0, const float w1) nfc->coeffs[1+1] = (2.0f * b_00) / g_0; } -void NfcFilterAdjust1(NfcFilter *nfc, const float w0) +static void NfcFilterAdjust1(struct NfcFilter1 *nfc, const float w0) { float b_00, g_0; float r; @@ -93,36 +91,12 @@ void NfcFilterAdjust1(NfcFilter *nfc, const float w0) nfc->coeffs[1] = (2.0f * b_00) / g_0; } -void NfcFilterUpdate1(NfcFilter *nfc, ALfloat *restrict dst, const float *restrict src, const int count) -{ - const float b0 = nfc->coeffs[0]; - const float a0 = nfc->coeffs[1]; - const float a1 = nfc->coeffs[2]; - float z1 = nfc->history[0]; - int i; - - for(i = 0;i < count;i++) - { - float out = src[i] * b0; - float y; - - y = out - (a1*z1); - out = y + (a0*z1); - z1 += y; - - dst[i] = out; - } - nfc->history[0] = z1; -} - -void NfcFilterCreate2(NfcFilter *nfc, const float w0, const float w1) +static void NfcFilterCreate2(struct NfcFilter2 *nfc, const float w0, const float w1) { float b_10, b_11, g_1; float r; - memset(nfc, 0, sizeof(*nfc)); - nfc->g = 1.0f; nfc->coeffs[0] = 1.0f; @@ -148,7 +122,7 @@ void NfcFilterCreate2(NfcFilter *nfc, const float w0, const float w1) nfc->coeffs[2+2] = (4.0f * b_11) / g_1; } -void NfcFilterAdjust2(NfcFilter *nfc, const float w0) +static void NfcFilterAdjust2(struct NfcFilter2 *nfc, const float w0) { float b_10, b_11, g_1; float r; @@ -163,42 +137,13 @@ void NfcFilterAdjust2(NfcFilter *nfc, const float w0) nfc->coeffs[2] = (4.0f * b_11) / g_1; } -void NfcFilterUpdate2(NfcFilter *nfc, ALfloat *restrict dst, const float *restrict src, const int count) -{ - const float b0 = nfc->coeffs[0]; - const float a00 = nfc->coeffs[1]; - const float a01 = nfc->coeffs[2]; - const float a10 = nfc->coeffs[3]; - const float a11 = nfc->coeffs[4]; - float z1 = nfc->history[0]; - float z2 = nfc->history[1]; - int i; - for(i = 0;i < count;i++) - { - float out = src[i] * b0; - float y; - - y = out - (a10*z1) - (a11*z2); - out = y + (a00*z1) + (a01*z2); - z2 += z1; - z1 += y; - - dst[i] = out; - } - nfc->history[0] = z1; - nfc->history[1] = z2; -} - - -void NfcFilterCreate3(NfcFilter *nfc, const float w0, const float w1) +static void NfcFilterCreate3(struct NfcFilter3 *nfc, const float w0, const float w1) { float b_10, b_11, g_1; float b_00, g_0; float r; - memset(nfc, 0, sizeof(*nfc)); - nfc->g = 1.0f; nfc->coeffs[0] = 1.0f; @@ -237,7 +182,7 @@ void NfcFilterCreate3(NfcFilter *nfc, const float w0, const float w1) nfc->coeffs[3+2+1] = (2.0f * b_00) / g_0; } -void NfcFilterAdjust3(NfcFilter *nfc, const float w0) +static void NfcFilterAdjust3(struct NfcFilter3 *nfc, const float w0) { float b_10, b_11, g_1; float b_00, g_0; @@ -259,18 +204,84 @@ void NfcFilterAdjust3(NfcFilter *nfc, const float w0) nfc->coeffs[2+1] = (2.0f * b_00) / g_0; } + +void NfcFilterCreate(NfcFilter *nfc, const float w0, const float w1) +{ + memset(nfc, 0, sizeof(*nfc)); + NfcFilterCreate1(&nfc->first, w0, w1); + NfcFilterCreate2(&nfc->second, w0, w1); + NfcFilterCreate3(&nfc->third, w0, w1); +} + +void NfcFilterAdjust(NfcFilter *nfc, const float w0) +{ + NfcFilterAdjust1(&nfc->first, w0); + NfcFilterAdjust2(&nfc->second, w0); + NfcFilterAdjust3(&nfc->third, w0); +} + + +void NfcFilterUpdate1(NfcFilter *nfc, ALfloat *restrict dst, const float *restrict src, const int count) +{ + const float b0 = nfc->first.coeffs[0]; + const float a0 = nfc->first.coeffs[1]; + const float a1 = nfc->first.coeffs[2]; + float z1 = nfc->first.history[0]; + int i; + + for(i = 0;i < count;i++) + { + float out = src[i] * b0; + float y; + + y = out - (a1*z1); + out = y + (a0*z1); + z1 += y; + + dst[i] = out; + } + nfc->first.history[0] = z1; +} + +void NfcFilterUpdate2(NfcFilter *nfc, ALfloat *restrict dst, const float *restrict src, const int count) +{ + const float b0 = nfc->second.coeffs[0]; + const float a00 = nfc->second.coeffs[1]; + const float a01 = nfc->second.coeffs[2]; + const float a10 = nfc->second.coeffs[3]; + const float a11 = nfc->second.coeffs[4]; + float z1 = nfc->second.history[0]; + float z2 = nfc->second.history[1]; + int i; + + for(i = 0;i < count;i++) + { + float out = src[i] * b0; + float y; + + y = out - (a10*z1) - (a11*z2); + out = y + (a00*z1) + (a01*z2); + z2 += z1; + z1 += y; + + dst[i] = out; + } + nfc->second.history[0] = z1; + nfc->second.history[1] = z2; +} + void NfcFilterUpdate3(NfcFilter *nfc, ALfloat *restrict dst, const float *restrict src, const int count) { - const float b0 = nfc->coeffs[0]; - const float a00 = nfc->coeffs[1]; - const float a01 = nfc->coeffs[2]; - const float a02 = nfc->coeffs[3]; - const float a10 = nfc->coeffs[4]; - const float a11 = nfc->coeffs[5]; - const float a12 = nfc->coeffs[6]; - float z1 = nfc->history[0]; - float z2 = nfc->history[1]; - float z3 = nfc->history[2]; + const float b0 = nfc->third.coeffs[0]; + const float a00 = nfc->third.coeffs[1]; + const float a01 = nfc->third.coeffs[2]; + const float a02 = nfc->third.coeffs[3]; + const float a10 = nfc->third.coeffs[4]; + const float a11 = nfc->third.coeffs[5]; + const float a12 = nfc->third.coeffs[6]; + float z1 = nfc->third.history[0]; + float z2 = nfc->third.history[1]; + float z3 = nfc->third.history[2]; int i; for(i = 0;i < count;i++) @@ -289,12 +300,11 @@ void NfcFilterUpdate3(NfcFilter *nfc, ALfloat *restrict dst, const float *restri dst[i] = out; } - nfc->history[0] = z1; - nfc->history[1] = z2; - nfc->history[2] = z3; + nfc->third.history[0] = z1; + nfc->third.history[1] = z2; + nfc->third.history[2] = z3; } - #if 0 /* Original methods the above are derived from. */ static void NfcFilterCreate(NfcFilter *nfc, const ALsizei order, const float src_dist, const float ctl_dist, const float rate) { diff --git a/Alc/nfcfilter.h b/Alc/nfcfilter.h index 199849fb..0bf9a5c4 100644 --- a/Alc/nfcfilter.h +++ b/Alc/nfcfilter.h @@ -3,12 +3,29 @@ #include "alMain.h" -typedef struct NfcFilter { +struct NfcFilter1 { + float g; + float coeffs[1*2 + 1]; + float history[1]; +}; +struct NfcFilter2 { float g; - float coeffs[MAX_AMBI_ORDER*2 + 1]; - float history[MAX_AMBI_ORDER]; + float coeffs[2*2 + 1]; + float history[2]; +}; +struct NfcFilter3 { + float g; + float coeffs[3*2 + 1]; + float history[3]; +}; + +typedef struct NfcFilter { + struct NfcFilter1 first; + struct NfcFilter2 second; + struct NfcFilter3 third; } NfcFilter; + /* NOTE: * w0 = speed_of_sound / (source_distance * sample_rate); * w1 = speed_of_sound / (control_distance * sample_rate); @@ -19,19 +36,16 @@ typedef struct NfcFilter { * small relative to the control distance. */ +void NfcFilterCreate(NfcFilter *nfc, const float w0, const float w1); +void NfcFilterAdjust(NfcFilter *nfc, const float w0); + /* Near-field control filter for first-order ambisonic channels (1-3). */ -void NfcFilterCreate1(NfcFilter *nfc, const float w0, const float w1); -void NfcFilterAdjust1(NfcFilter *nfc, const float w0); void NfcFilterUpdate1(NfcFilter *nfc, float *restrict dst, const float *restrict src, const int count); /* Near-field control filter for second-order ambisonic channels (4-8). */ -void NfcFilterCreate2(NfcFilter *nfc, const float w0, const float w1); -void NfcFilterAdjust2(NfcFilter *nfc, const float w0); void NfcFilterUpdate2(NfcFilter *nfc, float *restrict dst, const float *restrict src, const int count); /* Near-field control filter for third-order ambisonic channels (9-15). */ -void NfcFilterCreate3(NfcFilter *nfc, const float w0, const float w1); -void NfcFilterAdjust3(NfcFilter *nfc, const float w0); void NfcFilterUpdate3(NfcFilter *nfc, float *restrict dst, const float *restrict src, const int count); #endif /* NFCFILTER_H */ |