Merged love.audio changes.

This commit is contained in:
rude
2010-01-31 13:02:15 +01:00
51 changed files with 894 additions and 1693 deletions
+5 -1
View File
@@ -60,7 +60,11 @@ namespace lullaby
bool ModPlugDecoder::accepts(const std::string & ext)
{
static const std::string supported[] = {
"it", "xm", "mod", "wav", ""
"699", "abc", "amf", "ams", "dbm", "dmf",
"dsm", "far", "it", "j2b", "mdl", "med",
"mid", "mod", "mt2", "mtm", "okt", "pat",
"psm", "s3m", "stm", "ult", "umx", "wav",
"xm", ""
};
for(int i = 0; !(supported[i].empty()); i++)
+1 -1
View File
@@ -44,7 +44,7 @@ namespace lullaby
public:
ModPlugDecoder(Data * data, const std::string & ext, int bufferSize, int sampleRate);
~ModPlugDecoder();
virtual ~ModPlugDecoder();
static bool accepts(const std::string & ext);
+72 -33
View File
@@ -34,9 +34,12 @@ namespace lullaby
bool Mpg123Decoder::inited = false;
Mpg123Decoder::Mpg123Decoder(Data * data, const std::string & ext, int bufferSize, int sampleRate)
: Decoder(data, ext, bufferSize, sampleRate), handle(0), islooping(false)
: Decoder(data, ext, bufferSize, sampleRate), handle(0)
{
data_size = data->getSize();
data_offset = 0;
int ret;
if(!inited)
@@ -57,21 +60,11 @@ namespace lullaby
ret = mpg123_format(handle, sampleRate, MPG123_STEREO, MPG123_ENC_SIGNED_16);
if (ret != MPG123_OK)
throw love::Exception("Could not set output format.");
size_t numbytes = 0;
ret = mpg123_decode(handle, (unsigned char*)data->getData(), data->getSize(), NULL, 0, &numbytes);
if(ret == MPG123_NEW_FORMAT)
{
long rate;
int channels;
int encoding;
mpg123_getformat(handle, &rate, &channels, &encoding);
}
else if(ret != 0)
{
throw love::Exception(mpg123_strerror(handle));
}
ret = feed(16384);
if (ret != MPG123_OK && ret != MPG123_DONE)
throw love::Exception("Could not feed!");
}
Mpg123Decoder::~Mpg123Decoder()
@@ -108,26 +101,51 @@ namespace lullaby
int Mpg123Decoder::decode()
{
size_t numbytes;
int r = mpg123_read(handle, (unsigned char*) buffer, bufferSize, &numbytes);
if (r == MPG123_DONE || r != MPG123_OK)
int size = 0;
bool done = false;
while(size < bufferSize && !done && !eof)
{
if ( r == MPG123_NEED_MORE && islooping )
{
islooping = false;
size_t numbytes = 0;
mpg123_decode(handle, (unsigned char*) data->getData(), data->getSize(), (unsigned char*) buffer, bufferSize, &numbytes);
}
else
size_t numbytes = 0;
int r = mpg123_read(handle, (unsigned char*) buffer + size, bufferSize - size, &numbytes);
switch(r)
{
case MPG123_NEW_FORMAT:
continue;
case MPG123_NEED_MORE:
{
int v = feed(8192);
switch(v)
{
case MPG123_OK:
continue;
case MPG123_DONE:
if(numbytes == 0)
eof = true;
break;
default:
done = true;
}
continue;
}
case MPG123_OK:
size += numbytes;
continue;
case MPG123_DONE:
// Apparently, mpg123_read does not return MPG123_DONE, but
// let's keep it here anyway.
eof = true;
numbytes = 0;
default:
done = true;
break;
}
}
return numbytes;
return size;
}
bool Mpg123Decoder::seek(float s)
@@ -139,11 +157,16 @@ namespace lullaby
bool Mpg123Decoder::rewind()
{
if(mpg123_seek(handle, 0, SEEK_SET) >= 0)
return false;
islooping = true;
eof = false;
return true;
off_t offset;
if(mpg123_feedseek(handle, 0, SEEK_SET, &offset) >= 0)
{
data_offset = offset;
return true;
}
else
return false;
}
bool Mpg123Decoder::isSeekable()
@@ -160,7 +183,23 @@ namespace lullaby
{
return 16;
}
int Mpg123Decoder::feed(int bytes)
{
int remaining = data_size - data_offset;
if(remaining <= 0)
return MPG123_DONE;
int feed_bytes = remaining < bytes ? remaining : bytes;
int r = mpg123_feed(handle, (unsigned char*)data->getData() + data_offset, feed_bytes);
if(r == MPG123_OK || r == MPG123_DONE)
data_offset += feed_bytes;
return r;
}
} // lullaby
} // sound
+8 -2
View File
@@ -43,13 +43,15 @@ namespace lullaby
private:
mpg123_handle * handle;
bool islooping;
static bool inited;
int data_offset;
int data_size;
public:
Mpg123Decoder(Data * data, const std::string & ext, int bufferSize, int sampleRate);
~Mpg123Decoder();
virtual ~Mpg123Decoder();
static bool accepts(const std::string & ext);
static void quit();
@@ -62,6 +64,10 @@ namespace lullaby
int getChannels() const;
int getBits() const;
private:
int feed(int bytes);
}; // Decoder
} // lullaby
+2 -2
View File
@@ -55,9 +55,9 @@ namespace lullaby
// Find a suitable decoder here, and return it.
if(ModPlugDecoder::accepts(ext))
decoder = new ModPlugDecoder(data, ext, bufferSize, sampleRate);
else if (Mpg123Decoder::accepts(ext))
else if(Mpg123Decoder::accepts(ext))
decoder = new Mpg123Decoder(data, ext, bufferSize, sampleRate);
else if (VorbisDecoder::accepts(ext))
else if(VorbisDecoder::accepts(ext))
decoder = new VorbisDecoder(data, ext, bufferSize, sampleRate);
/*else if (FLACDecoder::accepts(ext))
decoder = new FLACDecoder(data, ext, bufferSize, sampleRate);*/
+10 -31
View File
@@ -182,42 +182,20 @@ namespace lullaby
int VorbisDecoder::decode()
{
int bits = this->getBits();
int size = 0;
int section;
int result;
if(bits == 16)
bits = 2;
else
bits = 1;
while(size < bufferSize)
{
result = ov_read(&handle, (char*) buffer + size, bufferSize - size, endian, bits, 1, &section);
int result = ov_read(&handle, (char*) buffer + size, bufferSize - size, endian, (getBits() == 16 ? 2 : 1), 1, 0);
if(result > 0)
size += result;
else if(result < 0)
{
switch(result)
{
case OV_EREAD:
throw love::Exception("Vorbis read: Read from media");
case OV_ENOTVORBIS:
throw love::Exception("Vorbis read: Not Vorbis data");
case OV_EVERSION:
throw love::Exception("Vorbis read: Vorbis version mismatch");
case OV_EBADHEADER:
throw love::Exception("Vorbis read: Invalid Vorbis header");
case OV_EFAULT:
throw love::Exception("Vorbis read: Internal logic fault (bug or heap/stack corruption)");
default:
throw love::Exception("Vorbis read: Unknown error");
}
}
else
if(result == OV_HOLE)
continue;
else if(result <= OV_EREAD)
return -1;
else if(result == 0)
break;
else if(result > 0)
size += result;
}
if(oggFile.dataSize - oggFile.dataRead == 0)
@@ -256,7 +234,8 @@ namespace lullaby
bool VorbisDecoder::rewind()
{
eof = false;
return this->seek(0);
ov_pcm_seek(&handle, 0);
return true;
}
bool VorbisDecoder::isSeekable()
+1 -1
View File
@@ -56,7 +56,7 @@ namespace lullaby
public:
VorbisDecoder(Data * data, const std::string & ext, int bufferSize, int sampleRate);
~VorbisDecoder();
virtual ~VorbisDecoder();
static bool accepts(const std::string & ext);