forked from teamnwah/openmw-tes3coop
Flesh out the sound decoder a bit more
This commit is contained in:
parent
637617056b
commit
9cf42f6d0f
5 changed files with 132 additions and 1 deletions
|
@ -6,8 +6,12 @@
|
|||
namespace MWSound
|
||||
{
|
||||
|
||||
static void fail(const std::string &msg)
|
||||
{ throw std::runtime_error("FFmpeg exception: "+msg); }
|
||||
|
||||
bool FFmpeg_Decoder::Open(const std::string &fname)
|
||||
{
|
||||
fail("Not currently working");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -15,6 +19,17 @@ void FFmpeg_Decoder::Close()
|
|||
{
|
||||
}
|
||||
|
||||
void FFmpeg_Decoder::GetInfo(int *samplerate, ChannelConfig *chans, SampleType *type)
|
||||
{
|
||||
fail("Not currently working");
|
||||
}
|
||||
|
||||
size_t FFmpeg_Decoder::Read(char *buffer, size_t bytes)
|
||||
{
|
||||
fail("Not currently working");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FFmpeg_Decoder::FFmpeg_Decoder()
|
||||
{
|
||||
|
|
|
@ -19,6 +19,9 @@ namespace MWSound
|
|||
virtual bool Open(const std::string &fname);
|
||||
virtual void Close();
|
||||
|
||||
virtual void GetInfo(int *samplerate, ChannelConfig *chans, SampleType *type);
|
||||
virtual size_t Read(char *buffer, size_t bytes);
|
||||
|
||||
FFmpeg_Decoder();
|
||||
virtual ~FFmpeg_Decoder();
|
||||
|
||||
|
|
|
@ -1,22 +1,115 @@
|
|||
#ifdef OPENMW_USE_MPG123
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
#include "mpgsnd_decoder.hpp"
|
||||
|
||||
|
||||
static void fail(const std::string &msg)
|
||||
{ throw std::runtime_error("MpgSnd exception: "+msg); }
|
||||
|
||||
namespace MWSound
|
||||
{
|
||||
|
||||
bool MpgSnd_Decoder::Open(const std::string &fname)
|
||||
{
|
||||
Close();
|
||||
|
||||
SF_INFO info;
|
||||
sndFile = sf_open(fname.c_str(), SFM_READ, &info);
|
||||
if(sndFile)
|
||||
{
|
||||
if(info.channels == 1)
|
||||
chanConfig = MonoChannels;
|
||||
else if(info.channels == 1)
|
||||
chanConfig = MonoChannels;
|
||||
else
|
||||
{
|
||||
sf_close(sndFile);
|
||||
sndFile = NULL;
|
||||
fail("Unsupported channel count in "+fname);
|
||||
}
|
||||
sampleRate = info.samplerate;
|
||||
return true;
|
||||
}
|
||||
|
||||
mpgFile = mpg123_new(NULL, NULL);
|
||||
if(mpgFile && mpg123_open(mpgFile, fname.c_str()) == MPG123_OK)
|
||||
{
|
||||
try
|
||||
{
|
||||
int encoding, channels;
|
||||
long rate;
|
||||
if(mpg123_getformat(mpgFile, &rate, &channels, &encoding) != MPG123_OK)
|
||||
fail("Failed to get audio format");
|
||||
if(encoding != MPG123_ENC_SIGNED_16)
|
||||
fail("Unsupported encoding in "+fname);
|
||||
if(channels != 1 && channels != 2)
|
||||
fail("Unsupported channel count in "+fname);
|
||||
chanConfig = ((channels==2)?StereoChannels:MonoChannels);
|
||||
sampleRate = rate;
|
||||
return true;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
mpg123_close(mpgFile);
|
||||
mpg123_delete(mpgFile);
|
||||
throw;
|
||||
}
|
||||
mpg123_close(mpgFile);
|
||||
}
|
||||
if(mpgFile)
|
||||
mpg123_delete(mpgFile);
|
||||
mpgFile = NULL;
|
||||
|
||||
fail("Unsupported file type: "+fname);
|
||||
return false;
|
||||
}
|
||||
|
||||
void MpgSnd_Decoder::Close()
|
||||
{
|
||||
if(sndFile)
|
||||
sf_close(sndFile);
|
||||
sndFile = NULL;
|
||||
|
||||
if(mpgFile)
|
||||
{
|
||||
mpg123_close(mpgFile);
|
||||
mpg123_delete(mpgFile);
|
||||
mpgFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void MpgSnd_Decoder::GetInfo(int *samplerate, ChannelConfig *chans, SampleType *type)
|
||||
{
|
||||
if(!sndFile && !mpgFile)
|
||||
fail("No open file");
|
||||
|
||||
MpgSnd_Decoder::MpgSnd_Decoder()
|
||||
*samplerate = sampleRate;
|
||||
*chans = chanConfig;
|
||||
*type = Int16Sample;
|
||||
}
|
||||
|
||||
size_t MpgSnd_Decoder::Read(char *buffer, size_t bytes)
|
||||
{
|
||||
size_t got = 0;
|
||||
|
||||
if(sndFile)
|
||||
{
|
||||
got = sf_read_short(sndFile, (short*)buffer, bytes/2)*2;
|
||||
}
|
||||
else if(mpgFile)
|
||||
{
|
||||
int err;
|
||||
err = mpg123_read(mpgFile, (unsigned char*)buffer, bytes, &got);
|
||||
if(err != MPG123_OK && err != MPG123_DONE)
|
||||
fail("Failed to read from file");
|
||||
}
|
||||
return got;
|
||||
}
|
||||
|
||||
MpgSnd_Decoder::MpgSnd_Decoder() : sndFile(NULL), mpgFile(NULL)
|
||||
{
|
||||
static bool initdone = false;
|
||||
if(!initdone)
|
||||
|
|
|
@ -13,9 +13,18 @@ namespace MWSound
|
|||
{
|
||||
class MpgSnd_Decoder : public Sound_Decoder
|
||||
{
|
||||
SNDFILE *sndFile;
|
||||
mpg123_handle *mpgFile;
|
||||
|
||||
ChannelConfig chanConfig;
|
||||
int sampleRate;
|
||||
|
||||
virtual bool Open(const std::string &fname);
|
||||
virtual void Close();
|
||||
|
||||
virtual void GetInfo(int *samplerate, ChannelConfig *chans, SampleType *type);
|
||||
virtual size_t Read(char *buffer, size_t bytes);
|
||||
|
||||
MpgSnd_Decoder();
|
||||
virtual ~MpgSnd_Decoder();
|
||||
|
||||
|
|
|
@ -6,9 +6,20 @@ namespace MWSound
|
|||
class Sound_Decoder
|
||||
{
|
||||
public:
|
||||
enum SampleType {
|
||||
UInt8Sample,
|
||||
Int16Sample
|
||||
};
|
||||
enum ChannelConfig {
|
||||
MonoChannels,
|
||||
StereoChannels
|
||||
};
|
||||
virtual bool Open(const std::string &fname) = 0;
|
||||
virtual void Close() = 0;
|
||||
|
||||
virtual void GetInfo(int *samplerate, ChannelConfig *chans, SampleType *type) = 0;
|
||||
virtual size_t Read(char *buffer, size_t bytes) = 0;
|
||||
|
||||
virtual ~Sound_Decoder() { }
|
||||
|
||||
friend class OpenAL_Output;
|
||||
|
|
Loading…
Reference in a new issue