JOAL v2.6.0-rc-20250712
JOAL, OpenAL® API Binding for Java™ (public API).
ALHelpers.java
Go to the documentation of this file.
1/**
2 * OpenAL Helpers
3 *
4 * Copyright (c) 2011 by Chris Robinson <chris.kcat@gmail.com>
5 * Copyright (c) 2013-2023 JogAmp Community
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25package com.jogamp.openal.util;
26
27import com.jogamp.openal.AL;
28import com.jogamp.openal.ALConstants;
29import static com.jogamp.openal.ALConstants.*;
30import com.jogamp.openal.ALExt;
31import static com.jogamp.openal.ALExtConstants.*;
32
33import com.jogamp.common.av.AudioFormat;
34
35
36/* This class contains routines to help with some menial OpenAL-related tasks,
37 * such as finding an audio format and getting readable strings for
38 * channel configs and sample types. */
39public class ALHelpers {
40 /**
41 * [openal-soft >= 1.18.0](https://github.com/kcat/openal-soft/blob/master/ChangeLog)
42 * - Removed support for the AL_SOFT_buffer_samples and AL_SOFT_buffer_sub_data
43 * extensions. Due to conflicts with AL_EXT_SOURCE_RADIUS.
44 */
45 public static final String AL_SOFT_buffer_samples = "AL_SOFT_buffer_samples";
46 // public static final String AL_SOFT_callback_buffer = "AL_SOFT_callback_buffer";
47 public static final String AL_SOFT_events = "AL_SOFT_events";
48
49 public static final String AL_EXT_MCFORMATS = "AL_EXT_MCFORMATS";
50 public static final String AL_EXT_FLOAT32 = "AL_EXT_FLOAT32";
51 public static final String AL_EXT_DOUBLE = "AL_EXT_DOUBLE";
52
53 public static final String ALC_EXT_thread_local_context = "ALC_EXT_thread_local_context";
54
55 public static final String ALC_ENUMERATION_EXT = "ALC_ENUMERATION_EXT";
56 public static final String ALC_ENUMERATE_ALL_EXT = "ALC_ENUMERATE_ALL_EXT";
57
58 public static final String ALC_EXT_debug = "ALC_EXT_debug";
59 public static final String AL_EXT_debug = "AL_EXT_debug";
60 public static final String ALC_SOFT_system_events = "ALC_SOFT_system_events";
61
62 /**
63 * Returns a compatible {@link AudioFormat} based on given OpenAL channel-layout, sample-type and format,
64 * as well as the generic sample-rate and sample-size.
65 * <p>
66 * The resulting {@link AudioFormat} uses {@link AudioFormat#planar} = false and {@link AudioFormat#littleEndian} = true.
67 * </p>
68 * @param alChannelLayout OpenAL channel layout
69 * @param alSampleType OpenAL sample type
70 * @param alFormat OpenAL format
71 * @param sampleRate sample rate, e.g. 44100
72 * @param sampleSize sample size in bits, e.g. 16
73 * @return a new {@link AudioFormat} instance or null if parameter are not conclusive or invalid.
74 */
75 public static AudioFormat getAudioFormat(final int alChannelLayout, final int alSampleType, final int alFormat,
76 final int sampleRate, final int sampleSize) {
77 if( ALConstants.AL_NONE == alChannelLayout || ALConstants.AL_NONE == alSampleType ||
78 ALConstants.AL_NONE == alFormat || 0 == sampleRate || 0 == sampleSize ) {
79 return null;
80 }
81 final int channelCount = getALChannelLayoutChannelCount(alChannelLayout);
82 if( 0 == channelCount ) {
83 return null;
84 }
85 final boolean signed = isALSampleTypeSigned(alSampleType);
86 final boolean fixedP = isALSampleTypeFixed(alSampleType);
87 return new AudioFormat(sampleRate, sampleSize, channelCount, signed, fixedP,
88 false /* planar */, true /* littleEndian */);
89 }
90
91 /**
92 * Returns a compatible AL buffer format given the {@link AudioFormat},
93 * which determines the AL channel layout and AL sample type.
94 * </p>
95 * <p>
96 * If <code>hasEXTMcFormats</code> or <code>hasSOFTBufferSamples</code> is true,
97 * it will be called to find the closest-matching format from
98 * <code>AL_EXT_MCFORMATS</code> or <code>AL_SOFT_buffer_samples</code>.
99 * </p>
100 * <p>
101 * Returns {@link ALConstants#AL_NONE} if no supported format can be found.
102 * </p>
103 * <p>
104 * Function uses {@link AL#alIsExtensionPresent(String)}, which might be context dependent,
105 * otherwise function is context independent.
106 * </p>
107 *
108 * @param audioFormat used to derive AL channel layout {@link #getDefaultALChannelLayout(int)}
109 * and AL sample type {@link #getALSampleType(int, boolean, boolean)}
110 * @param al AL instance
111 * @param alExt ALExt instance
112 * @return AL buffer format
113 */
114 public static int getALFormat(final AudioFormat audioFormat,
115 final AL al, final ALExt alExt) {
116 final int alChannelLayout = ALHelpers.getDefaultALChannelLayout(audioFormat.channelCount);
117 final int alSampleType = ALHelpers.getALSampleType(audioFormat.sampleSize, audioFormat.signed, audioFormat.fixedP);
118 if( ALConstants.AL_NONE != alChannelLayout && ALConstants.AL_NONE != alSampleType ) {
119 return ALHelpers.getALFormat(alChannelLayout, alSampleType, al, alExt);
120 } else {
121 return ALConstants.AL_NONE;
122 }
123 }
124
125 /**
126 * Returns a compatible AL buffer format given the {@link AudioFormat},
127 * which determines the AL channel layout and AL sample type.
128 * </p>
129 * <p>
130 * If <code>hasEXTMcFormats</code> or <code>hasSOFTBufferSamples</code> is true,
131 * it will be called to find the closest-matching format from
132 * <code>AL_EXT_MCFORMATS</code> or <code>AL_SOFT_buffer_samples</code>.
133 * </p>
134 * <p>
135 * Returns {@link ALConstants#AL_NONE} if no supported format can be found.
136 * </p>
137 * <p>
138 * Function is context independent.
139 * </p>
140 *
141 * @param audioFormat used to derive AL channel layout {@link #getDefaultALChannelLayout(int)}
142 * and AL sample type {@link #getALSampleType(int, boolean, boolean)}
143 * @param al AL instance
144 * @param alExt ALExt instance
145 * @param hasSOFTBufferSamples true if having extension <code>AL_SOFT_buffer_samples</code>, otherwise false
146 * @param hasEXTMcFormats true if having extension <code>AL_EXT_MCFORMATS</code>, otherwise false
147 * @param hasEXTFloat32 true if having extension <code>AL_EXT_FLOAT32</code>, otherwise false
148 * @param hasEXTDouble true if having extension <code>AL_EXT_DOUBLE</code>, otherwise false
149 * @return AL buffer format
150 */
151 public static int getALFormat(final AudioFormat audioFormat,
152 final AL al, final ALExt alExt,
153 final boolean hasSOFTBufferSamples,
154 final boolean hasEXTMcFormats,
155 final boolean hasEXTFloat32, final boolean hasEXTDouble) {
156 final int alChannelLayout = ALHelpers.getDefaultALChannelLayout(audioFormat.channelCount);
157 final int alSampleType = ALHelpers.getALSampleType(audioFormat.sampleSize, audioFormat.signed, audioFormat.fixedP);
158 final int alFormat;
159 if( ALConstants.AL_NONE != alChannelLayout && ALConstants.AL_NONE != alSampleType ) {
160 alFormat = ALHelpers.getALFormat(alChannelLayout, alSampleType, al, alExt,
161 hasSOFTBufferSamples, hasEXTMcFormats,
162 hasEXTFloat32, hasEXTDouble);
163 } else {
164 alFormat = ALConstants.AL_NONE;
165 }
166 return alFormat;
167 }
168
169 /**
170 * Returns a compatible AL buffer format given the AL channel layout and AL sample type.
171 * <p>
172 * If <code>hasEXTMcFormats</code> or <code>hasSOFTBufferSamples</code> is true,
173 * it will be called to find the closest-matching format from
174 * <code>AL_EXT_MCFORMATS</code> or <code>AL_SOFT_buffer_samples</code>.
175 * </p>
176 * <p>
177 * Returns {@link ALConstants#AL_NONE} if no supported format can be found.
178 * </p>
179 * <p>
180 * Function uses {@link AL#alIsExtensionPresent(String)}, which might be context dependent,
181 * otherwise function is context independent.
182 * </p>
183 *
184 * @param alChannelLayout AL channel layout, see {@link #getDefaultALChannelLayout(int)}
185 * @param alSampleType AL sample type, see {@link #getALSampleType(int, boolean, boolean)}.
186 * @param al AL instance
187 * @param alExt ALExt instance
188 * @return AL buffer format
189 */
190 public static final int getALFormat(final int alChannelLayout, final int alSampleType,
191 final AL al, final ALExt alExt) {
192 final boolean hasSOFTBufferSamples = al.alIsExtensionPresent(AL_SOFT_buffer_samples);
193 final boolean hasEXTMcFormats = al.alIsExtensionPresent(AL_EXT_MCFORMATS);
194 final boolean hasEXTFloat32 = al.alIsExtensionPresent(AL_EXT_FLOAT32);
195 final boolean hasEXTDouble = al.alIsExtensionPresent(AL_EXT_DOUBLE);
196 return ALHelpers.getALFormat(alChannelLayout, alSampleType, al, alExt,
197 hasSOFTBufferSamples, hasEXTMcFormats,
198 hasEXTFloat32, hasEXTDouble);
199 }
200
201 /**
202 * Returns a compatible AL buffer format given the AL channel layout and AL sample type.
203 * <p>
204 * If <code>hasEXTMcFormats</code> or <code>hasSOFTBufferSamples</code> is true,
205 * it will be called to find the closest-matching format from
206 * <code>AL_EXT_MCFORMATS</code> or <code>AL_SOFT_buffer_samples</code>.
207 * </p>
208 * <p>
209 * Returns {@link ALConstants#AL_NONE} if no supported format can be found.
210 * </p>
211 * <p>
212 * Function is context independent.
213 * </p>
214 *
215 * @param alChannelLayout AL channel layout, see {@link #getDefaultALChannelLayout(int)}
216 * @param alSampleType AL sample type, see {@link #getALSampleType(int, boolean, boolean)}.
217 * @param al AL instance
218 * @param alExt ALExt instance
219 * @param hasSOFTBufferSamples true if having extension <code>AL_SOFT_buffer_samples</code>, otherwise false
220 * @param hasEXTMcFormats true if having extension <code>AL_EXT_MCFORMATS</code>, otherwise false
221 * @param hasEXTFloat32 true if having extension <code>AL_EXT_FLOAT32</code>, otherwise false
222 * @param hasEXTDouble true if having extension <code>AL_EXT_DOUBLE</code>, otherwise false
223 * @return AL buffer format
224 */
225 public static final int getALFormat(final int alChannelLayout, final int alSampleType,
226 final AL al, final ALExt alExt,
227 final boolean hasSOFTBufferSamples,
228 final boolean hasEXTMcFormats,
229 final boolean hasEXTFloat32, final boolean hasEXTDouble) {
230 int format = AL_NONE;
231
232 /* If using AL_SOFT_buffer_samples, try looking through its formats */
233 if(hasSOFTBufferSamples)
234 {
235 /* AL_SOFT_buffer_samples is more lenient with matching formats. The
236 * specified sample type does not need to match the returned format,
237 * but it is nice to try to get something close. */
238 if(alSampleType == AL_UNSIGNED_BYTE_SOFT || alSampleType == AL_BYTE_SOFT)
239 {
240 if(alChannelLayout == AL_MONO_SOFT) format = AL_MONO8_SOFT;
241 else if(alChannelLayout == AL_STEREO_SOFT) format = AL_STEREO8_SOFT;
242 else if(alChannelLayout == AL_QUAD_SOFT) format = AL_QUAD8_SOFT;
243 else if(alChannelLayout == AL_5POINT1_SOFT) format = AL_5POINT1_8_SOFT;
244 else if(alChannelLayout == AL_6POINT1_SOFT) format = AL_6POINT1_8_SOFT;
245 else if(alChannelLayout == AL_7POINT1_SOFT) format = AL_7POINT1_8_SOFT;
246 }
247 else if(alSampleType == AL_UNSIGNED_SHORT_SOFT || alSampleType == AL_SHORT_SOFT)
248 {
249 if(alChannelLayout == AL_MONO_SOFT) format = AL_MONO16_SOFT;
250 else if(alChannelLayout == AL_STEREO_SOFT) format = AL_STEREO16_SOFT;
251 else if(alChannelLayout == AL_QUAD_SOFT) format = AL_QUAD16_SOFT;
252 else if(alChannelLayout == AL_5POINT1_SOFT) format = AL_5POINT1_16_SOFT;
253 else if(alChannelLayout == AL_6POINT1_SOFT) format = AL_6POINT1_16_SOFT;
254 else if(alChannelLayout == AL_7POINT1_SOFT) format = AL_7POINT1_16_SOFT;
255 }
256 else if(alSampleType == AL_UNSIGNED_BYTE3_SOFT || alSampleType == AL_BYTE3_SOFT ||
257 alSampleType == AL_UNSIGNED_INT_SOFT || alSampleType == AL_INT_SOFT ||
258 alSampleType == AL_FLOAT_SOFT || alSampleType == AL_DOUBLE_SOFT)
259 {
260 if(alChannelLayout == AL_MONO_SOFT) format = AL_MONO32F_SOFT;
261 else if(alChannelLayout == AL_STEREO_SOFT) format = AL_STEREO32F_SOFT;
262 else if(alChannelLayout == AL_QUAD_SOFT) format = AL_QUAD32F_SOFT;
263 else if(alChannelLayout == AL_5POINT1_SOFT) format = AL_5POINT1_32F_SOFT;
264 else if(alChannelLayout == AL_6POINT1_SOFT) format = AL_6POINT1_32F_SOFT;
265 else if(alChannelLayout == AL_7POINT1_SOFT) format = AL_7POINT1_32F_SOFT;
266 }
267
268 if(format != AL_NONE && !alExt.alIsBufferFormatSupportedSOFT(format))
269 format = AL_NONE;
270
271 /* A matching format was not found or supported. Try 32-bit float. */
272 if(format == AL_NONE)
273 {
274 if(alChannelLayout == AL_MONO_SOFT) format = AL_MONO32F_SOFT;
275 else if(alChannelLayout == AL_STEREO_SOFT) format = AL_STEREO32F_SOFT;
276 else if(alChannelLayout == AL_QUAD_SOFT) format = AL_QUAD32F_SOFT;
277 else if(alChannelLayout == AL_5POINT1_SOFT) format = AL_5POINT1_32F_SOFT;
278 else if(alChannelLayout == AL_6POINT1_SOFT) format = AL_6POINT1_32F_SOFT;
279 else if(alChannelLayout == AL_7POINT1_SOFT) format = AL_7POINT1_32F_SOFT;
280
281 if(format != AL_NONE && !alExt.alIsBufferFormatSupportedSOFT(format))
282 format = AL_NONE;
283 }
284 /* 32-bit float not supported. Try 16-bit int. */
285 if(format == AL_NONE)
286 {
287 if(alChannelLayout == AL_MONO_SOFT) format = AL_MONO16_SOFT;
288 else if(alChannelLayout == AL_STEREO_SOFT) format = AL_STEREO16_SOFT;
289 else if(alChannelLayout == AL_QUAD_SOFT) format = AL_QUAD16_SOFT;
290 else if(alChannelLayout == AL_5POINT1_SOFT) format = AL_5POINT1_16_SOFT;
291 else if(alChannelLayout == AL_6POINT1_SOFT) format = AL_6POINT1_16_SOFT;
292 else if(alChannelLayout == AL_7POINT1_SOFT) format = AL_7POINT1_16_SOFT;
293
294 if(format != AL_NONE && !alExt.alIsBufferFormatSupportedSOFT(format))
295 format = AL_NONE;
296 }
297 /* 16-bit int not supported. Try 8-bit int. */
298 if(format == AL_NONE)
299 {
300 if(alChannelLayout == AL_MONO_SOFT) format = AL_MONO8_SOFT;
301 else if(alChannelLayout == AL_STEREO_SOFT) format = AL_STEREO8_SOFT;
302 else if(alChannelLayout == AL_QUAD_SOFT) format = AL_QUAD8_SOFT;
303 else if(alChannelLayout == AL_5POINT1_SOFT) format = AL_5POINT1_8_SOFT;
304 else if(alChannelLayout == AL_6POINT1_SOFT) format = AL_6POINT1_8_SOFT;
305 else if(alChannelLayout == AL_7POINT1_SOFT) format = AL_7POINT1_8_SOFT;
306
307 if(format != AL_NONE && !alExt.alIsBufferFormatSupportedSOFT(format))
308 format = AL_NONE;
309 }
310
311 return format;
312 }
313
314 /* We use the AL_EXT_MCFORMATS extension to provide output of Quad, 5.1,
315 * and 7.1 channel configs, AL_EXT_FLOAT32 for 32-bit float samples, and
316 * AL_EXT_DOUBLE for 64-bit float samples. */
317 if(alSampleType == AL_UNSIGNED_BYTE_SOFT)
318 {
319 if(alChannelLayout == AL_MONO_SOFT)
320 format = AL_FORMAT_MONO8;
321 else if(alChannelLayout == AL_STEREO_SOFT)
322 format = AL_FORMAT_STEREO8;
323 else if( hasEXTMcFormats )
324 {
325 if(alChannelLayout == AL_QUAD_SOFT)
326 format = AL_FORMAT_QUAD8;
327 else if(alChannelLayout == AL_5POINT1_SOFT)
328 format = AL_FORMAT_51CHN8;
329 else if(alChannelLayout == AL_6POINT1_SOFT)
330 format = AL_FORMAT_61CHN8;
331 else if(alChannelLayout == AL_7POINT1_SOFT)
332 format = AL_FORMAT_71CHN8;
333 }
334 }
335 else if(alSampleType == AL_SHORT_SOFT)
336 {
337 if(alChannelLayout == AL_MONO_SOFT)
338 format = AL_FORMAT_MONO16;
339 else if(alChannelLayout == AL_STEREO_SOFT)
340 format = AL_FORMAT_STEREO16;
341 else if( hasEXTMcFormats )
342 {
343 if(alChannelLayout == AL_QUAD_SOFT)
344 format = AL_FORMAT_QUAD16;
345 else if(alChannelLayout == AL_5POINT1_SOFT)
346 format = AL_FORMAT_51CHN16;
347 else if(alChannelLayout == AL_6POINT1_SOFT)
348 format = AL_FORMAT_61CHN16;
349 else if(alChannelLayout == AL_7POINT1_SOFT)
350 format = AL_FORMAT_71CHN16;
351 }
352 }
353 else if(alSampleType == AL_FLOAT_SOFT && hasEXTFloat32)
354 {
355 if(alChannelLayout == AL_MONO_SOFT)
356 format = AL_FORMAT_MONO_FLOAT32;
357 else if(alChannelLayout == AL_STEREO_SOFT)
358 format = AL_FORMAT_STEREO_FLOAT32;
359 else if( hasEXTMcFormats )
360 {
361 if(alChannelLayout == AL_QUAD_SOFT)
362 format = AL_FORMAT_QUAD32;
363 else if(alChannelLayout == AL_5POINT1_SOFT)
364 format = AL_FORMAT_51CHN32;
365 else if(alChannelLayout == AL_6POINT1_SOFT)
366 format = AL_FORMAT_61CHN32;
367 else if(alChannelLayout == AL_7POINT1_SOFT)
368 format = AL_FORMAT_71CHN32;
369 }
370 }
371 else if(alSampleType == AL_DOUBLE_SOFT && hasEXTDouble)
372 {
373 if(alChannelLayout == AL_MONO_SOFT)
374 format = AL_FORMAT_MONO_DOUBLE_EXT;
375 else if(alChannelLayout == AL_STEREO_SOFT) {
376 format = AL_FORMAT_STEREO_DOUBLE_EXT;
377 }
378 }
379
380 /* NOTE: It seems OSX returns -1 from alGetEnumValue for unknown enums, as
381 * opposed to 0. Correct it. */
382 if(format == -1) {
383 format = AL_NONE;
384 }
385
386 return format;
387 }
388
389 /**
390 * Returns the default AL channel layout matching the given channel count, or {@link ALConstants#AL_NONE}.
391 * @param channelCount number of channels
392 * @param signed true if signed number, false for unsigned
393 * @param fixedP true for fixed point value, false for floating point value with a sampleSize of 32 (float) or 64 (double)
394 */
395 public static final int getDefaultALChannelLayout(final int channelCount) {
396 switch(channelCount) {
397 case 1: return AL_MONO_SOFT;
398 case 2: return AL_STEREO_SOFT;
399 // case 2: return AL_REAR_SOFT;
400 case 4: return AL_QUAD_SOFT;
401 case 6: return AL_5POINT1_SOFT;
402 case 7: return AL_6POINT1_SOFT;
403 case 8: return AL_7POINT1_SOFT;
404 }
405 return AL_NONE;
406 }
407
408 /**
409 * Returns the readable name of the given AL channel layout
410 */
411 public static final String alChannelLayoutName(final int alChannelLayout) {
412 switch(alChannelLayout) {
413 case AL_MONO_SOFT: return "Mono";
414 case AL_STEREO_SOFT: return "Stereo";
415 case AL_REAR_SOFT: return "Rear";
416 case AL_QUAD_SOFT: return "Quad";
417 case AL_5POINT1_SOFT: return "5.1";
418 case AL_6POINT1_SOFT: return "6.1";
419 case AL_7POINT1_SOFT: return "7.1";
420 }
421 return "Unknown AL-Channel-Layout 0x"+Integer.toHexString(alChannelLayout);
422 }
423
424 /**
425 * Returns the channel count of the given AL channel layout
426 */
427 public static final int getALChannelLayoutChannelCount(final int alChannelLayout) {
428 switch(alChannelLayout) {
429 case AL_MONO_SOFT: return 1;
430 case AL_STEREO_SOFT: return 2;
431 case AL_REAR_SOFT: return 2;
432 case AL_QUAD_SOFT: return 4;
433 case AL_5POINT1_SOFT: return 6;
434 case AL_6POINT1_SOFT: return 7;
435 case AL_7POINT1_SOFT: return 8;
436 }
437 return 0;
438 }
439
440 /**
441 * Returns the AL sample type matching the given audio type attributes, or {@link ALConstants#AL_NONE}.
442 * @param sampleSize sample size in bits
443 * @param signed true if signed number, false for unsigned
444 * @param fixedP true for fixed point value, false for floating point value with a sampleSize of 32 (float) or 64 (double)
445 */
446 public static final int getALSampleType(final int sampleSize, final boolean signed, final boolean fixedP) {
447 if( fixedP ) {
448 if( signed ) {
449 switch( sampleSize ) {
450 case 8: return AL_BYTE_SOFT;
451 case 16: return AL_SHORT_SOFT;
452 case 32: return AL_INT_SOFT;
453 }
454 } else {
455 switch( sampleSize ) {
456 case 8: return AL_UNSIGNED_BYTE_SOFT;
457 case 16: return AL_UNSIGNED_SHORT_SOFT;
458 case 32: return AL_UNSIGNED_INT_SOFT;
459 }
460 }
461 } else {
462 if( signed ) {
463 switch( sampleSize ) {
464 case 32: return AL_FLOAT_SOFT;
465 case 64: return AL_DOUBLE_SOFT;
466 }
467 }
468 }
469 return AL_NONE;
470 }
471
472 /**
473 * Returns the readable name of the given AL sample type
474 */
475 public static final String alSampleTypeName(final int alSampleType) {
476 switch(alSampleType) {
477 case AL_BYTE_SOFT: return "s8";
478 case AL_UNSIGNED_BYTE_SOFT: return "u8";
479 case AL_SHORT_SOFT: return "s16";
480 case AL_UNSIGNED_SHORT_SOFT: return "u16";
481 case AL_INT_SOFT: return "s32";
482 case AL_UNSIGNED_INT_SOFT: return "u32";
483 case AL_FLOAT_SOFT: return "f32";
484 case AL_DOUBLE_SOFT: return "f64";
485 }
486 return "Unknown AL-Type 0x"+Integer.toHexString(alSampleType);
487 }
488
489 /**
490 * Returns whether the given AL sample type is signed
491 */
492 public static final boolean isALSampleTypeSigned(final int alSampleType) {
493 switch(alSampleType) {
494 case AL_BYTE_SOFT:
495 case AL_SHORT_SOFT:
496 case AL_INT_SOFT:
497 case AL_FLOAT_SOFT:
498 case AL_DOUBLE_SOFT:
499 return true;
500 case AL_UNSIGNED_BYTE_SOFT:
501 case AL_UNSIGNED_SHORT_SOFT:
502 case AL_UNSIGNED_INT_SOFT:
503 default:
504 return false;
505 }
506 }
507
508 /**
509 * Returns true if the given AL sample type is a fixed point (byte, short, int, ..)
510 * or false if a floating point type (float, double).
511 */
512 public static final boolean isALSampleTypeFixed(final int alSampleType) {
513 switch(alSampleType) {
514 case AL_BYTE_SOFT:
515 case AL_SHORT_SOFT:
516 case AL_INT_SOFT:
517 case AL_UNSIGNED_BYTE_SOFT:
518 case AL_UNSIGNED_SHORT_SOFT:
519 case AL_UNSIGNED_INT_SOFT:
520 return true;
521 case AL_FLOAT_SOFT:
522 case AL_DOUBLE_SOFT:
523 default:
524 return false;
525 }
526 }
527
528 /**
529 * Returns the byte size of the given AL sample type
530 * @throws IllegalArgumentException for unknown <code>alChannelLayout</code> or <code>alSampleType</code> values.
531 */
532 public static final int sizeOfALSampleType(final int alSampleType) throws IllegalArgumentException {
533 switch(alSampleType) {
534 case AL_BYTE_SOFT:
535 case AL_UNSIGNED_BYTE_SOFT:
536 return 1;
537 case AL_SHORT_SOFT:
538 case AL_UNSIGNED_SHORT_SOFT:
539 return 2;
540 case AL_INT_SOFT:
541 case AL_UNSIGNED_INT_SOFT:
542 case AL_FLOAT_SOFT:
543 return 4;
544 case AL_DOUBLE_SOFT:
545 return 8;
546 default:
547 throw new IllegalArgumentException("Unknown al-type 0x"+Integer.toHexString(alSampleType));
548 }
549 }
550
551 /**
552 * @param sampleCount number of samples per channel
553 * @param alChannelLayout AL channel layout
554 * @param alSampleType AL sample type
555 * @return bytes count required
556 * @throws IllegalArgumentException for unknown <code>alChannelLayout</code> or <code>alSampleType</code> values.
557 */
558 public static final int samplesToByteCount(int sampleCount, final int alChannelLayout, final int alSampleType)
559 throws IllegalArgumentException
560 {
561 switch(alChannelLayout) {
562 case AL_MONO_SOFT: sampleCount *= 1; break;
563 case AL_STEREO_SOFT: sampleCount *= 2; break;
564 case AL_REAR_SOFT: sampleCount *= 2; break;
565 case AL_QUAD_SOFT: sampleCount *= 4; break;
566 case AL_5POINT1_SOFT: sampleCount *= 6; break;
567 case AL_6POINT1_SOFT: sampleCount *= 7; break;
568 case AL_7POINT1_SOFT: sampleCount *= 8; break;
569 default: throw new IllegalArgumentException("Unknown al-channel-layout 0x"+Integer.toHexString(alChannelLayout));
570 }
571
572 switch(alSampleType) {
573 case AL_BYTE_SOFT:
574 case AL_UNSIGNED_BYTE_SOFT:
575 break;
576 case AL_SHORT_SOFT:
577 case AL_UNSIGNED_SHORT_SOFT:
578 sampleCount *= 2;
579 break;
580 case AL_INT_SOFT:
581 case AL_UNSIGNED_INT_SOFT:
582 case AL_FLOAT_SOFT:
583 sampleCount *= 4;
584 break;
585 case AL_DOUBLE_SOFT:
586 sampleCount *= 8;
587 break;
588 default:
589 throw new IllegalArgumentException("Unknown al-type 0x"+Integer.toHexString(alSampleType));
590 }
591
592 return sampleCount;
593 }
594
595 public static final int bytesToSampleCount(final int byteCount, final int alChannelLayout, final int alSampleType) {
596 return byteCount / samplesToByteCount(1, alChannelLayout, alSampleType);
597 }
598
599 /** Returns given {@link ALConstants#AL_SOURCE_STATE} {@link AL#alGetSourcei(int, int, int[], int)}} value as a string. */
600 public static final String alSourceStateString(final int sourceState) {
601 switch( sourceState ) {
602 case AL_INITIAL: return "initial";
603 case AL_PLAYING: return "playing";
604 case AL_PAUSED: return "paused";
605 case AL_STOPPED: return "stopped";
606 default: return "invalid";
607 }
608 }
609
610 /**
611 public static final String alConstantString(final int state) {
612 switch(state) {
613 case AL_ILLEGAL_COMMAND: return "";
614 case AL_PROCESSED: return "";
615 case AL_FREQUENCY: return "";
616 case AL_NO_ERROR: return "";
617 case AL_VENDOR: return "";
618 case AL_STATIC: return "";
619 // case AL_INVALID_ENUM: return "";
620 case AL_MAX_DISTANCE: return "";
621 case AL_ROLLOFF_FACTOR: return "";
622 case AL_GAIN: return "";
623 case AL_SIZE: return "";
624 case AL_DISTANCE_MODEL: return "";
625 case AL_BYTE_OFFSET: return "";
626 case AL_SOURCE_STATE: return "";
627 case AL_STOPPED: return "";
628 case AL_REFERENCE_DISTANCE: return "";
629 case AL_MIN_GAIN: return "";
630 case AL_PLAYING: return "";
631 case AL_INVERSE_DISTANCE_CLAMPED: return "";
632 case AL_PITCH: return "";
633 case AL_OUT_OF_MEMORY: return "";
634 case AL_FORMAT_MONO8: return "";
635 case AL_TRUE: return "";
636 case AL_LINEAR_DISTANCE: return "";
637 case AL_LOOPING: return "";
638 case AL_STREAMING: return "";
639 case AL_EXPONENT_DISTANCE_CLAMPED: return "";
640 case AL_CHANNELS: return "";
641 case AL_PAUSED: return "";
642 case AL_CONE_OUTER_GAIN: return "";
643 case AL_INVERSE_DISTANCE: return "";
644 case AL_ILLEGAL_ENUM: return "";
645 case AL_DIRECTION: return "";
646 // case AL_INVALID_OPERATION: return "";
647 case AL_ORIENTATION: return "";
648 case AL_FORMAT_STEREO8: return "";
649 case AL_CONE_OUTER_ANGLE: return "";
650 case AL_DOPPLER_VELOCITY: return "";
651 case AL_RENDERER: return "";
652 case AL_SAMPLE_OFFSET: return "";
653 case AL_FORMAT_STEREO16: return "";
654 case AL_SEC_OFFSET: return "";
655 case AL_POSITION: return "";
656 case AL_PENDING: return "";
657 case AL_UNUSED: return "";
658 case AL_INVALID_VALUE: return "";
659 // case AL_NONE: return "";
660 case AL_BUFFER: return "";
661 case AL_BUFFERS_PROCESSED: return "";
662 case AL_VELOCITY: return "";
663 case AL_DOPPLER_FACTOR: return "";
664 case AL_MAX_GAIN: return "";
665 case AL_SPEED_OF_SOUND: return "";
666 case AL_UNDETERMINED: return "";
667 case AL_EXTENSIONS: return "";
668 case AL_EXPONENT_DISTANCE: return "";
669 case AL_INVALID: return "";
670 case AL_VERSION: return "";
671 case AL_INITIAL: return "";
672 case AL_BUFFERS_QUEUED: return "";
673 case AL_BITS: return "";
674 case AL_CONE_INNER_ANGLE: return "";
675 case AL_SOURCE_RELATIVE: return "";
676 case AL_SOURCE_TYPE: return "";
677 case AL_LINEAR_DISTANCE_CLAMPED: return "";
678 case AL_FORMAT_MONO16: return "";
679 // case AL_FALSE: return "";
680 case AL_INVALID_NAME: return "";
681 default: return "0x"+Integer.toHexString(state);
682 }
683 } */
684
685}
static int getALFormat(final AudioFormat audioFormat, final AL al, final ALExt alExt)
Returns a compatible AL buffer format given the AudioFormat, which determines the AL channel layout a...
Definition: ALHelpers.java:114
static final String ALC_EXT_debug
Definition: ALHelpers.java:58
static final String alChannelLayoutName(final int alChannelLayout)
Returns the readable name of the given AL channel layout.
Definition: ALHelpers.java:411
static final String AL_SOFT_events
Definition: ALHelpers.java:47
static final String AL_EXT_DOUBLE
Definition: ALHelpers.java:51
static final String ALC_EXT_thread_local_context
Definition: ALHelpers.java:53
static final int sizeOfALSampleType(final int alSampleType)
Returns the byte size of the given AL sample type.
Definition: ALHelpers.java:532
static final String ALC_ENUMERATION_EXT
Definition: ALHelpers.java:55
static final String AL_SOFT_buffer_samples
openal-soft >= 1.18.0
Definition: ALHelpers.java:45
static int getALFormat(final AudioFormat audioFormat, final AL al, final ALExt alExt, final boolean hasSOFTBufferSamples, final boolean hasEXTMcFormats, final boolean hasEXTFloat32, final boolean hasEXTDouble)
Returns a compatible AL buffer format given the AudioFormat, which determines the AL channel layout a...
Definition: ALHelpers.java:151
static final String ALC_ENUMERATE_ALL_EXT
Definition: ALHelpers.java:56
static final int getALChannelLayoutChannelCount(final int alChannelLayout)
Returns the channel count of the given AL channel layout.
Definition: ALHelpers.java:427
static final int getALFormat(final int alChannelLayout, final int alSampleType, final AL al, final ALExt alExt)
Returns a compatible AL buffer format given the AL channel layout and AL sample type.
Definition: ALHelpers.java:190
static final String alSampleTypeName(final int alSampleType)
Returns the readable name of the given AL sample type.
Definition: ALHelpers.java:475
static final boolean isALSampleTypeSigned(final int alSampleType)
Returns whether the given AL sample type is signed.
Definition: ALHelpers.java:492
static final boolean isALSampleTypeFixed(final int alSampleType)
Returns true if the given AL sample type is a fixed point (byte, short, int, ..) or false if a floati...
Definition: ALHelpers.java:512
static final String AL_EXT_MCFORMATS
Definition: ALHelpers.java:49
static final String alSourceStateString(final int sourceState)
Returns given ALConstants#AL_SOURCE_STATE AL#alGetSourcei(int, int, int[], int)} value as a string.
Definition: ALHelpers.java:600
static final int samplesToByteCount(int sampleCount, final int alChannelLayout, final int alSampleType)
Definition: ALHelpers.java:558
static final String AL_EXT_FLOAT32
Definition: ALHelpers.java:50
static final String AL_EXT_debug
Definition: ALHelpers.java:59
static final String ALC_SOFT_system_events
Definition: ALHelpers.java:60
static AudioFormat getAudioFormat(final int alChannelLayout, final int alSampleType, final int alFormat, final int sampleRate, final int sampleSize)
Returns a compatible AudioFormat based on given OpenAL channel-layout, sample-type and format,...
Definition: ALHelpers.java:75
static final int getALFormat(final int alChannelLayout, final int alSampleType, final AL al, final ALExt alExt, final boolean hasSOFTBufferSamples, final boolean hasEXTMcFormats, final boolean hasEXTFloat32, final boolean hasEXTDouble)
Returns a compatible AL buffer format given the AL channel layout and AL sample type.
Definition: ALHelpers.java:225
static final int getDefaultALChannelLayout(final int channelCount)
Returns the default AL channel layout matching the given channel count, or ALConstants#AL_NONE.
Definition: ALHelpers.java:395
static final int bytesToSampleCount(final int byteCount, final int alChannelLayout, final int alSampleType)
Definition: ALHelpers.java:595
static final int getALSampleType(final int sampleSize, final boolean signed, final boolean fixedP)
Returns the AL sample type matching the given audio type attributes, or ALConstants#AL_NONE.
Definition: ALHelpers.java:446
static final int AL_NONE
Define "AL_NONE" with expression '0', CType: int.
boolean alIsBufferFormatSupportedSOFT(int format)
Entry point (through function pointer) to C language function: ALboolean alIsBufferFormatSupportedS...
boolean alIsExtensionPresent(String extname)
Entry point (through function pointer) to C language function: ALboolean alIsExtensionPresent(const...