2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2010 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
36 #define ZERO_ORDER_SCALE 0.0f
37 #define FIRST_ORDER_SCALE 1.0f
38 #define SECOND_ORDER_SCALE (1.0f / 1.22474f)
39 #define THIRD_ORDER_SCALE (1.0f / 1.30657f)
42 static const ALuint FuMa2ACN
[MAX_AMBI_COEFFS
] = {
61 /* NOTE: These are scale factors as applied to Ambisonics content. FuMa
62 * decoder coefficients should be divided by these values to get N3D decoder
65 static const ALfloat FuMa2N3DScale
[MAX_AMBI_COEFFS
] = {
66 1.4142f
, /* ACN 0 (W), sqrt(2) */
67 1.7321f
, /* ACN 1 (Y), sqrt(3) */
68 1.7321f
, /* ACN 2 (Z), sqrt(3) */
69 1.7321f
, /* ACN 3 (X), sqrt(3) */
70 1.9365f
, /* ACN 4 (V), sqrt(15)/2 */
71 1.9365f
, /* ACN 5 (T), sqrt(15)/2 */
72 2.2361f
, /* ACN 6 (R), sqrt(5) */
73 1.9365f
, /* ACN 7 (S), sqrt(15)/2 */
74 1.9365f
, /* ACN 8 (U), sqrt(15)/2 */
75 2.0917f
, /* ACN 9 (Q), sqrt(35/8) */
76 1.9720f
, /* ACN 10 (O), sqrt(35)/3 */
77 2.2311f
, /* ACN 11 (M), sqrt(224/45) */
78 2.6458f
, /* ACN 12 (K), sqrt(7) */
79 2.2311f
, /* ACN 13 (L), sqrt(224/45) */
80 1.9720f
, /* ACN 14 (N), sqrt(35)/3 */
81 2.0917f
, /* ACN 15 (P), sqrt(35/8) */
85 void ComputeAmbientGains(const ALCdevice
*device
, ALfloat ingain
, ALfloat gains
[MAX_OUTPUT_CHANNELS
])
89 for(i
= 0;i
< device
->NumChannels
;i
++)
91 // The W coefficients are based on a mathematical average of the
92 // output. The square root of the base average provides for a more
93 // perceptual average volume, better suited to non-directional gains.
94 gains
[i
] = sqrtf(device
->AmbiCoeffs
[i
][0]) * ingain
;
96 for(;i
< MAX_OUTPUT_CHANNELS
;i
++)
100 void ComputeAngleGains(const ALCdevice
*device
, ALfloat angle
, ALfloat elevation
, ALfloat ingain
, ALfloat gains
[MAX_OUTPUT_CHANNELS
])
103 sinf(angle
) * cosf(elevation
),
105 -cosf(angle
) * cosf(elevation
)
107 ComputeDirectionalGains(device
, dir
, ingain
, gains
);
110 void ComputeDirectionalGains(const ALCdevice
*device
, const ALfloat dir
[3], ALfloat ingain
, ALfloat gains
[MAX_OUTPUT_CHANNELS
])
112 ALfloat coeffs
[MAX_AMBI_COEFFS
];
114 /* Convert from OpenAL coords to Ambisonics. */
120 coeffs
[0] = 1.0f
; /* ACN 0 = 1 */
122 coeffs
[1] = 1.7321f
* y
; /* ACN 1 = sqrt(3) * Y */
123 coeffs
[2] = 1.7321f
* z
; /* ACN 2 = sqrt(3) * Z */
124 coeffs
[3] = 1.7321f
* x
; /* ACN 3 = sqrt(3) * X */
126 coeffs
[4] = 3.8730f
* x
* y
; /* ACN 4 = sqrt(15) * X * Y */
127 coeffs
[5] = 3.8730f
* y
* z
; /* ACN 5 = sqrt(15) * Y * Z */
128 coeffs
[6] = 1.1180f
* (3.0f
*z
*z
- 1.0f
); /* ACN 6 = sqrt(5)/2 * (3*Z*Z - 1) */
129 coeffs
[7] = 3.8730f
* x
* z
; /* ACN 7 = sqrt(15) * X * Z */
130 coeffs
[8] = 1.9365f
* (x
*x
- y
*y
); /* ACN 8 = sqrt(15)/2 * (X*X - Y*Y) */
132 coeffs
[9] = 2.0917f
* y
* (3.0f
*x
*x
- y
*y
); /* ACN 9 = sqrt(35/8) * Y * (3*X*X - Y*Y) */
133 coeffs
[10] = 10.2470f
* z
* x
* y
; /* ACN 10 = sqrt(105) * Z * X * Y */
134 coeffs
[11] = 1.6292f
* y
* (5.0f
*z
*z
- 1.0f
); /* ACN 11 = sqrt(21/8) * Y * (5*Z*Z - 1) */
135 coeffs
[12] = 1.3229f
* z
* (5.0f
*z
*z
- 3.0f
); /* ACN 12 = sqrt(7)/2 * Z * (5*Z*Z - 3) */
136 coeffs
[13] = 1.6292f
* x
* (5.0f
*z
*z
- 1.0f
); /* ACN 13 = sqrt(21/8) * X * (5*Z*Z - 1) */
137 coeffs
[14] = 5.1235f
* z
* (x
*x
- y
*y
); /* ACN 14 = sqrt(105)/2 * Z * (X*X - Y*Y) */
138 coeffs
[15] = 2.0917f
* x
* (x
*x
- 3.0f
*y
*y
); /* ACN 15 = sqrt(35/8) * X * (X*X - 3*Y*Y) */
140 for(i
= 0;i
< device
->NumChannels
;i
++)
143 for(j
= 0;j
< MAX_AMBI_COEFFS
;j
++)
144 gain
+= device
->AmbiCoeffs
[i
][j
]*coeffs
[j
];
145 gains
[i
] = gain
* ingain
;
147 for(;i
< MAX_OUTPUT_CHANNELS
;i
++)
151 void ComputeBFormatGains(const ALCdevice
*device
, const ALfloat mtx
[4], ALfloat ingain
, ALfloat gains
[MAX_OUTPUT_CHANNELS
])
155 for(i
= 0;i
< device
->NumChannels
;i
++)
159 gain
+= device
->AmbiCoeffs
[i
][j
] * mtx
[j
];
160 gains
[i
] = gain
* ingain
;
162 for(;i
< MAX_OUTPUT_CHANNELS
;i
++)
167 DECL_CONST
static inline const char *GetLabelFromChannel(enum Channel channel
)
171 case FrontLeft
: return "front-left";
172 case FrontRight
: return "front-right";
173 case FrontCenter
: return "front-center";
174 case LFE
: return "lfe";
175 case BackLeft
: return "back-left";
176 case BackRight
: return "back-right";
177 case BackCenter
: return "back-center";
178 case SideLeft
: return "side-left";
179 case SideRight
: return "side-right";
181 case TopFrontLeft
: return "top-front-left";
182 case TopFrontRight
: return "top-front-right";
183 case TopBackLeft
: return "top-back-left";
184 case TopBackRight
: return "top-back-right";
185 case BottomFrontLeft
: return "bottom-front-left";
186 case BottomFrontRight
: return "bottom-front-right";
187 case BottomBackLeft
: return "bottom-back-left";
188 case BottomBackRight
: return "bottom-back-right";
190 case BFormatW
: return "bformat-w";
191 case BFormatX
: return "bformat-x";
192 case BFormatY
: return "bformat-y";
193 case BFormatZ
: return "bformat-z";
195 case InvalidChannel
: break;
201 typedef struct ChannelMap
{
202 enum Channel ChanName
;
203 ChannelConfig Config
;
206 static void SetChannelMap(ALCdevice
*device
, const ChannelMap
*chanmap
, size_t count
, ALfloat ambiscale
, ALboolean isfuma
)
210 device
->AmbiScale
= ambiscale
;
211 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
&& device
->ChannelName
[i
] != InvalidChannel
;i
++)
213 if(device
->ChannelName
[i
] == LFE
)
215 for(j
= 0;j
< MAX_AMBI_COEFFS
;j
++)
216 device
->AmbiCoeffs
[i
][j
] = 0.0f
;
220 for(j
= 0;j
< count
;j
++)
222 if(device
->ChannelName
[i
] == chanmap
[j
].ChanName
)
226 /* Reformat FuMa -> ACN/N3D */
227 for(k
= 0;k
< MAX_AMBI_COEFFS
;++k
)
229 ALuint acn
= FuMa2ACN
[k
];
230 device
->AmbiCoeffs
[i
][acn
] = chanmap
[j
].Config
[k
] / FuMa2N3DScale
[acn
];
235 for(k
= 0;k
< MAX_AMBI_COEFFS
;++k
)
236 device
->AmbiCoeffs
[i
][k
] = chanmap
[j
].Config
[k
];
242 ERR("Failed to match %s channel ("SZFMT
") in config\n", GetLabelFromChannel(device
->ChannelName
[i
]), i
);
244 device
->NumChannels
= i
;
247 static bool LoadChannelSetup(ALCdevice
*device
)
249 static const enum Channel mono_chans
[1] = {
251 }, stereo_chans
[2] = {
252 FrontLeft
, FrontRight
254 FrontLeft
, FrontRight
,
256 }, surround51_chans
[5] = {
257 FrontLeft
, FrontRight
, FrontCenter
,
259 }, surround51rear_chans
[5] = {
260 FrontLeft
, FrontRight
, FrontCenter
,
262 }, surround61_chans
[6] = {
263 FrontLeft
, FrontRight
,
264 FrontCenter
, BackCenter
,
266 }, surround71_chans
[7] = {
267 FrontLeft
, FrontRight
, FrontCenter
,
271 ChannelMap chanmap
[MAX_OUTPUT_CHANNELS
];
272 const enum Channel
*channels
= NULL
;
273 const char *layout
= NULL
;
274 ALfloat ambiscale
= 1.0f
;
280 switch(device
->FmtChans
)
284 channels
= mono_chans
;
285 count
= COUNTOF(mono_chans
);
289 channels
= stereo_chans
;
290 count
= COUNTOF(stereo_chans
);
294 channels
= quad_chans
;
295 count
= COUNTOF(quad_chans
);
298 layout
= "surround51";
299 channels
= surround51_chans
;
300 count
= COUNTOF(surround51_chans
);
303 layout
= "surround51rear";
304 channels
= surround51rear_chans
;
305 count
= COUNTOF(surround51rear_chans
);
308 layout
= "surround61";
309 channels
= surround61_chans
;
310 count
= COUNTOF(surround61_chans
);
313 layout
= "surround71";
314 channels
= surround71_chans
;
315 count
= COUNTOF(surround71_chans
);
317 case DevFmtBFormat3D
:
329 snprintf(name
, sizeof(name
), "%s/type", layout
);
330 if(!ConfigValueStr(al_string_get_cstr(device
->DeviceName
), "layouts", name
, &type
))
333 if(sscanf(type
, " %31[^: ] : %d%c", name
, &order
, &eol
) != 2)
335 ERR("Invalid type value '%s' (expected name:order) for layout %s\n", type
, layout
);
339 if(strcasecmp(name
, "fuma") == 0)
341 else if(strcasecmp(name
, "n3d") == 0)
345 ERR("Unhandled type name '%s' (expected FuMa or N3D) for layout %s\n", name
, layout
);
350 ambiscale
= THIRD_ORDER_SCALE
;
352 ambiscale
= SECOND_ORDER_SCALE
;
354 ambiscale
= FIRST_ORDER_SCALE
;
356 ambiscale
= ZERO_ORDER_SCALE
;
359 ERR("Unhandled type order %d (expected 0, 1, 2, or 3) for layout %s\n", order
, layout
);
364 for(i
= 0;i
< count
;i
++)
366 float coeffs
[MAX_AMBI_COEFFS
] = {0.0f
};
367 const char *channame
;
374 chanmap
[i
].ChanName
= channels
[i
];
375 channame
= GetLabelFromChannel(channels
[i
]);
377 snprintf(chanlayout
, sizeof(chanlayout
), "%s/%s", layout
, channame
);
378 if(!ConfigValueStr(al_string_get_cstr(device
->DeviceName
), "layouts", chanlayout
, &value
))
380 ERR("Missing channel %s\n", channame
);
384 props
= sscanf(value
, " %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %c",
385 &coeffs
[0], &coeffs
[1], &coeffs
[2], &coeffs
[3],
386 &coeffs
[4], &coeffs
[5], &coeffs
[6], &coeffs
[7],
387 &coeffs
[8], &coeffs
[9], &coeffs
[10], &coeffs
[11],
388 &coeffs
[12], &coeffs
[13], &coeffs
[14], &coeffs
[15],
392 props
= sscanf(value
, " %f %f %f %f %f %f %f %f %f %c",
393 &coeffs
[0], &coeffs
[1], &coeffs
[2],
394 &coeffs
[3], &coeffs
[4], &coeffs
[5],
395 &coeffs
[6], &coeffs
[7], &coeffs
[8],
399 props
= sscanf(value
, " %f %f %f %f %c",
400 &coeffs
[0], &coeffs
[1],
401 &coeffs
[2], &coeffs
[3],
405 props
= sscanf(value
, " %f %c", &coeffs
[0], &eol
);
408 ERR("Failed to parse option %s properties\n", chanlayout
);
412 if(props
> (order
+1)*(order
+1))
414 ERR("Excess elements in option %s (expected %d)\n", chanlayout
, (order
+1)*(order
+1));
418 for(j
= 0;j
< MAX_AMBI_COEFFS
;++j
)
419 chanmap
[i
].Config
[j
] = coeffs
[j
];
421 SetChannelMap(device
, chanmap
, count
, ambiscale
, isfuma
);
425 ALvoid
aluInitPanning(ALCdevice
*device
)
427 /* NOTE: These decoder coefficients are using FuMa channel ordering and
428 * normalization, since that's what was produced by the Ambisonic Decoder
429 * Toolbox. SetChannelMap will convert them to N3D.
431 static const ChannelMap MonoCfg
[1] = {
432 { FrontCenter
, { 1.4142f
} },
434 { FrontLeft
, { 0.7071f
, 0.0f
, 0.5f
, 0.0f
} },
435 { FrontRight
, { 0.7071f
, 0.0f
, -0.5f
, 0.0f
} },
437 { FrontLeft
, { 0.353553f
, 0.306184f
, 0.306184f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.000000f
, 0.117186f
} },
438 { FrontRight
, { 0.353553f
, 0.306184f
, -0.306184f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.000000f
, -0.117186f
} },
439 { BackLeft
, { 0.353553f
, -0.306184f
, 0.306184f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.000000f
, -0.117186f
} },
440 { BackRight
, { 0.353553f
, -0.306184f
, -0.306184f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.000000f
, 0.117186f
} },
442 { FrontLeft
, { 0.208954f
, 0.212846f
, 0.238350f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.017738f
, 0.204014f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.051023f
, 0.047490f
} },
443 { FrontRight
, { 0.208954f
, 0.212846f
, -0.238350f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.017738f
, -0.204014f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.051023f
, -0.047490f
} },
444 { FrontCenter
, { 0.109403f
, 0.179490f
, 0.000000f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.142031f
, 0.000000f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.072024f
, 0.000000f
} },
445 { SideLeft
, { 0.470936f
, -0.369626f
, 0.349386f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.031375f
, -0.058144f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.007119f
, -0.043968f
} },
446 { SideRight
, { 0.470936f
, -0.369626f
, -0.349386f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.031375f
, 0.058144f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.007119f
, 0.043968f
} },
448 { FrontLeft
, { 0.208954f
, 0.212846f
, 0.238350f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.017738f
, 0.204014f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.051023f
, 0.047490f
} },
449 { FrontRight
, { 0.208954f
, 0.212846f
, -0.238350f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.017738f
, -0.204014f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.051023f
, -0.047490f
} },
450 { FrontCenter
, { 0.109403f
, 0.179490f
, 0.000000f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.142031f
, 0.000000f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.072024f
, 0.000000f
} },
451 { BackLeft
, { 0.470936f
, -0.369626f
, 0.349386f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.031375f
, -0.058144f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.007119f
, -0.043968f
} },
452 { BackRight
, { 0.470936f
, -0.369626f
, -0.349386f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.031375f
, 0.058144f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.007119f
, 0.043968f
} },
454 { FrontLeft
, { 0.167065f
, 0.200583f
, 0.172695f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.029855f
, 0.186407f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.039241f
, 0.068910f
} },
455 { FrontRight
, { 0.167065f
, 0.200583f
, -0.172695f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.029855f
, -0.186407f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.039241f
, -0.068910f
} },
456 { FrontCenter
, { 0.109403f
, 0.179490f
, 0.000000f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.142031f
, 0.000000f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.072024f
, 0.000000f
} },
457 { BackCenter
, { 0.353556f
, -0.461940f
, 0.000000f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.165723f
, 0.000000f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.000000f
, 0.000000f
} },
458 { SideLeft
, { 0.289151f
, -0.081301f
, 0.401292f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.188208f
, -0.071420f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.010099f
, -0.032897f
} },
459 { SideRight
, { 0.289151f
, -0.081301f
, -0.401292f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.188208f
, 0.071420f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.010099f
, 0.032897f
} },
461 { FrontLeft
, { 0.167065f
, 0.200583f
, 0.172695f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.029855f
, 0.186407f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.039241f
, 0.068910f
} },
462 { FrontRight
, { 0.167065f
, 0.200583f
, -0.172695f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.029855f
, -0.186407f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.039241f
, -0.068910f
} },
463 { FrontCenter
, { 0.109403f
, 0.179490f
, 0.000000f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.142031f
, 0.000000f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.072024f
, 0.000000f
} },
464 { BackLeft
, { 0.224752f
, -0.295009f
, 0.170325f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.105349f
, -0.182473f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.000000f
, 0.065799f
} },
465 { BackRight
, { 0.224752f
, -0.295009f
, -0.170325f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.105349f
, 0.182473f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.000000f
, -0.065799f
} },
466 { SideLeft
, { 0.224739f
, 0.000000f
, 0.340644f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.210697f
, 0.000000f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.000000f
, -0.065795f
} },
467 { SideRight
, { 0.224739f
, 0.000000f
, -0.340644f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -0.210697f
, 0.000000f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.000000f
, 0.065795f
} },
469 { BFormatW
, { 1.0f
, 0.0f
, 0.0f
, 0.0f
} },
470 { BFormatX
, { 0.0f
, 1.0f
, 0.0f
, 0.0f
} },
471 { BFormatY
, { 0.0f
, 0.0f
, 1.0f
, 0.0f
} },
472 { BFormatZ
, { 0.0f
, 0.0f
, 0.0f
, 1.0f
} },
474 const ChannelMap
*chanmap
= NULL
;
475 ALfloat ambiscale
= 1.0f
;
478 device
->AmbiScale
= 1.0f
;
479 memset(device
->AmbiCoeffs
, 0, sizeof(device
->AmbiCoeffs
));
480 device
->NumChannels
= 0;
484 ALfloat (*coeffs_list
[4])[2];
485 ALuint
*delay_list
[4];
488 count
= COUNTOF(BFormat3D
);
492 for(i
= 0;i
< count
;i
++)
493 device
->ChannelName
[i
] = chanmap
[i
].ChanName
;
494 for(;i
< MAX_OUTPUT_CHANNELS
;i
++)
495 device
->ChannelName
[i
] = InvalidChannel
;
496 SetChannelMap(device
, chanmap
, count
, ambiscale
, AL_TRUE
);
500 static const enum Channel inputs
[4] = { BFormatW
, BFormatX
, BFormatY
, BFormatZ
};
501 int chan
= GetChannelIdxByName(device
, inputs
[i
]);
502 coeffs_list
[i
] = device
->Hrtf_Params
[chan
].Coeffs
;
503 delay_list
[i
] = device
->Hrtf_Params
[chan
].Delay
;
505 GetBFormatHrtfCoeffs(device
->Hrtf
, 4, coeffs_list
, delay_list
);
510 if(LoadChannelSetup(device
))
513 switch(device
->FmtChans
)
516 count
= COUNTOF(MonoCfg
);
518 ambiscale
= ZERO_ORDER_SCALE
;
522 count
= COUNTOF(StereoCfg
);
524 ambiscale
= FIRST_ORDER_SCALE
;
528 count
= COUNTOF(QuadCfg
);
530 ambiscale
= SECOND_ORDER_SCALE
;
534 count
= COUNTOF(X51SideCfg
);
535 chanmap
= X51SideCfg
;
536 ambiscale
= THIRD_ORDER_SCALE
;
540 count
= COUNTOF(X51RearCfg
);
541 chanmap
= X51RearCfg
;
542 ambiscale
= THIRD_ORDER_SCALE
;
546 count
= COUNTOF(X61Cfg
);
548 ambiscale
= THIRD_ORDER_SCALE
;
552 count
= COUNTOF(X71Cfg
);
554 ambiscale
= THIRD_ORDER_SCALE
;
557 case DevFmtBFormat3D
:
558 count
= COUNTOF(BFormat3D
);
564 SetChannelMap(device
, chanmap
, count
, ambiscale
, AL_TRUE
);