JOAL v2.6.0-rc-20250706
JOAL, OpenAL® API Binding for Java™ (public API).
ALCSystemEventTest.java
Go to the documentation of this file.
1package com.jogamp.openal.test.manual;
2
3import com.jogamp.openal.*;
4import com.jogamp.openal.util.ALHelpers;
5
6import java.io.IOException;
7import java.time.Duration;
8import java.util.*;
9import java.util.concurrent.ExecutorService;
10import java.util.concurrent.Executors;
11
12import static com.jogamp.openal.ALCConstants.*;
13import static com.jogamp.openal.ALConstants.AL_FORMAT_MONO8;
14import static com.jogamp.openal.ALExtConstants.*;
15
16/**
17 * Testing the OpenAL-Soft System Event Extension.
18 */
19public class ALCSystemEventTest {
20
21 public static class ALCDeviceMetadata {
22 public final String deviceIdentifier;
23 public final String deviceName;
24
25 public ALCDeviceMetadata(final String deviceIdentifier, final String deviceName) {
26 this.deviceIdentifier = deviceIdentifier;
27 this.deviceName = deviceName;
28 }
29 }
30
31 public static void main(final String[] args) throws IOException, InterruptedException {
32 final ALC alc = ALFactory.getALC();
33
35 System.err.println("Current alc implementation has no "+ALHelpers.ALC_SOFT_system_events+" extension");
36 return;
37 }
38
40 System.err.println(jv.toString(alc));
41 System.err.println("-----------------------------------------------------------------------------------------------------");
42
43 final ALExt alExt = ALFactory.getALExt();
44 final ExecutorService executorService = Executors.newSingleThreadExecutor();
45
46 final boolean enumerationExtIsPresent = alc.alcEnumerationExtIsPresent();
47 final boolean enumerateAllExtIsPresent = alc.alcEnumerateAllExtIsPresent();
48 final boolean noEnumerateExt = !enumerationExtIsPresent && !enumerateAllExtIsPresent;
49
50 final Map<ALCdevice, ALCDeviceMetadata> playbackDeviceNameEnumerationExt = new HashMap<>();
51 final Map<ALCdevice, ALCDeviceMetadata> captureDeviceNameEnumerationExt = new HashMap<>();
52
53 if (enumerationExtIsPresent) {
54 for (final String deviceIdentifier : alc.alcGetDeviceSpecifiers()) {
55 final ALCdevice device = alc.alcOpenDevice(deviceIdentifier);
56 String deviceName = alc.alcGetString(device, ALC_DEVICE_SPECIFIER);
57 playbackDeviceNameEnumerationExt.put(device, new ALCDeviceMetadata(deviceIdentifier, deviceName));
58 }
59 for (final String deviceIdentifier : alc.alcGetCaptureDeviceSpecifiers()) {
60 final ALCdevice device = alc.alcCaptureOpenDevice(deviceIdentifier, 1, AL_FORMAT_MONO8, 1);
61 String deviceName = alc.alcGetString(device, ALC_CAPTURE_DEVICE_SPECIFIER);
62 captureDeviceNameEnumerationExt.put(device, new ALCDeviceMetadata(deviceIdentifier, deviceName));
63 }
64 }
65
66 final Map<ALCdevice, ALCDeviceMetadata> playbackDeviceNameEnumerateAllExt = new HashMap<>();
67
68 if (enumerateAllExtIsPresent) {
69 for (final String deviceIdentifier : alc.alcGetAllDeviceSpecifiers()) {
70 final ALCdevice device = alc.alcOpenDevice(deviceIdentifier);
71 String deviceName = alc.alcGetString(device, ALCConstants.ALC_ALL_DEVICES_SPECIFIER);
72 playbackDeviceNameEnumerateAllExt.put(device, new ALCDeviceMetadata(deviceIdentifier, deviceName));
73 }
74 }
75
76 final ALExt.ALCEVENTPROCTYPESOFT systemEventsCallback = (eventType, deviceType, device, message, userParam) -> {
77 System.err.println("Event[eventType: "+Integer.toHexString(eventType)+
78 ", deviceType: "+Integer.toHexString(deviceType)+ ", device: "+device+ ", message: "+message+
79 ", userParam: "+userParam+"]");
80 switch (eventType) {
81 case ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT: {
82 switch (deviceType) {
83 case ALC_PLAYBACK_DEVICE_SOFT: {
84 executorService.submit(() -> {
85 System.err.println("Default playback device are changed");
86 if (enumerateAllExtIsPresent) {
87 System.err.println("New default playback device name (With "+
89 alc.alcGetString(null, ALC_DEFAULT_ALL_DEVICES_SPECIFIER)
90 );
91 }
92 if (enumerationExtIsPresent) {
93 System.err.println("New default playback device name (With "+
95 alc.alcGetString(null, ALC_DEFAULT_DEVICE_SPECIFIER)
96 );
97 }
98 if (noEnumerateExt) {
99 System.err.println("Unable to retrieve default playback device name ("+
101 ALHelpers.ALC_ENUMERATION_EXT+" are missing)"
102 );
103 }
104 });
105 break;
106 }
107 case ALC_CAPTURE_DEVICE_SOFT: {
108 executorService.submit(() -> {
109 System.err.println("Default capture device are changed");
110 if (enumerationExtIsPresent) {
111 System.err.println("New default capture device name: "+
112 alc.alcGetString(null, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)
113 );
114 } else {
115 System.err.println("Unable to retrieve default capture device name ("+
116 ALHelpers.ALC_ENUMERATION_EXT+" is missing)"
117 );
118 }
119 });
120 break;
121 }
122 }
123 }
124 case ALC_EVENT_TYPE_DEVICE_ADDED_SOFT: {
125 switch (deviceType) {
126 case ALC_PLAYBACK_DEVICE_SOFT: {
127 executorService.submit(() -> {
128 System.err.println("Playback device are added");
129 if (enumerateAllExtIsPresent) {
130 for (final String deviceIdentifier : alc.alcGetAllDeviceSpecifiers()) {
131 if (playbackDeviceNameEnumerateAllExt.values().stream()
132 .map(m -> m.deviceName.equals(deviceIdentifier))
133 .findAny()
134 .isPresent()
135 ) continue;
136
137 final ALCdevice currentDevice = alc.alcOpenDevice(deviceIdentifier);
138 final String deviceName = alc.alcGetString(currentDevice, ALCConstants.ALC_ALL_DEVICES_SPECIFIER);
139 System.err.println("New playback device name (With "+
141 deviceName
142 );
143 playbackDeviceNameEnumerateAllExt.put(currentDevice, new ALCDeviceMetadata(deviceIdentifier, deviceName));
144 }
145 }
146 if (enumerationExtIsPresent) {
147 for (final String deviceIdentifier : alc.alcGetDeviceSpecifiers()) {
148 if (playbackDeviceNameEnumerationExt.values().stream()
149 .map(m -> m.deviceName.equals(deviceIdentifier))
150 .findAny()
151 .isPresent()
152 ) continue;
153
154 final ALCdevice currentDevice = alc.alcOpenDevice(deviceIdentifier);
155 final String deviceName = alc.alcGetString(currentDevice, ALC_DEVICE_SPECIFIER);
156 System.err.println("New playback device name (With "+
158 deviceName
159 );
160 playbackDeviceNameEnumerationExt.put(currentDevice, new ALCDeviceMetadata(deviceIdentifier, deviceName));
161 }
162 }
163 if (noEnumerateExt) {
164 System.err.println("Unable to retrieve new playback device name ("+
166 ALHelpers.ALC_ENUMERATION_EXT+" are missing)"
167 );
168 }
169 });
170 break;
171 }
172 case ALC_CAPTURE_DEVICE_SOFT: {
173 executorService.submit(() -> {
174 System.err.println("Capture device are added");
175 if (enumerationExtIsPresent) {
176 for (final String deviceIdentifier : alc.alcGetCaptureDeviceSpecifiers()) {
177 if (captureDeviceNameEnumerationExt.values().stream()
178 .map(m -> m.deviceName.equals(deviceIdentifier))
179 .findAny()
180 .isPresent()
181 ) continue;
182
183 final ALCdevice currentDevice = alc.alcCaptureOpenDevice(deviceIdentifier, 1, AL_FORMAT_MONO8, 1);
184 final String deviceName = alc.alcGetString(currentDevice, ALC_CAPTURE_DEVICE_SPECIFIER);
185 System.err.println("New capture device name (With "+
187 deviceName
188 );
189 captureDeviceNameEnumerationExt.put(currentDevice, new ALCDeviceMetadata(deviceIdentifier, deviceName));
190 }
191 } else {
192 System.err.println("Unable to retrieve new capture device name ("+
193 ALHelpers.ALC_ENUMERATION_EXT+" is missing)"
194 );
195 }
196 });
197 break;
198 }
199 }
200 }
201 case ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT: {
202 switch (deviceType) {
203 case ALC_PLAYBACK_DEVICE_SOFT: {
204 executorService.submit(() -> {
205 System.err.println("Playback device are removed");
206 if (enumerateAllExtIsPresent) {
207 final List<String> devicesNames = Arrays.asList(alc.alcGetAllDeviceSpecifiers());
208 final List<ALCdevice> devicesToRemove = new ArrayList<>();
209 for (final Map.Entry<ALCdevice, ALCDeviceMetadata> deviceEntry : playbackDeviceNameEnumerateAllExt.entrySet()) {
210 if (!devicesNames.contains(deviceEntry.getValue().deviceIdentifier)) continue;
211
212 System.err.println("Removed playback device name (With "+
214 deviceEntry.getValue().deviceName
215 );
216 devicesToRemove.add(deviceEntry.getKey());
217 }
218 devicesToRemove.forEach(d -> {
219 alc.alcCloseDevice(d);
220 playbackDeviceNameEnumerateAllExt.remove(d);
221 });
222 }
223 if (enumerationExtIsPresent) {
224 final List<String> devicesNames = Arrays.asList(alc.alcGetDeviceSpecifiers());
225 final List<ALCdevice> devicesToRemove = new ArrayList<>();
226 for (final Map.Entry<ALCdevice, ALCDeviceMetadata> deviceEntry : playbackDeviceNameEnumerationExt.entrySet()) {
227 if (!devicesNames.contains(deviceEntry.getValue().deviceIdentifier)) continue;
228
229 System.err.println("Removed playback device name (With "+
231 deviceEntry.getValue().deviceName
232 );
233 devicesToRemove.add(deviceEntry.getKey());
234 }
235 devicesToRemove.forEach(d -> {
236 alc.alcCloseDevice(d);
237 playbackDeviceNameEnumerationExt.remove(d);
238 });
239 }
240 if (noEnumerateExt) {
241 System.err.println("Unable to retrieve new playback device name ("+
243 ALHelpers.ALC_ENUMERATION_EXT+" are missing)"
244 );
245 }
246 });
247 break;
248 }
249 case ALC_CAPTURE_DEVICE_SOFT: {
250 executorService.submit(() -> {
251 System.err.println("Capture device are removed");
252 if (enumerationExtIsPresent) {
253 final List<String> devicesNames = Arrays.asList(alc.alcGetCaptureDeviceSpecifiers());
254 final List<ALCdevice> devicesToRemove = new ArrayList<>();
255 for (final Map.Entry<ALCdevice, ALCDeviceMetadata> deviceEntry : captureDeviceNameEnumerationExt.entrySet()) {
256 if (!devicesNames.contains(deviceEntry.getValue().deviceIdentifier)) continue;
257
258 System.err.println("Removed capture device name (With "+
260 deviceEntry.getValue().deviceName
261 );
262 devicesToRemove.add(deviceEntry.getKey());
263 }
264 devicesToRemove.forEach(d -> {
266 captureDeviceNameEnumerationExt.remove(d);
267 });
268 } else {
269 System.err.println("Unable to retrieve new capture device name ("+
270 ALHelpers.ALC_ENUMERATION_EXT+" is missing)"
271 );
272 }
273 });
274 break;
275 }
276 }
277 }
278 }
279 };
280
281 alExt.alcEventControlSOFT(3, new int[] {
282 ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT,
283 ALC_EVENT_TYPE_DEVICE_ADDED_SOFT,
284 ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT
285 }, 0, true);
286 alExt.alcEventCallbackSOFT(systemEventsCallback, null);
287
288 Thread.sleep(Duration.ofMinutes(2).toMillis());
289
290 executorService.shutdown();
291
292 alExt.alcEventControlSOFT(3, new int[] {
293 ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT,
294 ALC_EVENT_TYPE_DEVICE_ADDED_SOFT,
295 ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT
296 }, 0, false);
297 alExt.alcEventCallbackSOFT(null, null);
298
299 if (enumerationExtIsPresent) {
300 for (final ALCdevice device : playbackDeviceNameEnumerationExt.keySet()) {
301 alc.alcCloseDevice(device);
302 }
303 for (final ALCdevice device : captureDeviceNameEnumerationExt.keySet()) {
304 alc.alcCaptureCloseDevice(device);
305 }
306 }
307
308 if (enumerateAllExtIsPresent) {
309 for (final ALCdevice device : playbackDeviceNameEnumerateAllExt.keySet()) {
310 alc.alcCloseDevice(device);
311 }
312 }
313 }
314}
This class provides factory methods for generating AL and ALC objects.
Definition: ALFactory.java:62
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.
ALCDeviceMetadata(final String deviceIdentifier, final String deviceName)
Testing the OpenAL-Soft System Event Extension.
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_ALL_DEVICES_SPECIFIER
Define "ALC_ALL_DEVICES_SPECIFIER" with expression '0x1013', CType: int.
boolean alcEnumerationExtIsPresent()
Specify if ALC_ENUMERATION_EXT is present.
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.
String alcGetString(ALCdevice device, int param)
Entry point (through function pointer) to C language function: const ALCchar * alcGetString(ALCdevi...
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 alcCaptureOpenDevice(String devicename, int frequency, int format, int buffersize)
Entry point (through function pointer) to C language function: ALCdevice * alcCaptureOpenDevice(con...
java.lang.String[] alcGetCaptureDeviceSpecifiers()
Fetches the names of the available ALC capture device specifiers.
boolean alcIsExtensionPresent(ALCdevice device, String extname)
Entry point (through function pointer) to C language function: ALCboolean alcIsExtensionPresent(ALC...
ALCdevice alcOpenDevice(String devicename)
Entry point (through function pointer) to C language function: ALCdevice * alcOpenDevice(const ALCc...
boolean alcCaptureCloseDevice(ALCdevice device)
Entry point (through function pointer) to C language function: ALCboolean alcCaptureCloseDevice(ALC...
JavaCallback interface: ALCEVENTPROCTYPESOFT -> void (*ALCEVENTPROCTYPESOFT)(ALCenum eventType,...
Definition: ALExt.java:41
boolean alcEventControlSOFT(int count, IntBuffer events, boolean enable)
Entry point (through function pointer) to C language function: ALCboolean alcEventControlSOFT(ALCsi...
void alcEventCallbackSOFT(ALCEVENTPROCTYPESOFT callback, Object userParam)
Entry point (through function pointer) to C language function: void alcEventCallbackSOFT(ALCEVENTPR...