混音算法研究

来源:互联网 发布:辛普森杀妻案真凶 知乎 编辑:程序博客网 时间:2024/05/02 04:22

转载请注明原创地址:  http://blog.csdn.net/iflychenyang/article/details/8694147

结合上篇转载的日志做了个research,没达到理想的效果(我在一边调程序,一边听音乐,混合出来的声音差点没把我耳朵炸坏掉),还是把程序贴出来吧,明天晚上继续研究。


////  Mixer.cpp//  语音合成助手(iphone上appstore中可下载这款软件)////  Created by chen yang on 13-3-19.//  Copyright 2013 陈阳. All rights reserved.//#include <string.h>#include <stdio.h>#include <math.h>#include <malloc.h>/********以下是wave格式文件的文件头格式说明******//*------------------------------------------------ |             RIFF WAVE Chunk                  | |             ID = 'RIFF'                     | |             RiffType = 'WAVE'                | ------------------------------------------------ |             Format Chunk                     | |             ID = 'fmt '                      | ------------------------------------------------ |             Fact Chunk(optional)             | |             ID = 'fact'                      | ------------------------------------------------ |             Data Chunk                       | |             ID = 'data'                      | ------------------------------------------------*//**********以上是wave文件格式头格式说明***********//*wave 文件一共有四个Chunk组成,其中第三个Chunk可以省略,每个Chunk有标示(ID), 大小(size,就是本Chunk的内容部分长度),内容三部分组成*/struct TWavehead{/****RIFF WAVE CHUNK*/unsigned char a[4];//四个字节存放'R','I','F','F'long int b;        //整个文件的长度-8;每个Chunk的size字段,都是表示除了本Chunk的ID和SIZE字段外的长度;unsigned char c[4];//四个字节存放'W','A','V','E'/****RIFF WAVE CHUNK*//****Format CHUNK*/unsigned char d[4];//四个字节存放'f','m','t',''long int e;       //16后没有附加消息,18后有附加消息;一般为16,其他格式转来的话为18short int f;       //编码方式,一般为0x0001;short int g;       //声道数目,1单声道,2双声道;long int h;        //采样频率;long int i;        //每秒所需字节数;short int j;       //每个采样需要多少字节,若声道是双,则两个一起考虑;short int k;       //即量化位数/****Format CHUNK*//***Data Chunk**/unsigned char p[4];//四个字节存放'd','a','t','a'long int q;        //语音数据部分长度,不包括文件头的任何部分};//定义WAVE文件的文件头结构体typedef struct TWavehead TWavehead;void writeHead(FILE *fp, long int filesize){if (fp == NULL){return;}const int CHANNELS = 1;const int RATE = 16000;const int SIZE = 16;struct TWavehead wavehead;wavehead.a[0] = 'R';wavehead.a[1] = 'I';wavehead.a[2] = 'F';wavehead.a[3] = 'F';wavehead.b = filesize - 8;wavehead.c[0] = 'W';wavehead.c[1] = 'A';wavehead.c[2] = 'V';wavehead.c[3] = 'E';wavehead.d[0] = 'f';wavehead.d[1] = 'm';wavehead.d[2] = 't';wavehead.d[3] = ' ';wavehead.e = 16;wavehead.f = 1;wavehead.g = CHANNELS;wavehead.h = RATE;wavehead.i = RATE*CHANNELS*SIZE/8;wavehead.j = CHANNELS*SIZE/8;wavehead.k = SIZE;wavehead.p[0] = 'd';wavehead.p[1] ='a';wavehead.p[2] ='t';wavehead.p[3] ='a';wavehead.q = filesize;fseek(fp, 0, SEEK_SET);fwrite(&wavehead, 1, sizeof(wavehead), fp);}void mixWav(char *backgroundFilePath, char *foregroundFilePath, char *dstFilePath){FILE *backgroundFile = fopen(backgroundFilePath, "rb");    if(NULL == backgroundFile){printf("Can Not find backgroundFile\r\n ");        return ;}FILE *foregroundFile = fopen(foregroundFilePath, "rb");    if(NULL == foregroundFile){printf("Can Not find foregroundFilePath\r\n ");        return ;}FILE *dstFile = fopen(dstFilePath, "wb");    if(NULL == dstFile){printf("Can Not find dstFilePath\r\n ");        return ;}int waveHeadSize = sizeof(struct TWavehead);    // 计算第一个文件除文件头后的大小fseek(backgroundFile, 0, SEEK_SET);void *backgroundHead = malloc(waveHeadSize);int success = fread(backgroundHead, 1, waveHeadSize, backgroundFile);struct TWavehead *backgroundWaveHead = (struct TWavehead *)backgroundHead;printf("headSize:%d,isSuccess:%d",waveHeadSize,success);// 计算第二个文件除文件头后的大小//fseek(secondFile, 0, SEEK_SET);void *foregroundHead = malloc(waveHeadSize);success = fread(foregroundHead, 1, waveHeadSize, foregroundFile);struct TWavehead *foregroundWaveHead = (struct TWavehead *)foregroundHead;    // 计算目标文件除文件头后的大小int fileSize = foregroundWaveHead->q;// 写入文件头writeHead(dstFile,fileSize);fseek(backgroundFile, waveHeadSize, SEEK_SET);fseek(foregroundFile, waveHeadSize, SEEK_SET);char sample1, sample2;int value;while(!feof(foregroundFile)) {if(feof(foregroundFile)){fseek(backgroundFile, waveHeadSize, SEEK_SET);}                //  以下是上篇日志中的算法,效果太差了sample1 = fgetc(foregroundFile);sample2 = fgetc(backgroundFile);if ((sample1 < 0) && (sample2 < 0)){//value = sample1 + sample2 - (sample1 * sample2 / (-1 *(pow(2,16-1)-1)));double i = 2, j = 15;value = sample1 + sample2 - (sample1 * sample2 / (-1 *(pow(i,j)-1)));}else{//value = sample1 + sample2 - (sample1 * sample2 / (pow(2,16-1)-1));double i = 2, j = 15;value = sample1 + sample2 - (sample1 * sample2 / (pow(i,j)-1));}fputc(value, dstFile);}fclose(backgroundFile);fclose(foregroundFile);fclose(dstFile);}int main(int argc,char *argv[]) {mixWav("d:\\game.wav", "d:\\background.wav", "d:\\temp.wav");return 0;}


原创粉丝点击