Godot Version
4.7.1
Question
for the last week or so I’ve been trying to implement a live voice chat system into my game, but so far I haven’t gotten any where.
I’ve followed a good 3 tutorials but the result has always been about the same, being all I hear is static, despite the code being 1:1. My only guess is that it isn’t sending the right voice data or something in that boat, but I’m not sure how to fix it.
The audio bus (if its not muted) for recording is replaying my voice back to me perfectly so I know that’s working.
I was originally using an amplitude method for detecting voice input, which kinda worked. At some point I swapped over to and RMS method, which broke it, and after going back to amplitude it just wasn’t detecting anything anymore so not sure what I did there
# // Constants //
const VCInputThreshold := 0.005;
# // Variables //
var RecordEffect : AudioEffectCapture; ## Effect used for recording mic audio
var VCToggled : bool = false; ## Whether or not VC is toggled on. Used when VC mode is set to toggled
var OutputBuffers : Dictionary[Node, PackedFloat32Array];
func _process(_delta):
if CanSpeak : ## Dont worry about this, its true
ProcessMic();
# // Output
ProcessOutputs();
func AddOutputAudio(Output : Node, AudioData : PackedFloat32Array) : ## adds an audio to an output to be played
if !Output is AudioStreamPlayer and !Output is AudioStreamPlayer3D : return;
if !Output.stream or !Output.stream in AudioStreamGenerator : print("Output has invalid stream."); return;
if !Output in OutputBuffers :
OutputBuffers[Output] = PackedFloat32Array();
if !Output.playing :
Output.play();
Output.stream.mix_rate = Steam.getVoiceOptimalSampleRate();
OutputBuffers[Output].append_array(AudioData);
# // processing
func ProcessMic() : ## Processes the users mic input
var SterioData : PackedVector2Array = RecordEffect.get_buffer(RecordEffect.get_frames_available());
if SterioData.size() > 0 :
# // Acquire data
var data := PackedFloat32Array();
data.resize(SterioData.size());
var SumOfSquares := 0.0;
for Index in range(SterioData.size()) :
var Value : float = (SterioData[Index].x + SterioData[Index].y) / 2;
#MaxAmplitude = max(Value, MaxAmplitude);
SumOfSquares += Value * Value;
data[Index] = Value;
var MeanSquare : float = SumOfSquares / SterioData.size();
if sqrt(MeanSquare) < VCInputThreshold : # Too quite, cancel.
return
rpc_id(1, "_send_player_audio", data);
func ProcessOutputs() : ## Processes all outputs
for Output : Node in OutputBuffers :
if !Output is AudioStreamPlayer and !Output is AudioStreamPlayer3D : continue;
var Playback : AudioStreamGeneratorPlayback = Output.get_stream_playback();
print("Output: ", Output.name);
if OutputBuffers[Output].size() <= 0 :
Playback.push_frame(Vector2.ZERO);
else :
for i in range (min(Playback.get_frames_available(), OutputBuffers[Output].size())) :
Playback.push_frame(Vector2(OutputBuffers[Output][0], OutputBuffers[Output][0]));
OutputBuffers[Output].remove_at(0);
I’ll also note that the RPC functions used to relay the data aren’t modifying it in anyway and are delivering it to the correct clients. If its important, I am using GodotSteam for some of the multiplayer stuff
So if anyone knows of any working tutorials I could try or might know what I’m doing wrong please let me know! Thanks in advanced