a22c238dc4
A complete audio-reactive visualizer for psytrance music featuring: Audio Analysis (DSPEngine): - FFT spectrum analysis via Accelerate/vDSP - 64-band Mel spectrogram - Sub-bass energy extraction (<100Hz) - Automatic sidechain pump detection - Harmonic-to-Noise ratio (HNR) calculation - Peak/transient detection 8 Visualization Modes (Metal Shaders): 1. FFT Classic - Frequency spectrum bars with glow 2. Mel Spectrogram - Waterfall display 3. Sub-Bass - Pulsating rings 4. Sidechain Pump - Breathing zoom effect 5. Harmonic/Noise - Geometric vs chaotic particles 6. Mandelbrot - Audio-reactive fractal zoom 7. Tunnel Warp - Infinite tunnel with distortion 8. DMT Geometry - Sacred geometry patterns Features: - Selectable audio input device (BlackHole support) - Configurable buffer size (512/1024) - Reactivity slider for visual intensity - Auto-hiding control panel - Fullscreen support with keyboard shortcuts (1-8, F, ESC) - Persistent settings via UserDefaults - Psytrance-inspired neon/UV color palette
121 lines
3.6 KiB
Swift
121 lines
3.6 KiB
Swift
//
|
|
// AppDelegate.swift
|
|
// PsytranceVisualizer
|
|
//
|
|
// Application delegate handling app lifecycle
|
|
//
|
|
|
|
import AppKit
|
|
import AVFoundation
|
|
|
|
/// Application delegate
|
|
final class AppDelegate: NSObject, NSApplicationDelegate {
|
|
// MARK: - Properties
|
|
|
|
private var mainWindowController: MainWindowController?
|
|
|
|
// MARK: - App Lifecycle
|
|
|
|
func applicationDidFinishLaunching(_ notification: Notification) {
|
|
// Request microphone permission
|
|
requestMicrophonePermission()
|
|
|
|
// Create and show main window
|
|
mainWindowController = MainWindowController()
|
|
mainWindowController?.showWindow(nil)
|
|
mainWindowController?.window?.makeKeyAndOrderFront(nil)
|
|
|
|
// Activate the application
|
|
NSApp.activate(ignoringOtherApps: true)
|
|
|
|
print("[AppDelegate] Application launched")
|
|
}
|
|
|
|
func applicationWillTerminate(_ notification: Notification) {
|
|
// Save settings
|
|
SettingsManager.shared.saveNow()
|
|
|
|
print("[AppDelegate] Application terminating")
|
|
}
|
|
|
|
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
|
return true
|
|
}
|
|
|
|
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
|
|
return true
|
|
}
|
|
|
|
// MARK: - Permissions
|
|
|
|
private func requestMicrophonePermission() {
|
|
switch AVCaptureDevice.authorizationStatus(for: .audio) {
|
|
case .authorized:
|
|
print("[AppDelegate] Microphone access already authorized")
|
|
|
|
case .notDetermined:
|
|
AVCaptureDevice.requestAccess(for: .audio) { granted in
|
|
if granted {
|
|
print("[AppDelegate] Microphone access granted")
|
|
} else {
|
|
print("[AppDelegate] Microphone access denied")
|
|
self.showMicrophonePermissionAlert()
|
|
}
|
|
}
|
|
|
|
case .denied, .restricted:
|
|
print("[AppDelegate] Microphone access denied or restricted")
|
|
showMicrophonePermissionAlert()
|
|
|
|
@unknown default:
|
|
break
|
|
}
|
|
}
|
|
|
|
private func showMicrophonePermissionAlert() {
|
|
DispatchQueue.main.async {
|
|
let alert = NSAlert()
|
|
alert.messageText = "Microphone Access Required"
|
|
alert.informativeText = "Psytrance Visualizer needs access to your audio input to visualize music. Please enable microphone access in System Preferences > Security & Privacy > Privacy > Microphone."
|
|
alert.alertStyle = .warning
|
|
alert.addButton(withTitle: "Open System Preferences")
|
|
alert.addButton(withTitle: "Cancel")
|
|
|
|
if alert.runModal() == .alertFirstButtonReturn {
|
|
if let url = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone") {
|
|
NSWorkspace.shared.open(url)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Menu Actions
|
|
|
|
@IBAction func showAbout(_ sender: Any) {
|
|
let alert = NSAlert()
|
|
alert.messageText = "Psytrance Visualizer"
|
|
alert.informativeText = """
|
|
An audio-reactive visualizer for psytrance music.
|
|
|
|
8 Visualization Modes:
|
|
1 - FFT Classic
|
|
2 - Mel Spectrogram
|
|
3 - Sub-Bass
|
|
4 - Sidechain Pump
|
|
5 - Harmonic/Noise
|
|
6 - Mandelbrot
|
|
7 - Tunnel Warp
|
|
8 - DMT Geometry
|
|
|
|
Keyboard Shortcuts:
|
|
1-8: Switch visualization mode
|
|
F: Toggle fullscreen
|
|
ESC: Exit fullscreen
|
|
|
|
Tip: Use a virtual audio device like BlackHole to route system audio.
|
|
"""
|
|
alert.alertStyle = .informational
|
|
alert.runModal()
|
|
}
|
|
}
|