diff --git a/audio/spectrum/project.godot b/audio/spectrum/project.godot index 4908fec4..d930459c 100644 --- a/audio/spectrum/project.godot +++ b/audio/spectrum/project.godot @@ -12,17 +12,17 @@ config_version=5 config/name="Audio Spectrum Demo" config/description="This is a demo showing how a spectrum analyzer can be built using Godot." +config/tags=PackedStringArray("audio", "demo", "official", "visualization") run/main_scene="res://show_spectrum.tscn" -config/features=PackedStringArray("4.0") +config/features=PackedStringArray("4.1") run/low_processor_mode=true config/icon="res://icon.webp" -config/tags=PackedStringArray("audio", "demo", "official", "visualization") [display] -window/vsync/vsync_mode=0 window/stretch/mode="canvas_items" window/stretch/aspect="expand" +window/vsync/vsync_mode=0 [rendering] diff --git a/audio/spectrum/show_spectrum.gd b/audio/spectrum/show_spectrum.gd index 9b8f35a6..3283a716 100644 --- a/audio/spectrum/show_spectrum.gd +++ b/audio/spectrum/show_spectrum.gd @@ -1,24 +1,27 @@ extends Node2D + const VU_COUNT = 16 const FREQ_MAX = 11050.0 const WIDTH = 800 const HEIGHT = 250 - +const HEIGHT_SCALE = 8.0 const MIN_DB = 60 +const ANIMATION_SPEED = 0.1 var spectrum +var min_values = [] +var max_values = [] + func _draw(): - @warning_ignore("integer_division") var w = WIDTH / VU_COUNT - var prev_hz = 0 - for i in range(1, VU_COUNT + 1): - var hz = i * FREQ_MAX / VU_COUNT - var magnitude = spectrum.get_magnitude_for_frequency_range(prev_hz, hz).length() - var energy = clampf((MIN_DB + linear_to_db(magnitude)) / MIN_DB, 0, 1) - var height = energy * HEIGHT + for i in range(VU_COUNT): + var min_height = min_values[i] + var max_height = max_values[i] + var height = lerp(min_height, max_height, ANIMATION_SPEED) + draw_rect( Rect2(w * i, HEIGHT - height, w - 2, height), Color.from_hsv(float(VU_COUNT * 0.6 + i * 0.5) / VU_COUNT, 0.5, 0.6) @@ -44,13 +47,35 @@ func _draw(): true ) - prev_hz = hz - func _process(_delta): + var data = [] + var prev_hz = 0 + + for i in range(1, VU_COUNT + 1): + var hz = i * FREQ_MAX / VU_COUNT + var magnitude = spectrum.get_magnitude_for_frequency_range(prev_hz, hz).length() + var energy = clampf((MIN_DB + linear_to_db(magnitude)) / MIN_DB, 0, 1) + var height = energy * HEIGHT * HEIGHT_SCALE + data.append(height) + prev_hz = hz + + for i in range(VU_COUNT): + if data[i] > max_values[i]: + max_values[i] = data[i] + else: + max_values[i] = lerp(max_values[i], data[i], ANIMATION_SPEED) + + if data[i] <= 0.0: + min_values[i] = lerp(min_values[i], 0.0, ANIMATION_SPEED) + # Sound plays back continuously, so the graph needs to be updated every frame. queue_redraw() func _ready(): spectrum = AudioServer.get_bus_effect_instance(0, 0) + min_values.resize(VU_COUNT) + max_values.resize(VU_COUNT) + min_values.fill(0.0) + max_values.fill(0.0)