The receiver that switches its own mode
A small Python script on the Mac watches which app is playing and tells the studio's Yamaha TSR-700 to use Dolby Surround for movies and All-Channel Stereo for music.
Try the rules
This runs the same decision the script makes every four seconds.
The problem
One receiver, two jobs. Movies want the Dolby Surround decoder. Music and whatever is playing in a browser sound better here in All-Channel Stereo. Switching by remote every time is the kind of chore that never gets done.
How it works
- Every four seconds the script asks macOS which apps are holding the system awake for audio or video playback, using the built-in
pmset -g assertionscommand. - It checks that list against two short lists of app names in a rules file.
- If a movie app is playing, it wants Dolby Surround. Movie apps win ties, so a trailer in Chrome during a Stremio film does not flip it.
- If only a music or browser app is playing, it wants All-Channel Stereo.
- If nothing is playing, it leaves the receiver alone.
- When the wanted mode changes, it asks the receiver for its status over Yamaha's local network API, and only if the receiver is on does it send the new sound program.
The rules file
Changing behaviour means editing a list, not code. The receiver's address is left out here.
{
"receiver_ip": "<receiver address>",
"poll_seconds": 4,
"dolby": ["Stremio", "TV", "VLC"],
"stereo": ["Google Chrome", "Safari", "TIDAL"]
}
The override
Sometimes the rules are wrong for the moment. A file called override next to the script, containing dolby or stereo, pins that mode. Delete it and the script goes back to automatic.
The heart of it
def want_mode():
ov = HERE / "override"
if ov.exists() and ov.read_text().strip() in MODES:
return ov.read_text().strip()
apps = playing_apps()
for mode in ("dolby", "stereo"): # movie apps win ties
for key in CFG[mode]:
if any(key.lower() == a.lower() or (len(key) > 3 and key.lower() in a.lower()) for a in apps):
return mode
return None
One day in the log
Every switch is logged. From 28 October 2026:
08:48:13 -> dolby
11:37:39 -> stereo
16:16:36 -> stereo
16:46:34 -> dolby
17:43:04 -> stereo
It runs in the background as a macOS launch agent, so it starts with the Mac. When the receiver does not answer, the script logs the error and simply tries again on the next round; the log shows one such timeout, on 25 October, followed by a normal switch half a minute later.