mirror of
https://github.com/MCKero6423/uv-k5-v3-emulator.git
synced 2026-10-02 03:15:36 +00:00
Document why there is no audio to model
Records the scope plainly, because "add a speaker and a microphone" is the obvious request and the answer is that neither is on the MCU: no audio samples exist in its address space, so there is nothing to capture, nothing to play, and nothing for a browser permission to carry. Same line as the analogue RF limit. Also records the stub lesson: QmpClient.command returns the unwrapped value, the test stub returned an envelope, and the divergence let 88 tests pass while the live UI returned 500. A stub more forgiving than the real client is worse than none.
This commit is contained in:
1 parent
7d299dbad2
commit
a1aca9395c
2 files changed
+63
No files matched your search
@@ -510,6 +510,43 @@ plausible way to stall a scan, and the S-meter work made the receiver always bus
|
||||
Page 4 is *not* the meter row, incidentally — it stayed byte-identical across all six
|
||||
samples while the frequency changed.
|
||||
|
||||
### Audio: there is nothing to model, and that is the finding
|
||||
|
||||
"Add a speaker and a microphone, then grant the browser audio permission" is the
|
||||
obvious request, and it cannot be done — not for lack of effort but because neither
|
||||
device is on the MCU. Receive audio is demodulated inside the BK4819 and leaves as
|
||||
analogue on its AF pin; transmit audio goes from the microphone into the chip's own ADC.
|
||||
The firmware touches only:
|
||||
|
||||
PA8 amplifier enable (GPIO_EnableAudioPath, driver/gpio.h:34)
|
||||
REG_47 which AF source the chip routes
|
||||
REG_64 a level it displays
|
||||
|
||||
**No audio samples exist anywhere in the MCU's address space.** There is nothing to
|
||||
capture, nothing to play, and nothing for a browser permission to carry. Generating
|
||||
sound would be inventing data the firmware never produced — the same line as the
|
||||
analogue RF limit.
|
||||
|
||||
What is real is the *intent*. `TYPE_UVK5_AUDIO` watches PA8 and exposes read-only
|
||||
`speaker-on`; the UI shows a speaker glyph and `/api/status` reports `speaker`.
|
||||
Read-only on purpose: a writable one would only let a test lie to itself. A unit test
|
||||
also asserts the page never asks for audio permission — no `getUserMedia`, no
|
||||
`AudioContext`, no `<audio>` — because prompting the user to approve something that
|
||||
cannot happen is worse than not offering it.
|
||||
|
||||
### A stub that is more forgiving than the real client is worse than no stub
|
||||
|
||||
`QmpClient.command` returns the **unwrapped** value and raises on error. The test stub
|
||||
returned `{"return": ...}`. So `webui.py` was written to unwrap a second time, all 88
|
||||
tests passed, and the live UI returned 500 with
|
||||
|
||||
TypeError: argument of type 'bool' is not iterable
|
||||
|
||||
Two lessons, both of which cost time here. The stub is now pinned to the real contract
|
||||
by an explicit test. And the failure was originally swallowed by a bare
|
||||
`except: return None`, which made a broken call indistinguishable from a radio that was
|
||||
simply silent — and sent me hunting a stale process that did not exist. Log the reason.
|
||||
|
||||
### PTT, and the transmit level bar
|
||||
|
||||
PTT is not a matrix key. `GPIO_IsPttPressed` reads PB10 directly
|
||||
|
||||
@@ -44,6 +44,7 @@ has no public datasheet, so its driver is the only specification available.
|
||||
| BK4819 register interface | works, RSSI and status readable |
|
||||
| S-meter | works via monitor (SIDE1); reads -53 dBm, S9+40 |
|
||||
| PTT and transmit | works; TX annunciator, timer, and mic level bar |
|
||||
| Speaker / microphone audio | **no samples exist to model**, see [Audio](#audio) |
|
||||
| Timing accuracy | deliberately wrong, see [Timing](#timing) |
|
||||
| Analogue RF behaviour | **not modelled and never will be**, see [AGENTS.md](AGENTS.md#the-bk4819-and-where-modelling-it-stops) |
|
||||
|
||||
@@ -86,6 +87,7 @@ keypresses silently stop working. Run the test after touching that code;
|
||||
test_smeter.py the S-meter reads a signal when monitoring
|
||||
test_ptt.py PTT keys the radio and releases cleanly
|
||||
test_scan.py a busy band does not stall a scan
|
||||
test_audio_path.py the amplifier turns on when the firmware wants sound
|
||||
run_tests.sh runs all of the above, build-checked first
|
||||
test_run_tests.sh that the runner actually notices failures
|
||||
lib_kill_emulator.sh cleanup that only ever kills emulators
|
||||
@@ -143,6 +145,7 @@ that was never compiled. Individual tests still run standalone:
|
||||
python3 tools/test_smeter.py
|
||||
python3 tools/test_ptt.py
|
||||
python3 tools/test_scan.py
|
||||
python3 tools/test_audio_path.py
|
||||
|
||||
This matters more than it looks. The keypad can break silently under -O2 without
|
||||
any compiler warning -- see the `volatile` note in [Status](#status) -- so a clean
|
||||
@@ -276,6 +279,29 @@ or `POST /api/release-all` — so a client going away cannot leave the radio key
|
||||
The `press` property still rejects "PTT" as a key name; unknown keys get a 400 rather
|
||||
than being forwarded.
|
||||
|
||||
## Audio
|
||||
|
||||
There is no audio, and there is nothing to add. On the real radio neither the speaker
|
||||
nor the microphone passes through the MCU: receive audio is demodulated inside the
|
||||
BK4819 and leaves it as analogue on its AF output, and transmit audio goes from the
|
||||
microphone straight into the chip's own ADC. The firmware only ever touches three
|
||||
things:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| PA8 | the amplifier enable, on or off |
|
||||
| `REG_47` | which AF source the chip routes |
|
||||
| `REG_64` | a level the firmware displays |
|
||||
|
||||
No audio samples exist anywhere in the MCU's address space, so the emulator has nothing
|
||||
to capture or play — and the browser page needs no microphone or playback permission,
|
||||
because there would be nothing for it to carry. Generating sound here would mean
|
||||
inventing data the firmware never produced.
|
||||
|
||||
What *is* real is whether the firmware currently wants sound, which PA8 states exactly.
|
||||
The UI shows it as a speaker glyph next to the power state, and `/api/status` reports it
|
||||
as `speaker`. Press SIDE1 to engage monitor and it lights up.
|
||||
|
||||
## How the machine is put together
|
||||
|
||||
Register layouts come from the vendor CMSIS header shipped with the firmware
|
||||
|
||||
Reference in new issue
Block a user