Major developments to love.audio/love.sound. Music and Sound are gone. There are only Sources now, which is much cleaner.

The audio module was not really stable in 0.6.0, it takes very little messing around to cause OpenAL to do horrible things. It should now be much more stable,
and you *should* be able to play/stop/pause/resume/rewind/loop like a madman without disasters. Seek and tell, however, are still not tested and verified for
all decoders, but that's less important. Also, all objects now have object:type() and object:typeOf(), which returns the type name of the object,
and checks whether an object is of a certain type, respectively.
This commit is contained in:
rude
2010-01-31 11:52:54 +01:00
parent 8e74574544
commit 5b30c7fcfe
51 changed files with 894 additions and 1693 deletions
+2 -2
View File
@@ -40,7 +40,7 @@ namespace sound
* Indicates how many bytes of raw data should be generated at each
* call to Decode.
**/
static const int DEFAULT_BUFFER_SIZE = 1024;
static const int DEFAULT_BUFFER_SIZE = 2048;
/**
* Indicates the quality of the sound.
@@ -55,7 +55,7 @@ namespace sound
/**
* 16 bit audio is the default.
**/
static const int DEFAULT_T = 16;
static const int DEFAULT_BITS = 16;
/**
* Creates a deep of itself. The sound stream can (and should) be
+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);
+1 -1
View File
@@ -37,7 +37,7 @@ namespace sound
{
int samples = luaL_checkint(L, 1);
int sampleRate = luaL_optint(L, 2, Decoder::DEFAULT_SAMPLE_RATE);
int bits = luaL_optint(L, 3, Decoder::DEFAULT_T);
int bits = luaL_optint(L, 3, Decoder::DEFAULT_BITS);
int channels = luaL_optint(L, 4, Decoder::DEFAULT_CHANNELS);
try