summaryrefslogtreecommitdiff
path: root/src/drivers/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/include')
-rw-r--r--src/drivers/include/drivers/bluetooth.hpp8
-rw-r--r--src/drivers/include/drivers/i2s_dac.hpp7
-rw-r--r--src/drivers/include/drivers/pcm_buffer.hpp24
3 files changed, 30 insertions, 9 deletions
diff --git a/src/drivers/include/drivers/bluetooth.hpp b/src/drivers/include/drivers/bluetooth.hpp
index 449812d6..99c71e52 100644
--- a/src/drivers/include/drivers/bluetooth.hpp
+++ b/src/drivers/include/drivers/bluetooth.hpp
@@ -45,7 +45,7 @@ class Bluetooth {
auto enable(bool en) -> void;
auto enabled() -> bool;
- auto source(PcmBuffer*) -> void;
+ auto sources(OutputBuffers*) -> void;
auto softVolume(float) -> void;
enum class ConnectionState {
@@ -98,7 +98,7 @@ struct Disable : public tinyfsm::Event {};
struct ConnectTimedOut : public tinyfsm::Event {};
struct PairedDeviceChanged : public tinyfsm::Event {};
-struct SourceChanged : public tinyfsm::Event {};
+struct SourcesChanged : public tinyfsm::Event {};
struct DeviceDiscovered : public tinyfsm::Event {
const Device& device;
};
@@ -172,7 +172,7 @@ class BluetoothState : public tinyfsm::Fsm<BluetoothState> {
virtual void react(const events::Disable& ev) = 0;
virtual void react(const events::ConnectTimedOut& ev){};
virtual void react(const events::PairedDeviceChanged& ev){};
- virtual void react(const events::SourceChanged& ev){};
+ virtual void react(const events::SourcesChanged& ev){};
virtual void react(const events::DeviceDiscovered&);
@@ -243,7 +243,7 @@ class Connected : public BluetoothState {
void exit() override;
void react(const events::PairedDeviceChanged& ev) override;
- void react(const events::SourceChanged& ev) override;
+ void react(const events::SourcesChanged& ev) override;
void react(const events::Disable& ev) override;
void react(events::internal::Gap ev) override;
diff --git a/src/drivers/include/drivers/i2s_dac.hpp b/src/drivers/include/drivers/i2s_dac.hpp
index cf9258c0..891acb56 100644
--- a/src/drivers/include/drivers/i2s_dac.hpp
+++ b/src/drivers/include/drivers/i2s_dac.hpp
@@ -40,9 +40,10 @@ constexpr size_t kI2SBufferLengthFrames = 1024;
*/
class I2SDac {
public:
- static auto create(IGpios& expander, PcmBuffer&) -> std::optional<I2SDac*>;
+ static auto create(IGpios& expander, OutputBuffers&)
+ -> std::optional<I2SDac*>;
- I2SDac(IGpios& gpio, PcmBuffer&, i2s_chan_handle_t i2s_handle);
+ I2SDac(IGpios& gpio, OutputBuffers&, i2s_chan_handle_t i2s_handle);
~I2SDac();
auto SetPaused(bool) -> void;
@@ -77,7 +78,7 @@ class I2SDac {
auto set_channel(bool) -> void;
IGpios& gpio_;
- PcmBuffer& buffer_;
+ OutputBuffers& buffers_;
i2s_chan_handle_t i2s_handle_;
bool i2s_active_;
diff --git a/src/drivers/include/drivers/pcm_buffer.hpp b/src/drivers/include/drivers/pcm_buffer.hpp
index 8f53317e..6b38be94 100644
--- a/src/drivers/include/drivers/pcm_buffer.hpp
+++ b/src/drivers/include/drivers/pcm_buffer.hpp
@@ -39,11 +39,17 @@ class PcmBuffer {
* Fills the given span with samples. If enough samples are available in
* the buffer, then the span will be filled with samples from the buffer. Any
* shortfall is made up by padding the given span with zeroes.
+ *
+ * If `mix` is set to true then, instead of overwriting the destination span,
+ * the retrieved samples will be mixed into any existing samples contained
+ * within the destination. This mixing uses a naive sum approach, and so may
+ * introduce clipping.
*/
- auto receive(std::span<int16_t>, bool isr) -> BaseType_t;
+ auto receive(std::span<int16_t>, bool mix, bool isr) -> BaseType_t;
auto clear() -> void;
auto isEmpty() -> bool;
+ auto suspend(bool) -> void;
/*
* How many samples have been added to this buffer since it was created. This
@@ -62,7 +68,7 @@ class PcmBuffer {
PcmBuffer& operator=(const PcmBuffer&) = delete;
private:
- auto readSingle(std::span<int16_t>, bool isr)
+ auto readSingle(std::span<int16_t>, bool mix, bool isr)
-> std::pair<size_t, BaseType_t>;
StaticRingbuffer_t meta_;
@@ -70,7 +76,21 @@ class PcmBuffer {
std::atomic<uint32_t> sent_;
std::atomic<uint32_t> received_;
+ std::atomic<bool> suspended_;
+
RingbufHandle_t ringbuf_;
};
+/*
+ * Convenience type for a pair of PcmBuffers. Each audio output handles mixing
+ * streams together to ensure that low-latency sounds in one channel (e.g. a
+ * system notification bleep) aren't delayed by a large audio buffer in the
+ * other channel (e.g. a long-running track).
+ *
+ * By convention, the first buffer of this pair is used for tracks, whilst the
+ * second is reserved for 'system sounds'; usually TTS, but potentially maybe
+ * other informative noises.
+ */
+using OutputBuffers = std::pair<PcmBuffer, PcmBuffer>;
+
} // namespace drivers