# 音频混音算法的实现

### 线性叠加后求平均

short  remix(short buffer1,short buffer2)
{
int value = buffer1 + buffer2;
return (short)(value/2);
}

### 归一化混音(自适应加权混音算法)

#### 方法：

void Mix(char sourseFile[10][SIZE_AUDIO_FRAME],int number,char *objectFile)
{
//归一化混音
int const MAX=32767;
int const MIN=-32768;

double f=1;
int output;
int i = 0,j = 0;
for (i=0;i<SIZE_AUDIO_FRAME/2;i++)
{
int temp=0;
for (j=0;j<number;j++)
{
temp+=*(short*)(sourseFile[j]+i*2);
}
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*)(objectFile+i*2)=(short)output;
}
}  

### 下面是我从newlc上找到的一个关于PCM脉冲编码的音频信号的混音实现，其中包含了一个关键的混音算法！

if( data1 < 0 && data2 < 0)
date_mix = data1+data2 - (data1 * data2 / -(pow(2,16-1)-1));
else
date_mix = data1+data2 - (data1 * data2 / (pow(2,16-1)-1)); 

### 下面是上面的混音的测试代码：

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define IN_FILE1 "1.wav"
#define IN_FILE2 "2.wav"
#define OUT_FILE "remix.pcm"

#define SIZE_AUDIO_FRAME (2)

void Mix(char sourseFile[10][SIZE_AUDIO_FRAME],int number,char *objectFile)
{
//归一化混音
int const MAX=32767;
int const MIN=-32768;

double f=1;
int output;
int i = 0,j = 0;
for (i=0;i<SIZE_AUDIO_FRAME/2;i++)
{
int temp=0;
for (j=0;j<number;j++)
{
temp+=*(short*)(sourseFile[j]+i*2);
}
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*)(objectFile+i*2)=(short)output;
}
}

int main()
{
FILE * fp1,*fp2,*fpm;
fp1 = fopen(IN_FILE1,"rb");
fp2 = fopen(IN_FILE2,"rb");
fpm = fopen(OUT_FILE,"wb");

short data1,data2,date_mix;
int ret1,ret2;
char sourseFile[10][2];

while(1)
{
*(short*) sourseFile[0] = data1;
*(short*) sourseFile[1] = data2;

if(ret1>0 && ret2>0)
{
Mix(sourseFile,2,(char *)&date_mix);
/*
if( data1 < 0 && data2 < 0)
date_mix = data1+data2 - (data1 * data2 / -(pow(2,16-1)-1));
else
date_mix = data1+data2 - (data1 * data2 / (pow(2,16-1)-1));*/

if(date_mix > pow(2,16-1) || date_mix < -pow(2,16-1))
printf("mix error\n");
}
else if( (ret1 > 0) && (ret2==0))
{
date_mix = data1;
}
else if( (ret2 > 0) && (ret1==0))
{
date_mix = data2;
}
else if( (ret1 == 0) && (ret2 == 0))
{
break;
}
fwrite(&date_mix,2,1,fpm);
}
fclose(fp1);
fclose(fp2);
fclose(fpm);
printf("Done!\n");
}  

07-09 111

07-01 512

05-15 3587

09-24 2465

06-27 131

#### 详解如何使用代码进行音频合成

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。