diff options
| author | jacqueline <me@jacqueline.id.au> | 2022-11-17 17:36:37 +1100 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2022-11-17 17:36:37 +1100 |
| commit | acd6d7890051b9253007941733ea37e4011b1b5e (patch) | |
| tree | 5a542b3c98fe2a37dd9c10d9093a6e46b2267875 /src/audio/fatfs_audio_input.cpp | |
| parent | ddcbcad6d4771e0ec8228dc1848ebd1dfe303a0b (diff) | |
| download | tangara-fw-acd6d7890051b9253007941733ea37e4011b1b5e.tar.gz | |
Progress on own pipeline. Still very WIP
Diffstat (limited to 'src/audio/fatfs_audio_input.cpp')
| -rw-r--r-- | src/audio/fatfs_audio_input.cpp | 110 |
1 files changed, 93 insertions, 17 deletions
diff --git a/src/audio/fatfs_audio_input.cpp b/src/audio/fatfs_audio_input.cpp index 1e8c35b8..df38f1d6 100644 --- a/src/audio/fatfs_audio_input.cpp +++ b/src/audio/fatfs_audio_input.cpp @@ -1,28 +1,42 @@ -#include "fatfs_audio_input.hpp" +#include "fatfs_audio_input.hpp<D-c>ccc +#include <cstdint> #include <memory> -#include "esp-adf/components/input_key_service/include/input_key_service.h" #include "esp_heap_caps.h" #include "audio_element.hpp" +#include "freertos/portmacro.h" +#include "include/audio_element.hpp" namespace audio { -static const size_t kQueueItems = 0; -static constexpr size_t kQueueItemSize = sizeof(IAudioElement::Command); -static constexpr size_t kQueueSize = kQueueItems * kQueueItemSize; +static const TickType_t kMaxWaitTicks = portMAX_DELAY; -static const size_t kOutputBufferSize = 1024; +// Large output buffer size, so that we can keep a get as much of the input file +// into memory as soon as possible. +static constexpr std::size_t kOutputBufferSize = 1024 * 128; +static constexpr std::size_t kQueueItemSize = sizeof(IAudioElement::Command); +// Use a large enough command queue size that we can fit reads for the full +// buffer into the queue. +static constexpr std::size_t kOutputQueueItemNumber = kOutputBufferSize / kMaxFrameSize; +static constexpr std::size_t kOutputQueueSize = kOutputQueueItemNumber * kQueueItemSize; + +// This should be a relatively responsive element, so no need for a particularly +// large queue. +static constexpr std::size_t kInputQueueItemNumber = 4; +static constexpr std::size_t kInputQueueSize = kInputQueueItemNumber * kQueueItemSize; FatfsAudioInput::FatfsAudioInput(std::shared_ptr<drivers::SdStorage> storage) : IAudioElement(), storage_(storage) { - input_queue_memory_ = heap_caps_malloc(kQueueSize, MALLOC_CAP_SPIRAM); + working_buffer_ = heap_caps_malloc(kMaxFrameSize, MALLOC_CAP_SPIRAM); + + input_queue_memory_ = heap_caps_malloc(kInputQueueSize, MALLOC_CAP_SPIRAM); input_queue_ = xQueueCreateStatic( - kQueueItems, kQueueItemSize, input_queue_memory_, &input_queue_metadata_); + kInputQueueItemNumber, kQueueItemSize, input_queue_memory_, &input_queue_metadata_); - output_queue_memory_ = heap_caps_malloc(kQueueSize, MALLOC_CAP_SPIRAM); + output_queue_memory_ = heap_caps_malloc(kOutputQueueSize, MALLOC_CAP_SPIRAM); output_queue_ = - xQueueCreateStatic(kQueueItems, kQueueItemSize, output_queue_memory_, + xQueueCreateStatic(kOutputQueueItems, kQueueItemSize, output_queue_memory_, &output_queue_metadata_); output_buffer_memory_ = @@ -33,6 +47,7 @@ FatfsAudioInput::FatfsAudioInput(std::shared_ptr<drivers::SdStorage> storage) } FatfsAudioInput::~FatfsAudioInput() { + free(working_buffer_); vStreamBufferDelete(output_buffer_); free(output_buffer_memory_); vQueueDelete(output_queue_); @@ -57,23 +72,84 @@ auto FatfsAudioInput::OutputBuffer() -> StreamBufferHandle_t { return output_buffer_; } -auto FatfsAudioInput::ProcessElementCommand(void* command) -> void { - InputCommand *real = std::reinterpret_pointer_cast<input_key_service_add_key*>(command); +auto FatfsAudioInput::ProcessElementCommand(void* command) -> ProcessResult { + InputCommand *real = std::reinterpret_cast<InputCommand*>(command); + + if (uxQueueSpacesAvailable(output_queue_) < 2) { + return OUTPUT_FULL; + } + + if (is_file_open_) { + f_close(¤t_file_); + } + + FRESULT res = f_open(¤t_file_, real->filename.c_str(), FA_READ); + if (res != FR_OK) { + delete real; + return ERROR; + } + + if (real->seek_to && f_lseek(¤t_file_, real->seek_to) { + return ERROR; + } + + is_file_open_ = true; + current_sequence_++; + + Command sequence_update; + sequence_update.type = SEQUENCE_NUMBER; + sequence_update.sequence_number = current_sequence_; - // TODO. + if (real->interrupt) { + xQueueSendToFront(output_queue_, &sequence_update, kMaxWaitTicks); + } else { + xQueueSendToBack(output_queue_, &sequence_update, kMaxWaitTicks); + } + + OutputCommand *data = new OutputCommand; + data->extension = "txt"; + Command file_info; + file_info.type = ELEMENT; + file_info.sequence_number = current_sequence_; + file_info.data = &data; + xQueueSendToBack(output_queue_, &file_info, kMaxWaitTicks); + + delete real; + return OK; } auto FatfsAudioInput::SkipElementCommand(void* command) -> void { - InputCommand *real = std::reinterpret_pointer_cast<input_key_service_add_key*>(command); + InputCommand *real = std::reinterpret_cast<input_key_service_add_key*>(command); delete real; } auto FatfsAudioInput::ProcessData(uint8_t* data, uint16_t length) -> void { - // Not implemented. + // Not used, since we have no input stream. } -auto FatfsAudioInput::ProcessIdle() -> void { - // TODO. +auto FatfsAudioInput::ProcessIdle() -> ProcessResult { + if (!is_file_open_) { + return OK; + } + + if (xStreamBufferSpacesAvailable(output_buffer) < kMaxFrameSize) { + return OUTPUT_FULL; + } + + UINT bytes_read = 0; + FRESULT result = f_read(¤t_file_, working_buffer_, kMaxFrameSize, &bytes_read); + if (!FR_OK) { + return ERROR; + } + + xStreamBufferSend(&output_buffer_, working_buffer_, bytes_read, kMaxWaitTicks); + + if (f_eof(¤t_file_)) { + f_close(¤t_file_); + is_file_open_ = false; + } + + return OK; } } // namespace audio |
