debba/melicum

HDMI and DisplayPort volume control for macOS, with native system volume and mute

Swift

1

18 commits

updated Oct 18, 2026

See the code

See what people are saying

SourceMessageScoreDate

Melicum, a free and open-source app that brings back volume keys for HDMI and DisplayPort displays on macOS (r/coolgithubprojects)

If you plug your Mac into a monitor or TV over HDMI or DisplayPort, macOS usually greys out the volume slider and the volume keys show a crossed-out speaker. I got tired of reaching for the monitor's buttons, so I built **Melicum** with Claude. **What it does** * **Volume, mute, balance and up to…

1

Oct 18, 2026

README

Melicum icon: a lyre whose yoke is an EQ curve and whose sound box is an HDMI receptacle

Melicum

HDMI and DisplayPort volume control for macOS.
Website · Download

A native macOS audio app focused on HDMI and DisplayPort volume control. Software gain works even when a digital output has no hardware volume control. The optional system volume component also enables the macOS volume slider and native volume keys.

Melicum uses an independent SwiftUI interface, Core Audio routing, and C DSP. It requires macOS 14.2 or later. Building the app from source additionally requires Xcode 26 or later and Swift to compile the native layered icon. English is the default language; Italian, French, German, and Spanish are available under Presets → Language.

Screenshots

Main windowApp mixerSpatial audio
Redesigned Melicum console with output selection, master volume, spectrum and expert EQPer-app volume sliders and mute controlsSpatial audio with five room settings, reverb mix and stereo width
Output, master controls and EQIndependent application levelsReverb and stereo width
Audio UnitsPresets and settingsQuick menu
Audio Unit effects panel and Add effect menuPreset management, language, startup preferences and automatic update checksMelicum menu bar panel with volume, mute, power, Open panel and update check
Installed effect chainsPresets, startup, language and updatesEveryday volume controls

Screenshots show the native SwiftUI interface with example devices, levels and presets. The original lyre logo and its graphite, cream and red palette are preserved. See the user guide for every control.

Getting started

  1. Download the latest .dmg from Releases, drag Melicum to Applications, and open it. Release builds are signed with a Developer ID and notarized by Apple.
  2. Choose a monitor or audio device under Audio output. Devices with identical names are numbered separately.
  3. Click Enable audio and approve system audio recording in the macOS permission dialog. Melicum processes audio locally without saving recordings or sending audio over the network.
  4. Adjust Volume, Mute, balance, and boost. The menu bar panel provides quick access to these controls.
  5. To use native macOS volume controls, click Enable system volume… and complete the installer using an administrator account. It installs MelicumSystemVolume.driver in /Library/Audio/Plug-Ins/HAL and restarts the audio service. Enable audio again after installation. The virtual output uses the selected physical output's name followed by (Melicum), for example DELL U2414H (Melicum), while playback continues on that physical output. Switching outputs updates the virtual device's name. Volume and mute stay synchronized between Melicum and macOS. Accessibility permission is unnecessary in this mode.
  6. Without the optional component, Volume keys offers a keyboard shortcut fallback. Enable Melicum under System Settings → Privacy & Security → Accessibility, then click the button again. This fallback controls keyboard volume keys while audio processing runs; the native HDMI volume slider remains unavailable.

Settings and everyday use

The main console keeps output selection, master volume, mute, balance, boost and the live spectrum visible while you switch between EQ, app mixer, spatial audio, Audio Units and presets. Cream controls and small red indicators follow the original logo palette.

Under Presets, save or export your audio setup, associate a preset with an output or application, select one of five languages, and configure startup behavior:

  • Launch at login opens Melicum when you sign in.
  • Enable audio on launch separately enables the saved output. It is off by default; if the saved output is disconnected, processing stays off.
  • Language changes the interface immediately. English is the source language; Italian, French, German and Spanish are included.

Audio settings and presets are stored in ~/Library/Application Support/Melicum/settings.json. Language, startup and updater preferences are stored separately from audio presets. The user guide explains volume, EQ modes, app levels, effects, preset recall and all preferences.

Automatic update checks

Melicum checks for new stable GitHub releases automatically, approximately once a day by default. Configure this under Presets → Updates → Automatically check for updates. You can also select Check for Updates… in that panel, the Melicum menu or the menu bar panel.

Automatic checks do not silently install updates. Melicum asks before downloading and installing, preserves settings, and restores the physical output before quitting for installation. Sparkle verifies the signed feed, EdDSA archive signature and Apple code signing. Draft and prerelease versions are excluded from the stable update feed. Updating the app does not automatically replace the optional HAL component; when a release includes a component update, run its included Enable system volume… installer separately.

Disable and Quit close the taps and aggregate devices, restoring the previous output when available. Processing stops if the physical device disconnects, its sample rate changes, or macOS selects another output. Choose the desired output and enable audio again.

Features

FeatureImplementation
HDMI / DisplayPort volumeSoftware volume, mute, 0–12 dB boost, L/R balance, menu bar controls
Native system volumeOptional virtual output with bidirectional volume/mute synchronization and native volume keys
Basic EQBass, mid, and treble
Advanced EQ10 fixed bands
Expert EQUp to 64 filters with independent frequency, gain, Q, and bypass; bell, low/high shelf, low/high pass, notch, and band pass
Spectrum2,048-sample FFT of processed audio, displayed in 64 logarithmic bins
Peak protectionClamps output samples to ±0.98; this is not a true-peak limiter
App mixerSeparate taps for applications with custom volume, grouped by bundle identifier
Spatial audioOriginal stereo reverb with five room sizes and mid/side width adjustment
Audio UnitsChain of up to 12 installed effects compatible with stereo float PCM; generic parameter editor
AutoEQ importLocal ParametricEQ .txt files in Equalizer APO / REW format
Super presetsComplete settings snapshots, JSON import/export, output associations, and app-triggered recall
InterfaceFixed graphite, cream and red palette from the logo, lyre menu bar icon and quick controls, launch at login, five languages

This version supports mono/stereo PCM. Configure multichannel HDMI devices for two channels in Audio MIDI Setup. Dolby/DTS passthrough and protected streams unavailable to macOS process taps are unsupported. The online AutoEQ database and proprietary plugin interfaces are not included. Incompatible Audio Units cancel startup with an error; effects that fail during rendering are bypassed. Peak protection operates per stream, so the sum of multiple mixer streams can still exceed full scale.

Output presets are recalled when selecting an output in Melicum. App presets are recalled when the active playback application changes, preferring the foreground application and otherwise the first active application alphabetically. Changing the mixer or Audio Unit chain rebuilds the audio path and may briefly interrupt playback. Switching to Basic or Advanced EQ initializes that mode's bands; save a preset first to preserve an Expert configuration.

Building and testing

The optional system volume component builds on BlackHole, included as a submodule. Clone with:

git clone --recurse-submodules https://github.com/debba/melicum.git
swift test
./scripts/make-brand-icon.sh
./scripts/build-system-volume.sh
./scripts/build.sh
.build/release/Melicum --list-devices

To regenerate the documentation screenshots from the native views with isolated example data, run:

./scripts/make-screenshots.sh

The capture script uses a temporary test harness, starts no audio session and leaves personal audio settings untouched.

The system volume driver has its own C tests:

mkdir -p build
xcrun clang -std=c11 -fblocks Driver/Tests.c -framework CoreAudio -framework CoreFoundation -framework Accelerate -o build/driver-tests
./build/driver-tests

The app bundle is written to build/Melicum.app and signed locally with an ad hoc signature. To install it without administrator privileges, close the running app and use:

./scripts/install.sh

Releases

Pushing a v* tag, or running the Release workflow manually with a tag name, builds a universal Melicum.app on GitHub Actions. The workflow runs the tests, signs the app and the system volume driver with a Developer ID and the hardened runtime, notarizes and staples the app and the disk image, and attaches Melicum-<version>.dmg, Melicum-<version>.zip, appcast.xml, and SHA256SUMS.txt to a draft release. An identical copy named Melicum.dmg provides the website's direct download of the latest stable release. Tags with a - suffix are marked as prereleases. Publishing a stable release makes its signed appcast.xml available at the updater's latest-release URL; drafts and prereleases are not offered through that feed. CI build numbers use 1000 + github.run_number so they increase monotonically and remain above local development builds.

The workflow requires these repository secrets:

SecretContents
APPLE_CERTIFICATEBase64-encoded .p12 with the Developer ID Application certificate and private key
APPLE_CERTIFICATE_PASSWORDPassword of the .p12
APPLE_SIGNING_IDENTITYIdentity name, for example Developer ID Application: Name (TEAMID)
APPLE_API_ISSUERApp Store Connect API issuer ID
APPLE_API_KEYApp Store Connect API key ID
APPLE_API_KEY_CONTENTBase64-encoded .p8 API key
APPLE_INSTALLER_SIGNING_IDENTITYOptional. Developer ID Installer: Name (TEAMID) to sign the driver package; its certificate must be in the same .p12
SPARKLE_PRIVATE_KEYBase64 EdDSA private key exported by Sparkle's generate_keys tool. It must match SUPublicEDKey in Resources/Info.plist.

To reproduce a signed build locally, set MELICUM_SIGN_IDENTITY (and optionally MELICUM_INSTALLER_IDENTITY) before running the build scripts. MELICUM_ARCHS="arm64 x86_64" produces a universal binary.

An updated build may require macOS permissions to be approved again. Launch at login uses SMAppService and may require confirmation in System Settings.

The Swift tests cover gain, mute, balance, filter response, FFT, peak protection, interleaved/planar buffers, tap input selection, Audio Units, AutoEQ parsing, preset round trips, all five localizations, and isolation of live spectrum updates from editable controls. Driver/Tests.c covers output names, stable device identity, property validation, hidden startup, visibility notifications, heartbeat, owner validation, volume round trips, shutdown, heartbeat timeout, and unexpected owner exit. Automated tests do not replace listening on the physical output or validating macOS permissions.

On this Mac, manual checks verified actual audio through the virtual output to the selected DELL device, volume and mute synchronization in both directions, and restoration of the physical output when processing stops.

Audio routing and system volume

The optional component wraps BlackHole source pinned to commit 561d934c77a1fa64987e01ccabe890fed30e181f. It exposes a stereo output with standard volume/mute properties. Melicum captures application audio targeted at that output and forwards the processed signal to the selected physical device. The loopback input is unused. For fixed-volume outputs, master volume is applied in Melicum's DSP. For outputs with writable master or channel volume controls, the physical volume follows the virtual slider and DSP omits master attenuation, preserving the device's full volume range. Writable physical mute controls follow the virtual mute state. Stopping leaves these controls at the last requested level, so fallback playback uses that level as well.

The virtual device appears in the macOS output list only while Melicum is open and processing audio. Disabling audio or quitting restores the previous physical output and hides the virtual device. If the owner process exits unexpectedly or its heartbeat is missing for five seconds, the driver hides and disables the device so macOS can choose another output. The component stays installed between launches; updating an older component requires running the system volume installer included in the new app.

Routing follows Apple's Capturing system audio with Core Audio taps, local SDK headers, and the shared-clock aggregate model described by CoreAudioTapKit. The tap and physical output share a callback. The C callback uses preallocated memory and atomic controls; audio lifecycle and Audio Unit configuration run on a separate serial queue.

Visual identity

The original vector mark is a lyre drawn as an equalizer: the yoke is an EQ curve with three hollow nodes, the strings end on that curve, and the sound box has the profile of an HDMI receptacle. The name comes from the Latin melicus, "lyrical". Its "Vinyl and VU" palette pairs a graphite tile with cream and VU-needle red. SVG masters are in Resources/brand; Resources/AppIcon.icon supplies the native layered macOS icon, Resources/BrandIcon.png supplies the legacy icon, and Resources/BrandMark.png supplies the transparent header mark. Shared geometry in scripts/make-icon.swift generates the SVG and PNG artwork. See the identity notes.

License

Copyright © 2026 Andrea Debernardi.

Melicum and its modified BlackHole component are distributed under GPL-3.0. See LICENSE, ThirdParty/BlackHole/LICENSE, and Driver/UPSTREAM.md. Upstream source and license notices are preserved.

audio
audio-units
core-audio
displayport
equalizer
hdmi
mac
macos
menu-bar-app
per-app-volume
spatial-audio
swiftui
volume-control

debba/melicum

HDMI and DisplayPort volume control for macOS, with native system volume and mute

Swift

1

18 commits

updated Oct 18, 2026

See the code

See what people are saying

SourceMessageScoreDate

Melicum, a free and open-source app that brings back volume keys for HDMI and DisplayPort displays on macOS (r/coolgithubprojects)

If you plug your Mac into a monitor or TV over HDMI or DisplayPort, macOS usually greys out the volume slider and the volume keys show a crossed-out speaker. I got tired of reaching for the monitor's buttons, so I built **Melicum** with Claude. **What it does** * **Volume, mute, balance and up to…

1

Oct 18, 2026

README

Melicum icon: a lyre whose yoke is an EQ curve and whose sound box is an HDMI receptacle

Melicum

HDMI and DisplayPort volume control for macOS.
Website · Download

A native macOS audio app focused on HDMI and DisplayPort volume control. Software gain works even when a digital output has no hardware volume control. The optional system volume component also enables the macOS volume slider and native volume keys.

Melicum uses an independent SwiftUI interface, Core Audio routing, and C DSP. It requires macOS 14.2 or later. Building the app from source additionally requires Xcode 26 or later and Swift to compile the native layered icon. English is the default language; Italian, French, German, and Spanish are available under Presets → Language.

Screenshots

Main windowApp mixerSpatial audio
Redesigned Melicum console with output selection, master volume, spectrum and expert EQPer-app volume sliders and mute controlsSpatial audio with five room settings, reverb mix and stereo width
Output, master controls and EQIndependent application levelsReverb and stereo width
Audio UnitsPresets and settingsQuick menu
Audio Unit effects panel and Add effect menuPreset management, language, startup preferences and automatic update checksMelicum menu bar panel with volume, mute, power, Open panel and update check
Installed effect chainsPresets, startup, language and updatesEveryday volume controls

Screenshots show the native SwiftUI interface with example devices, levels and presets. The original lyre logo and its graphite, cream and red palette are preserved. See the user guide for every control.

Getting started

  1. Download the latest .dmg from Releases, drag Melicum to Applications, and open it. Release builds are signed with a Developer ID and notarized by Apple.
  2. Choose a monitor or audio device under Audio output. Devices with identical names are numbered separately.
  3. Click Enable audio and approve system audio recording in the macOS permission dialog. Melicum processes audio locally without saving recordings or sending audio over the network.
  4. Adjust Volume, Mute, balance, and boost. The menu bar panel provides quick access to these controls.
  5. To use native macOS volume controls, click Enable system volume… and complete the installer using an administrator account. It installs MelicumSystemVolume.driver in /Library/Audio/Plug-Ins/HAL and restarts the audio service. Enable audio again after installation. The virtual output uses the selected physical output's name followed by (Melicum), for example DELL U2414H (Melicum), while playback continues on that physical output. Switching outputs updates the virtual device's name. Volume and mute stay synchronized between Melicum and macOS. Accessibility permission is unnecessary in this mode.
  6. Without the optional component, Volume keys offers a keyboard shortcut fallback. Enable Melicum under System Settings → Privacy & Security → Accessibility, then click the button again. This fallback controls keyboard volume keys while audio processing runs; the native HDMI volume slider remains unavailable.

Settings and everyday use

The main console keeps output selection, master volume, mute, balance, boost and the live spectrum visible while you switch between EQ, app mixer, spatial audio, Audio Units and presets. Cream controls and small red indicators follow the original logo palette.

Under Presets, save or export your audio setup, associate a preset with an output or application, select one of five languages, and configure startup behavior:

  • Launch at login opens Melicum when you sign in.
  • Enable audio on launch separately enables the saved output. It is off by default; if the saved output is disconnected, processing stays off.
  • Language changes the interface immediately. English is the source language; Italian, French, German and Spanish are included.

Audio settings and presets are stored in ~/Library/Application Support/Melicum/settings.json. Language, startup and updater preferences are stored separately from audio presets. The user guide explains volume, EQ modes, app levels, effects, preset recall and all preferences.

Automatic update checks

Melicum checks for new stable GitHub releases automatically, approximately once a day by default. Configure this under Presets → Updates → Automatically check for updates. You can also select Check for Updates… in that panel, the Melicum menu or the menu bar panel.

Automatic checks do not silently install updates. Melicum asks before downloading and installing, preserves settings, and restores the physical output before quitting for installation. Sparkle verifies the signed feed, EdDSA archive signature and Apple code signing. Draft and prerelease versions are excluded from the stable update feed. Updating the app does not automatically replace the optional HAL component; when a release includes a component update, run its included Enable system volume… installer separately.

Disable and Quit close the taps and aggregate devices, restoring the previous output when available. Processing stops if the physical device disconnects, its sample rate changes, or macOS selects another output. Choose the desired output and enable audio again.

Features

FeatureImplementation
HDMI / DisplayPort volumeSoftware volume, mute, 0–12 dB boost, L/R balance, menu bar controls
Native system volumeOptional virtual output with bidirectional volume/mute synchronization and native volume keys
Basic EQBass, mid, and treble
Advanced EQ10 fixed bands
Expert EQUp to 64 filters with independent frequency, gain, Q, and bypass; bell, low/high shelf, low/high pass, notch, and band pass
Spectrum2,048-sample FFT of processed audio, displayed in 64 logarithmic bins
Peak protectionClamps output samples to ±0.98; this is not a true-peak limiter
App mixerSeparate taps for applications with custom volume, grouped by bundle identifier
Spatial audioOriginal stereo reverb with five room sizes and mid/side width adjustment
Audio UnitsChain of up to 12 installed effects compatible with stereo float PCM; generic parameter editor
AutoEQ importLocal ParametricEQ .txt files in Equalizer APO / REW format
Super presetsComplete settings snapshots, JSON import/export, output associations, and app-triggered recall
InterfaceFixed graphite, cream and red palette from the logo, lyre menu bar icon and quick controls, launch at login, five languages

This version supports mono/stereo PCM. Configure multichannel HDMI devices for two channels in Audio MIDI Setup. Dolby/DTS passthrough and protected streams unavailable to macOS process taps are unsupported. The online AutoEQ database and proprietary plugin interfaces are not included. Incompatible Audio Units cancel startup with an error; effects that fail during rendering are bypassed. Peak protection operates per stream, so the sum of multiple mixer streams can still exceed full scale.

Output presets are recalled when selecting an output in Melicum. App presets are recalled when the active playback application changes, preferring the foreground application and otherwise the first active application alphabetically. Changing the mixer or Audio Unit chain rebuilds the audio path and may briefly interrupt playback. Switching to Basic or Advanced EQ initializes that mode's bands; save a preset first to preserve an Expert configuration.

Building and testing

The optional system volume component builds on BlackHole, included as a submodule. Clone with:

git clone --recurse-submodules https://github.com/debba/melicum.git
swift test
./scripts/make-brand-icon.sh
./scripts/build-system-volume.sh
./scripts/build.sh
.build/release/Melicum --list-devices

To regenerate the documentation screenshots from the native views with isolated example data, run:

./scripts/make-screenshots.sh

The capture script uses a temporary test harness, starts no audio session and leaves personal audio settings untouched.

The system volume driver has its own C tests:

mkdir -p build
xcrun clang -std=c11 -fblocks Driver/Tests.c -framework CoreAudio -framework CoreFoundation -framework Accelerate -o build/driver-tests
./build/driver-tests

The app bundle is written to build/Melicum.app and signed locally with an ad hoc signature. To install it without administrator privileges, close the running app and use:

./scripts/install.sh

Releases

Pushing a v* tag, or running the Release workflow manually with a tag name, builds a universal Melicum.app on GitHub Actions. The workflow runs the tests, signs the app and the system volume driver with a Developer ID and the hardened runtime, notarizes and staples the app and the disk image, and attaches Melicum-<version>.dmg, Melicum-<version>.zip, appcast.xml, and SHA256SUMS.txt to a draft release. An identical copy named Melicum.dmg provides the website's direct download of the latest stable release. Tags with a - suffix are marked as prereleases. Publishing a stable release makes its signed appcast.xml available at the updater's latest-release URL; drafts and prereleases are not offered through that feed. CI build numbers use 1000 + github.run_number so they increase monotonically and remain above local development builds.

The workflow requires these repository secrets:

SecretContents
APPLE_CERTIFICATEBase64-encoded .p12 with the Developer ID Application certificate and private key
APPLE_CERTIFICATE_PASSWORDPassword of the .p12
APPLE_SIGNING_IDENTITYIdentity name, for example Developer ID Application: Name (TEAMID)
APPLE_API_ISSUERApp Store Connect API issuer ID
APPLE_API_KEYApp Store Connect API key ID
APPLE_API_KEY_CONTENTBase64-encoded .p8 API key
APPLE_INSTALLER_SIGNING_IDENTITYOptional. Developer ID Installer: Name (TEAMID) to sign the driver package; its certificate must be in the same .p12
SPARKLE_PRIVATE_KEYBase64 EdDSA private key exported by Sparkle's generate_keys tool. It must match SUPublicEDKey in Resources/Info.plist.

To reproduce a signed build locally, set MELICUM_SIGN_IDENTITY (and optionally MELICUM_INSTALLER_IDENTITY) before running the build scripts. MELICUM_ARCHS="arm64 x86_64" produces a universal binary.

An updated build may require macOS permissions to be approved again. Launch at login uses SMAppService and may require confirmation in System Settings.

The Swift tests cover gain, mute, balance, filter response, FFT, peak protection, interleaved/planar buffers, tap input selection, Audio Units, AutoEQ parsing, preset round trips, all five localizations, and isolation of live spectrum updates from editable controls. Driver/Tests.c covers output names, stable device identity, property validation, hidden startup, visibility notifications, heartbeat, owner validation, volume round trips, shutdown, heartbeat timeout, and unexpected owner exit. Automated tests do not replace listening on the physical output or validating macOS permissions.

On this Mac, manual checks verified actual audio through the virtual output to the selected DELL device, volume and mute synchronization in both directions, and restoration of the physical output when processing stops.

Audio routing and system volume

The optional component wraps BlackHole source pinned to commit 561d934c77a1fa64987e01ccabe890fed30e181f. It exposes a stereo output with standard volume/mute properties. Melicum captures application audio targeted at that output and forwards the processed signal to the selected physical device. The loopback input is unused. For fixed-volume outputs, master volume is applied in Melicum's DSP. For outputs with writable master or channel volume controls, the physical volume follows the virtual slider and DSP omits master attenuation, preserving the device's full volume range. Writable physical mute controls follow the virtual mute state. Stopping leaves these controls at the last requested level, so fallback playback uses that level as well.

The virtual device appears in the macOS output list only while Melicum is open and processing audio. Disabling audio or quitting restores the previous physical output and hides the virtual device. If the owner process exits unexpectedly or its heartbeat is missing for five seconds, the driver hides and disables the device so macOS can choose another output. The component stays installed between launches; updating an older component requires running the system volume installer included in the new app.

Routing follows Apple's Capturing system audio with Core Audio taps, local SDK headers, and the shared-clock aggregate model described by CoreAudioTapKit. The tap and physical output share a callback. The C callback uses preallocated memory and atomic controls; audio lifecycle and Audio Unit configuration run on a separate serial queue.

Visual identity

The original vector mark is a lyre drawn as an equalizer: the yoke is an EQ curve with three hollow nodes, the strings end on that curve, and the sound box has the profile of an HDMI receptacle. The name comes from the Latin melicus, "lyrical". Its "Vinyl and VU" palette pairs a graphite tile with cream and VU-needle red. SVG masters are in Resources/brand; Resources/AppIcon.icon supplies the native layered macOS icon, Resources/BrandIcon.png supplies the legacy icon, and Resources/BrandMark.png supplies the transparent header mark. Shared geometry in scripts/make-icon.swift generates the SVG and PNG artwork. See the identity notes.

License

Copyright © 2026 Andrea Debernardi.

Melicum and its modified BlackHole component are distributed under GPL-3.0. See LICENSE, ThirdParty/BlackHole/LICENSE, and Driver/UPSTREAM.md. Upstream source and license notices are preserved.

audio
audio-units
core-audio
displayport
equalizer
hdmi
mac
macos
menu-bar-app
per-app-volume
spatial-audio
swiftui
volume-control