Don't force latency adjustment with PulseAudio
[openal-soft.git] / examples / openal-info.c
blob5af34bbcc9728beb7b67181de632755cf11b1df3
1 /*
2 * openal-info: Display information about ALC and AL.
4 * Idea based on glxinfo for OpenGL.
5 * Initial OpenAL version by Erik Hofman <erik@ehofman.com>.
6 * Further hacked by Sven Panne <sven.panne@aedion.de>.
7 * More work (clean up) by Chris Robinson <chris.kcat@gmail.com>.
9 */
11 #if HAVE_CONFIG_H
12 #include "config.h"
13 #endif
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
19 #include "AL/alc.h"
20 #include "AL/al.h"
21 #include "AL/alext.h"
23 #ifndef ALC_EXT_EFX
24 #define AL_FILTER_TYPE 0x8001
25 #define AL_EFFECT_TYPE 0x8001
26 #define AL_FILTER_NULL 0x0000
27 #define AL_FILTER_LOWPASS 0x0001
28 #define AL_FILTER_HIGHPASS 0x0002
29 #define AL_FILTER_BANDPASS 0x0003
30 #define AL_EFFECT_NULL 0x0000
31 #define AL_EFFECT_EAXREVERB 0x8000
32 #define AL_EFFECT_REVERB 0x0001
33 #define AL_EFFECT_CHORUS 0x0002
34 #define AL_EFFECT_DISTORTION 0x0003
35 #define AL_EFFECT_ECHO 0x0004
36 #define AL_EFFECT_FLANGER 0x0005
37 #define AL_EFFECT_FREQUENCY_SHIFTER 0x0006
38 #define AL_EFFECT_VOCAL_MORPHER 0x0007
39 #define AL_EFFECT_PITCH_SHIFTER 0x0008
40 #define AL_EFFECT_RING_MODULATOR 0x0009
41 #define AL_EFFECT_AUTOWAH 0x000A
42 #define AL_EFFECT_COMPRESSOR 0x000B
43 #define AL_EFFECT_EQUALIZER 0x000C
44 #define ALC_EFX_MAJOR_VERSION 0x20001
45 #define ALC_EFX_MINOR_VERSION 0x20002
46 #define ALC_MAX_AUXILIARY_SENDS 0x20003
47 #endif
48 ALvoid (AL_APIENTRY *p_alGenFilters)(ALsizei,ALuint*);
49 ALvoid (AL_APIENTRY *p_alDeleteFilters)(ALsizei,ALuint*);
50 ALvoid (AL_APIENTRY *p_alFilteri)(ALuint,ALenum,ALint);
51 ALvoid (AL_APIENTRY *p_alGenEffects)(ALsizei,ALuint*);
52 ALvoid (AL_APIENTRY *p_alDeleteEffects)(ALsizei,ALuint*);
53 ALvoid (AL_APIENTRY *p_alEffecti)(ALuint,ALenum,ALint);
55 static const int indentation = 4;
56 static const int maxmimumWidth = 79;
58 static void printChar(int c, int *width)
60 putchar(c);
61 *width = ((c == '\n') ? 0 : ((*width) + 1));
64 static void indent(int *width)
66 int i;
67 for(i = 0; i < indentation; i++)
68 printChar(' ', width);
71 static void printList(const char *header, char separator, const char *list)
73 int width = 0, start = 0, end = 0;
75 printf("%s:\n", header);
76 if(list == NULL || list[0] == '\0')
77 return;
79 indent(&width);
80 while(1)
82 if(list[end] == separator || list[end] == '\0')
84 if(width + end - start + 2 > maxmimumWidth)
86 printChar('\n', &width);
87 indent(&width);
89 while(start < end)
91 printChar(list[start], &width);
92 start++;
94 if(list[end] == '\0')
95 break;
96 start++;
97 end++;
98 if(list[end] == '\0')
99 break;
100 printChar(',', &width);
101 printChar(' ', &width);
103 end++;
105 printChar('\n', &width);
108 static void die(const char *kind, const char *description)
110 fprintf(stderr, "%s error %s occured\n", kind, description);
111 exit(EXIT_FAILURE);
114 static void checkForErrors(void)
117 ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
118 ALCenum error = alcGetError(device);
119 if(error != ALC_NO_ERROR)
120 die("ALC", (const char*)alcGetString(device, error));
123 ALenum error = alGetError();
124 if(error != AL_NO_ERROR)
125 die("AL", (const char*)alGetString(error));
129 static void printDevices(ALCenum which, const char *kind)
131 const char *s = alcGetString(NULL, which);
132 printf("Available %s devices:\n", kind);
133 if(s == NULL || *s == '\0')
134 printf(" (none!)\n");
135 else do {
136 printf(" %s\n", s);
137 while(*s++ != '\0')
139 } while(*s != '\0');
142 static void printALCInfo (void)
144 ALCint major, minor;
145 ALCdevice *device;
147 printf("Default device: %s\n",
148 alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));
149 printf("Default capture device: %s\n",
150 alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
152 device = alcGetContextsDevice(alcGetCurrentContext());
153 checkForErrors();
155 alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
156 alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor);
157 checkForErrors();
158 printf("ALC version: %d.%d\n", (int)major, (int)minor);
160 printList("ALC extensions", ' ', alcGetString(device, ALC_EXTENSIONS));
161 checkForErrors();
164 static void printALInfo(void)
166 printf("OpenAL vendor string: %s\n", alGetString(AL_VENDOR));
167 printf("OpenAL renderer string: %s\n", alGetString(AL_RENDERER));
168 printf("OpenAL version string: %s\n", alGetString(AL_VERSION));
169 printList("OpenAL extensions", ' ', alGetString(AL_EXTENSIONS));
170 checkForErrors();
173 static void printEFXInfo(void)
175 ALCint major, minor, sends;
176 ALCdevice *device;
177 ALuint obj;
178 int i;
179 const ALenum effects[] = {
180 AL_EFFECT_EAXREVERB, AL_EFFECT_REVERB, AL_EFFECT_CHORUS,
181 AL_EFFECT_DISTORTION, AL_EFFECT_ECHO, AL_EFFECT_FLANGER,
182 AL_EFFECT_FREQUENCY_SHIFTER, AL_EFFECT_VOCAL_MORPHER,
183 AL_EFFECT_PITCH_SHIFTER, AL_EFFECT_RING_MODULATOR, AL_EFFECT_AUTOWAH,
184 AL_EFFECT_COMPRESSOR, AL_EFFECT_EQUALIZER, AL_EFFECT_NULL
186 char effectNames[] = "EAX Reverb,Reverb,Chorus,Distortion,Echo,Flanger,"
187 "Frequency Shifter,Vocal Morpher,Pitch Shifter,"
188 "Ring Modulator,Autowah,Compressor,Equalizer,";
189 const ALenum filters[] = {
190 AL_FILTER_LOWPASS, AL_FILTER_HIGHPASS, AL_FILTER_BANDPASS,
191 AL_FILTER_NULL
193 char filterNames[] = "Low-pass,High-pass,Band-pass,";
194 char *current;
196 device = alcGetContextsDevice(alcGetCurrentContext());
197 if(alcIsExtensionPresent(device, (const ALCchar*)"ALC_EXT_EFX") == AL_FALSE)
199 printf("EFX not available\n");
200 return;
203 alcGetIntegerv(device, ALC_EFX_MAJOR_VERSION, 1, &major);
204 alcGetIntegerv(device, ALC_EFX_MINOR_VERSION, 1, &minor);
205 checkForErrors();
206 printf("EFX version: %d.%d\n", (int)major, (int)minor);
208 alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &sends);
209 checkForErrors();
210 printf("Max auxiliary sends: %d\n", (int)sends);
212 p_alGenFilters = alGetProcAddress("alGenFilters");
213 p_alDeleteFilters = alGetProcAddress("alDeleteFilters");
214 p_alFilteri = alGetProcAddress("alFilteri");
215 p_alGenEffects = alGetProcAddress("alGenEffects");
216 p_alDeleteEffects = alGetProcAddress("alDeleteEffects");
217 p_alEffecti = alGetProcAddress("alEffecti");
218 checkForErrors();
219 if(!p_alGenEffects || !p_alDeleteEffects || !p_alEffecti ||
220 !p_alGenFilters || !p_alDeleteFilters || !p_alFilteri)
222 printf("Missing EFX functions!\n");
223 return;
226 p_alGenFilters(1, &obj);
227 checkForErrors();
228 current = filterNames;
229 for(i = 0;filters[i] != AL_FILTER_NULL;i++)
231 char *next = strchr(current, ',');
233 p_alFilteri(obj, AL_FILTER_TYPE, filters[i]);
234 if(alGetError() == AL_NO_ERROR)
235 current = next+1;
236 else
237 memmove(current, next+1, strlen(next));
239 p_alDeleteFilters(1, &obj);
240 checkForErrors();
241 printList("Supported filters", ',', filterNames);
243 p_alGenEffects(1, &obj);
244 checkForErrors();
245 current = effectNames;
246 for(i = 0;effects[i] != AL_EFFECT_NULL;i++)
248 char *next = strchr(current, ',');
250 p_alEffecti(obj, AL_EFFECT_TYPE, effects[i]);
251 if(alGetError() == AL_NO_ERROR)
252 current = next+1;
253 else
254 memmove(current, next+1, strlen(next));
256 p_alDeleteEffects(1, &obj);
257 checkForErrors();
258 printList("Supported effects", ',', effectNames);
261 int main()
263 ALCdevice *device;
264 ALCcontext *context;
266 if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT") == AL_TRUE)
268 if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATE_ALL_EXT") == AL_TRUE)
269 printDevices(ALC_ALL_DEVICES_SPECIFIER, "playback");
270 else
271 printDevices(ALC_DEVICE_SPECIFIER, "playback");
272 printDevices(ALC_CAPTURE_DEVICE_SPECIFIER, "capture");
274 else
275 printf("No device enumeration available\n");
277 device = alcOpenDevice(NULL);
278 if(!device)
280 printf("Failed to open a device!\n");
281 exit(EXIT_FAILURE);
283 context = alcCreateContext(device, NULL);
284 if(!context || alcMakeContextCurrent(context) == ALC_FALSE)
286 printf("Failed to set a context!\n");
287 exit(EXIT_FAILURE);
290 printALCInfo();
291 printALInfo();
292 printEFXInfo();
293 checkForErrors();
295 alcMakeContextCurrent(NULL);
296 alcDestroyContext(context);
297 alcCloseDevice(device);
299 return EXIT_SUCCESS;