#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
const char *name;
const char *languages;
const char *identifier;
unsigned char gender;
unsigned char age;
unsigned char variant;
unsigned char xx1;
int score;
void *spare;
} espeak_VOICE;
typedef struct {
const char *mnem;
int value;
} MNEM_TAB;
MNEM_TAB genders [] = {
{"unknown", 0},
{"male", 1},
{"female", 2},
{NULL, 0 }
};
char path_home[160];
int n_voices_list = 0;
void strncpy0(char *to,const char *from, int size)
{//===================================================
// strcpy with limit, ensures a zero terminator
strncpy(to,from,size);
to[size-1] = 0;
}
static char *fgets_strip(char *buf, int size, FILE *f_in)
{//======================================================
// strip trailing spaces, and truncate lines at // comment
int len;
char *p;
if(fgets(buf,size,f_in) == NULL)
return(NULL);
if(buf[0] == '#')
{
buf[0] = 0;
return(buf);
}
len = strlen(buf);
while((--len > 0) && isspace(buf[len]))
buf[len] = 0;
if((p = strstr(buf,"//")) != NULL)
*p = 0;
return(buf);
}
int LookupMnem(MNEM_TAB *table, const char *string)
{//==================================================
while(table->mnem != NULL)
{
if(strcmp(string,table->mnem)==0)
return(table->value);
table++;
}
return(table->value);
}
int GetFileLength(const char *filename)
{
struct stat statbuf;
if(stat(filename,&statbuf) != 0)
return(0);
if((statbuf.st_mode & S_IFMT) == S_IFDIR)
return(-2); // a directory
return(statbuf.st_size);
}
static espeak_VOICE *ReadVoiceFile(FILE *f_in, const char *fname, const char*leafname)
{
char linebuf[120];
char vname[80];
char vgender[80];
char vlanguage[80];
char languages[300];
unsigned int len;
int langix = 0;
int n_languages = 0;
char *p;
espeak_VOICE *voice_data;
int priority;
int age;
int n_variants = 4;
int gender;
vname[0] = 0;
vgender[0] = 0;
age = 0;
while(fgets_strip(linebuf,sizeof(linebuf),f_in) != NULL)
{
if(memcmp(linebuf,"name",4)==0)
{
p = &linebuf[4];
while(isspace(*p)) p++;
strncpy0(vname,p,sizeof(vname));
}
else if(memcmp(linebuf,"language",8)==0)
{
priority = 5;
vlanguage[0] = 0;
sscanf(&linebuf[8],"%s %d",vlanguage,&priority);
len = strlen(vlanguage) + 2;
// check for space in languages[]
if(len < (sizeof(languages)-langix-1))
{
languages[langix] = priority;
strcpy(&languages[langix+1],vlanguage);
langix += len;
n_languages++;
}
}
else if(memcmp(linebuf,"gender",6)==0)
{
sscanf(&linebuf[6],"%s %d",vgender,&age);
}
else if(memcmp(linebuf,"variants",8)==0)
{
sscanf(&linebuf[8],"%d",&n_variants);
}
}
languages[langix++] = 0;
gender = LookupMnem(genders,vgender);
if(n_languages == 0)
{
return(NULL); // no language lines in the voice file
}
p = (char *)calloc(sizeof(espeak_VOICE) + langix + strlen(fname) + strlen(vname) + 3, 1);
voice_data = (espeak_VOICE *)p;
p = &p[sizeof(espeak_VOICE)];
memcpy(p,languages,langix);
voice_data->languages = p;
strcpy(&p[langix],fname);
voice_data->identifier = &p[langix];
voice_data->name = &p[langix];
if(vname[0] != 0)
{
langix += strlen(fname)+1;
strcpy(&p[langix],vname);
voice_data->name = &p[langix];
}
voice_data->age = age;
voice_data->gender = gender;
voice_data->variant = 0;
voice_data->xx1 = n_variants;
return(voice_data);
}
static void GetVoices(const char *path) {
static espeak_VOICE *voices_list[250];
FILE *f_voice;
espeak_VOICE *voice_data;
int ftype;
char fname[sizeof(path_home) + 100];
DIR *dir;
struct dirent *ent;
if ((dir = opendir((char *) path)) == NULL)
return;
while ((ent = readdir(dir)) != NULL) {
if (n_voices_list >= (250 - 2))
break;
if (ent->d_name[0] == '.')
continue;
sprintf(fname, "%s%s%s", path, "/", ent->d_name);
printf("%d %s\t\t%s\n",n_voices_list,ent->d_name,fname);
ftype = GetFileLength(fname);
printf("%d======\n",ftype);
if (ftype == -2) {
// a sub-sirectory
GetVoices(fname);
} else if (ftype > 0) {
// a regular line, add it to the voices list
if ((f_voice = fopen(fname, "r")) == NULL)
continue;
// pass voice file name within the voices directory
voice_data = ReadVoiceFile(f_voice, fname + 62, ent->d_name);
fclose(f_voice);
if (voice_data != NULL) {
voices_list[n_voices_list++] = voice_data;
}
}
}
closedir(dir);
}
int main(){
char *filepath = "espeak-data";
GetVoices(filepath);
}
C語言項目分析(一)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.