Skip to content

feat: MEMS microphone software handling for TX15 and TX16SMK3#7328

Open
3djc wants to merge 7 commits into
mainfrom
3djc/test
Open

feat: MEMS microphone software handling for TX15 and TX16SMK3#7328
3djc wants to merge 7 commits into
mainfrom
3djc/test

Conversation

@3djc
Copy link
Copy Markdown
Collaborator

@3djc 3djc commented Apr 28, 2026

Summary

  • Adds a software PDM (Pulse Density Modulation) driver for MEMS microphones using SPI+DMA to clock and sample the PDM bitstream and a CIC filter to decimate it to PCM audio.
  • Adds a pdm_wav_recorder module that captures PCM samples into a WAV file on the SD card, with configurable sample rate and duration.
  • Adds a "Mic Recorder" page in the Radio Tools GUI (Color LCD only), allowing users to trigger recordings directly from the radio menu.
  • Exposes a rec CLI command for recording from the debug console.

To record, head to Tools menu, a mic record tool will be displayed. Files are saved in /SOUNDS/

Please note that because there are no DMA channels left, flysky gimbal support cannot be used if mic is desired (compiling with flysky gimbal enabled will disable microphone support on TX15 (flysky gimbal support hasn't been implement on tx16smk3, hence mk3 doesn't suffer that limitation (but would if not)

Summary by CodeRabbit

  • New Features

    • Microphone recording: record to 16 kHz WAV files with automatic silence trimming, progress and countdown UI.
    • New GUI mic recorder tool with countdown, recording UI, save/rename workflow and overwrite handling.
    • New CLI "rec" command to record audio from the device.
    • Recording processing integrated into the audio task for real-time capture.
  • Localization

    • Added translations for the recording UI in 15+ languages.

Review Change Stack

@3djc 3djc added enhancement ✨ New feature or request hardware support backport/2.12 To be backported to a 2.12 release also. labels Apr 28, 2026
@Johanl1964
Copy link
Copy Markdown

Nice feature, tested, works fine! But if it were possible to be able to select input for rec, mic or internal audio, it would be very interesting to be able to record "audio telemetry", it would be a form of "audio log" that you could, for example, edit into a movie from the model/drone

@gagarinlg
Copy link
Copy Markdown
Member

Nice feature, tested, works fine! But if it were possible to be able to select input for rec, mic or internal audio, it would be very interesting to be able to record "audio telemetry", it would be a form of "audio log" that you could, for example, edit into a movie from the model/drone

Forget it, there is too much noise transported by the case. Every movement of the sticks is louder as your voice.

@Johanl1964
Copy link
Copy Markdown

Nice feature, tested, works fine! But if it were possible to be able to select input for rec, mic or internal audio, it would be very interesting to be able to record "audio telemetry", it would be a form of "audio log" that you could, for example, edit into a movie from the model/drone

Forget it, there is too much noise transported by the case. Every movement of the sticks is louder as your voice.

I mean being able to turn off the mic and record directly from internal audio, then there will be no "disturbing" other sounds.

@3djc
Copy link
Copy Markdown
Collaborator Author

3djc commented Apr 28, 2026

Indeed. My initial idea was a automatic audio volume adjustment based on background noise, but even your hands moving on the case produces a higher volume noise than gas planes flying by.

And this is not regular microphone, this is digital mems one, so would not work with external mic anyway, not that there is an entry for one either.

As for recording audio log, you could replay telemetry logs in companion simulator and record those. It would really be a bad idea to do that on radio while flying, there is simply not enough sd bandwidth for everything

@Johanl1964
Copy link
Copy Markdown

Indeed. My initial idea was a automatic audio volume adjustment based on background noise, but even your hands moving on the case produces a higher volume noise than gas planes flying by.

And this is not regular microphone, this is digital mems one, so would not work with external mic anyway, not that there is an entry for one either.

As for recording audio log, you could replay telemetry logs in companion simulator and record those. It would really be a bad idea to do that on radio while flying, there is simply not enough sd bandwidth for everything

In Audacity, for example, you choose which source you want to record from. If you choose an internal sound source such as ETX audio, such as speech/audio telemetry, no external sounds will be recorded.
Skärmbild från 2026-04-28 20-01-34

@pfeerick
Copy link
Copy Markdown
Member

It is isn't practical - per the last sentence of JC's last reply:

As for recording audio log, you could replay telemetry logs in companion simulator and record those. It would really be a bad idea to do that on radio while flying, there is simply not enough SD bandwidth for everything

The workaround would be to use companion simulator to "recreate" the telemetry triggered audio. It won't give you any audio that comes from special functions, lua scripts, or other radio events, but is the only other feasible option atm.

@Johanl1964
Copy link
Copy Markdown

It is isn't practical - per the last sentence of JC's last reply:

As for recording audio log, you could replay telemetry logs in companion simulator and record those. It would really be a bad idea to do that on radio while flying, there is simply not enough SD bandwidth for everything

The workaround would be to use companion simulator to "recreate" the telemetry triggered audio. It won't give you any audio that comes from special functions, lua scripts, or other radio events, but is the only other feasible option atm.

Okay, I understand. I solved it with this mobile app connected to my TX15 headphone jack, so I can now record all the "telemetry sound" I use like timers, vario and regular height and distance indications etc... But it would have been handy to be able to do this directly in the transmitter!
Screenshot_2026-04-29-12-26-00-800_com audio audiocheckapp6

@pfeerick pfeerick added this to the 2.12.2 milestone May 5, 2026
@pfeerick
Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9ba1125e-a48a-4572-8724-3ea6f5db2bef

📥 Commits

Reviewing files that changed from the base of the PR and between 4559660 and 1e99147.

📒 Files selected for processing (18)
  • radio/src/translations/i18n/cn.h
  • radio/src/translations/i18n/cz.h
  • radio/src/translations/i18n/da.h
  • radio/src/translations/i18n/de.h
  • radio/src/translations/i18n/es.h
  • radio/src/translations/i18n/fi.h
  • radio/src/translations/i18n/he.h
  • radio/src/translations/i18n/it.h
  • radio/src/translations/i18n/ko.h
  • radio/src/translations/i18n/nl.h
  • radio/src/translations/i18n/pl.h
  • radio/src/translations/i18n/pt.h
  • radio/src/translations/i18n/ru.h
  • radio/src/translations/i18n/se.h
  • radio/src/translations/i18n/tw.h
  • radio/src/translations/i18n/ua.h
  • radio/src/translations/sim_string_list.h
  • radio/src/translations/string_list.h
✅ Files skipped from review due to trivial changes (5)
  • radio/src/translations/i18n/tw.h
  • radio/src/translations/i18n/da.h
  • radio/src/translations/i18n/cz.h
  • radio/src/translations/i18n/se.h
  • radio/src/translations/i18n/he.h
🚧 Files skipped from review as they are similar to previous changes (13)
  • radio/src/translations/i18n/nl.h
  • radio/src/translations/i18n/de.h
  • radio/src/translations/i18n/ru.h
  • radio/src/translations/i18n/pl.h
  • radio/src/translations/i18n/ua.h
  • radio/src/translations/i18n/fi.h
  • radio/src/translations/i18n/it.h
  • radio/src/translations/i18n/cn.h
  • radio/src/translations/string_list.h
  • radio/src/translations/i18n/es.h
  • radio/src/translations/i18n/ko.h
  • radio/src/translations/sim_string_list.h
  • radio/src/translations/i18n/pt.h

📝 Walkthrough

Walkthrough

Adds end-to-end microphone recording: PDM software driver, PDM→PCM decimation, WAV recorder with silence-trim, GUI recorder page + CLI command, audio-task wiring, target HAL/CMake wiring, simulator stubs, and translations.

Changes

Microphone recording feature

Layer / File(s) Summary
PDM driver contract & config
radio/src/boards/rm-h750/pdm_software_driver.h, radio/src/boards/rm-h750/board.h
Declares PDM API (pdmStart/Stop/Capture/ConvertToPCM, level helpers) and PDM constants; board header conditionally includes the driver when PDM_CLOCK is defined.
PDM driver implementation
radio/src/boards/rm-h750/pdm_software_driver.cpp
Configures SAI/GPIO/timer/DMA for circular bitstream capture into a ring buffer; provides burst extraction, ones-density sound-level estimation, and a 3rd-order CIC decimator producing int16 PCM.
WAV recorder contract
radio/src/pdm_wav_recorder.h
Declares PdmWavRecorder API: start/stop, audioTick, trimSilence, status accessors, PCM buffer and file state; guarded by PDM_CLOCK.
WAV recorder implementation
radio/src/pdm_wav_recorder.cpp, radio/src/targets/simu/simufatfs.cpp
Writes placeholder RIFF header, appends PCM on audio ticks (mutex/active-instance protection), finalises header on stop, and supports in-place silence trimming; adds f_truncate for simulator builds.
Audio task integration
radio/src/tasks.cpp
Calls PdmWavRecorder::audioTick() from the periodic audio task when PDM_CLOCK is defined.
GUI page contract & implementation
radio/src/gui/colorlcd/radio/radio_mic_recorder.h, radio/src/gui/colorlcd/radio/radio_mic_recorder.cpp, radio/src/gui/colorlcd/CMakeLists.txt
Adds RadioMicRecorder page: 5s countdown, IDLE/COUNTDOWN/RECORDING states, automatic filename selection, start/stop/trim/Save-As flow, and CMake build entry for the page.
Tools wiring
radio/src/gui/colorlcd/radio/radio_tools.cpp
Registers the mic recorder tool in the tools list under PDM_CLOCK.
CLI integration
radio/src/cli.cpp
Adds rec command (guarded by PDM_CLOCK) to record to WAV via PdmWavRecorder, with optional duration argument and filename normalization.
Target HAL & build wiring
radio/src/targets/tx15/hal.h, radio/src/targets/tx16smk3/hal.h, radio/src/targets/tx15/CMakeLists.txt, radio/src/targets/tx16smk3/CMakeLists.txt, radio/src/CMakeLists.txt
Adds PDM hardware macro definitions (GPIO/SAI/timer/DMA) for targets, and includes pdm_software_driver.cpp & pdm_wav_recorder.cpp / GUI source additions in target/build lists.
Simulator stubs
radio/src/targets/simu/simulib.cpp
Provides no-op PDM functions for simulator builds so code links when PDM_CLOCK is enabled.
Translations & string mapping
radio/src/translations/i18n/*.h, radio/src/translations/string_list.h, radio/src/translations/sim_string_list.h
Adds recorder UI translation macros across languages and maps new string IDs (MIC_RECORDER, PUSH_TO_RECORD, RECORD, STOP, REC, STARTING_IN, GET_READY, SAVED, SAVE_AS, OPEN_ERROR) under PDM_CLOCK/COLORLCD.
Minor includes
radio/src/storage/storage_common.cpp, radio/src/cli.cpp
Small conditional include additions: hal/rgbleds.h (storage_common) and pdm_wav_recorder.h/string.h (cli).

Sequence Diagram

sequenceDiagram
  participant User
  participant GUI
  participant Recorder as PdmWavRecorder
  participant Driver as PDM Driver
  participant HW as DMA/Timer/SAI
  participant FS as FileSystem

  User->>GUI: Press record
  GUI->>Recorder: start(path, expectedSeconds)
  Recorder->>Driver: pdmStart()
  Driver->>HW: configure SAI/GPIO/Timer/DMA (circular)
  loop audio ticks
    HW->>Driver: DMA writes ring buffer
    Driver->>Recorder: pdmCapture()/pdmConvertToPCM()
    Recorder->>FS: append PCM samples to WAV file
  end
  User->>GUI: Stop
  GUI->>Recorder: stop()
  Recorder->>FS: update WAV header, trimSilence()
  Recorder->>GUI: report saved path/result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding MEMS microphone software support for TX15 and TX16SMK3 hardware platforms.
Description check ✅ Passed The description provides a detailed summary of changes, implementation details, usage instructions, and known limitations. It covers all substantive aspects of the PR despite not strictly following the template format.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 3djc/test

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (20)
radio/src/translations/i18n/da.h-974-983 (1)

974-983: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Danish locale entries are currently untranslated.

At Lines 974-983, the new TR_MIC_* strings are still in English. This causes mixed-language UI in Danish builds.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/da.h` around lines 974 - 983, The Danish
translation entries for the mic/recording strings are still in English; update
the constants TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC,
TR_STARTING_IN, TR_GET_READY, TR_SAVED, TR_SAVE_AS and TR_OPEN_ERROR in da.h to
their proper Danish translations so the UI is fully localized (replace the
English phrases with Danish equivalents while preserving the macro names and
string literal format).
radio/src/translations/i18n/de.h-968-977 (1)

968-977: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

German locale entries are currently untranslated.

At Lines 968-977, the new microphone-recorder labels are English, which leads to inconsistent German UI text.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/de.h` around lines 968 - 977, The new i18n macros
(TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN,
TR_GET_READY, TR_SAVED, TR_SAVE_AS, TR_OPEN_ERROR) are still in English; update
their German translations in de.h so the UI is consistent — replace each English
string with the appropriate German text (e.g., "Mic recorder" →
"Mikrofon-Recorder" or better-fitting term, "Push to record" → "Zum Aufnehmen
drücken", "Record" → "Aufnehmen", "Stop" → "Stopp"/"Stoppen", "REC" → "REC",
"Starting in" → "Startet in", "Get ready..." → "Machen Sie sich bereit..." or
"Bereit machen...", "Saved:" → "Gespeichert:", "Save as" → "Speichern unter",
"Open error" → "Fehler beim Öffnen") ensuring grammar and casing match existing
locale conventions.
radio/src/translations/i18n/tw.h-966-975 (1)

966-975: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the new mic-recorder strings in the Traditional Chinese locale.

The added labels are English-only, which creates inconsistent language output in this localized build.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/tw.h` around lines 966 - 975, The new
mic-recorder macros (TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP,
TR_REC, TR_STARTING_IN, TR_GET_READY, TR_SAVED, TR_SAVE_AS, TR_OPEN_ERROR) are
still in English; update their string values in radio/src/translations/i18n/tw.h
to proper Traditional Chinese translations so the locale is consistent—for
example replace each RHS English literal with the appropriate Traditional
Chinese phrase while keeping the macro names unchanged and preserving
surrounding quoting/escaping and punctuation.
radio/src/translations/i18n/cz.h-967-976 (1)

967-976: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new mic-recorder labels for Czech UI.

These new keys are still English, so Czech users will see mixed-language text in the recorder flow.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/cz.h` around lines 967 - 976, Update the Czech
translations for the new mic-recorder string macros so users don't see English
UI text: replace the values of TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD,
TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY, TR_SAVED, TR_SAVE_AS and
TR_OPEN_ERROR in cz.h with proper Czech phrases (keeping the `#define` macro
names, surrounding quotes and formatting intact) so the recorder flow displays
localized Czech text.
radio/src/translations/i18n/pt.h-970-979 (1)

970-979: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new recorder strings for Portuguese.

These labels are currently English, so the new recorder workflow appears partially untranslated in PT.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/pt.h` around lines 970 - 979, Update the
Portuguese translation macros so the recorder UI strings are localized: replace
the English values for TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP,
TR_REC, TR_STARTING_IN, TR_GET_READY, TR_SAVED, TR_SAVE_AS and TR_OPEN_ERROR
with their Portuguese equivalents (e.g., "Gravador de microfone", "Pressione
para gravar", "Gravar", "Parar", "REC" if kept or "GRAV", "Começando em",
"Prepare-se...", "Salvo:", "Salvar como", and "Erro ao abrir" as appropriate);
keep the macro names unchanged and ensure punctuation/accents match PT
conventions.
radio/src/translations/i18n/cn.h-969-978 (1)

969-978: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize new mic-recorder labels in the Chinese locale file.

Line 969–Line 978 are English strings in cn.h, which causes mixed-language UI in the recorder workflow for Chinese users.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/cn.h` around lines 969 - 978, The Chinese locale
file contains English literals for the mic-recorder strings; update the macro
values for TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC,
TR_STARTING_IN, TR_GET_READY, TR_SAVED, TR_SAVE_AS, and TR_OPEN_ERROR to their
proper Chinese translations (keeping the macro names unchanged) so the recorder
UI is fully localized for Chinese users.
radio/src/translations/i18n/ru.h-971-980 (1)

971-980: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Russian locale strings for mic recorder are not translated yet.

Line 971–Line 980 are English literals, so the recorder workflow is partially untranslated for Russian users.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/ru.h` around lines 971 - 980, The listed macros
(TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN,
TR_GET_READY, TR_SAVED, TR_SAVE_AS, TR_OPEN_ERROR) are still English; replace
each English literal with the appropriate Russian translation while keeping the
macro names and the exact `#define` syntax intact (e.g., TR_MIC_RECORDER -> "..."
in Russian). Ensure translations fit UI context (e.g., "Push to record" as a
short imperative, "Saved:" with colon preserved, "Get ready..." ellipsis kept)
and keep surrounding quotes and capitalization consistent with other entries in
ru.h.
radio/src/translations/i18n/pl.h-962-971 (1)

962-971: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Polish locale has untranslated mic-recorder strings.

Line 962–Line 971 remain in English, which creates inconsistent language in the new recorder tool UI.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/pl.h` around lines 962 - 971, The Polish locale
file contains untranslated recorder strings; update the macro definitions
TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN,
TR_GET_READY, TR_SAVED, and TR_SAVE_AS in pl.h to their Polish equivalents
(e.g., "Rejestrator mikrofonu", "Naciśnij, aby nagrać", "Nagraj"/"Zapisz" as
appropriate), replacing the English text with proper Polish translations and
correct UTF-8 encoding, and keep TR_OPEN_ERROR localized as well (e.g., "Błąd
otwarcia") so the new recorder UI is fully translated.
radio/src/translations/i18n/fi.h-963-972 (1)

963-972: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the newly added recorder flow strings for Finnish.

Line 963–Line 972 are still English, so the new mic recorder UI appears partially untranslated in Finnish locale.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/fi.h` around lines 963 - 972, The Finnish locale
still has English strings for the new recorder UI; update the `#define` values for
TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN,
TR_GET_READY, TR_SAVED, TR_SAVE_AS, and TR_OPEN_ERROR to Finnish equivalents so
the mic recorder UI is fully localized (suggested translations: TR_MIC_RECORDER
-> "Mikrofonitallennin", TR_PUSH_TO_RECORD -> "Paina tallentaaksesi", TR_RECORD
-> "Tallenna", TR_STOP -> "Lopeta", TR_REC -> "TALL.", TR_STARTING_IN ->
"Alkaa:", TR_GET_READY -> "Valmistaudu...", TR_SAVED -> "Tallennettu:",
TR_SAVE_AS -> "Tallenna nimellä", TR_OPEN_ERROR -> "Avausvirhe"). Ensure you
replace the English string literals in those `#define` entries in the fi.h diff so
the Finnish build shows the translated UI.
radio/src/translations/i18n/jp.h-968-977 (1)

968-977: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize new mic-recorder strings in Japanese

Lines 968-977 are still English, which makes the new mic-recorder UI inconsistent in Japanese builds. Please translate these new keys to Japanese.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/jp.h` around lines 968 - 977, The new
mic-recorder strings (TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP,
TR_REC, TR_STARTING_IN, TR_GET_READY, TR_SAVED, TR_SAVE_AS, TR_OPEN_ERROR) are
still in English; update their string values to Japanese translations so the
mic-recorder UI is localized. Edit the definitions for those macros in jp.h and
replace the English phrases with correct Japanese equivalents (for example: "Mic
recorder" → appropriate Japanese, "Push to record" → appropriate Japanese,
etc.), keeping the same macro names and quoting style.
radio/src/translations/i18n/nl.h-965-974 (1)

965-974: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize new mic-recorder strings in Dutch

Lines 965-974 introduce English literals for Dutch locale keys. This causes inconsistent UI language on the new recorder page. Please replace with Dutch translations.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/nl.h` around lines 965 - 974, Replace the English
literals for the new mic-recorder keys with Dutch translations by updating the
macros TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC,
TR_STARTING_IN, TR_GET_READY, TR_SAVED, TR_SAVE_AS and TR_OPEN_ERROR in nl.h to
their Dutch equivalents (suggestions: TR_MIC_RECORDER -> "Microfoonrecorder",
TR_PUSH_TO_RECORD -> "Houd ingedrukt om op te nemen", TR_RECORD -> "Opnemen",
TR_STOP -> "Stop", TR_REC -> "OPN", TR_STARTING_IN -> "Start over", TR_GET_READY
-> "Maak je klaar…", TR_SAVED -> "Opgeslagen:", TR_SAVE_AS -> "Opslaan als",
TR_OPEN_ERROR -> "Fout bij openen"); ensure spelling/diacritics follow project
locale conventions and run a quick UI check of the recorder page to confirm
strings display correctly.
radio/src/translations/i18n/se.h-970-979 (1)

970-979: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize new mic-recorder strings in Swedish

Lines 970-979 are still English, so the new recorder flow will appear mixed-language in Swedish UI. Please provide Swedish translations for these new keys before merge.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/se.h` around lines 970 - 979, Replace the English
strings for the recorder keys with Swedish translations: update TR_MIC_RECORDER
-> Mikrofoninspelare, TR_PUSH_TO_RECORD -> Tryck för att spela in, TR_RECORD ->
Spela in, TR_STOP -> Stopp, TR_REC -> INSP, TR_STARTING_IN -> Startar om,
TR_GET_READY -> Gör dig redo..., TR_SAVED -> Sparad:, TR_SAVE_AS -> Spara som,
and TR_OPEN_ERROR -> Fel vid öppning; change the string literals for these
macros in se.h so the Swedish UI shows these localized labels.
radio/src/translations/i18n/ua.h-970-979 (1)

970-979: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize new mic-recorder strings in Ukrainian

Lines 970-979 are English placeholders in the Ukrainian locale file. Please add Ukrainian translations for these keys to avoid mixed-language UX.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/ua.h` around lines 970 - 979, Replace the English
placeholders in the Ukrainian locale by updating the `#define` values for the
listed keys: TR_MIC_RECORDER -> Мікрофонний рекордер, TR_PUSH_TO_RECORD ->
Натисніть, щоб записати, TR_RECORD -> Запис, TR_STOP -> Зупинити, TR_REC -> ЗАП,
TR_STARTING_IN -> Початок через, TR_GET_READY -> Підготуйтеся..., TR_SAVED ->
Збережено:, TR_SAVE_AS -> Зберегти як, TR_OPEN_ERROR -> Помилка відкриття; edit
these defines in ua.h so the Ukrainian strings replace the English ones.
radio/src/targets/tx15/hal.h-58-63 (1)

58-63: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix PDM clock/timer comments to match the configured values.

Line 62 says 1 MHz, but Line 212 configures PDM_CLOCK_FREQ to 1.6 MHz; and TIM15 is now used but undocumented in the timer map.

📝 Suggested comment sync
-TIM15:
+TIM15:  PDM_CAPTURE_TIMER (!FLYSKY_GIMBAL)

-SAI1_Block_A: PDM_CLOCK (1 MHz bit-clock output on SAI1_CK1 / PE5, !FLYSKY_GIMBAL only)
+SAI1_Block_A: PDM_CLOCK (1.6 MHz bit-clock output on SAI1_CK1 / PE5, !FLYSKY_GIMBAL only)

Also applies to: 212-213

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/targets/tx15/hal.h` around lines 58 - 63, Update the timer and PDM
comments to reflect the actual configuration: change the PDM_CLOCK comment
(SAI1_Block_A / PE5) to state 1.6 MHz to match PDM_CLOCK_FREQ (configured at
lines ~212-213) and document that TIM15 is now used (add TIM15 to the timer map
and/or note its role alongside TIM16/TIM17 and ROTARY_ENCODER_TIMER). Ensure the
symbol names PDM_CLOCK, PDM_CLOCK_FREQ, TIM15, TIM16, TIM17 and
ROTARY_ENCODER_TIMER are referenced in the comment so the documentation matches
the code.
radio/src/targets/tx16smk3/hal.h-62-63 (1)

62-63: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align PDM clock comments with the actual configured frequency.

The comments still mention 1 MHz, but PDM_CLOCK_FREQ is set to 1.6 MHz, which can confuse timing/debug work.

Also applies to: 411-417

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/targets/tx16smk3/hal.h` around lines 62 - 63, Comments referencing
the PDM clock frequency are out of sync with the configured constant
PDM_CLOCK_FREQ (1.6 MHz); update all PDM clock comment text (e.g., the
SAI1_Block_A comment near "PDM_CLOCK (1 MHz bit-clock output on SAI1_CK1 / PE5)"
and the other occurrences around the block referenced at lines ~411-417) to
reflect 1.6 MHz (and adjust wording/units if needed) so the comments match the
actual configured frequency and signal mapping.
radio/src/boards/rm-h750/pdm_software_driver.h-31-36 (1)

31-36: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Resolve the default gain mismatch in comment vs macro.

Line 31 says “default calibrated at 4”, but Line 35 sets PDM_POST_GAIN_SHIFT to 5.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/boards/rm-h750/pdm_software_driver.h` around lines 31 - 36, The
comment above PDM_POST_GAIN_SHIFT is inconsistent with the macro value; update
the comment so the stated "default calibrated at X" matches the actual macro
(PDM_POST_GAIN_SHIFT) value used (currently 5), and ensure any mention of
trimSilence() scaling remains correct (see trimSilence() in
pdm_wav_recorder.cpp); alternatively, if the intended default is 4, change the
PDM_POST_GAIN_SHIFT definition to 4—make the comment and the macro
PDM_POST_GAIN_SHIFT consistent.
radio/src/translations/i18n/ko.h-1011-1020 (1)

1011-1020: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new mic-recorder labels in Korean.

Lines 1011-1020 are currently English strings, so the Korean UI will show mixed language on the recorder flow.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/ko.h` around lines 1011 - 1020, Replace the
English strings for the mic-recorder labels by updating the `#defines` for
TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN,
TR_GET_READY, TR_SAVED, TR_SAVE_AS, and TR_OPEN_ERROR with their Korean
equivalents (e.g. TR_MIC_RECORDER -> "마이크 녹음기", TR_PUSH_TO_RECORD -> "녹음하려면
누르세요", TR_RECORD -> "녹음", TR_STOP -> "중지", TR_REC -> "녹음", TR_STARTING_IN ->
"시작까지", TR_GET_READY -> "준비하세요...", TR_SAVED -> "저장됨:", TR_SAVE_AS -> "다른 이름으로
저장", TR_OPEN_ERROR -> "열기 오류") so the recorder flow displays fully localized
Korean strings.
radio/src/translations/i18n/es.h-963-972 (1)

963-972: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the new recorder strings to Spanish.

These entries are still English, which causes mixed-language UX in Spanish builds.

🌐 Proposed localization patch
-#define TR_MIC_RECORDER                "Mic recorder"
-#define TR_PUSH_TO_RECORD              "Push to record"
-#define TR_RECORD                      "Record"
-#define TR_STOP                        "Stop"
+#define TR_MIC_RECORDER                "Grabadora de micrófono"
+#define TR_PUSH_TO_RECORD              "Pulsa para grabar"
+#define TR_RECORD                      "Grabar"
+#define TR_STOP                        "Detener"
 `#define` TR_REC                         "REC"
-#define TR_STARTING_IN                 "Starting in"
-#define TR_GET_READY                   "Get ready..."
-#define TR_SAVED                       "Saved:"
-#define TR_SAVE_AS                     "Save as"
-#define TR_OPEN_ERROR                  "Open error"
+#define TR_STARTING_IN                 "Iniciando en"
+#define TR_GET_READY                   "Prepárate..."
+#define TR_SAVED                       "Guardado:"
+#define TR_SAVE_AS                     "Guardar como"
+#define TR_OPEN_ERROR                  "Error al abrir"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/es.h` around lines 963 - 972, Replace the English
recorder strings with Spanish equivalents for the macros TR_MIC_RECORDER,
TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY,
TR_SAVED, TR_SAVE_AS and TR_OPEN_ERROR; set them to natural Spanish labels such
as "Grabadora de micrófono" for TR_MIC_RECORDER, "Mantén pulsado para grabar"
for TR_PUSH_TO_RECORD, "Grabar" for TR_RECORD, "Detener" for TR_STOP, "REC" can
remain "REC" or "GRAB" if you prefer localized abbreviation for TR_REC,
"Comenzando en" for TR_STARTING_IN, "Prepárate..." for TR_GET_READY, "Guardado:"
for TR_SAVED, "Guardar como" for TR_SAVE_AS, and "Error al abrir" for
TR_OPEN_ERROR so the Spanish build is fully localized.
radio/src/translations/i18n/it.h-969-978 (1)

969-978: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the new recorder strings to Italian.

The newly added labels are English, so Italian users will see mixed-language labels in this flow.

🌐 Proposed localization patch
-#define TR_MIC_RECORDER                "Mic recorder"
-#define TR_PUSH_TO_RECORD              "Push to record"
-#define TR_RECORD                      "Record"
-#define TR_STOP                        "Stop"
+#define TR_MIC_RECORDER                "Registratore microfono"
+#define TR_PUSH_TO_RECORD              "Premi per registrare"
+#define TR_RECORD                      "Registra"
+#define TR_STOP                        "Ferma"
 `#define` TR_REC                         "REC"
-#define TR_STARTING_IN                 "Starting in"
-#define TR_GET_READY                   "Get ready..."
-#define TR_SAVED                       "Saved:"
-#define TR_SAVE_AS                     "Save as"
-#define TR_OPEN_ERROR                  "Open error"
+#define TR_STARTING_IN                 "Avvio tra"
+#define TR_GET_READY                   "Preparati..."
+#define TR_SAVED                       "Salvato:"
+#define TR_SAVE_AS                     "Salva come"
+#define TR_OPEN_ERROR                  "Errore di apertura"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/i18n/it.h` around lines 969 - 978, Replace the English
recorder labels with Italian translations by updating the macro values: set
TR_MIC_RECORDER to "Registratore microfono", TR_PUSH_TO_RECORD to "Premi per
registrare", TR_RECORD to "Registra", TR_STOP to "Interrompi", TR_REC to "REC"
(or "REG" if you prefer fully localized), TR_STARTING_IN to "Inizia tra",
TR_GET_READY to "Preparati...", TR_SAVED to "Salvato:", TR_SAVE_AS to "Salva
come", and TR_OPEN_ERROR to "Errore di apertura" so the UI uses consistent
Italian strings for the recorder flow.
radio/src/gui/colorlcd/radio/radio_mic_recorder.cpp-259-264 (1)

259-264: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Recording can stop silently without user notification or save option.

If the recording stops unexpectedly (e.g., SD card write error), isRecording() becomes false and the code transitions directly to IDLE without calling stopRecording(). This means:

  • trimSilence() is not called on the partial recording
  • The "Save As" dialog is never shown
  • The user has no indication that recording stopped or that a partial file exists

Consider detecting this case and either showing an error message or offering to save the partial recording:

Suggested approach
   } else if (state == State::RECORDING) {
     if (!recorder.isRecording()) {
+      // Recording stopped unexpectedly (possibly disk error)
+      PdmWavRecorder::trimSilence(filename);
       state = State::IDLE;
       stateStart = get_tmr10ms();
+      // Notify user and offer to save partial recording
+      bigLabel->setText(STR_OPEN_ERROR);  // or a new "Recording stopped" string
+      // Optionally: trigger the save dialog for the partial file
     }
     refreshUI();
   }

,

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/gui/colorlcd/radio/radio_mic_recorder.cpp` around lines 259 - 264,
The RECORDING branch currently flips to IDLE when recorder.isRecording() becomes
false, losing the partial capture; instead, detect this unexpected stop and
invoke the recording cleanup and user-flow: call the existing stopRecording()
(or implement a new helper like handleUnexpectedStop()) to run trimSilence(),
persist or mark the partial buffer, and present the save/error UI (e.g., the
same Save As dialog or an error message) before changing state and updating
stateStart; keep using recorder.isRecording(), stopRecording(), trimSilence(),
showSaveAsDialog()/displayError(), state, stateStart, get_tmr10ms(), and
refreshUI() to locate and wire the behavior.
🧹 Nitpick comments (3)
radio/src/translations/string_list.h (1)

245-255: ⚡ Quick win

Gate recorder strings behind PDM_CLOCK in COLORLCD builds.

This avoids carrying recorder-only strings on ColorLCD targets that cannot build/use the mic path.

♻️ Suggested guard
+#if defined(PDM_CLOCK)
 STR(MIC_RECORDER)
 STR(PUSH_TO_RECORD)
 STR(RECORD)
 STR(STOP)
 STR(REC)
 STR(STARTING_IN)
 STR(GET_READY)
 STR(SAVED)
 STR(SAVE_AS)
 STR(OPEN_ERROR)
+#endif
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/translations/string_list.h` around lines 245 - 255, Wrap the
recorder string entries (STR(MIC_RECORDER), STR(PUSH_TO_RECORD), STR(RECORD),
STR(STOP), STR(REC), STR(STARTING_IN), STR(GET_READY), STR(SAVED), STR(SAVE_AS),
STR(OPEN_ERROR)) so they are only compiled into COLORLCD builds when PDM_CLOCK
is defined: add a preprocessor guard that includes these STR(...) lines by
default for non-COLORLCD targets, but for COLORLCD targets require
defined(PDM_CLOCK) before emitting them (e.g. use a conditional that is true
when not COLORLCD or when PDM_CLOCK is present), then close the guard. Ensure
only the block containing those specific STR entries is wrapped and no other
strings are affected.
radio/src/cli.cpp (1)

267-328: 💤 Low value

Recording implementation looks correct.

The CLI record command properly validates arguments, manages PDM lifecycle, and handles file extension. The busy-wait polling loop with sleep_ms(50) is reasonable for CLI usage.

Minor note: If toInt returns -1 (parse error for malformed input like "5abc"), it prints its own error message, but since the check at line 280 tests for == 0, the function may continue with a partially-parsed value. Consider checking < 1 instead to catch error returns:

-    if (toInt(argv, 2, &seconds) == 0 || seconds <= 0 || seconds > 600) {
+    if (toInt(argv, 2, &seconds) < 1 || seconds <= 0 || seconds > 600) {

However, since invalid inputs like "abc" result in seconds=0 which is caught by seconds <= 0, this is a minor edge case.
,

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/cli.cpp` around lines 267 - 328, The toInt return-value check in
cliRecord is too narrow: change the condition that validates parsing of argv[2]
from "toInt(...) == 0" to "toInt(...) < 1" so parse errors (e.g., -1) are
treated as invalid; update the clause that currently reads if (toInt(argv, 2,
&seconds) == 0 || seconds <= 0 || seconds > 600) to instead treat any
non-success return (<1) as an error when validating seconds (refer to toInt and
the local seconds variable in cliRecord).
radio/src/pdm_wav_recorder.cpp (1)

35-41: 💤 Low value

Minor: Lazy mutex initialization has a theoretical race condition.

If ensureMutex() is called simultaneously from two threads during first initialization, both could observe s_mutexInited == false and call mutex_create. In practice, this is unlikely since start() is typically called from a single GUI/CLI thread before any audio-task interaction.

If you want to be defensive, consider initializing the mutex statically or using a call-once pattern. However, given the usage context, this is acceptable.
,

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/pdm_wav_recorder.cpp` around lines 35 - 41, The lazy mutex init in
ensureMutex() can race if two threads call it concurrently: replace the manual
s_mutexInited check with a thread-safe one-time initialization (e.g., a
call-once pattern) or convert the mutex to static-initialized so creation
happens before any threads run; specifically update ensureMutex()/s_mutexInited
usage (and any calls from start()) to use a std::call_once/once_flag or
equivalent platform call-once mechanism instead of calling mutex_create directly
based on s_mutexInited.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@radio/src/gui/colorlcd/radio/radio_mic_recorder.h`:
- Around line 43-48: PATH_MAX_LEN (currently sizeof(SOUNDS_PATH) + 14) is too
small for user-entered names and causes snprintf in pendingRename (and filename)
to overflow/truncate; fix by either increasing PATH_MAX_LEN to safely
accommodate SOUNDS_PATH + max user name + ".wav" + NUL, or introduce a separate
FILENAME_MAX_LEN and pass that reduced length to LabelDialog (instead of
PATH_MAX_LEN - 1) so newName cannot exceed the buffer when you call
snprintf(pendingRename, sizeof(pendingRename), "%s%s.wav", dir,
newName.c_str()); update any references to PATH_MAX_LEN, pendingRename,
filename, and LabelDialog call sites to use the chosen constant.

In `@radio/src/targets/simu/simufatfs.cpp`:
- Around line 619-623: In f_truncate, stop ignoring errors from
sf->stream->flush(): after calling sf->stream->flush() check the stream state
(e.g., if (!sf->stream->good()) return FR_DISK_ERR) before proceeding to
fs::resize_file; keep the existing resize_file call
(fs::resize_file(sf->filepath, fil->fptr, ec)) and its error check, but ensure
flush failures cause an immediate FR_DISK_ERR using the same pattern as f_write.

---

Minor comments:
In `@radio/src/boards/rm-h750/pdm_software_driver.h`:
- Around line 31-36: The comment above PDM_POST_GAIN_SHIFT is inconsistent with
the macro value; update the comment so the stated "default calibrated at X"
matches the actual macro (PDM_POST_GAIN_SHIFT) value used (currently 5), and
ensure any mention of trimSilence() scaling remains correct (see trimSilence()
in pdm_wav_recorder.cpp); alternatively, if the intended default is 4, change
the PDM_POST_GAIN_SHIFT definition to 4—make the comment and the macro
PDM_POST_GAIN_SHIFT consistent.

In `@radio/src/gui/colorlcd/radio/radio_mic_recorder.cpp`:
- Around line 259-264: The RECORDING branch currently flips to IDLE when
recorder.isRecording() becomes false, losing the partial capture; instead,
detect this unexpected stop and invoke the recording cleanup and user-flow: call
the existing stopRecording() (or implement a new helper like
handleUnexpectedStop()) to run trimSilence(), persist or mark the partial
buffer, and present the save/error UI (e.g., the same Save As dialog or an error
message) before changing state and updating stateStart; keep using
recorder.isRecording(), stopRecording(), trimSilence(),
showSaveAsDialog()/displayError(), state, stateStart, get_tmr10ms(), and
refreshUI() to locate and wire the behavior.

In `@radio/src/targets/tx15/hal.h`:
- Around line 58-63: Update the timer and PDM comments to reflect the actual
configuration: change the PDM_CLOCK comment (SAI1_Block_A / PE5) to state 1.6
MHz to match PDM_CLOCK_FREQ (configured at lines ~212-213) and document that
TIM15 is now used (add TIM15 to the timer map and/or note its role alongside
TIM16/TIM17 and ROTARY_ENCODER_TIMER). Ensure the symbol names PDM_CLOCK,
PDM_CLOCK_FREQ, TIM15, TIM16, TIM17 and ROTARY_ENCODER_TIMER are referenced in
the comment so the documentation matches the code.

In `@radio/src/targets/tx16smk3/hal.h`:
- Around line 62-63: Comments referencing the PDM clock frequency are out of
sync with the configured constant PDM_CLOCK_FREQ (1.6 MHz); update all PDM clock
comment text (e.g., the SAI1_Block_A comment near "PDM_CLOCK (1 MHz bit-clock
output on SAI1_CK1 / PE5)" and the other occurrences around the block referenced
at lines ~411-417) to reflect 1.6 MHz (and adjust wording/units if needed) so
the comments match the actual configured frequency and signal mapping.

In `@radio/src/translations/i18n/cn.h`:
- Around line 969-978: The Chinese locale file contains English literals for the
mic-recorder strings; update the macro values for TR_MIC_RECORDER,
TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY,
TR_SAVED, TR_SAVE_AS, and TR_OPEN_ERROR to their proper Chinese translations
(keeping the macro names unchanged) so the recorder UI is fully localized for
Chinese users.

In `@radio/src/translations/i18n/cz.h`:
- Around line 967-976: Update the Czech translations for the new mic-recorder
string macros so users don't see English UI text: replace the values of
TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN,
TR_GET_READY, TR_SAVED, TR_SAVE_AS and TR_OPEN_ERROR in cz.h with proper Czech
phrases (keeping the `#define` macro names, surrounding quotes and formatting
intact) so the recorder flow displays localized Czech text.

In `@radio/src/translations/i18n/da.h`:
- Around line 974-983: The Danish translation entries for the mic/recording
strings are still in English; update the constants TR_MIC_RECORDER,
TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY,
TR_SAVED, TR_SAVE_AS and TR_OPEN_ERROR in da.h to their proper Danish
translations so the UI is fully localized (replace the English phrases with
Danish equivalents while preserving the macro names and string literal format).

In `@radio/src/translations/i18n/de.h`:
- Around line 968-977: The new i18n macros (TR_MIC_RECORDER, TR_PUSH_TO_RECORD,
TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY, TR_SAVED, TR_SAVE_AS,
TR_OPEN_ERROR) are still in English; update their German translations in de.h so
the UI is consistent — replace each English string with the appropriate German
text (e.g., "Mic recorder" → "Mikrofon-Recorder" or better-fitting term, "Push
to record" → "Zum Aufnehmen drücken", "Record" → "Aufnehmen", "Stop" →
"Stopp"/"Stoppen", "REC" → "REC", "Starting in" → "Startet in", "Get ready..." →
"Machen Sie sich bereit..." or "Bereit machen...", "Saved:" → "Gespeichert:",
"Save as" → "Speichern unter", "Open error" → "Fehler beim Öffnen") ensuring
grammar and casing match existing locale conventions.

In `@radio/src/translations/i18n/es.h`:
- Around line 963-972: Replace the English recorder strings with Spanish
equivalents for the macros TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD,
TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY, TR_SAVED, TR_SAVE_AS and
TR_OPEN_ERROR; set them to natural Spanish labels such as "Grabadora de
micrófono" for TR_MIC_RECORDER, "Mantén pulsado para grabar" for
TR_PUSH_TO_RECORD, "Grabar" for TR_RECORD, "Detener" for TR_STOP, "REC" can
remain "REC" or "GRAB" if you prefer localized abbreviation for TR_REC,
"Comenzando en" for TR_STARTING_IN, "Prepárate..." for TR_GET_READY, "Guardado:"
for TR_SAVED, "Guardar como" for TR_SAVE_AS, and "Error al abrir" for
TR_OPEN_ERROR so the Spanish build is fully localized.

In `@radio/src/translations/i18n/fi.h`:
- Around line 963-972: The Finnish locale still has English strings for the new
recorder UI; update the `#define` values for TR_MIC_RECORDER, TR_PUSH_TO_RECORD,
TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY, TR_SAVED, TR_SAVE_AS,
and TR_OPEN_ERROR to Finnish equivalents so the mic recorder UI is fully
localized (suggested translations: TR_MIC_RECORDER -> "Mikrofonitallennin",
TR_PUSH_TO_RECORD -> "Paina tallentaaksesi", TR_RECORD -> "Tallenna", TR_STOP ->
"Lopeta", TR_REC -> "TALL.", TR_STARTING_IN -> "Alkaa:", TR_GET_READY ->
"Valmistaudu...", TR_SAVED -> "Tallennettu:", TR_SAVE_AS -> "Tallenna nimellä",
TR_OPEN_ERROR -> "Avausvirhe"). Ensure you replace the English string literals
in those `#define` entries in the fi.h diff so the Finnish build shows the
translated UI.

In `@radio/src/translations/i18n/it.h`:
- Around line 969-978: Replace the English recorder labels with Italian
translations by updating the macro values: set TR_MIC_RECORDER to "Registratore
microfono", TR_PUSH_TO_RECORD to "Premi per registrare", TR_RECORD to
"Registra", TR_STOP to "Interrompi", TR_REC to "REC" (or "REG" if you prefer
fully localized), TR_STARTING_IN to "Inizia tra", TR_GET_READY to
"Preparati...", TR_SAVED to "Salvato:", TR_SAVE_AS to "Salva come", and
TR_OPEN_ERROR to "Errore di apertura" so the UI uses consistent Italian strings
for the recorder flow.

In `@radio/src/translations/i18n/jp.h`:
- Around line 968-977: The new mic-recorder strings (TR_MIC_RECORDER,
TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY,
TR_SAVED, TR_SAVE_AS, TR_OPEN_ERROR) are still in English; update their string
values to Japanese translations so the mic-recorder UI is localized. Edit the
definitions for those macros in jp.h and replace the English phrases with
correct Japanese equivalents (for example: "Mic recorder" → appropriate
Japanese, "Push to record" → appropriate Japanese, etc.), keeping the same macro
names and quoting style.

In `@radio/src/translations/i18n/ko.h`:
- Around line 1011-1020: Replace the English strings for the mic-recorder labels
by updating the `#defines` for TR_MIC_RECORDER, TR_PUSH_TO_RECORD, TR_RECORD,
TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY, TR_SAVED, TR_SAVE_AS, and
TR_OPEN_ERROR with their Korean equivalents (e.g. TR_MIC_RECORDER -> "마이크 녹음기",
TR_PUSH_TO_RECORD -> "녹음하려면 누르세요", TR_RECORD -> "녹음", TR_STOP -> "중지", TR_REC ->
"녹음", TR_STARTING_IN -> "시작까지", TR_GET_READY -> "준비하세요...", TR_SAVED -> "저장됨:",
TR_SAVE_AS -> "다른 이름으로 저장", TR_OPEN_ERROR -> "열기 오류") so the recorder flow
displays fully localized Korean strings.

In `@radio/src/translations/i18n/nl.h`:
- Around line 965-974: Replace the English literals for the new mic-recorder
keys with Dutch translations by updating the macros TR_MIC_RECORDER,
TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY,
TR_SAVED, TR_SAVE_AS and TR_OPEN_ERROR in nl.h to their Dutch equivalents
(suggestions: TR_MIC_RECORDER -> "Microfoonrecorder", TR_PUSH_TO_RECORD -> "Houd
ingedrukt om op te nemen", TR_RECORD -> "Opnemen", TR_STOP -> "Stop", TR_REC ->
"OPN", TR_STARTING_IN -> "Start over", TR_GET_READY -> "Maak je klaar…",
TR_SAVED -> "Opgeslagen:", TR_SAVE_AS -> "Opslaan als", TR_OPEN_ERROR -> "Fout
bij openen"); ensure spelling/diacritics follow project locale conventions and
run a quick UI check of the recorder page to confirm strings display correctly.

In `@radio/src/translations/i18n/pl.h`:
- Around line 962-971: The Polish locale file contains untranslated recorder
strings; update the macro definitions TR_MIC_RECORDER, TR_PUSH_TO_RECORD,
TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY, TR_SAVED, and
TR_SAVE_AS in pl.h to their Polish equivalents (e.g., "Rejestrator mikrofonu",
"Naciśnij, aby nagrać", "Nagraj"/"Zapisz" as appropriate), replacing the English
text with proper Polish translations and correct UTF-8 encoding, and keep
TR_OPEN_ERROR localized as well (e.g., "Błąd otwarcia") so the new recorder UI
is fully translated.

In `@radio/src/translations/i18n/pt.h`:
- Around line 970-979: Update the Portuguese translation macros so the recorder
UI strings are localized: replace the English values for TR_MIC_RECORDER,
TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY,
TR_SAVED, TR_SAVE_AS and TR_OPEN_ERROR with their Portuguese equivalents (e.g.,
"Gravador de microfone", "Pressione para gravar", "Gravar", "Parar", "REC" if
kept or "GRAV", "Começando em", "Prepare-se...", "Salvo:", "Salvar como", and
"Erro ao abrir" as appropriate); keep the macro names unchanged and ensure
punctuation/accents match PT conventions.

In `@radio/src/translations/i18n/ru.h`:
- Around line 971-980: The listed macros (TR_MIC_RECORDER, TR_PUSH_TO_RECORD,
TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY, TR_SAVED, TR_SAVE_AS,
TR_OPEN_ERROR) are still English; replace each English literal with the
appropriate Russian translation while keeping the macro names and the exact
`#define` syntax intact (e.g., TR_MIC_RECORDER -> "..." in Russian). Ensure
translations fit UI context (e.g., "Push to record" as a short imperative,
"Saved:" with colon preserved, "Get ready..." ellipsis kept) and keep
surrounding quotes and capitalization consistent with other entries in ru.h.

In `@radio/src/translations/i18n/se.h`:
- Around line 970-979: Replace the English strings for the recorder keys with
Swedish translations: update TR_MIC_RECORDER -> Mikrofoninspelare,
TR_PUSH_TO_RECORD -> Tryck för att spela in, TR_RECORD -> Spela in, TR_STOP ->
Stopp, TR_REC -> INSP, TR_STARTING_IN -> Startar om, TR_GET_READY -> Gör dig
redo..., TR_SAVED -> Sparad:, TR_SAVE_AS -> Spara som, and TR_OPEN_ERROR -> Fel
vid öppning; change the string literals for these macros in se.h so the Swedish
UI shows these localized labels.

In `@radio/src/translations/i18n/tw.h`:
- Around line 966-975: The new mic-recorder macros (TR_MIC_RECORDER,
TR_PUSH_TO_RECORD, TR_RECORD, TR_STOP, TR_REC, TR_STARTING_IN, TR_GET_READY,
TR_SAVED, TR_SAVE_AS, TR_OPEN_ERROR) are still in English; update their string
values in radio/src/translations/i18n/tw.h to proper Traditional Chinese
translations so the locale is consistent—for example replace each RHS English
literal with the appropriate Traditional Chinese phrase while keeping the macro
names unchanged and preserving surrounding quoting/escaping and punctuation.

In `@radio/src/translations/i18n/ua.h`:
- Around line 970-979: Replace the English placeholders in the Ukrainian locale
by updating the `#define` values for the listed keys: TR_MIC_RECORDER ->
Мікрофонний рекордер, TR_PUSH_TO_RECORD -> Натисніть, щоб записати, TR_RECORD ->
Запис, TR_STOP -> Зупинити, TR_REC -> ЗАП, TR_STARTING_IN -> Початок через,
TR_GET_READY -> Підготуйтеся..., TR_SAVED -> Збережено:, TR_SAVE_AS -> Зберегти
як, TR_OPEN_ERROR -> Помилка відкриття; edit these defines in ua.h so the
Ukrainian strings replace the English ones.

---

Nitpick comments:
In `@radio/src/cli.cpp`:
- Around line 267-328: The toInt return-value check in cliRecord is too narrow:
change the condition that validates parsing of argv[2] from "toInt(...) == 0" to
"toInt(...) < 1" so parse errors (e.g., -1) are treated as invalid; update the
clause that currently reads if (toInt(argv, 2, &seconds) == 0 || seconds <= 0 ||
seconds > 600) to instead treat any non-success return (<1) as an error when
validating seconds (refer to toInt and the local seconds variable in cliRecord).

In `@radio/src/pdm_wav_recorder.cpp`:
- Around line 35-41: The lazy mutex init in ensureMutex() can race if two
threads call it concurrently: replace the manual s_mutexInited check with a
thread-safe one-time initialization (e.g., a call-once pattern) or convert the
mutex to static-initialized so creation happens before any threads run;
specifically update ensureMutex()/s_mutexInited usage (and any calls from
start()) to use a std::call_once/once_flag or equivalent platform call-once
mechanism instead of calling mutex_create directly based on s_mutexInited.

In `@radio/src/translations/string_list.h`:
- Around line 245-255: Wrap the recorder string entries (STR(MIC_RECORDER),
STR(PUSH_TO_RECORD), STR(RECORD), STR(STOP), STR(REC), STR(STARTING_IN),
STR(GET_READY), STR(SAVED), STR(SAVE_AS), STR(OPEN_ERROR)) so they are only
compiled into COLORLCD builds when PDM_CLOCK is defined: add a preprocessor
guard that includes these STR(...) lines by default for non-COLORLCD targets,
but for COLORLCD targets require defined(PDM_CLOCK) before emitting them (e.g.
use a conditional that is true when not COLORLCD or when PDM_CLOCK is present),
then close the guard. Ensure only the block containing those specific STR
entries is wrapped and no other strings are affected.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0a2ff1ec-d144-428c-b9ce-bb7742d8c1ac

📥 Commits

Reviewing files that changed from the base of the PR and between 29170d2 and 6a55891.

📒 Files selected for processing (40)
  • radio/src/CMakeLists.txt
  • radio/src/boards/rm-h750/board.h
  • radio/src/boards/rm-h750/pdm_software_driver.cpp
  • radio/src/boards/rm-h750/pdm_software_driver.h
  • radio/src/cli.cpp
  • radio/src/gui/colorlcd/CMakeLists.txt
  • radio/src/gui/colorlcd/radio/radio_mic_recorder.cpp
  • radio/src/gui/colorlcd/radio/radio_mic_recorder.h
  • radio/src/gui/colorlcd/radio/radio_tools.cpp
  • radio/src/pdm_wav_recorder.cpp
  • radio/src/pdm_wav_recorder.h
  • radio/src/storage/storage_common.cpp
  • radio/src/targets/simu/simufatfs.cpp
  • radio/src/targets/simu/simulib.cpp
  • radio/src/targets/tx15/CMakeLists.txt
  • radio/src/targets/tx15/hal.h
  • radio/src/targets/tx16smk3/CMakeLists.txt
  • radio/src/targets/tx16smk3/hal.h
  • radio/src/tasks.cpp
  • radio/src/translations/i18n/cn.h
  • radio/src/translations/i18n/cz.h
  • radio/src/translations/i18n/da.h
  • radio/src/translations/i18n/de.h
  • radio/src/translations/i18n/en.h
  • radio/src/translations/i18n/es.h
  • radio/src/translations/i18n/fi.h
  • radio/src/translations/i18n/fr.h
  • radio/src/translations/i18n/he.h
  • radio/src/translations/i18n/it.h
  • radio/src/translations/i18n/jp.h
  • radio/src/translations/i18n/ko.h
  • radio/src/translations/i18n/nl.h
  • radio/src/translations/i18n/pl.h
  • radio/src/translations/i18n/pt.h
  • radio/src/translations/i18n/ru.h
  • radio/src/translations/i18n/se.h
  • radio/src/translations/i18n/tw.h
  • radio/src/translations/i18n/ua.h
  • radio/src/translations/sim_string_list.h
  • radio/src/translations/string_list.h

Comment thread radio/src/gui/colorlcd/radio/radio_mic_recorder.h
Comment thread radio/src/targets/simu/simufatfs.cpp
@pfeerick
Copy link
Copy Markdown
Member

pfeerick commented May 11, 2026

@3djc If you haven't already, you might want to check the Minor comments (there are 20 of) and Nitpick comments (there are 3 off) sections above also just to see if there is anything of concern. CodeRabbit only breaks out what it thinks are the more serious ones to review comments.

@3djc
Copy link
Copy Markdown
Collaborator Author

3djc commented May 11, 2026

I did, it complains about some translation not done and other insignificant things

pfeerick and others added 2 commits May 15, 2026 03:21
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…uilds

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread radio/src/storage/storage_common.cpp Outdated
@pfeerick
Copy link
Copy Markdown
Member

Works great on the TX16SMK3.

For reference, the RM docs indicate the mic is located at the bottom left of the display.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport/2.12 To be backported to a 2.12 release also. enhancement ✨ New feature or request hardware support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants