]> git.tdb.fi Git - libs/al.git/blobdiff - source/sound.cpp
Add Streamer class
[libs/al.git] / source / sound.cpp
index 896d1d5c392798eb63595b0bb1b1f402a990a1fa..b2744b3abedeb9682a8c08e6ffbead563280f2dd 100644 (file)
@@ -5,6 +5,7 @@ Copyright © 2008 Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
+#include <cstring>
 #include <msp/core/except.h>
 #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<char *>(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, &section);
-       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, &section);
+               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