mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +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__
|
||||
#define __I_SOUND__
|
||||
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include "i_soundinternal.h"
|
||||
#include "zstring.h"
|
||||
|
@ -62,7 +63,7 @@ enum ECodecType
|
|||
class SoundStream
|
||||
{
|
||||
public:
|
||||
virtual ~SoundStream () {}
|
||||
virtual ~SoundStream() = default;
|
||||
|
||||
enum
|
||||
{ // For CreateStream
|
||||
|
@ -75,11 +76,18 @@ public:
|
|||
Loop = 16
|
||||
};
|
||||
|
||||
struct Position {
|
||||
uint64_t samplesplayed;
|
||||
std::chrono::nanoseconds latency;
|
||||
};
|
||||
|
||||
virtual bool Play(bool looping, float volume) = 0;
|
||||
virtual void Stop() = 0;
|
||||
virtual void SetVolume(float volume) = 0;
|
||||
virtual bool SetPaused(bool paused) = 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();
|
||||
};
|
||||
|
||||
|
|
|
@ -183,6 +183,8 @@ class OpenALSoundStream : public SoundStream
|
|||
std::atomic<bool> Playing;
|
||||
//bool Looping;
|
||||
ALfloat Volume;
|
||||
uint64_t Offset = 0;
|
||||
std::mutex Mutex;
|
||||
|
||||
bool SetupSource()
|
||||
{
|
||||
|
@ -263,6 +265,7 @@ public:
|
|||
return true;
|
||||
|
||||
/* Clear the buffer queue, then fill and queue each buffer */
|
||||
Offset = 0;
|
||||
alSourcei(Source, AL_BUFFER, 0);
|
||||
for(int i = 0;i < BufferCount;i++)
|
||||
{
|
||||
|
@ -297,6 +300,7 @@ public:
|
|||
alSourcei(Source, AL_BUFFER, 0);
|
||||
getALError();
|
||||
|
||||
Offset = 0;
|
||||
Playing.store(false);
|
||||
}
|
||||
|
||||
|
@ -326,6 +330,26 @@ public:
|
|||
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()
|
||||
{
|
||||
FString stats;
|
||||
|
@ -386,8 +410,12 @@ public:
|
|||
|
||||
// Unqueue the oldest buffer, fill it with more data, and queue it
|
||||
// on the end
|
||||
alSourceUnqueueBuffers(Source, 1, &bufid);
|
||||
processed--;
|
||||
{
|
||||
std::lock_guard _{Mutex};
|
||||
alSourceUnqueueBuffers(Source, 1, &bufid);
|
||||
Offset += Data.Size() / FrameSize;
|
||||
processed--;
|
||||
}
|
||||
|
||||
if(Callback(this, &Data[0], Data.Size(), UserData))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue