A native macOS audio player for musicians, built with Swift + AppKit.
Status: Early scaffolding. The architecture is in place; DSP wiring is in progress.
- Multi-format playback — anything the OS can't decode natively (Opus, WavPack, Musepack, …) via SFBAudioEngine.
- Waveform visualization — Metal-rendered, with on-disk overview cache.
- Section selection + looping — one or more regions, scheduled through
AVAudioPlayerNode. - High-quality pitch shifting & time stretching — Rubber Band Library (R3 "finer" engine) wrapped in a custom
AUAudioUnit. Cent-by-cent and semitone-by-semitone pitch, large stretch factors. - Graphic equalizer — multi-band, built on
AVAudioUnitEQ.
File → SFBAudioEngine decoder → AVAudioPCMBuffer
↓
AVAudioPlayerNode → RubberBandAU → AVAudioUnitEQ → MainMixer → Output
↓
Tap → Waveform / level meters
Stereo only. Real-time and offline pitch/time changes both supported (RT for live control, offline for highest-quality renders).
- macOS 26 (Tahoe) or later
- Xcode 17+
- Swift 6
open AudioLens.xcodeprojIf the .xcodeproj ever drifts from project.yml, regenerate it with XcodeGen:
brew install xcodegen
xcodegen generateMulti-format audio decoding (Opus, FLAC, Vorbis, WavPack, Musepack, Monkey's Audio, Shorten, True Audio, plus everything Core Audio handles natively). Add it through Xcode the first time you build:
- With
AudioLens.xcodeprojopen in Xcode: File → Add Package Dependencies… - Enter the URL
https://github.com/sbooth/SFBAudioEngine - Dependency Rule: Up to Next Major Version from the version Xcode pre-fills
(currently
0.12.x) - Add the
SFBAudioEngineproduct to the AudioLens target
Once added, import SFBAudioEngine in Audio/SFBAudioLoader.swift resolves and
the project builds.
Rubber Band Library provides the
R3 "Finer" engine for pitch shifting and time stretching. GPL-2.0-or-later
(compatible with this project's GPL-3.0). The source is vendored as a git
submodule and compiled in-tree by Packages/RubberBand — no Homebrew or
other system install needed, and the resulting .app is fully
self-contained.
Setup (one-time, after cloning):
git submodule update --init --recursiveThen in Xcode: File → Add Package Dependencies… → Add Local…, navigate
to Packages/RubberBand in this repo, and add the CRubberBand product
to the AudioLens target.
Audio/RubberBandStretcher.swift imports the C API via
#if canImport(CRubberBand), so the project still builds before the
package is added — the Rubber Band wrapper just isn't compiled in until
then.
GPL-3.0-or-later. See LICENSE.