X-Git-Url: http://git.tdb.fi/?p=libs%2Fal.git;a=blobdiff_plain;f=source%2Fsound.cpp;h=b2744b3abedeb9682a8c08e6ffbead563280f2dd;hp=896d1d5c392798eb63595b0bb1b1f402a990a1fa;hb=58dc1e7c15f928d0f861a20c46f2be4112bf5baf;hpb=8e69eba7dc53233c169152bdf654f032fcd0629f diff --git a/source/sound.cpp b/source/sound.cpp index 896d1d5..b2744b3 100644 --- a/source/sound.cpp +++ b/source/sound.cpp @@ -5,6 +5,7 @@ Copyright © 2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ +#include #include #include "sound.h" @@ -14,22 +15,37 @@ namespace Msp { namespace AL { Sound::Sound(): - data(0) + data(0), + eof_flag(false) { ovfile.datasource=0; } +Sound::Sound(const std::string &fn): + data(0), + eof_flag(false) +{ + ovfile.datasource=0; + open(fn); +} + Sound::~Sound() { + delete data; if(ovfile.datasource) ov_clear(&ovfile); } void Sound::open(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; + vorbis_info *info=ov_info(&ovfile, -1); freq=info->rate; switch(info->channels) @@ -46,10 +62,11 @@ void Sound::load_data() throw InvalidState("Data has already been loaded"); size=ov_pcm_total(&ovfile, 0)*4; - data=new char[size]; + char *dptr=new char[size]; unsigned pos=0; - while(unsigned len=read(data+pos, size-pos)) + while(unsigned len=read(dptr+pos, size-pos)) pos+=len; + data=dptr; size=pos; } @@ -57,22 +74,51 @@ void Sound::load(const string &fn) { open(fn); load_data(); + close(); } -const char *Sound::get_data() const +void Sound::close() { - if(!data) - throw InvalidState("Data has not been loaded"); - return data; + if(ovfile.datasource) + ov_clear(&ovfile); +} + +void Sound::rewind() +{ + if(data) + read_pos=0; + else + ov_pcm_seek(&ovfile, 0); } 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; + if(data) + { + len=min(len, size-read_pos); + memcpy(buf, data+read_pos, len); + read_pos+=len; + return len; + } + else if(ovfile.datasource) + { + int section=0; + int res=ov_read(&ovfile, buf, len, 0, 2, 1, §ion); + if(res<0) + throw Exception("Error reading ogg vorbis file"); + else if(res==0) + eof_flag=true; + return res; + } + else + throw InvalidState("No data available"); +} + +const char *Sound::get_data() const +{ + if(!data) + throw InvalidState("Data has not been loaded"); + return data; } } // namespace AL