当前位置: 首页 > article >正文

C++ 多路音频pcm混音算法

1、均值化混音算法

不适合商用,声音的损失比较大,不建议用,建议用第二种声音混音

short remix(short pcm1,short pcm2){

int value = pcm1+ pcm2;

return (short)(value/2)

}

2、归一化混音算法

输入数据为48Khz-2-16bit音频数据

方法:为避免发生溢出,使用一个可变的衰减因子对语音进行衰减。这个衰减因子也就代表语音的权重,衰减因子随着音频数据的变化而变化,所以称为自适应加权混音。当溢出时,衰减因子较小,使得溢出的数据在衰减后能够处于临界值以内,而在没有溢出时,又让衰减因子慢慢增大,使数据较为平缓的变化。(PCM音频混合的方法_pcm混音算法-CSDN博客)

//归一化混音    

void mix(char **src_data, char *mix_data, int channels, int buffer_size)
        {
            int const MAX = 32767;
            int const MIN = -32768;
            double f = 1;
            int output;
            int i = 0, j = 0;
            for (i = 0; i < buffer_size / channels; i++)
            {
                int temp = 0;
                for (j = 0; j < channels; j++)
                {
                    temp += *(short*)(src_data[j] + i * channels);
                }
                output = (int)(temp*f);
                if (output > MAX)
                {
                    f = (double)MAX / (double)(output);
                    output = MAX;
                }
                if (output < MIN)
                {
                    f = (double)MIN / (double)(output);
                    output = MIN;
                }
                if (f < 1)
                {
                    f += ((double)1 - f) / (double)32;
                }
                *(short*)(mix_data + i * 2) = (short)output;
            }
        }

调用方法:

char *testSrcData[2] = { NULL };
 testSrcData[0] = 声音通道1数据
 testSrcData[1] = 声音通道2数据
 mix(testSrcData, mix_data, 2, buffer_size);

3、其他方法本人没用过,不好评价,不过感觉第二种够用了,至少目前没什么特别大的反馈
4、混音的思路

采集多路pcm数据-》统一重采样成48Khz-2通道-16bit-》归一化混音


http://www.kler.cn/a/272025.html

相关文章:

  • JavaScript笔记APIs篇01——DOM获取与属性操作
  • OpenVela 各模块之间的交互方式和数据流
  • GPT 结束语设计 以nanogpt为例
  • Python----Python高级(正则表达式:语法规则,re库)
  • Linux——信号量和(环形队列消费者模型)
  • adb 命令使用大全
  • Web核心,HTTP,tomcat,Servlet
  • 力扣练习题2
  • 文件夹秒变应用程序?别慌,数据恢复有妙招!
  • 安装Pytorch——CPU版本
  • Rust 的 HashMap
  • 04- 人有多大胆,地有多大产 到 按需分配 - sealed JDK17
  • Python电梯楼层数字识别
  • 力扣--二叉树的最近公共祖先
  • Linux查看硬件型号详细信息
  • 在 Rust 中使用 Serde 处理json
  • 华为三层交换机:ACL的基本实验
  • 数据库基本知识
  • Kotlin:为什么创建类不能被继承
  • 88. 合并两个有序数组 (Swift版本)
  • sxf-漏洞研究员实习
  • DFL《384底丹 430万》 wf/df-udt/448/96/96/32预训练模型
  • unet各模块内容的理解(包含注意力机制、残差、以及数据维度的变化)
  • 软件杯 深度学习 python opencv 动物识别与检测
  • 最强AI换脸工具Rope使用教程,Rope整合包下载【全网最全安装步骤】
  • 内存函数memcpy和memmove的讲解