forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAudioLevelMonitor.swift
More file actions
56 lines (48 loc) · 1.72 KB
/
Copy pathAudioLevelMonitor.swift
File metadata and controls
56 lines (48 loc) · 1.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import Combine
import Foundation
import QuartzCore
/// Dedicated monitor for audio levels that doesn't trigger global AppState re-renders.
/// Only views that explicitly observe this class will update when audio levels change.
/// Updates are throttled to ~5 Hz to avoid flooding SwiftUI with layout invalidations.
@MainActor
class AudioLevelMonitor: ObservableObject {
static let shared = AudioLevelMonitor()
/// Microphone audio level (0.0 - 1.0)
@Published private(set) var microphoneLevel: Float = 0.0
/// System audio level (0.0 - 1.0)
@Published private(set) var systemLevel: Float = 0.0
// Throttle: only publish at ~5 Hz (every ~200ms)
private let updateInterval: Double = 1.0 / 5.0
private var lastMicUpdate: Double = 0.0
private var lastSysUpdate: Double = 0.0
private var pendingMicLevel: Float = 0.0
private var pendingSysLevel: Float = 0.0
private init() {}
/// Update microphone level - called from audio capture callback.
/// Throttled to ~5 Hz to prevent excessive SwiftUI re-renders.
func updateMicrophoneLevel(_ level: Float) {
pendingMicLevel = level
let now = CACurrentMediaTime()
if now - lastMicUpdate >= updateInterval {
lastMicUpdate = now
microphoneLevel = level
}
}
/// Update system audio level - called from audio capture callback.
/// Throttled to ~5 Hz to prevent excessive SwiftUI re-renders.
func updateSystemLevel(_ level: Float) {
pendingSysLevel = level
let now = CACurrentMediaTime()
if now - lastSysUpdate >= updateInterval {
lastSysUpdate = now
systemLevel = level
}
}
/// Reset both levels to zero
func reset() {
microphoneLevel = 0.0
systemLevel = 0.0
pendingMicLevel = 0.0
pendingSysLevel = 0.0
}
}