From 860e4c6193e0de865294e39caa10adcce3cdfbe5 Mon Sep 17 00:00:00 2001 From: Florent Berthaut <florent.berthaut@univ-lille.fr> Date: Fri, 3 May 2024 00:41:14 +0200 Subject: [PATCH] Got non rt audio working --- .gitmodules | 1 + SConstruct | 5 +- demo/Main.tscn | 51 ++++++++++--- src/gdpd.cpp | 169 ++++++++++++++++++++++++++++++++--------- src/gdpd.h | 71 +++++++++++++++-- src/godot-cpp | 2 +- src/register_types.cpp | 2 + src/rtaudio/RtAudio.os | Bin 74776 -> 75224 bytes 8 files changed, 243 insertions(+), 58 deletions(-) diff --git a/.gitmodules b/.gitmodules index 2e03585..1527b7a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,4 @@ [submodule "src/godot-cpp"] path = src/godot-cpp url = https://github.com/GodotNativeTools/godot-cpp + branch = 4.2 diff --git a/SConstruct b/SConstruct index 1ced9da..43122b6 100644 --- a/SConstruct +++ b/SConstruct @@ -29,7 +29,10 @@ env = SConscript("src/godot-cpp/SConstruct") # - CPPDEFINES are for pre-processor defines # - LINKFLAGS are for linking flags -env.Append(CPPPATH=['.', 'src/libpd/libpd_wrapper', 'src/libpd/libpd_wrapper/util', 'src/libpd/cpp','src/libpd/pure-data/src', 'src/rtaudio']) +env.Append(CPPPATH=['.', 'src/libpd/libpd_wrapper', + 'src/libpd/libpd_wrapper/util', + 'src/libpd/cpp','src/libpd/pure-data/src', 'src/rtaudio'], + CCFLAGS=["-fexceptions"]) env.Append(CFLAGS=['-DUSEAPI_DUMMY', '-DPD', '-DHAVE_UNISTD_H',\ '-D_GNU_SOURCE','-DLIBPD_EXTRA']) diff --git a/demo/Main.tscn b/demo/Main.tscn index 37ec47b..810ce47 100644 --- a/demo/Main.tscn +++ b/demo/Main.tscn @@ -6,6 +6,7 @@ script/source = "extends Control @onready var _gdpd = GdPd.new() func _ready(): + add_child(_gdpd) pass func _process(delta): @@ -42,6 +43,23 @@ func _on_Start_pressed() : # listen to messages sent with [send to_godot] _gdpd.subscribe(\"to_godot\") + + +func _on_start_non_rt_pressed(): + # initialise without realtime + _gdpd.init_nort() + + # the patch path should be absolute + _load_patch(ProjectSettings.globalize_path(\"res://patch1.pd\")) + _load_patch(ProjectSettings.globalize_path(\"res://patch2.pd\")) + + # send message to [receive from_godot] with one symbol + _gdpd.start_message(1) + _gdpd.add_symbol(\"hello\") + _gdpd.finish_list(\"from_godot\") + + # listen to messages sent with [send to_godot] + _gdpd.subscribe(\"to_godot\") func _on_Stop_pressed(): _gdpd.closefile(\"patch1.pd\") @@ -62,6 +80,8 @@ func _on_HSlider2_value_changed(value): _gdpd.add_symbol(\"pitch\") _gdpd.add_float(value) _gdpd.finish_list(\"from_godot\") + + " [node name="Control" type="Control"] @@ -73,21 +93,29 @@ grow_horizontal = 2 grow_vertical = 2 script = SubResource("1") +[node name="Start" type="Button" parent="."] +layout_mode = 0 +offset_left = 72.0 +offset_top = 80.0 +offset_right = 176.0 +offset_bottom = 128.0 +text = "Start" + [node name="Stop" type="Button" parent="."] layout_mode = 0 -offset_left = 213.0 -offset_top = 83.0 -offset_right = 316.0 -offset_bottom = 129.0 +offset_left = 296.0 +offset_top = 80.0 +offset_right = 399.0 +offset_bottom = 128.0 text = "Stop" -[node name="Start" type="Button" parent="."] +[node name="StartNonRT" type="Button" parent="."] layout_mode = 0 -offset_left = 73.0 -offset_top = 83.0 -offset_right = 177.0 -offset_bottom = 134.0 -text = "Start" +offset_left = 184.0 +offset_top = 80.0 +offset_right = 290.0 +offset_bottom = 128.0 +text = "Start Non RT" [node name="HSlider" type="HSlider" parent="."] layout_mode = 0 @@ -121,7 +149,8 @@ offset_right = 204.0 offset_bottom = 260.0 text = "Send pitch to patch2" -[connection signal="pressed" from="Stop" to="." method="_on_Stop_pressed"] [connection signal="pressed" from="Start" to="." method="_on_Start_pressed"] +[connection signal="pressed" from="Stop" to="." method="_on_Stop_pressed"] +[connection signal="pressed" from="StartNonRT" to="." method="_on_start_non_rt_pressed"] [connection signal="value_changed" from="HSlider" to="." method="_on_HSlider_value_changed"] [connection signal="value_changed" from="HSlider2" to="." method="_on_HSlider2_value_changed"] diff --git a/src/gdpd.cpp b/src/gdpd.cpp index 40481db..aae9f73 100644 --- a/src/gdpd.cpp +++ b/src/gdpd.cpp @@ -2,7 +2,7 @@ * gdpd.cpp * Part of GdPd * 2023- see README for AUTHORS - * https://gitlab.univ-lille.fr/immersync + * https://gitlab.univ-lille.fr/ivmi ****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -24,14 +24,16 @@ #include <godot_cpp/core/class_db.hpp> - #include <godot_cpp/classes/os.hpp> #include <godot_cpp/classes/global_constants.hpp> #include <godot_cpp/classes/label.hpp> #include <godot_cpp/variant/utility_functions.hpp> +#include <godot_cpp/classes/audio_server.hpp> using namespace godot; +const int PCM_BUFFER_SIZE = 4096 * 4; + void GdPd::_bind_methods() { ADD_GROUP("GdPd", "gdpd_"); @@ -40,7 +42,8 @@ void GdPd::_bind_methods() { ClassDB::bind_method(D_METHOD("get_available_output_devices"), &GdPd::get_available_output_devices); ClassDB::bind_method(D_METHOD("init_devices"), &GdPd::init_devices); - ClassDB::bind_method(D_METHOD("init"), &GdPd::init); + ClassDB::bind_method(D_METHOD("init_parameters"), &GdPd::init_parameters); + ClassDB::bind_method(D_METHOD("init_nort"), &GdPd::init_nort); ClassDB::bind_method(D_METHOD("stop"), &GdPd::stop); ClassDB::bind_method(D_METHOD("openfile"), &GdPd::openfile); ClassDB::bind_method(D_METHOD("closefile"), &GdPd::closefile); @@ -52,6 +55,7 @@ void GdPd::_bind_methods() { ClassDB::bind_method(D_METHOD("add_float"), &GdPd::add_float); ClassDB::bind_method(D_METHOD("finish_list"), &GdPd::finish_list); ClassDB::bind_method(D_METHOD("set_volume"), &GdPd::set_volume); + } GdPd::GdPd() : m_vol(1) { @@ -62,12 +66,13 @@ GdPd::GdPd() : m_vol(1) { GdPd::~GdPd() {} + + int GdPd::audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void *userData){ GdPd* gdpd = static_cast<GdPd*>(userData); - gdpd->processAudio(outputBuffer, inputBuffer, nBufferFrames, streamTime, - status, userData); + gdpd->processAudio(outputBuffer, inputBuffer, nBufferFrames); return 0; } @@ -113,10 +118,13 @@ int GdPd::init_devices(String inputDevice, String outputDevice) { m_nbOutputs = outInfo.outputChannels; m_sampleRate = outInfo.preferredSampleRate; m_bufferFrames = 128; + + m_realtime=true; + return start(); } -int GdPd::init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize) { +int GdPd::init_parameters(int nbInputs, int nbOutputs, int sampleRate, int bufferSize) { m_inputDevice = m_audio.getDefaultInputDevice(); m_outputDevice = m_audio.getDefaultOutputDevice(); RtAudio::DeviceInfo inpInfo = m_audio.getDeviceInfo(m_inputDevice); @@ -125,17 +133,54 @@ int GdPd::init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize) { m_nbOutputs = std::min<int>(nbOutputs, outInfo.outputChannels); m_sampleRate = sampleRate; m_bufferFrames = std::max<int>(64, bufferSize); + + m_realtime=true; + return start(); } +int GdPd::init_nort() { + + m_nbInputs=0; + m_nbOutputs=2; + m_sampleRate=44100; + m_realtime=false; + + + if(!m_pd.init(m_nbInputs, m_nbOutputs, m_sampleRate, true)) { + print("GDPD : Error starting libpd"); + return 1; + } + + // Create message hook + m_pd.subscribe("to_gdpd"); + m_pd.setReceiver(this); + m_init=true; + + // Create stream player + AudioStreamPlayer* p = new AudioStreamPlayer(); + add_child(p); + + Ref<GdPdStream> s; + s.instantiate(); + s->setGdPd(this); + + p->set_stream(s); + p->play(); + + print("Initialized"); + + return 0; +} + int GdPd::start() { - RtAudio::StreamParameters outParams, inpParams; - inpParams.deviceId = m_inputDevice; - inpParams.nChannels = m_nbInputs; - outParams.deviceId = m_outputDevice; - outParams.nChannels = m_nbOutputs; - print("Output channels = "+std::to_string(outParams.nChannels)); - print("Input channels = "+std::to_string(inpParams.nChannels)); + RtAudio::StreamParameters outParams, inpParams; + inpParams.deviceId = m_inputDevice; + inpParams.nChannels = m_nbInputs; + outParams.deviceId = m_outputDevice; + outParams.nChannels = m_nbOutputs; + print("Output channels = "+std::to_string(outParams.nChannels)); + print("Input channels = "+std::to_string(inpParams.nChannels)); if(!m_pd.init(m_nbInputs, m_nbOutputs, m_sampleRate, true)) { @@ -148,27 +193,32 @@ int GdPd::start() { //start dsp m_pd.computeAudio(true); - //intialize rtaudio - if(m_audio.getDeviceCount()==0){ - UtilityFunctions::print("There are no available sound devices."); - } - - RtAudio::StreamOptions options; - options.streamName = "gdpd"; - options.flags = RTAUDIO_SCHEDULE_REALTIME; - if(m_audio.getCurrentApi() != RtAudio::MACOSX_CORE) { - options.flags |= RTAUDIO_MINIMIZE_LATENCY; - } - try { - m_audio.openStream(&outParams, &inpParams, RTAUDIO_FLOAT32, - m_sampleRate, &m_bufferFrames, &audioCallback, - this, &options); - m_audio.startStream(); - print("Stream started"); - } - catch(RtAudioError& e) { - UtilityFunctions::print(e.getMessage().c_str()); - } + if(m_realtime) { + //intialize rtaudio + if(m_audio.getDeviceCount()==0){ + UtilityFunctions::print("There are no available sound devices."); + return 1; + } + + RtAudio::StreamOptions options; + options.streamName = "gdpd"; + options.flags = RTAUDIO_SCHEDULE_REALTIME; + if(m_audio.getCurrentApi() != RtAudio::MACOSX_CORE) { + options.flags |= RTAUDIO_MINIMIZE_LATENCY; + } + try { + m_audio.openStream(&outParams, &inpParams, RTAUDIO_FLOAT32, + m_sampleRate, &m_bufferFrames, &audioCallback, + this, &options); + m_audio.startStream(); + print("Stream started"); + } + catch(RtAudioError& e) { + UtilityFunctions::print(e.getMessage().c_str()); + } + } + else { + } //create message hook m_pd.subscribe("to_gdpd"); @@ -182,15 +232,18 @@ int GdPd::start() { void GdPd::stop() { m_init=false; - m_audio.stopStream(); - m_audio.closeStream(); + if(m_realtime) { + m_audio.stopStream(); + m_audio.closeStream(); + } + else { + } m_pd.computeAudio(false); print("Stopped"); } void GdPd::processAudio(void *outputBuffer, void *inputBuffer, - unsigned int nBufferFrames, double streamTime, - RtAudioStreamStatus status, void *userData) { + unsigned int nBufferFrames) { int ticks = nBufferFrames / libpd_blocksize(); m_pd.processFloat(ticks, (float*)inputBuffer, (float*)outputBuffer); @@ -301,4 +354,44 @@ void GdPd::set_volume(float vol) { m_vol=vol; } +/* GdPdStream */ +GdPdStream::GdPdStream() { + +} +Ref<AudioStreamPlayback> GdPdStream::_instantiate_playback() const { + Ref<GdPdStreamPlayback> gdPlayback; + gdPlayback.instantiate(); + gdPlayback->m_base = Ref<GdPdStream>(this); + return gdPlayback; +} + +#define zeromem(to, count) memset(to, 0, count) + +/* GdPdStreamplayback */ +GdPdStreamPlayback::GdPdStreamPlayback() { + m_buffer.resize(4096*2,0.0); + AudioServer::get_singleton()->lock(); + pcm_buffer = memalloc(PCM_BUFFER_SIZE); + zeromem(pcm_buffer, PCM_BUFFER_SIZE); + AudioServer::get_singleton()->unlock(); +} + +GdPdStreamPlayback::~GdPdStreamPlayback() { + +} + +int32_t GdPdStreamPlayback::_mix_resampled(AudioFrame *buffer, + int32_t nbFrames) { + m_buffer.resize(4096*2, 0.0); + m_base->getGdPd()->processAudio(m_buffer.data(), NULL, nbFrames); + for(int i = 0; i < nbFrames; i++) { + buffer[i].left = m_buffer[i*2]; + buffer[i].right = m_buffer[i*2+1]; + } + return nbFrames; +} + +double GdPdStreamPlayback::_get_stream_sampling_rate() const { + return AudioServer::get_singleton()->get_mix_rate(); +} diff --git a/src/gdpd.h b/src/gdpd.h index e0b97aa..44be93a 100644 --- a/src/gdpd.h +++ b/src/gdpd.h @@ -1,7 +1,8 @@ /*************************************************************************** - * gd4pd.h + * gdpd.h * Part of GdPd * 2023- see README for AUTHORS + * https://gitlab.univ-lille.fr/ivmi ****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -34,19 +35,26 @@ #include <godot_cpp/core/binder_common.hpp> #include <godot_cpp/classes/engine.hpp> #include <godot_cpp/classes/audio_stream.hpp> +#include <godot_cpp/classes/audio_stream_playback_resampled.hpp> +#include <godot_cpp/classes/audio_stream_player.hpp> +#include <godot_cpp/classes/audio_frame.hpp> #include "PdBase.hpp" #include "RtAudio.h" using namespace godot; -class GdPd : public AudioStream, public pd::PdReceiver { - GDCLASS(GdPd, AudioStream); +class GdPdStreamPlayback; + + +class GdPd : public Node, public pd::PdReceiver { + GDCLASS(GdPd, Node); protected: static void _bind_methods(); private: + bool m_realtime; float *m_inBuf; float *m_outBuf; Array* m_messages; @@ -64,6 +72,8 @@ private: bool m_init; + int start(); + public: GdPd(); @@ -72,9 +82,9 @@ public: //libpd functions Array get_available_input_devices(); Array get_available_output_devices(); + int init_nort(); int init_devices(String inputDevice, String outputDevice); - int init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize); - int start(); + int init_parameters(int nbInputs, int nbOutputs, int sampleRate, int bufferSize); void stop(); bool openfile(String basename, String dirname); void closefile(String basename); @@ -101,9 +111,56 @@ public: unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void *userData); void processAudio(void *outputBuffer, void *inputBuffer, - unsigned int nBufferFrames, double streamTime, - RtAudioStreamStatus status, void *userData); + unsigned int nBufferFrames); +}; + +class GdPdStream : public AudioStream { + GDCLASS(GdPdStream, AudioStream); + friend class GdPdStreamPlayback; + +private: + GdPd* m_gdpd; + +protected: + static void _bind_methods(){} + +public: + GdPdStream(); + Ref<AudioStreamPlayback> _instantiate_playback() const override; + + virtual String _get_stream_name() const {return "GdPd";} + virtual double _get_length() const { return 0; } + + void setGdPd(GdPd* gdpd){m_gdpd=gdpd;} + GdPd* getGdPd(){return m_gdpd;} }; +class GdPdStreamPlayback: public AudioStreamPlaybackResampled { + GDCLASS(GdPdStreamPlayback, AudioStreamPlaybackResampled); + friend class GdPdStream; + +protected: + Ref<GdPdStream> m_base; + std::vector<float> m_buffer; + bool active; + void *pcm_buffer; + + static void _bind_methods(){} + +public: + GdPdStreamPlayback(); + ~GdPdStreamPlayback(); + + int32_t _mix_resampled(AudioFrame *dst_buffer, int32_t frame_count) override; + double _get_stream_sampling_rate() const override; + + bool _is_playing() const override {return active;} + void _start(double from_pos) override {active=true;} + void _seek(double position) override {} + void _stop() override {active=false;} +}; + + + #endif diff --git a/src/godot-cpp b/src/godot-cpp index 28494f0..98c143a 160000 --- a/src/godot-cpp +++ b/src/godot-cpp @@ -1 +1 @@ -Subproject commit 28494f0bd59f9c35289524e503648ed8b4baaa59 +Subproject commit 98c143a48365f3f3bf5f99d6289a2cb25e6472d1 diff --git a/src/register_types.cpp b/src/register_types.cpp index 3097aa7..574b624 100644 --- a/src/register_types.cpp +++ b/src/register_types.cpp @@ -15,6 +15,8 @@ void initialize_gdpd_module(ModuleInitializationLevel p_level) { return; } ClassDB::register_class<GdPd>(); + ClassDB::register_class<GdPdStream>(); + ClassDB::register_class<GdPdStreamPlayback>(); } void uninitialize_gdpd_module(ModuleInitializationLevel p_level) { diff --git a/src/rtaudio/RtAudio.os b/src/rtaudio/RtAudio.os index 4dd83fb517790ff7e696d80faeef48fc2feb7ed5..2ff0399f747003294a06aead1af63b69ec45ff03 100644 GIT binary patch delta 22350 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 delta 21937 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 LBJ1>DVvKSC&^z+> -- GitLab