惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
N
Netflix TechBlog - Medium
宝玉的分享
宝玉的分享
Google DeepMind News
Google DeepMind News
腾讯CDC
G
Google Developers Blog
Martin Fowler
Martin Fowler
Microsoft Security Blog
Microsoft Security Blog
Recent Announcements
Recent Announcements
爱范儿
爱范儿
Engineering at Meta
Engineering at Meta
Microsoft Azure Blog
Microsoft Azure Blog
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
有赞技术团队
有赞技术团队
Jina AI
Jina AI
人人都是产品经理
人人都是产品经理
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
M
MIT News - Artificial intelligence
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
美团技术团队
WordPress大学
WordPress大学
阮一峰的网络日志
阮一峰的网络日志

博客园 - woaiusd

claude各种客户端的关系 pytorch对大模型推理,实现简单的对话 Agent原理与模拟 为红米Note 5 Pro编译Lineage OS 15.1的各种坑 C语言调用DIRECT3D的实例代码,通过lpVtbl字段进行 从工程角度看C++观察者模式中的接口是否需要提供默认的实现 Windows音频SDK的发展历程 闲话__stdcall, __cdecl, __fastcall出现的历史背景以及各自解决的问题 为什么需要超出48K的音频采样率,以及PCM到DSD的演进 wireshark使用笔记 managed_shared_memory.construct造成的性能损失 java.lang.NullPointerException Ubuntu中QT使用FFmpeg的奇怪问题 QT开启C++11的支持 尝鲜CodeBlocks ops中set_sysclk set_clkdiv set_pll详解 在内核中异步请求设备固件firmware的测试代码 探究MaxxBass音效 Alsa驱动snd_soc_read的底层实现 Device Drivers Should Not Do Power Management 探究platform_driver中“多态”思想 探究platform_driver中的shutdown用途
OBS插件学习入门:一个非常简单的、调节音量的filter
woaiusd · 2017-12-26 · via 博客园 - woaiusd

一个非常简单的、调节音量的filter,非线性调节:

#include <obs-module.h>
#include <math.h>

struct volume_data {
    obs_source_t *context;
    size_t channels;
    float factor;
};

static const char *volume_name(void *unused)
{
    UNUSED_PARAMETER(unused);
    return obs_module_text("Volume");
}

static void volume_destroy(void *data)
{
    struct volume_data *gf = data;
    bfree(gf);
}

static void volume_update(void *data, obs_data_t *s)
{
    struct volume_data *gf = data;
    double val = obs_data_get_double(s, "volume");
    gf->channels = audio_output_get_channels(obs_get_audio());
    gf->factor = (float)val;
}

static void *volume_create(obs_data_t *settings, obs_source_t *filter)
{
    struct volume_data *gf = bzalloc(sizeof(*gf));
    gf->context = filter;
    volume_update(gf, settings);
    return gf;
}

static struct obs_audio_data *volume_filter_audio(void *data, struct obs_audio_data *audio)
{
    struct volume_data *gf = data;
    const size_t channels = gf->channels;
    float **adata = (float**)audio->data;
    const float factor = gf->factor;

    for (size_t c = 0; c < channels; c++) {
        if (audio->data[c]) {
            for (size_t i = 0; i < audio->frames; i++) {
                adata[c][i] *= factor;
            }
        }
    }

    return audio;
}

static void volume_defaults(obs_data_t *s)
{
    obs_data_set_default_double(s, "volume", 1.0f);
}

static obs_properties_t *volume_properties(void *data)
{
    obs_properties_t *ppts = obs_properties_create();

    obs_properties_add_float_slider(ppts, "volume", "Volume", 0, 1.0, 0.1);

    UNUSED_PARAMETER(data);
    return ppts;
}

struct obs_source_info volume_filter = {
    .id = "volume_filter",
    .type = OBS_SOURCE_TYPE_FILTER,
    .output_flags = OBS_SOURCE_AUDIO,
    .get_name = volume_name,
    .create = volume_create,
    .destroy = volume_destroy,
    .update = volume_update,
    .filter_audio = volume_filter_audio,
    .get_defaults = volume_defaults,
    .get_properties = volume_properties,
};