Merge branch 'main' of codeberg.org:cool-tech-zone/tangara-fw

custom
ailurux 2 months ago
commit 29ad80d113
  1. BIN
      lua/img/back.png
  2. BIN
      lua/img/bat/0.png
  3. BIN
      lua/img/bat/100.png
  4. BIN
      lua/img/bat/20.png
  5. BIN
      lua/img/bat/40.png
  6. BIN
      lua/img/bat/60.png
  7. BIN
      lua/img/bat/80.png
  8. BIN
      lua/img/bat/chg.png
  9. BIN
      lua/img/bat/chg_outline.png
  10. BIN
      lua/img/bt.png
  11. BIN
      lua/img/bt_conn.png
  12. BIN
      lua/img/chevron.png
  13. BIN
      lua/img/db.png
  14. BIN
      lua/img/enqueue.png
  15. BIN
      lua/img/file_icons/directory.png
  16. BIN
      lua/img/file_icons/playlist.png
  17. BIN
      lua/img/files.png
  18. BIN
      lua/img/info.png
  19. BIN
      lua/img/listened.png
  20. BIN
      lua/img/menu.png
  21. BIN
      lua/img/next.png
  22. BIN
      lua/img/pause.png
  23. BIN
      lua/img/pausecirc.png
  24. BIN
      lua/img/play.png
  25. BIN
      lua/img/play_small.png
  26. BIN
      lua/img/playcirc.png
  27. BIN
      lua/img/prev.png
  28. BIN
      lua/img/queue.png
  29. BIN
      lua/img/repeat.png
  30. BIN
      lua/img/repeat_off.png
  31. BIN
      lua/img/repeat_queue.png
  32. BIN
      lua/img/settings.png
  33. BIN
      lua/img/shuffle.png
  34. BIN
      lua/img/shuffle_off.png
  35. BIN
      lua/img/shuffleplay.png
  36. BIN
      lua/img/unlistened.png
  37. BIN
      lua/img/usb.png
  38. 36
      src/tangara/app_console/app_console.cpp
  39. 34
      src/tangara/tts/README.md
  40. 2
      src/tangara/tts/player.cpp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 B

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 B

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 B

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 B

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 B

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 B

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 B

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 B

After

Width:  |  Height:  |  Size: 104 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

After

Width:  |  Height:  |  Size: 97 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

After

Width:  |  Height:  |  Size: 83 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 104 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 B

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 B

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 B

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

After

Width:  |  Height:  |  Size: 79 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 B

After

Width:  |  Height:  |  Size: 77 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 B

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 B

After

Width:  |  Height:  |  Size: 76 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 360 B

After

Width:  |  Height:  |  Size: 104 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 B

After

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 B

After

Width:  |  Height:  |  Size: 83 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 288 B

After

Width:  |  Height:  |  Size: 97 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 83 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 B

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 B

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 291 B

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 97 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 B

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 B

After

Width:  |  Height:  |  Size: 113 B

@ -207,8 +207,14 @@ void RegisterDbInit() {
int CmdTasks(int argc, char** argv) {
#if (configUSE_TRACE_FACILITY == 0)
std::cout << "configUSE_TRACE_FACILITY must be enabled" << std::endl;
std::cout << "also consider configTASKLIST_USE_COREID" << std::endl;
std::cout
<< "FreeRTOS is not configured to track task info." << std::endl
<< "You can enable task tracing via sdkconfig, by setting" << std::endl
<< "CONFIG_FREERTOS_USE_TRACE_FACILITY=y. Alternately, use" << std::endl
<< "idf.py menuconfig to enable Components/FreeRTOS/Kernel" << std::endl
<< "configUSE_TRACE_FACILITY to do the same." << std::endl << std::endl
<< "Also consider 'Enable display of xCoreID in vTaskList'," << std::endl
<< "or CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y" << std::endl;
return 1;
#endif
@ -218,6 +224,14 @@ int CmdTasks(int argc, char** argv) {
return 1;
}
// Sample the task runtime percentage over 2.5 seconds if collecting
// task statistics. Else, we don't need to sample for as long.
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
const int kSamplePeriodMs = 2500;
#else
const int kSamplePeriodMs = 10;
#endif
// Pad the number of tasks so that uxTaskGetSystemState still returns info
// if new tasks are started during measurement.
size_t num_tasks = uxTaskGetNumberOfTasks() + 4;
@ -229,11 +243,23 @@ int CmdTasks(int argc, char** argv) {
size_t start_num_tasks =
uxTaskGetSystemState(start_status, num_tasks, &start_elapsed_ticks);
vTaskDelay(pdMS_TO_TICKS(2500));
vTaskDelay(pdMS_TO_TICKS(kSamplePeriodMs));
size_t end_num_tasks =
uxTaskGetSystemState(end_status, num_tasks, &end_elapsed_ticks);
uint32_t elapsed_ticks = end_elapsed_ticks - start_elapsed_ticks;
if (0 == elapsed_ticks) {
std::cout << "Warning: the scheduler is not recording run-time" << std::endl
<< "statistics, and this means that detailed task" << std::endl
<< "information is not available." << std::endl
<< "Enable CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS" << std::endl
<< "in sdkconfig to capture these stats, or via" << std::endl
<< "idf.py menuconfig, in Components/FreeRTOS/Kernel" << std::endl
<< "configGENERATE_RUN_TIME_STATS." << std::endl;
}
std::vector<std::pair<uint32_t, std::pmr::string>> info_strings;
for (int i = 0; i < start_num_tasks; i++) {
int k = -1;
@ -279,8 +305,12 @@ int CmdTasks(int argc, char** argv) {
str << "\t\t";
}
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
str << std::fixed << std::setprecision(1) << (time_percent * 100);
str << "%";
#else
str << "(unavailable)";
#endif
info_strings.push_back({run_time, std::pmr::string{str.str()}});
}

@ -47,3 +47,37 @@ logs a `WARN`ing each time it cannot find a TTS sample. You can enable
these log messages on the console by using the command `loglevel warn`,
and then manipulating the click wheel to move through the UI to discover
other missing TTS samples.
## Tasks and Event Passing
### In the `ui` task
There are two main threads involved with running TTS - firstly, the `ui`
task, which is rooted in `ui::UiTask::Main()` (`src/tangara/ui/lvgl_task.hpp)`.
By way of the LVGL stack, eventually navigation in the UI results in sending
a `tts::SelectionChanged` message from `input::TextToSpeech::describe()`
(`src/tangara/input/feedback_tts.cpp`) to `tts::Provider::feed()`
(`src/tangara/tts/provider.cpp`), all in the UI task.
The `tts::Provider` is responsible for translating the UI string from a lump
of text to a TTS sample filename, which is then passed along to the player
in `tts::Player::playFile()` (`src/tangara/tts/player.cpp`), still on the UI
thread.
The UI task has a smaller stack than the `worker_X` tasks, and are not
appropriate to use for audio decoding work, both because they would block any
UI updates, and also have insufficient stack space for audio decode activity.
### Transitioning to the `WorkerPool` background threads
`playFile()` uses `tasks::WorkerPool::Dispatch()` to fire off a lambda in a
different task - one of the background `worker_X` tasks, owned by `WorkerPool`.
Control returns to the UI thread in under 2ms, so it remains pretty responsive
throughout this flow.
The background worker uses `tts::Player::openAndDecode` to do the bulk of the
decode/resample/playback work, and it is on this background task that the
majority of the work occurs. Note that there is nothing stopping the TTS worker
from consuming a number of worker tasks at once, but we rely on the interaction
of stream cancellation behaviour between the workers to ensure that previous
samples' playback is promptly terminated after a new sample is requested.

@ -174,7 +174,7 @@ auto Player::decodeToSink(const codecs::ICodec::OutputFormat& format,
// The mixin PcmBuffer should almost always be draining, so we can force
// samples into it more aggressively than with the main music PcmBuffer.
while (!stereo_buf.isEmpty()) {
while (!stereo_buf.isEmpty() && !stream_cancelled_) {
size_t sent = output_.send(stereo_buf.readAcquire());
stereo_buf.readCommit(sent);
}

Loading…
Cancel
Save