summaryrefslogtreecommitdiff
path: root/src/audio/include
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-07-26 17:11:23 +1000
committerjacqueline <me@jacqueline.id.au>2023-07-26 17:11:23 +1000
commit9b1b401dcb986a26d10bcc898be670653acc2d3f (patch)
tree697b14553dc75ddaab060406cd62ee4b08f05e9e /src/audio/include
parentf94be3db2f2bb6c1b359744cb915683095e4ee80 (diff)
downloadtangara-fw-9b1b401dcb986a26d10bcc898be670653acc2d3f.tar.gz
big cleanup of new encoder + stream buffer types
Diffstat (limited to 'src/audio/include')
-rw-r--r--src/audio/include/audio_sink.hpp2
-rw-r--r--src/audio/include/audio_source.hpp20
-rw-r--r--src/audio/include/audio_task.hpp18
-rw-r--r--src/audio/include/fatfs_audio_input.hpp13
-rw-r--r--src/audio/include/i2s_audio_output.hpp2
-rw-r--r--src/audio/include/stream_info.hpp72
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_;
};