100 lines
2.7 KiB
C
100 lines
2.7 KiB
C
#include <obs.h>
|
|
#include "audio-wrapper-source.h"
|
|
|
|
const char *audio_wrapper_get_name(void *type_data)
|
|
{
|
|
UNUSED_PARAMETER(type_data);
|
|
return "transition_audio_wrapper";
|
|
}
|
|
|
|
void *audio_wrapper_create(obs_data_t *settings, obs_source_t *source)
|
|
{
|
|
UNUSED_PARAMETER(settings);
|
|
struct audio_wrapper_info *audio_wrapper = bzalloc(sizeof(struct audio_wrapper_info));
|
|
audio_wrapper->source = source;
|
|
return audio_wrapper;
|
|
}
|
|
|
|
void audio_wrapper_destroy(void *data)
|
|
{
|
|
bfree(data);
|
|
}
|
|
|
|
bool audio_wrapper_render(void *data, uint64_t *ts_out, struct obs_source_audio_mix *audio, uint32_t mixers, size_t channels,
|
|
size_t sample_rate)
|
|
{
|
|
UNUSED_PARAMETER(sample_rate);
|
|
struct audio_wrapper_info *aw = (struct audio_wrapper_info *)data;
|
|
obs_source_t *source = aw->target(aw->param);
|
|
if (!source)
|
|
return false;
|
|
|
|
uint64_t timestamp = obs_source_get_audio_timestamp(source);
|
|
if (!timestamp) {
|
|
obs_source_release(source);
|
|
return false;
|
|
}
|
|
if (!aw->mixers) {
|
|
*ts_out = timestamp;
|
|
obs_source_release(source);
|
|
return true;
|
|
}
|
|
mixers &= aw->mixers(aw->param);
|
|
if (mixers == 0) {
|
|
*ts_out = timestamp;
|
|
obs_source_release(source);
|
|
return true;
|
|
}
|
|
struct obs_source_audio_mix child_audio;
|
|
obs_source_get_audio_mix(source, &child_audio);
|
|
for (size_t mix = 0; mix < MAX_AUDIO_MIXES; mix++) {
|
|
if ((mixers & (1 << mix)) == 0)
|
|
continue;
|
|
|
|
for (size_t ch = 0; ch < channels; ch++) {
|
|
float *out = audio->output[mix].data[ch];
|
|
float *in = child_audio.output[mix].data[ch];
|
|
float *end = in + AUDIO_OUTPUT_FRAMES;
|
|
while (in < end)
|
|
*(out++) += *(in++);
|
|
}
|
|
}
|
|
*ts_out = timestamp;
|
|
obs_source_release(source);
|
|
return true;
|
|
}
|
|
|
|
static void audio_wrapper_enum_sources(void *data, obs_source_enum_proc_t enum_callback, void *param, bool active)
|
|
{
|
|
UNUSED_PARAMETER(active);
|
|
struct audio_wrapper_info *aw = (struct audio_wrapper_info *)data;
|
|
obs_source_t *source = aw->target(aw->param);
|
|
if (!source)
|
|
return;
|
|
|
|
enum_callback(aw->source, source, param);
|
|
|
|
obs_source_release(source);
|
|
}
|
|
|
|
void audio_wrapper_enum_active_sources(void *data, obs_source_enum_proc_t enum_callback, void *param)
|
|
{
|
|
audio_wrapper_enum_sources(data, enum_callback, param, true);
|
|
}
|
|
|
|
void audio_wrapper_enum_all_sources(void *data, obs_source_enum_proc_t enum_callback, void *param)
|
|
{
|
|
audio_wrapper_enum_sources(data, enum_callback, param, false);
|
|
}
|
|
|
|
struct obs_source_info audio_wrapper_source = {
|
|
.id = "vertical_audio_wrapper_source",
|
|
.type = OBS_SOURCE_TYPE_SCENE,
|
|
.output_flags = OBS_SOURCE_COMPOSITE | OBS_SOURCE_CAP_DISABLED,
|
|
.get_name = audio_wrapper_get_name,
|
|
.create = audio_wrapper_create,
|
|
.destroy = audio_wrapper_destroy,
|
|
.audio_render = audio_wrapper_render,
|
|
.enum_active_sources = audio_wrapper_enum_active_sources,
|
|
.enum_all_sources = audio_wrapper_enum_all_sources,
|
|
};
|