归一化混音 c语言源码

项目需要用到混音,在网上找了一个归一化混音的代码,为适应项目需求,稍加修改,仅以此作为笔记,以供学习或方便日后查找。

源码和供测试的音频文件在这里下载:

点击打开链接

/*
*作者:韦访
*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;
}  

猜你喜欢

转载自blog.csdn.net/rookie_wei/article/details/80460252