66 lines
2.1 KiB
GDScript
66 lines
2.1 KiB
GDScript
extends Control
|
|
|
|
@export var audio_player: AudioStreamPlayer
|
|
|
|
var spectrum_instance
|
|
const NUM_BARS = 64 # Number of frequency bands to display
|
|
const MAX_FREQ = 1000 # Frequency range to analyze
|
|
var bars = []
|
|
@export var shuffle_freq = false
|
|
@export var flip_y = false
|
|
|
|
var color_gradient := Gradient.new() # Dynamic color transitions
|
|
|
|
|
|
func _ready():
|
|
position = Vector2(0, get_viewport_rect().size.y - 150)
|
|
# Set up color gradient (Blue → Purple → Red)
|
|
scale = Vector2(1.5, 1.5)
|
|
color_gradient.add_point(0.0, Color(0.2, 1.0, 0.8)) # Cyan
|
|
color_gradient.add_point(0.5, Color(0.6, 0.2, 1.0)) # Purple
|
|
color_gradient.add_point(1.0, Color(1.0, 0.2, 0.2)) # Red
|
|
spectrum_instance = AudioServer.get_bus_effect_instance(1, 0) # Bus 1, Effect 0
|
|
create_bars()
|
|
|
|
func create_bars():
|
|
for i in range(NUM_BARS):
|
|
var bar = ColorRect.new()
|
|
bar.color = Color(0.2, 0.8, 1.0)
|
|
|
|
# Set anchors so position/size are relative to top-left
|
|
bar.set_anchors_preset(Control.PRESET_BOTTOM_LEFT)
|
|
|
|
# Position each bar starting from the bottom left
|
|
bar.rect_position = Vector2(i * 10, 0) # X is offset, Y = 0 at bottom
|
|
bar.rect_size = Vector2(8, 1) # Start with a minimal height
|
|
|
|
add_child(bar)
|
|
bars.append(bar)
|
|
|
|
func _process(delta):
|
|
if not spectrum_instance:
|
|
return
|
|
var max_freq_amp = bars.reduce(func(m, b): return b if b.rect_size.y > m.rect_size.y else m).rect_size.y
|
|
|
|
for i in range(NUM_BARS):
|
|
var freq_start = (i * MAX_FREQ) / NUM_BARS
|
|
var freq_end = ((i + 1) * MAX_FREQ) / NUM_BARS
|
|
var magnitude = spectrum_instance.get_magnitude_for_frequency_range(freq_start, freq_end).length()
|
|
var target_height = magnitude * 1000 * 2
|
|
bars[i].rect_size.y = lerp(bars[i].rect_size.y, target_height, 0.2)
|
|
bars[i].rect_position.y = -bars[i].rect_size.y # Move bar so it grows upward
|
|
# Smooth animation
|
|
|
|
var intensity = bars[i].rect_size.y / (max_freq_amp * 1.0) if max_freq_amp > 0 else 0.0
|
|
# intensity *= 1000
|
|
intensity = clamp(intensity, 0.0, 1.0) # Keep within valid range
|
|
|
|
# Get dynamic color from gradient
|
|
var new_color = color_gradient.sample(intensity)
|
|
bars[i].color = new_color
|
|
if flip_y:
|
|
bars[i].scale.y = -1
|
|
|
|
if shuffle_freq:
|
|
bars.shuffle()
|
|
|