mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
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:
@@ -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;
|
||||
|
||||
@@ -112,6 +112,11 @@ float Source::tell(Source::Unit)
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
double Source::getDuration(Unit)
|
||||
{
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
void Source::setPosition(float *)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user