JOAL v2.6.0-rc-20250712
JOAL, OpenAL® API Binding for Java™ (public API).
JoalVersion.java
Go to the documentation of this file.
1/**
2 * Copyright 2013-2023 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.openal;
30
31import com.jogamp.common.GlueGenVersion;
32
33import com.jogamp.common.os.Platform;
34import com.jogamp.common.util.VersionUtil;
35import com.jogamp.common.util.JogampVersion;
36import com.jogamp.openal.util.ALHelpers;
37
38import java.util.jar.Manifest;
39
40public class JoalVersion extends JogampVersion {
41 protected static volatile JoalVersion jogampCommonVersionInfo;
42
43 protected JoalVersion(final String packageName, final Manifest mf) {
44 super(packageName, mf);
45 }
46
47 public static JoalVersion getInstance() {
48 if(null == jogampCommonVersionInfo) { // volatile: ok
49 synchronized(JoalVersion.class) {
50 if( null == jogampCommonVersionInfo ) {
51 final String packageName = "com.jogamp.openal";
52 final Manifest mf = VersionUtil.getManifest(JoalVersion.class.getClassLoader(), packageName);
53 jogampCommonVersionInfo = new JoalVersion(packageName, mf);
54 }
55 }
56 }
58 }
59
60 public StringBuilder getBriefOSALBuildInfo(StringBuilder sb) {
61 if(null==sb) {
62 sb = new StringBuilder();
63 }
64 sb.append("OS: ").append(Platform.getOSName()).append(", version ").append(Platform.getOSVersion()).append(", arch ").append(Platform.getArchName());
65 sb.append(Platform.getNewline());
66 sb.append("JOAL GIT sha1 ").append(getImplementationCommit());
67 sb.append(Platform.getNewline());
68 return sb;
69 }
70
71 /**
72 * Return {@link JogampVersion} package information and AL informal strings.
73 * <p>
74 * The given {@link ALC} is being used and {@Link ALCdevice} and {@link ALCcontext} are allocated,
75 * made current and finally being released.
76 * </p>
77 * @param alc static {@link ALC} instance
78 * @param sb optional StringBuffer to be reused
79 */
80 public StringBuilder toString(final ALC alc, StringBuilder sb) {
81 sb = super.toString(sb).append(Platform.getNewline());
82 getALStrings(alc, sb);
83 return sb;
84 }
85
86 /**
87 * Return {@link JogampVersion} package information and AL informal strings.
88 * <p>
89 * The given {@link ALC} is being used and {@Link ALCdevice} and {@link ALCcontext} are allocated,
90 * made current and finally being released.
91 * </p>
92 * @param alc static {@link ALC} instance
93 */
94 public String toString(final ALC alc) {
95 return toString(alc, null).toString();
96 }
97
98 /**
99 * Return AL informal strings.
100 * <p>
101 * The given {@link ALC} is being used and {@Link ALCdevice} and {@link ALCcontext} are allocated,
102 * made current and finally being released.
103 * </p>
104 * @param alc static {@link ALC} instance
105 */
106 public static StringBuilder getALStrings(final ALC alc, StringBuilder sb) {
107 if( null == sb ) {
108 sb = new StringBuilder();
109 }
110 if( null == alc ) {
111 sb.append("ALC null");
112 return sb;
113 }
114 final ALCcontext initialContext = alc.alcGetCurrentContext();
115
116 final ALCcontext context;
117 final ALCdevice device;
118 if( null == initialContext) {
119 device = alc.alcOpenDevice(null);
120 context = alc.alcCreateContext(device, null);
121 alc.alcMakeContextCurrent(context);
122 } else {
123 context = initialContext;
124 device = alc.alcGetContextsDevice(initialContext);
125 }
126 final AL al = ALFactory.getAL(); // valid after makeContextCurrent(..)
127 final ALVersion alv = new ALVersion(al);
128 final ALExt alExt = ALFactory.getALExt();
129
130 alv.toString(true, sb);
131 sb.append("AL_EXTENSIONS ").append(al.alGetString(ALConstants.AL_EXTENSIONS));
132 sb.append(Platform.getNewline());
133 final boolean enumerationExtIsPresent = alc.alcEnumerationExtIsPresent();
134 final boolean enumerateAllExtIsPresent = alc.alcEnumerateAllExtIsPresent();
135 final String enumExtAvailInfo = "(enumExt[def "+enumerationExtIsPresent+", all "+enumerateAllExtIsPresent+"])";
136 final boolean softEventsIsPresent = alc.alcSoftSystemEventsIsPresent();
137 {
138 final int[] iversion = { 0, 0 };
139 alc.alcGetIntegerv(device, ALCConstants.ALC_MAJOR_VERSION, 1, iversion, 0);
140 alc.alcGetIntegerv(device, ALCConstants.ALC_MINOR_VERSION, 1, iversion, 1);
141 sb.append("ALC_VERSION ").append(iversion[0]).append(".").append(iversion[1]);
142 sb.append(Platform.getNewline());
143 if (!enumerationExtIsPresent && !enumerateAllExtIsPresent) {
144 sb.append("ALC_DEF_OUTPUT Unknown ").append(enumExtAvailInfo);
145 sb.append(Platform.getNewline());
146 } else {
147 if (enumerationExtIsPresent) {
148 sb.append("ALC_DEF_OUTPUT (With " + ALHelpers.ALC_ENUMERATION_EXT + ") ")
150 sb.append(Platform.getNewline());
151 }
152 if (enumerateAllExtIsPresent) {
153 sb.append("ALC_DEF_OUTPUT (With " + ALHelpers.ALC_ENUMERATE_ALL_EXT + ") ")
155 sb.append(Platform.getNewline());
156 }
157 }
158 if (enumerationExtIsPresent) {
159 sb.append("ALC_DEF_CAPTURE ").append(alc.alcGetString(device, ALCConstants.ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
160 } else {
161 sb.append("ALC_DEF_CAPTURE Unknown ").append(enumExtAvailInfo);
162 }
163 sb.append(Platform.getNewline());
164 sb.append(ALHelpers.ALC_SOFT_system_events).append(" ")
165 .append(softEventsIsPresent ? "supported" : "unsupported");
166 sb.append(Platform.getNewline());
167 if (softEventsIsPresent) {
168 class EventType {
169 public final String key;
170 public final int value;
171 EventType(final String k, final int i) { key = k; value = i; }
172 }
173 final EventType[] events = {
174 new EventType("ALC_EVENT_TYPE_DEVICE_ADDED_SOFT", ALExtConstants.ALC_EVENT_TYPE_DEVICE_ADDED_SOFT),
175 new EventType("ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT", ALExtConstants.ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT),
176 new EventType("ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT", ALExtConstants.ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT) };
177 for (final EventType event : events) {
178 final int playbackSupported = alExt.alcEventIsSupportedSOFT(event.value, ALExtConstants.ALC_PLAYBACK_DEVICE_SOFT);
179 sb.append(" ").append(event.key).append(" event for playback devices is ")
180 .append(playbackSupported == ALExtConstants.ALC_EVENT_SUPPORTED_SOFT ? "supported" : "unsupported");
181 sb.append(Platform.getNewline());
182 final int captureSupported = alExt.alcEventIsSupportedSOFT(event.value, ALExtConstants.ALC_CAPTURE_DEVICE_SOFT);
183 sb.append(" ").append(event.key).append(" event for capture devices is ")
184 .append(captureSupported == ALExtConstants.ALC_EVENT_SUPPORTED_SOFT ? "supported" : "unsupported");
185 sb.append(Platform.getNewline());
186 }
187 }
188 }
189
190 if( null == initialContext ) {
191 alc.alcMakeContextCurrent(null);
192 alc.alcDestroyContext(context);
193 alc.alcCloseDevice(device);
194 }
195
196 devicesToString(sb, alc);
197 return sb;
198 }
199
200 private static boolean checkALCError(final ALC alc, final ALCdevice device, final String msg)
201 {
202 final int error = alc.alcGetError(device);
203 if (error != ALCConstants.ALC_NO_ERROR) {
204 System.err.printf("ALC Error 0x%x occurred: '%s' while '%s'%n", error, alc.alcGetString(device, error), msg);
205 return true;
206 }
207 return false;
208 }
209
210 public static void deviceToString(final StringBuilder sb, final ALC alc, final String devName, final boolean isInput, final String defOutDeviceName, final String defInDeviceName) {
211 if( isInput ) {
212 final boolean isDefault = devName.equals(defInDeviceName);
213 sb.append(" "+devName+", input, default "+isDefault+System.lineSeparator());
214 } else {
215 final boolean isDefault = devName.equals(defOutDeviceName);
216 final String defStr = isDefault ? "default " : "";
217 final String inOutStr = "output";
218 final int mixerFrequency, mixerRefresh, monoSourceCount, stereoSourceCount;
219 final int[] val = { 0 };
220 final ALCcontext initialContext = alc.alcGetCurrentContext();
221 final ALCdevice initialDevice = initialContext != null ? alc.alcGetContextsDevice(initialContext) : null;
222 final ALCdevice d = alc.alcOpenDevice(devName);
223 if( null == d ) {
224 System.err.println("Error: Failed to open "+defStr+inOutStr+" device "+devName);
225 return;
226 }
227 final ALCcontext c = alc.alcCreateContext(d, null);
228 if( null == c ) {
229 System.err.println("Error: Failed to create context for "+defStr+inOutStr+" device "+devName);
230 alc.alcCloseDevice(d);
231 return;
232 }
233 if( !alc.alcMakeContextCurrent(c) ) {
234 System.err.println("Error: Failed to make context current for "+defStr+inOutStr+" device "+devName);
235 checkALCError(alc, d, "alcMakeContextCurrent");
236 alc.alcDestroyContext(c);
237 alc.alcCloseDevice(d);
238 return;
239 }
240
241 {
242 val[0] = 0;
243 alc.alcGetIntegerv(d, ALCConstants.ALC_FREQUENCY, 1, val, 0);
244 if( checkALCError(alc, d, "read ALC_FREQUENCY") ) {
245 mixerFrequency = -1;
246 } else {
247 mixerFrequency = val[0];
248 }
249 }
250 {
251 val[0] = 0;
252 alc.alcGetIntegerv(d, ALCConstants.ALC_REFRESH, 1, val, 0);
253 if( checkALCError(alc, d, "read ALC_REFRESH") ) {
254 mixerRefresh = -1;
255 } else {
256 mixerRefresh = val[0];
257 }
258 }
259 {
260 val[0] = 0;
262 if( checkALCError(alc, d, "read ALC_MONO_SOURCES") ) {
263 monoSourceCount = -1;
264 } else {
265 monoSourceCount = val[0];
266 }
267 }
268 {
269 val[0] = 0;
271 if( checkALCError(alc, d, "read ALC_STEREO_SOURCES") ) {
272 stereoSourceCount = -1;
273 } else {
274 stereoSourceCount = val[0];
275 }
276 }
277 sb.append(" "+devName+", "+inOutStr+", default "+isDefault+", mixer[freq "+mixerFrequency+", refresh "+mixerRefresh+
278 " (min latency "+(1000f/mixerRefresh)+" ms)], sources[mono "+monoSourceCount+", stereo "+stereoSourceCount+"]"+
279 System.lineSeparator());
280
281 if( null != initialContext ) {
282 alc.alcMakeContextCurrent(initialContext);
283 if( initialContext.getDirectBufferAddress() != c.getDirectBufferAddress() ) {
284 alc.alcDestroyContext(c);
285 }
286 } else {
287 alc.alcMakeContextCurrent(null);
288 alc.alcDestroyContext(c);
289 }
290 if( initialDevice == null || initialDevice.getDirectBufferAddress() != d.getDirectBufferAddress() ) {
291 alc.alcCloseDevice(d);
292 }
293 }
294 }
295
296 public static void devicesToString(final StringBuilder sb, final ALC alc) {
297 final boolean enumerationExtIsPresent = alc.alcEnumerationExtIsPresent();
298 final boolean enumerateAllExtIsPresent = alc.alcEnumerateAllExtIsPresent();
299 final String enumExtAvailInfo = "(enumExt[def "+enumerationExtIsPresent+", all "+enumerateAllExtIsPresent+"])";
300
301 if (!enumerationExtIsPresent && !enumerateAllExtIsPresent) {
302 sb.append("No output devices infos available ").append(enumExtAvailInfo);
303 } else {
304 if (enumerateAllExtIsPresent) {
305 final String defOutAllDeviceName = alc.alcGetString(null, ALCConstants.ALC_DEFAULT_ALL_DEVICES_SPECIFIER);
306 sb.append("Output devices (With " + ALHelpers.ALC_ENUMERATE_ALL_EXT + "):" + System.lineSeparator());
307 {
308 final String[] outDevices = alc.alcGetAllDeviceSpecifiers();
309 if (null != outDevices) {
310 for (final String devName : outDevices) {
311 deviceToString(sb, alc, devName, false, defOutAllDeviceName, null);
312 }
313 }
314 }
315 }
316 if (enumerationExtIsPresent) {
317 final String defOutDeviceName = alc.alcGetString(null, ALCConstants.ALC_DEFAULT_DEVICE_SPECIFIER);
318 sb.append("Output devices (With " + ALHelpers.ALC_ENUMERATION_EXT + "):" + System.lineSeparator());
319 {
320 final String[] outDevices = alc.alcGetDeviceSpecifiers();
321 if (null != outDevices) {
322 for (final String devName : outDevices) {
323 deviceToString(sb, alc, devName, false, defOutDeviceName, null);
324 }
325 }
326 }
327 }
328 }
329 if (!enumerationExtIsPresent) {
330 sb.append("No capture devices infos available ").append(enumExtAvailInfo);
331 } else {
332 final String defInDeviceName = alc.alcGetString(null, ALCConstants.ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
333 sb.append("Capture devices:" + System.lineSeparator());
334 {
335 final String[] inDevices = alc.alcGetCaptureDeviceSpecifiers();
336 if (null != inDevices) {
337 for (final String devName : inDevices) {
338 deviceToString(sb, alc, devName, true, null, defInDeviceName);
339 }
340 }
341 }
342 }
343 }
344
345 public static void main(final String args[]) {
346 System.err.println(VersionUtil.getPlatformInfo());
347 System.err.println(GlueGenVersion.getInstance());
348 // System.err.println(NativeWindowVersion.getInstance());
349 // System.err.println(JoalVersion.getInstance());
350 System.err.println(JoalVersion.getInstance().toString(ALFactory.getALC()));
351
352 }
353}
354
final long getDirectBufferAddress()
Returns the native address of the underlying native ByteBuffer getBuffer().
Definition: ALCcontext.java:62
final long getDirectBufferAddress()
Returns the native address of the underlying native ByteBuffer getBuffer().
Definition: ALCdevice.java:62
This class provides factory methods for generating AL and ALC objects.
Definition: ALFactory.java:62
static AL getAL()
Get the default AL object.
Definition: ALFactory.java:122
static ALExt getALExt()
Get the default ALExt object.
Definition: ALFactory.java:150
static ALC getALC()
Get the default ALC object.
Definition: ALFactory.java:136
static JoalVersion getInstance()
StringBuilder toString(final ALC alc, StringBuilder sb)
Return JogampVersion package information and AL informal strings.
JoalVersion(final String packageName, final Manifest mf)
StringBuilder getBriefOSALBuildInfo(StringBuilder sb)
static void deviceToString(final StringBuilder sb, final ALC alc, final String devName, final boolean isInput, final String defOutDeviceName, final String defInDeviceName)
static volatile JoalVersion jogampCommonVersionInfo
String toString(final ALC alc)
Return JogampVersion package information and AL informal strings.
static void devicesToString(final StringBuilder sb, final ALC alc)
static StringBuilder getALStrings(final ALC alc, StringBuilder sb)
Return AL informal strings.
static void main(final String args[])
static final String ALC_ENUMERATION_EXT
Definition: ALHelpers.java:55
static final String ALC_ENUMERATE_ALL_EXT
Definition: ALHelpers.java:56
static final String ALC_SOFT_system_events
Definition: ALHelpers.java:60
static final int ALC_MAJOR_VERSION
Define "ALC_MAJOR_VERSION" with expression '0x1000', CType: int.
static final int ALC_STEREO_SOURCES
Define "ALC_STEREO_SOURCES" with expression '0x1011', CType: int.
static final int ALC_MINOR_VERSION
Define "ALC_MINOR_VERSION" with expression '0x1001', CType: int.
static final int ALC_FREQUENCY
Define "ALC_FREQUENCY" with expression '0x1007', CType: int.
static final int ALC_NO_ERROR
Define "ALC_NO_ERROR" with expression '0', CType: int.
static final int ALC_MONO_SOURCES
Define "ALC_MONO_SOURCES" with expression '0x1010', CType: int.
static final int ALC_DEFAULT_DEVICE_SPECIFIER
Define "ALC_DEFAULT_DEVICE_SPECIFIER" with expression '0x1004', CType: int.
static final int ALC_REFRESH
Define "ALC_REFRESH" with expression '0x1008', CType: int.
static final int ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
Define "ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER" with expression '0x311', CType: int.
static final int ALC_DEFAULT_ALL_DEVICES_SPECIFIER
Define "ALC_DEFAULT_ALL_DEVICES_SPECIFIER" with expression '0x1012', CType: int.
boolean alcEnumerationExtIsPresent()
Specify if ALC_ENUMERATION_EXT is present.
void alcDestroyContext(ALCcontext context)
Entry point (through function pointer) to C language function: void alcDestroyContext(ALCcontext * ...
boolean alcMakeContextCurrent(ALCcontext context)
Entry point (through function pointer) to C language function: ALCboolean alcMakeContextCurrent(ALC...
boolean alcSoftSystemEventsIsPresent()
Specify if ALC_SOFT_system_events is present.
ALCcontext alcGetCurrentContext()
Entry point (through function pointer) to C language function: ALCcontext * alcGetCurrentContext()
boolean alcEnumerateAllExtIsPresent()
Specify if ALC_ENUMERATE_ALL_EXT is present.
java.lang.String[] alcGetAllDeviceSpecifiers()
Fetches the names of the available ALC all capture device specifiers.
int alcGetError(ALCdevice device)
Entry point (through function pointer) to C language function: ALCenum alcGetError(ALCdevice * dev...
String alcGetString(ALCdevice device, int param)
Entry point (through function pointer) to C language function: const ALCchar * alcGetString(ALCdevi...
void alcGetIntegerv(ALCdevice device, int param, int size, IntBuffer values)
Entry point (through function pointer) to C language function: void alcGetIntegerv(ALCdevice * dev...
java.lang.String[] alcGetDeviceSpecifiers()
Fetches the names of the available ALC device specifiers.
boolean alcCloseDevice(ALCdevice device)
Entry point (through function pointer) to C language function: ALCboolean alcCloseDevice(ALCdevice ...
ALCdevice alcGetContextsDevice(ALCcontext context)
Entry point (through function pointer) to C language function: ALCdevice * alcGetContextsDevice(ALC...
java.lang.String[] alcGetCaptureDeviceSpecifiers()
Fetches the names of the available ALC capture device specifiers.
ALCdevice alcOpenDevice(String devicename)
Entry point (through function pointer) to C language function: ALCdevice * alcOpenDevice(const ALCc...
ALCcontext alcCreateContext(ALCdevice device, IntBuffer attrlist)
Entry point (through function pointer) to C language function: ALCcontext * alcCreateContext(ALCdev...
static final int AL_EXTENSIONS
Define "AL_EXTENSIONS" with expression '0xB004', CType: int.
static final int ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT
Define "ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT" with expression '0x19D6', CType: int.
static final int ALC_CAPTURE_DEVICE_SOFT
Define "ALC_CAPTURE_DEVICE_SOFT" with expression '0x19D5', CType: int.
static final int ALC_EVENT_TYPE_DEVICE_ADDED_SOFT
Define "ALC_EVENT_TYPE_DEVICE_ADDED_SOFT" with expression '0x19D7', CType: int.
static final int ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT
Define "ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT" with expression '0x19D8', CType: int.
static final int ALC_PLAYBACK_DEVICE_SOFT
Define "ALC_PLAYBACK_DEVICE_SOFT" with expression '0x19D4', CType: int.
static final int ALC_EVENT_SUPPORTED_SOFT
Define "ALC_EVENT_SUPPORTED_SOFT" with expression '0x19D9', CType: int.
int alcEventIsSupportedSOFT(int eventType, int deviceType)
Entry point (through function pointer) to C language function: ALCenum alcEventIsSupportedSOFT(ALCe...
String alGetString(int param)
Entry point (through function pointer) to C language function: const ALchar * alGetString(ALenum pa...