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>.
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
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
)
61 *width
= ((c
== '\n') ? 0 : ((*width
) + 1));
64 static void indent(int *width
)
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')
82 if(list
[end
] == separator
|| list
[end
] == '\0')
84 if(width
+ end
- start
+ 2 > maxmimumWidth
)
86 printChar('\n', &width
);
91 printChar(list
[start
], &width
);
100 printChar(',', &width
);
101 printChar(' ', &width
);
105 printChar('\n', &width
);
108 static void die(const char *kind
, const char *description
)
110 fprintf(stderr
, "%s error %s occured\n", kind
, description
);
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");
142 static void printALCInfo (void)
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());
155 alcGetIntegerv(device
, ALC_MAJOR_VERSION
, 1, &major
);
156 alcGetIntegerv(device
, ALC_MINOR_VERSION
, 1, &minor
);
158 printf("ALC version: %d.%d\n", (int)major
, (int)minor
);
160 printList("ALC extensions", ' ', alcGetString(device
, ALC_EXTENSIONS
));
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
));
173 static void printEFXInfo(void)
175 ALCint major
, minor
, sends
;
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
,
193 char filterNames
[] = "Low-pass,High-pass,Band-pass,";
196 device
= alcGetContextsDevice(alcGetCurrentContext());
197 if(alcIsExtensionPresent(device
, (const ALCchar
*)"ALC_EXT_EFX") == AL_FALSE
)
199 printf("EFX not available\n");
203 alcGetIntegerv(device
, ALC_EFX_MAJOR_VERSION
, 1, &major
);
204 alcGetIntegerv(device
, ALC_EFX_MINOR_VERSION
, 1, &minor
);
206 printf("EFX version: %d.%d\n", (int)major
, (int)minor
);
208 alcGetIntegerv(device
, ALC_MAX_AUXILIARY_SENDS
, 1, &sends
);
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");
219 if(!p_alGenEffects
|| !p_alDeleteEffects
|| !p_alEffecti
||
220 !p_alGenFilters
|| !p_alDeleteFilters
|| !p_alFilteri
)
222 printf("Missing EFX functions!\n");
226 p_alGenFilters(1, &obj
);
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
)
237 memmove(current
, next
+1, strlen(next
));
239 p_alDeleteFilters(1, &obj
);
241 printList("Supported filters", ',', filterNames
);
243 p_alGenEffects(1, &obj
);
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
)
254 memmove(current
, next
+1, strlen(next
));
256 p_alDeleteEffects(1, &obj
);
258 printList("Supported effects", ',', effectNames
);
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");
271 printDevices(ALC_DEVICE_SPECIFIER
, "playback");
272 printDevices(ALC_CAPTURE_DEVICE_SPECIFIER
, "capture");
275 printf("No device enumeration available\n");
277 device
= alcOpenDevice(NULL
);
280 printf("Failed to open a device!\n");
283 context
= alcCreateContext(device
, NULL
);
284 if(!context
|| alcMakeContextCurrent(context
) == ALC_FALSE
)
286 printf("Failed to set a context!\n");
295 alcMakeContextCurrent(NULL
);
296 alcDestroyContext(context
);
297 alcCloseDevice(device
);