Release

macOS 27: new icons, real glass, and an input that measured nothing

Lyra 1.8, Audita 1.5 and Specula 1.3 ship today, built with Xcode 27. Most of the work was invisible. This is the part that was not: icons that need a second Xcode on the machine, a volume pill matched to the system's glass one value at a time, and a measurement microphone that went silent on 27 until the log said why.

macOS 27 is out tomorrow, and three updates are out today: Lyra 1.8, Audita 1.5 and Specula 1.3. All three are free for existing licenses and all three still run on the macOS versions they ran on last week. The point of this post is what the week before a new macOS looks like for a one-person studio, because it was not the week of polish I had planned.

Icons: the SDK is not the whole toolchain

Every app got a new icon, rebuilt in Icon Composer 27: layered glass, specular highlights, separate fills for Light and Dark mode. The design work was pleasant. The build work was the surprise.

An Icon Composer 27 file only compiles with the asset tool that ships in Xcode 27. Open the same project with Xcode 26.6 and the build stops with attempt to insert nil object, which says nothing about icons. So Xcode 27 now lives next to 26.6 on every Mac here, and each app's Makefile checks which Xcode is selected: 27 or newer is used as is, otherwise the build reaches for /Applications/Xcode-27.app, and if neither exists it stops with a sentence saying why. One commit per app, and a rule I did not have before: the icon file decides the minimum Xcode, not the code.

Lyra: a volume pill that matches the system's

Lyra puts a volume overlay on screen when you press F11 or F12 for an Apollo. On macOS 26 the system's own volume control became a glass capsule, and Lyra's single-row pill stopped matching it. Lyra 1.8 replaces it with a capsule of the same shape: the connected Apollo's name above a tick-marked level slider, tinted by the wallpaper behind it, in Light and Dark mode. Reference Level jumps show the slot name in the same place.

Lyra's volume overlay on macOS 27: a clear glass capsule with the Apollo's name above a tick-marked level slider, tinted by the wallpaper behind it
Lyra 1.8's overlay. The geometry was measured off the macOS 27 volume control at 2x; the material was matched by comparison, not by eye.

The shape was measurement: 285 by 60 points, corner radius 24, 13 point semibold title, 10 points below the menu bar, all read off 2x screenshots of the system control. The material was the fight. Apple's public glass view renders the same material as SwiftUI's glass, and its least frosted setting is still far more frosted than the pill the system draws. There is no public property for the blur.

What worked was going one layer down. The glass is a backdrop layer with a filter on it, and the filter's inputs can be set by key path once the view has drawn. I did not guess the values. A small harness compiles the real overlay source, shows it at the system pill's anchor, and captures both over an identical backdrop, in both appearances, and a script stacks the crops side by side. Everything I tried that looked plausible failed that comparison: a full-height refraction lens inverted the backdrop, so a window below the pill showed at its top; the colour bleed from the slider variant washed the interior lighter; a lifted face colour read too bright over the wallpaper. The system pill, it turned out, differs from public clear glass in exactly one value: the blur radius, 1.0 instead of 5.83. Everything else stays stock.

One more trap: in Light mode the glass view re-renders its own backdrop several times a second, and every render installs a fresh stock filter. A one-off write lasted 50 to 250 milliseconds and the pill flickered between tuned and frosted on every key press. The fix observes the layer's filters and re-applies the value inside the same transaction. If any of this makes you nervous, the compact single-row pill from 1.7 is still there under Settings, and the tuning is guarded: if the filter is not the one expected, Lyra leaves the glass stock.

On macOS 27 the About and Settings windows also use interactive glass, the kind that responds to the pointer. That one is a public property and one line. Audita's Welcome and License windows got the same treatment.

Audita: the input that measured nothing

This is the reason the post exists. Audita 1.5 was built, signed, and on the macOS 27 test Mac, and the first calibration attempt measured nothing. Not zero dB: nothing, as if the microphone had never been plugged in. The microphone was the Studio Display's, selected explicitly in Settings. Switch the picker to System Default, which on that Mac is the same microphone, and the meter came alive. Audita 1.4 behaved the same way on 27. On macOS 26, both selections had worked for months.

An app launched from Finder does not have a console, so the first change was making the capture path talk. Every step now writes a line to the unified log: which device was selected, the formats before and after routing, whether the device assignment took, the channel map, which tap went in, whether the engine started, and a check three seconds later of how many audio buffers actually arrived. On the test Mac the answer came back in eight lines. The one that mattered:

start: inputFormat(bus0)=44100 Hz x 1  outputFormat(bus0)=44100 Hz x 1  before routing
setInputDevice: CurrentDevice set to 89; read back 89 (status 0)
start: tap format 44100 Hz x 1 after routing; inputFormat(bus0)=48000 Hz x 1
start: installAudioTap FAILED: Code=-10868 "Input HW format and tap format not matching"

Audita selects an input device the way every macOS app that uses AVAudioEngine has to: read the input node so the hardware unit exists, assign the device to that unit, set a channel map so the chosen channel lands on the bus, then install a measurement tap in the node's output format. On macOS 26, assigning the device refreshed that output format. On 27 it does not. The node keeps reporting the previous route's 44.1 kHz while the hardware side already says 48 kHz, and the new OS checks the two against each other and refuses the tap. System Default never assigns a device, so it never hit the mismatch.

The fix is small once you can see it. The tap keeps the node's channel count, because the channel map still decides that, but takes its sample rate from the hardware format whenever the two disagree, and the weighting filters follow that rate. Where the formats agree, on 26 and earlier, nothing changes. The diagnostics stayed in. If Audita ever goes quiet on your machine, this command shows the capture path step by step:

/usr/bin/log show --predicate 'subsystem == "com.headroom.Audita"' --last 5m

One aside for the developers reading. The old tap call raises an uncatchable exception on that mismatch; macOS 27 deprecates it in favour of a throwing variant that reports the same condition as an error. Audita uses the new one on 27, which is why the failure above is a log line and not a crash report. It is also why the bug was diagnosable at all.

Specula: the glass got lighter

Specula 1.3 carries the new icon and the same Record mode fix. Its input tap is built with the recipe Audita uses, and on 27 it met the same stale sample rate: arming Record mode on a device whose rate differed from the previous route captured nothing. The tap now follows the device, and a device that refuses the tap is reported as a failed arm instead of a crash.

The rest of the list is what a new OS does to an interface tuned on the old one. Specula's chrome has sat on Liquid Glass since macOS 26: the toolbar buttons, the side panel, the floating Output Router and Per-Channel Statistics panels. On 27 the same material renders lighter. Measured over the app's window background, a toolbar button that read 27 on 26 reads 59 on 27, and the side panel went from 23 to 45. The whole app looked washed out. The obvious fix, tinting the glass black, makes it brighter: a tint is a luminous layer over the material, whatever its colour. What works is a translucent black fill between the material and the label. It scales the face linearly and leaves the rim highlight and the refraction alone. On 26 the fill is off and nothing changes; on 27 it brings every surface back to within a few values of where it was.

Then the small ones. The glass segmented controls are wider on 27, so the Fade, Add Silence and Normalize popovers wrapped their inline labels one letter per line; the labels moved above their controls. The Spectral toolbar's L / R / Both switch ran into the menu next to it for the same reason. And the two floating panels could not be dragged at all: macOS 27 stops honouring the window-background drag flag when the click lands in SwiftUI content, so the panels now carry their own drag gesture. Audita's pinned measurement panel had the same bug and the same fix.

Small things

All three disk images now open on a window that looks like this site: dark ground, the studio mark, the app icon and the Applications folder side by side, a caption. One generator renders the three backgrounds so they cannot drift apart. Finder draws the icon labels in black over any background picture, on every macOS version, and no setting changes that, so the caption carries the instruction.

Audita's current-level readouts now spell out the units for VoiceOver on macOS 27: "d B A", not a guess at a word. Lyra gets a menu toggle that hands F10, F11 and F12 back to macOS for a while without quitting. Neither took an afternoon. The glass and the microphone took the week.

All three updates are free for existing licenses: Check for Updates in each app, or download from the app pages. Lyra 1.8 runs on macOS 12 or later ($9.99). Audita 1.5 and Specula 1.3 run on macOS 14 or later ($19.99 and $99.99). One-time purchases, 7-day trials. Release notes: Lyra, Audita, Specula.