Skip to content

Say why transpose is off, instead of naming the wrong cause - #559

Merged
thcp merged 1 commit into
mainfrom
fix/transpose-secure-context
Sep 2, 2026
Merged

Say why transpose is off, instead of naming the wrong cause#559
thcp merged 1 commit into
mainfrom
fix/transpose-secure-context

Conversation

@thcp

@thcp thcp commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Closes #552

A client opening a networked StemDeck saw greyed-out key controls and, on the lane steppers, "Transpose needs Web Audio". Web Audio was working fine.

The cause, measured

AudioWorklet is a secure-context API. A browser on http://<lan-ip> is never given it, so the SoundTouch stage cannot be built at all. One page served three ways, in Chromium:

http://127.0.0.1:8777/     secureContext=true   audioWorklet=true
http://localhost:8777/     secureContext=true   audioWorklet=true
http://192.168.1.14:8777/  secureContext=false  audioWorklet=false

So the greying out is correct. This PR does not make transpose work over a network and does not claim to. It fixes what the app said about it, which was wrong in three separate ways.

What changed

The lane tooltip named the wrong thing. It blamed Web Audio, which was working, and sent people looking for a missing browser feature instead of at the URL they typed. It now says transpose is not available over a network connection.

The transport control said nothing at all. Three dead buttons still reading "Transpose up a semitone". It explains itself now, on the group rather than the buttons, since a disabled button does not reliably fire the pointer events a tooltip needs.

Speed was silently moving the key. This is the one nobody reported. Without the pitch stage the sources resample, so changing speed also changes the key, and the control gave no sign. It says so now.

Where the reason lives

pitchBlockedKey() is in pitchBus.js, for the same reason the input mapping is: the transport control and the lane steppers both have to answer this question, and two copies drift into two different answers. On an already-secure origin it still reports a plain worklet failure, which is then the only remaining explanation.

Deliberately not in the tooltip

There are real workarounds: an ssh tunnel to localhost, tailscale serve, an HTTPS reverse proxy. They are in the README troubleshooting section for anyone who goes looking. They are not in the tooltip, because answering a musician with port forwarding is a worse answer than admitting the limit.

The capability itself is tracked in #558, with the measurement showing createScriptProcessor is not secure-context gated and an honest account of what that path would cost.

i18n

Three keys added across all ten tables. ptPT overrides the new string, since European Portuguese says "ligação" rather than "conexão". mixer.key.unavailable is removed from all ten, dead once the lane tooltip started sharing the transport's answer.

Verification

playwright        90 passed
node tests/js     11/11
i18n audit        clean

Five e2e tests, including that a secure origin says something different and that a working transpose explains nothing at all.

Checked against the unpatched code: four of the five fail, and the one that passes is the one asserting the absence of a tooltip. So the tests catch the bug rather than merely describing the fix.

… cause

A client opening a networked StemDeck saw greyed-out key controls and, on
the lane steppers, "Transpose needs Web Audio". Web Audio was working
fine. AudioWorklet is a secure-context API, so a browser on
http://<lan-ip> is never given it and the SoundTouch stage cannot be
built at all. Measured in Chromium: 127.0.0.1 and localhost report
secureContext=true and audioWorklet=true; 192.168.1.14 reports false and
false.

Nothing in the page can fix that today, so the control now says plainly
that transpose is not available over a network connection. It does not
offer a workaround. There are real ones -- an ssh tunnel to localhost,
tailscale serve, an HTTPS proxy -- and they are in the README for anyone
who goes looking, but a tooltip that answers a musician with port
forwarding is a worse answer than admitting the limit.

The transport group had no explanation at all before this, only three
dead buttons still offering to transpose up a semitone. It has one now,
on the group rather than the buttons, since a disabled button does not
reliably fire the pointer events a tooltip needs.

pitchBlockedKey lives in pitchBus.js for the same reason the input
mapping does: the transport control and the lane steppers both have to
answer this, and two copies drift into two different answers. On an
already-secure origin it still reports a plain worklet failure, which is
then the only remaining explanation.

Speed is the part nobody reported, because it is silent. Without the
pitch stage the sources resample, so changing speed also moves the key,
and the control gave no sign. It says so now.

mixer.key.unavailable is removed from all ten tables, dead once the lane
tooltip started sharing the transport's answer. ptPT overrides the new
string: European Portuguese says "ligação", not "conexão".

Five e2e tests cover it, including that a secure origin says something
different and that a working transpose explains nothing. Verified against
the unpatched code: four of the five fail, and the one that passes is the
one asserting the absence of a tooltip.

playwright 90 passed, node tests/js 11/11, i18n audit clean.
@thcp
thcp merged commit ec82e31 into main Sep 2, 2026
10 checks passed
@thcp
thcp deleted the fix/transpose-secure-context branch September 2, 2026 09:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Key transpose over web app client is not supported

1 participant