diff options
Diffstat (limited to 'examples/openal-info.c')
-rw-r--r-- | examples/openal-info.c | 414 |
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; } |