3 #include <msp/io/file.h>
4 #include <msp/io/memory.h>
5 #include "sounddecoder.h"
11 size_t read(void *ptr, size_t size, size_t nmemb, void *src)
13 Msp::IO::Base *in = reinterpret_cast<Msp::IO::Base *>(src);
14 unsigned len = in->read(reinterpret_cast<char *>(ptr), size*nmemb);
18 int seek(void *src, ogg_int64_t offset, int whence)
20 Msp::IO::SeekType type;
22 type = Msp::IO::S_BEG;
23 else if(whence==SEEK_CUR)
24 type = Msp::IO::S_CUR;
25 else if(whence==SEEK_END)
26 type = Msp::IO::S_END;
30 Msp::IO::Seekable *in = reinterpret_cast<Msp::IO::Seekable *>(src);
31 return in->seek(offset, type);
36 return reinterpret_cast<Msp::IO::Seekable *>(src)->tell();
39 ov_callbacks io_callbacks =
52 SoundDecoder::SoundDecoder():
56 ovfile.datasource = 0;
59 SoundDecoder::~SoundDecoder()
64 void SoundDecoder::open_file(const string &fn)
67 throw logic_error("Sound has already been opened");
69 IO::BufferedFile *file = new IO::BufferedFile(fn);
70 if(ov_open_callbacks(file, &ovfile, 0, 0, io_callbacks)<0)
73 throw runtime_error("Could not open ogg vorbis file "+fn);
80 void SoundDecoder::open_io(Msp::IO::Seekable &io)
83 throw logic_error("Sound has already been opened");
85 if(ov_open_callbacks(&io, &ovfile, 0, 0, io_callbacks)<0)
86 throw runtime_error("Could not open ogg vorbis resource");
91 void SoundDecoder::open_common()
93 vorbis_info *info = ov_info(&ovfile, -1);
96 size = ov_pcm_total(&ovfile, 0)*info->channels*2;
98 switch(info->channels)
100 case 1: format = MONO16; break;
101 case 2: format = STEREO16; break;
102 default: throw runtime_error("Unsupported number of channels");
106 void SoundDecoder::close()
108 if(ovfile.datasource)
114 void SoundDecoder::rewind()
116 ov_pcm_seek(&ovfile, 0);
119 unsigned SoundDecoder::read(char *buf, unsigned len)
122 int res = ov_read(&ovfile, buf, len, 0, 2, 1, §ion);
124 throw runtime_error("Error reading ogg vorbis file");