项目需要用到混音,在网上找了一个归一化混音的代码,为适应项目需求,稍加修改,仅以此作为笔记,以供学习或方便日后查找。
源码和供测试的音频文件在这里下载:
/*
*作者:韦访
*CSDN:https://blog.csdn.net/rookie_wei
***/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define IN_PCM_FILE1 "rolling.pcm"
#define IN_PCM_FILE2 "zhou.pcm"
#define OUT_MIX_FILE "mix.pcm"
/*
*要求两个音频编码一样
*/
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;
}
}
int main()
{
FILE * fp1;
FILE * fp2;
FILE * fpmix;
int size = 4*1024;
int channels = 2;
fp1 = fopen(IN_PCM_FILE1,"rb");
if (fp1 == NULL)
{
printf("Open FILE1 failed!");
goto ERROR1;
}
fp2 = fopen(IN_PCM_FILE2,"rb");
if (fp2 == NULL)
{
printf("Open FILE2 failed!");
goto ERROR2;
}
fpmix = fopen(OUT_MIX_FILE,"wb");
if (fpmix == NULL)
{
printf("Open MIX_FILE failed!");
goto ERROR3;
}
short *src_data1, *src_data2, *mix_data;
src_data1 = (short *)malloc(size);
if (src_data1 == NULL)
{
printf("Malloc data1 failed!");
goto ERROR3;
}
src_data2 = (short *)malloc(size);
if (src_data1 == NULL)
{
printf("Malloc data2 failed!");
goto ERROR4;
}
mix_data = (short *)malloc(size);
if (src_data1 == NULL)
{
printf("Malloc mix_data failed!");
goto ERROR5;
}
int ret1,ret2;
char *sourse_data[2];
printf("start mix!!\n");
while(1)
{
ret1 = fread(src_data1, 1, size, fp1);
ret2 = fread(src_data2, 1, size, fp2);
sourse_data[0] = (char *)src_data1;
sourse_data[1] = (char *)src_data2;
if(ret1 > 0 && ret2 > 0)
{
mix(sourse_data, (char *)mix_data, channels, size);
fwrite(mix_data, 1, size, fpmix);
}
else if( (ret1 > 0) && (ret2 == 0))
{
fwrite(src_data1, 1, ret1, fpmix);
}
else if( (ret2 > 0) && (ret1 == 0))
{
fwrite(src_data2, 1, ret2, fpmix);
}
else if( (ret1 == 0) && (ret2 == 0))
{
break;
}
}
printf("mix done!!\n");
free(src_data1);
free(src_data2);
free(mix_data);
fclose(fp1);
fclose(fp2);
fclose(fpmix);
return 0;
ERROR5:
free(src_data2);
ERROR4:
free(src_data1);
ERROR3:
fclose(fp2);
ERROR2:
fclose(fp1);
ERROR1:
return 0;
}
如果您感觉本篇博客对您有帮助,请打开支付宝,领个红包支持一下,祝您扫到99元,谢谢~~