Skip to content

Commit 3d852cd

Browse files
authored
rack_knob: the ring the T-Embed needs, and what a pedalboard change still costs (#130)
* rack_knob: 12 x 256 is the ring this board needs, and the pedalboard change is what is left (#125) The ring the example shipped -- 4 x 128, 10.7 ms -- leaks 426 ms of silence in twenty seconds of knob under a lit panel. Six rings measured twenty seconds each, a fresh LiveAudio per row because starved_ms is a high-water mark nothing in a boot can lower: 4 x 128 426 ms 8 x 128 85 ms 12 x 128 93 ms 16 x 128 18 ms 12 x 256 0 ms 16 x 256 0 ms 12 x 256 (64 ms) is the smallest that reads zero, and depth alone does not get there: 16 x 128 is 42.7 ms of cushion and still leaks, because the worst block is 8.4-8.7 ms against a 5333 us block and a ring of 128-frame pieces cannot hold one late block however many pieces it has. The note that used to be here said nothing deeper bought anything; that was measured at 128-frame descriptors only. What is left is not the ring. Thirty seconds of continuous turning on a macro row adds 0 ms, five times out of five; a PEDALBOARD CHANGE adds 0-176 ms and costs 395-1036 ms on the interpreter thread building the new Rack, which is why 190 s of the harness -- which walks the cursor onto the PATCH row and keeps turning -- still reads 3749 ms at this ring. The docstring and the README say so rather than promising a zero that only holds for the macro rows. * rack_knob: point at the public issue, not a private page; the README says what a pedalboard change costs on this board
1 parent ce69a41 commit 3d852cd

2 files changed

Lines changed: 59 additions & 15 deletions

File tree

lib/examples/audiolive/README.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,13 @@ Lighting that 720 × 720 panel alone costs about eleven points of a block,
121121
because a megabyte of framebuffer is read out of PSRAM for every frame it
122122
clocks and the graph is in PSRAM too; no amount of priority reaches a
123123
bandwidth tax. On the **T-Embed's SPI panel** a lit screen costs nothing
124-
measurable and the knee is **4 × 128** (10.7 ms), with 6 and 8 buying nothing
125-
after it. `audiolive.DMA_DESC_GUI` is the P4 number and an app opts into it;
124+
measurable, but `rack_knob` needs a *deeper* ring than the P4 does, not a
125+
shallower one: 4 × 128 leaks 426 ms in twenty seconds and 16 × 128 still
126+
leaks 18 ms, while **12 × 256** — 64 ms — reads zero for as long as you turn
127+
a macro (changing pedalboard is another matter, below). What decides it is the
128+
worst block, 8.4–8.7 ms against a 5333 µs block, and a ring in 128-frame
129+
pieces cannot hold one however many of them there are.
130+
`audiolive.DMA_DESC_GUI` is the P4 number and an app opts into it;
126131
32 ms is inaudible for a pedalboard and far too much for playing an
127132
instrument.
128133

@@ -161,9 +166,13 @@ is a board bug you will meet for the first time on a board.
161166
in place the attach needs no elevation, the kernel autoloads
162167
`snd-usb-audio`, and raw bytes written to `/dev/snd/midiC0D0` (group
163168
`audio`) are enough — no `amidi`, no `sudo`, no winmm.
164-
- **Nobody has heard `rack_knob` on the LilyGO T-Embed S3**, and it starved
165-
2.5 % of the time at a 4 × 128 ring across its 190-second run. 8 × 128 is
166-
better, not zero.
169+
- **Nobody has heard `rack_knob` on the LilyGO T-Embed S3.** Its ring is
170+
measured now — 12 × 256, the smallest that starves nothing — but every
171+
number behind it is electrical.
167172
- **A patch change builds a whole Rack on the UI thread.** One `app.poll()` in
168173
ten minutes on the P4 hit 222 ms at a patch change. It is a hitch, not a
169-
hang.
174+
hang. On the T-Embed it is a hole you can hear: 395–1036 ms of interpreter
175+
building the new Rack, and up to 176 ms of silence that no ring depth
176+
covers — a 190-second run that keeps changing pedalboard reads 3749 ms
177+
starved at the same 12 × 256 that reads zero under the knob
178+
([#126](https://github.com/PyDevices/pydevices-examples/issues/126)).

lib/examples/audiolive/rack_knob.py

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,15 @@
4646
The bottom line is the one that matters. ``load`` is how much of each block
4747
of audio the effects use; anything under 100 is fine. ``starved`` is how many
4848
milliseconds of silence the speaker has had to invent because the effects
49-
were late. It should read ``0 ms`` however hard you spin the knob.
49+
were late. Spin the knob and it stays at ``0 ms``; that is what the ring
50+
below was chosen for, and the measurements are beside it.
51+
52+
Two honest caveats. The ring is 64 ms deep, so a macro you move is heard up
53+
to 64 ms later - a knob still feels immediate at that, and anything
54+
shallower leaks silence on this board. And **changing pedalboard does cost
55+
you a hole**: building the new Rack takes 395-1036 ms on the interpreter
56+
thread and drops up to 176 ms of audio. No ring depth reaches that, so the
57+
``0 ms`` above is a promise about the macro rows and not about PATCH.
5058
5159
Two things this board does not do
5260
---------------------------------
@@ -95,16 +103,43 @@
95103
STEP = 4 # macro units per encoder detent
96104
LEVEL = 0.5 # see the docstring: this board's only volume
97105

98-
# 4 x 128 descriptors = 10.7 ms. Measured on this board with the panel up and
99-
# a bar redrawing 237 times a second, which is a harder screen than this one:
100-
# 2 x 128 starved 1976 ms in twenty seconds and 4 x 128 starved nothing, and
101-
# nothing deeper bought anything. The P4 needs 12 x 128 for the same job,
102-
# because a lit 720x720 panel reads a megabyte of PSRAM per frame and an SPI
103-
# ST7789 reads none.
106+
# 12 x 256 descriptors = 12 288 bytes = 64 ms. It is the smallest ring that
107+
# starves nothing UNDER THE KNOB, and it is not enough to make a long run
108+
# read zero - be clear about which claim you are reading.
109+
#
110+
# Twenty seconds a row, the panel lit, a detent every 30 ms and a press every
111+
# 2 s, one fresh LiveAudio per row because ``starved_ms`` is a high-water mark
112+
# nothing in a boot can lower (``probes/s3_rack.py`` ``ringsweep()``):
113+
#
114+
# 4 x 128 10.7 ms starved 426 ms
115+
# 8 x 128 21.3 ms starved 85 ms
116+
# 12 x 128 32.0 ms starved 93 ms
117+
# 16 x 128 42.7 ms starved 18 ms
118+
# 12 x 256 64.0 ms starved 0 ms <- this
119+
# 16 x 256 85.3 ms starved 0 ms
120+
#
121+
# What decides it is not the pump's average but its worst block: one pull of
122+
# ``Overdrive`` costs 89-90 % of the 5333 us a block lasts and the worst is
123+
# 8.4-8.7 ms, so a ring of 128-frame pieces cannot hold one late block
124+
# however many pieces it has. That is why 16 x 128 (42.7 ms) still leaks
125+
# where 12 x 256 (64 ms) does not, and why the note that used to be here -
126+
# "nothing deeper bought anything" - was wrong: it was measured at 128-frame
127+
# descriptors only.
128+
#
129+
# **What is left is the pedalboard change, and no ring cures it.** Thirty
130+
# seconds of continuous turning on a macro row adds 0 ms, five times out of
131+
# five. A CHANGE adds 0-176 ms, and costs 395-1036 ms on the interpreter
132+
# thread building the new Rack - so a 190 s run that keeps changing patch
133+
# reads 3749 ms starved at this same ring. Change pedalboards while you are
134+
# playing and you will hear it; turn a macro and you will not.
135+
# Tracked: https://github.com/PyDevices/pydevices-examples/issues/126
136+
#
137+
# The P4 runs ``rack_gui`` at 12 x 128, because a lit 720x720 panel reads a
138+
# megabyte of PSRAM per frame and an SPI ST7789 reads none.
104139
# A harness or a board file can choose the ring before this module is
105140
# imported; everything else gets the number this board was measured at.
106-
audiolive.DMA_DESC = getattr(audiolive, "RACK_DMA_DESC", 4)
107-
audiolive.DMA_FRAME = getattr(audiolive, "RACK_DMA_FRAME", 128)
141+
audiolive.DMA_DESC = getattr(audiolive, "RACK_DMA_DESC", 12)
142+
audiolive.DMA_FRAME = getattr(audiolive, "RACK_DMA_FRAME", 256)
108143

109144

110145
class RackKnob:

0 commit comments

Comments
 (0)