Repository navigation
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe pull request adds Tone as a Tactility app, with CMake configuration, a manifest, and feature documentation. It adds five waveform generators, fixed-frequency and sweep selection, and task-based audio playback with start, stop, and status functions. The interface provides frequency, waveform, channel, sweep, and volume controls, plus playback readouts. The app initializes its context and event handling, then stops playback and cleans up when it receives a close event. Priority: ⬇️ Low
|
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Advanced
Run ID: a05f571a-0d0d-44e7-aabd-73562038d3b6
📒 Files selected for processing (5)
.github/workflows/main.ymlApps/Tone/CMakeLists.txtApps/Tone/main/CMakeLists.txtApps/Tone/main/Source/App.cppApps/Tone/manifest.properties
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.
|
Neat! |
|
Seems like I broke the build. I'll fix it. |
|
@NellowTCS
edit: I was able to resolve it myself. |
Signed-off-by: Ken Van Hoeylandt <git@kenvanhoeylandt.net>
|
I'll rebase the branch, test UI + photos, and get it ready to merge today! |
|
Today, he said 😭 |
There was a problem hiding this comment.
Actionable comments posted: 3
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
98e0cfa8-139b-4318-aee7-7dfd1c41921a
📒 Files selected for processing (9)
Apps/Tone/README.mdApps/Tone/main/CMakeLists.txtApps/Tone/main/Source/Tone.hApps/Tone/main/Source/TonePlayback.cppApps/Tone/main/Source/TonePlayback.hApps/Tone/main/Source/ToneSynth.cppApps/Tone/main/Source/ToneSynth.hApps/Tone/main/Source/ToneUi.cppApps/Tone/main/Source/main.cpp
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.
🟠 Major · Serialize closing with Play callbacks. · main.cpp:46-53
Apps/Tone/main/Source/main.cpp:46-53
🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy liftSerialize closing with Play callbacks.
onPlayPressedcan run on the LVGL thread while the app main thread handlesAPP_EVENT_CLOSE.tone_playback_stopwaits only for the task that exists when it checkstask. A Play callback that runs after that check can start a new task with&ctx.playback.window_manager_removecan then complete andmaincan destroy the stack-ownedContextwhile the new task still accesses it.Set the closing state before stopping playback. Serialize that state with
tone_playback_startso a callback cannot pass the check during the close transition.Suggested fix
diff --git a/Apps/Tone/main/Source/Tone.h b/Apps/Tone/main/Source/Tone.h @@ #include <lvgl/lvgl.h> +#include <freertos/semphr.h> @@ struct Context { AppInstanceId appInstanceId = 0; TonePlayback playback; + SemaphoreHandle_t playbackGate = nullptr; + bool closing = false; // UI-only state, touched exclusively on the LVGL thread.diff --git a/Apps/Tone/main/Source/main.cpp b/Apps/Tone/main/Source/main.cpp @@ Context ctx {}; + ctx.playbackGate = xSemaphoreCreateMutex(); + check(ctx.playbackGate != nullptr); ctx.appInstanceId = appInstanceId; @@ } // Stop playback and join the audio task before the window (and its widgets) are destroyed. + xSemaphoreTake(ctx.playbackGate, portMAX_DELAY); + ctx.closing = true; + xSemaphoreGive(ctx.playbackGate); tone_playback_stop(&ctx.playback); @@ check(app_event_unsubscribe(&sub) == ERROR_NONE); task_event_group_destruct(&eventGroup); + vSemaphoreDelete(ctx.playbackGate); return 0;diff --git a/Apps/Tone/main/Source/ToneUi.cpp b/Apps/Tone/main/Source/ToneUi.cpp @@ void onPlayPressed(lv_event_t* event) { auto* ctx = static_cast<Context*>(lv_event_get_user_data(event)); + xSemaphoreTake(ctx->playbackGate, portMAX_DELAY); + if (ctx->closing) { + xSemaphoreGive(ctx->playbackGate); + return; + } + if (ctx->playback.playing.load()) { tone_playback_stop(&ctx->playback); updatePlayButton(ctx); updateChannelAvailability(ctx); updateReadout(ctx); + xSemaphoreGive(ctx->playbackGate); return; } const error_t result = tone_playback_start(&ctx->playback); if (result != ERROR_NONE) { @@ lv_label_set_text_fmt(ctx->readoutStatusLabel, "Playback failed (%s)", error_to_string(result)); } + xSemaphoreGive(ctx->playbackGate); return; } updatePlayButton(ctx); updateChannelAvailability(ctx); updateReadout(ctx); + xSemaphoreGive(ctx->playbackGate); }
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
6d2f46f3-be56-4a10-961d-574e2966f6ff
📒 Files selected for processing (4)
Apps/Tone/main/Source/TonePlayback.cppApps/Tone/main/Source/ToneSynth.cppApps/Tone/main/Source/ToneSynth.hApps/Tone/main/Source/ToneUi.cpp
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
15460e4e-0b23-4364-96ce-821f1af0f406
📒 Files selected for processing (5)
Apps/Tone/main/Source/Tone.hApps/Tone/main/Source/TonePlayback.cppApps/Tone/main/Source/TonePlayback.hApps/Tone/main/Source/ToneUi.cppApps/Tone/main/Source/main.cpp
🚧 Files skipped from review as they are similar to previous changes (2)
- Apps/Tone/main/Source/TonePlayback.h
- Apps/Tone/main/Source/TonePlayback.cpp
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.
| check(app_event_unsubscribe(&sub) == ERROR_NONE); | ||
| task_event_group_destruct(&eventGroup); | ||
| vSemaphoreDelete(ctx.playbackGate); | ||
| vSemaphoreDelete(ctx.playback.lifecycleMutex); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Do not delete the lifecycle mutex before the playback task finishes.
If the playback task pauses after clearing playback.task, tone_playback_stop() can return while the task still needs playback.lifecycleMutex. Line 64 can then delete the mutex before the task calls xSemaphoreGive(). Make task completion observable only after its final use of the mutex, including on the allocation-failure path. (github.com)
There was a problem hiding this comment.
@NellowTCS This seems like a valid concern.
I reviewed the rest of the code and it looks fine.
Adds a Tone Generator app.
Images
CL-32
CYD-2.2"
Cardputer
T-Deck
Summary by CodeRabbit