Move doxygen comments in the dsound2 player to the declarations from the defitions

Originally committed to SVN as r5852.
This commit is contained in:
Thomas Goyne 2011-11-16 19:54:55 +00:00
parent 554a61daf5
commit a5f6e0588e
2 changed files with 105 additions and 185 deletions

View file

@ -34,9 +34,6 @@
/// @ingroup audio_output /// @ingroup audio_output
/// ///
///////////
// Headers
#include "config.h" #include "config.h"
#ifdef WITH_DIRECTSOUND #ifdef WITH_DIRECTSOUND
@ -56,29 +53,24 @@
#include "main.h" #include "main.h"
#include "utils.h" #include "utils.h"
/// @brief RAII support class to init and de-init the COM library /// @brief RAII support class to init and de-init the COM library
struct COMInitialization { struct COMInitialization {
/// Flag set if an inited COM library is managed /// Flag set if an inited COM library is managed
bool inited; bool inited;
/// @brief Constructor, sets inited false /// @brief Constructor, sets inited false
COMInitialization() COMInitialization()
{ {
inited = false; inited = false;
} }
/// @brief Destructor, de-inits COM if it is inited /// @brief Destructor, de-inits COM if it is inited
~COMInitialization() ~COMInitialization()
{ {
if (inited) CoUninitialize(); if (inited) CoUninitialize();
} }
/// @brief Initialise the COM library as single-threaded apartment if isn't already inited by us /// @brief Initialise the COM library as single-threaded apartment if isn't already inited by us
void Init() void Init()
{ {
@ -91,24 +83,19 @@ struct COMInitialization {
} }
}; };
/// @class COMObjectRetainer /// @class COMObjectRetainer
/// @brief Simple auto_ptr-like class for COM objects /// @brief Simple auto_ptr-like class for COM objects
template<class T> template<class T>
struct COMObjectRetainer { struct COMObjectRetainer {
/// Managed object /// Managed object
T *obj; T *obj;
/// @brief Constructor for null object /// @brief Constructor for null object
COMObjectRetainer() COMObjectRetainer()
{ {
obj = 0; obj = 0;
} }
/// @brief Constructor to take object immediately /// @brief Constructor to take object immediately
/// @param _obj Object to manage /// @param _obj Object to manage
COMObjectRetainer(T *_obj) COMObjectRetainer(T *_obj)
@ -116,14 +103,12 @@ struct COMObjectRetainer {
obj = _obj; obj = _obj;
} }
/// @brief Destructor, releases object if there is one /// @brief Destructor, releases object if there is one
~COMObjectRetainer() ~COMObjectRetainer()
{ {
if (obj) obj->Release(); if (obj) obj->Release();
} }
/// @brief Dereference the managed object /// @brief Dereference the managed object
/// @return The managed object /// @return The managed object
T * operator -> () T * operator -> ()
@ -132,8 +117,6 @@ struct COMObjectRetainer {
} }
}; };
/// @brief RAII wrapper around Win32 HANDLE type /// @brief RAII wrapper around Win32 HANDLE type
struct Win32KernelHandle { struct Win32KernelHandle {
/// HANDLE value being managed /// HANDLE value being managed
@ -156,18 +139,29 @@ struct Win32KernelHandle {
operator HANDLE () const { return handle; } operator HANDLE () const { return handle; }
}; };
/// @class DirectSoundPlayer2Thread /// @class DirectSoundPlayer2Thread
/// @brief Playback thread class for DirectSoundPlayer2 /// @brief Playback thread class for DirectSoundPlayer2
/// ///
/// Not based on wxThread, but uses Win32 threads directly /// Not based on wxThread, but uses Win32 threads directly
class DirectSoundPlayer2Thread { class DirectSoundPlayer2Thread {
/// @brief Win32 thread entry point
/// @param parameter Pointer to our thread object
/// @return Thread return value, always 0 here
static unsigned int __stdcall ThreadProc(void *parameter); static unsigned int __stdcall ThreadProc(void *parameter);
/// @brief Thread entry point
void Run(); void Run();
/// @brief Fill audio data into a locked buffer-pair and unlock the buffers
/// @param buf1 First buffer in pair
/// @param buf1sz Byte-size of first buffer in pair
/// @param buf2 Second buffer in pair, or null
/// @param buf2sz Byte-size of second buffer in pair
/// @param input_frame First audio frame to fill into buffers
/// @param bfr DirectSound buffer object owning the buffer pair
/// @return Number of bytes written
DWORD FillAndUnlockBuffers(void *buf1, DWORD buf1sz, void *buf2, DWORD buf2sz, int64_t &input_frame, IDirectSoundBuffer8 *bfr); DWORD FillAndUnlockBuffers(void *buf1, DWORD buf1sz, void *buf2, DWORD buf2sz, int64_t &input_frame, IDirectSoundBuffer8 *bfr);
/// @brief Check for error state and throw exception if one occurred
void CheckError(); void CheckError();
@ -221,48 +215,74 @@ class DirectSoundPlayer2Thread {
/// System millisecond timestamp of last playback start, used to calculate playback position /// System millisecond timestamp of last playback start, used to calculate playback position
DWORD last_playback_restart; DWORD last_playback_restart;
/// Audio provider to take sample data from /// Audio provider to take sample data from
AudioProvider *provider; AudioProvider *provider;
public: public:
/// @brief Constructor, creates and starts playback thread
/// @param provider Audio provider to take sample data from
/// @param WantedLatency Desired length in milliseconds to write ahead of the playback cursor
/// @param BufferLength Multiplier for WantedLatency to get total buffer length
DirectSoundPlayer2Thread(AudioProvider *provider, int WantedLatency, int BufferLength); DirectSoundPlayer2Thread(AudioProvider *provider, int WantedLatency, int BufferLength);
/// @brief Destructor, waits for thread to have died
~DirectSoundPlayer2Thread(); ~DirectSoundPlayer2Thread();
/// @brief Start audio playback
/// @param start Audio frame to start playback at
/// @param count Number of audio frames to play
void Play(int64_t start, int64_t count); void Play(int64_t start, int64_t count);
/// @brief Stop audio playback
void Stop(); void Stop();
/// @brief Change audio playback end point
/// @param new_end_frame New last audio frame to play
///
/// Playback stops instantly if new_end_frame is before the current playback position
void SetEndFrame(int64_t new_end_frame); void SetEndFrame(int64_t new_end_frame);
/// @brief Change audio playback volume
/// @param new_volume New playback amplification factor, 1.0 is "unchanged"
void SetVolume(double new_volume); void SetVolume(double new_volume);
/// @brief Tell whether audio playback is active
/// @return True if audio is being played back, false if it is not
bool IsPlaying(); bool IsPlaying();
/// @brief Get first audio frame in current playback range
/// @return Audio frame index
int64_t GetStartFrame(); int64_t GetStartFrame();
/// @brief Get approximate current audio frame being heard by the user
/// @return Audio frame index
///
/// Returns 0 if not playing
int64_t GetCurrentFrame(); int64_t GetCurrentFrame();
/// @brief Get audio playback end point
/// @return Audio frame index
int64_t GetEndFrame(); int64_t GetEndFrame();
/// @brief Get current playback volume
/// @return Audio amplification factor
double GetVolume(); double GetVolume();
/// @brief Tell whether playback thread has died
/// @return True if thread is no longer running
bool IsDead(); bool IsDead();
}; };
/// @brief Win32 thread entry point
/// @param parameter Pointer to our thread object
/// @return Thread return value, always 0 here
///
unsigned int __stdcall DirectSoundPlayer2Thread::ThreadProc(void *parameter) unsigned int __stdcall DirectSoundPlayer2Thread::ThreadProc(void *parameter)
{ {
static_cast<DirectSoundPlayer2Thread*>(parameter)->Run(); static_cast<DirectSoundPlayer2Thread*>(parameter)->Run();
return 0; return 0;
} }
/// @brief Thread entry point
void DirectSoundPlayer2Thread::Run()
{
/// Macro used to set error_message, error_happened and end the thread /// Macro used to set error_message, error_happened and end the thread
#define REPORT_ERROR(msg) { error_message = "DirectSoundPlayer2Thread: " msg; SetEvent(error_happened); return; } #define REPORT_ERROR(msg) { error_message = "DirectSoundPlayer2Thread: " msg; SetEvent(error_happened); return; }
void DirectSoundPlayer2Thread::Run()
{
COMInitialization COM_library; COMInitialization COM_library;
try { COM_library.Init(); } try { COM_library.Init(); }
catch (std::exception e) catch (std::exception e)
@ -292,7 +312,7 @@ void DirectSoundPlayer2Thread::Run()
int aim = waveFormat.nAvgBytesPerSec * (wanted_latency*buffer_length)/1000; int aim = waveFormat.nAvgBytesPerSec * (wanted_latency*buffer_length)/1000;
int min = DSBSIZE_MIN; int min = DSBSIZE_MIN;
int max = DSBSIZE_MAX; int max = DSBSIZE_MAX;
DWORD bufSize = mid(min,aim,max); // size of entier playback buffer DWORD bufSize = mid(min,aim,max); // size of entire playback buffer
DSBUFFERDESC desc; DSBUFFERDESC desc;
desc.dwSize = sizeof(DSBUFFERDESC); desc.dwSize = sizeof(DSBUFFERDESC);
desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
@ -552,21 +572,10 @@ do_fill_buffer:
break; break;
} }
} }
#undef REPORT_ERROR
} }
#undef REPORT_ERROR
/// @brief Fill audio data into a locked buffer-pair and unlock the buffers
/// @param buf1 First buffer in pair
/// @param buf1sz Byte-size of first buffer in pair
/// @param buf2 Second buffer in pair, or null
/// @param buf2sz Byte-size of second buffer in pair
/// @param input_frame First audio frame to fill into buffers
/// @param bfr DirectSound buffer object owning the buffer pair
/// @return Number of bytes written
///
DWORD DirectSoundPlayer2Thread::FillAndUnlockBuffers(void *buf1, DWORD buf1sz, void *buf2, DWORD buf2sz, int64_t &input_frame, IDirectSoundBuffer8 *bfr) DWORD DirectSoundPlayer2Thread::FillAndUnlockBuffers(void *buf1, DWORD buf1sz, void *buf2, DWORD buf2sz, int64_t &input_frame, IDirectSoundBuffer8 *bfr)
{ {
// Assume buffers have been locked and are ready to be filled // Assume buffers have been locked and are ready to be filled
@ -625,9 +634,6 @@ DWORD DirectSoundPlayer2Thread::FillAndUnlockBuffers(void *buf1, DWORD buf1sz, v
return buf1sz + buf2sz; return buf1sz + buf2sz;
} }
/// @brief Check for error state and throw exception if one occurred
void DirectSoundPlayer2Thread::CheckError() void DirectSoundPlayer2Thread::CheckError()
{ {
try try
@ -656,13 +662,7 @@ void DirectSoundPlayer2Thread::CheckError()
} }
} }
DirectSoundPlayer2Thread::DirectSoundPlayer2Thread(AudioProvider *provider, int WantedLatency, int BufferLength)
/// @brief Constructor, creates and starts playback thread
/// @param provider Audio provider to take sample data from
/// @param _WantedLatency Desired length in milliseconds to write ahead of the playback cursor
/// @param _BufferLength Multiplier for WantedLatency to get total buffer length
DirectSoundPlayer2Thread::DirectSoundPlayer2Thread(AudioProvider *provider, int _WantedLatency, int _BufferLength)
: event_start_playback (CreateEvent(0, FALSE, FALSE, 0)) : event_start_playback (CreateEvent(0, FALSE, FALSE, 0))
, event_stop_playback (CreateEvent(0, FALSE, FALSE, 0)) , event_stop_playback (CreateEvent(0, FALSE, FALSE, 0))
, event_update_end_time (CreateEvent(0, FALSE, FALSE, 0)) , event_update_end_time (CreateEvent(0, FALSE, FALSE, 0))
@ -671,17 +671,15 @@ DirectSoundPlayer2Thread::DirectSoundPlayer2Thread(AudioProvider *provider, int
, thread_running (CreateEvent(0, TRUE, FALSE, 0)) , thread_running (CreateEvent(0, TRUE, FALSE, 0))
, is_playing (CreateEvent(0, TRUE, FALSE, 0)) , is_playing (CreateEvent(0, TRUE, FALSE, 0))
, error_happened (CreateEvent(0, FALSE, FALSE, 0)) , error_happened (CreateEvent(0, FALSE, FALSE, 0))
, wanted_latency(WantedLatency)
, buffer_length(BufferLength)
, provider(provider)
{ {
error_message = 0; error_message = 0;
volume = 1.0; volume = 1.0;
start_frame = 0; start_frame = 0;
end_frame = 0; end_frame = 0;
wanted_latency = _WantedLatency;
buffer_length = _BufferLength;
this->provider = provider;
thread_handle.handle = (HANDLE)_beginthreadex(0, 0, ThreadProc, this, 0, 0); thread_handle.handle = (HANDLE)_beginthreadex(0, 0, ThreadProc, this, 0, 0);
if (!thread_handle) if (!thread_handle)
@ -703,20 +701,12 @@ DirectSoundPlayer2Thread::DirectSoundPlayer2Thread(AudioProvider *provider, int
} }
} }
/// @brief Destructor, waits for thread to have died
DirectSoundPlayer2Thread::~DirectSoundPlayer2Thread() DirectSoundPlayer2Thread::~DirectSoundPlayer2Thread()
{ {
SetEvent(event_kill_self); SetEvent(event_kill_self);
WaitForSingleObject(thread_handle, INFINITE); WaitForSingleObject(thread_handle, INFINITE);
} }
/// @brief Start audio playback
/// @param start Audio frame to start playback at
/// @param count Number of audio frames to play
void DirectSoundPlayer2Thread::Play(int64_t start, int64_t count) void DirectSoundPlayer2Thread::Play(int64_t start, int64_t count)
{ {
CheckError(); CheckError();
@ -728,9 +718,6 @@ void DirectSoundPlayer2Thread::Play(int64_t start, int64_t count)
last_playback_restart = GetTickCount(); last_playback_restart = GetTickCount();
} }
/// @brief Stop audio playback
void DirectSoundPlayer2Thread::Stop() void DirectSoundPlayer2Thread::Stop()
{ {
CheckError(); CheckError();
@ -738,12 +725,6 @@ void DirectSoundPlayer2Thread::Stop()
SetEvent(event_stop_playback); SetEvent(event_stop_playback);
} }
/// @brief Change audio playback end point
/// @param new_end_frame New last audio frame to play
///
/// Playback stops instantly if new_end_frame is before the current playback position
void DirectSoundPlayer2Thread::SetEndFrame(int64_t new_end_frame) void DirectSoundPlayer2Thread::SetEndFrame(int64_t new_end_frame)
{ {
CheckError(); CheckError();
@ -752,10 +733,6 @@ void DirectSoundPlayer2Thread::SetEndFrame(int64_t new_end_frame)
SetEvent(event_update_end_time); SetEvent(event_update_end_time);
} }
/// @brief Change audio playback volume
/// @param new_volume New playback amplification factor, 1.0 is "unchanged"
void DirectSoundPlayer2Thread::SetVolume(double new_volume) void DirectSoundPlayer2Thread::SetVolume(double new_volume)
{ {
CheckError(); CheckError();
@ -764,10 +741,6 @@ void DirectSoundPlayer2Thread::SetVolume(double new_volume)
SetEvent(event_set_volume); SetEvent(event_set_volume);
} }
/// @brief Tell whether audio playback is active
/// @return True if audio is being played back, false if it is not
bool DirectSoundPlayer2Thread::IsPlaying() bool DirectSoundPlayer2Thread::IsPlaying()
{ {
CheckError(); CheckError();
@ -789,10 +762,6 @@ bool DirectSoundPlayer2Thread::IsPlaying()
} }
} }
/// @brief Get first audio frame in current playback range
/// @return Audio frame index
int64_t DirectSoundPlayer2Thread::GetStartFrame() int64_t DirectSoundPlayer2Thread::GetStartFrame()
{ {
CheckError(); CheckError();
@ -800,12 +769,6 @@ int64_t DirectSoundPlayer2Thread::GetStartFrame()
return start_frame; return start_frame;
} }
/// @brief Get approximate current audio frame being heard by the user
/// @return Audio frame index
///
/// Returns 0 if not playing
int64_t DirectSoundPlayer2Thread::GetCurrentFrame() int64_t DirectSoundPlayer2Thread::GetCurrentFrame()
{ {
CheckError(); CheckError();
@ -817,10 +780,6 @@ int64_t DirectSoundPlayer2Thread::GetCurrentFrame()
return start_frame + milliseconds_elapsed * provider->GetSampleRate() / 1000; return start_frame + milliseconds_elapsed * provider->GetSampleRate() / 1000;
} }
/// @brief Get audio playback end point
/// @return Audio frame index
int64_t DirectSoundPlayer2Thread::GetEndFrame() int64_t DirectSoundPlayer2Thread::GetEndFrame()
{ {
CheckError(); CheckError();
@ -828,10 +787,6 @@ int64_t DirectSoundPlayer2Thread::GetEndFrame()
return end_frame; return end_frame;
} }
/// @brief Get current playback volume
/// @return Audio amplification factor
double DirectSoundPlayer2Thread::GetVolume() double DirectSoundPlayer2Thread::GetVolume()
{ {
CheckError(); CheckError();
@ -839,10 +794,6 @@ double DirectSoundPlayer2Thread::GetVolume()
return volume; return volume;
} }
/// @brief Tell whether playback thread has died
/// @return True if thread is no longer running
bool DirectSoundPlayer2Thread::IsDead() bool DirectSoundPlayer2Thread::IsDead()
{ {
switch (WaitForSingleObject(thread_running, 0)) switch (WaitForSingleObject(thread_running, 0))
@ -855,11 +806,6 @@ bool DirectSoundPlayer2Thread::IsDead()
} }
} }
/// @brief Constructor
DirectSoundPlayer2::DirectSoundPlayer2() DirectSoundPlayer2::DirectSoundPlayer2()
{ {
thread = 0; thread = 0;
@ -875,18 +821,11 @@ DirectSoundPlayer2::DirectSoundPlayer2()
BufferLength = 5; BufferLength = 5;
} }
/// @brief Destructor
DirectSoundPlayer2::~DirectSoundPlayer2() DirectSoundPlayer2::~DirectSoundPlayer2()
{ {
CloseStream(); CloseStream();
} }
/// @brief Tell whether playback thread is alive
/// @return True if there is a playback thread and it's ready
bool DirectSoundPlayer2::IsThreadAlive() bool DirectSoundPlayer2::IsThreadAlive()
{ {
if (!thread) return false; if (!thread) return false;
@ -901,11 +840,6 @@ bool DirectSoundPlayer2::IsThreadAlive()
return true; return true;
} }
/// @brief Prepare for playback
///
/// This means creating the playback thread
void DirectSoundPlayer2::OpenStream() void DirectSoundPlayer2::OpenStream()
{ {
if (IsThreadAlive()) return; if (IsThreadAlive()) return;
@ -921,9 +855,6 @@ void DirectSoundPlayer2::OpenStream()
} }
} }
/// @brief Shutdown playback
void DirectSoundPlayer2::CloseStream() void DirectSoundPlayer2::CloseStream()
{ {
if (!IsThreadAlive()) return; if (!IsThreadAlive()) return;
@ -939,12 +870,6 @@ void DirectSoundPlayer2::CloseStream()
thread = 0; thread = 0;
} }
/// @brief Change audio provider used
/// @param provider New audio provider to use
///
/// Will re-create the playback thread if the provider changed and playback was open
void DirectSoundPlayer2::SetProvider(AudioProvider *provider) void DirectSoundPlayer2::SetProvider(AudioProvider *provider)
{ {
try try
@ -963,11 +888,6 @@ void DirectSoundPlayer2::SetProvider(AudioProvider *provider)
} }
} }
/// @brief Start playback
/// @param start First audio frame to play
/// @param count Number of audio frames to play
void DirectSoundPlayer2::Play(int64_t start,int64_t count) void DirectSoundPlayer2::Play(int64_t start,int64_t count)
{ {
try try
@ -983,11 +903,6 @@ void DirectSoundPlayer2::Play(int64_t start,int64_t count)
} }
} }
/// @brief Stop audio playback
/// @param timerToo Whether to also stop the playback update timer
///
void DirectSoundPlayer2::Stop(bool timerToo) void DirectSoundPlayer2::Stop(bool timerToo)
{ {
try try
@ -1004,10 +919,6 @@ void DirectSoundPlayer2::Stop(bool timerToo)
} }
} }
/// @brief Tell whether playback is active
/// @return True if audio is playing back
bool DirectSoundPlayer2::IsPlaying() bool DirectSoundPlayer2::IsPlaying()
{ {
try try
@ -1022,12 +933,6 @@ bool DirectSoundPlayer2::IsPlaying()
} }
} }
/// @brief Get first audio frame in playback range
/// @return Audio frame index
///
/// Returns 0 if playback is stopped or there is no playback thread
int64_t DirectSoundPlayer2::GetStartPosition() int64_t DirectSoundPlayer2::GetStartPosition()
{ {
try try
@ -1042,12 +947,6 @@ int64_t DirectSoundPlayer2::GetStartPosition()
} }
} }
/// @brief Get playback end position
/// @return Audio frame index
///
/// Returns 0 if playback is stopped or there is no playback thread
int64_t DirectSoundPlayer2::GetEndPosition() int64_t DirectSoundPlayer2::GetEndPosition()
{ {
try try
@ -1062,12 +961,6 @@ int64_t DirectSoundPlayer2::GetEndPosition()
} }
} }
/// @brief Get approximate playback position
/// @return Index of audio frame user is currently hearing
///
/// Returns 0 if playback is stopped or there is no playback thread
int64_t DirectSoundPlayer2::GetCurrentPosition() int64_t DirectSoundPlayer2::GetCurrentPosition()
{ {
try try
@ -1082,10 +975,6 @@ int64_t DirectSoundPlayer2::GetCurrentPosition()
} }
} }
/// @brief Change playback end position
/// @param pos New end position
void DirectSoundPlayer2::SetEndPosition(int64_t pos) void DirectSoundPlayer2::SetEndPosition(int64_t pos)
{ {
try try
@ -1098,12 +987,6 @@ void DirectSoundPlayer2::SetEndPosition(int64_t pos)
} }
} }
/// @brief Seek playback to new position
/// @param pos New position to seek to
///
/// This is done by simply restarting playback
void DirectSoundPlayer2::SetCurrentPosition(int64_t pos) void DirectSoundPlayer2::SetCurrentPosition(int64_t pos)
{ {
try try
@ -1116,10 +999,6 @@ void DirectSoundPlayer2::SetCurrentPosition(int64_t pos)
} }
} }
/// @brief Change playback volume
/// @param vol Amplification factor
void DirectSoundPlayer2::SetVolume(double vol) void DirectSoundPlayer2::SetVolume(double vol)
{ {
try try
@ -1132,10 +1011,6 @@ void DirectSoundPlayer2::SetVolume(double vol)
} }
} }
/// @brief Get playback volume
/// @return Amplification factor
double DirectSoundPlayer2::GetVolume() double DirectSoundPlayer2::GetVolume()
{ {
try try
@ -1149,6 +1024,4 @@ double DirectSoundPlayer2::GetVolume()
return 0; return 0;
} }
} }
#endif // WITH_DIRECTSOUND #endif // WITH_DIRECTSOUND

View file

@ -58,28 +58,75 @@ protected:
/// Multiplier for WantedLatency to get total buffer length /// Multiplier for WantedLatency to get total buffer length
int BufferLength; int BufferLength;
/// @brief Tell whether playback thread is alive
/// @return True if there is a playback thread and it's ready
bool IsThreadAlive(); bool IsThreadAlive();
public: public:
/// @brief Constructor
DirectSoundPlayer2(); DirectSoundPlayer2();
/// @brief Destructor
~DirectSoundPlayer2(); ~DirectSoundPlayer2();
/// @brief Prepare for playback
///
/// This means creating the playback thread
void OpenStream(); void OpenStream();
/// @brief Shutdown playback
void CloseStream(); void CloseStream();
/// @brief Change audio provider used
/// @param provider New audio provider to use
///
/// Will re-create the playback thread if the provider changed and playback was open
void SetProvider(AudioProvider *provider); void SetProvider(AudioProvider *provider);
/// @brief Start playback
/// @param start First audio frame to play
/// @param count Number of audio frames to play
void Play(int64_t start,int64_t count); void Play(int64_t start,int64_t count);
/// @brief Stop audio playback
/// @param timerToo Whether to also stop the playback update timer
void Stop(bool timerToo=true); void Stop(bool timerToo=true);
/// @brief Tell whether playback is active
/// @return True if audio is playing back
bool IsPlaying(); bool IsPlaying();
/// @brief Get first audio frame in playback range
/// @return Audio frame index
///
/// Returns 0 if playback is stopped or there is no playback thread
int64_t GetStartPosition(); int64_t GetStartPosition();
/// @brief Get playback end position
/// @return Audio frame index
///
/// Returns 0 if playback is stopped or there is no playback thread
int64_t GetEndPosition(); int64_t GetEndPosition();
/// @brief Get approximate playback position
/// @return Index of audio frame user is currently hearing
///
/// Returns 0 if playback is stopped or there is no playback thread
int64_t GetCurrentPosition(); int64_t GetCurrentPosition();
/// @brief Change playback end position
/// @param pos New end position
void SetEndPosition(int64_t pos); void SetEndPosition(int64_t pos);
/// @brief Seek playback to new position
/// @param pos New position to seek to
///
/// This is done by simply restarting playback
void SetCurrentPosition(int64_t pos); void SetCurrentPosition(int64_t pos);
/// @brief Change playback volume
/// @param vol Amplification factor
void SetVolume(double vol); void SetVolume(double vol);
/// @brief Get playback volume
/// @return Amplification factor
double GetVolume(); double GetVolume();
}; };
#endif #endif