2020-12-05 13:08:24 +01:00
|
|
|
#pragma once
|
2018-12-20 23:35:49 +01:00
|
|
|
|
2020-12-12 13:01:29 +01:00
|
|
|
#include "util/types.hpp"
|
2020-12-22 09:42:57 +01:00
|
|
|
#include "Utilities/StrFmt.h"
|
2018-12-20 23:35:49 +01:00
|
|
|
|
|
|
|
|
enum : u32
|
|
|
|
|
{
|
|
|
|
|
DEFAULT_AUDIO_SAMPLING_RATE = 48000,
|
|
|
|
|
MAX_AUDIO_BUFFERS = 64,
|
2021-11-24 19:41:05 +01:00
|
|
|
AUDIO_BUFFER_SAMPLES = 256,
|
|
|
|
|
AUDIO_MIN_LATENCY = 512,
|
|
|
|
|
AUDIO_MAX_CHANNELS = 8,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum class AudioFreq : u32
|
|
|
|
|
{
|
|
|
|
|
FREQ_32K = 32000,
|
|
|
|
|
FREQ_44K = 44100,
|
|
|
|
|
FREQ_48K = 48000,
|
|
|
|
|
FREQ_88K = 88200,
|
|
|
|
|
FREQ_96K = 96000,
|
|
|
|
|
FREQ_176K = 176400,
|
|
|
|
|
FREQ_192K = 192000,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum class AudioSampleSize : u32
|
|
|
|
|
{
|
|
|
|
|
FLOAT = sizeof(float),
|
|
|
|
|
S16 = sizeof(s16),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum class AudioChannelCnt : u32
|
|
|
|
|
{
|
|
|
|
|
STEREO = 2,
|
|
|
|
|
SURROUND_5_1 = 6,
|
|
|
|
|
SURROUND_7_1 = 8,
|
2018-12-20 23:35:49 +01:00
|
|
|
};
|
2015-01-11 00:46:10 +01:00
|
|
|
|
2018-12-16 18:40:50 +01:00
|
|
|
class AudioBackend
|
2015-01-11 00:46:10 +01:00
|
|
|
{
|
|
|
|
|
public:
|
2018-12-16 18:40:50 +01:00
|
|
|
enum Capabilities : u32
|
|
|
|
|
{
|
2021-11-24 19:41:05 +01:00
|
|
|
SET_FREQUENCY_RATIO = 0x1, // Implements SetFrequencyRatio
|
2018-12-16 18:40:50 +01:00
|
|
|
};
|
|
|
|
|
|
2020-06-20 02:44:32 +02:00
|
|
|
AudioBackend();
|
|
|
|
|
|
2018-12-16 18:40:50 +01:00
|
|
|
virtual ~AudioBackend() = default;
|
2015-01-11 00:46:10 +01:00
|
|
|
|
2018-12-21 03:13:22 +01:00
|
|
|
/*
|
|
|
|
|
* Pure virtual methods
|
|
|
|
|
*/
|
2021-11-29 12:52:02 +01:00
|
|
|
virtual std::string_view GetName() const = 0;
|
2018-12-16 18:40:50 +01:00
|
|
|
virtual u32 GetCapabilities() const = 0;
|
|
|
|
|
|
2021-11-24 19:41:05 +01:00
|
|
|
virtual void Open(AudioFreq freq, AudioSampleSize sample_size, AudioChannelCnt ch_cnt) = 0;
|
2015-01-11 00:46:10 +01:00
|
|
|
virtual void Close() = 0;
|
2018-12-20 23:35:49 +01:00
|
|
|
|
2021-11-24 19:41:05 +01:00
|
|
|
// Sets write callback. It's called when backend requests new data to be sent
|
|
|
|
|
// Callback should return number of submitted bytes. Calling other backend functions from callback is unsafe
|
|
|
|
|
virtual void SetWriteCallback(std::function<u32(u32 /* byte_cnt */, void * /* buffer */)> cb) = 0;
|
2018-12-16 18:40:50 +01:00
|
|
|
|
2021-11-24 19:41:05 +01:00
|
|
|
// Returns length of one callback frame in seconds.
|
|
|
|
|
virtual f64 GetCallbackFrameLen() = 0;
|
|
|
|
|
|
|
|
|
|
// Returns true if audio is currently being played, false otherwise
|
|
|
|
|
virtual bool IsPlaying() = 0;
|
|
|
|
|
|
|
|
|
|
// Start playing enqueued data
|
|
|
|
|
virtual void Play() = 0;
|
|
|
|
|
|
|
|
|
|
// Pause playing enqueued data
|
|
|
|
|
virtual void Pause() = 0;
|
2018-12-21 03:13:22 +01:00
|
|
|
|
2020-02-18 20:42:55 +01:00
|
|
|
/*
|
|
|
|
|
* This virtual method should be reimplemented if backend can fail to be initialized under non-error conditions
|
|
|
|
|
* eg. when there is no audio devices attached
|
|
|
|
|
*/
|
2021-11-24 19:41:05 +01:00
|
|
|
virtual bool Initialized() { return true; }
|
2020-02-18 20:42:55 +01:00
|
|
|
|
2018-12-21 03:13:22 +01:00
|
|
|
/*
|
2021-11-24 19:41:05 +01:00
|
|
|
* This virtual method should be reimplemented if backend can fail during normal operation
|
2018-12-21 03:13:22 +01:00
|
|
|
*/
|
2021-11-24 19:41:05 +01:00
|
|
|
virtual bool Operational() { return true; }
|
2018-12-21 03:13:22 +01:00
|
|
|
|
2021-11-24 19:41:05 +01:00
|
|
|
/*
|
|
|
|
|
* Virtual methods - should be implemented depending on backend capabilities
|
|
|
|
|
*/
|
2018-12-16 18:40:50 +01:00
|
|
|
|
2018-12-21 03:13:22 +01:00
|
|
|
// Sets a new frequency ratio. Backend is allowed to modify the ratio value, e.g. clamping it to the allowed range
|
|
|
|
|
// Returns the new frequency ratio set
|
|
|
|
|
// Should be implemented if capabilities & SET_FREQUENCY_RATIO
|
2018-12-21 02:16:54 +01:00
|
|
|
virtual f32 SetFrequencyRatio(f32 /* new_ratio */) // returns the new ratio
|
2018-12-16 22:12:58 +01:00
|
|
|
{
|
|
|
|
|
fmt::throw_exception("SetFrequencyRatio() not implemented");
|
|
|
|
|
return 1.0f;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-21 03:13:22 +01:00
|
|
|
/*
|
|
|
|
|
* Helper methods
|
|
|
|
|
*/
|
2020-06-20 02:44:32 +02:00
|
|
|
u32 get_sampling_rate() const;
|
2018-12-20 23:35:49 +01:00
|
|
|
|
2020-06-20 02:44:32 +02:00
|
|
|
u32 get_sample_size() const;
|
2018-12-20 23:35:49 +01:00
|
|
|
|
2020-06-20 02:44:32 +02:00
|
|
|
u32 get_channels() const;
|
2020-12-12 13:01:29 +01:00
|
|
|
|
2021-11-24 19:41:05 +01:00
|
|
|
bool get_convert_to_s16() const;
|
2018-12-16 22:12:58 +01:00
|
|
|
|
2020-02-15 23:36:20 +01:00
|
|
|
bool has_capability(u32 cap) const;
|
2018-12-16 22:12:58 +01:00
|
|
|
|
2020-02-15 23:36:20 +01:00
|
|
|
void dump_capabilities(std::string& out) const;
|
2020-06-20 02:44:32 +02:00
|
|
|
|
|
|
|
|
protected:
|
2021-11-24 19:41:05 +01:00
|
|
|
AudioSampleSize m_sample_size = AudioSampleSize::FLOAT;
|
|
|
|
|
AudioFreq m_sampling_rate = AudioFreq::FREQ_48K;
|
|
|
|
|
AudioChannelCnt m_channels = AudioChannelCnt::STEREO;
|
2015-06-19 17:49:38 +02:00
|
|
|
};
|