aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-12-15 02:42:04 -0800
committerChris Robinson <[email protected]>2018-12-15 02:56:19 -0800
commit0dd13a9dfed47660946fa9d37a1fc35e44b73687 (patch)
treed2a0644a466ee0c3def10c8af725451ce6e902c7
parent640c06c292632f2ac78d349b0ad3b8b5f000c61a (diff)
Make the AmbDec speaker and matrix arrays dynamic
-rw-r--r--Alc/ambdec.cpp86
-rw-r--r--Alc/ambdec.h31
-rw-r--r--Alc/bformatdec.cpp6
-rw-r--r--Alc/panning.cpp23
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);