最近忙着做一个项目,使用godot就比较少了。最新出了Godot4.0a版,始终关注中。也关注着它与XR(VR/AR)的发展。
这个示例将音频显示出来,Godot隐藏了一些细节,非常便于可视化。
extends Node2D
onready var spectrum = AudioServer.get_bus_effect_instance(0, 0)
var definition = 300
var total_w = 400
var total_h = 200
var min_freq = 10
var max_freq = 40000
var max_db = 140
var min_db = -140
var accel = 20
var histogram = []
func _ready():
OS.center_window()
total_w = OS.window_size.y
max_db += get_parent().volume_db
min_db += get_parent().volume_db
for i in range(definition):
histogram.append(0)
func _process(delta):
var freq = min_freq
var interval = (max_freq - min_freq) / definition
for i in range(definition):
var freqrange_low = float(freq - min_freq) / float(max_freq - min_freq)
freqrange_low = freqrange_low * freqrange_low * freqrange_low * freqrange_low
freqrange_low = lerp(min_freq, max_freq, freqrange_low)
freq += interval
var freqrange_high = float(freq - min_freq) / float(max_freq - min_freq)
freqrange_high = freqrange_high * freqrange_high * freqrange_high * freqrange_high
freqrange_high = lerp(min_freq, max_freq, freqrange_high)
var mag = spectrum.get_magnitude_for_frequency_range(freqrange_low, freqrange_high)
mag = linear2db(mag.length())
mag = (mag - min_db) / (max_db - min_db)
mag += 0.3 * (freq - min_freq) / (max_freq - min_freq)
mag = clamp(mag, 0.05, 1) # 限制value,并返回一个不小于min和不大于max的值.
histogram[i] = lerp(histogram[i], mag, accel * delta)
update()
func _draw():
# 水平效果
var draw_pos = Vector2(-100, -50)
var w_interval = total_w / definition
for i in range(definition):
draw_line(draw_pos, draw_pos + Vector2(0, -histogram[i] * total_h),Color(0.9,0.9,0.8,1), 1.0, true)
# 我在原示例上增加的效果,图中红色部份
myPoint(draw_pos+Vector2(0,-200),histogram[i] * total_h)
draw_pos.x += w_interval # 横向间隔
# 圆形效果
var angle = PI
var angle_interval = 2 * PI / definition
var radius = 80
var length = 150
for i in range(definition):
var normal = Vector2(0, -1).rotated(angle)
var start_pos = normal * radius
var end_pos = normal * (radius + histogram[i] * length)
draw_line(start_pos, end_pos, Color.dodgerblue, 1.0, true)
angle += angle_interval
func myPoint(pos: Vector2, height: int):
var p = float(height)
for i in range(height):
var m = i/p
draw_line(pos,pos+Vector2(0,-i),Color(1,0,0,1.0-m), 1.0)