Create PulseAudio's playback stream when the AL context is created
[openal-soft.git] / examples / openal-info.c
blobdaf083b2d1b8584a716feb02758688dfcaa46541
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>
18 #include "AL/alc.h"
19 #include "AL/al.h"
20 #include "AL/alext.h"
22 #ifndef ALC_EXT_EFX
23 #define AL_FILTER_TYPE 0x8001
24 #define AL_EFFECT_TYPE 0x8001
25 #define AL_FILTER_NULL 0x0000
26 #define AL_FILTER_LOWPASS 0x0001
27 #define AL_FILTER_HIGHPASS 0x0002
28 #define AL_FILTER_BANDPASS 0x0003
29 #define AL_EFFECT_NULL 0x0000
30 #define AL_EFFECT_EAXREVERB 0x8000
31 #define AL_EFFECT_REVERB 0x0001
32 #define AL_EFFECT_CHORUS 0x0002
33 #define AL_EFFECT_DISTORTION 0x0003
34 #define AL_EFFECT_ECHO 0x0004
35 #define AL_EFFECT_FLANGER 0x0005
36 #define AL_EFFECT_FREQUENCY_SHIFTER 0x0006
37 #define AL_EFFECT_VOCAL_MORPHER 0x0007
38 #define AL_EFFECT_PITCH_SHIFTER 0x0008
39 #define AL_EFFECT_RING_MODULATOR 0x0009
40 #define AL_EFFECT_AUTOWAH 0x000A
41 #define AL_EFFECT_COMPRESSOR 0x000B
42 #define AL_EFFECT_EQUALIZER 0x000C
43 #define ALC_EFX_MAJOR_VERSION 0x20001
44 #define ALC_EFX_MINOR_VERSION 0x20002
45 #define ALC_MAX_AUXILIARY_SENDS 0x20003
46 #endif
47 ALvoid (AL_APIENTRY *p_alGenFilters)(ALsizei,ALuint*);
48 ALvoid (AL_APIENTRY *p_alDeleteFilters)(ALsizei,ALuint*);
49 ALvoid (AL_APIENTRY *p_alFilteri)(ALuint,ALenum,ALint);
50 ALvoid (AL_APIENTRY *p_alGenEffects)(ALsizei,ALuint*);
51 ALvoid (AL_APIENTRY *p_alDeleteEffects)(ALsizei,ALuint*);
52 ALvoid (AL_APIENTRY *p_alEffecti)(ALuint,ALenum,ALint);
54 static const int indentation = 4;
55 static const int maxmimumWidth = 79;
57 static void printChar(int c, int *width)
59 putchar(c);
60 *width = ((c == '\n') ? 0 : ((*width) + 1));
63 static void indent(int *width)
65 int i;
66 for(i = 0; i < indentation; i++)
67 printChar(' ', width);
70 static void printExtensions(const char *header, char separator, const char *extensions)
72 int width = 0, start = 0, end = 0;
74 printf("%s:\n", header);
75 if(extensions == NULL || extensions[0] == '\0')
76 return;
78 indent(&width);
79 while (1)
81 if(extensions[end] == separator || extensions[end] == '\0')
83 if(width + end - start + 2 > maxmimumWidth)
85 printChar('\n', &width);
86 indent(&width);
88 while(start < end)
90 printChar(extensions[start], &width);
91 start++;
93 if(extensions[end] == '\0')
94 break;
95 start++;
96 end++;
97 if(extensions[end] == '\0')
98 break;
99 printChar(',', &width);
100 printChar(' ', &width);
102 end++;
104 printChar('\n', &width);
107 static void die(const char *kind, const char *description)
109 fprintf(stderr, "%s error %s occured\n", kind, description);
110 exit(EXIT_FAILURE);
113 static void checkForErrors(void)
116 ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
117 ALCenum error = alcGetError(device);
118 if(error != ALC_NO_ERROR)
119 die("ALC", (const char*)alcGetString(device, error));
122 ALenum error = alGetError();
123 if(error != AL_NO_ERROR)
124 die("AL", (const char*)alGetString(error));
128 static void printDevices(ALCenum which, const char *kind)
130 const char *s = alcGetString(NULL, which);
131 checkForErrors();
133 printf("Available %sdevices:\n", kind);
134 while(*s != '\0')
136 printf(" %s\n", s);
137 while(*s++ != '\0')
142 static void printALCInfo (void)
144 ALCint major, minor;
145 ALCdevice *device;
147 if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT") == AL_TRUE)
149 if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATE_ALL_EXT") == AL_TRUE)
150 printDevices(ALC_ALL_DEVICES_SPECIFIER, "playback ");
151 else
152 printDevices(ALC_DEVICE_SPECIFIER, "playback ");
153 printDevices(ALC_CAPTURE_DEVICE_SPECIFIER, "capture ");
155 else
156 printf("No device enumeration available\n");
158 device = alcGetContextsDevice(alcGetCurrentContext());
159 checkForErrors();
161 printf("Default device: %s\n",
162 alcGetString(device, ALC_DEFAULT_DEVICE_SPECIFIER));
164 printf("Default capture device: %s\n",
165 alcGetString(device, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
167 alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
168 alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor);
169 checkForErrors();
170 printf("ALC version: %d.%d\n", (int)major, (int)minor);
172 printExtensions("ALC extensions", ' ',
173 alcGetString(device, ALC_EXTENSIONS));
174 checkForErrors();
177 static void printALInfo(void)
179 printf("OpenAL vendor string: %s\n", alGetString(AL_VENDOR));
180 printf("OpenAL renderer string: %s\n", alGetString(AL_RENDERER));
181 printf("OpenAL version string: %s\n", alGetString(AL_VERSION));
182 printExtensions("OpenAL extensions", ' ', alGetString(AL_EXTENSIONS));
183 checkForErrors();
186 static void printEFXInfo(void)
188 ALCint major, minor, sends;
189 ALCdevice *device;
190 ALuint obj;
191 int i;
192 const struct {
193 ALenum type;
194 const char *name;
195 } effects[] = {
196 { AL_EFFECT_EAXREVERB, "EAX Reverb" },
197 { AL_EFFECT_REVERB, "Reverb" },
198 { AL_EFFECT_CHORUS, "Chorus" },
199 { AL_EFFECT_DISTORTION, "Distortion" },
200 { AL_EFFECT_ECHO, "Echo" },
201 { AL_EFFECT_FLANGER, "Flanger" },
202 { AL_EFFECT_FREQUENCY_SHIFTER, "Frequency Shifter" },
203 { AL_EFFECT_VOCAL_MORPHER, "Vocal Morpher" },
204 { AL_EFFECT_PITCH_SHIFTER, "Pitch Shifter" },
205 { AL_EFFECT_RING_MODULATOR, "Ring Modulator" },
206 { AL_EFFECT_AUTOWAH, "Autowah" },
207 { AL_EFFECT_COMPRESSOR, "Compressor" },
208 { AL_EFFECT_EQUALIZER, "Equalizer" },
209 { AL_EFFECT_NULL, NULL }
211 const struct {
212 ALenum type;
213 const char *name;
214 } filters[] = {
215 { AL_FILTER_LOWPASS, "Low-pass" },
216 { AL_FILTER_HIGHPASS, "High-pass" },
217 { AL_FILTER_BANDPASS, "Band-pass" },
218 { AL_FILTER_NULL, NULL }
221 device = alcGetContextsDevice(alcGetCurrentContext());
223 if(alcIsExtensionPresent(device, (const ALCchar*)"ALC_EXT_EFX") == AL_FALSE)
225 printf("EFX not available\n");
226 return;
229 alcGetIntegerv(device, ALC_EFX_MAJOR_VERSION, 1, &major);
230 alcGetIntegerv(device, ALC_EFX_MINOR_VERSION, 1, &minor);
231 checkForErrors();
232 printf("EFX version: %d.%d\n", (int)major, (int)minor);
234 alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &sends);
235 checkForErrors();
236 printf("Max auxiliary sends: %d\n", (int)sends);
238 p_alGenFilters = alGetProcAddress("alGenFilters");
239 p_alDeleteFilters = alGetProcAddress("alDeleteFilters");
240 p_alFilteri = alGetProcAddress("alFilteri");
241 p_alGenEffects = alGetProcAddress("alGenEffects");
242 p_alDeleteEffects = alGetProcAddress("alDeleteEffects");
243 p_alEffecti = alGetProcAddress("alEffecti");
244 checkForErrors();
245 if(!p_alGenEffects || !p_alDeleteEffects || !p_alEffecti ||
246 !p_alGenFilters || !p_alDeleteFilters || !p_alFilteri)
248 printf("Missing EFX functions!\n");
249 return;
252 p_alGenFilters(1, &obj);
253 checkForErrors();
254 printf("Available filters:\n");
255 for(i = 0;filters[i].type != AL_FILTER_NULL;i++)
257 p_alFilteri(obj, AL_FILTER_TYPE, filters[i].type);
258 if(alGetError() == AL_NO_ERROR)
259 printf(" %s\n", filters[i].name);
261 p_alDeleteFilters(1, &obj);
262 checkForErrors();
264 p_alGenEffects(1, &obj);
265 checkForErrors();
266 printf("Available effects:\n");
267 for(i = 0;effects[i].type != AL_EFFECT_NULL;i++)
269 p_alEffecti(obj, AL_EFFECT_TYPE, effects[i].type);
270 if(alGetError() == AL_NO_ERROR)
271 printf(" %s\n", effects[i].name);
273 p_alDeleteEffects(1, &obj);
274 checkForErrors();
277 int main()
279 ALCdevice *device = alcOpenDevice(NULL);
280 ALCcontext *context = alcCreateContext(device, NULL);
281 alcMakeContextCurrent(context);
282 checkForErrors();
284 printALCInfo();
285 printALInfo();
286 printEFXInfo();
287 checkForErrors();
289 alcMakeContextCurrent(NULL);
290 alcDestroyContext(context);
291 alcCloseDevice(device);
293 return EXIT_SUCCESS;