Repository navigation
Windows: Mochi dances to the song's own beat (opt-in) - #412
Open
shakibbinkabir wants to merge 4 commits into
Open
shakibbinkabir wants to merge 4 commits into
shakibbinkabir wants to merge 4 commits into
Conversation
The Linux pill reads Spotify over MPRIS. Windows has System Media Transport Controls: every player reports its track to the system and takes play, pause, next… through it. The pill now reads Spotify's session there, behind the same five functions the Linux client implements, so the page is the Linux one. - No polling: one thread sleeps on a channel while the pill is declared, and Windows wakes it when a session comes or goes or Spotify's changes. Spotify updates its timeline as it plays; only a jump counts as news, so a playing track sends the island nothing. - Spotify only: the session is picked by its app id (the Store build and the one from spotify.com). A browser playing a video is not shown. - The cover comes with the session, so nothing is fetched. - The session has no volume: the slider moves Spotify's level in the Windows volume mixer. - Shuffle and repeat are left out of the card on Windows. Spotify answers that it changed them and changes nothing, so `modes` in the state tells the card. - The session carries no Spotify URI: tracks get a `spotify:local:` id, so there is no page to open and an ad is not recognised as one. - "Open Spotify" follows a `spotify:` link, which starts it or brings it forward; without Spotify, its download page. The pill is now offered on both systems (`support: "yes"`), and the Linux-only support kind this pill had introduced goes away with its last user. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
When Spotify moves on to another song, the island opens on Spotify's card for three seconds and folds back, and the pill that was in front gets its place again. A light in Mochi's colour breathes behind him, the cover glows and a sheen crosses it, so it reads as news and not as an island that opened by accident. No sound: music is playing. The idea and its look are Edurique's, from Louis-CFM#83. It is rebuilt here on the card and the state machine as they are today, and nothing of the card changes outside those three seconds. - Off by default (Settings → Integrations → Spotify → Announce new songs). The island never opens on its own for news that asks nothing, and the Mac does not do this, so it is something to turn on. - A new song is one that starts after another: not the first heard since Spotify started, not the same one going on after a pause or a seek, never an ad. Windows names a track before it says it plays; it is announced once it does. - Never over an island that is open, under the mouse, pinned or waiting for an answer. The mouse coming, a key or an alert makes it an open island like any other: the auto-close delay applies again, the usual sounds come back, and the front stays where the user sees it. - The state machine gains `glance(seconds)`: open, and fold after its own delay instead of the auto-close preference. It is the hover-open's short countdown with another length, and ends the same way (`userInteracted`). - The light takes the colour of the pill's Mochi, so a colour picked in Settings → Active pills is the light's too. - Songs skipped through carry one announcement on, and the front still goes back to the pill that had it before the first. Co-authored-by: Edurique <225876024+Edurique@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
taktus reads the tempo of music and where its beats fall from the sound itself (https://github.com/shakibbinkabir/taktus, Apache-2.0, by Shakib Bin Kabir). This is its one source file as published in 0.1.0, put in the tree whole so that the app takes on no dependency: no crate, nothing to fetch, std only, no unsafe. Left out of the file: the page of documentation at its top, with the examples it runs, and its tests. Both live in its repository, with what it was measured on. Nothing else is changed, and its header says so. Nothing uses it yet: the next commit does. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBruuRH1qTWSvSpxoV6mKT
The Mac's Mochi bounces at 112 beats a minute whatever plays. On Windows the app can hear what the computer plays (a loopback of the default output), so it can find the song's tempo and where its beats fall, and he lands on them. - Off by default: Settings → Integrations → Spotify → Dance to the song's beat. Listening to what the computer plays is for the user to ask for, and the row says what it does. It is shown only where the song can be heard. - Nothing of the sound is kept or sent. As it comes it is reduced to "how much just started", a hundred numbers a second, and those are all that is looked at (taktus.rs, the commit before). - Only while a Mochi is seen dancing: in the compact island, on Spotify's card, or on the desktop. The page says when (spotify_dancing), and with the island hidden and nobody on the desktop the tap is closed and the listener sleeps on its channel as before. - A few seconds at a time. The follower listens until two readings agree (about ten seconds), settles on sixteen, then rests and only looks again now and then; the tap is closed while it rests. About a quarter of a song is heard. - A pause or a seek keeps the tempo and forgets where the beats fall until they are found again; another song starts from scratch. Until a beat is known, and on Linux, he keeps the 112. - He dances between 80 and 160: a tempo read outside that is danced at half or double. - The whole output is heard, not Spotify alone, so another app's sound blurs the reading (a note in beat.rs says what tapping one process would take). The player's state gains tempo and beatAt; the dance takes a tempo and a beat to count from, and is unchanged when given none. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBruuRH1qTWSvSpxoV6mKT
PythonTilk
added a commit
to PythonTilk/coucou
that referenced
this pull request
Oct 9, 2026
…(opt-in) Taken from shakibbinkabir's branch while it is still open upstream; its first two commits are Louis-CFM#374, already here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PythonTilk
added a commit
to PythonTilk/coucou
that referenced
this pull request
Oct 18, 2026
…s on top From upstream: the Coucou window with Flow dictation, the Notetaker and « OK Coucou », its Spotify pill, and settings as pages in that window. Taken over this build's own versions: « OK Coucou » replaces the hotkey voice (removed just before), upstream's Spotify replaces Louis-CFM#374 and Louis-CFM#412 (the beat dance goes with them), and the settings pages replace the folding groups. Kept and moved onto the pages: Updates (General), the chat provider picker (Chat), Phone alerts and Mail (Integrations). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Mac's Mochi bounces at 112 beats a minute whatever plays. On Windows the app can hear what the computer plays, so it can find the song's tempo and where its beats fall, and he lands on them. Off by default, one switch in Settings.
Recorded from the running app. So that three tempi sit side by side, the page was handed the three states by hand, in the shape the listener reports them; the live reading is further down.
What the user sees
Nothing, until they ask: Settings → Integrations → Spotify → Dance to the song's beat. The row sits under "Announce new songs", built from the same
rowandhintas its neighbours, and is offered only where the song can be heard (Windows).With it on, a song starts on the Mac's 112, and about ten seconds in the bounce takes the song's tempo and lands on its beats. A pause or a seek keeps the tempo; where the beats fall is found again in a few seconds. Another song starts from scratch. Nothing else on screen changes: no new view, no new element in the island or the card.
How it works
beat.rs,taptaktus.rs,Eartaktus.rs,Followerspotify.rs,Ears,tell_beatmochi/engine.ts,DanceClockHe dances between 80 and 160: a tempo read outside that is danced at half or double (
dance_tempo).Only while a Mochi is seen dancing. The page knows when one is (the compact island, Spotify's card in front, or Mochi on the desktop) and tells Rust when that changes (
spotify_dancing). With the island hidden and nobody on the desktop, or the app paused, or the choice off, the tap is closed, no timer runs, and the thread sleeps on its channel exactly as in #374.What it costs
Measured on the installed build (Windows 11, i7-1260P), on the listener's own thread (
coucou-spotify, by thread times, 15.6 ms resolution):The engine by itself (its
bench, same machine): 0.26 ms to hear a second of sound, 0.27 ms for a reading of sixteen seconds, and about a quarter of a song listened to. It holds about 9 KB while it listens.Privacy
The engine in the tree
The listening is taktus, a tempo and beat engine. I am its author; I published it as 0.1.0 while writing this, so judge it as you would any new code. It is here as one file,
windows/src-tauri/src/taktus.rs, so that the app takes on no dependency:unsafe, no allocation while listening. 571 lines of code.If you would rather have it as a crate (
taktus = "0.1", which has no dependencies of its own), or would rather not have the file at all, say so and I will reshape this.Against the repo's rules
Cargo.tomlgains one feature of thewindowscrate already in use (Win32_Media_Audio_Endpoints).settings.jsongainsdanceToBeat, false when absent.windows/README.mdgains a paragraph under what differs from the Mac.Tested
npx tsc --noEmit,npm test(379 pass),cargo test --workspace --locked(253 pass), on Windows 11.tests/spotify.test.mjs): the bounce keeps any tempo it is given and is the Mac's when given none; the song's beat is danced to only when asked for, and no longer the moment it is not; Rust is told that somebody dances only when asked, once per change, through the island hiding, Mochi on the desktop, a pause, the app paused, and another pill's card in front.beat.rs); a drum fed as the app feeds it is followed to its tempo, with a beat within 40 ms of a drum and rests in between (beat.rs); a settings file from before reads with the choice off (settings.rs); the player's state carries no tempo until one is heard (spotify.rs).cargo test -p coucou the_tap_hears_what_plays -- --ignored --nocapture).Not tested, and known limits
beat.rssays what it would take.Commits
595d993taktus in the tree. The file, and nothing that uses it.d142479Mochi dances to the song's own beat. Everything else. Needs the commit before it, and Windows: the Spotify pill through the system's media session, and an opt-in new-song announcement #374.🤖 Generated with Claude Code
https://claude.ai/code/session_01NBruuRH1qTWSvSpxoV6mKT