哼唱打分

#include <stdio.h>
#include<stdlib.h>
#include <memory.h>
#include <math.h>
#include <time.h>
#define ABS(a) ((a)>0?(a):(-(a)))

int getArrayMin(double arr[12][10]);
double getScore(int pitchs,int ditance);
int getFrameNum(FILE *filep,int frameLength);
char *PCM_to_pitch(FILE *filePoint,int frameNumber,int framelength,int time);
char getScale(double pitch);
int min(int a,int b,int c) ;
int ComputeDistance(char raw[],char mix[]) ;
int getArrayMax(double *arr,int length);


void main(int argc, char *argv[] ) {

time_t timep;
time(&timep);
printf("main begin %s \n",ctime(&timep));

FILE *fp_raw=NULL;
FILE *fp_mix=NULL;
int frameNumberRaw=0;
int frameNumberMix=0;
int frameNumber=0;
const int frameLength=1024;
char *Music_raw;
char *Music_mix;
int distance=0;
int test_i=0;
double score= 0;

fp_raw = fopen("/XP_share/音频/wangfei_res.wav","r");
fp_mix = fopen("/XP_share/音频/lijian_res.wav","r");

if(fp_raw==NULL )
{
printf("fp_raw file cant be opened!\n ");
exit(0);

}
if(fp_mix==NULL )
{
printf("fp_mix file cant be opened!\n ");
exit(0);

}
//******************** *******************************

//Remove background music

//****************************************************


frameNumberRaw=getFrameNum(fp_raw,frameLength);
frameNumberMix=getFrameNum(fp_mix,frameLength);

Music_raw=PCM_to_pitch(fp_raw,frameNumberRaw,frameLength,0);
Music_mix=PCM_to_pitch(fp_mix,frameNumberMix,frameLength,0);


time(&timep);
printf("ComputeDistance begin %s \n",ctime(&timep));

if(Music_mix!=NULL&&Music_mix!=NULL)
distance = ComputeDistance(Music_raw,Music_mix);


time(&timep);
printf("ComputeDistance end %s \n",ctime(&timep));

printf("distance is %d\n",distance);

frameNumber = frameNumberRaw>frameNumberMix ?frameNumberRaw:frameNumberMix;
score = getScore(frameNumber,distance);
if(score>=0)
printf("score is %5.2lf\n",score);

//*****************\close***************************************

time(&timep);
printf("main end %s \n",ctime(&timep));

Music_raw=NULL;
Music_mix=NULL;
fclose(fp_raw);
fp_raw= NULL;
fclose(fp_mix);
fp_mix= NULL;

}


double getScore(int pitchs,int ditance)
{
double molecular=0.0;
double denominator=0.0;
double result=0.0;

molecular = pitchs-1 - ditance;
denominator = pitchs - 1;
result= (molecular/denominator )*100;

printf("molecular*********** is %lf\n",molecular);
printf("denominator*********** is %lf\n", denominator);
printf("getScore*********** is %lf\n",result);
return result;
}
int getFrameNum(FILE *filep,int frameLength)
{

int fileSize = 0;
int frameNum= 0;
const int frame_len = frameLength;
fseek(filep,0,2);
fileSize = ftell(filep);
//get ceil int ((x+n-1)/n);
frameNum =(((fileSize-44)+2*frame_len-1)/(2*frame_len));
printf("getFrameNum()*****the result of getFrameNum is %d\n",frameNum);
return frameNum;
}

char *PCM_to_pitch(FILE *filePoint,int frameNumber,int framelength,int time)
{
short *array_raw;
int i=0;
int j = 0;
double in_raw[framelength];
double pitch=0.0;
char *scale;
int flag=0;
int test=0;
int loop_out=0;
int loop_in = 0;
int offset = time*44100*2; //ms
double R[framelength];
FILE *RRRRRR= fopen("yingao.txt","w");
#ifdef DEBUG
printf("DEBUG---------");
#endif
array_raw = (short*)malloc(sizeof(short)*framelength);
memset((void*)array_raw,0,sizeof(short)*framelength);
scale = (char*)malloc(sizeof(char)*frameNumber);
memset((void*)scale,0,sizeof(char)*frameNumber);

//bound 44Byte,reload file poiter
fseek(filePoint,44,0);
for(i = 0;i<frameNumber;i++)
{

fread(array_raw,framelength,2,filePoint);

for(j=0;j<framelength;j++)
{
in_raw[j]=(double)array_raw[j];
R[j]=0;
}
for(loop_out=0;loop_out<framelength;loop_out++)
for(loop_in=0;loop_in<framelength-loop_out;loop_in++)
R[loop_out]=R[loop_out]+in_raw[loop_in]*in_raw[loop_out+loop_in];

for(test=0;test<44;test++)
R[test]=0;

flag = getArrayMax(R,framelength);
if(flag!=0)
pitch = 44100.0/flag;
fprintf(RRRRRR,"%f\n", pitch);

// printf("--------- index=%d pitch=%lf \n",flag,pitch);
scale[i]=getScale(pitch);

// fseek(filePoint,offset,SEEK_CUR);
}

free(array_raw);
return scale;

}

int getArrayMin(double arr[12][10])
{
int rows,cols;
double min=0.0;
int index=0;
/************found************/
min = arr[0][0];
for ( rows=0; rows<12; rows++)
for ( cols=0; cols<10; cols++)
if (min > arr[rows][cols])
{
min = arr[rows][cols];
index=rows;
}

return (index);
}

char getScale(double pitch)
{

int i=0;
int j=0;
int index = 0;

// C P D O E F I G U A Y B
double Octave[12][10]={
16.352,32.703,65.406,130.81,261.63,523.25,1046.5,2093.0,4186.0,8372.0,
17.324,34.648,69.296,138.59,277.18,554.37,1108.7,2217.5,4434.9,8869.8,
18.354,36.708,73.416,146.83,293.66,587.33,1174.7,2349.3,4698.6,9397.3,
19.445,38.891,77.782,155.56,311.13,622.25,1244.5,2489.0,4978.0,9956.1,
20.602,41.203,82.407,164.81,329.63,659.26,1318.5,2637.0,5274.0,10548,
21.827,43.654,87.307,174.61,349.23,698.46,1396.9,2793.8,5587.7,11175,
23.125,46.249,92.499,185.00,369.99,739.99,1480.0,2960.0,5919.9,11840,
24.500,48.999,97.999,196.00,392.00,783.99,1568.0,3136.0,6271.9,12544,
25.957,51.913,103.83,207.65,415.30,830.61,1661.2,3322.4,6644.9,13290,
27.500,55.000,110.00,220.00,440.00,880.00,1760.0,3520.0,7040.0,14080,
29.135,58.270,116.54,233.08,466.16,466.16,1864.7,3729.3,7458.6,14917,
30.868,61.735,123.47,246.94,493.88,987.77,1975.5,3951.1,7902.1,15804
};
double Temp[12][10]={0.0};


for(i=0;i<12;i++)
for(j=0;j<10;j++)
Temp[i][j] = ABS(Octave[i][j]-pitch);

index =getArrayMin(Temp);

if(index==0)
{ return 'C';
}else if(index==1)
{ return 'C';
}else if(index==2)
{ return 'D';
}else if(index==3)
{ return 'D';
}else if(index==4)
{ return 'E';
}else if(index==5)
{ return 'F';
}else if(index==6)
{ return 'F';
}else if(index==7)
{ return 'G';
}else if(index==8)
{ return 'G';
}else if(index==9)
{ return 'A';
}else if(index==10)
{ return 'A';
}else if(index==11)
{ return 'B';
}
}


int min(int a,int b,int c)
{
int t = a < b ? a : b;
return t < c ? t : c;
}

int ComputeDistance(char raw[],char mix[])
{
int rawLength = strlen(raw);

int mixLength= strlen(mix);
int i = 0;
int j = 0;
int cost=0;
//int d[][] = new int[rawLength + 1, mixLength + 1]; // matrix
int **d = (int **)malloc((rawLength+1) * sizeof(int *));
for( i=0; i<=rawLength; ++i)
{
d[i] = (int *)malloc((mixLength+1) * sizeof(int));
}
if (rawLength == 0)
{
return mixLength;
}

if (mixLength == 0)
{
return rawLength;
}
for ( i = 0; i <= rawLength; i++)
{
d[i][0] =i;
}

for (j = 0; j <= mixLength; d[0][j] = j++)
{
d[0][j] =j;
}
for ( i = 1; i <= rawLength; i++)
{
for ( j = 1; j <= mixLength; j++)
{
cost = (mix[j-1] == raw[i-1]) ? 0 : 1;
d[i][j] = min(d[i-1][j]+1, d[i][j-1]+1,d[i-1][j-1]+cost);
}
}
return d[rawLength][mixLength];
}

int getArrayMax(double *arr,int length)
{
int rows;
double max=0.0;
int Rno=0;
/************found************/
max = arr[0];
for ( rows=0; rows<length; rows++)
if (max < arr[rows])
{
max = arr[rows];
Rno=rows;
}

return (Rno);
}

原文地址:https://www.cnblogs.com/shuimo/p/2693279.html