From 4c88fcc4a57b1fae7b6edaf42034945d5ac24a89 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Fri, 20 Jan 2023 09:48:29 +1100 Subject: fix build issues with new pipeline --- src/audio/audio_element_handle.cpp | 79 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/audio/audio_element_handle.cpp (limited to 'src/audio/audio_element_handle.cpp') 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 task, + std::shared_ptr 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 -- cgit v1.2.3