88 void configure(
float sampleRate,
float cutoffFrequency = 380)
90 double k = tan(
M_PI*cutoffFrequency/sampleRate);
91 a1 =
float(2.*(k*k - 1.)/(k*k + 2*k + 1.));
92 a2 =
float((k*k - 2*k + 1.)/(k*k + 2*k + 1.));
94 b0_lf =
float(k*k/(k*k + 2*k + 1));
97 b0_hf =
float(1./(k*k + 2*k + 1));
109 float r_lf = x*b0_lf +
114 float r_hf = x*b0_hf +
121 prevR_lf[1] = prevR_lf[0];
123 prevR_hf[1] = prevR_hf[0];
125 return { r_lf, r_hf };
139 float prevR_lf[2] = {};
140 float prevR_hf[2] = {};
145 : level(ambisonicLevel)
147 Q_ASSERT(level > 0 && level <= 3);
148 inputChannels = (level+1)*(level+1);
153 channelConfig = format.defaultChannelConfigForChannelCount(format
.channelCount());
169 simpleDecoderFactors =
new float[4*outputChannels];
170 float *r =
new float[2*outputChannels];
171 float *f = simpleDecoderFactors;
174 f[0] = 0.5f; f[1] = 0.5f; f[2] = 0.; f[3] = 0.f;
176 r[0] = 1.; r[1] = 0.;
180 f[0] = 0.5f; f[1] = -0.5f; f[2] = 0.; f[3] = 0.f;
182 r[0] = 0.; r[1] = 1.;
186 f[0] = 0.5f; f[1] = -0.f; f[2] = 0.; f[3] = 0.5f;
188 r[0] = .5; r[1] = .5;
192 f[0] = 0.5f; f[1] = -0.f; f[2] = 0.; f[3] = 0.0f;
194 r[0] = 0.; r[1] = 0.;
199 Q_ASSERT((f - simpleDecoderFactors) == 4*outputChannels);
200 Q_ASSERT((r - reverbFactors) == 2*outputChannels);
206 if (d
.config == channelConfig) {
208 reverbFactors = decoderData->reverb;
219 for (
int i = 0; i < inputChannels; ++i)
225 if (simpleDecoderFactors) {
226 delete[] simpleDecoderFactors;
227 delete[] reverbFactors;
234 memset(o, 0, nSamples*outputChannels*
sizeof(
float));
236 if (simpleDecoderFactors) {
237 for (
int i = 0; i < nSamples; ++i) {
238 for (
int j = 0; j < 4; ++j) {
239 for (
int k = 0; k < outputChannels; ++k)
240 o[k] += simpleDecoderFactors[k*4 + j]*input[j][i];
247 const float *matrix_hi = decoderData->hf[level - 1];
248 const float *matrix_lo = decoderData->lf[level - 1];
249 for (
int i = 0; i < nSamples; ++i) {
251 for (
int j = 0; j < inputChannels; ++j)
252 buf[j] = filters[j]
.next(input[j][i]
);
253 for (
int j = 0; j < inputChannels; ++j) {
254 for (
int k = 0; k < outputChannels; ++k)
255 o[k] += matrix_lo[k*inputChannels + j]*buf[j]
.lf + matrix_hi[k*inputChannels + j]*buf[j]
.hf;
263 const float *reverb[] = {
nullptr,
nullptr };
269 if (simpleDecoderFactors) {
270 for (
int i = 0; i < nSamples; ++i) {
272 for (
int k = 0; k < outputChannels; ++k) {
273 for (
int j = 0; j < 4; ++j)
274 o[k] += simpleDecoderFactors[k*4 + j]*input[j][i];
277 for (
int k = 0; k < outputChannels; ++k) {
278 o[k] += reverb[0][i]*reverbFactors[2*k] + reverb[1][i]*reverbFactors[2*k+1];
282 for (
int k = 0; k < outputChannels; ++k)
283 output[k] =
static_cast<
short>(o[k]*32768.);
284 output += outputChannels;
290 const float *matrix_hi = decoderData->hf[level - 1];
291 const float *matrix_lo = decoderData->lf[level - 1];
292 for (
int i = 0; i < nSamples; ++i) {
294 for (
int j = 0; j < inputChannels; ++j)
295 buf[j] = filters[j]
.next(input[j][i]
);
297 for (
int j = 0; j < inputChannels; ++j) {
298 for (
int k = 0; k < outputChannels; ++k)
299 o[k] += matrix_lo[k*inputChannels + j]*buf[j]
.lf + matrix_hi[k*inputChannels + j]*buf[j]
.hf;
302 for (
int k = 0; k < outputChannels; ++k) {
303 o[k] += reverb[0][i]*reverbFactors[2*k] + reverb[1][i]*reverbFactors[2*k+1];
306 for (
int k = 0; k < outputChannels; ++k)
307 output[k] =
static_cast<
short>(o[k]*32768.);
308 output += outputChannels;
QAmbisonicDecoderFilter()=default
void configure(float sampleRate, float cutoffFrequency=380)
static constexpr int maxAmbisonicChannels
void processBuffer(const float *input[], float *output, int nSamples)
void processBuffer(const float *input[], short *output, int nSamples)
void processBufferWithReverb(const float *input[], const float *reverb[2], short *output, int nSamples)
QAmbisonicDecoder(AmbisonicLevel ambisonicLevel, const QAudioFormat &format)
Combined button and popup list for selecting options.
static const QAmbisonicDecoderData decoderMap[]
static constexpr float decoderMatrix_5dot0_2_hf[5 *9]
static constexpr float decoderMatrix_5dot1_2_lf[6 *9]
static constexpr float decoderMatrix_5dot0_1_hf[5 *4]
static constexpr float decoderMatrix_5dot0_3_hf[5 *16]
static constexpr float decoderMatrix_5dot1_1_hf[6 *4]
static constexpr float decoderMatrix_7dot1_3_hf[8 *16]
static constexpr float decoderMatrix_5dot1_2_hf[6 *9]
static constexpr float decoderMatrix_7dot1_2_hf[8 *9]
static constexpr float decoderMatrix_7dot1_2_lf[8 *9]
static constexpr float decoderMatrix_5dot1_3_lf[6 *16]
static constexpr float decoderMatrix_7dot1_3_lf[8 *16]
static QT_BEGIN_NAMESPACE constexpr float decoderMatrix_5dot0_1_lf[5 *4]
static constexpr float decoderMatrix_5dot0_2_lf[5 *9]
static constexpr float decoderMatrix_5dot1_3_hf[6 *16]
static constexpr float decoderMatrix_7dot0_2_lf[7 *9]
static constexpr float decoderMatrix_7dot0_3_lf[7 *16]
static constexpr float decoderMatrix_7dot1_1_hf[8 *4]
static constexpr float decoderMatrix_7dot0_1_lf[7 *4]
static constexpr float decoderMatrix_7dot0_1_hf[7 *4]
static constexpr float decoderMatrix_5dot1_1_lf[6 *4]
static constexpr float decoderMatrix_7dot1_1_lf[8 *4]
static constexpr float decoderMatrix_5dot0_3_lf[5 *16]
static constexpr float decoderMatrix_7dot0_2_hf[7 *9]
static constexpr float decoderMatrix_7dot0_3_hf[7 *16]
QAudioFormat::ChannelConfig config