X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fsounddecoder.cpp;h=138117f730a9210545b807a0338bd8887861fa1d;hb=35b092aaa718dcb12933effd33324bda5d3b5cce;hp=c9da9b808e75b87b540179e4932907fbd92b6858;hpb=ef9906f379e066cb9c754853a3cc771e8e881356;p=libs%2Fal.git diff --git a/source/sounddecoder.cpp b/source/sounddecoder.cpp index c9da9b8..138117f 100644 --- a/source/sounddecoder.cpp +++ b/source/sounddecoder.cpp @@ -1,130 +1,42 @@ -#include -#include +#include #include -#include +#include "oggdecoder.h" #include "sounddecoder.h" using namespace std; -namespace { - -size_t read(void *ptr, size_t size, size_t nmemb, void *src) -{ - Msp::IO::Base *in = reinterpret_cast(src); - unsigned len = in->read(reinterpret_cast(ptr), size*nmemb); - return len/size; -} - -int seek(void *src, ogg_int64_t offset, int whence) -{ - Msp::IO::SeekType type; - if(whence==SEEK_SET) - type = Msp::IO::S_BEG; - else if(whence==SEEK_CUR) - type = Msp::IO::S_CUR; - else if(whence==SEEK_END) - type = Msp::IO::S_END; - else - return -1; - - Msp::IO::Seekable *in = reinterpret_cast(src); - return in->seek(offset, type); -} - -long tell(void *src) -{ - return reinterpret_cast(src)->tell(); -} - -ov_callbacks io_callbacks = -{ - &read, - &seek, - 0, - &tell -}; - -} // namespace - namespace Msp { namespace AL { +unsupported_sound::unsupported_sound(const string &w): + runtime_error(w) +{ } + + SoundDecoder::SoundDecoder(): source(0), + freq(0), + size(0), + format(MONO8), eof_flag(false) -{ - ovfile.datasource = 0; -} +{ } SoundDecoder::~SoundDecoder() { - close(); -} - -void SoundDecoder::open_file(const string &fn) -{ - if(ovfile.datasource) - throw logic_error("Sound has already been opened"); - - 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_io(Msp::IO::Seekable &io) -{ - if(ovfile.datasource) - throw logic_error("Sound has already been opened"); - - if(ov_open_callbacks(&io, &ovfile, 0, 0, io_callbacks)<0) - throw runtime_error("Could not open ogg vorbis resource"); - - open_common(); -} - -void SoundDecoder::open_common() -{ - vorbis_info *info = ov_info(&ovfile, -1); - freq = info->rate; - - size = ov_pcm_total(&ovfile, 0)*info->channels*2; - - switch(info->channels) - { - case 1: format = MONO16; break; - case 2: format = STEREO16; break; - default: throw runtime_error("Unsupported number of channels"); - } -} - -void SoundDecoder::close() -{ - if(ovfile.datasource) - ov_clear(&ovfile); delete source; - source = 0; } -void SoundDecoder::rewind() +SoundDecoder *SoundDecoder::open_file(const string &fn) { - ov_pcm_seek(&ovfile, 0); + RefPtr file = new IO::BufferedFile(fn); + SoundDecoder *decoder = new OggDecoder(*file); + decoder->source = file.release(); + return decoder; } -unsigned SoundDecoder::read(char *buf, unsigned len) +SoundDecoder *SoundDecoder::open_io(IO::Seekable &io) { - int section = 0; - int res = ov_read(&ovfile, buf, len, 0, 2, 1, §ion); - if(res<0) - throw runtime_error("Error reading ogg vorbis file"); - else if(res==0) - eof_flag = true; - return res; + return new OggDecoder(io); } } // namespace AL