Added Source:getDuration (thanks Boolsheet!)

For streaming sources, the duration may not always be sample-accurate and may return -1 if it cannot be determined at all.
This commit is contained in:
Alex Szpakowski
2015-11-07 01:49:37 -04:00
parent 1b5a0f49fa
commit 0558fcdbd4
28 changed files with 321 additions and 90 deletions
+2 -1
View File
@@ -39,7 +39,7 @@ public:
TYPE_STATIC,
TYPE_STREAM,
TYPE_MAX_ENUM
}; // Type
};
enum Unit
{
@@ -71,6 +71,7 @@ public:
virtual void seek(float offset, Unit unit) = 0;
virtual float tell(Unit unit) = 0;
virtual double getDuration(Unit unit) = 0;
// all float * v must be of size 3
virtual void setPosition(float *v) = 0;
+5
View File
@@ -112,6 +112,11 @@ float Source::tell(Source::Unit)
return 0.0f;
}
double Source::getDuration(Unit)
{
return -1.0f;
}
void Source::setPosition(float *)
{
}
+1
View File
@@ -54,6 +54,7 @@ public:
virtual float getVolume() const;
virtual void seek(float offset, Unit unit);
virtual float tell(Unit unit);
virtual double getDuration(Unit unit);
virtual void setPosition(float *v);
virtual void getPosition(float *v) const;
virtual void setVelocity(float *v);
+6
View File
@@ -263,6 +263,12 @@ float Pool::tell(Source *source, void *unit)
return source->tellAtomic(unit);
}
double Pool::getDuration(Source *source, void *unit)
{
thread::Lock lock(mutex);
return source->getDurationAtomic(unit);
}
ALuint Pool::findi(const Source *source) const
{
std::map<Source *, ALuint>::const_iterator i = playing.find((Source *)source);
+1
View File
@@ -93,6 +93,7 @@ public:
void softRewind(Source *source);
void seek(Source *source, float offset, void *unit);
float tell(Source *source, void *unit);
double getDuration(Source *source, void *unit);
private:
+34
View File
@@ -65,6 +65,7 @@ Ensure the Source is not multi-channel before calling this function.")
};
StaticDataBuffer::StaticDataBuffer(ALenum format, const ALvoid *data, ALsizei size, ALsizei freq)
: size(size)
{
alGenBuffers(1, &buffer);
alBufferData(buffer, format, data, size, freq);
@@ -95,6 +96,7 @@ Source::Source(Pool *pool, love::sound::SoundData *soundData)
, offsetSeconds(0)
, sampleRate(soundData->getSampleRate())
, channels(soundData->getChannels())
, bitDepth(soundData->getBitDepth())
, decoder(nullptr)
, toLoop(0)
{
@@ -134,6 +136,7 @@ Source::Source(Pool *pool, love::sound::Decoder *decoder)
, offsetSeconds(0)
, sampleRate(decoder->getSampleRate())
, channels(decoder->getChannels())
, bitDepth(decoder->getBitDepth())
, decoder(decoder)
, toLoop(0)
{
@@ -169,6 +172,7 @@ Source::Source(const Source &s)
, offsetSeconds(0)
, sampleRate(s.sampleRate)
, channels(s.channels)
, bitDepth(s.bitDepth)
, decoder(nullptr)
, toLoop(0)
{
@@ -441,6 +445,36 @@ float Source::tell(Source::Unit unit)
return pool->tell(this, &unit);
}
double Source::getDurationAtomic(void *vunit)
{
Unit unit = *(Unit *) vunit;
if (type == TYPE_STREAM)
{
double seconds = decoder->getDuration();
if (unit == UNIT_SECONDS)
return seconds;
else
return seconds * decoder->getSampleRate();
}
else
{
ALsizei size = staticBuffer->getSize();
ALsizei samples = (size / channels) / (bitDepth / 8);
if (unit == UNIT_SAMPLES)
return (double) samples;
else
return (double) samples / (double) sampleRate;
}
}
double Source::getDuration(Unit unit)
{
return pool->getDuration(this, &unit);
}
void Source::setPosition(float *v)
{
if (channels > 1)
+9
View File
@@ -65,9 +65,15 @@ public:
return buffer;
}
inline ALsizei getSize() const
{
return size;
}
private:
ALuint buffer;
ALsizei size;
}; // StaticDataBuffer
@@ -98,6 +104,8 @@ public:
virtual void seek(float offset, Unit unit);
virtual float tellAtomic(void *unit) const;
virtual float tell(Unit unit);
virtual double getDurationAtomic(void *unit);
virtual double getDuration(Unit unit);
virtual void setPosition(float *v);
virtual void getPosition(float *v) const;
virtual void setVelocity(float *v);
@@ -180,6 +188,7 @@ private:
int sampleRate;
int channels;
int bitDepth;
StrongRef<love::sound::Decoder> decoder;
+14
View File
@@ -140,6 +140,19 @@ int w_Source_tell(lua_State *L)
return 1;
}
int w_Source_getDuration(lua_State *L)
{
Source *t = luax_checksource(L, 1);
Source::Unit u = Source::UNIT_SECONDS;
const char *unit = lua_isnoneornil(L, 2) ? 0 : lua_tostring(L, 2);
if (unit && !t->getConstant(unit, u))
return luaL_error(L, "Invalid Source time unit: %s", unit);
lua_pushnumber(L, t->getDuration(u));
return 1;
}
int w_Source_setPosition(lua_State *L)
{
Source *t = luax_checksource(L, 1);
@@ -373,6 +386,7 @@ static const luaL_Reg functions[] =
{ "getVolume", w_Source_getVolume },
{ "seek", w_Source_seek },
{ "tell", w_Source_tell },
{ "getDuration", w_Source_getDuration },
{ "setPosition", w_Source_setPosition },
{ "getPosition", w_Source_getPosition },
{ "setVelocity", w_Source_setVelocity },
+1
View File
@@ -42,6 +42,7 @@ int w_Source_setVolume(lua_State *L);
int w_Source_getVolume(lua_State *L);
int w_Source_seek(lua_State *L);
int w_Source_tell(lua_State *L);
int w_Source_getDuration(lua_State *L);
int w_Source_setPosition(lua_State *L);
int w_Source_getPosition(lua_State *L);
int w_Source_setVelocity(lua_State *L);