--- /dev/null
+package "mspal"
+{
+ version "0.0";
+ description "C++ wrapper for OpenAL";
+
+ require "vorbisfile";
+ require "openal";
+ require "mspcore";
+
+ library "mspal"
+ {
+ source "source";
+ install true;
+ install_headers "msp/al";
+ };
+};
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#include "buffer.h"
+#include "sound.h"
+
+using namespace std;
+
+namespace Msp {
+namespace AL {
+
+Buffer::Buffer()
+{
+ alGenBuffers(1, &id);
+}
+
+Buffer::~Buffer()
+{
+ alDeleteBuffers(1, &id);
+}
+
+void Buffer::data(Format fmt, const void *dt, sizei size, sizei freq)
+{
+ alBufferData(id, fmt, dt, size, freq);
+}
+
+void Buffer::load_data(const string &fn)
+{
+ Sound sound;
+ sound.load(fn);
+
+ data(sound.get_format(), sound.get_data(), sound.get_size(), sound.get_frequency());
+}
+
+} // namespace AL
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#ifndef MSP_AL_BUFFER_H_
+#define MSP_AL_BUFFER_H_
+
+#include <string>
+#include <AL/al.h>
+#include "format.h"
+#include "types.h"
+
+namespace Msp {
+namespace AL {
+
+class Buffer
+{
+private:
+ uint id;
+
+public:
+ Buffer();
+ ~Buffer();
+
+ uint get_id() const { return id; }
+ void data(Format, const void *, sizei, sizei);
+ void load_data(const std::string &);
+};
+
+} // namespace AL
+} // namespace Msp
+
+#endif
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#include <msp/core/except.h>
+#include "context.h"
+#include "device.h"
+
+namespace Msp {
+namespace AL {
+
+Context::Context(Device &dev)
+{
+ context=alcCreateContext(dev.get_device(), 0);
+ if(!context)
+ throw Exception("Couldn't create OpenAL context");
+
+ alcMakeContextCurrent(context);
+}
+
+} // namespace AL
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#ifndef MSP_AL_CONTEXT_H_
+#define MSP_AL_CONTEXT_H_
+
+#include <AL/alc.h>
+
+namespace Msp {
+namespace AL {
+
+class Device;
+
+class Context
+{
+private:
+ ALCcontext *context;
+
+public:
+ Context(Device &);
+};
+
+} // namespace AL
+} // namespace Msp
+
+#endif
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#include <msp/core/except.h>
+#include "device.h"
+
+using namespace std;
+
+namespace Msp {
+namespace AL {
+
+Device::Device()
+{
+ dev=alcOpenDevice(0);
+ if(!dev)
+ throw Exception("Couldn't get OpenAL device");
+}
+
+Device::Device(const string &spec)
+{
+ dev=alcOpenDevice(spec.c_str());
+ if(!dev)
+ throw Exception("Couldn't get OpenAL device");
+}
+
+} // namespace AL
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#ifndef MSP_AL_DEVICE_H_
+#define MSP_AL_DEVICE_H_
+
+#include <string>
+#include <AL/alc.h>
+
+namespace Msp {
+namespace AL {
+
+class Device
+{
+private:
+ ALCdevice *dev;
+
+public:
+ Device();
+ Device(const std::string &);
+ ALCdevice *get_device() { return dev; }
+};
+
+} // namespace AL
+} // namespace Msp
+
+#endif
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#ifndef MSP_AL_FORMAT_H_
+#define MSP_AL_FORMAT_H_
+
+#include <AL/al.h>
+
+namespace Msp {
+namespace AL {
+
+enum Format
+{
+ MONO8 = AL_FORMAT_MONO8,
+ MONO16 = AL_FORMAT_MONO16,
+ STEREO8 = AL_FORMAT_STEREO8,
+ STEREO16 = AL_FORMAT_STEREO16
+};
+
+} // namespace AL
+} // namespace Msp
+
+#endif
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#include "listener.h"
+
+namespace Msp {
+namespace AL {
+
+void Listener::attribute(ALenum attr, float v)
+{
+ alListenerf(attr, v);
+}
+
+void Listener::attribute(ALenum attr, float v0, float v1, float v2)
+{
+ alListener3f(attr, v0, v1, v2);
+}
+
+void Listener::attribute(ALenum attr, const float *v)
+{
+ alListenerfv(attr, v);
+}
+
+void Listener::set_position(float x, float y, float z)
+{
+ attribute(AL_POSITION, x, y, z);
+}
+
+void Listener::set_gain(float g)
+{
+ attribute(AL_GAIN, g);
+}
+
+} // namespace AL
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#ifndef MSP_AL_LIStENER_H_
+#define MSP_AL_LISTENER_H_
+
+#include <AL/al.h>
+
+namespace Msp {
+namespace AL {
+
+class Listener
+{
+private:
+ Listener();
+public:
+ static void attribute(ALenum, float);
+ static void attribute(ALenum, float, float, float);
+ static void attribute(ALenum, const float *);
+ static void set_position(float, float, float);
+ static void set_gain(float);
+};
+
+} // namespace AL
+} // namespace Msp
+
+#endif
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#include <msp/core/except.h>
+#include "sound.h"
+
+using namespace std;
+
+namespace Msp {
+namespace AL {
+
+Sound::Sound():
+ data(0)
+{
+ ovfile.datasource=0;
+}
+
+Sound::~Sound()
+{
+ if(ovfile.datasource)
+ ov_clear(&ovfile);
+}
+
+void Sound::open(const string &fn)
+{
+ if(ov_fopen(const_cast<char *>(fn.c_str()), &ovfile)<0)
+ throw Exception("Could not open ogg vorbis file");
+
+ vorbis_info *info=ov_info(&ovfile, -1);
+ freq=info->rate;
+ switch(info->channels)
+ {
+ case 1: format=MONO16; break;
+ case 2: format=STEREO16; break;
+ default: throw Exception("Unsupported number of channels");
+ }
+}
+
+void Sound::load_data()
+{
+ if(data)
+ throw InvalidState("Data has already been loaded");
+
+ size=ov_pcm_total(&ovfile, 0)*4;
+ data=new char[size];
+ unsigned pos=0;
+ while(unsigned len=read(data+pos, size-pos))
+ pos+=len;
+ size=pos;
+}
+
+void Sound::load(const string &fn)
+{
+ open(fn);
+ load_data();
+}
+
+const char *Sound::get_data() const
+{
+ if(!data)
+ throw InvalidState("Data has not been loaded");
+ return data;
+}
+
+unsigned Sound::read(char *buf, unsigned len)
+{
+ int section=0;
+ int res=ov_read(&ovfile, buf, len, 0, 2, 1, §ion);
+ if(res<0)
+ throw Exception("Error reading ogg vorbis file");
+ return res;
+}
+
+} // namespace AL
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#ifndef MSP_AL_SOUND_H_
+#define MSP_AL_SOUND_H_
+
+#include <vorbis/vorbisfile.h>
+#include "format.h"
+
+namespace Msp {
+namespace AL {
+
+class Sound
+{
+private:
+ OggVorbis_File ovfile;
+ unsigned freq;
+ unsigned size;
+ char *data;
+ Format format;
+
+public:
+ Sound();
+ ~Sound();
+
+ void open(const std::string &);
+ void load_data();
+ void load(const std::string &);
+ Format get_format() const { return format; }
+ unsigned get_frequency() const { return freq; }
+ unsigned get_size() const { return size; }
+ const char *get_data() const;
+ unsigned read(char *, unsigned);
+};
+
+} // namespace AL
+} // namespace Msp
+
+#endif
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#include "buffer.h"
+#include "source.h"
+
+using namespace std;
+
+namespace Msp {
+namespace AL {
+
+Source::Source()
+{
+ alGenSources(1, &id);
+}
+
+Source::~Source()
+{
+ alDeleteSources(1, &id);
+}
+
+void Source::attribute(ALenum attr, int v)
+{
+ alSourcei(id, attr, v);
+}
+
+void Source::attribute(ALenum attr, float v)
+{
+ alSourcef(id, attr, v);
+}
+
+void Source::attribute(ALenum attr, float v0, float v1, float v2)
+{
+ alSource3f(id, attr, v0, v1, v2);
+}
+
+void Source::attribute(ALenum attr, const float *v)
+{
+ alSourcefv(id, attr, v);
+}
+
+void Source::set_buffer(Buffer &buffer)
+{
+ attribute(AL_BUFFER, static_cast<int>(buffer.get_id()));
+}
+
+void Source::queue_buffers(const vector<Buffer *> &buffers)
+{
+ vector<uint> ids;
+ ids.reserve(buffers.size());
+ for(vector<Buffer *>::const_iterator i=buffers.begin(); i!=buffers.end(); ++i)
+ ids.push_back((*i)->get_id());
+ alSourceQueueBuffers(id, ids.size(), &ids.front());
+}
+
+void Source::queue_buffer(Buffer &buffer)
+{
+ uint bid=buffer.get_id();
+ alSourceQueueBuffers(id, 1, &bid);
+}
+
+} // namespace AL
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#ifndef MSP_AL_SOURCE_H_
+#define MSP_AL_SOURCE_H_
+
+#include <vector>
+#include <AL/al.h>
+
+namespace Msp {
+namespace AL {
+
+class Buffer;
+
+class Source
+{
+private:
+ uint id;
+
+public:
+ Source();
+ ~Source();
+
+ void attribute(ALenum, int);
+ void attribute(ALenum, float);
+ void attribute(ALenum, float, float, float);
+ void attribute(ALenum, const float *);
+ void set_buffer(Buffer &);
+ void queue_buffers(const std::vector<Buffer *> &);
+ void queue_buffer(Buffer &);
+};
+
+} // namespace AL
+} // namespace Msp
+
+#endif
--- /dev/null
+/* $Id$
+
+This file is part of libmspal
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Diestributed under the LGPL
+*/
+
+#ifndef MSP_AL_TYPES_H_
+#define MSP_AL_TYPES_H_
+
+namespace Msp {
+namespace AL {
+
+typedef unsigned uint;
+typedef unsigned sizei;
+
+} // namespace AL
+} // namespace Msp
+
+#endif