From 35b092aaa718dcb12933effd33324bda5d3b5cce Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 21 Nov 2012 00:53:11 +0200 Subject: [PATCH] Add dedicated exception classes for decoding sounds --- source/oggdecoder.cpp | 35 ++++++++++++++++++++++++++++++----- source/oggdecoder.h | 12 ++++++++++++ source/sounddecoder.cpp | 5 +++++ source/sounddecoder.h | 8 ++++++++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/source/oggdecoder.cpp b/source/oggdecoder.cpp index a00b78e..5462b79 100644 --- a/source/oggdecoder.cpp +++ b/source/oggdecoder.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include "oggdecoder.h" using namespace std; @@ -48,6 +48,30 @@ ov_callbacks io_callbacks = namespace Msp { namespace AL { +ogg_error::ogg_error(const std::string &func, int code): + runtime_error(format("%s: %s", func, get_message(code))) +{ } + +string ogg_error::get_message(int code) +{ + switch(code) + { + case OV_FALSE: return "No data available"; + case OV_HOLE: return "Missing or corrupt data"; + case OV_EREAD: return "Read error"; + case OV_EFAULT: return "Internal inconsistency"; + case OV_EIMPL: return "Not implemented"; + case OV_EINVAL: return "Invalid argument"; + case OV_ENOTVORBIS: return "Not Vorbis data"; + case OV_EBADHEADER: return "Corrupt Vorbis header"; + case OV_EVERSION: return "Unsupported version"; + case OV_EBADLINK: return "Bad link"; + case OV_ENOSEEK: return "Stream is not seekable"; + default: return format("Unknown error (%d)", code); + } +} + + struct OggDecoder::Private { OggVorbis_File ovfile; @@ -56,8 +80,9 @@ struct OggDecoder::Private OggDecoder::OggDecoder(IO::Seekable &io): priv(new Private) { - if(ov_open_callbacks(&io, &priv->ovfile, 0, 0, io_callbacks)<0) - throw runtime_error("Could not open ogg vorbis resource"); + int ret = ov_open_callbacks(&io, &priv->ovfile, 0, 0, io_callbacks); + if(ret<0) + throw ogg_error("ov_open_callbacks", ret); vorbis_info *info = ov_info(&priv->ovfile, -1); freq = info->rate; @@ -68,7 +93,7 @@ OggDecoder::OggDecoder(IO::Seekable &io): { case 1: format = MONO16; break; case 2: format = STEREO16; break; - default: throw runtime_error("Unsupported number of channels"); + default: throw unsupported_sound(Msp::format("%d channels", info->channels)); } } @@ -89,7 +114,7 @@ unsigned OggDecoder::read(char *buf, unsigned len) int section = 0; int res = ov_read(&priv->ovfile, buf, len, 0, 2, 1, §ion); if(res<0) - throw runtime_error("Error reading ogg vorbis file"); + throw ogg_error("ov_read", res); else if(res==0) eof_flag = true; return res; diff --git a/source/oggdecoder.h b/source/oggdecoder.h index a3f5504..49cadbb 100644 --- a/source/oggdecoder.h +++ b/source/oggdecoder.h @@ -1,11 +1,23 @@ #ifndef MSP_AL_OGGDECODER_H_ #define MSP_AL_OGGDECODER_H_ +#include #include "sounddecoder.h" namespace Msp { namespace AL { +class ogg_error: public std::runtime_error +{ +public: + ogg_error(const std::string &, int); + virtual ~ogg_error() throw() { } + +private: + static std::string get_message(int); +}; + + class OggDecoder: public SoundDecoder { private: diff --git a/source/sounddecoder.cpp b/source/sounddecoder.cpp index 77e3b40..138117f 100644 --- a/source/sounddecoder.cpp +++ b/source/sounddecoder.cpp @@ -8,6 +8,11 @@ using namespace std; namespace Msp { namespace AL { +unsupported_sound::unsupported_sound(const string &w): + runtime_error(w) +{ } + + SoundDecoder::SoundDecoder(): source(0), freq(0), diff --git a/source/sounddecoder.h b/source/sounddecoder.h index 7a08644..ee5b07d 100644 --- a/source/sounddecoder.h +++ b/source/sounddecoder.h @@ -8,6 +8,14 @@ namespace Msp { namespace AL { +class unsupported_sound: public std::runtime_error +{ +public: + unsupported_sound(const std::string &); + virtual ~unsupported_sound() throw() { } +}; + + /** This class facilitates loading sound files. Currently only Ogg Vorbis is supported. -- 2.43.0