Audaspace:

* Added an error string for audaspace exceptions.
* Fixed PyAPI exceptions.
* Minor bugfixes.
* Added a name parameter to the Jack device, so that one can define an own name via Python.
This commit is contained in:
Joerg Mueller 2010-08-03 08:07:21 +00:00
parent 8baeb4393c
commit ce44d63ae1
15 changed files with 385 additions and 316 deletions

@ -27,6 +27,9 @@
#include <cstring> #include <cstring>
static const char* specs_error = "AUD_DoubleReader: Both readers have to have "
"the same specs.";
AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1, AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1,
AUD_IReader* reader2) : AUD_IReader* reader2) :
m_reader1(reader1), m_reader2(reader2), m_finished1(false) m_reader1(reader1), m_reader2(reader2), m_finished1(false)
@ -38,7 +41,7 @@ AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1,
{ {
delete reader1; delete reader1;
delete reader2; delete reader2;
AUD_THROW(AUD_ERROR_READER); AUD_THROW(AUD_ERROR_SPECS, specs_error);
} }
} }

@ -27,13 +27,16 @@
#include <cstring> #include <cstring>
static const char* props_error = "AUD_ReverseReader: The reader has to be "
"seekable and a finite length.";
AUD_ReverseReader::AUD_ReverseReader(AUD_IReader* reader) : AUD_ReverseReader::AUD_ReverseReader(AUD_IReader* reader) :
AUD_EffectReader(reader), AUD_EffectReader(reader),
m_length(reader->getLength()), m_length(reader->getLength()),
m_position(0) m_position(0)
{ {
if(m_length < 0 || !reader->isSeekable()) if(m_length < 0 || !reader->isSeekable())
AUD_THROW(AUD_ERROR_READER); AUD_THROW(AUD_ERROR_PROPS, props_error);
} }
void AUD_ReverseReader::seek(int position) void AUD_ReverseReader::seek(int position)

@ -27,6 +27,9 @@
#include <cstring> #include <cstring>
static const char* specs_error = "AUD_SuperposeReader: Both readers have to "
"have the same specs.";
AUD_SuperposeReader::AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2) : AUD_SuperposeReader::AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2) :
m_reader1(reader1), m_reader2(reader2) m_reader1(reader1), m_reader2(reader2)
{ {
@ -36,7 +39,7 @@ AUD_SuperposeReader::AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* read
s1 = reader1->getSpecs(); s1 = reader1->getSpecs();
s2 = reader2->getSpecs(); s2 = reader2->getSpecs();
if(memcmp(&s1, &s2, sizeof(AUD_Specs))) if(memcmp(&s1, &s2, sizeof(AUD_Specs)))
AUD_THROW(AUD_ERROR_READER); AUD_THROW(AUD_ERROR_SPECS, specs_error);
} }
catch(AUD_Exception&) catch(AUD_Exception&)
{ {

@ -289,6 +289,8 @@ bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
return false; return false;
} }
static const char* open_error = "AUD_OpenALDevice: Device couldn't be opened.";
AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize) AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
{ {
// cannot determine how many channels or which format OpenAL uses, but // cannot determine how many channels or which format OpenAL uses, but
@ -313,7 +315,7 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
m_device = alcOpenDevice(NULL); m_device = alcOpenDevice(NULL);
if(!m_device) if(!m_device)
AUD_THROW(AUD_ERROR_OPENAL); AUD_THROW(AUD_ERROR_OPENAL, open_error);
// at least try to set the frequency // at least try to set the frequency
ALCint attribs[] = { ALC_FREQUENCY, specs.rate, 0 }; ALCint attribs[] = { ALC_FREQUENCY, specs.rate, 0 };
@ -513,6 +515,15 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
return valid; return valid;
} }
static const char* genbuffer_error = "AUD_OpenALDevice: Buffer couldn't be "
"generated.";
static const char* gensource_error = "AUD_OpenALDevice: Source couldn't be "
"generated.";
static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
"queued to the source.";
static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
"filled with data.";
AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep) AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
{ {
lock(); lock();
@ -542,13 +553,13 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
{ {
alGenSources(1, &sound->source); alGenSources(1, &sound->source);
if(alGetError() != AL_NO_ERROR) if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL); AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
try try
{ {
alSourcei(sound->source, AL_BUFFER, (*i)->buffer); alSourcei(sound->source, AL_BUFFER, (*i)->buffer);
if(alGetError() != AL_NO_ERROR) if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL); AUD_THROW(AUD_ERROR_OPENAL, queue_error);
} }
catch(AUD_Exception&) catch(AUD_Exception&)
{ {
@ -586,9 +597,6 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
AUD_IReader* reader = factory->createReader(); AUD_IReader* reader = factory->createReader();
if(reader == NULL)
AUD_THROW(AUD_ERROR_READER);
AUD_DeviceSpecs specs = m_specs; AUD_DeviceSpecs specs = m_specs;
specs.specs = reader->getSpecs(); specs.specs = reader->getSpecs();
@ -624,7 +632,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
{ {
alGenBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers); alGenBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
if(alGetError() != AL_NO_ERROR) if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL); AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error);
try try
{ {
@ -639,19 +647,19 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
length * AUD_DEVICE_SAMPLE_SIZE(specs), length * AUD_DEVICE_SAMPLE_SIZE(specs),
specs.rate); specs.rate);
if(alGetError() != AL_NO_ERROR) if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL); AUD_THROW(AUD_ERROR_OPENAL, bufferdata_error);
} }
alGenSources(1, &sound->source); alGenSources(1, &sound->source);
if(alGetError() != AL_NO_ERROR) if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL); AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
try try
{ {
alSourceQueueBuffers(sound->source, AUD_OPENAL_CYCLE_BUFFERS, alSourceQueueBuffers(sound->source, AUD_OPENAL_CYCLE_BUFFERS,
sound->buffers); sound->buffers);
if(alGetError() != AL_NO_ERROR) if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL); AUD_THROW(AUD_ERROR_OPENAL, queue_error);
} }
catch(AUD_Exception&) catch(AUD_Exception&)
{ {

File diff suppressed because it is too large Load Diff

@ -33,6 +33,10 @@ void AUD_SDLDevice::SDL_mix(void *data, Uint8* buffer, int length)
device->mix((data_t*)buffer,length/AUD_DEVICE_SAMPLE_SIZE(device->m_specs)); device->mix((data_t*)buffer,length/AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
} }
static const char* open_error = "AUD_SDLDevice: Device couldn't be opened.";
static const char* format_error = "AUD_SDLDevice: Obtained unsupported sample "
"format.";
AUD_SDLDevice::AUD_SDLDevice(AUD_DeviceSpecs specs, int buffersize) AUD_SDLDevice::AUD_SDLDevice(AUD_DeviceSpecs specs, int buffersize)
{ {
if(specs.channels == AUD_CHANNELS_INVALID) if(specs.channels == AUD_CHANNELS_INVALID)
@ -57,7 +61,7 @@ AUD_SDLDevice::AUD_SDLDevice(AUD_DeviceSpecs specs, int buffersize)
format.userdata = this; format.userdata = this;
if(SDL_OpenAudio(&format, &obtained) != 0) if(SDL_OpenAudio(&format, &obtained) != 0)
AUD_THROW(AUD_ERROR_SDL); AUD_THROW(AUD_ERROR_SDL, open_error);
m_specs.rate = (AUD_SampleRate)obtained.freq; m_specs.rate = (AUD_SampleRate)obtained.freq;
m_specs.channels = (AUD_Channels)obtained.channels; m_specs.channels = (AUD_Channels)obtained.channels;
@ -66,7 +70,10 @@ AUD_SDLDevice::AUD_SDLDevice(AUD_DeviceSpecs specs, int buffersize)
else if(obtained.format == AUDIO_S16LSB || obtained.format == AUDIO_S16MSB) else if(obtained.format == AUDIO_S16LSB || obtained.format == AUDIO_S16MSB)
m_specs.format = AUD_FORMAT_S16; m_specs.format = AUD_FORMAT_S16;
else else
AUD_THROW(AUD_ERROR_SDL); {
SDL_CloseAudio();
AUD_THROW(AUD_ERROR_SDL, format_error);
}
create(); create();
} }

@ -34,6 +34,9 @@ static long src_callback(void *cb_data, float **data)
return ((AUD_SRCResampleReader*)cb_data)->doCallback(data); return ((AUD_SRCResampleReader*)cb_data)->doCallback(data);
} }
static const char* state_error = "AUD_SRCResampleReader: SRC State couldn't be "
"created.";
AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader, AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
AUD_Specs specs) : AUD_Specs specs) :
AUD_EffectReader(reader), AUD_EffectReader(reader),
@ -54,8 +57,7 @@ AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
if(!m_src) if(!m_src)
{ {
// XXX printf("%s\n", src_strerror(error)); // XXX printf("%s\n", src_strerror(error));
delete m_reader; AUD_THROW(AUD_ERROR_SRC, state_error);
AUD_THROW(AUD_ERROR_READER);
} }
} }

@ -77,13 +77,24 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer& buffer)
return buf_pos; return buf_pos;
} }
static const char* streaminfo_error = "AUD_FFMPEGReader: Stream info couldn't "
"be found.";
static const char* noaudio_error = "AUD_FFMPEGReader: File doesn't include an "
"audio stream.";
static const char* nodecoder_error = "AUD_FFMPEGReader: No decoder found for "
"the audio stream.";
static const char* codecopen_error = "AUD_FFMPEGReader: Codec couldn't be "
"opened.";
static const char* format_error = "AUD_FFMPEGReader: Unsupported sample "
"format.";
void AUD_FFMPEGReader::init() void AUD_FFMPEGReader::init()
{ {
m_position = 0; m_position = 0;
m_pkgbuf_left = 0; m_pkgbuf_left = 0;
if(av_find_stream_info(m_formatCtx)<0) if(av_find_stream_info(m_formatCtx)<0)
AUD_THROW(AUD_ERROR_FFMPEG); AUD_THROW(AUD_ERROR_FFMPEG, streaminfo_error);
// find audio stream and codec // find audio stream and codec
m_stream = -1; m_stream = -1;
@ -99,17 +110,17 @@ void AUD_FFMPEGReader::init()
} }
if(m_stream == -1) if(m_stream == -1)
AUD_THROW(AUD_ERROR_FFMPEG); AUD_THROW(AUD_ERROR_FFMPEG, noaudio_error);
m_codecCtx = m_formatCtx->streams[m_stream]->codec; m_codecCtx = m_formatCtx->streams[m_stream]->codec;
// get a decoder and open it // get a decoder and open it
AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id); AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
if(!aCodec) if(!aCodec)
AUD_THROW(AUD_ERROR_FFMPEG); AUD_THROW(AUD_ERROR_FFMPEG, nodecoder_error);
if(avcodec_open(m_codecCtx, aCodec)<0) if(avcodec_open(m_codecCtx, aCodec)<0)
AUD_THROW(AUD_ERROR_FFMPEG); AUD_THROW(AUD_ERROR_FFMPEG, codecopen_error);
// XXX this prints file information to stdout: // XXX this prints file information to stdout:
//dump_format(m_formatCtx, 0, NULL, 0); //dump_format(m_formatCtx, 0, NULL, 0);
@ -139,19 +150,22 @@ void AUD_FFMPEGReader::init()
m_specs.format = AUD_FORMAT_FLOAT64; m_specs.format = AUD_FORMAT_FLOAT64;
break; break;
default: default:
AUD_THROW(AUD_ERROR_FILE); AUD_THROW(AUD_ERROR_FFMPEG, format_error);
} }
m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate; m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
} }
static const char* fileopen_error = "AUD_FFMPEGReader: File couldn't be "
"opened.";
AUD_FFMPEGReader::AUD_FFMPEGReader(std::string filename) : AUD_FFMPEGReader::AUD_FFMPEGReader(std::string filename) :
m_pkgbuf(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1), m_pkgbuf(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1),
m_byteiocontext(NULL) m_byteiocontext(NULL)
{ {
// open file // open file
if(av_open_input_file(&m_formatCtx, filename.c_str(), NULL, 0, NULL)!=0) if(av_open_input_file(&m_formatCtx, filename.c_str(), NULL, 0, NULL)!=0)
AUD_THROW(AUD_ERROR_FILE); AUD_THROW(AUD_ERROR_FILE, fileopen_error);
try try
{ {
@ -164,6 +178,9 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(std::string filename) :
} }
} }
static const char* streamopen_error = "AUD_FFMPEGReader: Stream couldn't be "
"opened.";
AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer) : AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer) :
m_pkgbuf(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1), m_pkgbuf(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1),
m_membuffer(buffer) m_membuffer(buffer)
@ -174,7 +191,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer) :
buffer.get()->getSize(), 0, NULL, NULL, NULL, NULL) != 0) buffer.get()->getSize(), 0, NULL, NULL, NULL, NULL) != 0)
{ {
av_free(m_byteiocontext); av_free(m_byteiocontext);
AUD_THROW(AUD_ERROR_FILE); AUD_THROW(AUD_ERROR_FILE, fileopen_error);
} }
AVProbeData probe_data; AVProbeData probe_data;
@ -187,7 +204,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer) :
if(av_open_input_stream(&m_formatCtx, m_byteiocontext, "", fmt, NULL)!=0) if(av_open_input_stream(&m_formatCtx, m_byteiocontext, "", fmt, NULL)!=0)
{ {
av_free(m_byteiocontext); av_free(m_byteiocontext);
AUD_THROW(AUD_ERROR_FILE); AUD_THROW(AUD_ERROR_FILE, streamopen_error);
} }
try try

@ -131,7 +131,7 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
#endif #endif
#ifdef WITH_JACK #ifdef WITH_JACK
case AUD_JACK_DEVICE: case AUD_JACK_DEVICE:
dev = new AUD_JackDevice(specs, buffersize); dev = new AUD_JackDevice("Blender", specs, buffersize);
break; break;
#endif #endif
default: default:

@ -51,6 +51,8 @@ AUD_FileFactory::AUD_FileFactory(const data_t* buffer, int size) :
memcpy(m_buffer.get()->getBuffer(), buffer, size); memcpy(m_buffer.get()->getBuffer(), buffer, size);
} }
static const char* read_error = "AUD_FileFactory: File couldn't be read.";
AUD_IReader* AUD_FileFactory::createReader() const AUD_IReader* AUD_FileFactory::createReader() const
{ {
#ifdef WITH_SNDFILE #ifdef WITH_SNDFILE
@ -75,5 +77,5 @@ AUD_IReader* AUD_FileFactory::createReader() const
catch(AUD_Exception&) {} catch(AUD_Exception&) {}
#endif #endif
AUD_THROW(AUD_ERROR_FILE); AUD_THROW(AUD_ERROR_FILE, read_error);
} }

@ -211,9 +211,6 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep)
{ {
AUD_IReader* reader = factory->createReader(); AUD_IReader* reader = factory->createReader();
if(reader == NULL)
AUD_THROW(AUD_ERROR_READER);
// prepare the reader // prepare the reader
reader = m_mixer->prepare(reader); reader = m_mixer->prepare(reader);
if(reader == NULL) if(reader == NULL)

@ -33,7 +33,7 @@
/// The size of a sample in the specified format in bytes. /// The size of a sample in the specified format in bytes.
#define AUD_SAMPLE_SIZE(specs) (specs.channels * sizeof(sample_t)) #define AUD_SAMPLE_SIZE(specs) (specs.channels * sizeof(sample_t))
/// Throws a AUD_Exception with the provided error code. /// Throws a AUD_Exception with the provided error code.
#define AUD_THROW(exception) { AUD_Exception e; e.error = exception; throw e; } #define AUD_THROW(exception, errorstr) { AUD_Exception e; e.error = exception; e.str = errorstr; throw e; }
/// Returns the smaller of the two values. /// Returns the smaller of the two values.
#define AUD_MIN(a, b) (((a) < (b)) ? (a) : (b)) #define AUD_MIN(a, b) (((a) < (b)) ? (a) : (b))
@ -108,13 +108,14 @@ typedef enum
typedef enum typedef enum
{ {
AUD_NO_ERROR = 0, AUD_NO_ERROR = 0,
AUD_ERROR_READER, AUD_ERROR_SPECS,
AUD_ERROR_FACTORY, AUD_ERROR_PROPS,
AUD_ERROR_FILE, AUD_ERROR_FILE,
AUD_ERROR_SRC,
AUD_ERROR_FFMPEG, AUD_ERROR_FFMPEG,
AUD_ERROR_SDL,
AUD_ERROR_OPENAL, AUD_ERROR_OPENAL,
AUD_ERROR_JACK AUD_ERROR_SDL,
AUD_ERROR_JACK,
} AUD_Error; } AUD_Error;
/// Fading types. /// Fading types.
@ -181,6 +182,11 @@ typedef struct
*/ */
AUD_Error error; AUD_Error error;
/**
* Error string.
*/
const char* str;
// void* userData; - for the case it is needed someday // void* userData; - for the case it is needed someday
} AUD_Exception; } AUD_Exception;

@ -172,7 +172,13 @@ void AUD_JackDevice::jack_shutdown(void *data)
device->m_valid = false; device->m_valid = false;
} }
AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs, int buffersize) static const char* clientopen_error = "AUD_JackDevice: Couldn't connect to "
"jack server.";
static const char* port_error = "AUD_JackDevice: Couldn't create output port.";
static const char* activate_error = "AUD_JackDevice: Couldn't activate the "
"client.";
AUD_JackDevice::AUD_JackDevice(std::string name, AUD_DeviceSpecs specs, int buffersize)
{ {
if(specs.channels == AUD_CHANNELS_INVALID) if(specs.channels == AUD_CHANNELS_INVALID)
specs.channels = AUD_CHANNELS_STEREO; specs.channels = AUD_CHANNELS_STEREO;
@ -185,9 +191,9 @@ AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs, int buffersize)
jack_status_t status; jack_status_t status;
// open client // open client
m_client = jack_client_open("Blender", options, &status); m_client = jack_client_open(name.c_str(), options, &status);
if(m_client == NULL) if(m_client == NULL)
AUD_THROW(AUD_ERROR_JACK); AUD_THROW(AUD_ERROR_JACK, clientopen_error);
// set callbacks // set callbacks
jack_set_process_callback(m_client, AUD_JackDevice::jack_mix, this); jack_set_process_callback(m_client, AUD_JackDevice::jack_mix, this);
@ -207,7 +213,7 @@ AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs, int buffersize)
JACK_DEFAULT_AUDIO_TYPE, JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0); JackPortIsOutput, 0);
if(m_ports[i] == NULL) if(m_ports[i] == NULL)
AUD_THROW(AUD_ERROR_JACK); AUD_THROW(AUD_ERROR_JACK, port_error);
} }
} }
catch(AUD_Exception&) catch(AUD_Exception&)
@ -249,7 +255,7 @@ AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs, int buffersize)
pthread_cond_destroy(&m_mixingCondition); pthread_cond_destroy(&m_mixingCondition);
destroy(); destroy();
AUD_THROW(AUD_ERROR_JACK); AUD_THROW(AUD_ERROR_JACK, activate_error);
} }
const char** ports = jack_get_ports(m_client, NULL, NULL, const char** ports = jack_get_ports(m_client, NULL, NULL,

@ -30,6 +30,8 @@
#include "AUD_SoftwareDevice.h" #include "AUD_SoftwareDevice.h"
#include "AUD_Buffer.h" #include "AUD_Buffer.h"
#include <string>
#include <jack.h> #include <jack.h>
#include <ringbuffer.h> #include <ringbuffer.h>
@ -127,11 +129,13 @@ protected:
public: public:
/** /**
* Creates a Jack client for audio output. * Creates a Jack client for audio output.
* \param name The client name.
* \param specs The wanted audio specification, where only the channel count * \param specs The wanted audio specification, where only the channel count
* is important. * is important.
* \param buffersize The size of the internal buffer.
* \exception AUD_Exception Thrown if the audio device cannot be opened. * \exception AUD_Exception Thrown if the audio device cannot be opened.
*/ */
AUD_JackDevice(AUD_DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE); AUD_JackDevice(std::string name, AUD_DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
/** /**
* Closes the Jack client. * Closes the Jack client.

@ -76,6 +76,9 @@ sf_count_t AUD_SndFileReader::vio_tell(void *user_data)
return reader->m_memoffset; return reader->m_memoffset;
} }
static const char* fileopen_error = "AUD_SndFileReader: File couldn't be "
"read.";
AUD_SndFileReader::AUD_SndFileReader(std::string filename) : AUD_SndFileReader::AUD_SndFileReader(std::string filename) :
m_position(0) m_position(0)
{ {
@ -85,7 +88,7 @@ AUD_SndFileReader::AUD_SndFileReader(std::string filename) :
m_sndfile = sf_open(filename.c_str(), SFM_READ, &sfinfo); m_sndfile = sf_open(filename.c_str(), SFM_READ, &sfinfo);
if(!m_sndfile) if(!m_sndfile)
AUD_THROW(AUD_ERROR_FILE); AUD_THROW(AUD_ERROR_FILE, fileopen_error);
m_specs.channels = (AUD_Channels) sfinfo.channels; m_specs.channels = (AUD_Channels) sfinfo.channels;
m_specs.rate = (AUD_SampleRate) sfinfo.samplerate; m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
@ -110,7 +113,7 @@ AUD_SndFileReader::AUD_SndFileReader(AUD_Reference<AUD_Buffer> buffer) :
m_sndfile = sf_open_virtual(&m_vio, SFM_READ, &sfinfo, this); m_sndfile = sf_open_virtual(&m_vio, SFM_READ, &sfinfo, this);
if(!m_sndfile) if(!m_sndfile)
AUD_THROW(AUD_ERROR_FILE); AUD_THROW(AUD_ERROR_FILE, fileopen_error);
m_specs.channels = (AUD_Channels) sfinfo.channels; m_specs.channels = (AUD_Channels) sfinfo.channels;
m_specs.rate = (AUD_SampleRate) sfinfo.samplerate; m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;