diff options
Diffstat (limited to 'src/audio/include')
| -rw-r--r-- | src/audio/include/audio_sink.hpp | 2 | ||||
| -rw-r--r-- | src/audio/include/audio_source.hpp | 20 | ||||
| -rw-r--r-- | src/audio/include/audio_task.hpp | 18 | ||||
| -rw-r--r-- | src/audio/include/fatfs_audio_input.hpp | 13 | ||||
| -rw-r--r-- | src/audio/include/i2s_audio_output.hpp | 2 | ||||
| -rw-r--r-- | src/audio/include/stream_info.hpp | 72 |
6 files changed, 81 insertions, 46 deletions
diff --git a/src/audio/include/audio_sink.hpp b/src/audio/include/audio_sink.hpp index c9124688..261f7c79 100644 --- a/src/audio/include/audio_sink.hpp +++ b/src/audio/include/audio_sink.hpp @@ -38,7 +38,7 @@ class IAudioSink { virtual auto AdjustVolumeUp() -> bool = 0; virtual auto AdjustVolumeDown() -> bool = 0; - virtual auto Configure(const StreamInfo::Format& format) -> bool = 0; + virtual auto Configure(const StreamInfo::Pcm& format) -> bool = 0; virtual auto Send(const cpp::span<std::byte>& data) -> void = 0; auto stream() -> StreamBufferHandle_t { return stream_; } diff --git a/src/audio/include/audio_source.hpp b/src/audio/include/audio_source.hpp index e062fd1a..115f8bf4 100644 --- a/src/audio/include/audio_source.hpp +++ b/src/audio/include/audio_source.hpp @@ -8,6 +8,7 @@ #include <stdint.h> +#include <bitset> #include <memory> #include "freertos/FreeRTOS.h" @@ -22,12 +23,25 @@ class IAudioSource { public: virtual ~IAudioSource() {} + class Flags { + public: + Flags(bool is_start, bool is_end) { + flags_[0] = is_start; + flags_[1] = is_start; + } + + auto is_start() -> bool { return flags_[0]; } + auto is_end() -> bool { return flags_[1]; } + + private: + std::bitset<2> flags_; + }; + /* * Synchronously fetches data from this source. */ - virtual auto Read(std::function<bool(StreamInfo::Format)>, - std::function<size_t(cpp::span<const std::byte>)>, - TickType_t) -> void = 0; + virtual auto Read(std::function<void(Flags, InputStream&)>, TickType_t) + -> void = 0; }; } // namespace audio diff --git a/src/audio/include/audio_task.hpp b/src/audio/include/audio_task.hpp index f80c8878..ae4c2221 100644 --- a/src/audio/include/audio_task.hpp +++ b/src/audio/include/audio_task.hpp @@ -14,6 +14,7 @@ #include "audio_source.hpp" #include "codec.hpp" #include "pipeline.hpp" +#include "stream_info.hpp" namespace audio { @@ -27,10 +28,13 @@ class Timer { auto AddBytes(std::size_t) -> void; private: + auto bytes_to_samples(uint32_t) -> uint32_t; + StreamInfo::Pcm format_; uint32_t current_seconds_; uint32_t current_sample_in_second_; + uint32_t total_duration_seconds_; }; @@ -43,14 +47,24 @@ class AudioTask { private: AudioTask(IAudioSource* source, IAudioSink* sink); + auto HandleNewStream(const InputStream&) -> bool; + + auto BeginDecoding(InputStream&) -> bool; + auto ContinueDecoding(InputStream&) -> bool; + auto FinishDecoding(InputStream&) -> void; + + auto ForwardPcmStream(StreamInfo::Pcm&, cpp::span<const std::byte>) -> bool; + + auto ConfigureSink(const StreamInfo::Pcm&) -> bool; + IAudioSource* source_; IAudioSink* sink_; std::unique_ptr<codecs::ICodec> codec_; std::unique_ptr<Timer> timer_; - bool is_new_stream_; + bool has_begun_decoding_; std::optional<StreamInfo::Format> current_input_format_; - std::optional<StreamInfo::Format> current_output_format_; + std::optional<StreamInfo::Pcm> current_output_format_; std::byte* sample_buffer_; std::size_t sample_buffer_len_; diff --git a/src/audio/include/fatfs_audio_input.hpp b/src/audio/include/fatfs_audio_input.hpp index a1b9689b..e13e49e2 100644 --- a/src/audio/include/fatfs_audio_input.hpp +++ b/src/audio/include/fatfs_audio_input.hpp @@ -89,9 +89,8 @@ class FatfsAudioInput : public IAudioSource { auto SetPath(const std::string&) -> void; auto SetPath() -> void; - auto Read(std::function<bool(StreamInfo::Format)>, - std::function<size_t(cpp::span<const std::byte>)>, - TickType_t) -> void override; + auto Read(std::function<void(Flags, InputStream&)>, TickType_t) + -> void override; FatfsAudioInput(const FatfsAudioInput&) = delete; FatfsAudioInput& operator=(const FatfsAudioInput&) = delete; @@ -118,11 +117,7 @@ class FatfsAudioInput : public IAudioSource { StreamBufferHandle_t streamer_buffer_; std::unique_ptr<FileStreamer> streamer_; - StreamInfo file_buffer_info_; - std::size_t file_buffer_len_; - std::byte* file_buffer_; - - RawStream file_buffer_stream_; + std::unique_ptr<RawStream> input_buffer_; // Mutex guarding the current file/stream associated with this source. Must be // held during readings, and before altering the current file. @@ -130,7 +125,7 @@ class FatfsAudioInput : public IAudioSource { std::unique_ptr<database::FutureFetcher<std::optional<std::string>>> pending_path_; - std::optional<StreamInfo::Format> current_format_; + bool is_first_read_; }; } // namespace audio diff --git a/src/audio/include/i2s_audio_output.hpp b/src/audio/include/i2s_audio_output.hpp index 583a5d6a..d42efc42 100644 --- a/src/audio/include/i2s_audio_output.hpp +++ b/src/audio/include/i2s_audio_output.hpp @@ -34,7 +34,7 @@ class I2SAudioOutput : public IAudioSink { auto AdjustVolumeUp() -> bool override; auto AdjustVolumeDown() -> bool override; - auto Configure(const StreamInfo::Format& format) -> bool override; + auto Configure(const StreamInfo::Pcm& format) -> bool override; auto Send(const cpp::span<std::byte>& data) -> void override; I2SAudioOutput(const I2SAudioOutput&) = delete; diff --git a/src/audio/include/stream_info.hpp b/src/audio/include/stream_info.hpp index 00aa1110..77789c24 100644 --- a/src/audio/include/stream_info.hpp +++ b/src/audio/include/stream_info.hpp @@ -7,6 +7,7 @@ #pragma once #include <stdint.h> +#include <sys/_stdint.h> #include <cstdint> #include <optional> #include <string> @@ -25,25 +26,26 @@ namespace audio { -struct StreamInfo { +class StreamInfo { + public: + StreamInfo() : bytes_in_stream_(0), total_length_bytes_(), format_() {} + // The number of bytes that are available for consumption within this // stream's buffer. - std::size_t bytes_in_stream{0}; - - bool is_producer_finished = true; - - bool is_consumer_finished = true; - - std::optional<std::uint32_t> duration_seconds; + auto bytes_in_stream() -> std::size_t& { return bytes_in_stream_; } + auto bytes_in_stream() const -> std::size_t { return bytes_in_stream_; } - std::optional<std::uint32_t> seek_to_seconds{}; + auto total_length_bytes() -> std::optional<std::uint32_t>& { + return total_length_bytes_; + } + auto total_length_bytes() const -> std::optional<std::uint32_t> { + return total_length_bytes_; + } struct Encoded { // The codec that this stream is associated with. codecs::StreamType type; - std::optional<std::size_t> duration_bytes; - bool operator==(const Encoded&) const = default; }; @@ -59,33 +61,48 @@ struct StreamInfo { }; typedef std::variant<std::monostate, Encoded, Pcm> Format; - Format format{}; + auto format() const -> const Format& { return format_; } + auto set_format(Format f) -> void { format_ = f; } + + template <typename T> + auto format_as() const -> std::optional<T> { + if (std::holds_alternative<T>(format_)) { + return std::get<T>(format_); + } + return {}; + } bool operator==(const StreamInfo&) const = default; + + private: + std::size_t bytes_in_stream_; + std::optional<std::uint32_t> total_length_bytes_; + Format format_{}; }; +class InputStream; +class OutputStream; + class RawStream { public: - StreamInfo* info; - cpp::span<std::byte> data; + explicit RawStream(std::size_t size); + ~RawStream(); - RawStream(StreamInfo* i, cpp::span<std::byte> d) : info(i), data(d) {} + auto info() -> StreamInfo& { return info_; } + auto data() -> cpp::span<std::byte>; + + private: + StreamInfo info_; + std::size_t buffer_size_; + std::byte* buffer_; }; -/* - * A byte buffer + associated metadata, which is not allowed to modify any of - * the underlying data. - */ class InputStream { public: explicit InputStream(RawStream* s) : raw_(s) {} void consume(std::size_t bytes) const; - bool is_producer_finished() const; - - void mark_consumer_finished() const; - const StreamInfo& info() const; cpp::span<const std::byte> data() const; @@ -100,18 +117,13 @@ class OutputStream { void add(std::size_t bytes) const; - bool prepare(const StreamInfo::Format& new_format); - - void set_duration(std::size_t); + void prepare(const StreamInfo::Format& new_format, + std::optional<uint32_t> length); const StreamInfo& info() const; cpp::span<std::byte> data() const; - bool is_consumer_finished() const; - - void mark_producer_finished() const; - private: RawStream* raw_; }; |
