]> git.tdb.fi Git - libs/al.git/commitdiff
Two more atribute setting functions in Source
authorMikko Rasa <tdb@tdb.fi>
Wed, 9 Jul 2008 16:06:09 +0000 (16:06 +0000)
committerMikko Rasa <tdb@tdb.fi>
Wed, 9 Jul 2008 16:06:09 +0000 (16:06 +0000)
Support loading Sounds from memory
Support loading Buffers from datafiles
Automatically clear Sound from Streamer when eof is reached

source/buffer.cpp
source/buffer.h
source/sound.cpp
source/sound.h
source/source.cpp
source/source.h
source/streamer.cpp

index b2ef01698c948221877c312abfa476ce4f5326fa..8f5b4aa6daf98dbe2a5cfd3ea61ca0f3f74293ef 100644 (file)
@@ -28,12 +28,32 @@ void Buffer::data(Format fmt, const void *dt, sizei size, sizei freq)
        alBufferData(id, fmt, dt, size, freq);
 }
 
+void Buffer::data(const Sound &snd)
+{
+       data(snd.get_format(), snd.get_data(), snd.get_size(), snd.get_frequency());
+}
+
 void Buffer::load_data(const string &fn)
 {
        Sound sound;
-       sound.load(fn);
+       sound.load_file(fn);
+
+       data(sound);
+}
+
+
+Buffer::Loader::Loader(Buffer &b):
+       buf(b)
+{
+       add("sound_data", &Loader::sound_data);
+}
+
+void Buffer::Loader::sound_data(const string &data)
+{
+       Sound sound;
+       sound.load_memory(data.data(), data.size());
 
-       data(sound.get_format(), sound.get_data(), sound.get_size(), sound.get_frequency());
+       buf.data(sound);
 }
 
 } // namespace AL
index f7ac307da7b644ff8f79eec80f81b90d02e2fce5..3680e5411ac3f7dd900846a652dc00b0fcfc1fbc 100644 (file)
@@ -10,14 +10,29 @@ Distributed under the LGPL
 
 #include <string>
 #include <AL/al.h>
+#include <msp/datafile/loader.h>
 #include "format.h"
 #include "types.h"
 
 namespace Msp {
 namespace AL {
 
+class Sound;
+
 class Buffer
 {
+public:
+       class Loader: public DataFile::Loader
+       {
+       private:
+               Buffer &buf;
+
+       public:
+               Loader(Buffer &);
+       private:
+               void sound_data(const std::string &);
+       };
+
 private:
        uint id;
 
@@ -27,6 +42,7 @@ public:
 
        uint get_id() const { return id; }
        void data(Format, const void *, sizei, sizei);
+       void data(const Sound &);
        void load_data(const std::string &);
 };
 
index b2744b3abedeb9682a8c08e6ffbead563280f2dd..8b6af20fcde8fe2c0ea22951a8d138c3dece0289 100644 (file)
@@ -11,49 +11,102 @@ Distributed under the LGPL
 
 using namespace std;
 
-namespace Msp {
-namespace AL {
+namespace {
 
-Sound::Sound():
-       data(0),
-       eof_flag(false)
+struct MemorySource
 {
-       ovfile.datasource=0;
+       const void *data;
+       unsigned length;
+       unsigned pos;
+
+       MemorySource(const void *d, unsigned l): data(d), length(l), pos(0) { }
+};
+
+size_t memory_read(void *ptr, size_t size, size_t nmemb, void *src)
+{
+       MemorySource &memsrc=*reinterpret_cast<MemorySource *>(src);
+       unsigned len=min(size*nmemb, memsrc.length-memsrc.pos);
+       memcpy(ptr, reinterpret_cast<const char *>(memsrc.data)+memsrc.pos, len);
+       memsrc.pos+=len;
+
+       return len/size;
+}
+
+int memory_seek(void *src, ogg_int64_t offset, int whence)
+{
+       MemorySource &memsrc=*reinterpret_cast<MemorySource *>(src);
+       if(whence==SEEK_SET)
+               memsrc.pos=offset;
+       else if(whence==SEEK_CUR)
+               memsrc.pos+=offset;
+       else if(whence==SEEK_END)
+               memsrc.pos=memsrc.length-offset;
+       memsrc.pos=min(memsrc.pos, memsrc.length);
+
+       return memsrc.pos;
+}
+
+void memory_close(void *src)
+{
+       delete reinterpret_cast<MemorySource *>(src);
+}
+
+long memory_tell(void *src)
+{
+       MemorySource &memsrc=*reinterpret_cast<MemorySource *>(src);
+       return memsrc.pos;
 }
 
-Sound::Sound(const std::string &fn):
+ov_callbacks memory_callbacks=
+{
+       &memory_read,
+       &memory_seek,
+       0,
+       &memory_tell
+};
+
+} // namespace
+
+namespace Msp {
+namespace AL {
+
+Sound::Sound():
        data(0),
        eof_flag(false)
 {
        ovfile.datasource=0;
-       open(fn);
 }
 
 Sound::~Sound()
 {
-       delete data;
+       delete[] data;
        if(ovfile.datasource)
                ov_clear(&ovfile);
 }
 
-void Sound::open(const string &fn)
+void Sound::open_file(const string &fn)
 {
        if(ovfile.datasource)
                throw InvalidState("Sound has already been opened");
        if(ov_fopen(const_cast<char *>(fn.c_str()), &ovfile)<0)
                throw Exception("Could not open ogg vorbis file "+fn);
 
-       delete data;
-       data=0;
+       open_common();
+}
 
-       vorbis_info *info=ov_info(&ovfile, -1);
-       freq=info->rate;
-       switch(info->channels)
+void Sound::open_memory(const void *d, unsigned len)
+{
+       if(ovfile.datasource)
+               throw InvalidState("Sound has already been opened");
+
+       MemorySource *src=new MemorySource(d, len);
+       if(ov_open_callbacks(src, &ovfile, 0, 0, memory_callbacks)<0)
        {
-       case 1: format=MONO16; break;
-       case 2: format=STEREO16; break;
-       default: throw Exception("Unsupported number of channels");
+               delete src;
+               throw Exception("Could not open ogg vorbis memory block");
        }
+
+       open_common();
 }
 
 void Sound::load_data()
@@ -68,11 +121,19 @@ void Sound::load_data()
                pos+=len;
        data=dptr;
        size=pos;
+       read_pos=0;
+}
+
+void Sound::load_file(const std::string &fn)
+{
+       open_file(fn);
+       load_data();
+       close();
 }
 
-void Sound::load(const string &fn)
+void Sound::load_memory(const void *d, unsigned len)
 {
-       open(fn);
+       open_memory(d, len);
        load_data();
        close();
 }
@@ -121,5 +182,20 @@ const char *Sound::get_data() const
        return data;
 }
 
+void Sound::open_common()
+{
+       delete data;
+       data=0;
+
+       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");
+       }
+}
+
 } // namespace AL
 } // namespace Msp
index 1badf3c03a9d01ff03f211daf539579278faec3b..a97de4623f9704bcdf0003733c683ea6b2edb915 100644 (file)
@@ -28,12 +28,13 @@ private:
 
 public:
        Sound();
-       Sound(const std::string &);
        ~Sound();
 
-       void open(const std::string &);
+       void open_file(const std::string &);
+       void open_memory(const void *, unsigned);
        void load_data();
-       void load(const std::string &);
+       void load_file(const std::string &);
+       void load_memory(const void *, unsigned);
        void close();
        void rewind();
        unsigned read(char *, unsigned);
@@ -43,6 +44,8 @@ public:
        unsigned get_frequency() const { return freq; }
        unsigned get_size() const { return size; }
        const char *get_data() const;
+private:
+       void open_common();
 };
 
 } // namespace AL
index 3619b1d61205c9128d0ffb87d7e66909acf738f2..137b785d131ac008b47f335edff6dc5abbb34cdc 100644 (file)
@@ -84,6 +84,16 @@ void Source::set_looping(bool l)
        attribute(AL_LOOPING, l);
 }
 
+void Source::set_gain(float g)
+{
+       attribute(AL_GAIN, g);
+}
+
+void Source::set_rolloff_factor(float f)
+{
+       attribute(AL_ROLLOFF_FACTOR, f);
+}
+
 void Source::set_buffer(const Buffer &buffer)
 {
        attribute(AL_BUFFER, static_cast<int>(buffer.get_id()));
index 090de0ff36b12e30666fdff8f55c2bd821122046..d5b4663d7d3b9da7a4f1886c2ac10fbb55dd89f1 100644 (file)
@@ -45,6 +45,8 @@ public:
        unsigned get_buffers_processed() const;
        void set_position(float, float, float);
        void set_looping(bool);
+       void set_gain(float);
+       void set_rolloff_factor(float);
        void set_buffer(const Buffer &);
        void queue_buffers(const std::vector<const Buffer *> &);
        void queue_buffer(const Buffer &);
index 36545f67cab004c63b73cb27145ececa4c27fe04..99503b9b70a013e9a3266dda1e95ba7f56d76e68 100644 (file)
@@ -78,6 +78,9 @@ void Streamer::tick()
                        buffers.push_back(buf);
                }
        }
+
+       if(snd->eof())
+               snd=0;
 }
 
 } // namespace AL