diff --git a/libobs/obs-audio-controls.c b/libobs/obs-audio-controls.c index 19bdd585e..6e3ee33e0 100644 --- a/libobs/obs-audio-controls.c +++ b/libobs/obs-audio-controls.c @@ -34,9 +34,13 @@ along with this program. If not, see . typedef float (*obs_fader_conversion_t)(const float val); +struct fader_cb { + obs_fader_changed_t callback; + void *param; +}; + struct obs_fader { pthread_mutex_t mutex; - signal_handler_t *signals; obs_fader_conversion_t def_to_db; obs_fader_conversion_t db_to_def; obs_source_t *source; @@ -45,17 +49,27 @@ struct obs_fader { float min_db; float cur_db; bool ignore_next_signal; + + pthread_mutex_t callback_mutex; + DARRAY(struct fader_cb)callbacks; +}; + +struct meter_cb { + obs_volmeter_updated_t callback; + void *param; }; struct obs_volmeter { pthread_mutex_t mutex; - signal_handler_t *signals; obs_fader_conversion_t pos_to_db; obs_fader_conversion_t db_to_pos; obs_source_t *source; enum obs_fader_type type; float cur_db; + pthread_mutex_t callback_mutex; + DARRAY(struct meter_cb)callbacks; + unsigned int channels; unsigned int update_ms; unsigned int update_frames; @@ -72,17 +86,6 @@ struct obs_volmeter { float vol_max; }; -static const char *fader_signals[] = { - "void volume_changed(ptr fader, float db)", - NULL -}; - -static const char *volmeter_signals[] = { - "void levels_updated(ptr volmeter, float level, " - "float magnitude, float peak, bool muted)", - NULL -}; - static float cubic_def_to_db(const float def) { if (def == 1.0f) @@ -191,39 +194,26 @@ static float log_db_to_def(const float db) / (LOG_OFFSET_VAL - LOG_RANGE_VAL); } -static void signal_volume_changed(signal_handler_t *sh, - struct obs_fader *fader, const float db) +static void signal_volume_changed(struct obs_fader *fader, const float db) { - struct calldata data; - - calldata_init(&data); - - calldata_set_ptr (&data, "fader", fader); - calldata_set_float(&data, "db", db); - - signal_handler_signal(sh, "volume_changed", &data); - - calldata_free(&data); + pthread_mutex_lock(&fader->callback_mutex); + for (size_t i = fader->callbacks.num; i > 0; i--) { + struct fader_cb cb = fader->callbacks.array[i - 1]; + cb.callback(cb.param, db); + } + pthread_mutex_unlock(&fader->callback_mutex); } -static void signal_levels_updated(signal_handler_t *sh, - struct obs_volmeter *volmeter, +static void signal_levels_updated(struct obs_volmeter *volmeter, const float level, const float magnitude, const float peak, bool muted) { - struct calldata data; - - calldata_init(&data); - - calldata_set_ptr (&data, "volmeter", volmeter); - calldata_set_float(&data, "level", level); - calldata_set_float(&data, "magnitude", magnitude); - calldata_set_float(&data, "peak", peak); - calldata_set_bool (&data, "muted", muted); - - signal_handler_signal(sh, "levels_updated", &data); - - calldata_free(&data); + pthread_mutex_lock(&volmeter->callback_mutex); + for (size_t i = volmeter->callbacks.num; i > 0; i--) { + struct meter_cb cb = volmeter->callbacks.array[i - 1]; + cb.callback(cb.param, level, magnitude, peak, muted); + } + pthread_mutex_unlock(&volmeter->callback_mutex); } static void fader_source_volume_changed(void *vptr, calldata_t *calldata) @@ -238,14 +228,13 @@ static void fader_source_volume_changed(void *vptr, calldata_t *calldata) return; } - signal_handler_t *sh = fader->signals; const float mul = (float)calldata_float(calldata, "volume"); const float db = mul_to_db(mul); fader->cur_db = db; pthread_mutex_unlock(&fader->mutex); - signal_volume_changed(sh, fader, db); + signal_volume_changed(fader, db); } static void volmeter_source_volume_changed(void *vptr, calldata_t *calldata) @@ -335,7 +324,7 @@ static void volmeter_calc_ival_levels(obs_volmeter_t *volmeter) } static bool volmeter_process_audio_data(obs_volmeter_t *volmeter, - struct audio_data *data) + const struct audio_data *data) { bool updated = false; size_t frames = 0; @@ -374,16 +363,15 @@ static bool volmeter_process_audio_data(obs_volmeter_t *volmeter, return updated; } -static void volmeter_source_data_received(void *vptr, calldata_t *calldata) +static void volmeter_source_data_received(void *vptr, obs_source_t *source, + const struct audio_data *data, bool muted) { struct obs_volmeter *volmeter = (struct obs_volmeter *) vptr; bool updated = false; float mul, level, mag, peak; - signal_handler_t *sh; pthread_mutex_lock(&volmeter->mutex); - struct audio_data *data = calldata_ptr(calldata, "data"); updated = volmeter_process_audio_data(volmeter, data); if (updated) { @@ -393,14 +381,14 @@ static void volmeter_source_data_received(void *vptr, calldata_t *calldata) mag = volmeter->db_to_pos(mul_to_db(volmeter->vol_mag * mul)); peak = volmeter->db_to_pos( mul_to_db(volmeter->vol_peak * mul)); - sh = volmeter->signals; } pthread_mutex_unlock(&volmeter->mutex); if (updated) - signal_levels_updated(sh, volmeter, level, mag, peak, - calldata_bool(calldata, "muted")); + signal_levels_updated(volmeter, level, mag, peak, muted); + + UNUSED_PARAMETER(source); } static void volmeter_update_audio_settings(obs_volmeter_t *volmeter) @@ -420,12 +408,10 @@ obs_fader_t *obs_fader_create(enum obs_fader_type type) return NULL; pthread_mutex_init_value(&fader->mutex); + pthread_mutex_init_value(&fader->callback_mutex); if (pthread_mutex_init(&fader->mutex, NULL) != 0) goto fail; - fader->signals = signal_handler_create(); - if (!fader->signals) - goto fail; - if (!signal_handler_add_array(fader->signals, fader_signals)) + if (pthread_mutex_init(&fader->callback_mutex, NULL) != 0) goto fail; switch(type) { @@ -465,7 +451,8 @@ void obs_fader_destroy(obs_fader_t *fader) return; obs_fader_detach_source(fader); - signal_handler_destroy(fader->signals); + da_free(fader->callbacks); + pthread_mutex_destroy(&fader->callback_mutex); pthread_mutex_destroy(&fader->mutex); bfree(fader); @@ -603,9 +590,30 @@ exit: pthread_mutex_unlock(&fader->mutex); } -signal_handler_t *obs_fader_get_signal_handler(obs_fader_t *fader) +void obs_fader_add_callback(obs_fader_t *fader, obs_fader_changed_t callback, + void *param) { - return (fader) ? fader->signals : NULL; + struct fader_cb cb = {callback, param}; + + if (!obs_ptr_valid(fader, "obs_fader_add_callback")) + return; + + pthread_mutex_lock(&fader->callback_mutex); + da_push_back(fader->callbacks, &cb); + pthread_mutex_unlock(&fader->callback_mutex); +} + +void obs_fader_remove_callback(obs_fader_t *fader, obs_fader_changed_t callback, + void *param) +{ + struct fader_cb cb = {callback, param}; + + if (!obs_ptr_valid(fader, "obs_fader_remove_callback")) + return; + + pthread_mutex_lock(&fader->callback_mutex); + da_erase_item(fader->callbacks, &cb); + pthread_mutex_unlock(&fader->callback_mutex); } obs_volmeter_t *obs_volmeter_create(enum obs_fader_type type) @@ -615,12 +623,10 @@ obs_volmeter_t *obs_volmeter_create(enum obs_fader_type type) return NULL; pthread_mutex_init_value(&volmeter->mutex); + pthread_mutex_init_value(&volmeter->callback_mutex); if (pthread_mutex_init(&volmeter->mutex, NULL) != 0) goto fail; - volmeter->signals = signal_handler_create(); - if (!volmeter->signals) - goto fail; - if (!signal_handler_add_array(volmeter->signals, volmeter_signals)) + if (pthread_mutex_init(&volmeter->callback_mutex, NULL) != 0) goto fail; /* set conversion functions */ @@ -658,7 +664,8 @@ void obs_volmeter_destroy(obs_volmeter_t *volmeter) return; obs_volmeter_detach_source(volmeter); - signal_handler_destroy(volmeter->signals); + da_free(volmeter->callbacks); + pthread_mutex_destroy(&volmeter->callback_mutex); pthread_mutex_destroy(&volmeter->mutex); bfree(volmeter); @@ -678,10 +685,10 @@ bool obs_volmeter_attach_source(obs_volmeter_t *volmeter, obs_source_t *source) sh = obs_source_get_signal_handler(source); signal_handler_connect(sh, "volume", volmeter_source_volume_changed, volmeter); - signal_handler_connect(sh, "audio_data", - volmeter_source_data_received, volmeter); signal_handler_connect(sh, "destroy", volmeter_source_destroyed, volmeter); + obs_source_add_audio_capture_callback(source, + volmeter_source_data_received, volmeter); volmeter->source = source; volmeter->cur_db = mul_to_db(obs_source_get_volume(source)); @@ -706,10 +713,10 @@ void obs_volmeter_detach_source(obs_volmeter_t *volmeter) sh = obs_source_get_signal_handler(volmeter->source); signal_handler_disconnect(sh, "volume", volmeter_source_volume_changed, volmeter); - signal_handler_disconnect(sh, "audio_data", - volmeter_source_data_received, volmeter); signal_handler_disconnect(sh, "destroy", volmeter_source_destroyed, volmeter); + obs_source_remove_audio_capture_callback(volmeter->source, + volmeter_source_data_received, volmeter); volmeter->source = NULL; @@ -717,11 +724,6 @@ exit: pthread_mutex_unlock(&volmeter->mutex); } -signal_handler_t *obs_volmeter_get_signal_handler(obs_volmeter_t *volmeter) -{ - return (volmeter) ? volmeter->signals : NULL; -} - void obs_volmeter_set_update_interval(obs_volmeter_t *volmeter, const unsigned int ms) { @@ -768,3 +770,29 @@ unsigned int obs_volmeter_get_peak_hold(obs_volmeter_t *volmeter) return peakhold; } + +void obs_volmeter_add_callback(obs_volmeter_t *volmeter, + obs_volmeter_updated_t callback, void *param) +{ + struct meter_cb cb = {callback, param}; + + if (!obs_ptr_valid(volmeter, "obs_volmeter_add_callback")) + return; + + pthread_mutex_lock(&volmeter->callback_mutex); + da_push_back(volmeter->callbacks, &cb); + pthread_mutex_unlock(&volmeter->callback_mutex); +} + +void obs_volmeter_remove_callback(obs_volmeter_t *volmeter, + obs_volmeter_updated_t callback, void *param) +{ + struct meter_cb cb = {callback, param}; + + if (!obs_ptr_valid(volmeter, "obs_volmeter_remove_callback")) + return; + + pthread_mutex_lock(&volmeter->callback_mutex); + da_erase_item(volmeter->callbacks, &cb); + pthread_mutex_unlock(&volmeter->callback_mutex); +} diff --git a/libobs/obs-audio-controls.h b/libobs/obs-audio-controls.h index 857c6816a..89020afee 100644 --- a/libobs/obs-audio-controls.h +++ b/libobs/obs-audio-controls.h @@ -154,12 +154,12 @@ EXPORT bool obs_fader_attach_source(obs_fader_t *fader, obs_source_t *source); */ EXPORT void obs_fader_detach_source(obs_fader_t *fader); -/** - * @brief Get signal handler for the fader - * @param fader pointer to the fader object - * @return signal handler - */ -EXPORT signal_handler_t *obs_fader_get_signal_handler(obs_fader_t *fader); +typedef void (*obs_fader_changed_t)(void *param, float db); + +EXPORT void obs_fader_add_callback(obs_fader_t *fader, + obs_fader_changed_t callback, void *param); +EXPORT void obs_fader_remove_callback(obs_fader_t *fader, + obs_fader_changed_t callback, void *param); /** * @brief Create a volume meter @@ -251,6 +251,14 @@ EXPORT void obs_volmeter_set_peak_hold(obs_volmeter_t *volmeter, */ EXPORT unsigned int obs_volmeter_get_peak_hold(obs_volmeter_t *volmeter); +typedef void (*obs_volmeter_updated_t)(void *param, float level, + float magnitude, float peak, float muted); + +EXPORT void obs_volmeter_add_callback(obs_volmeter_t *volmeter, + obs_volmeter_updated_t callback, void *param); +EXPORT void obs_volmeter_remove_callback(obs_volmeter_t *volmeter, + obs_volmeter_updated_t callback, void *param); + #ifdef __cplusplus } #endif diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index 960a3f891..12511d5a2 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -485,6 +485,11 @@ struct obs_weak_source { struct obs_source *source; }; +struct audio_cb_info { + obs_source_audio_capture_t callback; + void *param; +}; + struct obs_source { struct obs_context_data context; struct obs_source_info info; @@ -542,6 +547,8 @@ struct obs_source { pthread_mutex_t audio_actions_mutex; pthread_mutex_t audio_buf_mutex; pthread_mutex_t audio_mutex; + pthread_mutex_t audio_cb_mutex; + DARRAY(struct audio_cb_info) audio_cb_list; struct obs_audio_data audio_data; size_t audio_storage_size; uint32_t audio_mixers; diff --git a/libobs/obs-source.c b/libobs/obs-source.c index fb017229b..474517136 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -65,7 +65,6 @@ static const char *source_signals[] = { "void update_properties(ptr source)", "void update_flags(ptr source, int flags)", "void audio_sync(ptr source, int out int offset)", - "void audio_data(ptr source, ptr data, bool muted)", "void audio_mixers(ptr source, in out int mixers)", "void filter_add(ptr source, ptr filter)", "void filter_remove(ptr source, ptr filter)", @@ -131,6 +130,7 @@ bool obs_source_init(struct obs_source *source) pthread_mutex_init_value(&source->async_mutex); pthread_mutex_init_value(&source->audio_mutex); pthread_mutex_init_value(&source->audio_buf_mutex); + pthread_mutex_init_value(&source->audio_cb_mutex); if (pthread_mutexattr_init(&attr) != 0) return false; @@ -142,6 +142,8 @@ bool obs_source_init(struct obs_source *source) return false; if (pthread_mutex_init(&source->audio_actions_mutex, NULL) != 0) return false; + if (pthread_mutex_init(&source->audio_cb_mutex, NULL) != 0) + return false; if (pthread_mutex_init(&source->audio_mutex, NULL) != 0) return false; if (pthread_mutex_init(&source->async_mutex, NULL) != 0) @@ -415,12 +417,14 @@ void obs_source_destroy(struct obs_source *source) obs_transition_free(source); da_free(source->audio_actions); + da_free(source->audio_cb_list); da_free(source->async_cache); da_free(source->async_frames); da_free(source->filters); pthread_mutex_destroy(&source->filter_mutex); pthread_mutex_destroy(&source->audio_actions_mutex); pthread_mutex_destroy(&source->audio_buf_mutex); + pthread_mutex_destroy(&source->audio_cb_mutex); pthread_mutex_destroy(&source->audio_mutex); pthread_mutex_destroy(&source->async_mutex); obs_context_data_free(&source->context); @@ -912,17 +916,14 @@ static void handle_ts_jump(obs_source_t *source, uint64_t expected, static void source_signal_audio_data(obs_source_t *source, struct audio_data *in, bool muted) { - struct calldata data; + pthread_mutex_lock(&source->audio_cb_mutex); - calldata_init(&data); + for (size_t i = source->audio_cb_list.num; i > 0; i--) { + struct audio_cb_info info = source->audio_cb_list.array[i - 1]; + info.callback(info.param, source, in, muted); + } - calldata_set_ptr(&data, "source", source); - calldata_set_ptr(&data, "data", in); - calldata_set_bool(&data, "muted", muted); - - signal_handler_signal(source->context.signals, "audio_data", &data); - - calldata_free(&data); + pthread_mutex_unlock(&source->audio_cb_mutex); } static inline uint64_t uint64_diff(uint64_t ts1, uint64_t ts2) @@ -3531,3 +3532,29 @@ void obs_source_get_audio_mix(const obs_source_t *source, } } } + +void obs_source_add_audio_capture_callback(obs_source_t *source, + obs_source_audio_capture_t callback, void *param) +{ + struct audio_cb_info info = {callback, param}; + + if (!obs_source_valid(source, "obs_source_add_audio_capture_callback")) + return; + + pthread_mutex_lock(&source->audio_cb_mutex); + da_push_back(source->audio_cb_list, &info); + pthread_mutex_unlock(&source->audio_cb_mutex); +} + +void obs_source_remove_audio_capture_callback(obs_source_t *source, + obs_source_audio_capture_t callback, void *param) +{ + struct audio_cb_info info = {callback, param}; + + if (!obs_source_valid(source, "obs_source_remove_audio_capture_callback")) + return; + + pthread_mutex_lock(&source->audio_cb_mutex); + da_erase_item(source->audio_cb_list, &info); + pthread_mutex_unlock(&source->audio_cb_mutex); +} diff --git a/libobs/obs.h b/libobs/obs.h index 9a6ebdf7b..6714cc379 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -844,6 +844,14 @@ EXPORT uint64_t obs_source_get_push_to_talk_delay(obs_source_t *source); EXPORT void obs_source_set_push_to_talk_delay(obs_source_t *source, uint64_t delay); +typedef void (*obs_source_audio_capture_t)(void *param, obs_source_t *source, + const struct audio_data *audio_data, bool muted); + +EXPORT void obs_source_add_audio_capture_callback(obs_source_t *source, + obs_source_audio_capture_t callback, void *param); +EXPORT void obs_source_remove_audio_capture_callback(obs_source_t *source, + obs_source_audio_capture_t callback, void *param); + /* ------------------------------------------------------------------------- */ /* Functions used by sources */ diff --git a/obs/volume-control.cpp b/obs/volume-control.cpp index 568bdbbc5..02456a48e 100644 --- a/obs/volume-control.cpp +++ b/obs/volume-control.cpp @@ -16,26 +16,23 @@ using namespace std; -void VolControl::OBSVolumeChanged(void *data, calldata_t *calldata) +void VolControl::OBSVolumeChanged(void *data, float db) { - Q_UNUSED(calldata); + Q_UNUSED(db); VolControl *volControl = static_cast(data); QMetaObject::invokeMethod(volControl, "VolumeChanged"); } -void VolControl::OBSVolumeLevel(void *data, calldata_t *calldata) +void VolControl::OBSVolumeLevel(void *data, float level, float mag, + float peak, float muted) { VolControl *volControl = static_cast(data); - float peak = calldata_float(calldata, "level"); - float mag = calldata_float(calldata, "magnitude"); - float peakHold = calldata_float(calldata, "peak"); - bool muted = calldata_bool (calldata, "muted"); QMetaObject::invokeMethod(volControl, "VolumeLevel", Q_ARG(float, mag), + Q_ARG(float, level), Q_ARG(float, peak), - Q_ARG(float, peakHold), Q_ARG(bool, muted)); } @@ -174,11 +171,8 @@ VolControl::VolControl(OBSSource source_, bool showConfig) setLayout(mainLayout); - signal_handler_connect(obs_fader_get_signal_handler(obs_fader), - "volume_changed", OBSVolumeChanged, this); - - signal_handler_connect(obs_volmeter_get_signal_handler(obs_volmeter), - "levels_updated", OBSVolumeLevel, this); + obs_fader_add_callback(obs_fader, OBSVolumeChanged, this); + obs_volmeter_add_callback(obs_volmeter, OBSVolumeLevel, this); signal_handler_connect(obs_source_get_signal_handler(source), "mute", OBSVolumeMuted, this); @@ -199,11 +193,8 @@ VolControl::VolControl(OBSSource source_, bool showConfig) VolControl::~VolControl() { - signal_handler_disconnect(obs_fader_get_signal_handler(obs_fader), - "volume_changed", OBSVolumeChanged, this); - - signal_handler_disconnect(obs_volmeter_get_signal_handler(obs_volmeter), - "levels_updated", OBSVolumeLevel, this); + obs_fader_remove_callback(obs_fader, OBSVolumeChanged, this); + obs_volmeter_remove_callback(obs_volmeter, OBSVolumeLevel, this); signal_handler_disconnect(obs_source_get_signal_handler(source), "mute", OBSVolumeMuted, this); diff --git a/obs/volume-control.hpp b/obs/volume-control.hpp index a1fb10f6f..27b52b207 100644 --- a/obs/volume-control.hpp +++ b/obs/volume-control.hpp @@ -56,8 +56,9 @@ private: obs_fader_t *obs_fader; obs_volmeter_t *obs_volmeter; - static void OBSVolumeChanged(void *param, calldata_t *calldata); - static void OBSVolumeLevel(void *data, calldata_t *calldata); + static void OBSVolumeChanged(void *param, float db); + static void OBSVolumeLevel(void *data, float level, float mag, + float peak, float muted); static void OBSVolumeMuted(void *data, calldata_t *calldata); void EmitConfigClicked();