#include <cstring>
#include <stdexcept>
+#include <msp/io/file.h>
+#include <msp/io/memory.h>
#include "sounddecoder.h"
using namespace std;
namespace {
-struct MemorySource
+size_t read(void *ptr, size_t size, size_t nmemb, void *src)
{
- 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<unsigned>(size*nmemb, memsrc.length-memsrc.pos);
- memcpy(ptr, reinterpret_cast<const char *>(memsrc.data)+memsrc.pos, len);
- memsrc.pos += len;
-
+ Msp::IO::Base *in = reinterpret_cast<Msp::IO::Base *>(src);
+ unsigned len = in->read(reinterpret_cast<char *>(ptr), size*nmemb);
return len/size;
}
-int memory_seek(void *src, ogg_int64_t offset, int whence)
+int seek(void *src, ogg_int64_t offset, int whence)
{
- MemorySource &memsrc = *reinterpret_cast<MemorySource *>(src);
+ Msp::IO::SeekType type;
if(whence==SEEK_SET)
- memsrc.pos = offset;
+ type = Msp::IO::S_BEG;
else if(whence==SEEK_CUR)
- memsrc.pos += offset;
+ type = Msp::IO::S_CUR;
else if(whence==SEEK_END)
- memsrc.pos = memsrc.length-offset;
- memsrc.pos = min(memsrc.pos, memsrc.length);
-
- return memsrc.pos;
-}
+ type = Msp::IO::S_END;
+ else
+ return -1;
-int memory_close(void *src)
-{
- delete reinterpret_cast<MemorySource *>(src);
- return 0;
+ Msp::IO::Seekable *in = reinterpret_cast<Msp::IO::Seekable *>(src);
+ return in->seek(offset, type);
}
-long memory_tell(void *src)
+long tell(void *src)
{
- MemorySource &memsrc = *reinterpret_cast<MemorySource *>(src);
- return memsrc.pos;
+ return reinterpret_cast<Msp::IO::Seekable *>(src)->tell();
}
-ov_callbacks memory_callbacks=
+ov_callbacks io_callbacks =
{
- &memory_read,
- &memory_seek,
- &memory_close,
- &memory_tell
+ &read,
+ &seek,
+ 0,
+ &tell
};
} // namespace
namespace AL {
SoundDecoder::SoundDecoder():
+ source(0),
eof_flag(false)
{
ovfile.datasource = 0;
SoundDecoder::~SoundDecoder()
{
- if(ovfile.datasource)
- ov_clear(&ovfile);
+ close();
}
void SoundDecoder::open_file(const string &fn)
{
if(ovfile.datasource)
throw logic_error("Sound has already been opened");
- if(ov_fopen(const_cast<char *>(fn.c_str()), &ovfile)<0)
+
+ IO::BufferedFile *file = new IO::BufferedFile(fn);
+ if(ov_open_callbacks(file, &ovfile, 0, 0, io_callbacks)<0)
+ {
+ delete file;
throw runtime_error("Could not open ogg vorbis file "+fn);
+ }
+ source = file;
open_common();
}
-void SoundDecoder::open_memory(const void *d, unsigned len)
+void SoundDecoder::open_io(Msp::IO::Seekable &io)
{
if(ovfile.datasource)
throw logic_error("Sound has already been opened");
- MemorySource *src = new MemorySource(d, len);
- if(ov_open_callbacks(src, &ovfile, 0, 0, memory_callbacks)<0)
- {
- delete src;
- throw runtime_error("Could not open ogg vorbis memory block");
- }
+ if(ov_open_callbacks(&io, &ovfile, 0, 0, io_callbacks)<0)
+ throw runtime_error("Could not open ogg vorbis resource");
open_common();
}
{
if(ovfile.datasource)
ov_clear(&ovfile);
+ delete source;
+ source = 0;
}
void SoundDecoder::rewind()