@@ -365,27 +365,58 @@ public struct OrbVisualizer: View {
365365 self . agentState = agentState
366366 self . colors = colors
367367
368- _inputProcessor = StateObject ( wrappedValue: AudioProcessor ( track: inputTrack, bandCount: 1 ) )
369- _outputProcessor = StateObject ( wrappedValue: AudioProcessor ( track: outputTrack, bandCount: 1 ) )
368+ _inputProcessor = StateObject ( wrappedValue: AudioProcessor ( track: inputTrack, bandCount: 7 ) )
369+ _outputProcessor = StateObject ( wrappedValue: AudioProcessor ( track: outputTrack, bandCount: 7 ) )
370370 }
371371
372372 public var body : some View {
373373 GeometryReader { geometry in
374- let inputVolume = inputProcessor. bands. first ?? 0
375- let outputVolume = outputProcessor. bands. first ?? 0
374+ let inputVolume = aggregateVolume ( from : inputProcessor. bands)
375+ let outputVolume = aggregateVolume ( from : outputProcessor. bands)
376376
377- // Override input volume to 1.0 when thinking
378377 let effectiveInputVolume = agentState == . thinking ? 1.0 : Float ( inputVolume)
379378
380379 Orb ( color1: colors. 0 ,
381380 color2: colors. 1 ,
382- inputVolume: effectiveInputVolume ,
381+ inputVolume: Float ( inputVolume ) ,
383382 outputVolume: Float ( outputVolume) ,
384383 agentState: agentState)
385384 . frame ( width: geometry. size. width, height: geometry. size. height)
386385 }
387386 . aspectRatio ( 1 , contentMode: . fit)
388387 }
388+
389+ /// Aggregates multiple frequency bands into a single volume value with intelligent weighting.
390+ /// Emphasizes mid-range frequencies where most speech and music energy is located.
391+ private func aggregateVolume( from bands: [ Float ] ) -> Float {
392+ guard !bands. isEmpty else { return 0.0 }
393+
394+ // Frequency weights: emphasize mid-range (indices 2-4) for speech/music
395+ // Lower weights for bass (0-1) and treble (5-6) frequencies
396+ let weights : [ Float ] = [ 1 , 1 , 1 , 1 , 1 , 1.0 , 1.0 ]
397+
398+ var weightedSum : Float = 0.0
399+ var totalWeight : Float = 0.0
400+
401+ for (index, band) in bands. enumerated ( ) {
402+ let weight = index < weights. count ? weights [ index] : 1.0
403+ weightedSum += band * weight
404+ totalWeight += weight
405+ }
406+
407+ // Calculate weighted average and apply slight amplification for better responsiveness
408+ let weightedAverage = totalWeight > 0 ? weightedSum / totalWeight : 0.0
409+
410+ // Apply a more aggressive power curve and amplification for better responsiveness
411+ // Use a lower power (0.6) to make quiet sounds more visible, and higher amplification (1.8)
412+ let enhanced = pow ( weightedAverage, 0.6 ) * 1.8
413+
414+ // Add a small baseline to ensure some movement even with quiet audio
415+ let withBaseline = enhanced + 0.05
416+
417+ // Clamp to valid range
418+ return min ( max ( withBaseline, 0.0 ) , 1.0 )
419+ }
389420}
390421
391422#if DEBUG
0 commit comments