89 lines
4.0 KiB
GDScript
89 lines
4.0 KiB
GDScript
# audio_miles_test —— MilesLib SoundManager 对齐回归。
|
|
# 验证 40250 的缩放、音量曲线和角色音效限频/距离规则。
|
|
extends SceneTree
|
|
|
|
const Audio = preload("res://audio.gd")
|
|
|
|
var _fail := 0
|
|
|
|
func _ck(condition: bool, message: String) -> void:
|
|
if not condition:
|
|
_fail += 1
|
|
printerr("FAIL: " + message)
|
|
|
|
func _init() -> void:
|
|
var audio := Audio.new()
|
|
get_root().add_child(audio)
|
|
|
|
_ck(is_equal_approx(Audio.SOUND_SCALE, 200.0), "sound scale is 200")
|
|
_ck(is_equal_approx(Audio.AMBIENCE_SOUND_SCALE, 1000.0), "ambience scale is 1000")
|
|
_ck(is_equal_approx(Audio.ratio_to_apply_volume(0.05), 0.05), "low ratio stays linear")
|
|
_ck(is_equal_approx(Audio.ratio_to_apply_volume(0.5), pow(10.0, -0.5)),
|
|
"ratio volume uses ClientVS22 logarithmic curve")
|
|
_ck(is_equal_approx(Audio.grade_to_apply_volume(5), 1.0), "grade 5 maps to full volume")
|
|
_ck(is_equal_approx(Audio.grade_to_apply_volume(0), 0.0), "grade 0 maps to silence")
|
|
|
|
audio.set_sound_scale(320.0)
|
|
audio.set_ambience_sound_scale(1200.0)
|
|
_ck(is_equal_approx(audio.get_sound_scale(), 320.0), "sound scale setter")
|
|
_ck(is_equal_approx(audio.get_ambience_sound_scale(), 1200.0), "ambience scale setter")
|
|
audio.set_listener(Vector3.ZERO, Vector3(0, 0, -1), Vector3.UP)
|
|
var assets := AssetRoot.path()
|
|
if DirAccess.dir_exists_absolute(assets):
|
|
audio.setup(assets)
|
|
var mss := assets.path_join("sound_m/sound/pc/warrior/general/run.mss")
|
|
if FileAccess.file_exists(mss):
|
|
var data: Array = audio.load_sound_information_piece(mss)
|
|
_ck(data.size() == 3, ".mss SoundDataCount and records parse")
|
|
_ck(is_equal_approx(float(data[0]["time"]), 0.759), ".mss preserves event time")
|
|
_ck(String(data[0]["sound"]) == "sound/common/walk_dirt_n.wav",
|
|
".mss preserves virtual sound path")
|
|
var instances: Array = audio.data_to_sound_instances(data)
|
|
_ck(int(instances[0]["frame"]) == 45 and int(instances[2]["frame"]) == 11,
|
|
".mss time converts to DWORD 60 FPS frames")
|
|
_ck(audio._find_sound(String(data[0]["sound"])) != "",
|
|
"virtual sound/ prefix resolves inside mounted sound root")
|
|
var motion := assets.path_join("PC/ymir work/pc/warrior/general/run.msa")
|
|
var motion_instances: Array = audio.load_mss_for_motion(motion)
|
|
_ck(motion_instances.size() == 3, "motion .msa resolves paired .mss")
|
|
var ambience := [{
|
|
"key": "waterfall-test",
|
|
"position": Vector3(20, 0, 0),
|
|
"range_cm": 3300,
|
|
"max_volume_area_percentage": 0.5,
|
|
"play_type": "LOOP",
|
|
"sounds": ["sound/ambience/warp_test.mp3"],
|
|
}]
|
|
audio.update_ambience_sources(ambience)
|
|
var ambience_state: Dictionary = audio._ambience_states.get("waterfall-test", {})
|
|
var ambience_id := int(ambience_state.get("id", -1))
|
|
_ck(ambience_id >= 0 and audio._active_3d.has(ambience_id),
|
|
"area ambience LOOP creates a Miles 3D instance")
|
|
if ambience_id >= 0 and audio._active_3d.has(ambience_id):
|
|
var ambience_player: AudioStreamPlayer3D = audio._active_3d[ambience_id]
|
|
_ck(abs(ambience_player.position.x - (20.0 * 100.0 / 1200.0)) < 0.001,
|
|
"ambience source uses cm -> ambience scale conversion")
|
|
audio.update_ambience_sources([])
|
|
_ck(not audio._ambience_states.has("waterfall-test") and not audio._active_3d.has(ambience_id),
|
|
"leaving / unloading area ambience stops its loop")
|
|
_ck(audio.can_play_character_sound("step.wav", Vector3(1, 0, 0), 10.0),
|
|
"near character sound is allowed")
|
|
_ck(not audio.can_play_character_sound("step.wav", Vector3(1, 0, 0), 10.2),
|
|
"same character sound is suppressed within 0.3 seconds")
|
|
_ck(audio.can_play_character_sound("step.wav", Vector3(1, 0, 0), 10.31),
|
|
"same character sound resumes after 0.3 seconds")
|
|
_ck(not audio.can_play_character_sound("far.wav", Vector3(51, 0, 0), 20.0),
|
|
"character sound beyond 5000cm is suppressed")
|
|
|
|
audio.set_sound_volume(0.0)
|
|
_ck(is_equal_approx(audio.master_sfx, 0.0), "sound volume setter accepts silence")
|
|
audio.stop_all_sound_3d()
|
|
audio.free()
|
|
|
|
if _fail == 0:
|
|
print("PASS: audio_miles_test (scale + volume curve + character sound guard)")
|
|
quit(0)
|
|
else:
|
|
printerr("%d check(s) failed" % _fail)
|
|
quit(1)
|