请各位大虾帮助,小弟感激不尽
小弟最近做语音端点检测c语言程序,在vc++平台上运行,可编译不成功,但改成c++程序时就可编译成功,请各位大虾分析一下原因,小弟感激不尽.
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<math.h>
#define PI 3.141593
#define NN 240//帧长
#define N 80//帧移
#define alpha 0.97 //预加重系数
void main()
{ //double zcr(double *x,int FRAMELEN,int FRAMEINC)
double amp1; //能量第一门限
double amp2; //能量第二门限
double zcr2; //过零率第二门限
int maxsilence=3; //最长静音段长度
int minlen=15; //最短语音长度
long int ps1,ps2;//指向文件头和文件尾的指针
int Length;//语音的长度
int i,j,k;
int pp;//语音的帧数
int pp1;//求过零率时用到的语音的帧数
//int st;
//打开语音文件
FILE *fp;
fp=fopen("57.wav","rb");
if(fp==NULL)
{
printf("file can't open!\n");
exit(1);
}
//求语音文件长度
rewind(fp);
ps1=ftell(fp);
fseek(fp,0L,2);
ps2=ftell(fp);
Length=(ps2-ps1)/2;//length为语音数组的长度,因为是双字节,所以除以2
typedef struct st_type6
{
int item_e[];
}type_e;
type_e *st=(type_e*)malloc(sizeof(int)*Length);
//const int A=length;
//double *signal = new double [Length];
//double signal[A];
rewind(fp);
fread((char *)&st,sizeof(int),Length,fp);
//将语音信号复制给数组,复制的过程中强制转换
typedef struct st_type
{
double item[];
}type_a;
type_a *signal=(type_a*)malloc(sizeof(double)*Length);
for(i=0;i<Length;i++)
signal->item[i]=(double)(st->item_e[i]);
//以下部分防止直流飘移
double sqret1=0;
for(i=50;i<=450;i++)
sqret1-=signal->item[i]/400;
for(i=0;i<Length;i++)
signal->item[i]-=sqret1;
//下面开始语音的分帧
pp=(Length-(NN-N))/N;//帧数
//计算短时能量
type_a *amp=(type_a*)malloc(sizeof(double)*pp);
//double *amp=new double[pp];
for(i=0;i<pp;i++)
amp->item[i]=0;
double xs=0;
for(i=0;i<pp*N;i=i+N)
{
for(int j=0;j<NN;j++)
{
xs=signal->item[i+j];
amp->item[i/N]=amp->item[i/N]+xs*xs;
}
}
//以下设置双门限值
double amp_min=amp->item[0],amp_max=amp->item[0];
double I1,I2;
for(i=i;i<10;i++)
{
if(amp_min>amp->item[i])
{
amp_min=amp->item[i];
}
if(amp_max<amp->item[i])
{
amp_max=amp->item[i];
}
}
I1=0.03*(amp_max-amp_min)+amp_min;
I2=4*amp_min;
//double amp1;
//double amp2;
if(I1>I2)
amp2=I1;
else
amp2=I2;
amp1=5*amp2;//amp2为低阈值,amp1为高阈值
typedef struct st_type2
{
int item_b[][NN];
}type_b;
typedef struct st_type3
{
double item_c[][NN];
}type_c;
//以下求短时过零率
pp1=(Length-1-(NN-N))/N;
type_a *zcr=(type_a*)malloc(sizeof(double)*pp1);
//double *zcr=new double[pp1];//短时过零率
type_c *temp1=(type_c*)malloc(sizeof(double)*pp1*NN);
//double *temp1=new double[pp1][NN];//分帧后的语音
type_c *temp2=(type_c*)malloc(sizeof(double)*pp1*NN);
//double *temp2=new double[pp1][NN];//分帧后的语音
type_b *diff=(type_b*)malloc(sizeof(int)*pp1*NN);
//int *diff=new int[pp1][NN];//记录前后两点语音差值
type_b *signs=(type_b*)malloc(sizeof(int)*pp1*NN);
//int *signs=new int[pp1][NN];//记录前后两点语音符号不同的情况
type_b *xzcr=(type_b*)malloc(sizeof(int)*pp1*NN);
//int *xzcr=new int[pp1][NN];//综合差值和符号不同的情况
//以下求语音交错一点的分帧情况
for(i=0;i<pp1*N;i=i+N)
{
for(int j=0;j<NN;j++)
{
temp1->item_c[i/N][j]=signal->item[i+j];
temp2->item_c[i/N][j]=signal->item[i+j+1];
}
}
//以下求diff[][],signs[][]和xzcr[][]
for(i=0;i<pp1;i++)
{
for(j=0;j<NN;j++)
{
if(temp1->item_c[i][j]*temp2->item_c[i][j]<0)
{
signs->item_b[i][j]=1;
}
else
signs->item_b[i][j]=0;
if(fabs(temp1->item_c[i][j]-temp2->item_c[i][j])>0.02)
{
diff->item_b[i][j]=1;
}
else
diff->item_b[i][j]=0;
}
}
for(i=0;i<pp1;i++)
{
for(j=0;j<NN;j++)
{
xzcr->item_b[i][j]=signs->item_b[i][j]*diff->item_b[i][j];
}
}
//求短时过零率
for(i=0;i<pp1;i++)
zcr->item[i]=0;
for(i=0;i<pp1;i++)
{
for(j=0;j<NN;j++)
{
zcr->item[i]+=xzcr->item_b[i][j];
}
}
//求zcr2,即求过零率的阈值
double zc=0.00,fzc=0.00,xzc=0.00;
for(i=0;i<10;i++)
{
zc+=zcr->item[i]/10;
}
for(i=0;i<10;i++)
{
xzc=zcr->item[i]*zcr->item[i];
}
fzc=sqrt(xzc);
if(zc+2*fzc<25)
zcr2=zc+2*fzc;
else
zcr2=25;
free(temp2) ,free(diff),free(signs),free(xzcr),free(signal);
//以下开始进行端点检测
int s1=0; //记录可能出现的脉冲噪声长度
int status=0;
typedef struct st_type4
{
int item_d[];
}type_d;
type_d *silence=(type_d*)malloc(sizeof(int)*pp1);
//int *silence=new int[pp1];
type_d *count=(type_d*)malloc(sizeof(int)*pp1);
//int *count=new int[pp1];
type_d *x1=(type_d*)malloc(sizeof(int)*pp1);
//int *x1=new int[pp1];
type_d *x2=(type_d*)malloc(sizeof(int)*pp1);
//int *x2=new int[pp1];
silence->item_d[0]=0;
count->item_d[0]=0;
for(i=0;i<pp1;i++)
{
x1->item_d[i]=0;
x2->item_d[i]=0;
}
for(j=0;j<=pp1-1;j++)
{
switch(status)
{
case(0||1):
{
if (amp->item[i]>amp1)
{
if(j-count->item_d[i]-1>=1)
{
x1->item_d[i]=j-count->item_d[i]-1;
}
else
{
x1->item_d[i]=1;
}
status=2;
silence->item_d[i]=0;
count->item_d[i]=count->item_d[i]+1;
} //确认进入语音段
else if(amp->item[i]>amp2||zcr->item[i]>zcr2)
{
status=1;
count->item_d[i]=count->item_d[i]+1;
}//可能进入语音段
else //静音状态
{
status=0;
count->item_d[i]=0;
}
break;
}//case 0&&1
case 2://进入语音段
{
if((amp->item[j]>amp2||zcr->item[j]>zcr2)&&silence->item_d[i]==0) //保持在语音段
{
count->item_d[i]=count->item_d[i]+1;
}
else if((amp->item[j]>amp2||zcr->item[j]>zcr2)&&silence->item_d[i]>0)
{
count->item_d[i]=count->item_d[i]+1;
silence->item_d[i]=silence->item_d[i]+1;
s1=s1+1;
if(s1>2)
silence->item_d[i]=0;
}
else //语音段结束
{
silence->item_d[i]=silence->item_d[i]+1;
s1=0;
if(silence->item_d[i]<maxsilence)//噪音还不够长,尚未结束
{
count->item_d[i]=count->item_d[i]+1;
}
else if(count->item_d[i]<minlen)//语音长太短,以为是噪声
{
status=0;
silence->item_d[i]=0;
count->item_d[i]=0;
}
else //语音结束
{
status=3;
}
}
break;
}//case2
case 3:
{
i=i+1;
status=0;
x1->item_d[i]=0;
x2->item_d[i]=0;
silence->item_d[i]=0;
count->item_d[i]=0;
s1=0;
break;
}//case3
}//switch
}//for
for(j=0;j<i-1;j++)
{
count->item_d[j]=count->item_d[j]-silence->item_d[j];
x2->item_d[j]=x1->item_d[j]+count->item_d[j]+1;
}
free(silence),free(count),free(amp),free(zcr);
//以下去除非语音的帧
int w=0;//语音段的总帧数
for(i=0;i<pp1;i++)
{
w+=x2->item_d[i]-x1->item_d[i];
}
type_c *finally_signal=(type_c*)malloc(sizeof(double)*w*NN);
//double *finally_signal=new double[W][NN];
k=0;
int L;
for(i=0;i<pp1;i++)
{
if(x2->item_d[i]!=0)
{
for(j=x1->item_d[i];j<=x2->item_d[j];j++)
{
for(L=0;L<NN;L++)
{
finally_signal->item_c[k][L]=temp1->item_c[j][L];
k++;
}
}
}//if
}//for
free(temp1);
}//main
[解决办法]
C的类型和变量定义必须在语句块开头的地方;C++则可以在任意地方。