aboutsummaryrefslogtreecommitdiffstats
path: root/examples/alhelpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/alhelpers.c')
-rw-r--r--examples/alhelpers.c226
1 files changed, 226 insertions, 0 deletions
diff --git a/examples/alhelpers.c b/examples/alhelpers.c
new file mode 100644
index 00000000..ba23cabd
--- /dev/null
+++ b/examples/alhelpers.c
@@ -0,0 +1,226 @@
+/*
+ * OpenAL Helpers
+ *
+ * Copyright (c) 2011 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.
+ */
+
+/* This file contains routines to help with some menial OpenAL-related tasks,
+ * such as opening a device and setting up a context, closing the device and
+ * destroying its context, converting between frame counts and byte lengths,
+ * finding an appropriate buffer format, and getting readable strings for
+ * channel configs and sample types. */
+
+#include <stdio.h>
+
+#include "AL/al.h"
+#include "AL/alc.h"
+#include "AL/alext.h"
+
+#include "alhelpers.h"
+
+
+const char *ChannelsName(ALenum chans)
+{
+ switch(chans)
+ {
+ case AL_MONO: return "Mono";
+ case AL_STEREO: return "Stereo";
+ case AL_REAR: return "Rear";
+ case AL_QUAD: return "Quadraphonic";
+ case AL_5POINT1: return "5.1 Surround";
+ case AL_6POINT1: return "6.1 Surround";
+ case AL_7POINT1: return "7.1 Surround";
+ }
+ return "Unknown Channels";
+}
+
+const char *TypeName(ALenum type)
+{
+ switch(type)
+ {
+ case AL_BYTE: return "S8";
+ case AL_UNSIGNED_BYTE: return "U8";
+ case AL_SHORT: return "S16";
+ case AL_UNSIGNED_SHORT: return "U16";
+ case AL_INT: return "S32";
+ case AL_UNSIGNED_INT: return "U32";
+ case AL_FLOAT: return "Float32";
+ case AL_DOUBLE: return "Float64";
+ }
+ return "Unknown Type";
+}
+
+
+ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type)
+{
+ switch(channels)
+ {
+ case AL_MONO: size *= 1; break;
+ case AL_STEREO: size *= 2; break;
+ case AL_REAR: size *= 2; break;
+ case AL_QUAD: size *= 4; break;
+ case AL_5POINT1: size *= 6; break;
+ case AL_6POINT1: size *= 7; break;
+ case AL_7POINT1: size *= 8; break;
+ }
+
+ switch(type)
+ {
+ case AL_BYTE: size *= sizeof(ALbyte); break;
+ case AL_UNSIGNED_BYTE: size *= sizeof(ALubyte); break;
+ case AL_SHORT: size *= sizeof(ALshort); break;
+ case AL_UNSIGNED_SHORT: size *= sizeof(ALushort); break;
+ case AL_INT: size *= sizeof(ALint); break;
+ case AL_UNSIGNED_INT: size *= sizeof(ALuint); break;
+ case AL_FLOAT: size *= sizeof(ALfloat); break;
+ case AL_DOUBLE: size *= sizeof(ALdouble); break;
+ }
+
+ return size;
+}
+
+ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type)
+{
+ return size / FramesToBytes(1, channels, type);
+}
+
+
+ALenum GetFormat(ALenum channels, ALenum type)
+{
+ ALenum format = 0;
+
+ /* We use the AL_EXT_MCFORMATS extension to provide output of Quad, 5.1,
+ * and 7.1 channel configs, AL_EXT_FLOAT32 for 32-bit float samples, and
+ * AL_EXT_DOUBLE for 64-bit float samples. */
+ if(type == AL_UNSIGNED_BYTE)
+ {
+ if(channels == AL_MONO)
+ format = AL_FORMAT_MONO8;
+ else if(channels == AL_STEREO)
+ format = AL_FORMAT_STEREO8;
+ else if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
+ {
+ if(channels == AL_QUAD)
+ format = alGetEnumValue("AL_FORMAT_QUAD8");
+ else if(channels == AL_5POINT1)
+ format = alGetEnumValue("AL_FORMAT_51CHN8");
+ else if(channels == AL_6POINT1)
+ format = alGetEnumValue("AL_FORMAT_61CHN8");
+ else if(channels == AL_7POINT1)
+ format = alGetEnumValue("AL_FORMAT_71CHN8");
+ }
+ }
+ else if(type == AL_SHORT)
+ {
+ if(channels == AL_MONO)
+ format = AL_FORMAT_MONO16;
+ else if(channels == AL_STEREO)
+ format = AL_FORMAT_STEREO16;
+ else if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
+ {
+ if(channels == AL_QUAD)
+ format = alGetEnumValue("AL_FORMAT_QUAD16");
+ else if(channels == AL_5POINT1)
+ format = alGetEnumValue("AL_FORMAT_51CHN16");
+ else if(channels == AL_6POINT1)
+ format = alGetEnumValue("AL_FORMAT_61CHN16");
+ else if(channels == AL_7POINT1)
+ format = alGetEnumValue("AL_FORMAT_71CHN16");
+ }
+ }
+ else if(type == AL_FLOAT && alIsExtensionPresent("AL_EXT_FLOAT32"))
+ {
+ if(channels == AL_MONO)
+ format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
+ else if(channels == AL_STEREO)
+ format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
+ else if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
+ {
+ if(channels == AL_QUAD)
+ format = alGetEnumValue("AL_FORMAT_QUAD32");
+ else if(channels == AL_5POINT1)
+ format = alGetEnumValue("AL_FORMAT_51CHN32");
+ else if(channels == AL_6POINT1)
+ format = alGetEnumValue("AL_FORMAT_61CHN32");
+ else if(channels == AL_7POINT1)
+ format = alGetEnumValue("AL_FORMAT_71CHN32");
+ }
+ }
+ else if(type == AL_DOUBLE && alIsExtensionPresent("AL_EXT_DOUBLE"))
+ {
+ if(channels == AL_MONO)
+ format = alGetEnumValue("AL_FORMAT_MONO_DOUBLE");
+ else if(channels == AL_STEREO)
+ format = alGetEnumValue("AL_FORMAT_STEREO_DOUBLE");
+ }
+
+ /* NOTE: It seems OSX returns -1 from alGetEnumValue for unknown enums, as
+ * opposed to 0. Correct it. */
+ if(format == -1)
+ format = 0;
+
+ return format;
+}
+
+
+int InitAL(void)
+{
+ ALCdevice *device;
+ ALCcontext *ctx;
+
+ /* Open and initialize a device with default settings */
+ device = alcOpenDevice(NULL);
+ if(!device)
+ {
+ fprintf(stderr, "Could not open a device!\n");
+ return 1;
+ }
+
+ ctx = alcCreateContext(device, NULL);
+ if(ctx == NULL || alcMakeContextCurrent(ctx) == ALC_FALSE)
+ {
+ if(ctx != NULL)
+ alcDestroyContext(ctx);
+ alcCloseDevice(device);
+ fprintf(stderr, "Could not set a context!\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+void CloseAL(void)
+{
+ ALCdevice *device;
+ ALCcontext *ctx;
+
+ /* Close the device belonging to the current context, and destroy the
+ * context. */
+ ctx = alcGetCurrentContext();
+ if(ctx == NULL)
+ return;
+
+ device = alcGetContextsDevice(ctx);
+
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(ctx);
+ alcCloseDevice(device);
+}