(摘) Godot之音频可视化

声明:内容源自网络,版权归原作者所有。若有侵权请在网页聊天中联系我

最近忙着做一个项目,使用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)

相关文章