Use class methods for the NFC filters
This commit is contained in:
parent
164a86a381
commit
10b39d57d5
@ -2341,8 +2341,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
|||||||
ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
|
ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
|
||||||
(device->AvgSpeakerDist * device->Frequency);
|
(device->AvgSpeakerDist * device->Frequency);
|
||||||
std::for_each(voice->Direct.Params, voice->Direct.Params+voice->NumChannels,
|
std::for_each(voice->Direct.Params, voice->Direct.Params+voice->NumChannels,
|
||||||
[w1](DirectParams ¶ms) -> void
|
[w1](DirectParams ¶ms) noexcept -> void
|
||||||
{ NfcFilterCreate(¶ms.NFCtrlFilter, 0.0f, w1); }
|
{ params.NFCtrlFilter.init(0.0f, w1); }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -608,7 +608,7 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALfloat Elev
|
|||||||
w0 = minf(w0, w1*4.0f);
|
w0 = minf(w0, w1*4.0f);
|
||||||
|
|
||||||
/* Only need to adjust the first channel of a B-Format source. */
|
/* Only need to adjust the first channel of a B-Format source. */
|
||||||
NfcFilterAdjust(&voice->Direct.Params[0].NFCtrlFilter, w0);
|
voice->Direct.Params[0].NFCtrlFilter.adjust(w0);
|
||||||
|
|
||||||
std::copy(std::begin(Device->NumChannelsPerOrder),
|
std::copy(std::begin(Device->NumChannelsPerOrder),
|
||||||
std::end(Device->NumChannelsPerOrder),
|
std::end(Device->NumChannelsPerOrder),
|
||||||
@ -649,7 +649,7 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALfloat Elev
|
|||||||
* is what we want for FOA input. The first channel may have
|
* is what we want for FOA input. The first channel may have
|
||||||
* been previously re-adjusted if panned, so reset it.
|
* been previously re-adjusted if panned, so reset it.
|
||||||
*/
|
*/
|
||||||
NfcFilterAdjust(&voice->Direct.Params[0].NFCtrlFilter, 0.0f);
|
voice->Direct.Params[0].NFCtrlFilter.adjust(0.0f);
|
||||||
|
|
||||||
voice->Direct.ChannelsPerOrder[0] = 1;
|
voice->Direct.ChannelsPerOrder[0] = 1;
|
||||||
voice->Direct.ChannelsPerOrder[1] = mini(voice->Direct.Channels-1, 3);
|
voice->Direct.ChannelsPerOrder[1] = mini(voice->Direct.Channels-1, 3);
|
||||||
@ -853,7 +853,7 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALfloat Elev
|
|||||||
|
|
||||||
/* Adjust NFC filters. */
|
/* Adjust NFC filters. */
|
||||||
for(c = 0;c < num_channels;c++)
|
for(c = 0;c < num_channels;c++)
|
||||||
NfcFilterAdjust(&voice->Direct.Params[c].NFCtrlFilter, w0);
|
voice->Direct.Params[c].NFCtrlFilter.adjust(w0);
|
||||||
|
|
||||||
for(i = 0;i < MAX_AMBI_ORDER+1;i++)
|
for(i = 0;i < MAX_AMBI_ORDER+1;i++)
|
||||||
voice->Direct.ChannelsPerOrder[i] = Device->NumChannelsPerOrder[i];
|
voice->Direct.ChannelsPerOrder[i] = Device->NumChannelsPerOrder[i];
|
||||||
@ -913,7 +913,7 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALfloat Elev
|
|||||||
(Device->AvgSpeakerDist * (ALfloat)Device->Frequency);
|
(Device->AvgSpeakerDist * (ALfloat)Device->Frequency);
|
||||||
|
|
||||||
for(c = 0;c < num_channels;c++)
|
for(c = 0;c < num_channels;c++)
|
||||||
NfcFilterAdjust(&voice->Direct.Params[c].NFCtrlFilter, w0);
|
voice->Direct.Params[c].NFCtrlFilter.adjust(w0);
|
||||||
|
|
||||||
for(i = 0;i < MAX_AMBI_ORDER+1;i++)
|
for(i = 0;i < MAX_AMBI_ORDER+1;i++)
|
||||||
voice->Direct.ChannelsPerOrder[i] = Device->NumChannelsPerOrder[i];
|
voice->Direct.ChannelsPerOrder[i] = Device->NumChannelsPerOrder[i];
|
||||||
|
@ -48,7 +48,9 @@
|
|||||||
* low frequencies.
|
* low frequencies.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const float B[4][3] = {
|
namespace {
|
||||||
|
|
||||||
|
constexpr float B[4][3] = {
|
||||||
{ 0.0f },
|
{ 0.0f },
|
||||||
{ 1.0f },
|
{ 1.0f },
|
||||||
{ 3.0f, 3.0f },
|
{ 3.0f, 3.0f },
|
||||||
@ -56,33 +58,36 @@ static const float B[4][3] = {
|
|||||||
/*{ 4.2076f, 11.4877f, 5.7924f, 9.1401f }*/
|
/*{ 4.2076f, 11.4877f, 5.7924f, 9.1401f }*/
|
||||||
};
|
};
|
||||||
|
|
||||||
static void NfcFilterCreate1(struct NfcFilter1 *nfc, const float w0, const float w1)
|
NfcFilter1 NfcFilterCreate1(const float w0, const float w1) noexcept
|
||||||
{
|
{
|
||||||
|
NfcFilter1 nfc{};
|
||||||
float b_00, g_0;
|
float b_00, g_0;
|
||||||
float r;
|
float r;
|
||||||
|
|
||||||
nfc->base_gain = 1.0f;
|
nfc.base_gain = 1.0f;
|
||||||
nfc->gain = 1.0f;
|
nfc.gain = 1.0f;
|
||||||
|
|
||||||
/* Calculate bass-boost coefficients. */
|
/* Calculate bass-boost coefficients. */
|
||||||
r = 0.5f * w0;
|
r = 0.5f * w0;
|
||||||
b_00 = B[1][0] * r;
|
b_00 = B[1][0] * r;
|
||||||
g_0 = 1.0f + b_00;
|
g_0 = 1.0f + b_00;
|
||||||
|
|
||||||
nfc->gain *= g_0;
|
nfc.gain *= g_0;
|
||||||
nfc->b1 = 2.0f * b_00 / g_0;
|
nfc.b1 = 2.0f * b_00 / g_0;
|
||||||
|
|
||||||
/* Calculate bass-cut coefficients. */
|
/* Calculate bass-cut coefficients. */
|
||||||
r = 0.5f * w1;
|
r = 0.5f * w1;
|
||||||
b_00 = B[1][0] * r;
|
b_00 = B[1][0] * r;
|
||||||
g_0 = 1.0f + b_00;
|
g_0 = 1.0f + b_00;
|
||||||
|
|
||||||
nfc->base_gain /= g_0;
|
nfc.base_gain /= g_0;
|
||||||
nfc->gain /= g_0;
|
nfc.gain /= g_0;
|
||||||
nfc->a1 = 2.0f * b_00 / g_0;
|
nfc.a1 = 2.0f * b_00 / g_0;
|
||||||
|
|
||||||
|
return nfc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NfcFilterAdjust1(struct NfcFilter1 *nfc, const float w0)
|
void NfcFilterAdjust1(NfcFilter1 *nfc, const float w0) noexcept
|
||||||
{
|
{
|
||||||
float b_00, g_0;
|
float b_00, g_0;
|
||||||
float r;
|
float r;
|
||||||
@ -96,13 +101,14 @@ static void NfcFilterAdjust1(struct NfcFilter1 *nfc, const float w0)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void NfcFilterCreate2(struct NfcFilter2 *nfc, const float w0, const float w1)
|
NfcFilter2 NfcFilterCreate2(const float w0, const float w1) noexcept
|
||||||
{
|
{
|
||||||
|
NfcFilter2 nfc{};
|
||||||
float b_10, b_11, g_1;
|
float b_10, b_11, g_1;
|
||||||
float r;
|
float r;
|
||||||
|
|
||||||
nfc->base_gain = 1.0f;
|
nfc.base_gain = 1.0f;
|
||||||
nfc->gain = 1.0f;
|
nfc.gain = 1.0f;
|
||||||
|
|
||||||
/* Calculate bass-boost coefficients. */
|
/* Calculate bass-boost coefficients. */
|
||||||
r = 0.5f * w0;
|
r = 0.5f * w0;
|
||||||
@ -110,9 +116,9 @@ static void NfcFilterCreate2(struct NfcFilter2 *nfc, const float w0, const float
|
|||||||
b_11 = B[2][1] * r * r;
|
b_11 = B[2][1] * r * r;
|
||||||
g_1 = 1.0f + b_10 + b_11;
|
g_1 = 1.0f + b_10 + b_11;
|
||||||
|
|
||||||
nfc->gain *= g_1;
|
nfc.gain *= g_1;
|
||||||
nfc->b1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
|
nfc.b1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
|
||||||
nfc->b2 = 4.0f * b_11 / g_1;
|
nfc.b2 = 4.0f * b_11 / g_1;
|
||||||
|
|
||||||
/* Calculate bass-cut coefficients. */
|
/* Calculate bass-cut coefficients. */
|
||||||
r = 0.5f * w1;
|
r = 0.5f * w1;
|
||||||
@ -120,13 +126,15 @@ static void NfcFilterCreate2(struct NfcFilter2 *nfc, const float w0, const float
|
|||||||
b_11 = B[2][1] * r * r;
|
b_11 = B[2][1] * r * r;
|
||||||
g_1 = 1.0f + b_10 + b_11;
|
g_1 = 1.0f + b_10 + b_11;
|
||||||
|
|
||||||
nfc->base_gain /= g_1;
|
nfc.base_gain /= g_1;
|
||||||
nfc->gain /= g_1;
|
nfc.gain /= g_1;
|
||||||
nfc->a1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
|
nfc.a1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
|
||||||
nfc->a2 = 4.0f * b_11 / g_1;
|
nfc.a2 = 4.0f * b_11 / g_1;
|
||||||
|
|
||||||
|
return nfc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NfcFilterAdjust2(struct NfcFilter2 *nfc, const float w0)
|
void NfcFilterAdjust2(NfcFilter2 *nfc, const float w0) noexcept
|
||||||
{
|
{
|
||||||
float b_10, b_11, g_1;
|
float b_10, b_11, g_1;
|
||||||
float r;
|
float r;
|
||||||
@ -142,14 +150,15 @@ static void NfcFilterAdjust2(struct NfcFilter2 *nfc, const float w0)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void NfcFilterCreate3(struct NfcFilter3 *nfc, const float w0, const float w1)
|
NfcFilter3 NfcFilterCreate3(const float w0, const float w1) noexcept
|
||||||
{
|
{
|
||||||
|
NfcFilter3 nfc{};
|
||||||
float b_10, b_11, g_1;
|
float b_10, b_11, g_1;
|
||||||
float b_00, g_0;
|
float b_00, g_0;
|
||||||
float r;
|
float r;
|
||||||
|
|
||||||
nfc->base_gain = 1.0f;
|
nfc.base_gain = 1.0f;
|
||||||
nfc->gain = 1.0f;
|
nfc.gain = 1.0f;
|
||||||
|
|
||||||
/* Calculate bass-boost coefficients. */
|
/* Calculate bass-boost coefficients. */
|
||||||
r = 0.5f * w0;
|
r = 0.5f * w0;
|
||||||
@ -157,15 +166,15 @@ static void NfcFilterCreate3(struct NfcFilter3 *nfc, const float w0, const float
|
|||||||
b_11 = B[3][1] * r * r;
|
b_11 = B[3][1] * r * r;
|
||||||
g_1 = 1.0f + b_10 + b_11;
|
g_1 = 1.0f + b_10 + b_11;
|
||||||
|
|
||||||
nfc->gain *= g_1;
|
nfc.gain *= g_1;
|
||||||
nfc->b1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
|
nfc.b1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
|
||||||
nfc->b2 = 4.0f * b_11 / g_1;
|
nfc.b2 = 4.0f * b_11 / g_1;
|
||||||
|
|
||||||
b_00 = B[3][2] * r;
|
b_00 = B[3][2] * r;
|
||||||
g_0 = 1.0f + b_00;
|
g_0 = 1.0f + b_00;
|
||||||
|
|
||||||
nfc->gain *= g_0;
|
nfc.gain *= g_0;
|
||||||
nfc->b3 = 2.0f * b_00 / g_0;
|
nfc.b3 = 2.0f * b_00 / g_0;
|
||||||
|
|
||||||
/* Calculate bass-cut coefficients. */
|
/* Calculate bass-cut coefficients. */
|
||||||
r = 0.5f * w1;
|
r = 0.5f * w1;
|
||||||
@ -173,20 +182,22 @@ static void NfcFilterCreate3(struct NfcFilter3 *nfc, const float w0, const float
|
|||||||
b_11 = B[3][1] * r * r;
|
b_11 = B[3][1] * r * r;
|
||||||
g_1 = 1.0f + b_10 + b_11;
|
g_1 = 1.0f + b_10 + b_11;
|
||||||
|
|
||||||
nfc->base_gain /= g_1;
|
nfc.base_gain /= g_1;
|
||||||
nfc->gain /= g_1;
|
nfc.gain /= g_1;
|
||||||
nfc->a1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
|
nfc.a1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
|
||||||
nfc->a2 = 4.0f * b_11 / g_1;
|
nfc.a2 = 4.0f * b_11 / g_1;
|
||||||
|
|
||||||
b_00 = B[3][2] * r;
|
b_00 = B[3][2] * r;
|
||||||
g_0 = 1.0f + b_00;
|
g_0 = 1.0f + b_00;
|
||||||
|
|
||||||
nfc->base_gain /= g_0;
|
nfc.base_gain /= g_0;
|
||||||
nfc->gain /= g_0;
|
nfc.gain /= g_0;
|
||||||
nfc->a3 = 2.0f * b_00 / g_0;
|
nfc.a3 = 2.0f * b_00 / g_0;
|
||||||
|
|
||||||
|
return nfc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NfcFilterAdjust3(struct NfcFilter3 *nfc, const float w0)
|
void NfcFilterAdjust3(NfcFilter3 *nfc, const float w0) noexcept
|
||||||
{
|
{
|
||||||
float b_10, b_11, g_1;
|
float b_10, b_11, g_1;
|
||||||
float b_00, g_0;
|
float b_00, g_0;
|
||||||
@ -208,100 +219,96 @@ static void NfcFilterAdjust3(struct NfcFilter3 *nfc, const float w0)
|
|||||||
nfc->b3 = 2.0f * b_00 / g_0;
|
nfc->b3 = 2.0f * b_00 / g_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void NfcFilterCreate(NfcFilter *nfc, const float w0, const float w1)
|
void NfcFilter::init(const float w0, const float w1) noexcept
|
||||||
{
|
{
|
||||||
memset(nfc, 0, sizeof(*nfc));
|
first = NfcFilterCreate1(w0, w1);
|
||||||
NfcFilterCreate1(&nfc->first, w0, w1);
|
second = NfcFilterCreate2(w0, w1);
|
||||||
NfcFilterCreate2(&nfc->second, w0, w1);
|
third = NfcFilterCreate3(w0, w1);
|
||||||
NfcFilterCreate3(&nfc->third, w0, w1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NfcFilterAdjust(NfcFilter *nfc, const float w0)
|
void NfcFilter::adjust(const float w0) noexcept
|
||||||
{
|
{
|
||||||
NfcFilterAdjust1(&nfc->first, w0);
|
NfcFilterAdjust1(&first, w0);
|
||||||
NfcFilterAdjust2(&nfc->second, w0);
|
NfcFilterAdjust2(&second, w0);
|
||||||
NfcFilterAdjust3(&nfc->third, w0);
|
NfcFilterAdjust3(&third, w0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NfcFilterProcess1(NfcFilter *nfc, float *RESTRICT dst, const float *RESTRICT src, const int count)
|
void NfcFilter::process1(float *RESTRICT dst, const float *RESTRICT src, const int count)
|
||||||
{
|
{
|
||||||
const float gain = nfc->first.gain;
|
|
||||||
const float b1 = nfc->first.b1;
|
|
||||||
const float a1 = nfc->first.a1;
|
|
||||||
float z1 = nfc->first.z[0];
|
|
||||||
|
|
||||||
ASSUME(count > 0);
|
ASSUME(count > 0);
|
||||||
|
|
||||||
auto proc_sample = [gain,b1,a1,&z1](float in) noexcept -> float
|
const float gain{first.gain};
|
||||||
|
const float b1{first.b1};
|
||||||
|
const float a1{first.a1};
|
||||||
|
float z1{first.z[0]};
|
||||||
|
auto proc_sample = [gain,b1,a1,&z1](const float in) noexcept -> float
|
||||||
{
|
{
|
||||||
float y = in*gain - a1*z1;
|
const float y{in*gain - a1*z1};
|
||||||
float out = y + b1*z1;
|
const float out{y + b1*z1};
|
||||||
z1 += y;
|
z1 += y;
|
||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
std::transform<const float*RESTRICT>(src, src+count, dst, proc_sample);
|
std::transform(src, src+count, dst, proc_sample);
|
||||||
nfc->first.z[0] = z1;
|
first.z[0] = z1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NfcFilterProcess2(NfcFilter *nfc, float *RESTRICT dst, const float *RESTRICT src, const int count)
|
void NfcFilter::process2(float *RESTRICT dst, const float *RESTRICT src, const int count)
|
||||||
{
|
{
|
||||||
const float gain = nfc->second.gain;
|
|
||||||
const float b1 = nfc->second.b1;
|
|
||||||
const float b2 = nfc->second.b2;
|
|
||||||
const float a1 = nfc->second.a1;
|
|
||||||
const float a2 = nfc->second.a2;
|
|
||||||
float z1 = nfc->second.z[0];
|
|
||||||
float z2 = nfc->second.z[1];
|
|
||||||
|
|
||||||
ASSUME(count > 0);
|
ASSUME(count > 0);
|
||||||
|
|
||||||
auto proc_sample = [gain,b1,b2,a1,a2,&z1,&z2](float in) noexcept -> float
|
const float gain{second.gain};
|
||||||
|
const float b1{second.b1};
|
||||||
|
const float b2{second.b2};
|
||||||
|
const float a1{second.a1};
|
||||||
|
const float a2{second.a2};
|
||||||
|
float z1{second.z[0]};
|
||||||
|
float z2{second.z[1]};
|
||||||
|
auto proc_sample = [gain,b1,b2,a1,a2,&z1,&z2](const float in) noexcept -> float
|
||||||
{
|
{
|
||||||
float y = in*gain - a1*z1 - a2*z2;
|
const float y{in*gain - a1*z1 - a2*z2};
|
||||||
float out = y + b1*z1 + b2*z2;
|
const float out{y + b1*z1 + b2*z2};
|
||||||
z2 += z1;
|
z2 += z1;
|
||||||
z1 += y;
|
z1 += y;
|
||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
std::transform<const float*RESTRICT>(src, src+count, dst, proc_sample);
|
std::transform(src, src+count, dst, proc_sample);
|
||||||
nfc->second.z[0] = z1;
|
second.z[0] = z1;
|
||||||
nfc->second.z[1] = z2;
|
second.z[1] = z2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NfcFilterProcess3(NfcFilter *nfc, float *RESTRICT dst, const float *RESTRICT src, const int count)
|
void NfcFilter::process3(float *RESTRICT dst, const float *RESTRICT src, const int count)
|
||||||
{
|
{
|
||||||
const float gain = nfc->third.gain;
|
|
||||||
const float b1 = nfc->third.b1;
|
|
||||||
const float b2 = nfc->third.b2;
|
|
||||||
const float b3 = nfc->third.b3;
|
|
||||||
const float a1 = nfc->third.a1;
|
|
||||||
const float a2 = nfc->third.a2;
|
|
||||||
const float a3 = nfc->third.a3;
|
|
||||||
float z1 = nfc->third.z[0];
|
|
||||||
float z2 = nfc->third.z[1];
|
|
||||||
float z3 = nfc->third.z[2];
|
|
||||||
|
|
||||||
ASSUME(count > 0);
|
ASSUME(count > 0);
|
||||||
|
|
||||||
auto proc_sample = [gain,b1,b2,b3,a1,a2,a3,&z1,&z2,&z3](float in) noexcept -> float
|
const float gain{third.gain};
|
||||||
|
const float b1{third.b1};
|
||||||
|
const float b2{third.b2};
|
||||||
|
const float b3{third.b3};
|
||||||
|
const float a1{third.a1};
|
||||||
|
const float a2{third.a2};
|
||||||
|
const float a3{third.a3};
|
||||||
|
float z1{third.z[0]};
|
||||||
|
float z2{third.z[1]};
|
||||||
|
float z3{third.z[2]};
|
||||||
|
auto proc_sample = [gain,b1,b2,b3,a1,a2,a3,&z1,&z2,&z3](const float in) noexcept -> float
|
||||||
{
|
{
|
||||||
float y = in*gain - a1*z1 - a2*z2;
|
float y{in*gain - a1*z1 - a2*z2};
|
||||||
float out = y + b1*z1 + b2*z2;
|
float out{y + b1*z1 + b2*z2};
|
||||||
z2 += z1;
|
z2 += z1;
|
||||||
z1 += y;
|
z1 += y;
|
||||||
|
|
||||||
y = out - a3*z3;
|
y = out - a3*z3;
|
||||||
out = y + b3*z3;
|
out = y + b3*z3;
|
||||||
z3 += y;
|
z3 += y;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
std::transform<const float*RESTRICT>(src, src+count, dst, proc_sample);
|
std::transform(src, src+count, dst, proc_sample);
|
||||||
nfc->third.z[0] = z1;
|
third.z[0] = z1;
|
||||||
nfc->third.z[1] = z2;
|
third.z[1] = z2;
|
||||||
nfc->third.z[2] = z3;
|
third.z[2] = z3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* Original methods the above are derived from. */
|
#if 0 /* Original methods the above are derived from. */
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
#ifndef FILTER_NFC_H
|
#ifndef FILTER_NFC_H
|
||||||
#define FILTER_NFC_H
|
#define FILTER_NFC_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct NfcFilter1 {
|
struct NfcFilter1 {
|
||||||
float base_gain, gain;
|
float base_gain, gain;
|
||||||
float b1, a1;
|
float b1, a1;
|
||||||
@ -21,37 +17,33 @@ struct NfcFilter3 {
|
|||||||
float z[3];
|
float z[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct NfcFilter {
|
class NfcFilter {
|
||||||
struct NfcFilter1 first;
|
NfcFilter1 first;
|
||||||
struct NfcFilter2 second;
|
NfcFilter2 second;
|
||||||
struct NfcFilter3 third;
|
NfcFilter3 third;
|
||||||
} NfcFilter;
|
|
||||||
|
|
||||||
|
public:
|
||||||
/* NOTE:
|
/* NOTE:
|
||||||
* w0 = speed_of_sound / (source_distance * sample_rate);
|
* w0 = speed_of_sound / (source_distance * sample_rate);
|
||||||
* w1 = speed_of_sound / (control_distance * sample_rate);
|
* w1 = speed_of_sound / (control_distance * sample_rate);
|
||||||
*
|
*
|
||||||
* Generally speaking, the control distance should be approximately the average
|
* Generally speaking, the control distance should be approximately the
|
||||||
* speaker distance, or based on the reference delay if outputing NFC-HOA. It
|
* average speaker distance, or based on the reference delay if outputing
|
||||||
* must not be negative, 0, or infinite. The source distance should not be too
|
* NFC-HOA. It must not be negative, 0, or infinite. The source distance
|
||||||
* small relative to the control distance.
|
* should not be too small relative to the control distance.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void NfcFilterCreate(NfcFilter *nfc, const float w0, const float w1);
|
void init(const float w0, const float w1) noexcept;
|
||||||
void NfcFilterAdjust(NfcFilter *nfc, const float w0);
|
void adjust(const float w0) noexcept;
|
||||||
|
|
||||||
/* Near-field control filter for first-order ambisonic channels (1-3). */
|
/* Near-field control filter for first-order ambisonic channels (1-3). */
|
||||||
void NfcFilterProcess1(NfcFilter *nfc, float *RESTRICT dst, const float *RESTRICT src, const int count);
|
void process1(float *RESTRICT dst, const float *RESTRICT src, const int count);
|
||||||
|
|
||||||
/* Near-field control filter for second-order ambisonic channels (4-8). */
|
/* Near-field control filter for second-order ambisonic channels (4-8). */
|
||||||
void NfcFilterProcess2(NfcFilter *nfc, float *RESTRICT dst, const float *RESTRICT src, const int count);
|
void process2(float *RESTRICT dst, const float *RESTRICT src, const int count);
|
||||||
|
|
||||||
/* Near-field control filter for third-order ambisonic channels (9-15). */
|
/* Near-field control filter for third-order ambisonic channels (9-15). */
|
||||||
void NfcFilterProcess3(NfcFilter *nfc, float *RESTRICT dst, const float *RESTRICT src, const int count);
|
void process3(float *RESTRICT dst, const float *RESTRICT src, const int count);
|
||||||
|
};
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* FILTER_NFC_H */
|
#endif /* FILTER_NFC_H */
|
||||||
|
@ -531,21 +531,21 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize
|
|||||||
|
|
||||||
ALfloat *nfcsamples{Device->TempBuffer[NFC_DATA_BUF]};
|
ALfloat *nfcsamples{Device->TempBuffer[NFC_DATA_BUF]};
|
||||||
ALsizei chanoffset{voice->Direct.ChannelsPerOrder[0]};
|
ALsizei chanoffset{voice->Direct.ChannelsPerOrder[0]};
|
||||||
using FilterProc = void(NfcFilter*,ALfloat*,const ALfloat*,ALsizei);
|
using FilterProc = void (NfcFilter::*)(float*,const float*,int);
|
||||||
auto apply_nfc = [voice,parms,samples,DstBufferSize,Counter,OutPos,&chanoffset,nfcsamples](FilterProc &process, ALsizei order) -> void
|
auto apply_nfc = [voice,parms,samples,DstBufferSize,Counter,OutPos,&chanoffset,nfcsamples](FilterProc process, ALsizei order) -> void
|
||||||
{
|
{
|
||||||
if(voice->Direct.ChannelsPerOrder[order] < 1)
|
if(voice->Direct.ChannelsPerOrder[order] < 1)
|
||||||
return;
|
return;
|
||||||
process(&parms->NFCtrlFilter, nfcsamples, samples, DstBufferSize);
|
(parms->NFCtrlFilter.*process)(nfcsamples, samples, DstBufferSize);
|
||||||
MixSamples(nfcsamples, voice->Direct.ChannelsPerOrder[order],
|
MixSamples(nfcsamples, voice->Direct.ChannelsPerOrder[order],
|
||||||
voice->Direct.Buffer+chanoffset, parms->Gains.Current+chanoffset,
|
voice->Direct.Buffer+chanoffset, parms->Gains.Current+chanoffset,
|
||||||
parms->Gains.Target+chanoffset, Counter, OutPos, DstBufferSize
|
parms->Gains.Target+chanoffset, Counter, OutPos, DstBufferSize
|
||||||
);
|
);
|
||||||
chanoffset += voice->Direct.ChannelsPerOrder[order];
|
chanoffset += voice->Direct.ChannelsPerOrder[order];
|
||||||
};
|
};
|
||||||
apply_nfc(NfcFilterProcess1, 1);
|
apply_nfc(&NfcFilter::process1, 1);
|
||||||
apply_nfc(NfcFilterProcess2, 2);
|
apply_nfc(&NfcFilter::process2, 2);
|
||||||
apply_nfc(NfcFilterProcess3, 3);
|
apply_nfc(&NfcFilter::process3, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2840,8 +2840,8 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
|
|||||||
ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
|
ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
|
||||||
(device->AvgSpeakerDist * device->Frequency);
|
(device->AvgSpeakerDist * device->Frequency);
|
||||||
std::for_each(voice->Direct.Params+0, voice->Direct.Params+voice->NumChannels,
|
std::for_each(voice->Direct.Params+0, voice->Direct.Params+voice->NumChannels,
|
||||||
[w1](DirectParams &parms) -> void
|
[w1](DirectParams &parms) noexcept -> void
|
||||||
{ NfcFilterCreate(&parms.NFCtrlFilter, 0.0f, w1); }
|
{ parms.NFCtrlFilter.init(0.0f, w1); }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user