From a7df2855889055976956a58d2a36f23626371ee9 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Wed, 23 Nov 2022 17:15:06 +1100 Subject: Mostly done pipeline arch. Now onto cleanup and building. --- src/audio/include/audio_element.hpp | 69 ++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 8 deletions(-) (limited to 'src/audio/include/audio_element.hpp') diff --git a/src/audio/include/audio_element.hpp b/src/audio/include/audio_element.hpp index 0be58f48..2a2f0727 100644 --- a/src/audio/include/audio_element.hpp +++ b/src/audio/include/audio_element.hpp @@ -3,30 +3,83 @@ #include #include #include "freertos/portmacro.h" -#include "types.hpp" #include "result.hpp" +#include "types.hpp" namespace audio { -extern const std::size_t kMaxFrameSize; - +/* + * One indepedentent part of an audio pipeline. Each element has an input and + * output message stream, and is responsible for taking data from the input + * stream, applying some kind of transformation to it, then sending the result + * out via the output stream. All communication with an element should be done + * over these streams, as an element's methods are only safe to call from the + * task that owns it. + * + * Each element implementation will have its input stream automatically parsed + * by its owning task, and its various Process* methods will be invoked + * accordingly. Element implementations are responsible for managing their own + * writes to their output streams. + */ class IAudioElement { public: + IAudioElement() : input_buffer_(nullptr), output_buffer_(nullptr) {} virtual ~IAudioElement(); + /* + * Returns the stack size in bytes that this element requires. This should + * be tuned according to the observed stack size of each element, as different + * elements have fairly different stack requirements. + */ + virtual auto StackSizeBytes() -> std::size_t { return 2048; }; + + /* + * How long to wait for new data on the input stream before triggering a call + * to ProcessIdle(). If this is portMAX_DELAY (the default), then ProcessIdle + * will never be called. + */ virtual auto IdleTimeout() -> TickType_t { return portMAX_DELAY; } - virtual auto InputBuffer() -> MessageBufferHandle_t* = 0; + /* Returns this element's input buffer. */ + auto InputBuffer() -> MessageBufferHandle_t* { return input_buffer_; } - virtual auto OutputBuffer() -> MessageBufferHandle_t* = 0; + /* Returns this element's output buffer. */ + auto OutputBuffer() -> MessageBufferHandle_t* { return output_buffer_; } + /* Errors that may be returned by any of the Process* methods. */ enum StreamError { - BAD_FORMAT + // Indicates that this element is unable to handle the upcoming chunks. + UNSUPPORTED_STREAM, + // Indicates an error with reading or writing stream data. + IO_ERROR, }; - virtual auto ProcessStreamInfo(StreamInfo &info) -> cpp::result = 0; - virtual auto ProcessChunk(uint8_t* data, std::size_t length) -> cpp::result = 0; + /* + * Called when a StreamInfo message is received. Used to configure this + * element in preperation for incoming chunks. + */ + virtual auto ProcessStreamInfo(StreamInfo&& info) + -> cpp::result = 0; + + /* + * Called when a ChunkHeader message is received. Includes the data associated + * with this chunk of stream data. This method should return the number of + * bytes in this chunk that were actually used; leftover bytes will be + * prepended to the next call. + */ + virtual auto ProcessChunk(uint8_t* data, std::size_t length) + -> cpp::result = 0; + + /* + * Called when there has been no data received over the input buffer for some + * time. This could be used to synthesize output, or to save memory by + * releasing unused resources. + */ virtual auto ProcessIdle() -> cpp::result = 0; + + protected: + StreamBufferHandle_t* input_buffer_; + StreamBufferHandle_t* output_buffer_; }; } // namespace audio -- cgit v1.2.3