diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-01-20 09:48:29 +1100 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-01-20 09:48:29 +1100 |
| commit | 4c88fcc4a57b1fae7b6edaf42034945d5ac24a89 (patch) | |
| tree | e44c384ba40e9eab37374b3f339c79e9bf1fde5d /src/audio/audio_element_handle.cpp | |
| parent | e53dfc4cc59fd0c3b01dc74762c1904f3ec9cc06 (diff) | |
| download | tangara-fw-4c88fcc4a57b1fae7b6edaf42034945d5ac24a89.tar.gz | |
fix build issues with new pipeline
Diffstat (limited to 'src/audio/audio_element_handle.cpp')
| -rw-r--r-- | src/audio/audio_element_handle.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/audio/audio_element_handle.cpp b/src/audio/audio_element_handle.cpp new file mode 100644 index 00000000..4b746db3 --- /dev/null +++ b/src/audio/audio_element_handle.cpp @@ -0,0 +1,79 @@ +#include "audio_element_handle.hpp" +#include "audio_element.hpp" +#include "freertos/projdefs.h" + +namespace audio { + +AudioElementHandle::AudioElementHandle(std::unique_ptr<TaskHandle_t> task, + std::shared_ptr<IAudioElement> element) + : task_(std::move(task)), element_(std::move(element)) {} + +AudioElementHandle::~AudioElementHandle() { + Quit(); +} + +auto AudioElementHandle::CurrentState() -> ElementState { + return element_->ElementState(); +} + +auto AudioElementHandle::PlayPause(enum PlayPause state) -> void { + ElementState s = CurrentState(); + if (state == PLAY && s == STATE_PAUSE) { + // Ensure we actually finished any previous pause command. + // TODO: really? + PauseSync(); + SetStateAndWakeUp(STATE_RUN); + return; + } + if (state == PAUSE && s == STATE_RUN) { + element_->ElementState(STATE_PAUSE); + SetStateAndWakeUp(STATE_PAUSE); + return; + } +} + +auto AudioElementHandle::Quit() -> void { + SetStateAndWakeUp(STATE_QUIT); +} + +auto AudioElementHandle::PauseSync() -> void { + PlayPause(PAUSE); + MonitorUtilState(eSuspended); +} + +auto AudioElementHandle::QuitSync() -> void { + Quit(); + MonitorUtilState(eDeleted); +} + +auto AudioElementHandle::MonitorUtilState(eTaskState desired) -> void { + while (eTaskGetState(task_.get()) != desired) { + WakeUpTask(); + vTaskDelay(pdMS_TO_TICKS(1)); + } +} + +auto AudioElementHandle::SetStateAndWakeUp(ElementState state) -> void { + element_->ElementState(state); + WakeUpTask(); +} + +auto AudioElementHandle::WakeUpTask() -> void { + // TODO: various races where the task isn't blocked yet, but there is a block + // between now and its next element state check. Also think about chunk blocks + // nested in element bodies. + // Maybe we need a big mutex or semaphore somewhere in here. + switch (eTaskGetState(task_.get())) { + case eBlocked: + // TODO: when is this safe? + xTaskAbortDelay(task_.get()); + break; + case eSuspended: + vTaskResume(task_.get()); + break; + default: + return; + } +} + +} // namespace audio |
