diff options
-rw-r--r-- | Alc/alc.cpp | 3 | ||||
-rw-r--r-- | Alc/alu.cpp | 8 | ||||
-rw-r--r-- | Alc/bformatdec.cpp | 70 | ||||
-rw-r--r-- | Alc/bformatdec.h | 67 | ||||
-rw-r--r-- | Alc/panning.cpp | 29 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 6 |
6 files changed, 74 insertions, 109 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp index 9e4d1ac9..d96f6df0 100644 --- a/Alc/alc.cpp +++ b/Alc/alc.cpp @@ -2424,9 +2424,6 @@ ALCdevice_struct::~ALCdevice_struct() al_free(Bs2b); Bs2b = nullptr; - - bformatdec_free(&AmbiDecoder); - ambiup_free(&AmbiUp); } diff --git a/Alc/alu.cpp b/Alc/alu.cpp index da9d10f2..9372da85 100644 --- a/Alc/alu.cpp +++ b/Alc/alu.cpp @@ -114,7 +114,7 @@ void ProcessHrtf(ALCdevice *device, ALsizei SamplesToDo) ALsizei c; if(device->AmbiUp) - ambiup_process(device->AmbiUp, + ambiup_process(device->AmbiUp.get(), device->Dry.Buffer, device->Dry.NumChannels, device->FOAOut.Buffer, SamplesToDo ); @@ -137,11 +137,11 @@ void ProcessHrtf(ALCdevice *device, ALsizei SamplesToDo) void ProcessAmbiDec(ALCdevice *device, ALsizei SamplesToDo) { if(device->Dry.Buffer != device->FOAOut.Buffer) - bformatdec_upSample(device->AmbiDecoder, + bformatdec_upSample(device->AmbiDecoder.get(), device->Dry.Buffer, device->FOAOut.Buffer, device->FOAOut.NumChannels, SamplesToDo ); - bformatdec_process(device->AmbiDecoder, + bformatdec_process(device->AmbiDecoder.get(), device->RealOut.Buffer, device->RealOut.NumChannels, device->Dry.Buffer, SamplesToDo ); @@ -149,7 +149,7 @@ void ProcessAmbiDec(ALCdevice *device, ALsizei SamplesToDo) void ProcessAmbiUp(ALCdevice *device, ALsizei SamplesToDo) { - ambiup_process(device->AmbiUp, + ambiup_process(device->AmbiUp.get(), device->RealOut.Buffer, device->RealOut.NumChannels, device->FOAOut.Buffer, SamplesToDo ); diff --git a/Alc/bformatdec.cpp b/Alc/bformatdec.cpp index f36cf08b..f82d2d9c 100644 --- a/Alc/bformatdec.cpp +++ b/Alc/bformatdec.cpp @@ -62,7 +62,8 @@ namespace { #define HF_BAND 0 #define LF_BAND 1 -#define NUM_BANDS 2 +static_assert(BFormatDec::NumBands == 2, "Unexpected BFormatDec::NumBands"); +static_assert(AmbiUpsampler::NumBands == 2, "Unexpected AmbiUpsampler::NumBands"); /* These points are in AL coordinates! */ constexpr ALfloat Ambi3DPoints[8][3] = { @@ -107,47 +108,6 @@ ALsizei GetACNIndex(const BFChannelConfig *chans, ALsizei numchans, ALsizei acn) } // namespace -/* NOTE: BandSplitter filters are unused with single-band decoding */ -struct BFormatDec { - ALuint Enabled; /* Bitfield of enabled channels. */ - - union { - alignas(16) ALfloat Dual[MAX_OUTPUT_CHANNELS][NUM_BANDS][MAX_AMBI_COEFFS]; - alignas(16) ALfloat Single[MAX_OUTPUT_CHANNELS][MAX_AMBI_COEFFS]; - } Matrix; - - BandSplitter XOver[MAX_AMBI_COEFFS]; - - al::vector<std::array<ALfloat,BUFFERSIZE>, 16> Samples; - /* These two alias into Samples */ - std::array<ALfloat,BUFFERSIZE> *SamplesHF; - std::array<ALfloat,BUFFERSIZE> *SamplesLF; - - alignas(16) ALfloat ChannelMix[BUFFERSIZE]; - - struct { - BandSplitter XOver; - ALfloat Gains[NUM_BANDS]; - } UpSampler[4]; - - ALsizei NumChannels; - ALboolean DualBand; - - DEF_NEWDEL(BFormatDec) -}; - -BFormatDec *bformatdec_alloc() -{ return new BFormatDec{}; } - -void bformatdec_free(BFormatDec **dec) -{ - if(dec && *dec) - { - delete *dec; - *dec = nullptr; - } -} - void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount, ALuint srate, const ALsizei chanmap[MAX_OUTPUT_CHANNELS]) { static constexpr ALsizei map2DTo3D[MAX_AMBI2D_COEFFS] = { @@ -392,34 +352,12 @@ void bformatdec_upSample(struct BFormatDec *dec, ALfloat (*RESTRICT OutBuffer)[B /* Now write each band to the output. */ MixRowSamples(OutBuffer[i], dec->UpSampler[i].Gains, &reinterpret_cast<ALfloat(&)[BUFFERSIZE]>(dec->Samples[0]), - NUM_BANDS, 0, SamplesToDo + BFormatDec::NumBands, 0, SamplesToDo ); } } -struct AmbiUpsampler { - alignas(16) ALfloat Samples[NUM_BANDS][BUFFERSIZE]; - - BandSplitter XOver[4]; - - ALfloat Gains[4][MAX_OUTPUT_CHANNELS][NUM_BANDS]; - - DEF_NEWDEL(AmbiUpsampler) -}; - -AmbiUpsampler *ambiup_alloc() -{ return new AmbiUpsampler{}; } - -void ambiup_free(struct AmbiUpsampler **ambiup) -{ - if(ambiup) - { - delete *ambiup; - *ambiup = nullptr; - } -} - void ambiup_reset(struct AmbiUpsampler *ambiup, const ALCdevice *device, ALfloat w_scale, ALfloat xyz_scale) { ALfloat ratio; @@ -488,7 +426,7 @@ void ambiup_process(struct AmbiUpsampler *ambiup, ALfloat (*RESTRICT OutBuffer)[ for(j = 0;j < OutChannels;j++) MixRowSamples(OutBuffer[j], ambiup->Gains[i][j], - ambiup->Samples, NUM_BANDS, 0, SamplesToDo + ambiup->Samples, AmbiUpsampler::NumBands, 0, SamplesToDo ); } } diff --git a/Alc/bformatdec.h b/Alc/bformatdec.h index 964a89f9..0d3fe611 100644 --- a/Alc/bformatdec.h +++ b/Alc/bformatdec.h @@ -2,10 +2,12 @@ #define BFORMATDEC_H #include "alMain.h" +#include "filters/splitter.h" +#include "almalloc.h" + + +struct AmbDecConf; -#ifdef __cplusplus -extern "C" { -#endif /* These are the necessary scales for first-order HF responses to play over * higher-order 2D (non-periphonic) decoders. @@ -32,33 +34,62 @@ extern const ALfloat SN3D2N3DScale[MAX_AMBI_COEFFS]; extern const ALfloat FuMa2N3DScale[MAX_AMBI_COEFFS]; -struct AmbDecConf; -struct BFormatDec; -struct AmbiUpsampler; +struct BFormatDec { + static constexpr size_t NumBands{2}; + + ALuint Enabled; /* Bitfield of enabled channels. */ + + union { + alignas(16) ALfloat Dual[MAX_OUTPUT_CHANNELS][NumBands][MAX_AMBI_COEFFS]; + alignas(16) ALfloat Single[MAX_OUTPUT_CHANNELS][MAX_AMBI_COEFFS]; + } Matrix; + + /* NOTE: BandSplitter filters are unused with single-band decoding */ + BandSplitter XOver[MAX_AMBI_COEFFS]; + al::vector<std::array<ALfloat,BUFFERSIZE>, 16> Samples; + /* These two alias into Samples */ + std::array<ALfloat,BUFFERSIZE> *SamplesHF; + std::array<ALfloat,BUFFERSIZE> *SamplesLF; -struct BFormatDec *bformatdec_alloc(); -void bformatdec_free(struct BFormatDec **dec); -void bformatdec_reset(struct BFormatDec *dec, const struct AmbDecConf *conf, ALsizei chancount, ALuint srate, const ALsizei chanmap[MAX_OUTPUT_CHANNELS]); + alignas(16) ALfloat ChannelMix[BUFFERSIZE]; + + struct { + BandSplitter XOver; + ALfloat Gains[NumBands]; + } UpSampler[4]; + + ALsizei NumChannels; + ALboolean DualBand; + + DEF_NEWDEL(BFormatDec) +}; + +void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount, ALuint srate, const ALsizei chanmap[MAX_OUTPUT_CHANNELS]); /* Decodes the ambisonic input to the given output channels. */ -void bformatdec_process(struct BFormatDec *dec, ALfloat (*RESTRICT OutBuffer)[BUFFERSIZE], ALsizei OutChannels, const ALfloat (*RESTRICT InSamples)[BUFFERSIZE], ALsizei SamplesToDo); +void bformatdec_process(BFormatDec *dec, ALfloat (*RESTRICT OutBuffer)[BUFFERSIZE], ALsizei OutChannels, const ALfloat (*RESTRICT InSamples)[BUFFERSIZE], ALsizei SamplesToDo); /* Up-samples a first-order input to the decoder's configuration. */ -void bformatdec_upSample(struct BFormatDec *dec, ALfloat (*RESTRICT OutBuffer)[BUFFERSIZE], const ALfloat (*RESTRICT InSamples)[BUFFERSIZE], ALsizei InChannels, ALsizei SamplesToDo); +void bformatdec_upSample(BFormatDec *dec, ALfloat (*RESTRICT OutBuffer)[BUFFERSIZE], const ALfloat (*RESTRICT InSamples)[BUFFERSIZE], ALsizei InChannels, ALsizei SamplesToDo); /* Stand-alone first-order upsampler. Kept here because it shares some stuff * with bformatdec. Assumes a periphonic (4-channel) input mix! */ -struct AmbiUpsampler *ambiup_alloc(); -void ambiup_free(struct AmbiUpsampler **ambiup); -void ambiup_reset(struct AmbiUpsampler *ambiup, const ALCdevice *device, ALfloat w_scale, ALfloat xyz_scale); +struct AmbiUpsampler { + static constexpr size_t NumBands{2}; + + alignas(16) ALfloat Samples[NumBands][BUFFERSIZE]; + + BandSplitter XOver[4]; + + ALfloat Gains[4][MAX_OUTPUT_CHANNELS][NumBands]; -void ambiup_process(struct AmbiUpsampler *ambiup, ALfloat (*RESTRICT OutBuffer)[BUFFERSIZE], ALsizei OutChannels, const ALfloat (*RESTRICT InSamples)[BUFFERSIZE], ALsizei SamplesToDo); + DEF_NEWDEL(AmbiUpsampler) +}; -#ifdef __cplusplus -} // extern "C" -#endif +void ambiup_reset(AmbiUpsampler *ambiup, const ALCdevice *device, ALfloat w_scale, ALfloat xyz_scale); +void ambiup_process(AmbiUpsampler *ambiup, ALfloat (*RESTRICT OutBuffer)[BUFFERSIZE], ALsizei OutChannels, const ALfloat (*RESTRICT InSamples)[BUFFERSIZE], ALsizei SamplesToDo); #endif /* BFORMATDEC_H */ diff --git a/Alc/panning.cpp b/Alc/panning.cpp index 4ffdf969..e9a410e1 100644 --- a/Alc/panning.cpp +++ b/Alc/panning.cpp @@ -563,7 +563,7 @@ static void InitPanning(ALCdevice *device) w_scale = W_SCALE_2H2P; xyz_scale = XYZ_SCALE_2H2P; } - ambiup_reset(device->AmbiUp, device, w_scale, xyz_scale); + ambiup_reset(device->AmbiUp.get(), device, w_scale, xyz_scale); } if(ConfigValueFloat(devname, "decoder", "nfc-ref-delay", &nfc_delay) && nfc_delay > 0.0f) @@ -725,7 +725,7 @@ static void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALsiz (conf->ChanMask > 0xf) ? (conf->ChanMask > 0x1ff) ? "third" : "second" : "first", (conf->ChanMask&AMBI_PERIPHONIC_MASK) ? " periphonic" : "" ); - bformatdec_reset(device->AmbiDecoder, conf, count, device->Frequency, speakermap); + bformatdec_reset(device->AmbiDecoder.get(), conf, count, device->Frequency, speakermap); if(conf->ChanMask <= 0xf) { @@ -879,7 +879,7 @@ static void InitHrtfPanning(ALCdevice *device) device->FOAOut.CoeffCount = 0; device->FOAOut.NumChannels = 4; - ambiup_reset(device->AmbiUp, device, AmbiOrderHFGainFOA[0] / AmbiOrderHFGain[0], + ambiup_reset(device->AmbiUp.get(), device, AmbiOrderHFGainFOA[0] / AmbiOrderHFGain[0], AmbiOrderHFGainFOA[1] / AmbiOrderHFGain[1]); } else @@ -995,20 +995,17 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf if(pconf && GetConfigValueBool(devname, "decoder", "hq-mode", 0)) { - ambiup_free(&device->AmbiUp); + device->AmbiUp = nullptr; if(!device->AmbiDecoder) - device->AmbiDecoder = bformatdec_alloc(); + device->AmbiDecoder.reset(new BFormatDec{}); } else { - bformatdec_free(&device->AmbiDecoder); + device->AmbiDecoder = nullptr; if(device->FmtChans != DevFmtAmbi3D || device->mAmbiOrder < 2) - ambiup_free(&device->AmbiUp); - else - { - if(!device->AmbiUp) - device->AmbiUp = ambiup_alloc(); - } + device->AmbiUp = nullptr; + else if(!device->AmbiUp) + device->AmbiUp.reset(new AmbiUpsampler{}); } if(!pconf) @@ -1058,7 +1055,7 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf return; } - bformatdec_free(&device->AmbiDecoder); + device->AmbiDecoder = nullptr; headphones = device->IsHeadphones; if(device->Type != Loopback) @@ -1147,12 +1144,12 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf /* Don't bother with HOA when using full HRTF rendering. Nothing * needs it, and it eases the CPU/memory load. */ - ambiup_free(&device->AmbiUp); + device->AmbiUp = nullptr; } else { if(!device->AmbiUp) - device->AmbiUp = ambiup_alloc(); + device->AmbiUp.reset(new AmbiUpsampler{}); } TRACE("%s HRTF rendering enabled, using \"%s\"\n", @@ -1171,7 +1168,7 @@ no_hrtf: device->Render_Mode = StereoPair; - ambiup_free(&device->AmbiUp); + device->AmbiUp = nullptr; bs2blevel = ((headphones && hrtf_appreq != Hrtf_Disable) || (hrtf_appreq == Hrtf_Enable)) ? 5 : 0; diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index c57d87ba..de602d35 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -208,6 +208,8 @@ struct ALeffect; struct ALfilter; struct EffectState; struct Uhj2Encoder; +struct BFormatDec; +struct AmbiUpsampler; #define DEFAULT_OUTPUT_RATE (44100) @@ -673,13 +675,13 @@ struct ALCdevice_struct { std::unique_ptr<Uhj2Encoder> Uhj_Encoder; /* High quality Ambisonic decoder */ - struct BFormatDec *AmbiDecoder{nullptr}; + std::unique_ptr<BFormatDec> AmbiDecoder; /* Stereo-to-binaural filter */ struct bs2b *Bs2b{nullptr}; /* First-order ambisonic upsampler for higher-order output */ - struct AmbiUpsampler *AmbiUp{nullptr}; + std::unique_ptr<AmbiUpsampler> AmbiUp; /* Rendering mode. */ RenderMode Render_Mode{NormalRender}; |