| 49 | |
| 50 | |
| 51 | BFormatDec::BFormatDec(const AmbDecConf *conf, const bool allow_2band, const ALuint inchans, |
| 52 | const ALuint srate, const ALuint (&chanmap)[MAX_OUTPUT_CHANNELS]) |
| 53 | { |
| 54 | mDualBand = allow_2band && (conf->FreqBands == 2); |
| 55 | if(!mDualBand) |
| 56 | mSamples.resize(2); |
| 57 | else |
| 58 | { |
| 59 | ASSUME(inchans > 0); |
| 60 | mSamples.resize(inchans * 2); |
| 61 | mSamplesHF = mSamples.data(); |
| 62 | mSamplesLF = mSamplesHF + inchans; |
| 63 | } |
| 64 | mNumChannels = inchans; |
| 65 | |
| 66 | mEnabled = std::accumulate(std::begin(chanmap), std::begin(chanmap)+conf->Speakers.size(), 0u, |
| 67 | [](ALuint mask, const ALuint &chan) noexcept -> ALuint |
| 68 | { return mask | (1 << chan); } |
| 69 | ); |
| 70 | |
| 71 | const ALfloat xover_norm{conf->XOverFreq / static_cast<float>(srate)}; |
| 72 | |
| 73 | const bool periphonic{(conf->ChanMask&AMBI_PERIPHONIC_MASK) != 0}; |
| 74 | const std::array<float,MAX_AMBI_CHANNELS> &coeff_scale = GetAmbiScales(conf->CoeffScale); |
| 75 | const size_t coeff_count{periphonic ? MAX_AMBI_CHANNELS : MAX_AMBI2D_CHANNELS}; |
| 76 | |
| 77 | if(!mDualBand) |
| 78 | { |
| 79 | for(size_t i{0u};i < conf->Speakers.size();i++) |
| 80 | { |
| 81 | ALfloat (&mtx)[MAX_AMBI_CHANNELS] = mMatrix.Single[chanmap[i]]; |
| 82 | for(size_t j{0},k{0};j < coeff_count;j++) |
| 83 | { |
| 84 | const size_t l{periphonic ? j : AmbiIndex::From2D[j]}; |
| 85 | if(!(conf->ChanMask&(1u<<l))) continue; |
| 86 | mtx[j] = conf->HFMatrix[i][k] / coeff_scale[l] * |
| 87 | ((l>=9) ? conf->HFOrderGain[3] : |
| 88 | (l>=4) ? conf->HFOrderGain[2] : |
| 89 | (l>=1) ? conf->HFOrderGain[1] : conf->HFOrderGain[0]); |
| 90 | ++k; |
| 91 | } |
| 92 | } |
| 93 | } |
| 94 | else |
| 95 | { |
| 96 | mXOver[0].init(xover_norm); |
| 97 | std::fill(std::begin(mXOver)+1, std::end(mXOver), mXOver[0]); |
| 98 | |
| 99 | const float ratio{std::pow(10.0f, conf->XOverRatio / 40.0f)}; |
| 100 | for(size_t i{0u};i < conf->Speakers.size();i++) |
| 101 | { |
| 102 | ALfloat (&mtx)[sNumBands][MAX_AMBI_CHANNELS] = mMatrix.Dual[chanmap[i]]; |
| 103 | for(size_t j{0},k{0};j < coeff_count;j++) |
| 104 | { |
| 105 | const size_t l{periphonic ? j : AmbiIndex::From2D[j]}; |
| 106 | if(!(conf->ChanMask&(1u<<l))) continue; |
| 107 | mtx[sHFBand][j] = conf->HFMatrix[i][k] / coeff_scale[l] * |
| 108 | ((l>=9) ? conf->HFOrderGain[3] : |