output/jack: implement Interrupt()
This commit is contained in:
parent
b80a135cf3
commit
4484d7a5c2
2
NEWS
2
NEWS
|
@ -1,7 +1,7 @@
|
||||||
ver 0.22.1 (not yet released)
|
ver 0.22.1 (not yet released)
|
||||||
* output
|
* output
|
||||||
- alsa: don't deadlock when the ALSA driver is buggy
|
- alsa: don't deadlock when the ALSA driver is buggy
|
||||||
- pulse: reduce the delay when stopping or pausing playback
|
- jack, pulse: reduce the delay when stopping or pausing playback
|
||||||
|
|
||||||
ver 0.22 (2020/09/23)
|
ver 0.22 (2020/09/23)
|
||||||
* protocol
|
* protocol
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "JackOutputPlugin.hxx"
|
#include "JackOutputPlugin.hxx"
|
||||||
#include "../OutputAPI.hxx"
|
#include "../OutputAPI.hxx"
|
||||||
|
#include "../Error.hxx"
|
||||||
#include "output/Features.h"
|
#include "output/Features.h"
|
||||||
#include "thread/Mutex.hxx"
|
#include "thread/Mutex.hxx"
|
||||||
#include "util/ScopeExit.hxx"
|
#include "util/ScopeExit.hxx"
|
||||||
|
@ -79,6 +80,15 @@ class JackOutput final : public AudioOutput {
|
||||||
*/
|
*/
|
||||||
std::atomic_bool pause;
|
std::atomic_bool pause;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Was Interrupt() called? This will unblock Play(). It will
|
||||||
|
* be reset by Cancel() and Pause(), as documented by the
|
||||||
|
* #AudioOutput interface.
|
||||||
|
*
|
||||||
|
* Only initialized while the output is open.
|
||||||
|
*/
|
||||||
|
bool interrupted;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protects #error.
|
* Protects #error.
|
||||||
*/
|
*/
|
||||||
|
@ -156,6 +166,8 @@ public:
|
||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Interrupt() noexcept override;
|
||||||
|
|
||||||
std::chrono::steady_clock::duration Delay() const noexcept override {
|
std::chrono::steady_clock::duration Delay() const noexcept override {
|
||||||
return pause && !LockWasShutdown()
|
return pause && !LockWasShutdown()
|
||||||
? std::chrono::seconds(1)
|
? std::chrono::seconds(1)
|
||||||
|
@ -164,6 +176,7 @@ public:
|
||||||
|
|
||||||
size_t Play(const void *chunk, size_t size) override;
|
size_t Play(const void *chunk, size_t size) override;
|
||||||
|
|
||||||
|
void Cancel() noexcept override;
|
||||||
bool Pause() override;
|
bool Pause() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -613,9 +626,21 @@ JackOutput::Open(AudioFormat &new_audio_format)
|
||||||
new_audio_format.format = SampleFormat::FLOAT;
|
new_audio_format.format = SampleFormat::FLOAT;
|
||||||
audio_format = new_audio_format;
|
audio_format = new_audio_format;
|
||||||
|
|
||||||
|
interrupted = false;
|
||||||
|
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JackOutput::Interrupt() noexcept
|
||||||
|
{
|
||||||
|
const std::unique_lock<Mutex> lock(mutex);
|
||||||
|
|
||||||
|
/* the "interrupted" flag will prevent Play() from waiting,
|
||||||
|
and will instead throw AudioOutputInterrupted */
|
||||||
|
interrupted = true;
|
||||||
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
JackOutput::WriteSamples(const float *src, size_t n_frames)
|
JackOutput::WriteSamples(const float *src, size_t n_frames)
|
||||||
{
|
{
|
||||||
|
@ -671,6 +696,9 @@ JackOutput::Play(const void *chunk, size_t size)
|
||||||
const std::lock_guard<Mutex> lock(mutex);
|
const std::lock_guard<Mutex> lock(mutex);
|
||||||
if (error)
|
if (error)
|
||||||
std::rethrow_exception(error);
|
std::rethrow_exception(error);
|
||||||
|
|
||||||
|
if (interrupted)
|
||||||
|
throw AudioOutputInterrupted{};
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t frames_written =
|
size_t frames_written =
|
||||||
|
@ -684,11 +712,19 @@ JackOutput::Play(const void *chunk, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JackOutput::Cancel() noexcept
|
||||||
|
{
|
||||||
|
const std::unique_lock<Mutex> lock(mutex);
|
||||||
|
interrupted = false;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
JackOutput::Pause()
|
JackOutput::Pause()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
const std::lock_guard<Mutex> lock(mutex);
|
const std::lock_guard<Mutex> lock(mutex);
|
||||||
|
interrupted = false;
|
||||||
if (error)
|
if (error)
|
||||||
std::rethrow_exception(error);
|
std::rethrow_exception(error);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue