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();