aboutsummaryrefslogtreecommitdiffstats
path: root/examples/openal-info.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/openal-info.c')
-rw-r--r--examples/openal-info.c414
1 files changed, 223 insertions, 191 deletions
diff --git a/examples/openal-info.c b/examples/openal-info.c
index 5af34bbc..586a1c73 100644
--- a/examples/openal-info.c
+++ b/examples/openal-info.c
@@ -1,164 +1,174 @@
/*
- * openal-info: Display information about ALC and AL.
+ * OpenAL Info Utility
*
- * Idea based on glxinfo for OpenGL.
- * Initial OpenAL version by Erik Hofman <[email protected]>.
- * Further hacked by Sven Panne <[email protected]>.
- * More work (clean up) by Chris Robinson <[email protected]>.
+ * Copyright (c) 2010 by Chris Robinson <[email protected]>
*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
*/
-#if HAVE_CONFIG_H
#include "config.h"
-#endif
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
#include "AL/alc.h"
#include "AL/al.h"
#include "AL/alext.h"
-#ifndef ALC_EXT_EFX
-#define AL_FILTER_TYPE 0x8001
-#define AL_EFFECT_TYPE 0x8001
-#define AL_FILTER_NULL 0x0000
-#define AL_FILTER_LOWPASS 0x0001
-#define AL_FILTER_HIGHPASS 0x0002
-#define AL_FILTER_BANDPASS 0x0003
-#define AL_EFFECT_NULL 0x0000
-#define AL_EFFECT_EAXREVERB 0x8000
-#define AL_EFFECT_REVERB 0x0001
-#define AL_EFFECT_CHORUS 0x0002
-#define AL_EFFECT_DISTORTION 0x0003
-#define AL_EFFECT_ECHO 0x0004
-#define AL_EFFECT_FLANGER 0x0005
-#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006
-#define AL_EFFECT_VOCAL_MORPHER 0x0007
-#define AL_EFFECT_PITCH_SHIFTER 0x0008
-#define AL_EFFECT_RING_MODULATOR 0x0009
-#define AL_EFFECT_AUTOWAH 0x000A
-#define AL_EFFECT_COMPRESSOR 0x000B
-#define AL_EFFECT_EQUALIZER 0x000C
-#define ALC_EFX_MAJOR_VERSION 0x20001
-#define ALC_EFX_MINOR_VERSION 0x20002
-#define ALC_MAX_AUXILIARY_SENDS 0x20003
+#ifndef ALC_ENUMERATE_ALL_EXT
+#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
+#define ALC_ALL_DEVICES_SPECIFIER 0x1013
#endif
-ALvoid (AL_APIENTRY *p_alGenFilters)(ALsizei,ALuint*);
-ALvoid (AL_APIENTRY *p_alDeleteFilters)(ALsizei,ALuint*);
-ALvoid (AL_APIENTRY *p_alFilteri)(ALuint,ALenum,ALint);
-ALvoid (AL_APIENTRY *p_alGenEffects)(ALsizei,ALuint*);
-ALvoid (AL_APIENTRY *p_alDeleteEffects)(ALsizei,ALuint*);
-ALvoid (AL_APIENTRY *p_alEffecti)(ALuint,ALenum,ALint);
-static const int indentation = 4;
-static const int maxmimumWidth = 79;
+#ifndef ALC_EXT_EFX
+#define ALC_EFX_MAJOR_VERSION 0x20001
+#define ALC_EFX_MINOR_VERSION 0x20002
+#define ALC_MAX_AUXILIARY_SENDS 0x20003
+#define AL_FILTER_TYPE 0x8001
+#define AL_FILTER_NULL 0x0000
+#define AL_FILTER_LOWPASS 0x0001
+#define AL_FILTER_HIGHPASS 0x0002
+#define AL_FILTER_BANDPASS 0x0003
+#define AL_EFFECT_TYPE 0x8001
+#define AL_EFFECT_NULL 0x0000
+#define AL_EFFECT_EAXREVERB 0x8000
+#define AL_EFFECT_REVERB 0x0001
+#define AL_EFFECT_CHORUS 0x0002
+#define AL_EFFECT_DISTORTION 0x0003
+#define AL_EFFECT_ECHO 0x0004
+#define AL_EFFECT_FLANGER 0x0005
+#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006
+#define AL_EFFECT_VOCAL_MORPHER 0x0007
+#define AL_EFFECT_PITCH_SHIFTER 0x0008
+#define AL_EFFECT_RING_MODULATOR 0x0009
+#define AL_EFFECT_AUTOWAH 0x000A
+#define AL_EFFECT_COMPRESSOR 0x000B
+#define AL_EFFECT_EQUALIZER 0x000C
+typedef void (AL_APIENTRY *LPALGENFILTERS)(ALsizei, ALuint*);
+typedef void (AL_APIENTRY *LPALDELETEFILTERS)(ALsizei, ALuint*);
+typedef void (AL_APIENTRY *LPALFILTERI)(ALuint, ALenum, ALint);
+typedef void (AL_APIENTRY *LPALGENEFFECTS)(ALsizei, ALuint*);
+typedef void (AL_APIENTRY *LPALDELETEEFFECTS)(ALsizei, ALuint*);
+typedef void (AL_APIENTRY *LPALEFFECTI)(ALuint, ALenum, ALint);
+#endif
+static LPALGENFILTERS palGenFilters;
+static LPALDELETEFILTERS palDeleteFilters;
+static LPALFILTERI palFilteri;
+static LPALGENEFFECTS palGenEffects;
+static LPALDELETEEFFECTS palDeleteEffects;
+static LPALEFFECTI palEffecti;
-static void printChar(int c, int *width)
-{
- putchar(c);
- *width = ((c == '\n') ? 0 : ((*width) + 1));
-}
-static void indent(int *width)
-{
- int i;
- for(i = 0; i < indentation; i++)
- printChar(' ', width);
-}
+#define MAX_WIDTH 80
-static void printList(const char *header, char separator, const char *list)
+static void printList(const char *list, char separator)
{
- int width = 0, start = 0, end = 0;
+ size_t col = MAX_WIDTH, len;
+ const char *indent = " ";
+ const char *next;
- printf("%s:\n", header);
- if(list == NULL || list[0] == '\0')
+ if(!list || *list == '\0')
+ {
+ fprintf(stdout, "\n%s!!! none !!!\n", indent);
return;
+ }
- indent(&width);
- while(1)
- {
- if(list[end] == separator || list[end] == '\0')
+ do {
+ next = strchr(list, separator);
+ if(next)
{
- if(width + end - start + 2 > maxmimumWidth)
- {
- printChar('\n', &width);
- indent(&width);
- }
- while(start < end)
- {
- printChar(list[start], &width);
- start++;
- }
- if(list[end] == '\0')
- break;
- start++;
- end++;
- if(list[end] == '\0')
- break;
- printChar(',', &width);
- printChar(' ', &width);
+ len = next-list;
+ do {
+ next++;
+ } while(*next == separator);
}
- end++;
- }
- printChar('\n', &width);
+ else
+ len = strlen(list);
+
+ if(len + col + 2 >= MAX_WIDTH)
+ {
+ fprintf(stdout, "\n%s", indent);
+ col = strlen(indent);
+ }
+ else
+ {
+ fputc(' ', stdout);
+ col++;
+ }
+
+ len = fwrite(list, 1, len, stdout);
+ col += len;
+
+ if(!next || *next == '\0')
+ break;
+ fputc(',', stdout);
+ col++;
+
+ list = next;
+ } while(1);
+ fputc('\n', stdout);
}
-static void die(const char *kind, const char *description)
+static void printDeviceList(const char *list)
{
- fprintf(stderr, "%s error %s occured\n", kind, description);
- exit(EXIT_FAILURE);
+ if(!list || *list == '\0')
+ printf(" !!! none !!!\n");
+ else do {
+ printf(" %s\n", list);
+ list += strlen(list) + 1;
+ } while(*list != '\0');
}
-static void checkForErrors(void)
+
+static ALenum checkALErrors(int linenum)
{
- {
- ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
- ALCenum error = alcGetError(device);
- if(error != ALC_NO_ERROR)
- die("ALC", (const char*)alcGetString(device, error));
- }
- {
- ALenum error = alGetError();
- if(error != AL_NO_ERROR)
- die("AL", (const char*)alGetString(error));
- }
+ ALenum err = alGetError();
+ if(err != AL_NO_ERROR)
+ printf("OpenAL Error: %s (0x%x), @ %d\n", alGetString(err), err, linenum);
+ return err;
}
+#define checkALErrors() checkALErrors(__LINE__)
-static void printDevices(ALCenum which, const char *kind)
+static ALCenum checkALCErrors(ALCdevice *device, int linenum)
{
- const char *s = alcGetString(NULL, which);
- printf("Available %s devices:\n", kind);
- if(s == NULL || *s == '\0')
- printf(" (none!)\n");
- else do {
- printf(" %s\n", s);
- while(*s++ != '\0')
- ;
- } while(*s != '\0');
+ ALCenum err = alcGetError(device);
+ if(err != ALC_NO_ERROR)
+ printf("ALC Error: %s (0x%x), @ %d\n", alcGetString(device, err), err, linenum);
+ return err;
}
+#define checkALCErrors(x) checkALCErrors((x),__LINE__)
-static void printALCInfo (void)
+
+static void printALCInfo(ALCdevice *device)
{
ALCint major, minor;
- ALCdevice *device;
-
- printf("Default device: %s\n",
- alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));
- printf("Default capture device: %s\n",
- alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
-
- device = alcGetContextsDevice(alcGetCurrentContext());
- checkForErrors();
alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor);
- checkForErrors();
- printf("ALC version: %d.%d\n", (int)major, (int)minor);
-
- printList("ALC extensions", ' ', alcGetString(device, ALC_EXTENSIONS));
- checkForErrors();
+ if(checkALCErrors(device) == ALC_NO_ERROR)
+ printf("ALC version: %d.%d\n", major, minor);
+ if(device)
+ {
+ printf("ALC extensions:");
+ printList(alcGetString(device, ALC_EXTENSIONS), ' ');
+ checkALCErrors(device);
+ }
}
static void printALInfo(void)
@@ -166,16 +176,21 @@ static void printALInfo(void)
printf("OpenAL vendor string: %s\n", alGetString(AL_VENDOR));
printf("OpenAL renderer string: %s\n", alGetString(AL_RENDERER));
printf("OpenAL version string: %s\n", alGetString(AL_VERSION));
- printList("OpenAL extensions", ' ', alGetString(AL_EXTENSIONS));
- checkForErrors();
+ printf("OpenAL extensions:");
+ printList(alGetString(AL_EXTENSIONS), ' ');
+ checkALErrors();
}
-static void printEFXInfo(void)
+static void printEFXInfo(ALCdevice *device)
{
ALCint major, minor, sends;
- ALCdevice *device;
ALuint obj;
int i;
+ const ALenum filters[] = {
+ AL_FILTER_LOWPASS, AL_FILTER_HIGHPASS, AL_FILTER_BANDPASS,
+ AL_FILTER_NULL
+ };
+ char filterNames[] = "Low-pass,High-pass,Band-pass,";
const ALenum effects[] = {
AL_EFFECT_EAXREVERB, AL_EFFECT_REVERB, AL_EFFECT_CHORUS,
AL_EFFECT_DISTORTION, AL_EFFECT_ECHO, AL_EFFECT_FLANGER,
@@ -186,15 +201,9 @@ static void printEFXInfo(void)
char effectNames[] = "EAX Reverb,Reverb,Chorus,Distortion,Echo,Flanger,"
"Frequency Shifter,Vocal Morpher,Pitch Shifter,"
"Ring Modulator,Autowah,Compressor,Equalizer,";
- const ALenum filters[] = {
- AL_FILTER_LOWPASS, AL_FILTER_HIGHPASS, AL_FILTER_BANDPASS,
- AL_FILTER_NULL
- };
- char filterNames[] = "Low-pass,High-pass,Band-pass,";
char *current;
- device = alcGetContextsDevice(alcGetCurrentContext());
- if(alcIsExtensionPresent(device, (const ALCchar*)"ALC_EXT_EFX") == AL_FALSE)
+ if(alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_FALSE)
{
printf("EFX not available\n");
return;
@@ -202,99 +211,122 @@ static void printEFXInfo(void)
alcGetIntegerv(device, ALC_EFX_MAJOR_VERSION, 1, &major);
alcGetIntegerv(device, ALC_EFX_MINOR_VERSION, 1, &minor);
- checkForErrors();
- printf("EFX version: %d.%d\n", (int)major, (int)minor);
-
+ if(checkALCErrors(device) == ALC_NO_ERROR)
+ printf("EFX version: %d.%d\n", major, minor);
alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &sends);
- checkForErrors();
- printf("Max auxiliary sends: %d\n", (int)sends);
-
- p_alGenFilters = alGetProcAddress("alGenFilters");
- p_alDeleteFilters = alGetProcAddress("alDeleteFilters");
- p_alFilteri = alGetProcAddress("alFilteri");
- p_alGenEffects = alGetProcAddress("alGenEffects");
- p_alDeleteEffects = alGetProcAddress("alDeleteEffects");
- p_alEffecti = alGetProcAddress("alEffecti");
- checkForErrors();
- if(!p_alGenEffects || !p_alDeleteEffects || !p_alEffecti ||
- !p_alGenFilters || !p_alDeleteFilters || !p_alFilteri)
+ if(checkALCErrors(device) == ALC_NO_ERROR)
+ printf("Max auxiliary sends: %d\n", sends);
+
+ palGenFilters = alGetProcAddress("alGenFilters");
+ palDeleteFilters = alGetProcAddress("alDeleteFilters");
+ palFilteri = alGetProcAddress("alFilteri");
+ palGenEffects = alGetProcAddress("alGenEffects");
+ palDeleteEffects = alGetProcAddress("alDeleteEffects");
+ palEffecti = alGetProcAddress("alEffecti");
+ if(checkALErrors() != AL_NO_ERROR ||
+ !palGenFilters || !palDeleteFilters || !palFilteri ||
+ !palGenEffects || !palDeleteEffects || !palEffecti)
{
- printf("Missing EFX functions!\n");
+ printf("!!! Missing EFX functions !!!\n");
return;
}
- p_alGenFilters(1, &obj);
- checkForErrors();
- current = filterNames;
- for(i = 0;filters[i] != AL_FILTER_NULL;i++)
+ palGenFilters(1, &obj);
+ if(checkALErrors() == AL_NO_ERROR)
{
- char *next = strchr(current, ',');
+ current = filterNames;
+ for(i = 0;filters[i] != AL_FILTER_NULL;i++)
+ {
+ char *next = strchr(current, ',');
- p_alFilteri(obj, AL_FILTER_TYPE, filters[i]);
- if(alGetError() == AL_NO_ERROR)
- current = next+1;
- else
- memmove(current, next+1, strlen(next));
+ palFilteri(obj, AL_FILTER_TYPE, filters[i]);
+ if(alGetError() == AL_NO_ERROR)
+ current = next+1;
+ else
+ memmove(current, next+1, strlen(next));
+ }
+ palDeleteFilters(1, &obj);
+ checkALErrors();
+
+ printf("Supported filters:");
+ printList(filterNames, ',');
}
- p_alDeleteFilters(1, &obj);
- checkForErrors();
- printList("Supported filters", ',', filterNames);
-
- p_alGenEffects(1, &obj);
- checkForErrors();
- current = effectNames;
- for(i = 0;effects[i] != AL_EFFECT_NULL;i++)
+
+ palGenEffects(1, &obj);
+ if(checkALErrors() == AL_NO_ERROR)
{
- char *next = strchr(current, ',');
+ current = effectNames;
+ for(i = 0;effects[i] != AL_EFFECT_NULL;i++)
+ {
+ char *next = strchr(current, ',');
- p_alEffecti(obj, AL_EFFECT_TYPE, effects[i]);
- if(alGetError() == AL_NO_ERROR)
- current = next+1;
- else
- memmove(current, next+1, strlen(next));
+ palEffecti(obj, AL_EFFECT_TYPE, effects[i]);
+ if(alGetError() == AL_NO_ERROR)
+ current = next+1;
+ else
+ memmove(current, next+1, strlen(next));
+ }
+ palDeleteEffects(1, &obj);
+ checkALErrors();
+
+ printf("Supported effects:");
+ printList(effectNames, ',');
}
- p_alDeleteEffects(1, &obj);
- checkForErrors();
- printList("Supported effects", ',', effectNames);
}
-int main()
+int main(int argc, char *argv[])
{
ALCdevice *device;
ALCcontext *context;
- if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT") == AL_TRUE)
+ if(argc > 1 && (strcmp(argv[1], "--help") == 0 ||
+ strcmp(argv[1], "-h") == 0))
{
- if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATE_ALL_EXT") == AL_TRUE)
- printDevices(ALC_ALL_DEVICES_SPECIFIER, "playback");
- else
- printDevices(ALC_DEVICE_SPECIFIER, "playback");
- printDevices(ALC_CAPTURE_DEVICE_SPECIFIER, "capture");
+ printf("Usage: %s [playback device]\n", argv[0]);
+ return 0;
}
+
+ printf("Available playback devices:\n");
+ if(alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
+ printDeviceList(alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER));
else
- printf("No device enumeration available\n");
+ printDeviceList(alcGetString(NULL, ALC_DEVICE_SPECIFIER));
+ printf("Available capture devices:\n");
+ printDeviceList(alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER));
- device = alcOpenDevice(NULL);
+ printf("Default playback device: %s\n",
+ alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));
+ printf("Default capture device: %s\n",
+ alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
+
+ printALCInfo(NULL);
+
+ device = alcOpenDevice((argc>1) ? argv[1] : NULL);
if(!device)
{
- printf("Failed to open a device!\n");
- exit(EXIT_FAILURE);
+ printf("\n!!! Failed to open %s !!!\n\n", ((argc>1) ? argv[1] : "default device"));
+ return 1;
}
+
+ printf("\n** Info for device \"%s\" **\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
+ printALCInfo(device);
+
context = alcCreateContext(device, NULL);
if(!context || alcMakeContextCurrent(context) == ALC_FALSE)
{
- printf("Failed to set a context!\n");
- exit(EXIT_FAILURE);
+ if(context)
+ alcDestroyContext(context);
+ alcCloseDevice(device);
+ printf("\n!!! Failed to set a context !!!\n\n");
+ return 1;
}
- printALCInfo();
printALInfo();
- printEFXInfo();
- checkForErrors();
+ printEFXInfo(device);
alcMakeContextCurrent(NULL);
alcDestroyContext(context);
alcCloseDevice(device);
- return EXIT_SUCCESS;
+ return 0;
}