自相关提取基频

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <fftw3.h>
#include <sys/time.h>
#define ABS(a) ((a)>0?(a):(-(a)))
//function declare
int getScale(double pitch);
int getPeaks(double array[],int len);
int *PCM_to_pitch(FILE *filePoint,int frameNumber,int framelength,float time);
int getArrayMin(double *ar,int length);
int getArrayMax(double *arr,int length);
void getTime();

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

FILE *fp_raw=NULL;
int frameNumberRaw=0;
int frameLength;
int *Music_raw;
int test_i=0;
float offset_time;
const float acf_time=0.023;
int fs = 44100;

getTime();

fp_raw = fopen("/XP_share/音频/banzou_res.wav","rw");
if(fp_raw==NULL )
{
printf("fp_raw file cant be opened!\n ");
exit(0);
}
//******************** *******************************

//Remove background music

//****************************************************
remove("/root/workspace/MusicPlayer/res/raw/index.txt");

printf("please input the offset_time with the unit (S)\n");
scanf("%f",&offset_time);
frameLength=offset_time*44100;
frameNumberRaw=getFrameNum(fp_raw,frameLength);

offset_time-=0.023;
frameLength=0.023*44100;
Music_raw=PCM_to_pitch(fp_raw,frameNumberRaw,frameLength,offset_time);

//*****************\close***************************************
getTime();

Music_raw=NULL;
fclose(fp_raw);
fp_raw= NULL;
}

int getFrameNum(FILE *filep,int frameLength)
{

int fileSize = 0;
int frameNum= 0;
//4096/2;the number of Byte per frame
const int frame_len = frameLength;
fseek(filep,0,SEEK_END);
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;
}

int *PCM_to_pitch(FILE *filePoint,int frameNumber,int framelength,float time)
{

short *array_raw;
int i=0;
int j = 0;
double in_raw[framelength];
double pitch=0.0;
int *scale;
int flag=0;
int test=0;
int loop_out=0;
int loop_in = 0;
int offset = ceil(time*44100*2); //s
double R[framelength];
FILE *RRRRRR= fopen("yingao.txt","w");

#ifdef DEBUG
printf("offset---------%d\n",offset);
#endif

array_raw = (short*)malloc(sizeof(short)*framelength);
memset((void*)array_raw,0,sizeof(short)*framelength);


scale = (int*)malloc(sizeof(int)*frameNumber);
memset((void*)scale,0,sizeof(int)*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;

}

//get the numbers of peaks, use it to getpitch

int getArrayMin(double *arr,int length)
{

int rows;
double min=0.0;
int Rno=0;
/************found************/
min = arr[0];
for ( rows=0; rows<length; rows++)
if (min >arr[rows])
{
min = arr[rows];
Rno=rows;
}
return (Rno);
}

int getScale(double pitch)
{
// double frequence = 440.0*pow(2,((pitch-69)/12));
int i=0;
int j=0;
int index = 0;
FILE *fpWrite= fopen("/root/workspace/MusicPlayer/res/raw/index.txt","a+");
if(NULL == fpWrite)
{
printf("no this file");
}
// C P D O E F I G U A Y B
double Octave[88]={
27.500,29.135,55.000,58.270,110.000,116.541,220.000,233.082,
440.000,466.164,880.000,932.328, 1760.000,1864.655,3520.000,3729.310,
30.868, 61.735,123.471, 246.942,493.883,987.767,1975.533, 3951.066,
32.703,34.648,65.406, 69.296,130.813,138.591,261.626,277.183,
523.251,554.365,1046.502,1108.731,2093.005,2217.461,4186.009,
36.708,38.891,73.416,77.782,146.832,155.563,293.665,311.127,
587.330,622.254,1174.659,1244.508,2349.318,2489.016,
41.203,82.407,164.814, 329.628,659.255, 1318.510,2637.020,
43.654,46.249, 87.307,92.499,174.614,184.997,349.228,369.994,
698.456,739.989,1396.913,1479.978, 2793.826,2959.955,
48.999,51.913,97.999,103.826, 195.998,207.652,391.995,415.305,
783.991,830.609,1567.982,1661.219, 3135.963,3322.438 };

double Temp[88]={0.0};
for(i=0;i<88;i++)
{
Temp[i] = ABS(Octave[i]-pitch);
}
index =getArrayMin(Temp,88);
fprintf(fpWrite,"%d\n",index);
fclose(fpWrite);
return index;
}

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);
}


void getTime()
{
time_t now;
struct tm *timenow;
time(&now);
timenow = localtime(&now);
printf("Local time is %s\n",asctime(timenow));

}

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