Skip to content

Commit

Permalink
using new hacked godot source code from godotengine/godot#100508
Browse files Browse the repository at this point in the history
  • Loading branch information
goatchurchprime committed Dec 18, 2024
1 parent 1d8917a commit e213f56
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 14 deletions.
9 changes: 8 additions & 1 deletion example/default_bus_layout.tres
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
[gd_resource type="AudioBusLayout" load_steps=2 format=3 uid="uid://orx4iw038t0c"]
[gd_resource type="AudioBusLayout" load_steps=3 format=3 uid="uid://orx4iw038t0c"]

[sub_resource type="AudioEffectPitchShift" id="AudioEffectPitchShift_urnej"]
resource_name = "PitchShift"

[sub_resource type="AudioEffectCapture" id="AudioEffectCapture_sj64h"]
resource_local_to_scene = true
resource_name = "Capture"
buffer_length = 0.3

[resource]
bus/1/name = &"SpeechBus"
bus/1/solo = false
Expand All @@ -18,3 +23,5 @@ bus/2/mute = true
bus/2/bypass_fx = false
bus/2/volume_db = 0.0
bus/2/send = &"Master"
bus/2/effect/0/effect = SubResource("AudioEffectCapture_sj64h")
bus/2/effect/0/enabled = true
10 changes: 10 additions & 0 deletions example/minimalusecase/minimalusecase.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ var audiostreamopuschunked : AudioStreamOpusChunked
var prepend = PackedByteArray()
var opuspacketsbuffer = [ ]

@onready var playbackmic = AudioStreamPlaybackMicrophone.new()

func _ready():
var microphoneidx = AudioServer.get_bus_index("MicrophoneBus")
opuschunked = AudioServer.get_bus_effect(microphoneidx, 0)
Expand All @@ -13,10 +15,18 @@ func _ready():
for r in opusaudiodata:
opuspacketsbuffer.append(PackedByteArray(r))

playbackmic.start(0.0)

func _process(delta):
#_process_record(delta)
_process_playback(delta)

func _input(event):
if event is InputEventKey and event.pressed and event.keycode == KEY_D:
print(playbackmic.is_playing())
print(playbackmic.get_microphone_buffer(20)+playbackmic.get_microphone_buffer(20))


func _process_record(delta):
while opuschunked.chunk_available():
var chunkmax = opuschunked.chunk_max(false, false)
Expand Down
2 changes: 1 addition & 1 deletion example/minimalusecase/minimalusecase.tscn
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[gd_scene load_steps=4 format=3 uid="uid://cx10t585wbeo2"]

[ext_resource type="Script" path="res://minimalusecase/minimalusecase.gd" id="1_m25c5"]
[ext_resource type="Script" uid="uid://dg10tsmim56bv" path="res://minimalusecase/minimalusecase.gd" id="1_m25c5"]

[sub_resource type="AudioStreamMicrophone" id="AudioStreamMicrophone_c8xp2"]

Expand Down
2 changes: 1 addition & 1 deletion example/project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ config_version=5

config/name="Two-voip-godot-4"
run/main_scene="res://radiomqtt/radiomqtt.tscn"
config/features=PackedStringArray("4.3", "GL Compatibility")
config/features=PackedStringArray("4.4", "GL Compatibility")
config/icon="res://icon.png"

[audio]
Expand Down
2 changes: 1 addition & 1 deletion example/radiomqtt/member.tscn
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[gd_scene load_steps=6 format=3 uid="uid://c1ibcb1toyerh"]

[ext_resource type="Script" path="res://radiomqtt/member.gd" id="1_o3hks"]
[ext_resource type="Script" uid="uid://bckl548pomyik" path="res://radiomqtt/member.gd" id="1_o3hks"]
[ext_resource type="Texture2D" uid="uid://cvyjsyigutxbh" path="res://icon.png" id="2_atirx"]

[sub_resource type="AudioStreamGenerator" id="AudioStreamGenerator_t0bqw"]
Expand Down
25 changes: 20 additions & 5 deletions example/radiomqtt/radiomqtt.gd
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var audioeffectpitchshift : AudioEffectPitchShift = null
var audioeffectpitchshiftidx = 0
var audioeffectcapture : AudioEffectCapture = null
var audioopuschunkedeffect # : AudioEffectOpusChunked
@onready var audiostreamplaybackmicrophone : AudioStreamPlaybackMicrophone = AudioStreamPlaybackMicrophone.new()

# values to use when AudioEffectOpusChunked cannot be instantiated
var frametimems : float = 20
Expand Down Expand Up @@ -44,6 +45,8 @@ var visemes = [ "sil", "PP", "FF", "TH", "DD", "kk", "CH", "SS", "nn", "RR", "aa
var possibleusernames = ["Alice", "Beth", "Cath", "Dan", "Earl", "Fred", "George", "Harry", "Ivan", "John", "Kevin", "Larry", "Martin", "Oliver", "Peter", "Quentin", "Robert", "Samuel", "Thomas", "Ulrik", "Victor", "Wayne", "Xavier", "Youngs", "Zephir"]

func _ready():
if audiostreamplaybackmicrophone != null:
audiostreamplaybackmicrophone.start_microphone()
print("AudioServer.get_mix_rate()=", AudioServer.get_mix_rate())
print("ProjectSettings.get_setting_with_override(\"audio/driver/mix_rate\")=", ProjectSettings.get_setting_with_override("audio/driver/mix_rate"))
$VBoxPlayback/HBoxStream/MixRate.value = AudioServer.get_mix_rate()
Expand Down Expand Up @@ -289,7 +292,8 @@ func _input(event):
$AudioStreamMicrophone.volume_db += (1 if event.keycode == KEY_I else -1)
print($AudioStreamMicrophone.volume_db)


if event.keycode == KEY_D:
audioopuschunkedeffect.Drunmicthing()


func _process(_delta):
Expand All @@ -299,14 +303,14 @@ func _process(_delta):
if talking:
$VBoxPlayback/HBoxPlaycount/GridContainer/TimeSecs.text = "%.1f" % ((Time.get_ticks_msec() - talkingstarttime)*0.001)
if talking and not currentlytalking:
if not $AudioStreamMicrophone.playing:
if not $AudioStreamMicrophone.playing and audiostreamplaybackmicrophone == null:
$AudioStreamMicrophone.play()
starttalking()
elif not talking and currentlytalking:
endtalking()
$HBoxMicTalk/MicWorking.button_pressed = $AudioStreamMicrophone.playing

if audioeffectcapture == null:
if audioeffectcapture == null and audiostreamplaybackmicrophone == null:
assert (audioopuschunkedeffect != null)
while audioopuschunkedeffect.chunk_available():
var audiosamples = audioopuschunkedeffect.read_chunk(false)
Expand Down Expand Up @@ -357,8 +361,19 @@ func _process(_delta):
audioopuschunkedeffect.drop_chunk()

else:
while audioeffectcapture.get_frames_available() > audiosamplesize:
var audiosamples = audioeffectcapture.get_buffer(audiosamplesize)
while true:
var audiosamples = null
if audiostreamplaybackmicrophone.is_microphone_playing() and audiostreamplaybackmicrophone != null:
audiosamples = audiostreamplaybackmicrophone.get_microphone_buffer(audiosamplesize)
if len(audiosamples) != audiosamplesize:
assert (len(audiosamples) == 0)
break
else:
if audioeffectcapture.get_frames_available() > audiosamplesize:
audiosamples = audioeffectcapture.get_buffer(audiosamplesize)
else:
break

audiosamplestoshader(audiosamples, false)
var chunkv1 = 0.0
var schunkv2 = 0.0
Expand Down
13 changes: 8 additions & 5 deletions example/radiomqtt/radiomqtt.tscn
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[gd_scene load_steps=22 format=3 uid="uid://babntosbiq5r8"]

[ext_resource type="Script" path="res://radiomqtt/radiomqtt.gd" id="1_anot2"]
[ext_resource type="Script" uid="uid://bdckem1ncyrbm" path="res://radiomqtt/radiomqtt.gd" id="1_anot2"]
[ext_resource type="PackedScene" uid="uid://ktm7k0co2o7l" path="res://addons/mqtt/mqtt.tscn" id="2_4wm5t"]
[ext_resource type="Script" path="res://radiomqtt/MQTTnetwork.gd" id="2_y485j"]
[ext_resource type="Script" uid="uid://bnox12o7ro1j6" path="res://radiomqtt/MQTTnetwork.gd" id="2_y485j"]
[ext_resource type="Texture2D" uid="uid://cvyjsyigutxbh" path="res://icon.png" id="3_eh2h5"]
[ext_resource type="Script" path="res://radiomqtt/voxdetector.gd" id="3_qvq17"]
[ext_resource type="Script" uid="uid://byx6ipd6c6ldh" path="res://radiomqtt/voxdetector.gd" id="3_qvq17"]
[ext_resource type="PackedScene" uid="uid://c1ibcb1toyerh" path="res://radiomqtt/member.tscn" id="4_w5dv2"]

[sub_resource type="AudioStreamMicrophone" id="AudioStreamMicrophone_itmlg"]
Expand Down Expand Up @@ -57,8 +57,8 @@ void fragment() {

[sub_resource type="ShaderMaterial" id="ShaderMaterial_cklni"]
shader = SubResource("Shader_r847e")
shader_parameter/drawresampled = false
shader_parameter/voice = ExtResource("3_eh2h5")
shader_parameter/drawresampled = false
shader_parameter/voice_resampled = ExtResource("3_eh2h5")

[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_onpxr"]
Expand Down Expand Up @@ -96,7 +96,6 @@ script = ExtResource("1_anot2")

[node name="AudioStreamMicrophone" type="AudioStreamPlayer" parent="."]
stream = SubResource("AudioStreamMicrophone_itmlg")
autoplay = true
bus = &"MicrophoneBus"

[node name="LabelTitle" type="Label" parent="."]
Expand Down Expand Up @@ -295,6 +294,7 @@ text = "Frame duration"
layout_mode = 2
item_count = 6
popup/item_0/text = "2.5ms"
popup/item_0/id = 0
popup/item_1/text = "5ms"
popup/item_1/id = 1
popup/item_2/text = "10ms"
Expand Down Expand Up @@ -382,6 +382,7 @@ layout_mode = 2
allow_reselect = true
item_count = 5
popup/item_0/text = "8KHz"
popup/item_0/id = 0
popup/item_1/text = "12KHz"
popup/item_1/id = 1
popup/item_2/text = "16KHz"
Expand Down Expand Up @@ -469,6 +470,7 @@ layout_mode = 2
selected = 0
item_count = 4
popup/item_0/text = "(actions)"
popup/item_0/id = 0
popup/item_1/text = "Save"
popup/item_1/id = 1
popup/item_2/text = "Load"
Expand Down Expand Up @@ -655,6 +657,7 @@ layout_mode = 2
size_flags_horizontal = 3
item_count = 4
popup/item_0/text = "doesliverpool"
popup/item_0/id = 0
popup/item_1/text = "hivemq"
popup/item_1/id = 1
popup/item_2/text = "m.org"
Expand Down
52 changes: 52 additions & 0 deletions src/audio_effect_opus_chunked.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,60 @@ void AudioEffectOpusChunked::_bind_methods() {
ClassDB::bind_method(D_METHOD("resetencoder"), &AudioEffectOpusChunked::resetencoder);
ClassDB::bind_method(D_METHOD("chunk_to_opus_packet", "prefixbytes", "audiosamples", "denoise"), &AudioEffectOpusChunked::chunk_to_opus_packet);
ClassDB::bind_method(D_METHOD("chunk_resample", "audiosamples", "denoise", "backresample"), &AudioEffectOpusChunked::chunk_resample);

ClassDB::bind_method(D_METHOD("Drunmicthing"), &AudioEffectOpusChunked::Drunmicthing);
}

// What have I done:
// in v4.3.stable
// change the ngodot/flake.nix
// substituteInPlace servers/register_server_types.cpp \
// --replace-fail 'GDREGISTER_CLASS(AudioStreamMicrophone);' 'GDREGISTER_CLASS(AudioStreamMicrophone);GDREGISTER_CLASS(AudioStreamPlaybackMicrophone);'
//
// godot4 --dump-extension-api
// cp extension_api.json ../two-voip-godot-4-DEV/godot-cpp/gdextension/
// in twovoip run scons
// cp addons/twovoip/libs/libtwovoip.linux.template_debug.x86_64.so example/addons/twovoip_lipsync/libs/
//
// To compile godot from repositories/godot source code
// nix develop nixpkgs#godot_4
// scons -j16 dbus=true debug_symbols=false fontconfig=true platform=linuxbsd precision=single production=true pulseaudio=true speechd=true target=editor touch=true udev=true wayland=true x11=true prefix=/home/julian/repositories/godot/outputs/out
// runPhase installPhase
// runphase fixupPhase
// outputs/out/bin/godot4



void AudioEffectOpusChunked::Drunmicthing() {
if (!DBrunmicthing) {
Daudiostreammicrophoneplayback = Daudiostreammicrophone.instantiate_playback();
godot::UtilityFunctions::prints("Bingo!");
godot::UtilityFunctions::prints(Daudiostreammicrophoneplayback);
Daudiostreammicrophoneplayback->begin_resample();
//Daudiostreammicrophoneplayback->Dingo();
godot::UtilityFunctions::prints("Bongo!");
DBrunmicthing = true;
}

godot::UtilityFunctions::prints(Daudiostreammicrophoneplayback->_is_playing());
std::vector<AudioFrame> buff;
buff.resize(882);
int mixed = Daudiostreammicrophoneplayback->_mix_resampled(&buff.front(), 882);
godot::UtilityFunctions::prints(mixed);


/* virtual void _start(double p_from_pos);
virtual void _stop();
virtual bool _is_playing() const;
virtual int32_t _get_loop_count() const;
virtual double _get_playback_position() const;
virtual void _seek(double p_position);
virtual int32_t _mix(AudioFrame *p_buffer, double p_rate_scale, int32_t p_frames);
virtual void _tag_used_streams();
*/
}


const int MAXPREFIXBYTES = 100;

AudioEffectOpusChunked::AudioEffectOpusChunked() {
Expand Down
16 changes: 16 additions & 0 deletions src/audio_effect_opus_chunked.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
#include <godot_cpp/classes/mutex.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
#include <godot_cpp/classes/node.hpp>
#include <godot_cpp/classes/audio_stream_microphone.hpp>
#include <godot_cpp/classes/audio_stream_playback.hpp>
#include <godot_cpp/classes/audio_frame.hpp>
#include <godot_cpp/classes/audio_stream_playback_resampled.hpp>
//#include <godot_cpp/classes/audio_stream_playback_microphone.hpp>

#include "opus.h"
#include "speex_resampler/speex_resampler.h"
Expand All @@ -58,6 +63,9 @@


namespace godot {




class AudioEffectOpusChunked;

Expand Down Expand Up @@ -140,6 +148,12 @@ class AudioEffectOpusChunked : public AudioEffect {

void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count);


bool DBrunmicthing = false;
AudioStreamMicrophone Daudiostreammicrophone;
Ref<AudioStreamPlaybackResampled> Daudiostreammicrophoneplayback;


protected:
static void _bind_methods();

Expand All @@ -154,6 +168,8 @@ class AudioEffectOpusChunked : public AudioEffect {
void deleteencoder();
void resetencoder();

void Drunmicthing();

bool chunk_available();
void drop_chunk();
bool undrop_chunk();
Expand Down

0 comments on commit e213f56

Please sign in to comment.