~ubuntu-branches/ubuntu/quantal/openal-soft/quantal

« back to all changes in this revision

Viewing changes to examples/openal-info.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Ritchie
  • Date: 2010-04-16 15:20:20 UTC
  • mfrom: (0.2.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20100416152020-7gbp12lzhugfr2n0
Tags: 1:1.12.854-0ubuntu1
* New upstream release (LP: #565071)
  - Fully backwards compatible
  - Fixed playback when the PulseAudio buffer is calculated to be more than 64KB.
  - Restored compatibility with some older PulseAudio libs.
  - Alternative buffer sizing for PulseAudio, specified using a new config option.
  - Improved buffer size calculations, to prevent drastic latency changes when certain properties (such as ALC_FREQUENCY) are modified.
  - "Not broken" unlike 1.11.753, according to upstream
* Should fix some remaining crackling issues (LP: #351732, #516435)
* Should be ok to sync over; no extra patches

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * openal-info: Display information about ALC and AL.
3
 
 *
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>.
8
 
 *
 
2
 * OpenAL Info Utility
 
3
 *
 
4
 * Copyright (c) 2010 by Chris Robinson <chris.kcat@gmail.com>
 
5
 *
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
7
 * of this software and associated documentation files (the "Software"), to deal
 
8
 * in the Software without restriction, including without limitation the rights
 
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
10
 * copies of the Software, and to permit persons to whom the Software is
 
11
 * furnished to do so, subject to the following conditions:
 
12
 *
 
13
 * The above copyright notice and this permission notice shall be included in
 
14
 * all copies or substantial portions of the Software.
 
15
 *
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
22
 * THE SOFTWARE.
9
23
 */
10
24
 
11
 
#if HAVE_CONFIG_H
12
25
#include "config.h"
13
 
#endif
14
26
 
15
27
#include <stdio.h>
16
 
#include <stdlib.h>
17
28
#include <string.h>
18
29
 
19
30
#include "AL/alc.h"
20
31
#include "AL/al.h"
21
32
#include "AL/alext.h"
22
33
 
 
34
#ifndef ALC_ENUMERATE_ALL_EXT
 
35
#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER        0x1012
 
36
#define ALC_ALL_DEVICES_SPECIFIER                0x1013
 
37
#endif
 
38
 
23
39
#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
 
40
#define ALC_EFX_MAJOR_VERSION                    0x20001
 
41
#define ALC_EFX_MINOR_VERSION                    0x20002
 
42
#define ALC_MAX_AUXILIARY_SENDS                  0x20003
 
43
#define AL_FILTER_TYPE                           0x8001
 
44
#define AL_FILTER_NULL                           0x0000
 
45
#define AL_FILTER_LOWPASS                        0x0001
 
46
#define AL_FILTER_HIGHPASS                       0x0002
 
47
#define AL_FILTER_BANDPASS                       0x0003
 
48
#define AL_EFFECT_TYPE                           0x8001
 
49
#define AL_EFFECT_NULL                           0x0000
 
50
#define AL_EFFECT_EAXREVERB                      0x8000
 
51
#define AL_EFFECT_REVERB                         0x0001
 
52
#define AL_EFFECT_CHORUS                         0x0002
 
53
#define AL_EFFECT_DISTORTION                     0x0003
 
54
#define AL_EFFECT_ECHO                           0x0004
 
55
#define AL_EFFECT_FLANGER                        0x0005
 
56
#define AL_EFFECT_FREQUENCY_SHIFTER              0x0006
 
57
#define AL_EFFECT_VOCAL_MORPHER                  0x0007
 
58
#define AL_EFFECT_PITCH_SHIFTER                  0x0008
 
59
#define AL_EFFECT_RING_MODULATOR                 0x0009
 
60
#define AL_EFFECT_AUTOWAH                        0x000A
 
61
#define AL_EFFECT_COMPRESSOR                     0x000B
 
62
#define AL_EFFECT_EQUALIZER                      0x000C
 
63
typedef void (AL_APIENTRY *LPALGENFILTERS)(ALsizei, ALuint*);
 
64
typedef void (AL_APIENTRY *LPALDELETEFILTERS)(ALsizei, ALuint*);
 
65
typedef void (AL_APIENTRY *LPALFILTERI)(ALuint, ALenum, ALint);
 
66
typedef void (AL_APIENTRY *LPALGENEFFECTS)(ALsizei, ALuint*);
 
67
typedef void (AL_APIENTRY *LPALDELETEEFFECTS)(ALsizei, ALuint*);
 
68
typedef void (AL_APIENTRY *LPALEFFECTI)(ALuint, ALenum, ALint);
47
69
#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);
54
 
 
55
 
static const int indentation = 4;
56
 
static const int maxmimumWidth = 79;
57
 
 
58
 
static void printChar(int c, int *width)
59
 
{
60
 
    putchar(c);
61
 
    *width = ((c == '\n') ? 0 : ((*width) + 1));
62
 
}
63
 
 
64
 
static void indent(int *width)
65
 
{
66
 
    int i;
67
 
    for(i = 0; i < indentation; i++)
68
 
        printChar(' ', width);
69
 
}
70
 
 
71
 
static void printList(const char *header, char separator, const char *list)
72
 
{
73
 
    int width = 0, start = 0, end = 0;
74
 
 
75
 
    printf("%s:\n", header);
76
 
    if(list == NULL || list[0] == '\0')
 
70
static LPALGENFILTERS    palGenFilters;
 
71
static LPALDELETEFILTERS palDeleteFilters;
 
72
static LPALFILTERI       palFilteri;
 
73
static LPALGENEFFECTS    palGenEffects;
 
74
static LPALDELETEEFFECTS palDeleteEffects;
 
75
static LPALEFFECTI       palEffecti;
 
76
 
 
77
 
 
78
#define MAX_WIDTH  80
 
79
 
 
80
static void printList(const char *list, char separator)
 
81
{
 
82
    size_t col = MAX_WIDTH, len;
 
83
    const char *indent = "    ";
 
84
    const char *next;
 
85
 
 
86
    if(!list || *list == '\0')
 
87
    {
 
88
        fprintf(stdout, "\n%s!!! none !!!\n", indent);
77
89
        return;
78
 
 
79
 
    indent(&width);
80
 
    while(1)
81
 
    {
82
 
        if(list[end] == separator || list[end] == '\0')
83
 
        {
84
 
            if(width + end - start + 2 > maxmimumWidth)
85
 
            {
86
 
                printChar('\n', &width);
87
 
                indent(&width);
88
 
            }
89
 
            while(start < end)
90
 
            {
91
 
                printChar(list[start], &width);
92
 
                start++;
93
 
            }
94
 
            if(list[end] == '\0')
95
 
                break;
96
 
            start++;
97
 
            end++;
98
 
            if(list[end] == '\0')
99
 
                break;
100
 
            printChar(',', &width);
101
 
            printChar(' ', &width);
102
 
        }
103
 
        end++;
104
 
    }
105
 
    printChar('\n', &width);
106
 
}
107
 
 
108
 
static void die(const char *kind, const char *description)
109
 
{
110
 
    fprintf(stderr, "%s error %s occured\n", kind, description);
111
 
    exit(EXIT_FAILURE);
112
 
}
113
 
 
114
 
static void checkForErrors(void)
115
 
{
116
 
    {
117
 
        ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
118
 
        ALCenum error = alcGetError(device);
119
 
        if(error != ALC_NO_ERROR)
120
 
            die("ALC", (const char*)alcGetString(device, error));
121
 
    }
122
 
    {
123
 
        ALenum error = alGetError();
124
 
        if(error != AL_NO_ERROR)
125
 
            die("AL", (const char*)alGetString(error));
126
 
    }
127
 
}
128
 
 
129
 
static void printDevices(ALCenum which, const char *kind)
130
 
{
131
 
    const char *s = alcGetString(NULL, which);
132
 
    printf("Available %s devices:\n", kind);
133
 
    if(s == NULL || *s == '\0')
134
 
        printf("    (none!)\n");
 
90
    }
 
91
 
 
92
    do {
 
93
        next = strchr(list, separator);
 
94
        if(next)
 
95
        {
 
96
            len = next-list;
 
97
            do {
 
98
                next++;
 
99
            } while(*next == separator);
 
100
        }
 
101
        else
 
102
            len = strlen(list);
 
103
 
 
104
        if(len + col + 2 >= MAX_WIDTH)
 
105
        {
 
106
            fprintf(stdout, "\n%s", indent);
 
107
            col = strlen(indent);
 
108
        }
 
109
        else
 
110
        {
 
111
            fputc(' ', stdout);
 
112
            col++;
 
113
        }
 
114
 
 
115
        len = fwrite(list, 1, len, stdout);
 
116
        col += len;
 
117
 
 
118
        if(!next || *next == '\0')
 
119
            break;
 
120
        fputc(',', stdout);
 
121
        col++;
 
122
 
 
123
        list = next;
 
124
    } while(1);
 
125
    fputc('\n', stdout);
 
126
}
 
127
 
 
128
static void printDeviceList(const char *list)
 
129
{
 
130
    if(!list || *list == '\0')
 
131
        printf("    !!! none !!!\n");
135
132
    else do {
136
 
        printf("    %s\n", s);
137
 
        while(*s++ != '\0')
138
 
            ;
139
 
    } while(*s != '\0');
140
 
}
141
 
 
142
 
static void printALCInfo (void)
 
133
        printf("    %s\n", list);
 
134
        list += strlen(list) + 1;
 
135
    } while(*list != '\0');
 
136
}
 
137
 
 
138
 
 
139
static ALenum checkALErrors(int linenum)
 
140
{
 
141
    ALenum err = alGetError();
 
142
    if(err != AL_NO_ERROR)
 
143
        printf("OpenAL Error: %s (0x%x), @ %d\n", alGetString(err), err, linenum);
 
144
    return err;
 
145
}
 
146
#define checkALErrors() checkALErrors(__LINE__)
 
147
 
 
148
static ALCenum checkALCErrors(ALCdevice *device, int linenum)
 
149
{
 
150
    ALCenum err = alcGetError(device);
 
151
    if(err != ALC_NO_ERROR)
 
152
        printf("ALC Error: %s (0x%x), @ %d\n", alcGetString(device, err), err, linenum);
 
153
    return err;
 
154
}
 
155
#define checkALCErrors(x) checkALCErrors((x),__LINE__)
 
156
 
 
157
 
 
158
static void printALCInfo(ALCdevice *device)
143
159
{
144
160
    ALCint major, minor;
145
 
    ALCdevice *device;
146
 
 
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));
151
 
 
152
 
    device = alcGetContextsDevice(alcGetCurrentContext());
153
 
    checkForErrors();
154
161
 
155
162
    alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
156
163
    alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor);
157
 
    checkForErrors();
158
 
    printf("ALC version: %d.%d\n", (int)major, (int)minor);
159
 
 
160
 
    printList("ALC extensions", ' ', alcGetString(device, ALC_EXTENSIONS));
161
 
    checkForErrors();
 
164
    if(checkALCErrors(device) == ALC_NO_ERROR)
 
165
        printf("ALC version: %d.%d\n", major, minor);
 
166
    if(device)
 
167
    {
 
168
        printf("ALC extensions:");
 
169
        printList(alcGetString(device, ALC_EXTENSIONS), ' ');
 
170
        checkALCErrors(device);
 
171
    }
162
172
}
163
173
 
164
174
static void printALInfo(void)
166
176
    printf("OpenAL vendor string: %s\n", alGetString(AL_VENDOR));
167
177
    printf("OpenAL renderer string: %s\n", alGetString(AL_RENDERER));
168
178
    printf("OpenAL version string: %s\n", alGetString(AL_VERSION));
169
 
    printList("OpenAL extensions", ' ', alGetString(AL_EXTENSIONS));
170
 
    checkForErrors();
 
179
    printf("OpenAL extensions:");
 
180
    printList(alGetString(AL_EXTENSIONS), ' ');
 
181
    checkALErrors();
171
182
}
172
183
 
173
 
static void printEFXInfo(void)
 
184
static void printEFXInfo(ALCdevice *device)
174
185
{
175
186
    ALCint major, minor, sends;
176
 
    ALCdevice *device;
177
187
    ALuint obj;
178
188
    int i;
 
189
    const ALenum filters[] = {
 
190
        AL_FILTER_LOWPASS, AL_FILTER_HIGHPASS, AL_FILTER_BANDPASS,
 
191
        AL_FILTER_NULL
 
192
    };
 
193
    char filterNames[] = "Low-pass,High-pass,Band-pass,";
179
194
    const ALenum effects[] = {
180
195
        AL_EFFECT_EAXREVERB, AL_EFFECT_REVERB, AL_EFFECT_CHORUS,
181
196
        AL_EFFECT_DISTORTION, AL_EFFECT_ECHO, AL_EFFECT_FLANGER,
186
201
    char effectNames[] = "EAX Reverb,Reverb,Chorus,Distortion,Echo,Flanger,"
187
202
                         "Frequency Shifter,Vocal Morpher,Pitch Shifter,"
188
203
                         "Ring Modulator,Autowah,Compressor,Equalizer,";
189
 
    const ALenum filters[] = {
190
 
        AL_FILTER_LOWPASS, AL_FILTER_HIGHPASS, AL_FILTER_BANDPASS,
191
 
        AL_FILTER_NULL
192
 
    };
193
 
    char filterNames[] = "Low-pass,High-pass,Band-pass,";
194
204
    char *current;
195
205
 
196
 
    device = alcGetContextsDevice(alcGetCurrentContext());
197
 
    if(alcIsExtensionPresent(device, (const ALCchar*)"ALC_EXT_EFX") == AL_FALSE)
 
206
    if(alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_FALSE)
198
207
    {
199
208
        printf("EFX not available\n");
200
209
        return;
202
211
 
203
212
    alcGetIntegerv(device, ALC_EFX_MAJOR_VERSION, 1, &major);
204
213
    alcGetIntegerv(device, ALC_EFX_MINOR_VERSION, 1, &minor);
205
 
    checkForErrors();
206
 
    printf("EFX version: %d.%d\n", (int)major, (int)minor);
207
 
 
 
214
    if(checkALCErrors(device) == ALC_NO_ERROR)
 
215
        printf("EFX version: %d.%d\n", major, minor);
208
216
    alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &sends);
209
 
    checkForErrors();
210
 
    printf("Max auxiliary sends: %d\n", (int)sends);
 
217
    if(checkALCErrors(device) == ALC_NO_ERROR)
 
218
        printf("Max auxiliary sends: %d\n", sends);
211
219
 
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)
 
220
    palGenFilters = alGetProcAddress("alGenFilters");
 
221
    palDeleteFilters = alGetProcAddress("alDeleteFilters");
 
222
    palFilteri = alGetProcAddress("alFilteri");
 
223
    palGenEffects = alGetProcAddress("alGenEffects");
 
224
    palDeleteEffects = alGetProcAddress("alDeleteEffects");
 
225
    palEffecti = alGetProcAddress("alEffecti");
 
226
    if(checkALErrors() != AL_NO_ERROR ||
 
227
       !palGenFilters || !palDeleteFilters || !palFilteri ||
 
228
       !palGenEffects || !palDeleteEffects || !palEffecti)
221
229
    {
222
 
        printf("Missing EFX functions!\n");
 
230
        printf("!!! Missing EFX functions !!!\n");
223
231
        return;
224
232
    }
225
233
 
226
 
    p_alGenFilters(1, &obj);
227
 
    checkForErrors();
228
 
    current = filterNames;
229
 
    for(i = 0;filters[i] != AL_FILTER_NULL;i++)
230
 
    {
231
 
        char *next = strchr(current, ',');
232
 
 
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));
238
 
    }
239
 
    p_alDeleteFilters(1, &obj);
240
 
    checkForErrors();
241
 
    printList("Supported filters", ',', filterNames);
242
 
 
243
 
    p_alGenEffects(1, &obj);
244
 
    checkForErrors();
245
 
    current = effectNames;
246
 
    for(i = 0;effects[i] != AL_EFFECT_NULL;i++)
247
 
    {
248
 
        char *next = strchr(current, ',');
249
 
 
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));
255
 
    }
256
 
    p_alDeleteEffects(1, &obj);
257
 
    checkForErrors();
258
 
    printList("Supported effects", ',', effectNames);
 
234
    palGenFilters(1, &obj);
 
235
    if(checkALErrors() == AL_NO_ERROR)
 
236
    {
 
237
        current = filterNames;
 
238
        for(i = 0;filters[i] != AL_FILTER_NULL;i++)
 
239
        {
 
240
            char *next = strchr(current, ',');
 
241
 
 
242
            palFilteri(obj, AL_FILTER_TYPE, filters[i]);
 
243
            if(alGetError() == AL_NO_ERROR)
 
244
                current = next+1;
 
245
            else
 
246
                memmove(current, next+1, strlen(next));
 
247
        }
 
248
        palDeleteFilters(1, &obj);
 
249
        checkALErrors();
 
250
 
 
251
        printf("Supported filters:");
 
252
        printList(filterNames, ',');
 
253
    }
 
254
 
 
255
    palGenEffects(1, &obj);
 
256
    if(checkALErrors() == AL_NO_ERROR)
 
257
    {
 
258
        current = effectNames;
 
259
        for(i = 0;effects[i] != AL_EFFECT_NULL;i++)
 
260
        {
 
261
            char *next = strchr(current, ',');
 
262
 
 
263
            palEffecti(obj, AL_EFFECT_TYPE, effects[i]);
 
264
            if(alGetError() == AL_NO_ERROR)
 
265
                current = next+1;
 
266
            else
 
267
                memmove(current, next+1, strlen(next));
 
268
        }
 
269
        palDeleteEffects(1, &obj);
 
270
        checkALErrors();
 
271
 
 
272
        printf("Supported effects:");
 
273
        printList(effectNames, ',');
 
274
    }
259
275
}
260
276
 
261
 
int main()
 
277
int main(int argc, char *argv[])
262
278
{
263
279
    ALCdevice *device;
264
280
    ALCcontext *context;
265
281
 
266
 
    if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT") == AL_TRUE)
 
282
    if(argc > 1 && (strcmp(argv[1], "--help") == 0 ||
 
283
                    strcmp(argv[1], "-h") == 0))
267
284
    {
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");
 
285
        printf("Usage: %s [playback device]\n", argv[0]);
 
286
        return 0;
273
287
    }
 
288
 
 
289
    printf("Available playback devices:\n");
 
290
    if(alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
 
291
        printDeviceList(alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER));
274
292
    else
275
 
        printf("No device enumeration available\n");
276
 
 
277
 
    device = alcOpenDevice(NULL);
 
293
        printDeviceList(alcGetString(NULL, ALC_DEVICE_SPECIFIER));
 
294
    printf("Available capture devices:\n");
 
295
    printDeviceList(alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER));
 
296
 
 
297
    printf("Default playback device: %s\n",
 
298
           alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));
 
299
    printf("Default capture device: %s\n",
 
300
           alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
 
301
 
 
302
    printALCInfo(NULL);
 
303
 
 
304
    device = alcOpenDevice((argc>1) ? argv[1] : NULL);
278
305
    if(!device)
279
306
    {
280
 
        printf("Failed to open a device!\n");
281
 
        exit(EXIT_FAILURE);
 
307
        printf("\n!!! Failed to open %s !!!\n\n", ((argc>1) ? argv[1] : "default device"));
 
308
        return 1;
282
309
    }
 
310
 
 
311
    printf("\n** Info for device \"%s\" **\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
 
312
    printALCInfo(device);
 
313
 
283
314
    context = alcCreateContext(device, NULL);
284
315
    if(!context || alcMakeContextCurrent(context) == ALC_FALSE)
285
316
    {
286
 
        printf("Failed to set a context!\n");
287
 
        exit(EXIT_FAILURE);
 
317
        if(context)
 
318
            alcDestroyContext(context);
 
319
        alcCloseDevice(device);
 
320
        printf("\n!!! Failed to set a context !!!\n\n");
 
321
        return 1;
288
322
    }
289
323
 
290
 
    printALCInfo();
291
324
    printALInfo();
292
 
    printEFXInfo();
293
 
    checkForErrors();
 
325
    printEFXInfo(device);
294
326
 
295
327
    alcMakeContextCurrent(NULL);
296
328
    alcDestroyContext(context);
297
329
    alcCloseDevice(device);
298
330
 
299
 
    return EXIT_SUCCESS;
 
331
    return 0;
300
332
}