Append _SOFT to the AL_SOFT_buffer_samples enums
[openal-soft.git] / examples / alhelpers.c
blobba23cabd5ab71c7dab122a610b253d961239f5dd
1 /*
2 * OpenAL Helpers
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
22 * THE SOFTWARE.
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. */
31 #include <stdio.h>
33 #include "AL/al.h"
34 #include "AL/alc.h"
35 #include "AL/alext.h"
37 #include "alhelpers.h"
40 const char *ChannelsName(ALenum chans)
42 switch(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)
57 switch(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)
74 switch(channels)
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;
85 switch(type)
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;
97 return size;
100 ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type)
102 return size / FramesToBytes(1, channels, type);
106 ALenum GetFormat(ALenum channels, ALenum type)
108 ALenum format = 0;
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. */
177 if(format == -1)
178 format = 0;
180 return format;
184 int InitAL(void)
186 ALCdevice *device;
187 ALCcontext *ctx;
189 /* Open and initialize a device with default settings */
190 device = alcOpenDevice(NULL);
191 if(!device)
193 fprintf(stderr, "Could not open a device!\n");
194 return 1;
197 ctx = alcCreateContext(device, NULL);
198 if(ctx == NULL || alcMakeContextCurrent(ctx) == ALC_FALSE)
200 if(ctx != NULL)
201 alcDestroyContext(ctx);
202 alcCloseDevice(device);
203 fprintf(stderr, "Could not set a context!\n");
204 return 1;
207 return 0;
210 void CloseAL(void)
212 ALCdevice *device;
213 ALCcontext *ctx;
215 /* Close the device belonging to the current context, and destroy the
216 * context. */
217 ctx = alcGetCurrentContext();
218 if(ctx == NULL)
219 return;
221 device = alcGetContextsDevice(ctx);
223 alcMakeContextCurrent(NULL);
224 alcDestroyContext(ctx);
225 alcCloseDevice(device);