📄 mpeg_param.cpp
字号:
/* Mnemonics
32bit TTS_Sequence_Start_Code ==> TTS_seq : 0x011111111
8bit Language_Code ==> L_code ----
1bit Prosody_Enable ==> P_en |
1bit Video_Enable ==> V_en |--- TTSinputType
1bit Lip_Shape_Enable ==> L_en |
1bit Trick_Mode_Enable ==> T_en _|
32bit TTS_Sentence_Start_Code ==> TTS_sent : 0x012121212
1bit Silence
12bit Silence_Duration ==> Sdur
1bit Gender ____________
2bit Age |___ TTSCmmd
4bit Speech_Rate _______|
12bit Length_of_Text ==> Ntext
?x8bit TTS_Text ==> Text
10bit Number_of_phonemes ==> Nphone
8bit Symbol_each_phoneme[] ==> Phone[]
12bit Dur_each_phoneme[] ==> Dur[]
3x8bit F0_contour_each_phoneme[][] ==> Ptch[][]
3x8bit Energy_contour_each_phoneme[][] ==> Energy[][]
16bit Sentence_Duration ==> SntDur
16bit Position_in_Sentence ==> PinSnt
10bit Offset
10bit Number_of_Lip_Event ==> Nlip
16bit Lip_in_Sentence[] ==> LinSnt[]
8bit Lip_shape[] ==> Lshape[]
*/
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h> // for isdigit()
#include <io.h> // for _access()
#include "tts-bitstream.h"
short Nlip;
unsigned char YY[2];
int p_rd_txt(FILE *fp);
void read_phone(FILE *fphone, FILE *fF0);
void ws_lstype(int n, short *F0s, char *ptch);
void read_lip (FILE *flip);
void save_dat(FILE *fout);
void Sdata_write(short *A, int n, int nbits, unsigned char *B, FILE *fout);
void Cdata_write(char *A,int n, int nbits, unsigned char *B,FILE *fout);
void CMdata_write(char A[][3], int n1, int n2, int nbits, unsigned char *B, FILE *fout);
void Make_Mpeg_Param(int f_gen, int f_pro, int f_video, int f_lip, int f_lcode, int f_sprate, int f_trick, int f_age)
{
int i, j, fh, step;
short f0; char fname[30]; FILE *ftext, *fsp, *fphone, *fpp, *fF0, *flip, *fout; struct stat fst;
char str[50];/* input Encoding conditions */ YY[0]=0; YY[1]=8; Silence=1; if( f_lcode == 1 ) L_code=1;
else L_code=2; if( f_pro == 1 ) P_en=1; else P_en=0; if( f_video == 1 ) V_en=1; else V_en=0; if(V_en)
{ if( f_lip == 1 ) L_en=1; else L_en=0; /* We assume 30 frames/sec, and 15 frames between I frames */ Niframe=15; Sdur=1000*Niframe/30; }
else L_en = 0; if( f_trick == 1 ) T_en=1; else T_en=0; if( f_gen == 0 ) Gender=1; else Gender=0; Age=f_age; if(Age<0 || Age>3) Age=1; if(!V_en) Speech_Rate=f_sprate;/* Check Data files */ if((ftext=fopen("prdb.txt","r"))==NULL) {
wsprintf(str, "Error prdb.txt");
::MessageBox( NULL, str, "error", MB_OK );
exit(1);
} if(V_en)
{ if(Gender) strcpy(fname,"f-mpeg.dat");
else strcpy(fname,"m-mpeg.dat"); if((fsp=fopen(fname,"rb"))==NULL) {
wsprintf(str, "Err: %s\n",fname);
::MessageBox( NULL, str, "error", MB_OK );
exit(1);
}
fh=fileno(fsp); fstat(fh, &fst); fclose(fsp); v_st=0; v_ed=fst.st_size/32+1; /* msec : Fs=16000 */ } if(V_en || P_en)
{ if(Gender) strcpy(fname,"f-mpeg.phones"); else strcpy(fname,"m-mpeg.phones"); if((fphone=fopen(fname,"r"))==NULL) {
wsprintf(str, "Err: %s\n",fname);
::MessageBox( NULL, str, "error", MB_OK );
exit(1);
} } if(P_en)
{ if(Gender) strcpy(fname,"f-mpeg.ff0");
else strcpy(fname,"m-mpeg.ff0"); if((fF0=fopen(fname,"r"))==NULL)
{
wsprintf(str, "Err: %s\n",fname);
::MessageBox( NULL, str, "error", MB_OK );
exit(1);
} fpp=fopen("F0.dat","w+b"); while((j=fscanf(fF0,"%d",&i))==1)
{
f0=i;
fwrite(&f0,2,1,fpp);
} fclose(fF0); fclose(fpp); fF0=fopen("F0.dat","rb"); } if(L_en)
{ if(Gender) strcpy(fname,"f-mpeg.lip");
else strcpy(fname,"m-mpeg.lip"); if((flip=fopen(fname,"r"))==NULL) {
wsprintf(str, "Err: %s\n",fname);
::MessageBox( NULL, str, "error", MB_OK );
exit(1);
} }/* Save TTS_Sequence Data */ fout=fopen("mpeg_tts.dat","w+b"); if(V_en) fwrite(&v_ed,4,1,fout);
else { i=-1; fwrite(&i,4,1,fout); } TTSinputType=((short)L_code) << 8; TTSinputType= TTSinputType | (P_en <<7) | (V_en <<6) | (L_en <<5) | (T_en <<4); fwrite(&TTS_seq,sizeof(TTS_seq),1,fout); fwrite(&TTSinputType,sizeof(TTSinputType),1,fout);/* Save TTS_Sentence Data */ while( (i=p_rd_txt(ftext)) > 1 )
{ if(V_en || P_en) read_phone(fphone,fF0); if(L_en) read_lip(flip); save_dat(fout); } fclose(ftext); if(V_en || P_en) fclose(fphone); if(P_en) fclose(fF0); if(L_en) fclose(flip); if(V_en)
{ step=1000*Niframe/30; for( ; v_st+step< v_ed; v_st+=step ) { fwrite(&v_st,4,1,fout); /* for TimeStemp */ fwrite(&TTS_sent,4,1,fout); /* for TTS_Snt_Start_Code */ Cdata_write(&Silence,1,BSilence,YY,fout); /* for Silence */ Sdata_write(&Sdur,1,BSdur,YY,fout); if(YY[1]!=8) { fwrite(YY,1,1,fout); YY[0]=0; YY[1]=8; } } } fclose(fout);
::MessageBox( NULL, "MPEG4-TTS Encoding Success", "舅覆", MB_OK );}int p_rd_txt(FILE *fp){ int sentnce_end=0, i=0, ch;
char pchr; pchr=32;
while( (ch=fgetc(fp)) != EOF && i< 800 )
{ if(ch=='\n' || ch=='\r' || ch == '\0' || ch =='\t') ch=32; if(ch=='"' || ch=='\'' || ch=='{' || ch=='}' || ch=='[' || ch==']' || ch=='<' || ch=='>' || ch=='(' || ch==')' || ch==',' ) continue; if(ch != 32 || pchr != 32) Text[i++]=ch; if(ch=='.')
{ ch=fgetc(fp);
if(!isdigit(ch)) { sentnce_end=1; break; } Text[i++]=ch; } pchr=ch;
if( ch=='?' || ch=='!') { sentnce_end=1; break; }
}
if(sentnce_end == 0)
{
if(Text[i-1]==32) i--;
Text[i++]='.';
} Text[i]=0;
return(i);}char *PHONs[]= { "g","n","d","r","m", "b","s","z","c","k", "t","p","h","G","D", "B","S","Z", "a","v","o","u","U", "i","E","e","Wi","ja", "jv","jo","ju","jE","je", "wa","wv","wI","wi","wE", "we", "gt","nt","dt","l","mt", "bt","N", "PAU","END","P","/","\0" };int nPHONs[]= { 1,2,3,4,5, 6,7,8,9,10, 11,12,13,14,15, 16,17,18, 1,2,3,4,5, 6,7,8,9,10, 11,12,13,14,15, 16,17,18,19,20,21, 1,2,3,4,5, 6,7, 10,11,12,13,0 };int vPHONs[]= { 0,1,0,0,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,1, 1,1,1,1,1, 1,1, 0,0,0,0 };int pPHONs[]= { 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,1, 2,2,2,2,2, 2,2, 3,3,3,3,3 };void read_phone(FILE *fphone, FILE *fF0){ int i, j, k, n, nst, color; short f0, F0s[200]; float st, ed; char PHON1[10], PHON2[10];
char str[50]; Nphone=0;
fscanf(fphone,"%f %d %s",&st, &color,PHON1);
sp_st=(int)(st*1000); while((i=fscanf(fphone,"%f %d %s",&ed, &color,PHON2))==3)
{ nst=(int)(16000.*st);
Dur[Nphone]=16000.*ed-nst; /* no. of samples */ for(j=0; PHONs[j][0]!=0; j++)
{
if(strcmp(PHON1,PHONs[j])==0) break;
} if(PHONs[j][0]==0) {
wsprintf(str, "ERR: SYMBOL %s in phone.dat file\n",PHON1);
::MessageBox( NULL, str, "error", MB_OK );
exit(1);
}
Phone[Nphone]=pPHONs[j]*30+nPHONs[j];
st=ed;
strcpy(PHON1,PHON2); if(P_en)
{ if(vPHONs[j]==0)
{
for(k=0; k<3; k++) Ptch[Nphone][k]=0;
} else
{ for(i=n=0; i<Dur[Nphone]; ) { j=(nst+i)/160; /* per 10 msec */ fseek(fF0,j*2,0);
fread(&f0,2,1,fF0); if(f0==0) { if(n!=0) f0=F0s[n-1]; else exit(1); } F0s[n++]=f0;
i+=(16000/f0); } ws_lstype(n,F0s,&Ptch[Nphone][0]); }
} Nphone++; if(strcmp(PHON2,"END")==0) { sp_ed=(int)(ed*1000); break; } }
for(i=0; i<Nphone; i++) Dur[i]=(Dur[i]+8)/16; /* convert to msec */}void ws_lstype(int n, short *F0s, char *ptch){ int i, j, mid ; float a1,a2,a3, b1,b2,b3, c1,c2,c3,c4, A1,A2,B; if(n==1) F0s[1]=F0s[2]=F0s[0]; else if(n==2) F0s[2]=F0s[1]; else { /* estimate slop, offset of two lines */ mid=n/2;
a1=a2=a3=b1=b2=b3=c1=c2=c3=0; for(i=0; i<mid; i++) {
j=i-mid;
a1=a1+F0s[i]*j;
a2=a2+j*j;
a3=a3+j;
} for(i=mid; i<n; i++) {
j=i-mid;
b1=b1+F0s[i]*j;
b2=b2+j*j;
b3=b3+j;
} for(i=0; i<n; i++) c1=c1+F0s[i]; c2=a3; c3=b3; c4=n; B=(a1*b2*c2+a2*b1*c3-a2*b2*c1)/(a3*b2*c2+a2*b3*c3-a2*b2*c4); A1=(a1-a3*B)/a2; A2=(b1-b3*B)/b2; /* estimate st, mid, end value */ F0s[0]=-A1*mid+B+0.5;
F0s[1]=B+0.5;
F0s[2]=A2*(n-mid)+B+0.5; } for(i=0; i<3; i++) { /* bias 50Hz */ if(F0s[i]<50) F0s[i]=50;
if(F0s[i]>300) F0s[i]=300;
ptch[i]=F0s[i]-50; }}void read_lip (FILE *flip){ int i, j, k, color; float st; fpos_t pos;
k=0;
fgetpos(flip,&pos); while((j=fscanf(flip,"%f %d %d",&st, &color,&i))==3)
{ Lshape[k]=i; LinSnt[k]=st*1000; if(LinSnt[k]>sp_ed) { fsetpos(flip,&pos); break; } fgetpos(flip,&pos);
k++; }
// 巩厘场俊 涝贱阑 摧酒林绊, 傈眉 涝贱肮荐甫 唱鸥郴扁困秦 k甫 窍唱 刘啊矫糯
Lshape[k] = 0;
LinSnt[k++] = sp_ed + 500;
Nlip=k;
for(i=0; i<k; i++)
{
LinSnt[i]-=sp_st;
}
}void save_dat(FILE *fout){ int i, N, step; short Ntext; if(V_en)
{ step=1000*Niframe/30;
N=(sp_st-v_st)/step; for(i=0; i<N; i++, v_st+=step)
{ fwrite(&v_st,4,1,fout); /* for TimeStemp */ fwrite(&TTS_sent,4,1,fout); /* for TTS_Snt_Start_Code */ Cdata_write(&Silence,1,BSilence,YY,fout); /* for Silence */ Sdata_write(&Sdur,1,BSdur,YY,fout); if(YY[1]!=8) { fwrite(YY,1,1,fout); YY[0]=0; YY[1]=8; } } } TTSCmmd= (Gender<<2) | Age; BTTSCmmd=4; if(!V_en)
{
TTSCmmd= (TTSCmmd << 4) | Speech_Rate;
BTTSCmmd=8;
} if(V_en)
{ N=(sp_ed-v_st)/step; SntDur=(sp_ed-sp_st)*3/100;
Offset=(sp_st-v_st)*3/100;
PinSnt=0; } else N=1; for(i=0; i<N; i++, v_st+=step)
{ if(V_en) fwrite(&v_st,4,1,fout); /* for TimeStemp */ fwrite(&TTS_sent,4,1,fout); /* for TTS_Snt_Start_Code */ Cdata_write(&TTSCmmd,1,BTTSCmmd,YY,fout); Ntext=strlen(Text)+1; Sdata_write(&Ntext,1,BNtext,YY,fout); Cdata_write(Text,Ntext,BText,YY,fout); if(P_en)
{ Sdata_write(&Nphone,1,BNphone,YY,fout); Cdata_write(Phone,Nphone,BPhone,YY,fout); Sdata_write(Dur,Nphone,BDur,YY,fout); CMdata_write(Ptch,Nphone,3,BPtch,YY,fout); } if(V_en)
{ if(v_st<=sp_st) PinSnt=0; else {
PinSnt=(v_st-sp_st)*3/100;
if(PinSnt==0) PinSnt=1;
} Sdata_write(&SntDur,1,BSntDur,YY,fout); Sdata_write(&PinSnt,1,BPinSnt,YY,fout); Sdata_write(&Offset,1,BOffset,YY,fout); } if(L_en)
{ Sdata_write(&Nlip,1,BNlip,YY,fout); Sdata_write(LinSnt,Nlip,BLinSnt,YY,fout); Cdata_write(Lshape,Nlip,BLshape,YY,fout);
}
if(YY[1]!=8) { fwrite(YY,1,1,fout); YY[0]=0; YY[1]=8; } } }void Sdata_write(short *A, int n, int nbits, unsigned char *B, FILE *fout){ int i, nx, ny; unsigned short X; unsigned char Y; short W[9]={ 0,1,3,7,0x0F,0x01F,0x03F,0x07F,0x0FF }; Y=B[0]; ny=B[1]; for(i=0; i<n; i++)
{ nx=nbits; while(nx!=0)
{ if(ny>nx)
{
X=*(A+i) & W[nx];
Y=Y | (X << (ny-nx));
ny-=nx; nx=0;
} else { X=(*(A+i)) >> (nx-ny);
Y=Y | (X & W[ny]);
nx-=ny;
ny=8; fwrite(&Y,1,1,fout);
Y=0; }
} }
B[0]=Y; B[1]=ny; }void Cdata_write(char *A,int n, int nbits, unsigned char *B,FILE *fout){ int i, nx, ny; unsigned char X,Y; short W[9]={ 0,1,3,7,0x0F,0x01F,0x03F,0x07F,0x0FF }; Y=B[0]; ny=B[1]; for(i=0; i<n; i++)
{ nx=nbits; while(nx!=0)
{ if(ny>nx)
{
X=*(A+i) & W[nx];
Y=Y | (X << (ny-nx));
ny-=nx;
nx=0;
} else { X=(*(A+i)) >> (nx-ny);
Y=Y | (X & W[ny]);
nx-=ny;
ny=8; fwrite(&Y,1,1,fout);
Y=0; }
} }
B[0]=Y; B[1]=ny;}void CMdata_write(char A[][3], int n1, int n2, int nbits, unsigned char *B, FILE *fout)
{ int i, j, nx, ny; unsigned char X,Y; short W[9]={ 0,1,3,7,0x0F,0x01F,0x03F,0x07F,0x0FF }; Y=B[0]; ny=B[1]; for(i=0; i<n1; i++)
{ for(j=0; j<n2; j++)
{ nx=nbits; while(nx!=0)
{ if(ny>nx) {
X=A[i][j] & W[nx];
Y=Y | (X << (ny-nx));
ny-=nx;
nx=0;
} else
{ X=A[i][j] >> (nx-ny);
Y=Y | (X & W[ny]);
nx-=ny;
ny=8; fwrite(&Y,1,1,fout);
Y=0; }
} }
B[0]=Y; B[1]=ny; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -