diff --git a/LICENSE b/LICENSE index 2b1823e..7ac87da 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019-2020 Cas Brugman +Copyright (c) 2019-2021 Cas Brugman Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index abeff06..5564759 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,12 @@ [⮩View in Godot Asset Library](https://godotengine.org/asset-library/asset/425) ->previously godot-voip-demo # Godot VoIP 🎤📡 ![logo](https://raw.githubusercontent.com/casbrugman/godot-voip/master/icon.png "Logo") -Godot-voip is a Godot addon (currently only 3.2) which makes it very easy to setup a voip system in your Godot game. This addon also includes a demo project. +Godot-voip is a Godot addon which makes it very easy to setup a real time voice chat system in your Godot game. This addon also includes a demo project. + +## Compatibility +* 2.0: Godot 3.2 +* 3.0: from Godot 3.2.4 ## Setup @@ -21,7 +24,3 @@ Godot-voip is a Godot addon (currently only 3.2) which makes it very easy to set ### Running demo 1. Go to the [Godot Asset Library](https://godotengine.org/asset-library/asset/425) to download the latest release, or you can clone/download this repository to get the latest commit. 2. Open downloaded project. - -## Issues - -In this current implementation there are issues with latency and interruptions. This is because the native way access to the microphone audio is handled. Sadly it is up to engine development to improve this. diff --git a/addons/godot-voip/demo/Demo.tscn b/addons/godot-voip/demo/Demo.tscn index a19c97e..e7fed10 100644 --- a/addons/godot-voip/demo/Demo.tscn +++ b/addons/godot-voip/demo/Demo.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=5 format=2] [ext_resource path="res://addons/godot-voip/scripts/voip_instance.gd" type="Script" id=1] [ext_resource path="res://addons/godot-voip/demo/Network.gd" type="Script" id=2] @@ -6,9 +6,26 @@ [sub_resource type="GDScript" id=1] script/source = "extends Control +onready var buttonServer: Button = $MarginContainer/HBoxContainer/VBoxContainer/Server +onready var buttonClient: Button = $MarginContainer/HBoxContainer/VBoxContainer/Client +onready var buttonVoice : Button = $MarginContainer/HBoxContainer/VBoxContainer/Voice + +onready var spinBoxHostPort: SpinBox = $MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/Port +onready var lineEditClientIp: LineEdit = $MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer1/Ip +onready var spinBoxClientPort: SpinBox = $MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer3/Port +onready var checkboxListen: CheckBox = $MarginContainer/HBoxContainer/VBoxContainer/Listen +onready var sliderInputThreshold: HSlider = $MarginContainer/HBoxContainer/VBoxContainer/InputThreshold + +onready var labelStatus: Label = $MarginContainer/HBoxContainer/VBoxContainer2/Status +onready var labelLog: Label = $MarginContainer/HBoxContainer/VBoxContainer2/ScrollContainer/Log +onready var spinBoxInputThreshold: SpinBox = $MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/Value + +onready var voip: VoipInstance = $VoipInstance +onready var network: Network = $Network + func _ready(): - $VoipInstance.connect(\"received_voice_data\", self, \"_received_voice_data\") - $VoipInstance.connect(\"send_voice_data\", self, \"_send_voice_data\") + voip.connect(\"received_voice_data\", self, \"_received_voice_data\") + voip.connect(\"send_voice_data\", self, \"_send_voice_data\") get_tree().connect(\"connected_to_server\", self, \"_connected_ok\") get_tree().connect(\"server_disconnected\", self, \"_server_disconnected\") @@ -17,53 +34,105 @@ func _ready(): get_tree().connect(\"network_peer_connected\", self, \"_player_connected\") get_tree().connect(\"network_peer_disconnected\", self, \"_player_disconnected\") + spinBoxHostPort.value = network.server_port + lineEditClientIp.text = network.server_ip + spinBoxClientPort.value = network.server_port + sliderInputThreshold.value = voip.input_threshold + func _on_Button_server_pressed() -> void: - var err = $Network.start_server() + var err = network.start_server() if err != OK: - $Status.text = \"Failed to create server!\" + labelStatus.text = \"Failed to create server!\" - $Status.text = \"server started\" - $Button_server.disabled = true - $Button_client.disabled = true - $Button_voice.disabled = false + labelStatus.text = \"server started\" + buttonServer.disabled = true + buttonClient.disabled = true + buttonVoice.disabled = false + checkboxListen.disabled = false + sliderInputThreshold.editable = true + spinBoxInputThreshold.editable = true + spinBoxHostPort.editable = false + lineEditClientIp.editable = false + spinBoxClientPort.editable = false func _on_Button_client_pressed() -> void: - var err = $Network.start_client() + var err = network.start_client() if err != OK: - $Status.text = \"failed to create client!\" + labelStatus.text = \"failed to create client!\" - $Status.text = \"Connecting...\" - $Button_server.disabled = true - $Button_client.disabled = true - $Button_voice.disabled = false + labelStatus.text = \"Connecting...\" func _on_Button_voice_button_down() -> void: - $VoipInstance.recording = true + voip.recording = true func _on_Button_voice_button_up() -> void: - $VoipInstance.recording = false + voip.recording = false + +func _on_Listen_toggled(button_pressed: bool) -> void: + voip.listen = button_pressed + +func _on_InputThreshold_value_changed(value: float) -> void: + voip.input_threshold = value + spinBoxInputThreshold.value = value + +func _on_Value_value_changed(value: float) -> void: + sliderInputThreshold.value = value + +func _on_Port_value_changed(value: float) -> void: + network.server_port = int(value) + +func _on_Ip_text_changed(new_text: String) -> void: + network.server_ip = new_text func _connected_ok(): - $Status.text = \"Connected ok\" + labelStatus.text = \"Connected ok\" + + buttonServer.disabled = true + buttonClient.disabled = true + buttonVoice.disabled = false + checkboxListen.disabled = false + sliderInputThreshold.editable = true + spinBoxInputThreshold.editable = true + spinBoxHostPort.editable = false + lineEditClientIp.editable = false + spinBoxClientPort.editable = false func _connected_fail(): - $Status.text = \"Failed to connect to server!\" + labelStatus.text = \"Failed to connect to server!\" func _server_disconnected(): - $Status.text = \"Server disconnected\" + labelStatus.text = \"Server disconnected\" + buttonServer.disabled = false + buttonClient.disabled = false + buttonVoice.disabled = true + checkboxListen.disabled = true + buttonVoice.pressed = false + sliderInputThreshold.editable = false + spinBoxInputThreshold.editable = false + spinBoxHostPort.editable = true + lineEditClientIp.editable = true + spinBoxClientPort.editable = true func _player_connected(_id): - $Log.text += \"Player with id: %s connected\\n\" % _id + labelLog.text += \"Player with id: %s connected\\n\" % _id func _player_disconnected(_id): - $Log.text += \"Player with id: %s disconnected\\n\" % _id + labelLog.text += \"Player with id: %s disconnected\\n\" % _id + +func _received_voice_data(data: PoolRealArray, id: int): + labelLog.text += \"received voice data of size:%s from id:%s\\n\" % [data.size(), id] + +func _send_voice_data(data: PoolRealArray): + labelLog.text += \"send voice data of size:%s\\n\" % data.size() + +" -func _received_voice_data(data: PoolByteArray, id: int): - $Log.text += \"received voice data of size:%s from id:%s\\n\" % [data.size(), id] +[sub_resource type="GDScript" id=2] +script/source = "extends ScrollContainer -func _send_voice_data(data: PoolByteArray): - $Log.text += \"send voice data of size:%s\\n\" % data.size() +func _on_Log_resized() -> void: + scroll_vertical = $Log.rect_size.y " [node name="Demo" type="Control"] @@ -77,59 +146,237 @@ __meta__ = { [node name="Network" type="Node" parent="."] script = ExtResource( 2 ) -[node name="Button_server" type="Button" parent="."] -margin_left = 46.3451 -margin_top = 44.2765 -margin_right = 173.345 -margin_bottom = 64.2765 +[node name="VoipInstance" type="Node" parent="."] +script = ExtResource( 1 ) + +[node name="MarginContainer" type="MarginContainer" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +custom_constants/margin_right = 50 +custom_constants/margin_top = 50 +custom_constants/margin_left = 50 +custom_constants/margin_bottom = 50 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"] +margin_left = 50.0 +margin_top = 50.0 +margin_right = 974.0 +margin_bottom = 550.0 +custom_constants/separation = 50 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HBoxContainer"] +margin_right = 250.0 +margin_bottom = 500.0 +rect_min_size = Vector2( 250, 0 ) +custom_constants/separation = 10 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Server" type="Button" parent="MarginContainer/HBoxContainer/VBoxContainer"] +margin_right = 250.0 +margin_bottom = 20.0 text = "Start server" __meta__ = { "_edit_use_anchors_": false } -[node name="Button_client" type="Button" parent="."] -margin_left = 46.3451 -margin_top = 80.0 -margin_right = 173.345 -margin_bottom = 100.0 +[node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/HBoxContainer/VBoxContainer"] +margin_top = 30.0 +margin_right = 250.0 +margin_bottom = 54.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Label" type="Label" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2"] +margin_top = 5.0 +margin_right = 64.0 +margin_bottom = 19.0 +text = "Host port:" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Port" type="SpinBox" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2"] +margin_left = 68.0 +margin_right = 250.0 +margin_bottom = 24.0 +size_flags_horizontal = 3 +max_value = 65535.0 +rounded = true +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="HSeparator" type="HSeparator" parent="MarginContainer/HBoxContainer/VBoxContainer"] +margin_top = 64.0 +margin_right = 250.0 +margin_bottom = 68.0 + +[node name="Client" type="Button" parent="MarginContainer/HBoxContainer/VBoxContainer"] +margin_top = 78.0 +margin_right = 250.0 +margin_bottom = 98.0 text = "Start client" __meta__ = { "_edit_use_anchors_": false } -[node name="Button_voice" type="Button" parent="."] -margin_left = 46.3451 -margin_top = 160.0 -margin_right = 173.345 +[node name="HBoxContainer1" type="HBoxContainer" parent="MarginContainer/HBoxContainer/VBoxContainer"] +margin_top = 108.0 +margin_right = 250.0 +margin_bottom = 132.0 + +[node name="Label2" type="Label" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer1"] +margin_top = 5.0 +margin_right = 60.0 +margin_bottom = 19.0 +text = "Server ip:" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Ip" type="LineEdit" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer1"] +margin_left = 64.0 +margin_right = 250.0 +margin_bottom = 24.0 +size_flags_horizontal = 3 +text = "127.0.0.1" + +[node name="HBoxContainer3" type="HBoxContainer" parent="MarginContainer/HBoxContainer/VBoxContainer"] +margin_top = 142.0 +margin_right = 250.0 +margin_bottom = 166.0 + +[node name="Label2" type="Label" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer3"] +margin_top = 5.0 +margin_right = 74.0 +margin_bottom = 19.0 +text = "Server port:" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Port" type="SpinBox" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer3"] +margin_left = 78.0 +margin_right = 250.0 +margin_bottom = 24.0 +size_flags_horizontal = 3 +max_value = 65535.0 +rounded = true +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="HSeparator2" type="HSeparator" parent="MarginContainer/HBoxContainer/VBoxContainer"] +margin_top = 176.0 +margin_right = 250.0 margin_bottom = 180.0 + +[node name="Listen" type="CheckBox" parent="MarginContainer/HBoxContainer/VBoxContainer"] +margin_top = 190.0 +margin_right = 250.0 +margin_bottom = 214.0 +disabled = true +text = "Listen" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/HBoxContainer/VBoxContainer"] +margin_top = 224.0 +margin_right = 250.0 +margin_bottom = 248.0 + +[node name="Label" type="Label" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer"] +margin_top = 5.0 +margin_right = 103.0 +margin_bottom = 19.0 +text = "Input threshold:" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Value" type="SpinBox" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer"] +margin_left = 107.0 +margin_right = 250.0 +margin_bottom = 24.0 +size_flags_horizontal = 3 +max_value = 1.0 +step = 0.0 +editable = false + +[node name="InputThreshold" type="HSlider" parent="MarginContainer/HBoxContainer/VBoxContainer"] +margin_top = 258.0 +margin_right = 250.0 +margin_bottom = 274.0 +max_value = 0.1 +step = 0.0 +allow_greater = true +allow_lesser = true +editable = false +ticks_on_borders = true + +[node name="Voice" type="Button" parent="MarginContainer/HBoxContainer/VBoxContainer"] +margin_top = 284.0 +margin_right = 250.0 +margin_bottom = 304.0 disabled = true text = "Speak" __meta__ = { "_edit_use_anchors_": false } -[node name="Status" type="Label" parent="."] -margin_left = 220.0 -margin_top = 44.2765 -margin_right = 370.0 -margin_bottom = 58.2765 +[node name="VBoxContainer2" type="VBoxContainer" parent="MarginContainer/HBoxContainer"] +margin_left = 300.0 +margin_right = 924.0 +margin_bottom = 500.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="Status" type="Label" parent="MarginContainer/HBoxContainer/VBoxContainer2"] +margin_right = 624.0 +margin_bottom = 14.0 text = "Status:" __meta__ = { "_edit_use_anchors_": false } -[node name="Log" type="Label" parent="."] -margin_left = 220.0 -margin_top = 100.0 -margin_right = 980.0 -margin_bottom = 340.0 +[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer/HBoxContainer/VBoxContainer2"] +margin_top = 18.0 +margin_right = 624.0 +margin_bottom = 500.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = SubResource( 2 ) __meta__ = { "_edit_use_anchors_": false } -[node name="VoipInstance" type="Node" parent="."] -script = ExtResource( 1 ) -[connection signal="pressed" from="Button_server" to="." method="_on_Button_server_pressed"] -[connection signal="pressed" from="Button_client" to="." method="_on_Button_client_pressed"] -[connection signal="button_down" from="Button_voice" to="." method="_on_Button_voice_button_down"] -[connection signal="button_up" from="Button_voice" to="." method="_on_Button_voice_button_up"] +[node name="Log" type="Label" parent="MarginContainer/HBoxContainer/VBoxContainer2/ScrollContainer"] +margin_right = 624.0 +margin_bottom = 482.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +__meta__ = { +"_edit_use_anchors_": false +} + +[connection signal="pressed" from="MarginContainer/HBoxContainer/VBoxContainer/Server" to="." method="_on_Button_server_pressed"] +[connection signal="value_changed" from="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/Port" to="." method="_on_Port_value_changed"] +[connection signal="pressed" from="MarginContainer/HBoxContainer/VBoxContainer/Client" to="." method="_on_Button_client_pressed"] +[connection signal="text_changed" from="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer1/Ip" to="." method="_on_Ip_text_changed"] +[connection signal="value_changed" from="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer3/Port" to="." method="_on_Port_value_changed"] +[connection signal="toggled" from="MarginContainer/HBoxContainer/VBoxContainer/Listen" to="." method="_on_Listen_toggled"] +[connection signal="value_changed" from="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/Value" to="." method="_on_Value_value_changed"] +[connection signal="value_changed" from="MarginContainer/HBoxContainer/VBoxContainer/InputThreshold" to="." method="_on_InputThreshold_value_changed"] +[connection signal="button_down" from="MarginContainer/HBoxContainer/VBoxContainer/Voice" to="." method="_on_Button_voice_button_down"] +[connection signal="button_up" from="MarginContainer/HBoxContainer/VBoxContainer/Voice" to="." method="_on_Button_voice_button_up"] +[connection signal="resized" from="MarginContainer/HBoxContainer/VBoxContainer2/ScrollContainer/Log" to="MarginContainer/HBoxContainer/VBoxContainer2/ScrollContainer" method="_on_Log_resized"] diff --git a/addons/godot-voip/demo/Network.gd b/addons/godot-voip/demo/Network.gd index 90e38e0..bcdf415 100644 --- a/addons/godot-voip/demo/Network.gd +++ b/addons/godot-voip/demo/Network.gd @@ -1,13 +1,15 @@ extends Node +class_name Network -const SERVER_PORT = 3000 -const MAX_PLAYERS = 20 -const SERVER_IP = "127.0.0.1" +var server_port := 3000 +var server_ip := "127.0.0.1" + +const MAX_PLAYERS := 20 func start_client() -> int: var peer = NetworkedMultiplayerENet.new() - var err = peer.create_client(SERVER_IP, SERVER_PORT) + var err = peer.create_client(server_ip, server_port) if err != OK: return err @@ -18,7 +20,7 @@ func start_client() -> int: func start_server() -> int: var peer = NetworkedMultiplayerENet.new() - var err = peer.create_server(SERVER_PORT, MAX_PLAYERS) + var err = peer.create_server(server_port, MAX_PLAYERS) if err != OK: return err diff --git a/addons/godot-voip/plugin.cfg b/addons/godot-voip/plugin.cfg index 9224a08..8426425 100644 --- a/addons/godot-voip/plugin.cfg +++ b/addons/godot-voip/plugin.cfg @@ -3,5 +3,5 @@ name="godot-voip" description="godot-voip" author="Cas Brugman" -version="2.0" +version="3.0" script="plugin.gd" diff --git a/addons/godot-voip/scripts/voip_instance.gd b/addons/godot-voip/scripts/voip_instance.gd index e7ad7c4..7ecd2e3 100644 --- a/addons/godot-voip/scripts/voip_instance.gd +++ b/addons/godot-voip/scripts/voip_instance.gd @@ -3,91 +3,96 @@ class_name VoipInstance signal received_voice_data signal send_voice_data -signal _updated_sample_format -export var min_packet_lenght_seconds: float = 1.0 export var custom_voice_audio_stream_player: NodePath -var recording: bool = false +export var recording: bool = false +export var listen: bool = false +export(float, 0.0, 1.0) var input_threshold: = 0.005 -var voip_format: int = -1 -var voip_mix_rate: int = -1 -var voip_stereo: bool = true - -var _microphone: VoipMicrophone +var _mic: VoipMic var _voice -var _effect_record: AudioEffectRecord -var _latest_sample: AudioStreamSample -var _time_recording: float = 0 +var _effect_capture: AudioEffectCapture +var _playback: AudioStreamGeneratorPlayback +var _receive_buffer := PoolRealArray() + +func _process(delta: float) -> void: + _process_voice() + _process_mic() -func _ready() -> void: - _microphone = VoipMicrophone.new() - add_child(_microphone) +func create_mic(): + _mic = VoipMic.new() + add_child(_mic) + var record_bus_idx = AudioServer.get_bus_index(_mic.bus) + _effect_capture = AudioServer.get_bus_effect(record_bus_idx, 0) +func create_voice(): if !custom_voice_audio_stream_player.is_empty(): var player = get_node(custom_voice_audio_stream_player) if player != null: if player is AudioStreamPlayer || player is AudioStreamPlayer2D || player is AudioStreamPlayer3D: _voice = player else: - push_error("voip_isntance.gd: node:'%s' is not any kind of AudioStreamPlayer!" % custom_voice_audio_stream_player) + push_error("node:'%s' is not any kind of AudioStreamPlayer!" % custom_voice_audio_stream_player) else: - push_error("voip_isntance.gd: node:'%s' does not exist!" % custom_voice_audio_stream_player) + push_error("node:'%s' does not exist!" % custom_voice_audio_stream_player) else: _voice = AudioStreamPlayer.new() add_child(_voice) - var record_bus_idx = AudioServer.get_bus_index(_microphone.bus) - _effect_record = AudioServer.get_bus_effect(record_bus_idx, 0) + var generator := AudioStreamGenerator.new() + generator.buffer_length = 0.1 + _voice.stream = generator -remote func _receive_stream_format(_format: int, _mix_rate: int, _stereo: bool): - voip_format = _format - voip_mix_rate = _mix_rate - voip_stereo = _stereo - - emit_signal("_updated_sample_format") + _playback = _voice.get_stream_playback() + _voice.play() -remote func _send_stream_format(): - rpc("_receive_stream_format", _latest_sample.format, _latest_sample.mix_rate, _latest_sample.stereo) +remote func _speak(sample_data: PoolRealArray, id: int = -1): + if _playback == null: + create_voice() -remote func _speak(sample_data: PoolByteArray, id: int = -1): emit_signal("received_voice_data", sample_data, id) + _receive_buffer.append_array(sample_data) - var sample = AudioStreamSample.new() - sample.data = sample_data +func _process_voice(): + if _playback == null: + return - if voip_format == -1: - rpc("_send_stream_format") - yield(self, "_updated_sample_format") - - sample.set_format(voip_format) - sample.set_mix_rate(voip_mix_rate) - sample.set_stereo(voip_stereo) - - _voice.stream = sample - _voice.play() + for i in range(_playback.get_frames_available()): + if _receive_buffer.size() > 0: + _playback.push_frame(Vector2(_receive_buffer[0], _receive_buffer[0])) + _receive_buffer.remove(0) + else: + _playback.push_frame(Vector2.ZERO) -func _process(delta: float) -> void: +func _process_mic(): if recording: - if _effect_record.is_recording_active(): - if _time_recording >= min_packet_lenght_seconds: - - _effect_record.set_recording_active(false) - _latest_sample = _effect_record.get_recording() - - rpc_unreliable("_speak", _latest_sample.get_data(), get_tree().get_network_unique_id()) - - emit_signal("send_voice_data", _latest_sample.get_data()) - - _effect_record.set_recording_active(true) - _time_recording = 0 + if _effect_capture == null: + create_mic() + + var stereo_data = _effect_capture.get_buffer(_effect_capture.get_frames_available()) + if stereo_data.size() > 0: + + var data = PoolRealArray() + data.resize(stereo_data.size()) + + if input_threshold > 0.0: + var max_value = 0.0 + for i in range(stereo_data.size()): + var value = (stereo_data[i].x + stereo_data[i].y) / 2.0 + max_value = max(value, max_value) + data[i] = value + if max_value < input_threshold: + return + else: + for i in range(stereo_data.size()): + data[i] = (stereo_data[i].x + stereo_data[i].y) / 2.0 - _time_recording += delta - else: - _effect_record.set_recording_active(true) - else: - _effect_record.set_recording_active(false) + if listen: + _speak(data, get_tree().get_network_unique_id()) + rpc_unreliable("_speak", data, get_tree().get_network_unique_id()) + emit_signal("send_voice_data", data) diff --git a/addons/godot-voip/scripts/voip_microphone.gd b/addons/godot-voip/scripts/voip_mic.gd similarity index 56% rename from addons/godot-voip/scripts/voip_microphone.gd rename to addons/godot-voip/scripts/voip_mic.gd index 74bbf64..89c0b9d 100644 --- a/addons/godot-voip/scripts/voip_microphone.gd +++ b/addons/godot-voip/scripts/voip_mic.gd @@ -1,18 +1,19 @@ extends AudioStreamPlayer -class_name VoipMicrophone +class_name VoipMic func _ready() -> void: var current_number = 0 - while AudioServer.get_bus_index("VoipMicrophoneRecorder" + str(current_number)) != -1: + while AudioServer.get_bus_index("VoipMicRecorder" + str(current_number)) != -1: current_number += 1 - var bus_name = "VoipMicrophoneRecorder" + str(current_number) + var bus_name = "VoipMicRecorder" + str(current_number) var idx = AudioServer.bus_count AudioServer.add_bus(idx) AudioServer.set_bus_name(idx, bus_name) - AudioServer.add_bus_effect(idx, AudioEffectRecord.new()) + AudioServer.add_bus_effect(idx, AudioEffectCapture.new()) + AudioServer.set_bus_mute(idx, true) bus = bus_name diff --git a/project.godot b/project.godot index 7b5d795..c9092e8 100644 --- a/project.godot +++ b/project.godot @@ -10,18 +10,24 @@ config_version=4 _global_script_classes=[ { "base": "Node", +"class": "Network", +"language": "GDScript", +"path": "res://addons/godot-voip/demo/Network.gd" +}, { +"base": "Node", "class": "VoipInstance", "language": "GDScript", "path": "res://addons/godot-voip/scripts/voip_instance.gd" }, { "base": "AudioStreamPlayer", -"class": "VoipMicrophone", +"class": "VoipMic", "language": "GDScript", -"path": "res://addons/godot-voip/scripts/voip_microphone.gd" +"path": "res://addons/godot-voip/scripts/voip_mic.gd" } ] _global_script_class_icons={ +"Network": "", "VoipInstance": "", -"VoipMicrophone": "" +"VoipMic": "" } [application] @@ -43,4 +49,5 @@ enabled=PoolStringArray( "godot-voip" ) [rendering] +quality/driver/driver_name="GLES2" environment/default_environment="res://default_env.tres"