4 * Copyright (c) 2011 by Chris Robinson <chris.kcat@gmail.com>
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
25 /* This file contains routines to help with some menial OpenAL-related tasks,
26 * such as opening a device and setting up a context, closing the device and
27 * destroying its context, converting between frame counts and byte lengths,
28 * finding an appropriate buffer format, and getting readable strings for
29 * channel configs and sample types. */
37 #include "alhelpers.h"
40 const char *ChannelsName(ALenum chans
)
44 case AL_MONO
: return "Mono";
45 case AL_STEREO
: return "Stereo";
46 case AL_REAR
: return "Rear";
47 case AL_QUAD
: return "Quadraphonic";
48 case AL_5POINT1
: return "5.1 Surround";
49 case AL_6POINT1
: return "6.1 Surround";
50 case AL_7POINT1
: return "7.1 Surround";
52 return "Unknown Channels";
55 const char *TypeName(ALenum type
)
59 case AL_BYTE
: return "S8";
60 case AL_UNSIGNED_BYTE
: return "U8";
61 case AL_SHORT
: return "S16";
62 case AL_UNSIGNED_SHORT
: return "U16";
63 case AL_INT
: return "S32";
64 case AL_UNSIGNED_INT
: return "U32";
65 case AL_FLOAT
: return "Float32";
66 case AL_DOUBLE
: return "Float64";
68 return "Unknown Type";
72 ALsizei
FramesToBytes(ALsizei size
, ALenum channels
, ALenum type
)
76 case AL_MONO
: size
*= 1; break;
77 case AL_STEREO
: size
*= 2; break;
78 case AL_REAR
: size
*= 2; break;
79 case AL_QUAD
: size
*= 4; break;
80 case AL_5POINT1
: size
*= 6; break;
81 case AL_6POINT1
: size
*= 7; break;
82 case AL_7POINT1
: size
*= 8; break;
87 case AL_BYTE
: size
*= sizeof(ALbyte
); break;
88 case AL_UNSIGNED_BYTE
: size
*= sizeof(ALubyte
); break;
89 case AL_SHORT
: size
*= sizeof(ALshort
); break;
90 case AL_UNSIGNED_SHORT
: size
*= sizeof(ALushort
); break;
91 case AL_INT
: size
*= sizeof(ALint
); break;
92 case AL_UNSIGNED_INT
: size
*= sizeof(ALuint
); break;
93 case AL_FLOAT
: size
*= sizeof(ALfloat
); break;
94 case AL_DOUBLE
: size
*= sizeof(ALdouble
); break;
100 ALsizei
BytesToFrames(ALsizei size
, ALenum channels
, ALenum type
)
102 return size
/ FramesToBytes(1, channels
, type
);
106 ALenum
GetFormat(ALenum channels
, ALenum type
)
110 /* We use the AL_EXT_MCFORMATS extension to provide output of Quad, 5.1,
111 * and 7.1 channel configs, AL_EXT_FLOAT32 for 32-bit float samples, and
112 * AL_EXT_DOUBLE for 64-bit float samples. */
113 if(type
== AL_UNSIGNED_BYTE
)
115 if(channels
== AL_MONO
)
116 format
= AL_FORMAT_MONO8
;
117 else if(channels
== AL_STEREO
)
118 format
= AL_FORMAT_STEREO8
;
119 else if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
121 if(channels
== AL_QUAD
)
122 format
= alGetEnumValue("AL_FORMAT_QUAD8");
123 else if(channels
== AL_5POINT1
)
124 format
= alGetEnumValue("AL_FORMAT_51CHN8");
125 else if(channels
== AL_6POINT1
)
126 format
= alGetEnumValue("AL_FORMAT_61CHN8");
127 else if(channels
== AL_7POINT1
)
128 format
= alGetEnumValue("AL_FORMAT_71CHN8");
131 else if(type
== AL_SHORT
)
133 if(channels
== AL_MONO
)
134 format
= AL_FORMAT_MONO16
;
135 else if(channels
== AL_STEREO
)
136 format
= AL_FORMAT_STEREO16
;
137 else if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
139 if(channels
== AL_QUAD
)
140 format
= alGetEnumValue("AL_FORMAT_QUAD16");
141 else if(channels
== AL_5POINT1
)
142 format
= alGetEnumValue("AL_FORMAT_51CHN16");
143 else if(channels
== AL_6POINT1
)
144 format
= alGetEnumValue("AL_FORMAT_61CHN16");
145 else if(channels
== AL_7POINT1
)
146 format
= alGetEnumValue("AL_FORMAT_71CHN16");
149 else if(type
== AL_FLOAT
&& alIsExtensionPresent("AL_EXT_FLOAT32"))
151 if(channels
== AL_MONO
)
152 format
= alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
153 else if(channels
== AL_STEREO
)
154 format
= alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
155 else if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
157 if(channels
== AL_QUAD
)
158 format
= alGetEnumValue("AL_FORMAT_QUAD32");
159 else if(channels
== AL_5POINT1
)
160 format
= alGetEnumValue("AL_FORMAT_51CHN32");
161 else if(channels
== AL_6POINT1
)
162 format
= alGetEnumValue("AL_FORMAT_61CHN32");
163 else if(channels
== AL_7POINT1
)
164 format
= alGetEnumValue("AL_FORMAT_71CHN32");
167 else if(type
== AL_DOUBLE
&& alIsExtensionPresent("AL_EXT_DOUBLE"))
169 if(channels
== AL_MONO
)
170 format
= alGetEnumValue("AL_FORMAT_MONO_DOUBLE");
171 else if(channels
== AL_STEREO
)
172 format
= alGetEnumValue("AL_FORMAT_STEREO_DOUBLE");
175 /* NOTE: It seems OSX returns -1 from alGetEnumValue for unknown enums, as
176 * opposed to 0. Correct it. */
189 /* Open and initialize a device with default settings */
190 device
= alcOpenDevice(NULL
);
193 fprintf(stderr
, "Could not open a device!\n");
197 ctx
= alcCreateContext(device
, NULL
);
198 if(ctx
== NULL
|| alcMakeContextCurrent(ctx
) == ALC_FALSE
)
201 alcDestroyContext(ctx
);
202 alcCloseDevice(device
);
203 fprintf(stderr
, "Could not set a context!\n");
215 /* Close the device belonging to the current context, and destroy the
217 ctx
= alcGetCurrentContext();
221 device
= alcGetContextsDevice(ctx
);
223 alcMakeContextCurrent(NULL
);
224 alcDestroyContext(ctx
);
225 alcCloseDevice(device
);