Add a readAll method to the sound decoder, for potentially more efficient reading

actorid
Chris Robinson 13 years ago
parent deb473b9ae
commit 26a441f29a

@ -353,6 +353,18 @@ size_t FFmpeg_Decoder::read(char *buffer, size_t bytes)
return mStreams.front()->readAVAudioData(buffer, bytes);
}
void FFmpeg_Decoder::readAll(std::vector<char> &output)
{
if(mStreams.empty())
fail("No audio streams");
MyStream *stream = mStreams.front();
char *inbuf;
size_t got;
while((inbuf=(char*)stream->getAVAudioData(&got)) != NULL && got > 0)
output.insert(output.end(), inbuf, inbuf+got);
}
void FFmpeg_Decoder::rewind()
{
av_seek_frame(mFormatCtx, -1, 0, 0);

@ -39,6 +39,7 @@ namespace MWSound
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type);
virtual size_t read(char *buffer, size_t bytes);
virtual void readAll(std::vector<char> &output);
virtual void rewind();
FFmpeg_Decoder();

@ -83,17 +83,16 @@ void MpgSnd_Decoder::open(const std::string &fname)
close();
mDataStream = mResourceMgr.openResource(fname);
SF_INFO info;
SF_VIRTUAL_IO streamIO = {
ogresf_get_filelen, ogresf_seek,
ogresf_read, ogresf_write, ogresf_tell
};
mSndFile = sf_open_virtual(&streamIO, SFM_READ, &info, this);
mSndFile = sf_open_virtual(&streamIO, SFM_READ, &mSndInfo, this);
if(mSndFile)
{
if(info.channels == 1)
if(mSndInfo.channels == 1)
mChanConfig = ChannelConfig_Mono;
else if(info.channels == 2)
else if(mSndInfo.channels == 2)
mChanConfig = ChannelConfig_Stereo;
else
{
@ -101,7 +100,7 @@ void MpgSnd_Decoder::open(const std::string &fname)
mSndFile = NULL;
fail("Unsupported channel count in "+fname);
}
mSampleRate = info.samplerate;
mSampleRate = mSndInfo.samplerate;
return;
}
mDataStream->seek(0);
@ -184,6 +183,19 @@ size_t MpgSnd_Decoder::read(char *buffer, size_t bytes)
return got;
}
void MpgSnd_Decoder::readAll(std::vector<char> &output)
{
if(mSndFile && mSndInfo.frames > 0)
{
size_t pos = output.size();
output.resize(pos + mSndInfo.frames*mSndInfo.channels*2);
sf_readf_short(mSndFile, (short*)(output.data()+pos), mSndInfo.frames);
return;
}
// Fallback in case we don't know the total already
Sound_Decoder::readAll(output);
}
void MpgSnd_Decoder::rewind()
{
if(!mSndFile && !mMpgFile)

@ -15,6 +15,7 @@ namespace MWSound
{
class MpgSnd_Decoder : public Sound_Decoder
{
SF_INFO mSndInfo;
SNDFILE *mSndFile;
mpg123_handle *mMpgFile;
@ -36,6 +37,7 @@ namespace MWSound
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type);
virtual size_t read(char *buffer, size_t bytes);
virtual void readAll(std::vector<char> &output);
virtual void rewind();
MpgSnd_Decoder();

@ -442,30 +442,25 @@ ALuint OpenAL_Output::getBuffer(const std::string &fname)
}
throwALerror();
int srate;
std::vector<char> data;
ChannelConfig chans;
SampleType type;
ALenum format;
int srate;
DecoderPtr decoder = mManager.getDecoder();
decoder->open(fname);
decoder->getInfo(&srate, &chans, &type);
format = getALFormat(chans, type);
std::vector<char> data(32768);
size_t got, total = 0;
while((got=decoder->read(&data[total], data.size()-total)) > 0)
{
total += got;
data.resize(total*2);
}
data.resize(total);
decoder->readAll(data);
decoder->close();
alGenBuffers(1, &buf);
throwALerror();
alBufferData(buf, format, &data[0], total, srate);
alBufferData(buf, format, data.data(), data.size(), srate);
mBufferCache[fname] = buf;
mBufferRefs[buf] = 1;

@ -32,6 +32,7 @@ namespace MWSound
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) = 0;
virtual size_t read(char *buffer, size_t bytes) = 0;
virtual void readAll(std::vector<char> &output);
virtual void rewind() = 0;
Sound_Decoder() : mResourceMgr(Ogre::ResourceGroupManager::getSingleton())

@ -449,6 +449,22 @@ namespace MWSound
updateRegionSound(duration);
}
// Default readAll implementation, for decoders that can't do anything
// better
void Sound_Decoder::readAll(std::vector<char> &output)
{
size_t total = output.size();
size_t got;
output.resize(total+32768);
while((got=read(&output[total], output.size()-total)) > 0)
{
total += got;
output.resize(total*2);
}
output.resize(total);
}
const char *getSampleTypeName(SampleType type)
{

Loading…
Cancel
Save