diff --git a/source/obs/obs-source.cpp b/source/obs/obs-source.cpp index e0aeb8d..1a76680 100644 --- a/source/obs/obs-source.cpp +++ b/source/obs/obs-source.cpp @@ -286,6 +286,16 @@ void obs::source::handle_audio_mixers(void* p, calldata_t* calldata) calldata_set_int(calldata, "mixers", mixers); } +void obs::source::handle_audio_data(void* p, obs_source_t* source, const audio_data* audio, bool muted) +{ + obs::source* self = reinterpret_cast(p); + if (!self->events.audio_data) { + return; + } + + self->events.audio_data(self, audio, muted); +} + void obs::source::handle_filter_add(void* p, calldata_t* calldata) { obs::source* self = reinterpret_cast(p); @@ -352,83 +362,73 @@ void obs::source::handle_transition_stop(void* p, calldata_t*) self->events.transition_stop(self); } -void obs::source::connect_signals() -{ - auto sh = obs_source_get_signal_handler(this->self); - if (sh) { -#define auto_signal_c(SIGNAL) signal_handler_connect(sh, "" #SIGNAL, obs::source::handle_##SIGNAL, this); - auto_signal_c(destroy); - auto_signal_c(remove); - auto_signal_c(save); - auto_signal_c(load); - auto_signal_c(activate); - auto_signal_c(deactivate); - auto_signal_c(show); - auto_signal_c(hide); - auto_signal_c(mute); - auto_signal_c(push_to_mute_changed); - auto_signal_c(push_to_mute_delay); - auto_signal_c(push_to_talk_changed); - auto_signal_c(push_to_talk_delay); - auto_signal_c(enable); - auto_signal_c(rename); - auto_signal_c(volume); - auto_signal_c(update_properties); - auto_signal_c(update_flags); - auto_signal_c(audio_sync); - auto_signal_c(audio_mixers); - auto_signal_c(filter_add); - auto_signal_c(filter_remove); - auto_signal_c(reorder_filters); - auto_signal_c(transition_start); - auto_signal_c(transition_video_stop); - auto_signal_c(transition_stop); -#undef auto_signal_c - } -} - obs::source::~source() { - if (this->self) { - auto sh = obs_source_get_signal_handler(this->self); - if (sh) { -#define auto_signal_dc(SIGNAL) signal_handler_disconnect(sh, "" #SIGNAL, obs::source::handle_##SIGNAL, this); - auto_signal_dc(destroy); - auto_signal_dc(remove); - auto_signal_dc(save); - auto_signal_dc(load); - auto_signal_dc(activate); - auto_signal_dc(deactivate); - auto_signal_dc(show); - auto_signal_dc(hide); - auto_signal_dc(mute); - auto_signal_dc(push_to_mute_changed); - auto_signal_dc(push_to_mute_delay); - auto_signal_dc(push_to_talk_changed); - auto_signal_dc(push_to_talk_delay); - auto_signal_dc(enable); - auto_signal_dc(rename); - auto_signal_dc(volume); - auto_signal_dc(update_properties); - auto_signal_dc(update_flags); - auto_signal_dc(audio_sync); - auto_signal_dc(audio_mixers); - auto_signal_dc(filter_add); - auto_signal_dc(filter_remove); - auto_signal_dc(reorder_filters); - auto_signal_dc(transition_start); - auto_signal_dc(transition_video_stop); - auto_signal_dc(transition_stop); -#undef auto_signal_dc - } - } if (this->track_ownership && this->self) { obs_source_release(this->self); } this->self = nullptr; } -obs::source::source(std::string name, bool track_ownership, bool add_reference) +obs::source::source() +{ +#ifdef auto_signal_c +#undef auto_signal_c +#endif +#define auto_signal_c(SIGNAL) \ + { \ + this->events.##SIGNAL.set_listen_callback([this] { \ + auto sh = obs_source_get_signal_handler(this->self); \ + if (sh) { \ + signal_handler_connect(sh, "" #SIGNAL, obs::source::handle_##SIGNAL, this); \ + } \ + }); \ + this->events.##SIGNAL.set_silence_callback([this] { \ + auto sh = obs_source_get_signal_handler(this->self); \ + if (sh) { \ + signal_handler_disconnect(sh, "" #SIGNAL, obs::source::handle_##SIGNAL, this); \ + } \ + }); \ + } + auto_signal_c(destroy); + auto_signal_c(remove); + auto_signal_c(save); + auto_signal_c(load); + auto_signal_c(activate); + auto_signal_c(deactivate); + auto_signal_c(show); + auto_signal_c(hide); + auto_signal_c(mute); + auto_signal_c(push_to_mute_changed); + auto_signal_c(push_to_mute_delay); + auto_signal_c(push_to_talk_changed); + auto_signal_c(push_to_talk_delay); + auto_signal_c(enable); + auto_signal_c(rename); + auto_signal_c(volume); + auto_signal_c(update_properties); + auto_signal_c(update_flags); + auto_signal_c(audio_sync); + auto_signal_c(audio_mixers); + auto_signal_c(filter_add); + auto_signal_c(filter_remove); + auto_signal_c(reorder_filters); + auto_signal_c(transition_start); + auto_signal_c(transition_video_stop); + auto_signal_c(transition_stop); +#undef auto_signal_c + + // libOBS unfortunately does not use the event system for audio data callbacks, which is kind of odd as most other + // things do. So instead we'll have to manually deal with it for now. + { + this->events.audio_data.set_listen_callback( + [this] { obs_source_add_audio_capture_callback(this->self, obs::source::handle_audio_data, this); }); + this->events.audio_data.set_silence_callback( + [this] { obs_source_remove_audio_capture_callback(this->self, obs::source::handle_audio_data, this); }); + } +} + +obs::source::source(std::string name, bool track_ownership, bool add_reference) : source() { this->self = obs_get_source_by_name(name.c_str()); if (!this->self) { @@ -439,10 +439,9 @@ obs::source::source(std::string name, bool track_ownership, bool add_reference) if (!add_reference) { obs_source_release(this->self); } - connect_signals(); } -obs::source::source(obs_source_t* source, bool track_ownership, bool add_reference) +obs::source::source(obs_source_t* source, bool track_ownership, bool add_reference) : source() { this->self = source; if (!this->self) { @@ -453,7 +452,6 @@ obs::source::source(obs_source_t* source, bool track_ownership, bool add_referen if (add_reference) { obs_source_addref(this->self); } - connect_signals(); } obs::source::source(source const& other) diff --git a/source/obs/obs-source.hpp b/source/obs/obs-source.hpp index cb1f4e0..db57a5d 100644 --- a/source/obs/obs-source.hpp +++ b/source/obs/obs-source.hpp @@ -60,6 +60,7 @@ namespace obs { static void handle_volume(void* p, calldata_t* calldata); static void handle_audio_sync(void* p, calldata_t* calldata); static void handle_audio_mixers(void* p, calldata_t* calldata); + static void handle_audio_data(void* p, obs_source_t* source, const audio_data* audio, bool muted); static void handle_filter_add(void* p, calldata_t* calldata); static void handle_filter_remove(void* p, calldata_t* calldata); static void handle_reorder_filters(void* p, calldata_t* calldata); @@ -67,12 +68,11 @@ namespace obs { static void handle_transition_video_stop(void* p, calldata_t* calldata); static void handle_transition_stop(void* p, calldata_t* calldata); - private: - void connect_signals(); - public: virtual ~source(); + source(); + source(std::string name, bool track_ownership = true, bool add_reference = true); source(obs_source_t* source, bool track_ownership = true, bool add_reference = false); @@ -102,36 +102,47 @@ namespace obs { public: // Events struct { + // Destroy and Remove util::event destroy; util::event remove; + + // Saving, Loading and Update util::event save; util::event load; + util::event update_properties; + + // Activate, Deactivate util::event activate; util::event deactivate; + + // Show Hide util::event show; util::event hide; - util::event enable; + // Other + util::event enable; + util::event rename; + util::event update_flags; + // Hotkeys (PtM, PtT) util::event push_to_mute_changed; util::event push_to_mute_delay; util::event push_to_talk_changed; util::event push_to_talk_delay; - util::event rename; - - util::event update_properties; - util::event update_flags; - - util::event mute; - util::event volume; - util::event audio_sync; - util::event audio_mixers; + // Audio + util::event mute; + util::event volume; + util::event audio_sync; + util::event audio_mixers; + util::event audio_data; + // Filters util::event filter_add; util::event filter_remove; util::event reorder_filters; + // Transition util::event transition_start; util::event transition_video_stop; util::event transition_stop;