添加回复用音频(文本转语音生成的)

语音会话添加play_reply方法实现播放回复
探索录音方式
This commit is contained in:
soul-walker 2024-05-09 20:05:07 +08:00
parent 6c8aa8ef80
commit 104a16955c
20 changed files with 169 additions and 96 deletions

View File

@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://dvvpoqb8umdjy"
path="res://.godot/imported/sd.mp3-c6dc8a540e4c3c58e60586436e316423.mp3str"
[deps]
source_file="res://Assets/training_speech/sd.mp3"
dest_files=["res://.godot/imported/sd.mp3-c6dc8a540e4c3c58e60586436e316423.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

Binary file not shown.

View File

@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://iqr672ekex01"
path="res://.godot/imported/xt_pslgbztmwx.mp3-c340c6f2fdc9b84c839f54346780b458.mp3str"
[deps]
source_file="res://Assets/training_speech/xt_pslgbztmwx.mp3"
dest_files=["res://.godot/imported/xt_pslgbztmwx.mp3-c340c6f2fdc9b84c839f54346780b458.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

Binary file not shown.

View File

@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://op4mbi1lemrb"
path="res://.godot/imported/xt_pslibpkmwx.mp3-165b8ea64f29779308cdddb6c9efb934.mp3str"
[deps]
source_file="res://Assets/training_speech/xt_pslibpkmwx.mp3"
dest_files=["res://.godot/imported/xt_pslibpkmwx.mp3-165b8ea64f29779308cdddb6c9efb934.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

Binary file not shown.

View File

@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://dr1m5h02s45jf"
path="res://.godot/imported/zby_ztmjczc.mp3-849bbce90b59ebabfadd754a0ccf691a.mp3str"
[deps]
source_file="res://Assets/training_speech/zby_ztmjczc.mp3"
dest_files=["res://.godot/imported/zby_ztmjczc.mp3-849bbce90b59ebabfadd754a0ccf691a.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

Binary file not shown.

View File

@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://b5wej2w00ttnj"
path="res://.godot/imported/zbzz_ckcjwb.mp3-3c85dcaed29528587c7e0c8e32ccee6b.mp3str"
[deps]
source_file="res://Assets/training_speech/zbzz_ckcjwb.mp3"
dest_files=["res://.godot/imported/zbzz_ckcjwb.mp3-3c85dcaed29528587c7e0c8e32ccee6b.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

View File

@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://bv1xfsb4450r1"
path="res://.godot/imported/zlgzmhfzc.mp3-02c91e6200e7ec22dcd1900223f9e0da.mp3str"
[deps]
source_file="res://Assets/training_speech/zlgzmhfzc.mp3"
dest_files=["res://.godot/imported/zlgzmhfzc.mp3-02c91e6200e7ec22dcd1900223f9e0da.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

View File

@ -1,19 +0,0 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://dvvpoqb8umdjy"
path="res://.godot/imported/shoudao.mp3-8e2429a197cf2b3306a67088ca44c2bf.mp3str"
[deps]
source_file="res://Communication/Assets/shoudao.mp3"
dest_files=["res://.godot/imported/shoudao.mp3-8e2429a197cf2b3306a67088ca44c2bf.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

View File

@ -1,19 +0,0 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://bv1xfsb4450r1"
path="res://.godot/imported/zhenglieguzhangmenhuifuzhengchang.mp3-e699f05501af2fc615013fe553302b4f.mp3str"
[deps]
source_file="res://Communication/Assets/zhenglieguzhangmenhuifuzhengchang.mp3"
dest_files=["res://.godot/imported/zhenglieguzhangmenhuifuzhengchang.mp3-e699f05501af2fc615013fe553302b4f.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

View File

@ -1,8 +1,9 @@
extends Node
## 录音效果器
var effect: AudioEffectRecord
var recording: AudioStreamWAV
var record_stream: AudioStreamWAV
## 录音捕获效果器(用于判断录音音量)
var capture: AudioEffectCapture
func _ready():
@ -11,9 +12,7 @@ func _ready():
# And use it to retrieve its first effect, which has been defined
# as an "AudioEffectRecord" resource.
effect = AudioServer.get_bus_effect(idx, 0)
record_stream = AudioStreamWAV.new()
startRecord()
capture = AudioServer.get_bus_effect(idx, 1)
## 启动录音
func startRecord():
@ -26,13 +25,38 @@ func stopRecord():
if effect.is_recording_active():
effect.set_recording_active(false)
var audio_sd = preload("res://Communication/Assets/shoudao.mp3")
var audio_zlgzmhfzc = preload("res://Communication/Assets/zhenglieguzhangmenhuifuzhengchang.mp3")
var audio_sd = preload("res://Assets/training_speech/sd.mp3")
var audio_zlgzmhfzc = preload("res://Assets/training_speech/zlgzmhfzc.mp3")
## 播放回复
## PS: 是协程函数外部可以await
func play_reply(reply):
stopRecord()
assert(reply is AudioStream, "reply不是音频资源")
## 确保不循环播放
if reply is AudioStreamMP3:
reply.loop = false
if reply is AudioStreamOggVorbis:
reply.loop = false
if reply is AudioStreamWAV:
reply.loop_mode = AudioStreamWAV.LOOP_DISABLED
$AudioStreamPlayer.stream = reply
$AudioStreamPlayer.play()
await $AudioStreamPlayer.finished
## 录音并语音识别检查
## PS: 是协程函数外部如果关心结果需await
func speech_record_check(keywords: Array[String]):
pass
func _on_timer_timeout():
if effect.is_recording_active():
var vdb = $AudioStreamRecord.get_volume_db()
print(vdb)
print(capture.get_buffer_length_frames(), ", ", capture.get_discarded_frames(), ", ", capture.get_frames_available())
var buf = capture.get_buffer(capture.get_frames_available())
for vec in buf:
if vec.x > 0.1 or vec.y > 0.1:
print("Left channel volume = ", vec.x, ", Right volume = ", vec.y)
#if effect.is_recording_active():
#recording = effect.get_recording()
#print(recording.data.size(), ", ", recording.format, ", ", recording.loop_mode, ", ", recording.get_length())

View File

@ -16,7 +16,7 @@ bus = &"Record"
autoplay = true
[node name="Timer" type="Timer" parent="."]
wait_time = 0.1
wait_time = 0.2
autostart = true
[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]

View File

@ -1,8 +1,12 @@
[gd_resource type="AudioBusLayout" load_steps=2 format=3 uid="uid://b4m2yc5k0re6f"]
[gd_resource type="AudioBusLayout" load_steps=3 format=3 uid="uid://b4m2yc5k0re6f"]
[sub_resource type="AudioEffectRecord" id="AudioEffectRecord_bjx8q"]
resource_name = "Record"
[sub_resource type="AudioEffectCapture" id="AudioEffectCapture_fxogc"]
resource_name = "Capture"
buffer_length = 1.0
[resource]
bus/1/name = &"Record"
bus/1/solo = false
@ -12,3 +16,5 @@ bus/1/volume_db = 0.0
bus/1/send = &"Master"
bus/1/effect/0/effect = SubResource("AudioEffectRecord_bjx8q")
bus/1/effect/0/enabled = true
bus/1/effect/1/effect = SubResource("AudioEffectCapture_fxogc")
bus/1/effect/1/enabled = true

View File

@ -1,8 +1,8 @@
[preset.0]
name="station_keys"
name="Web"
platform="Web"
runnable=false
runnable=true
dedicated_server=false
custom_features=""
export_filter="exclude"
@ -22,49 +22,7 @@ custom_template/release=""
variant/extensions_support=false
vram_texture_compression/for_desktop=true
vram_texture_compression/for_mobile=false
html/export_icon=true
html/custom_html_shell=""
html/head_include="<style>
body {
overflow: hidden;
}
</style>"
html/canvas_resize_policy=2
html/focus_canvas_on_start=true
html/experimental_virtual_keyboard=false
progressive_web_app/enabled=false
progressive_web_app/offline_page=""
progressive_web_app/display=1
progressive_web_app/orientation=0
progressive_web_app/icon_144x144=""
progressive_web_app/icon_180x180=""
progressive_web_app/icon_512x512=""
progressive_web_app/background_color=Color(0, 0, 0, 1)
[preset.1]
name="Web"
platform="Web"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="../export/total.html"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
[preset.1.options]
custom_template/debug=""
custom_template/release=""
variant/extensions_support=false
vram_texture_compression/for_desktop=true
vram_texture_compression/for_mobile=false
html/export_icon=true
html/export_icon=false
html/custom_html_shell=""
html/head_include=""
html/canvas_resize_policy=2

View File

@ -5,10 +5,16 @@ extends Node
## 场景描述
@export var trainingDesc: String = "场景描述"
var a_sd = preload("res://Assets/training_speech/sd.mp3")
var a_xt_pslgbztmwx = preload("res://Assets/training_speech/xt_pslgbztmwx.mp3")
var a_zby_ztmjczc = preload("res://Assets/training_speech/zby_ztmjczc.mp3")
func _ready():
$TrainingDescDialog.title = trainingName
$TrainingDescDialog.updateSceneDesc(trainingDesc)
func _on_training_desc_dialog_start_training():
pass # Replace with function body.
await $VoiceCommunication.play_reply(a_xt_pslgbztmwx)
await $VoiceCommunication.play_reply(a_zby_ztmjczc)
await $VoiceCommunication.play_reply(a_sd)

View File

@ -1,7 +1,8 @@
[gd_scene load_steps=3 format=3 uid="uid://dvsauaycyah6j"]
[gd_scene load_steps=4 format=3 uid="uid://dvsauaycyah6j"]
[ext_resource type="Script" path="res://trainings/training1.gd" id="1_71wgx"]
[ext_resource type="PackedScene" uid="uid://qh8b3g6n3k2u" path="res://trainings/training_desc_dialog.tscn" id="2_oc00d"]
[ext_resource type="PackedScene" uid="uid://6lortgihx5jy" path="res://Communication/voice_communication.tscn" id="3_ceo1a"]
[node name="Training1" type="Node"]
script = ExtResource("1_71wgx")
@ -11,4 +12,6 @@ trainingDesc = "列车关门作业,突发单个站台门未正常关闭。"
[node name="TrainingDescDialog" parent="." instance=ExtResource("2_oc00d")]
size = Vector2i(400, 300)
[node name="VoiceCommunication" parent="." instance=ExtResource("3_ceo1a")]
[connection signal="StartTraining" from="TrainingDescDialog" to="." method="_on_training_desc_dialog_start_training"]