2 #include <vorbis/vorbisfile.h>
3 #include "oggdecoder.h"
9 size_t read(void *ptr, size_t size, size_t nmemb, void *src)
11 Msp::IO::Base *in = reinterpret_cast<Msp::IO::Base *>(src);
12 unsigned len = in->read(reinterpret_cast<char *>(ptr), size*nmemb);
16 int seek(void *src, ogg_int64_t offset, int whence)
18 Msp::IO::SeekType type;
20 type = Msp::IO::S_BEG;
21 else if(whence==SEEK_CUR)
22 type = Msp::IO::S_CUR;
23 else if(whence==SEEK_END)
24 type = Msp::IO::S_END;
28 Msp::IO::Seekable *in = reinterpret_cast<Msp::IO::Seekable *>(src);
29 return in->seek(offset, type);
34 return reinterpret_cast<Msp::IO::Seekable *>(src)->tell();
37 ov_callbacks io_callbacks =
51 struct OggDecoder::Private
53 OggVorbis_File ovfile;
56 OggDecoder::OggDecoder(IO::Seekable &io):
59 if(ov_open_callbacks(&io, &priv->ovfile, 0, 0, io_callbacks)<0)
60 throw runtime_error("Could not open ogg vorbis resource");
62 vorbis_info *info = ov_info(&priv->ovfile, -1);
65 size = ov_pcm_total(&priv->ovfile, 0)*info->channels*2;
67 switch(info->channels)
69 case 1: format = MONO16; break;
70 case 2: format = STEREO16; break;
71 default: throw runtime_error("Unsupported number of channels");
75 OggDecoder::~OggDecoder()
77 if(priv->ovfile.datasource)
78 ov_clear(&priv->ovfile);
82 void OggDecoder::rewind()
84 ov_pcm_seek(&priv->ovfile, 0);
87 unsigned OggDecoder::read(char *buf, unsigned len)
90 int res = ov_read(&priv->ovfile, buf, len, 0, 2, 1, §ion);
92 throw runtime_error("Error reading ogg vorbis file");