{"id":50752681,"url":"https://github.com/altuzar/sonicflow","last_synced_at":"2026-06-11T02:30:22.134Z","repository":{"id":358302149,"uuid":"1240843196","full_name":"altuzar/sonicflow","owner":"altuzar","description":"Per-app volume for macOS, built with CoreAudio Process Taps","archived":false,"fork":false,"pushed_at":"2026-05-16T16:59:56.000Z","size":1668,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-16T18:47:10.341Z","etag":null,"topics":["audio","macos"],"latest_commit_sha":null,"homepage":"http://altuzar.github.io/sonicflow","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/altuzar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-16T16:31:50.000Z","updated_at":"2026-05-16T17:22:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/altuzar/sonicflow","commit_stats":null,"previous_names":["altuzar/sonicflow"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/altuzar/sonicflow","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altuzar%2Fsonicflow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altuzar%2Fsonicflow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altuzar%2Fsonicflow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altuzar%2Fsonicflow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/altuzar","download_url":"https://codeload.github.com/altuzar/sonicflow/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altuzar%2Fsonicflow/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34180147,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-11T02:00:06.485Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio","macos"],"created_at":"2026-06-11T02:30:20.949Z","updated_at":"2026-06-11T02:30:22.127Z","avatar_url":"https://github.com/altuzar.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"![SonicFlow — per-app volume for macOS](marketing/brand/lockup-banner.png)\n\n# SonicFlow\n\n\u003e Per-app volume for macOS. Finally.\n\nA free, open-source macOS menu bar app for **per-app volume control**.\nBuilt in Swift 6 with SwiftUI + CoreAudio Process Taps.\n\n[**Download v0.1**](https://github.com/altuzar/sonicflow/releases/latest) ·\n[**Landing**](https://altuzar.github.io/sonicflow) ·\n[**Roadmap**](ROADMAP.md) ·\n[**Marketing kit**](marketing/)\n\n---\n\n## What it does\n\n- 🎧 **Per-app audio detection** — every app currently producing audio shows\n  up live in the menu bar panel.\n- 🎚️ **Per-app volume slider** — adjust Music, Zoom, Chrome, Spotify\n  independently. Changes apply in ~10 ms via a realtime IOProc.\n- 🔇 **Click-to-mute** — tap any app's icon to mute it instantly.\n- 📢 **Auto-ducking** — when a communication app (Zoom, Teams, Slack)\n  actively outputs voice, other apps automatically lower by a configurable\n  amount (default 50 %).\n- 🎛️ **Master volume** — drives the macOS system volume; follows the\n  keyboard volume keys (F11/F12).\n- 🪟 **Menu bar only** — `LSUIElement = true`, no Dock icon, no window\n  on launch.\n- ⚡ **Low overhead** — \u003c 1 % CPU at idle, 1–2 % under realtime audio\n  processing.\n\n---\n\n## Architecture\n\nThree layered phases, each behind the `AudioEngine` protocol so the UI is\nunchanged across phases:\n\n```\n┌───────────────────────────────────────────────────────────────┐\n│ SwiftUI MenuBarExtra panel                                     │\n│   Observable AudioState → AppRowView · MasterControlView · …   │\n└───────────────────────────────────────────────────────────────┘\n                        ↑↓ any AudioEngine\n┌───────────────────────────────────────────────────────────────┐\n│ Phase 2: AudioProcessDetector                                  │\n│   • kAudioHardwarePropertyProcessObjectList                    │\n│   • kAudioProcessPropertyIsRunningOutput (piro) listener       │\n│   • 1 Hz fallback poll for HAL state-change latency            │\n└───────────────────────────────────────────────────────────────┘\n                                ↓\n┌───────────────────────────────────────────────────────────────┐\n│ Phase 3: AudioGainController (per-app real-time gain)          │\n│                                                                │\n│   ProcessTap (one per app, CATapMutedWhenTapped)               │\n│      ↓                                                         │\n│   AggregateOutputDevice (private, captures taps)               │\n│      IOProc: applies per-app gain, mixes stereo                │\n│      ↓                                                         │\n│   FloatRingBuffer (lock-free SPSC, 8192 samples)               │\n│      ↓                                                         │\n│   PlaybackDevice (IOProc on user's default output)             │\n│      adds to outputData → speakers                             │\n└───────────────────────────────────────────────────────────────┘\n```\n\nTapped apps' direct path to the speakers is silenced (`CATapMutedWhenTapped`)\nso we don't get double audio. Non-tapped apps flow through the system mixer\nunchanged.\n\n---\n\n## Build \u0026 run\n\nRequires **macOS 14.2+**, **Xcode 16+**, **Swift 6+**.\n\n```bash\nmake sign           # build → wrap in .app → ad-hoc sign\nopen build/SonicFlow.app   # launch as menu bar app\n```\n\nFor development:\n\n```bash\nmake debug          # debug build\nmake run            # build + sign + open\nmake icon           # regenerate AppIcon.icns from SVG\n```\n\n### Runtime flags\n\n| Flag | Effect |\n|---|---|\n| (none) | Production: Phase 3 enabled, menu bar only |\n| `--no-gain` | Disable Phase 3 (detection only) |\n| `--debug` | Verbose stats to stderr — HAL snapshots, frame counters |\n| `--preview` | Mock engine in a floating window (design work) |\n| `--preview-live` | Live engine in a floating window (useful when Ice hides the menu bar icon) |\n| `--test-gain-cycle` | Auto-cycle the first active app through 25 % / 100 % / mute / 100 % / 50 % every 3 s |\n\n---\n\n## Permissions\n\n- **AppleScript Automation** — for compatible apps (Music, Spotify, TV,\n  Podcasts), SonicFlow uses AppleScript to also move the app's own volume\n  slider. macOS will prompt \"SonicFlow wants to control X\" on first contact.\n- **System Audio Capture (TCC)** — process taps may require explicit grant\n  on macOS 14.4+ for system audio capture. The privacy string is in\n  `Info.plist`.\n- **No microphone permission requested** — the purple mic dot never appears.\n\n---\n\n## Project layout\n\n```\nsonicflow-app/\n├── Package.swift                    SwiftPM, macOS 14.2+, Swift 6\n├── Makefile                         build/sign/bundle helpers\n├── README.md / CLAUDE.md / ROADMAP.md\n├── Resources/Icon/                  AppIcon.svg → AppIcon.icns\n├── Sources/SonicFlow/\n│   ├── App/                         @main, AppDelegate, signal cleanup\n│   ├── Models/                      AudioApp, AudioState (@Observable)\n│   ├── Audio/                       Detector, Engine, GainController,\n│   │                                ProcessTap, AggregateOutputDevice,\n│   │                                PlaybackDevice, RingBuffer, …\n│   ├── Services/PermissionsManager  Accessibility hooks (future hotkeys)\n│   ├── UI/                          ControlCenterView, AppRowView,\n│   │                                FluidSlider, SettingsView, …\n│   └── Resources/Info.plist / SonicFlow.entitlements\n└── build/SonicFlow.app              output bundle (832 KB)\n```\n\n---\n\n## Honest status\n\n- ✅ **Phase 1 — UI mockup** — done\n- ✅ **Phase 2 — Live detection** — done, push + poll fallback\n- ✅ **Phase 3 — Real per-app gain** — done, two-IOProc + ring buffer\n- ⚠️ Not yet: real RMS meters from the IOProc, headphone hot-swap,\n  persistence between launches, Developer ID signing.\n- See [ROADMAP.md](ROADMAP.md) for the full open list.\n\n---\n\n## Acknowledgements\n\nInspired by the architecture used by SoundSource, BackgroundMusic, and\nsimilar pro audio utilities. CoreAudio Process Tap API by Apple (macOS\n14.2+).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faltuzar%2Fsonicflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faltuzar%2Fsonicflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faltuzar%2Fsonicflow/lists"}