summaryrefslogtreecommitdiff
path: root/src/audio/audio_element_handle.cpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-01-20 09:48:29 +1100
committerjacqueline <me@jacqueline.id.au>2023-01-20 09:48:29 +1100
commit4c88fcc4a57b1fae7b6edaf42034945d5ac24a89 (patch)
treee44c384ba40e9eab37374b3f339c79e9bf1fde5d /src/audio/audio_element_handle.cpp
parente53dfc4cc59fd0c3b01dc74762c1904f3ec9cc06 (diff)
downloadtangara-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.cpp79
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