Skip to content

Claude/ci jobs failing xxrsmg - #13

Closed
jhhr wants to merge 311 commits into
sonic-visualiser:defaultfrom
jhhr:claude/ci-jobs-failing-xxrsmg
Closed

jhhr wants to merge 311 commits into
sonic-visualiser:defaultfrom
jhhr:claude/ci-jobs-failing-xxrsmg

Conversation

@jhhr

@jhhr jhhr commented Sep 27, 2026

Copy link
Copy Markdown

No description provided.

Four connections in Analyser and one in MainWindow named their slots
in SIGNAL()/SLOT() strings with ModelId or sv_frame_t, while moc
records the slots as taking sv::ModelId and sv::sv_frame_t. Qt 6.4
does not match the two ("No such slot"), so the analyser never heard
that pYIN had finished and TestSingingAnalysis timed out; the Qt the
project is developed with happens to match them. Member pointers are
checked at compile time and match under any version, as the rule in
docs/architecture.md already asks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012YZZce5FzUjNEE1ZPgVtJj
Timed lyrics are to come from LRC files: the Moises lyrics exporter
writes them, line by line or word by word, and so do many other tools.
parseLrc() reads both kinds into words with a start, an end and a
line, and lyricsToEvents() makes them the events of a region model, one
region per word with the line as its value, on the reference's timeline.

The exporter writes no end times, so a word ends where the next one
starts and the last word of a line is capped at 2 s unless a gap line
(a time tag with no text, or only a note sign) says where it ends. Its
words are split on their tags, never on spaces: it leaves the space out
before a word with punctuation in it. Text that XML 1.0 cannot hold is
removed on the way in, so that no label can make a session unreadable.
Files that are not UTF-8 are read as Latin-1, the same on every system.

The core suite reads the fixtures in testdata/lyrics through a define
of the source directory; the fixture text is invented.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012YZZce5FzUjNEE1ZPgVtJj
svgui gains RegionLayer::PlotLyrics (62af60f, on the fork's branch
claude/nifty-goodall-4kocmz): each region's label along the top of the
view at its start, over a bar as long as the region, in up to two rows,
for the words of a song. The pin moves to it.

TestLyricsLayer, a new app suite, tests where labels go
(assignLabelRows), that nothing is drawn below the band, and that the
layer painted strip by strip is the same as the layer painted whole: a
view that scrolls repaints only what comes into sight, and a layout that
depended on the strip broke the text at the seams.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012YZZce5FzUjNEE1ZPgVtJj
File > Import Lyrics... reads an LRC file and shows its words along
the top of pane 0, on the reference's timeline, in the lyrics plot
style of the svgui fork. LyricsTrack owns the one layer, as the
coverage strip's class owns its own: one set of lyrics per session, a
new import in place of the last, File > Remove Lyrics to take them away
and View > Show Lyrics to hide them without losing them.

Like loading background music, an import is not undoable and pushes no
command, but marks the session modified. The layer goes in under the
pane's top layer, whose hover readout and scale the pane uses, and its
model is taken out of the play source, so that words after the end of
the reference do not hold playback open. A file that cannot be read or
holds no timed lyrics is refused with a dialog and changes nothing;
what was skipped goes to the status bar with the counts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012YZZce5FzUjNEE1ZPgVtJj
The lyrics' layer and model are document contents, so a session file
already held them; what a load lacked was LyricsTrack taking the layer
up again. analyseNewMainModel() now adopts it by its name, next to the
alternate pitch track, with the visibility and the name it was saved
with, and takes its model out of the play source, which the load had put
it into. A session saved with the lyrics on top of the pane comes back
with them under the layer that was below them.

Tests show the lyrics coming through a save and reopen exactly, hidden
or shown; left alone by recording, undo, redo, new takes, switching and
Load Singing Track; and gone with their session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012YZZce5FzUjNEE1ZPgVtJj
The pane takes its hover readout and its vertical scale from its top
layer, which the lyrics never are: an import puts them under the layer
on top, and a session load puts them back under it. But deleting the
layer just above them, by turning the alternate pitch track off or
deleting a take, left them on top until the session was loaded again.
LyricsTrack now looks again once any other layer has gone, and puts
the layer under the lyrics back on top if they are there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012YZZce5FzUjNEE1ZPgVtJj
Feasibility research for running Tony on a phone, kept so that a
session starting either port need not repeat it. mobile-port.md holds
the decisions, the facts about Tony and its libraries that any port
depends on, and a comparison; port-android.md and port-sailfish.md hold
the dated platform facts with sources, the work, and a first test port.

The research also found that a recording device not at 44.1 kHz
probably places take audio at the wrong scale, since the splice does
not resample; noted in open-points.md as unverified.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
What the lyrics are made of and why (architecture), the lyrics plot
style of the svgui fork and why it stays scrollable (forks), the new
suites, the test data they read and the tests expected to fail when
built on Linux with Qt 6.4 (testing), what is not built and what is
weak (open points), what only a person can judge (manual checklist,
items 37-48), and how to import lyrics and get them out of Moises
(README).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012YZZce5FzUjNEE1ZPgVtJj
The phases, decisions and rules that the agents building the android
port read. Tracked on the branch because cloud containers are thrown
away between sessions; the last phase folds it into the other pages
and deletes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
download.qt.io and dl.google.com are now allowed from the cloud
container and actions is enabled on the fork, so the toolchain phase
installs locally and the apk phase adds the ci workflow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
Tony shifts every take by the latency PortAudio reports, which on MME,
DirectSound and WASAPI is buffer sizes only, and most of the manual
checklist has never been run. The plan measures the round trip through
the ordinary take path with the mic hearing the output, stores it per
device, and in development builds runs the checklist items a loopback
can settle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDVZsDa83T6H9RKkbeBVzV
…ntainer

repoint cannot reach hg.sr.ht from the cloud container, so the mercurial
libraries come from their github mirrors, matched to the pins by date.
qt 6.11 comes from conda-forge: with ubuntu's 6.4 the analyser's string
connects naming sv:: types never match, and the analysis never
completes. the work orders record phase a0 and the container's build
and test commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
back slashes as separators and names that ignore case are windows
behaviour by design; on other systems the suite checks that names are
case-sensitive and uses a posix absolute path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
The plan is split into phases for a line of agents. The work orders
say what each reads, how to build and test in this session, and what
it may not touch; the spec gains the decisions made and the facts about
today's code the phases rest on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDVZsDa83T6H9RKkbeBVzV
Four connections in Analyser and one in MainWindow named their slots
in SIGNAL()/SLOT() strings with ModelId or sv_frame_t, while moc
records the slots as taking sv::ModelId and sv::sv_frame_t. Qt 6.4
does not match the two ("No such slot"), so the analyser never heard
that pYIN had finished and TestSingingAnalysis timed out; the Qt the
project is developed with happens to match them. Member pointers are
checked at compile time and match under any version, as the rule in
docs/architecture.md already asks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012YZZce5FzUjNEE1ZPgVtJj
The app suite needs pyin.so beside it or it hangs until the QtTest
watchdog fires; Qt 6.4 does not match string connects naming sv types;
four TestTakesFile tests use Windows paths and fail on Linux only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDVZsDa83T6H9RKkbeBVzV
stale_pitch_event_ignored queued onRealtimePitchDetected by name with
Q_ARG(sv::sv_frame_t), which Qt 6.4 does not match against the slot
moc recorded, so invokeMethod returned false and the test failed
before testing anything. A queued functor calling the same slot is
checked at compile time. Removing the slot's guard still makes it fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDVZsDa83T6H9RKkbeBVzV
Two cloud sessions have had to work out how to build and test Tony on
Linux. The steps are now in docs/building.md: the packages, the
libraries at their pins (the six Mercurial ones from their GitHub
mirrors, as the cloud proxy refuses hg.sr.ht), the targets, and the
traps of Qt 6.4. build_linux/ is ignored like the other build folders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012YZZce5FzUjNEE1ZPgVtJj
the repository's workflows are turned off, so phase a3 writes a build
script and the lead hands the apk over.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
The svgui pin moves to e2c736d, the second version of the lyrics plot
style: light boxes as long as each word along the bottom of the pane,
text centred, a font at least twice the view's that grows as the view
zooms in, and the word at a given frame in amber, shown over the others
if it has no room of its own.

TestLyricsLayer now checks the band is along the bottom and leaves the
coverage strip's pixels alone, where a box goes, how the font follows
the zoom, that a label is centred in its box, and that the highlight
repaints only when the word changes, changes nothing but its own box,
and is shown even for a word that had no row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012YZZce5FzUjNEE1ZPgVtJj
LatencyCheck makes the reference a calibration plays: linear sweeps of
1 to 8 kHz at irregular spacings, each followed by a tone pYIN can
track. findSweep() locates a sweep in a take with an FFT matched
filter, takes the earliest peak within 6 dB of the largest so that a
stronger reflection does not win, and says how sure it is. It works at
the take's own rate. Pure functions, tested in TestLatencyCheck; the
reflection, 48 kHz, polarity and notched-band tests were seen to fail
with the code broken.

Core suite: all green but the four known TestTakesFile Windows-path
tests on Linux. App suite: green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDVZsDa83T6H9RKkbeBVzV
tony's models are at 44.1 khz, but a recording is written at the
device's rate, and phones run at 48 khz, as some desktop devices do. the
take's audio went in at the wrong scale and place, punch-out stopped
early, and the live dots used the wrong timeline.

a recording is now resampled to the reference's rate before the splice,
and taketiming converts between device frames (latency, frames received,
the live tracker) and the reference's. the 48 khz placement, latency and
punch-out tests failed before. the play cursor still runs fast while
recording at 48 khz, which needs the svgui fork; an expected failure
marks it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
The ranged-analysis tests of TestSingingAnalysis took initialAnalysisCompleted
as the sign that the range had been merged. The whole-file analysis each of
them runs first can still be delivering its own completion when the range
starts, and Analyser::layerCompletionChanged() emits the same signal for it,
so now and then isAnalysingRange() was still true when it was read
(ranged_range_shorter_than_the_margin, once in a full run on Linux). Wait
for the flag, as docs/testing.md says to.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019UV9LcYjNdAyq7Edp5Jygt
The MainWindow subclass that TestRecordWorkflow drives is wanted by two
more: a suite that works through the shown window, and a check with the
real audio device. Moved as it was, word for word.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019UV9LcYjNdAyq7Edp5Jygt
Of its 36 items, those about what is on the screen and what the window
does with keys, mouse and dialogs become TestUiChecks, a suite of
test-tony-app: the real window, shown offscreen and made active, driven
with QTest key presses and mouse gestures on pane 0 and with the dialogs
MainWindow shows, and judged by the pixels of the window's backing store.
With TONY_TEST_SHOT_DIR set it saves what it judged, for a person to look
over. The items about the audio device become test-tony-device, which is
built with the rest but run only by hand: it records a four-minute click
track through the air into one take and measures where the clicks landed,
how long Stop took, which input carries the microphone, and whether the
input comes back out. TONY_DEVICE_CHECK_FAKE runs it on the fake device
fed back into itself, to check the check. FakeAudioIO can put its input
on one channel, for a microphone on input 2.

The checks found four defects, committed as expected failures: the live
dots stop being drawn during a take (the dot model defers its change
notices), the band of the coverage strip goes under the take's waveform
from the second recording on, commitData() writes a .sv that Tony does not
open as a session, and with playback constrained to the selection a
pre-roll places the take a whole pre-roll early. They and the other
findings are in docs/open-points.md. What is left of the checklist is the
device check, six items by hand, and decisions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019UV9LcYjNdAyq7Edp5Jygt
How Tony was built and both suites run in a cloud container: Ubuntu's
packages, but Qt 6.11 from conda-forge, because under Ubuntu's Qt 6.4 the
string-based connects of Analyser with sv:: types do not resolve and no
analysis ever completes; the libraries cloned at their pins, the hg ones
from their GitHub mirrors; and the four TestTakesFile tests that are about
Windows paths and fail anywhere else.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019UV9LcYjNdAyq7Edp5Jygt
judgeTake() runs the sweep finder over a take's punch-ins and says what
the audio path did: the median offset across punch-ins, how far they
disagree, whether the offset grows with position, whether the input
clipped or the sweeps faded, and whether each sweep came back a second
time, which is a monitored input. calibratedRoundTrip() adds the median
offset to the round trip the take was placed with; a take that lands
late was spliced from too early a frame. The sign, the position rule
and the echo's minimum delay were each seen to fail their test when
broken.

Core suite: all green but the four known TestTakesFile Windows-path
tests on Linux. App suite: green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDVZsDa83T6H9RKkbeBVzV
claude and others added 29 commits September 26, 2026 21:11
svcore reads a small WAV file on a thread of its own, and the model's
frame count grows from 0 until it is ready. swap_keeps_layers_and_events
compared it straight after the swap, which no analysis follows: here
the model was not ready yet at that point, with all its frames read,
and on CI's macOS it had 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FSQFemK6yNDepHnCX4Nq
Items 1, 2, 7 and 13 passed at 6 ms, the takes running the same
course from the calibration as the run before; a slip fell inside a
take. The microphone showed in use throughout and no take clicked.
Item 3 failed on four dots in silence, which no run before had: the
live tracker has no level floor, and what made them is not known.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDVZsDa83T6H9RKkbeBVzV
Oboe's input latency capped at its buffer, Oboe named as the driver,
and a test that reads the swapped-in audio in full.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDVZsDa83T6H9RKkbeBVzV
… once idle

The user's phone, restarting the streams at every take, landed a
Bluetooth calibration's punch-ins 8.5 ms apart and the dev run's up to
+4.9 ms off, while one take's sweeps agreed: every start moved the
input against the output, as on the desktop before feat/wasapi. The
stream now runs on between takes on Android too, so that a session's
takes share one alignment.

So that a phone does not keep its microphone open and its battery
draining, a device neither playing nor recording is suspended after
two minutes (audioIdleSuspendMillis(), never on desktop), and when
Android sends Tony to the background; the next Play or Record resumes
it. Oboe's latency is then measured at open and at those suspends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
The slip is a period of silence in the playback, not input dropped:
the two cards' clocks are about 100 ppm apart, so a running stream
gaps about every 100 s. The dots in silence came from the room's
steady noise, about -66.5 dBFS with lines at 306 and 334 Hz, 25 dB
below the quietest dot on a tone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDVZsDa83T6H9RKkbeBVzV
Stop splices the take before it returns, after the idle time has
started, and under the sharded runner's load that took long enough for
the device to be suspended "1323 ms after the take" by a stopwatch
started once Stop had returned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
… layout

The overview took 60 px of a phone's height. In the compact layout a
24 px strip (SongScrollBar) now stands in its place: the whole song with
a faint contour of the reference's pitch, so that sung parts can be told
from rests, a thumb for what the panes show, and the playhead. A drag on
the thumb moves the panes by the drag; a press elsewhere centres them
there. The thumb follows scrolling, zoom and playback's paging. The
arithmetic is in tony_core (SongScroll); CompactLayout gains shownWidgets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
… at a tone's end

Items 1, 2, 7 and 13 allow 6 ms, from the kept-running WASAPI runs on
two sound cards; item 3 sets apart the live dots at a tone's end. The
one conflict, calibrate-audio.md's restart jitter, keeps both the PC's
measurements and the phone's, which Android now keeps running too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
YIN is blind to level and found a pitch now and then in the user's
room noise, fans at -66.5 dBFS, 25 dB below the quietest window of a
tone, and item 3 failed on those dots. A window whose first half is
quieter than -60 dBFS now gives no dot: the first half, as YIN takes
its pitch from it, so that a window reaching into a sound does not pass
with the pitch of the quiet before it; and the channels' average, as
the mixdown is their sum. The fake's room gets a steady 306 Hz at
-66 dBFS, on which the kept-running dev run fails without the floor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDVZsDa83T6H9RKkbeBVzV
Item 3 passed with the level floor. Items 1 and 2 failed: the takes
lay within 9.4 ms as before, but the calibration sat at the window's
edge. The user took that as good enough and ended the work here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDVZsDa83T6H9RKkbeBVzV
…the last driver runs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDVZsDa83T6H9RKkbeBVzV
On the user's phone, with the input at -28 dBFS, 4 of about 280 live
dots a punch-in came out an octave under the tone, and the dev checks'
item 3 failed on them: where noise lifts YIN's dip at the period over
its threshold, the dip at twice the period can still be under it.

Every hop of the tracker now goes through OctaveSlips: a dot about an
octave from the one before it is held back with those after it that
are too, and the run is dropped when the next dot is back at the pitch
before it. A run longer than one window's hops, or one ending in
silence or at another pitch, is let through late: a real leap of an
octave shows up to 46 ms later, and no other dot is late.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
…ctave slips

Both change the live tracker's loop: a window under the level floor
now counts as an unvoiced hop for OctaveSlips, which lets a held run
through. recording.md keeps both paragraphs, the floor first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
svgui's feat/tonyandroid and svapp's feat/wasapi were merged into their
forks' tony-customizations, and bqaudioio's WASAPI work is its fork's
tony-customizations, which its master does not have: the pins move to
those heads (the same trees as before), and bqaudioio is followed on
tony-customizations. svcore was there already; bqaudiostream has no
such branch and stays on master.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
Windows headers define far as an empty macro, and the Windows build
failed on the variable of that name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FSQFemK6yNDepHnCX4Nq
live_dots_under_the_cursor let the pointer be 50 ms behind the
playback, a tick and a half of svgui's 20 ms timer. On CI's macOS a
20 ms timer fires every 60 to 67 ms, and the pointer was drawn about
80 ms behind. A 20 ms timer of the test's own measures how late this
machine's timers are, and the 50 ms is scaled by that; here it stays
at 1.0 to 1.1, and svgui's timer slowed to 150 ms still fails it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FSQFemK6yNDepHnCX4Nq
The README still opened as upstream Tony's, with its home page, download
link, screenshot and CI badges, which implied that this repository is what
the upstream site distributes. It now starts with what the fork is for and
walks through a first recording. It adds the features it did not mention
(live pitch dots, Calibrate Audio, the alternate pitch track, background
music, Load Singing Track) and points to docs/building.md, since there are
no ready-made builds. Tony's credits and licence are kept, citation points
to the CITATION file, and the badges show the fork's own workflows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VjiM5rHmDR8Zfy2377o2DH
Rewrite README for singing practice fork
The README described the desktop app only. It now has an On Android
section: how to get the test APK from CI, the compact layout, touch,
files and All files access, the audio routes, and what happens when Tony
goes into the background. It also gains View > Plot Size, Lyrics Size and
Compact Layout, the audio device kept open between takes, WASAPI as the
Windows default, the Android build scripts and an Android CI badge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VjiM5rHmDR8Zfy2377o2DH
hands_over_everything_at_once waited 100 ms for the feed's first look,
which on CI's macOS had not come by then: it now waits until the feed
has looked three times. The slow-GUI test likewise waits until nothing
is left to hand over, not 100 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FSQFemK6yNDepHnCX4Nq
…d in

Every page is brought up to date with the code as the port left it,
and what was still true and useful in android-work-orders.md is folded
into the pages it belongs to; the file is deleted.

- building.md: the Android build (toolchain, C libraries, Qt from
  source, the APK and its version), the cloud session, the CI jobs.
- testing.md: all suites of the three executables, the fakes' and
  window's seams, testing the phone's code on the desktop.
- architecture.md: tony_core and tony_app as meson builds them, the
  port's classes and who wires them, the drawing rules.
- recording.md, takes.md: the Android take path, a device at another
  rate, the stream kept running everywhere, the background save.
- forks.md: every fork's Tony branch is tony-customizations.
- calibrate-audio.md, audio-drivers.md: Calibrate Audio and the dev
  checks on a phone, and the phone's runs.
- mobile-port.md, port-android.md, port-sailfish.md: what was built,
  the facts the port confirmed or disproved, known limitations.
- manual-checklist.md, open-points.md: what was tried on the phone,
  what is left, what stays open.

Statements the code had made false are corrected, among them the
resampler's unreported delay (about 53 frames at 48 kHz, as measured),
the Qt 6.4 note in container-setup.sh, and the line counts in AGENTS.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9EHVCNZ4EXP662cDczuon
On CI's Windows the app suite took 863 s of its 900, and then ran over
them with every test passing: meson reported a timeout. The dev suite
keeps its 900 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FSQFemK6yNDepHnCX4Nq
Android port, Windows audio drivers, and live dot and latency fixes
The background music's hidden waveform layer was already written into the
.ton with its model, but opening the session took that model for a singing
track's and dropped it, so the music had to be loaded again each time.

The layer is now named "Background Music", and restoreTakes() adopts it by
that name before dropRestoredSingingTrack() runs. Its mute, gain and pan come
back with the model's play parameters. Music whose file cannot be found is
asked for as the reference is and leaves the session incomplete; the empty
layer the reader keeps for it is dropped. Sessions saved before this open
without their music, as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014pVszfB3GFRpEHDrNerAyk
Save and restore background music with session
deploy/linux/ci-local.sh runs what those two workflows run: Ubuntu's
Qt 6.4 in a release build in build-linux-ci/, every meson test in one
process and the workflow's list of failed tests (--quick: the core and
app suites in one process per core); and deploy/android's five scripts
in the workflow's order. It waits for the session's background build
first and logs to tmp/ci-local/.

In a cloud session live_dots_under_the_cursor fails with Qt 6.4, alone
and unloaded: the dots trail the cursor by 333 to 369 ms against its
300, and by 114 to 125 ms with Qt 6.11 in release and debugoptimized
builds alike. testing.md now says so, in place of its note that the
test passed there with four processes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FSQFemK6yNDepHnCX4Nq
@jhhr jhhr closed this Sep 27, 2026
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.

2 participants