mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 22:11:43 +00:00
Add a method to retrieve the play position of a SoundStream
This commit is contained in:
parent
c808aad595
commit
78f40fe99c
2 changed files with 39 additions and 3 deletions
|
@ -35,6 +35,7 @@
|
||||||
#ifndef __I_SOUND__
|
#ifndef __I_SOUND__
|
||||||
#define __I_SOUND__
|
#define __I_SOUND__
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "i_soundinternal.h"
|
#include "i_soundinternal.h"
|
||||||
#include "zstring.h"
|
#include "zstring.h"
|
||||||
|
@ -62,7 +63,7 @@ enum ECodecType
|
||||||
class SoundStream
|
class SoundStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~SoundStream () {}
|
virtual ~SoundStream() = default;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{ // For CreateStream
|
{ // For CreateStream
|
||||||
|
@ -75,11 +76,18 @@ public:
|
||||||
Loop = 16
|
Loop = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Position {
|
||||||
|
uint64_t samplesplayed;
|
||||||
|
std::chrono::nanoseconds latency;
|
||||||
|
};
|
||||||
|
|
||||||
virtual bool Play(bool looping, float volume) = 0;
|
virtual bool Play(bool looping, float volume) = 0;
|
||||||
virtual void Stop() = 0;
|
virtual void Stop() = 0;
|
||||||
virtual void SetVolume(float volume) = 0;
|
virtual void SetVolume(float volume) = 0;
|
||||||
virtual bool SetPaused(bool paused) = 0;
|
virtual bool SetPaused(bool paused) = 0;
|
||||||
virtual bool IsEnded() = 0;
|
virtual bool IsEnded() = 0;
|
||||||
|
// Be aware this can be called during the callback invocation after Play is called.
|
||||||
|
virtual Position GetPlayPosition() = 0;
|
||||||
virtual FString GetStats();
|
virtual FString GetStats();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,8 @@ class OpenALSoundStream : public SoundStream
|
||||||
std::atomic<bool> Playing;
|
std::atomic<bool> Playing;
|
||||||
//bool Looping;
|
//bool Looping;
|
||||||
ALfloat Volume;
|
ALfloat Volume;
|
||||||
|
uint64_t Offset = 0;
|
||||||
|
std::mutex Mutex;
|
||||||
|
|
||||||
bool SetupSource()
|
bool SetupSource()
|
||||||
{
|
{
|
||||||
|
@ -263,6 +265,7 @@ public:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Clear the buffer queue, then fill and queue each buffer */
|
/* Clear the buffer queue, then fill and queue each buffer */
|
||||||
|
Offset = 0;
|
||||||
alSourcei(Source, AL_BUFFER, 0);
|
alSourcei(Source, AL_BUFFER, 0);
|
||||||
for(int i = 0;i < BufferCount;i++)
|
for(int i = 0;i < BufferCount;i++)
|
||||||
{
|
{
|
||||||
|
@ -297,6 +300,7 @@ public:
|
||||||
alSourcei(Source, AL_BUFFER, 0);
|
alSourcei(Source, AL_BUFFER, 0);
|
||||||
getALError();
|
getALError();
|
||||||
|
|
||||||
|
Offset = 0;
|
||||||
Playing.store(false);
|
Playing.store(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,6 +330,26 @@ public:
|
||||||
return !Playing.load();
|
return !Playing.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Position GetPlayPosition() override
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
|
||||||
|
std::lock_guard _{Mutex};
|
||||||
|
// TODO: Get latency using AL_SOFT_source_latency
|
||||||
|
ALint state{}, offset{}, queued{};
|
||||||
|
alGetSourcei(Source, AL_BUFFERS_QUEUED, &queued);
|
||||||
|
alGetSourcei(Source, AL_SAMPLE_OFFSET, &offset);
|
||||||
|
alGetSourcei(Source, AL_SOURCE_STATE, &state);
|
||||||
|
// If the source is stopped, there was an underrun, so the play position is
|
||||||
|
// the end of the queue.
|
||||||
|
if(state == AL_STOPPED)
|
||||||
|
return Position{Offset + queued*(Data.Size()/FrameSize), nanoseconds{0}};
|
||||||
|
// The offset is otherwise valid as long as the source has been started.
|
||||||
|
if(state != AL_INITIAL)
|
||||||
|
return Position{Offset + offset, nanoseconds{0}};
|
||||||
|
return Position{0, nanoseconds{0}};
|
||||||
|
}
|
||||||
|
|
||||||
virtual FString GetStats()
|
virtual FString GetStats()
|
||||||
{
|
{
|
||||||
FString stats;
|
FString stats;
|
||||||
|
@ -386,8 +410,12 @@ public:
|
||||||
|
|
||||||
// Unqueue the oldest buffer, fill it with more data, and queue it
|
// Unqueue the oldest buffer, fill it with more data, and queue it
|
||||||
// on the end
|
// on the end
|
||||||
|
{
|
||||||
|
std::lock_guard _{Mutex};
|
||||||
alSourceUnqueueBuffers(Source, 1, &bufid);
|
alSourceUnqueueBuffers(Source, 1, &bufid);
|
||||||
|
Offset += Data.Size() / FrameSize;
|
||||||
processed--;
|
processed--;
|
||||||
|
}
|
||||||
|
|
||||||
if(Callback(this, &Data[0], Data.Size(), UserData))
|
if(Callback(this, &Data[0], Data.Size(), UserData))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue