This file is part of libmspal
Copyright © 2008 Mikko Rasa, Mikkosoft Productions
-Diestributed under the LGPL
+Distributed under the LGPL
*/
+#include <cstring>
#include <msp/core/except.h>
#include "sound.h"
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");
+ throw Exception("Could not open ogg vorbis file "+fn);
+
+ delete data;
+ data=0;
vorbis_info *info=ov_info(&ovfile, -1);
freq=info->rate;
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;
}
{
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