diff options
| author | jacqueline <me@jacqueline.id.au> | 2024-05-02 19:12:26 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2024-05-02 19:12:26 +1000 |
| commit | 1573a8c4cde1cd9528b422b2dcc598e37ffe94a7 (patch) | |
| tree | d162822b8fd7054f81bace0c7a65ab4d5e6f93ef /src/audio/include | |
| parent | a231fd1c8afedbeb14b0bc77d76bad61db986059 (diff) | |
| download | tangara-fw-1573a8c4cde1cd9528b422b2dcc598e37ffe94a7.tar.gz | |
WIP merge cyclically dependent components into one big component
Diffstat (limited to 'src/audio/include')
| -rw-r--r-- | src/audio/include/audio_converter.hpp | 73 | ||||
| -rw-r--r-- | src/audio/include/audio_decoder.hpp | 56 | ||||
| -rw-r--r-- | src/audio/include/audio_events.hpp | 155 | ||||
| -rw-r--r-- | src/audio/include/audio_fsm.hpp | 129 | ||||
| -rw-r--r-- | src/audio/include/audio_sink.hpp | 87 | ||||
| -rw-r--r-- | src/audio/include/audio_source.hpp | 57 | ||||
| -rw-r--r-- | src/audio/include/bt_audio_output.hpp | 61 | ||||
| -rw-r--r-- | src/audio/include/fatfs_audio_input.hpp | 66 | ||||
| -rw-r--r-- | src/audio/include/fatfs_source.hpp | 46 | ||||
| -rw-r--r-- | src/audio/include/i2s_audio_output.hpp | 63 | ||||
| -rw-r--r-- | src/audio/include/readahead_source.hpp | 60 | ||||
| -rw-r--r-- | src/audio/include/resample.hpp | 37 | ||||
| -rw-r--r-- | src/audio/include/track_queue.hpp | 170 |
13 files changed, 0 insertions, 1060 deletions
diff --git a/src/audio/include/audio_converter.hpp b/src/audio/include/audio_converter.hpp deleted file mode 100644 index 163c6836..00000000 --- a/src/audio/include/audio_converter.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <stdint.h> -#include <cstdint> -#include <memory> - -#include "audio_events.hpp" -#include "audio_sink.hpp" -#include "audio_source.hpp" -#include "codec.hpp" -#include "resample.hpp" -#include "sample.hpp" - -namespace audio { - -/* - * Handle to a persistent task that converts samples between formats (sample - * rate, channels, bits per sample), in order to put samples in the preferred - * format of the current output device. The resulting samples are forwarded - * to the output device's sink stream. - */ -class SampleConverter { - public: - SampleConverter(); - ~SampleConverter(); - - auto SetOutput(std::shared_ptr<IAudioOutput>) -> void; - - auto beginStream(std::shared_ptr<TrackInfo>) -> void; - auto continueStream(std::span<sample::Sample>) -> void; - auto endStream() -> void; - - private: - auto Main() -> void; - - auto handleBeginStream(std::shared_ptr<TrackInfo>) -> void; - auto handleContinueStream(size_t samples_available) -> void; - auto handleEndStream() -> void; - - auto handleSamples(std::span<sample::Sample>) -> size_t; - - auto sendToSink(std::span<sample::Sample>) -> void; - - struct Args { - std::shared_ptr<TrackInfo>* track; - size_t samples_available; - bool is_end_of_stream; - }; - QueueHandle_t commands_; - - std::unique_ptr<Resampler> resampler_; - - StreamBufferHandle_t source_; - std::span<sample::Sample> input_buffer_; - std::span<std::byte> input_buffer_as_bytes_; - - std::span<sample::Sample> resampled_buffer_; - - std::shared_ptr<IAudioOutput> sink_; - IAudioOutput::Format source_format_; - IAudioOutput::Format target_format_; - size_t leftover_bytes_; - - uint32_t samples_sunk_; -}; - -} // namespace audio diff --git a/src/audio/include/audio_decoder.hpp b/src/audio/include/audio_decoder.hpp deleted file mode 100644 index 8e955f74..00000000 --- a/src/audio/include/audio_decoder.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <cstdint> -#include <memory> - -#include "audio_converter.hpp" -#include "audio_events.hpp" -#include "audio_sink.hpp" -#include "audio_source.hpp" -#include "codec.hpp" -#include "track.hpp" -#include "types.hpp" - -namespace audio { - -/* - * Handle to a persistent task that takes bytes from the given source, decodes - * them into sample::Sample (normalised to 16 bit signed PCM), and then - * forwards the resulting stream to the given converter. - */ -class Decoder { - public: - static auto Start(std::shared_ptr<IAudioSource> source, - std::shared_ptr<SampleConverter> converter) -> Decoder*; - - auto Main() -> void; - - Decoder(const Decoder&) = delete; - Decoder& operator=(const Decoder&) = delete; - - private: - Decoder(std::shared_ptr<IAudioSource> source, - std::shared_ptr<SampleConverter> converter); - - auto BeginDecoding(std::shared_ptr<TaggedStream>) -> bool; - auto ContinueDecoding() -> bool; - - std::shared_ptr<IAudioSource> source_; - std::shared_ptr<SampleConverter> converter_; - - std::shared_ptr<codecs::IStream> stream_; - std::unique_ptr<codecs::ICodec> codec_; - - std::optional<codecs::ICodec::OutputFormat> current_format_; - std::optional<IAudioOutput::Format> current_sink_format_; - - std::span<sample::Sample> codec_buffer_; -}; - -} // namespace audio diff --git a/src/audio/include/audio_events.hpp b/src/audio/include/audio_events.hpp deleted file mode 100644 index b8a0dba6..00000000 --- a/src/audio/include/audio_events.hpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <stdint.h> -#include <cstdint> -#include <memory> -#include <optional> -#include <string> - -#include "audio_sink.hpp" -#include "tinyfsm.hpp" - -#include "track.hpp" -#include "types.hpp" - -namespace audio { - -/* - * Struct encapsulating information about the decoder's current track. - */ -struct TrackInfo { - /* - * Audio tags extracted from the file. May be absent for files without any - * parseable tags. - */ - std::shared_ptr<database::TrackTags> tags; - - /* - * URI that the current track was retrieved from. This is currently always a - * file path on the SD card. - */ - std::string uri; - - /* - * The length of this track in seconds. This is either retrieved from the - * track's tags, or sometimes computed. It may therefore sometimes be - * inaccurate or missing. - */ - std::optional<uint32_t> duration; - - /* The offset in seconds that this file's decoding started from. */ - std::optional<uint32_t> start_offset; - - /* The approximate bitrate of this track in its original encoded form. */ - std::optional<uint32_t> bitrate_kbps; - - /* The encoded format of the this track. */ - codecs::StreamType encoding; - - IAudioOutput::Format format; -}; - -/* - * Event emitted by the audio FSM when the state of the audio pipeline has - * changed. This is usually once per second while a track is playing, plus one - * event each when a track starts or finishes. - */ -struct PlaybackUpdate : tinyfsm::Event { - /* - * The track that is currently being decoded by the audio pipeline. May be - * absent if there is no current track. - */ - std::shared_ptr<TrackInfo> current_track; - - /* - * How long the current track has been playing for, in seconds. Will always - * be present if current_track is present. - */ - std::optional<uint32_t> track_position; - - /* Whether or not the current track is currently being output to a sink. */ - bool paused; -}; - -/* - * Sets a new track to be decoded by the audio pipeline, replacing any - * currently playing track. - */ -struct SetTrack : tinyfsm::Event { - std::variant<std::string, database::TrackId, std::monostate> new_track; - std::optional<uint32_t> seek_to_second; - - enum Transition { - kHardCut, - kGapless, - // TODO: kCrossFade - }; - Transition transition; -}; - -struct TogglePlayPause : tinyfsm::Event { - std::optional<bool> set_to; -}; - -struct QueueUpdate : tinyfsm::Event { - bool current_changed; - - enum Reason { - kExplicitUpdate, - kRepeatingLastTrack, - kTrackFinished, - kDeserialised, - }; - Reason reason; -}; - -struct StepUpVolume : tinyfsm::Event {}; -struct StepDownVolume : tinyfsm::Event {}; -struct SetVolume : tinyfsm::Event { - std::optional<uint_fast8_t> percent; - std::optional<int32_t> db; -}; -struct SetVolumeBalance : tinyfsm::Event { - int left_bias; -}; - -struct VolumeChanged : tinyfsm::Event { - uint_fast8_t percent; - int db; -}; -struct VolumeBalanceChanged : tinyfsm::Event { - int left_bias; -}; -struct VolumeLimitChanged : tinyfsm::Event { - int new_limit_db; -}; - -struct SetVolumeLimit : tinyfsm::Event { - int limit_db; -}; - -struct OutputModeChanged : tinyfsm::Event {}; - -namespace internal { - -struct StreamStarted : tinyfsm::Event { - std::shared_ptr<TrackInfo> track; - IAudioOutput::Format src_format; - IAudioOutput::Format dst_format; -}; - -struct StreamUpdate : tinyfsm::Event { - uint32_t samples_sunk; -}; - -struct StreamEnded : tinyfsm::Event {}; - -} // namespace internal - -} // namespace audio diff --git a/src/audio/include/audio_fsm.hpp b/src/audio/include/audio_fsm.hpp deleted file mode 100644 index 60afb321..00000000 --- a/src/audio/include/audio_fsm.hpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <stdint.h> -#include <deque> -#include <memory> -#include <vector> - -#include "audio_sink.hpp" -#include "service_locator.hpp" -#include "tinyfsm.hpp" - -#include "audio_decoder.hpp" -#include "audio_events.hpp" -#include "bt_audio_output.hpp" -#include "database.hpp" -#include "display.hpp" -#include "fatfs_audio_input.hpp" -#include "gpios.hpp" -#include "i2s_audio_output.hpp" -#include "i2s_dac.hpp" -#include "storage.hpp" -#include "system_events.hpp" -#include "tag_parser.hpp" -#include "track.hpp" -#include "track_queue.hpp" - -namespace audio { - -class AudioState : public tinyfsm::Fsm<AudioState> { - public: - virtual ~AudioState() {} - - virtual void entry() {} - virtual void exit() {} - - /* Fallback event handler. Does nothing. */ - void react(const tinyfsm::Event& ev) {} - - void react(const QueueUpdate&); - void react(const SetTrack&); - void react(const TogglePlayPause&); - - void react(const internal::StreamStarted&); - void react(const internal::StreamUpdate&); - void react(const internal::StreamEnded&); - - void react(const StepUpVolume&); - void react(const StepDownVolume&); - virtual void react(const system_fsm::HasPhonesChanged&); - - void react(const SetVolume&); - void react(const SetVolumeLimit&); - void react(const SetVolumeBalance&); - - void react(const OutputModeChanged&); - - virtual void react(const system_fsm::BootComplete&) {} - virtual void react(const system_fsm::KeyLockChanged&){}; - virtual void react(const system_fsm::StorageMounted&) {} - virtual void react(const system_fsm::BluetoothEvent&); - - protected: - auto clearDrainBuffer() -> void; - auto awaitEmptyDrainBuffer() -> void; - - auto playTrack(database::TrackId id) -> void; - auto commitVolume() -> void; - - static std::shared_ptr<system_fsm::ServiceLocator> sServices; - - static std::shared_ptr<FatfsAudioInput> sFileSource; - static std::unique_ptr<Decoder> sDecoder; - static std::shared_ptr<SampleConverter> sSampleConverter; - static std::shared_ptr<I2SAudioOutput> sI2SOutput; - static std::shared_ptr<BluetoothAudioOutput> sBtOutput; - static std::shared_ptr<IAudioOutput> sOutput; - - static StreamBufferHandle_t sDrainBuffer; - - static std::shared_ptr<TrackInfo> sCurrentTrack; - static uint64_t sCurrentSamples; - static std::optional<IAudioOutput::Format> sDrainFormat; - static bool sCurrentTrackIsFromQueue; - - static std::shared_ptr<TrackInfo> sNextTrack; - static uint64_t sNextTrackCueSamples; - static bool sNextTrackIsFromQueue; - - static bool sIsResampling; - static bool sIsPaused; - - auto currentPositionSeconds() -> std::optional<uint32_t>; -}; - -namespace states { - -class Uninitialised : public AudioState { - public: - void react(const system_fsm::BootComplete&) override; - void react(const system_fsm::BluetoothEvent&) override{}; - - using AudioState::react; -}; - -class Standby : public AudioState { - public: - void react(const system_fsm::KeyLockChanged&) override; - void react(const system_fsm::StorageMounted&) override; - - using AudioState::react; -}; - -class Playback : public AudioState { - public: - void entry() override; - void exit() override; - - using AudioState::react; -}; - -} // namespace states - -} // namespace audio diff --git a/src/audio/include/audio_sink.hpp b/src/audio/include/audio_sink.hpp deleted file mode 100644 index f31d0d75..00000000 --- a/src/audio/include/audio_sink.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <stdint.h> -#include <cstdint> - -#include "esp_heap_caps.h" -#include "freertos/FreeRTOS.h" - -namespace audio { - -/* - * Interface for classes that use PCM samples to create noises for the user. - * - * These classes do not generally have any specific task for their work, and - * simply help to mediate working out the correct PCM format, and then sending - * those samples to the appropriate hardware driver. - */ -class IAudioOutput { - private: - StreamBufferHandle_t stream_; - - public: - IAudioOutput(StreamBufferHandle_t stream) - : stream_(stream), mode_(Modes::kOff) {} - - virtual ~IAudioOutput() {} - - enum class Modes { - kOff, - kOnPaused, - kOnPlaying, - }; - - /* - * Indicates whether this output is currently being sent samples. If this is - * false, the output should place itself into a low power state. - */ - auto mode(Modes m) -> void { - if (mode_ == m) { - return; - } - changeMode(m); - mode_ = m; - } - auto mode() -> Modes { return mode_; } - - virtual auto SetVolumeImbalance(int_fast8_t balance) -> void = 0; - - virtual auto SetVolume(uint16_t) -> void = 0; - - virtual auto GetVolume() -> uint16_t = 0; - - virtual auto GetVolumePct() -> uint_fast8_t = 0; - virtual auto GetVolumeDb() -> int_fast16_t = 0; - - virtual auto SetVolumePct(uint_fast8_t) -> bool = 0; - virtual auto SetVolumeDb(int_fast16_t) -> bool = 0; - - virtual auto AdjustVolumeUp() -> bool = 0; - virtual auto AdjustVolumeDown() -> bool = 0; - - struct Format { - uint32_t sample_rate; - uint_fast8_t num_channels; - uint_fast8_t bits_per_sample; - - bool operator==(const Format&) const = default; - }; - - virtual auto PrepareFormat(const Format&) -> Format = 0; - virtual auto Configure(const Format& format) -> void = 0; - - auto stream() -> StreamBufferHandle_t { return stream_; } - - protected: - Modes mode_; - - virtual auto changeMode(Modes new_mode) -> void = 0; -}; - -} // namespace audio diff --git a/src/audio/include/audio_source.hpp b/src/audio/include/audio_source.hpp deleted file mode 100644 index f6a34300..00000000 --- a/src/audio/include/audio_source.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <memory> -#include "codec.hpp" -#include "track.hpp" -#include "types.hpp" - -namespace audio { - -class TaggedStream : public codecs::IStream { - public: - TaggedStream(std::shared_ptr<database::TrackTags>, - std::unique_ptr<codecs::IStream> wrapped, - std::string path, - uint32_t offset = 0 - ); - - auto tags() -> std::shared_ptr<database::TrackTags>; - - auto Read(std::span<std::byte> dest) -> ssize_t override; - - auto CanSeek() -> bool override; - - auto SeekTo(int64_t destination, SeekFrom from) -> void override; - - auto CurrentPosition() -> int64_t override; - - auto Size() -> std::optional<int64_t> override; - - auto Offset() -> uint32_t; - - auto Filepath() -> std::string; - - auto SetPreambleFinished() -> void override; - - private: - std::shared_ptr<database::TrackTags> tags_; - std::unique_ptr<codecs::IStream> wrapped_; - std::string filepath_; - int32_t offset_; -}; - -class IAudioSource { - public: - virtual ~IAudioSource() {} - - virtual auto HasNewStream() -> bool = 0; - virtual auto NextStream() -> std::shared_ptr<TaggedStream> = 0; -}; - -} // namespace audio diff --git a/src/audio/include/bt_audio_output.hpp b/src/audio/include/bt_audio_output.hpp deleted file mode 100644 index cc3b2462..00000000 --- a/src/audio/include/bt_audio_output.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <stdint.h> -#include <cstdint> -#include <memory> -#include <vector> - -#include "result.hpp" - -#include "audio_sink.hpp" -#include "bluetooth.hpp" -#include "gpios.hpp" -#include "i2s_dac.hpp" -#include "tasks.hpp" - -namespace audio { - -class BluetoothAudioOutput : public IAudioOutput { - public: - BluetoothAudioOutput(StreamBufferHandle_t, - drivers::Bluetooth& bt, - tasks::WorkerPool&); - ~BluetoothAudioOutput(); - - auto SetVolumeImbalance(int_fast8_t balance) -> void override; - - auto SetVolume(uint16_t) -> void override; - - auto GetVolume() -> uint16_t override; - - auto GetVolumePct() -> uint_fast8_t override; - auto SetVolumePct(uint_fast8_t val) -> bool override; - auto GetVolumeDb() -> int_fast16_t override; - auto SetVolumeDb(int_fast16_t) -> bool override; - - auto AdjustVolumeUp() -> bool override; - auto AdjustVolumeDown() -> bool override; - - auto PrepareFormat(const Format&) -> Format override; - auto Configure(const Format& format) -> void override; - - BluetoothAudioOutput(const BluetoothAudioOutput&) = delete; - BluetoothAudioOutput& operator=(const BluetoothAudioOutput&) = delete; - - protected: - auto changeMode(Modes) -> void override; - - private: - drivers::Bluetooth& bluetooth_; - tasks::WorkerPool& bg_worker_; - - uint16_t volume_; -}; - -} // namespace audio diff --git a/src/audio/include/fatfs_audio_input.hpp b/src/audio/include/fatfs_audio_input.hpp deleted file mode 100644 index 10b7433e..00000000 --- a/src/audio/include/fatfs_audio_input.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <cstddef> -#include <cstdint> -#include <future> -#include <memory> -#include <string> - -#include "ff.h" -#include "freertos/portmacro.h" - -#include "audio_source.hpp" -#include "codec.hpp" -#include "future_fetcher.hpp" -#include "tag_parser.hpp" -#include "tasks.hpp" -#include "types.hpp" - -namespace audio { - -/* - * Audio source that fetches data from a FatFs (or exfat i guess) filesystem. - * - * All public methods are safe to call from any task. - */ -class FatfsAudioInput : public IAudioSource { - public: - explicit FatfsAudioInput(database::ITagParser&, tasks::WorkerPool&); - ~FatfsAudioInput(); - - /* - * Immediately cease reading any current source, and begin reading from the - * given file path. - */ - auto SetPath(std::optional<std::string>) -> void; - auto SetPath(const std::string&,uint32_t offset = 0) -> void; - auto SetPath() -> void; - - auto HasNewStream() -> bool override; - auto NextStream() -> std::shared_ptr<TaggedStream> override; - - FatfsAudioInput(const FatfsAudioInput&) = delete; - FatfsAudioInput& operator=(const FatfsAudioInput&) = delete; - - private: - auto OpenFile(const std::string& path,uint32_t offset) -> bool; - - auto ContainerToStreamType(database::Container) - -> std::optional<codecs::StreamType>; - - database::ITagParser& tag_parser_; - tasks::WorkerPool& bg_worker_; - - std::mutex new_stream_mutex_; - std::shared_ptr<TaggedStream> new_stream_; - - std::atomic<bool> has_new_stream_; -}; - -} // namespace audio diff --git a/src/audio/include/fatfs_source.hpp b/src/audio/include/fatfs_source.hpp deleted file mode 100644 index ce9b4db8..00000000 --- a/src/audio/include/fatfs_source.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <cstddef> -#include <cstdint> -#include <memory> - -#include "codec.hpp" -#include "ff.h" - -#include "audio_source.hpp" - -namespace audio { - -/* - * Handles coordination with a persistent background task to asynchronously - * read files from disk into a StreamBuffer. - */ -class FatfsSource : public codecs::IStream { - public: - FatfsSource(codecs::StreamType, std::unique_ptr<FIL> file); - ~FatfsSource(); - - auto Read(std::span<std::byte> dest) -> ssize_t override; - - auto CanSeek() -> bool override; - - auto SeekTo(int64_t destination, SeekFrom from) -> void override; - - auto CurrentPosition() -> int64_t override; - - auto Size() -> std::optional<int64_t> override; - - FatfsSource(const FatfsSource&) = delete; - FatfsSource& operator=(const FatfsSource&) = delete; - - private: - std::unique_ptr<FIL> file_; -}; - -} // namespace audio diff --git a/src/audio/include/i2s_audio_output.hpp b/src/audio/include/i2s_audio_output.hpp deleted file mode 100644 index 7954257a..00000000 --- a/src/audio/include/i2s_audio_output.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <stdint.h> -#include <cstdint> -#include <memory> -#include <vector> - -#include "audio_sink.hpp" -#include "gpios.hpp" -#include "i2s_dac.hpp" -#include "result.hpp" - -namespace audio { - -class I2SAudioOutput : public IAudioOutput { - public: - I2SAudioOutput(StreamBufferHandle_t, drivers::IGpios& expander); - ~I2SAudioOutput(); - - auto SetMaxVolume(uint16_t) -> void; - auto SetVolumeDb(uint16_t) -> void; - - auto SetVolumeImbalance(int_fast8_t balance) -> void override; - - auto SetVolume(uint16_t) -> void override; - - auto GetVolume() -> uint16_t override; - - auto GetVolumePct() -> uint_fast8_t override; - auto SetVolumePct(uint_fast8_t val) -> bool override; - auto GetVolumeDb() -> int_fast16_t override; - auto SetVolumeDb(int_fast16_t) -> bool override; - - auto AdjustVolumeUp() -> bool override; - auto AdjustVolumeDown() -> bool override; - - auto PrepareFormat(const Format&) -> Format override; - auto Configure(const Format& format) -> void override; - - I2SAudioOutput(const I2SAudioOutput&) = delete; - I2SAudioOutput& operator=(const I2SAudioOutput&) = delete; - - protected: - auto changeMode(Modes) -> void override; - - private: - drivers::IGpios& expander_; - std::unique_ptr<drivers::I2SDac> dac_; - - Modes current_mode_; - std::optional<Format> current_config_; - int_fast8_t left_difference_; - uint16_t current_volume_; - uint16_t max_volume_; -}; - -} // namespace audio diff --git a/src/audio/include/readahead_source.hpp b/src/audio/include/readahead_source.hpp deleted file mode 100644 index 74a30e1b..00000000 --- a/src/audio/include/readahead_source.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <cstddef> -#include <cstdint> -#include <memory> - -#include "freertos/FreeRTOS.h" - -#include "ff.h" -#include "freertos/stream_buffer.h" - -#include "audio_source.hpp" -#include "codec.hpp" -#include "tasks.hpp" - -namespace audio { - -/* - * Wraps another stream, proactively buffering large chunks of it into memory - * at a time. - */ -class ReadaheadSource : public codecs::IStream { - public: - ReadaheadSource(tasks::WorkerPool&, std::unique_ptr<codecs::IStream>); - ~ReadaheadSource(); - - auto Read(std::span<std::byte> dest) -> ssize_t override; - - auto CanSeek() -> bool override; - - auto SeekTo(int64_t destination, SeekFrom from) -> void override; - - auto CurrentPosition() -> int64_t override; - - auto Size() -> std::optional<int64_t> override; - - auto SetPreambleFinished() -> void override; - - ReadaheadSource(const ReadaheadSource&) = delete; - ReadaheadSource& operator=(const ReadaheadSource&) = delete; - - private: - auto BeginReadahead() -> void; - - tasks::WorkerPool& worker_; - std::unique_ptr<codecs::IStream> wrapped_; - - bool readahead_enabled_; - std::atomic<bool> is_refilling_; - StreamBufferHandle_t buffer_; - int64_t tell_; -}; - -} // namespace audio diff --git a/src/audio/include/resample.hpp b/src/audio/include/resample.hpp deleted file mode 100644 index 4d48d47f..00000000 --- a/src/audio/include/resample.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <cstdint> -#include <span> -#include <vector> - -#include "speex/speex_resampler.h" - -#include "sample.hpp" - -namespace audio { - -class Resampler { - public: - Resampler(uint32_t source_sample_rate, - uint32_t target_sample_rate, - uint8_t num_channels); - - ~Resampler(); - - auto Process(std::span<sample::Sample> input, - std::span<sample::Sample> output, - bool end_of_data) -> std::pair<size_t, size_t>; - - private: - int err_; - SpeexResamplerState* resampler_; - uint8_t num_channels_; -}; - -} // namespace audio diff --git a/src/audio/include/track_queue.hpp b/src/audio/include/track_queue.hpp deleted file mode 100644 index 5b7c9448..00000000 --- a/src/audio/include/track_queue.hpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#pragma once - -#include <list> -#include <memory> -#include <mutex> -#include <shared_mutex> -#include <vector> - -#include "audio_events.hpp" -#include "cppbor_parse.h" -#include "database.hpp" -#include "tasks.hpp" -#include "track.hpp" - -namespace audio { - -/* - * Utility that uses a Miller shuffle to yield well-distributed random indexes - * from within a range. - */ -class RandomIterator { - public: - RandomIterator(); - RandomIterator(size_t size); - - auto current() const -> size_t; - - auto next() -> void; - auto prev() -> void; - - // Note resizing has the side-effect of restarting iteration. - auto resize(size_t) -> void; - auto replay(bool) -> void; - - auto seed() -> size_t& { return seed_; } - auto pos() -> size_t& { return pos_; } - auto size() -> size_t& { return size_; } - - private: - size_t seed_; - size_t pos_; - size_t size_; - bool replay_; -}; - -/* - * Owns and manages a complete view of the playback queue. Includes the - * currently playing track, a truncated list of previously played tracks, and - * all future tracks that have been queued. - * - * In order to not use all of our memory, this class deals strictly with track - * ids. Consumers that need more data than this should fetch it from the - * database. - * - * Instances of this class are broadly safe to use from multiple tasks; each - * method represents an atomic operation. No guarantees are made about - * consistency between calls however. - */ -class TrackQueue { - public: - TrackQueue(tasks::WorkerPool& bg_worker); - - /* Returns the currently playing track. */ - auto current() const -> std::optional<database::TrackId>; - - /* Returns, in order, tracks that have been queued to be played next. */ - auto peekNext(std::size_t limit) const -> std::vector<database::TrackId>; - - /* - * Returns the tracks in the queue that have already been played, ordered - * most recently played first. - */ - auto peekPrevious(std::size_t limit) const -> std::vector<database::TrackId>; - - auto currentPosition() const -> size_t; - auto totalSize() const -> size_t; - - using Item = std::variant<database::TrackId, database::TrackIterator>; - auto insert(Item, size_t index = 0) -> void; - auto append(Item i) -> void; - - /* - * Advances to the next track in the queue, placing the current track at the - * front of the 'played' queue. - */ - auto next() -> void; - auto previous() -> void; - - /* - * Called when the current track finishes - */ - auto finish() -> void; - - auto skipTo(database::TrackId) -> void; - - /* - * Removes all tracks from all queues, and stops any currently playing track. - */ - auto clear() -> void; - - auto random(bool) -> void; - auto random() const -> bool; - - auto repeat(bool) -> void; - auto repeat() const -> bool; - - auto replay(bool) -> void; - auto replay() const -> bool; - - auto serialise() -> std::string; - auto deserialise(const std::string&) -> void; - - // Cannot be copied or moved. - TrackQueue(const TrackQueue&) = delete; - TrackQueue& operator=(const TrackQueue&) = delete; - - private: - auto next(QueueUpdate::Reason r) -> void; - - mutable std::shared_mutex mutex_; - - tasks::WorkerPool& bg_worker_; - - size_t pos_; - std::pmr::vector<database::TrackId> tracks_; - - std::optional<RandomIterator> shuffle_; - bool repeat_; - bool replay_; - - class QueueParseClient : public cppbor::ParseClient { - public: - QueueParseClient(TrackQueue& queue); - - ParseClient* item(std::unique_ptr<cppbor::Item>& item, - const uint8_t* hdrBegin, - const uint8_t* valueBegin, - const uint8_t* end) override; - - ParseClient* itemEnd(std::unique_ptr<cppbor::Item>& item, - const uint8_t* hdrBegin, - const uint8_t* valueBegin, - const uint8_t* end) override; - - void error(const uint8_t* position, - const std::string& errorMessage) override {} - - private: - TrackQueue& queue_; - - enum class State { - kInit, - kRoot, - kMetadata, - kShuffle, - kTracks, - kFinished, - }; - State state_; - size_t i_; - }; -}; - -} // namespace audio |
