diff options
author | Chris Robinson <[email protected]> | 2018-12-15 02:42:04 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2018-12-15 02:56:19 -0800 |
commit | 0dd13a9dfed47660946fa9d37a1fc35e44b73687 (patch) | |
tree | d2a0644a466ee0c3def10c8af725451ce6e902c7 | |
parent | 640c06c292632f2ac78d349b0ad3b8b5f000c61a (diff) |
Make the AmbDec speaker and matrix arrays dynamic
-rw-r--r-- | Alc/ambdec.cpp | 86 | ||||
-rw-r--r-- | Alc/ambdec.h | 31 | ||||
-rw-r--r-- | Alc/bformatdec.cpp | 6 | ||||
-rw-r--r-- | Alc/panning.cpp | 23 |
4 files changed, 76 insertions, 70 deletions
diff --git a/Alc/ambdec.cpp b/Alc/ambdec.cpp index 66fc2255..8b251187 100644 --- a/Alc/ambdec.cpp +++ b/Alc/ambdec.cpp @@ -3,8 +3,9 @@ #include "ambdec.h" -#include <cstring> #include <cctype> +#include <cstring> +#include <algorithm> #include <limits> #include <string> @@ -61,10 +62,9 @@ bool is_at_end(const std::string &buffer, std::size_t endpos) } -bool load_ambdec_speakers(AmbDecConf *conf, std::istream &f, std::string &buffer) +bool load_ambdec_speakers(al::vector<AmbDecConf::SpeakerConf> &spkrs, const std::size_t num_speakers, std::istream &f, std::string &buffer) { - ALsizei cur = 0; - while(cur < conf->NumSpeakers) + while(spkrs.size() < num_speakers) { std::istringstream istr{buffer}; @@ -81,18 +81,20 @@ bool load_ambdec_speakers(AmbDecConf *conf, std::istream &f, std::string &buffer if(cmd == "add_spkr") { - istr >> conf->Speakers[cur].Name; - if(istr.fail()) WARN("Name not specified for speaker %u\n", cur+1); - istr >> conf->Speakers[cur].Distance; - if(istr.fail()) WARN("Distance not specified for speaker %u\n", cur+1); - istr >> conf->Speakers[cur].Azimuth; - if(istr.fail()) WARN("Azimuth not specified for speaker %u\n", cur+1); - istr >> conf->Speakers[cur].Elevation; - if(istr.fail()) WARN("Elevation not specified for speaker %u\n", cur+1); - istr >> conf->Speakers[cur].Connection; - if(istr.fail()) TRACE("Connection not specified for speaker %u\n", cur+1); - - cur++; + spkrs.emplace_back(); + AmbDecConf::SpeakerConf &spkr = spkrs.back(); + const size_t spkr_num{spkrs.size()}; + + istr >> spkr.Name; + if(istr.fail()) WARN("Name not specified for speaker " SZFMT "\n", spkr_num); + istr >> spkr.Distance; + if(istr.fail()) WARN("Distance not specified for speaker " SZFMT "\n", spkr_num); + istr >> spkr.Azimuth; + if(istr.fail()) WARN("Azimuth not specified for speaker " SZFMT "\n", spkr_num); + istr >> spkr.Elevation; + if(istr.fail()) WARN("Elevation not specified for speaker " SZFMT "\n", spkr_num); + istr >> spkr.Connection; + if(istr.fail()) TRACE("Connection not specified for speaker " SZFMT "\n", spkr_num); } else { @@ -113,10 +115,10 @@ bool load_ambdec_speakers(AmbDecConf *conf, std::istream &f, std::string &buffer return true; } -bool load_ambdec_matrix(ALfloat *gains, ALfloat (*matrix)[MAX_AMBI_COEFFS], ALsizei maxrow, std::istream &f, std::string &buffer) +bool load_ambdec_matrix(float (&gains)[MAX_AMBI_ORDER+1], al::vector<AmbDecConf::CoeffArray> &matrix, const std::size_t maxrow, std::istream &f, std::string &buffer) { - bool gotgains = false; - ALsizei cur = 0; + bool gotgains{false}; + std::size_t cur{0u}; while(cur < maxrow) { std::istringstream istr{buffer}; @@ -134,7 +136,7 @@ bool load_ambdec_matrix(ALfloat *gains, ALfloat (*matrix)[MAX_AMBI_COEFFS], ALsi if(cmd == "order_gain") { - ALuint curgain = 0; + std::size_t curgain{0u}; float value; while(istr.good()) { @@ -142,36 +144,37 @@ bool load_ambdec_matrix(ALfloat *gains, ALfloat (*matrix)[MAX_AMBI_COEFFS], ALsi if(istr.fail()) break; if(!istr.eof() && !std::isspace(istr.peek())) { - ERR("Extra junk on gain %u: %s\n", curgain+1, + ERR("Extra junk on gain " SZFMT ": %s\n", curgain+1, buffer.c_str()+static_cast<std::size_t>(istr.tellg())); return false; } - if(curgain < MAX_AMBI_ORDER+1) + if(curgain < countof(gains)) gains[curgain++] = value; } - while(curgain < MAX_AMBI_ORDER+1) - gains[curgain++] = 0.0f; + std::fill(std::begin(gains)+curgain, std::end(gains), 0.0f); gotgains = true; } else if(cmd == "add_row") { - ALuint curidx = 0; - float value; + matrix.emplace_back(); + AmbDecConf::CoeffArray &mtxrow = matrix.back(); + std::size_t curidx{0u}; + float value{}; while(istr.good()) { istr >> value; if(istr.fail()) break; if(!istr.eof() && !std::isspace(istr.peek())) { - ERR("Extra junk on matrix element %ux%u: %s\n", cur, curidx, - buffer.c_str()+static_cast<std::size_t>(istr.tellg())); + ERR("Extra junk on matrix element " SZFMT "x" SZFMT ": %s\n", curidx, + matrix.size(), buffer.c_str()+static_cast<std::size_t>(istr.tellg())); + matrix.pop_back(); return false; } - if(curidx < MAX_AMBI_COEFFS) - matrix[cur][curidx++] = value; + if(curidx < mtxrow.size()) + mtxrow[curidx++] = value; } - while(curidx < MAX_AMBI_COEFFS) - matrix[cur][curidx++] = 0.0f; + std::fill(mtxrow.begin()+curidx, mtxrow.end(), 0.0f); cur++; } else @@ -210,6 +213,7 @@ int AmbDecConf::load(const char *fname) noexcept return 0; } + std::size_t num_speakers{0u}; std::string buffer; while(read_clipped_line(f, buffer)) { @@ -266,18 +270,16 @@ int AmbDecConf::load(const char *fname) noexcept } else if(command == "/dec/speakers") { - istr >> NumSpeakers; + istr >> num_speakers; if(!istr.eof() && !std::isspace(istr.peek())) { ERR("Extra junk after speakers: %s\n", buffer.c_str()+static_cast<std::size_t>(istr.tellg())); return 0; } - if(NumSpeakers > MAX_OUTPUT_CHANNELS) - { - ERR("Unsupported speaker count: %u\n", NumSpeakers); - return 0; - } + Speakers.reserve(num_speakers); + LFMatrix.reserve(num_speakers); + HFMatrix.reserve(num_speakers); } else if(command == "/dec/coeff_scale") { @@ -327,7 +329,7 @@ int AmbDecConf::load(const char *fname) noexcept } buffer.clear(); - if(!load_ambdec_speakers(this, f, buffer)) + if(!load_ambdec_speakers(Speakers, num_speakers, f, buffer)) return 0; if(!read_clipped_line(f, buffer)) @@ -361,19 +363,19 @@ int AmbDecConf::load(const char *fname) noexcept ERR("Unexpected \"%s\" type for a single-band decoder\n", command.c_str()); return 0; } - if(!load_ambdec_matrix(HFOrderGain, HFMatrix, NumSpeakers, f, buffer)) + if(!load_ambdec_matrix(HFOrderGain, HFMatrix, num_speakers, f, buffer)) return 0; } else { if(command == "/lfmatrix/{") { - if(!load_ambdec_matrix(LFOrderGain, LFMatrix, NumSpeakers, f, buffer)) + if(!load_ambdec_matrix(LFOrderGain, LFMatrix, num_speakers, f, buffer)) return 0; } else if(command == "/hfmatrix/{") { - if(!load_ambdec_matrix(HFOrderGain, HFMatrix, NumSpeakers, f, buffer)) + if(!load_ambdec_matrix(HFOrderGain, HFMatrix, num_speakers, f, buffer)) return 0; } else diff --git a/Alc/ambdec.h b/Alc/ambdec.h index 99caf9a2..5ec5eb0c 100644 --- a/Alc/ambdec.h +++ b/Alc/ambdec.h @@ -1,9 +1,11 @@ #ifndef AMBDEC_H #define AMBDEC_H +#include <array> #include <string> #include "alMain.h" +#include "vector.h" /* Helpers to read .ambdec configuration files. */ @@ -14,30 +16,31 @@ enum class AmbDecScale { }; struct AmbDecConf { std::string Description; - ALuint Version; /* Must be 3 */ + int Version; /* Must be 3 */ - ALuint ChanMask; - ALuint FreqBands; /* Must be 1 or 2 */ - ALsizei NumSpeakers; + unsigned int ChanMask; + unsigned int FreqBands; /* Must be 1 or 2 */ AmbDecScale CoeffScale; - ALfloat XOverFreq; - ALfloat XOverRatio; + float XOverFreq; + float XOverRatio; struct SpeakerConf { std::string Name; - ALfloat Distance; - ALfloat Azimuth; - ALfloat Elevation; + float Distance{0.0f}; + float Azimuth{0.0f}; + float Elevation{0.0f}; std::string Connection; - } Speakers[MAX_OUTPUT_CHANNELS]; + }; + al::vector<SpeakerConf> Speakers; + using CoeffArray = std::array<float,MAX_AMBI_COEFFS>; /* Unused when FreqBands == 1 */ - ALfloat LFOrderGain[MAX_AMBI_ORDER+1]; - ALfloat LFMatrix[MAX_OUTPUT_CHANNELS][MAX_AMBI_COEFFS]; + float LFOrderGain[MAX_AMBI_ORDER+1]; + al::vector<CoeffArray> LFMatrix; - ALfloat HFOrderGain[MAX_AMBI_ORDER+1]; - ALfloat HFMatrix[MAX_OUTPUT_CHANNELS][MAX_AMBI_COEFFS]; + float HFOrderGain[MAX_AMBI_ORDER+1]; + al::vector<CoeffArray> HFMatrix; int load(const char *fname) noexcept; }; diff --git a/Alc/bformatdec.cpp b/Alc/bformatdec.cpp index 882184a3..d92c84db 100644 --- a/Alc/bformatdec.cpp +++ b/Alc/bformatdec.cpp @@ -91,7 +91,7 @@ void BFormatDec::reset(const AmbDecConf *conf, ALsizei chancount, ALuint srate, mSamplesHF = mSamples.data(); mSamplesLF = mSamplesHF + chancount; - mEnabled = std::accumulate(std::begin(chanmap), std::begin(chanmap)+conf->NumSpeakers, 0u, + mEnabled = std::accumulate(std::begin(chanmap), std::begin(chanmap)+conf->Speakers.size(), 0u, [](ALuint mask, const ALsizei &chan) noexcept -> ALuint { return mask | (1 << chan); } ); @@ -139,7 +139,7 @@ void BFormatDec::reset(const AmbDecConf *conf, ALsizei chancount, ALuint srate, mDualBand = (conf->FreqBands == 2); if(!mDualBand) { - for(ALsizei i{0};i < conf->NumSpeakers;i++) + for(size_t i{0u};i < conf->Speakers.size();i++) { ALfloat (&mtx)[MAX_AMBI_COEFFS] = mMatrix.Single[chanmap[i]]; for(ALsizei j{0},k{0};j < coeff_count;j++) @@ -160,7 +160,7 @@ void BFormatDec::reset(const AmbDecConf *conf, ALsizei chancount, ALuint srate, std::fill(std::begin(mXOver)+1, std::end(mXOver), mXOver[0]); const float ratio{std::pow(10.0f, conf->XOverRatio / 40.0f)}; - for(ALsizei i{0};i < conf->NumSpeakers;i++) + for(size_t i{0u};i < conf->Speakers.size();i++) { ALfloat (&mtx)[sNumBands][MAX_AMBI_COEFFS] = mMatrix.Dual[chanmap[i]]; for(ALsizei j{0},k{0};j < coeff_count;j++) diff --git a/Alc/panning.cpp b/Alc/panning.cpp index e854a966..bf0c1931 100644 --- a/Alc/panning.cpp +++ b/Alc/panning.cpp @@ -119,7 +119,7 @@ struct ChannelMap { }; void SetChannelMap(const Channel (&devchans)[MAX_OUTPUT_CHANNELS], ChannelConfig *ambicoeffs, - const ChannelMap *chanmap, ALsizei count, ALsizei *outcount) + const ChannelMap *chanmap, const size_t count, ALsizei *outcount) { auto copy_coeffs = [&devchans,ambicoeffs](ALsizei maxchans, const ChannelMap &channel) -> ALsizei { @@ -217,10 +217,9 @@ bool MakeSpeakerMap(ALCdevice *device, const AmbDecConf *conf, ALsizei (&speaker ERR("Failed to lookup AmbDec speaker label %s\n", speaker.Name.c_str()); return chidx; }; - auto speakers_end = std::begin(conf->Speakers) + conf->NumSpeakers; - std::transform(std::begin(conf->Speakers), speakers_end, std::begin(speakermap), map_spkr); + std::transform(conf->Speakers.begin(), conf->Speakers.end(), std::begin(speakermap), map_spkr); /* Return success if no invalid entries are found. */ - auto speakermap_end = std::begin(speakermap) + conf->NumSpeakers; + auto speakermap_end = std::begin(speakermap) + conf->Speakers.size(); return std::find(std::begin(speakermap), speakermap_end, -1) == speakermap_end; } @@ -281,9 +280,8 @@ void InitDistanceComp(ALCdevice *device, const AmbDecConf *conf, const ALsizei ( { using namespace std::placeholders; - auto speakers_end = std::begin(conf->Speakers) + conf->NumSpeakers; const ALfloat maxdist{ - std::accumulate(std::begin(conf->Speakers), speakers_end, float{0.0f}, + std::accumulate(conf->Speakers.begin(), conf->Speakers.end(), float{0.0f}, std::bind(maxf, _1, std::bind(std::mem_fn(&AmbDecConf::SpeakerConf::Distance), _2)) ) }; @@ -294,7 +292,7 @@ void InitDistanceComp(ALCdevice *device, const AmbDecConf *conf, const ALsizei ( auto srate = static_cast<ALfloat>(device->Frequency); size_t total{0u}; - for(ALsizei i{0};i < conf->NumSpeakers;i++) + for(size_t i{0u};i < conf->Speakers.size();i++) { const AmbDecConf::SpeakerConf &speaker = conf->Speakers[i]; const ALsizei chan{speakermap[i]}; @@ -536,7 +534,7 @@ void InitCustomPanning(ALCdevice *device, const AmbDecConf *conf, const ALsizei const ALfloat (&coeff_scale)[MAX_AMBI_COEFFS] = GetAmbiScales(conf->CoeffScale); ChannelMap chanmap[MAX_OUTPUT_CHANNELS]{}; - for(ALsizei i{0};i < conf->NumSpeakers;i++) + for(size_t i{0u};i < conf->Speakers.size();i++) { chanmap[i].ChanName = device->RealOut.ChannelName[speakermap[i]]; std::fill(std::begin(chanmap[i].Config), std::end(chanmap[i].Config), 0.0f); @@ -553,7 +551,7 @@ void InitCustomPanning(ALCdevice *device, const AmbDecConf *conf, const ALsizei } SetChannelMap(device->RealOut.ChannelName, device->Dry.Ambi.Coeffs, chanmap, - conf->NumSpeakers, &device->Dry.NumChannels); + conf->Speakers.size(), &device->Dry.NumChannels); device->Dry.CoeffCount = (conf->ChanMask > AMBI_2ORDER_MASK) ? 16 : (conf->ChanMask > AMBI_1ORDER_MASK) ? 9 : 4; @@ -643,8 +641,8 @@ void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALsizei (&sp std::plus<float>{}, _1, std::bind(std::mem_fn(&AmbDecConf::SpeakerConf::Distance), _2) ); const ALfloat avg_dist{ - std::accumulate(std::begin(conf->Speakers), std::begin(conf->Speakers)+conf->NumSpeakers, - float{0.0f}, accum_spkr_dist) / (ALfloat)conf->NumSpeakers + std::accumulate(conf->Speakers.begin(), conf->Speakers.end(), float{0.0f}, + accum_spkr_dist) / static_cast<ALfloat>(conf->Speakers.size()) }; InitNearFieldCtrl(device, avg_dist, (conf->ChanMask > AMBI_2ORDER_MASK) ? 3 : @@ -964,6 +962,9 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, HrtfRequestMode hrtf_appr { if(!conf.load(fname)) ERR("Failed to load layout file %s\n", fname); + else if(conf.Speakers.size() > MAX_OUTPUT_CHANNELS) + ERR("Unsupported speaker count " SZFMT " (max %d)\n", conf.Speakers.size(), + MAX_OUTPUT_CHANNELS); else if(conf.ChanMask > AMBI_3ORDER_MASK) ERR("Unsupported channel mask 0x%04x (max 0x%x)\n", conf.ChanMask, AMBI_3ORDER_MASK); |