Hertzwise

Automatic sample-rate switching for Mac music players, so your DAC follows every track and lossless plays bit-perfect.

It works with Apple Music and Tidal, adds a volume stage for DACs that ignore the Mac’s volume, and has a headphone EQ you switch on per output device.

The Hertzwise panel: Tidal at 192 kHz, in sync with the PAW S1

Why

macOS runs each output device at one sample rate and resamples everything else to it, so a 96 kHz track on a DAC left at 48 kHz plays as 48 kHz. Players work around this with an exclusive mode, but Tidal’s takes the whole device away from other apps, and on some setups drops audio or locks the volume. Hertzwise keeps exclusive mode off and switches the DAC’s rate to each track instead.

  Hertzwise SyncHz LosslessSwitcher
Players Apple Music, Tidal Apple Music Apple Music
Volume for DACs that ignore the Mac’s volume Yes No No
Headphone EQ Any app, per device Apple Music No
macOS 15+ 15+ 11.4+ (2.0 beta for 15.4+)

Status

Player Rate switching Status
Apple Music Yes From SyncHz
Tidal (exclusive mode off) Yes New
YouTube Music Planned Later

Per-device volume and EQ

Each output device’s submenu has two switches, on by default only for the Lotoo PAW S1:

Both run in one muted process tap per device, so each device is processed once.

How it works

Install

  1. Download the latest .dmg from Releases and drag Hertzwise into Applications.
  2. It is not notarized, so clear the quarantine flag once:
    xattr -dr com.apple.quarantine /Applications/Hertzwise.app
    

After that, Hertzwise updates itself: it checks daily and installs a new version from the panel’s menu, with no quarantine step and no new permission prompts.

Requires macOS 15 or later. Hertzwise can be installed next to SyncHz: settings, EQ profiles and permissions are separate.

Build from source

git clone --recursive https://github.com/zeetabit/Hertzwise.git
cd Hertzwise
open SampleRateSwitcher.xcodeproj

Needs Xcode 26 or later. In an existing clone, run git submodule update --init once.

How the audio path works, and why: docs/audio-engine.md. Releases, signing and the update keys: docs/releasing.md.

Updating the MediaRemote adapter

Track info and playback controls come from mediaremote-adapter, pinned as a submodule in Vendor/mediaremote-adapter. Updates are deliberate:

  1. Read the release notes of the new tag and the diff since the pinned one:
    cd Vendor/mediaremote-adapter
    git fetch --tags
    git log --oneline HEAD..NEW_TAG
    git diff HEAD NEW_TAG -- src bin include CMakeLists.txt
    
  2. Check the diff for anything a now-playing reader should not do (network, file writes, spawning processes) and for changes to the stream and send output the app parses.
  3. git checkout NEW_TAG, build, run the tests and check track info and playback controls with Tidal and Apple Music.
  4. Commit the new pin from the repository root: git add Vendor/mediaremote-adapter.

Acknowledgements

License

MIT. The original copyright notice is kept as the license requires.