From 97dae493948466867b9f661f45e451711dd6b41b Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 9 Jul 2008 16:06:09 +0000 Subject: [PATCH] Two more atribute setting functions in Source Support loading Sounds from memory Support loading Buffers from datafiles Automatically clear Sound from Streamer when eof is reached --- source/buffer.cpp | 24 ++++++++- source/buffer.h | 16 ++++++ source/sound.cpp | 116 ++++++++++++++++++++++++++++++++++++-------- source/sound.h | 9 ++-- source/source.cpp | 10 ++++ source/source.h | 2 + source/streamer.cpp | 3 ++ 7 files changed, 155 insertions(+), 25 deletions(-) diff --git a/source/buffer.cpp b/source/buffer.cpp index b2ef016..8f5b4aa 100644 --- a/source/buffer.cpp +++ b/source/buffer.cpp @@ -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 diff --git a/source/buffer.h b/source/buffer.h index f7ac307..3680e54 100644 --- a/source/buffer.h +++ b/source/buffer.h @@ -10,14 +10,29 @@ Distributed under the LGPL #include #include +#include #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 &); }; diff --git a/source/sound.cpp b/source/sound.cpp index b2744b3..8b6af20 100644 --- a/source/sound.cpp +++ b/source/sound.cpp @@ -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(src); + unsigned len=min(size*nmemb, memsrc.length-memsrc.pos); + memcpy(ptr, reinterpret_cast(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(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(src); +} + +long memory_tell(void *src) +{ + MemorySource &memsrc=*reinterpret_cast(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(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 diff --git a/source/sound.h b/source/sound.h index 1badf3c..a97de46 100644 --- a/source/sound.h +++ b/source/sound.h @@ -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 diff --git a/source/source.cpp b/source/source.cpp index 3619b1d..137b785 100644 --- a/source/source.cpp +++ b/source/source.cpp @@ -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(buffer.get_id())); diff --git a/source/source.h b/source/source.h index 090de0f..d5b4663 100644 --- a/source/source.h +++ b/source/source.h @@ -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 &); void queue_buffer(const Buffer &); diff --git a/source/streamer.cpp b/source/streamer.cpp index 36545f6..99503b9 100644 --- a/source/streamer.cpp +++ b/source/streamer.cpp @@ -78,6 +78,9 @@ void Streamer::tick() buffers.push_back(buf); } } + + if(snd->eof()) + snd=0; } } // namespace AL -- 2.45.2