以下所有的内容基于eSpeak1.06 的移植过程
1. 先写的main 函数,大致就是初始化,设置回调函数,转换文件,里面的具体参数还不了解。
目前还存在的问题,怎么支持中文,源码里面的 非 C 非 H 的文件怎么放到工程中
void espeak_trans_text()
{
int synth_flags = espeakCHARS_AUTO | espeakPHONEMES | espeakENDPAUSE;
const char* sText = "tralalalallala";
char file_type[] = ".wav";
//初始化
//nRate 是什么?
samples_split = espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, 10000, NULL, 0);
samples_split = samplerate * samples_split_seconds;
espeak_SetSynthCallback(SynthCallback);
espeak_SetParameter(espeakRATE, 175, 0);
espeak_Synth(sText,15,0,POS_CHARACTER,0,synth_flags,NULL,NULL);
espeak_Terminate();
}
2. 关键应该是这个回调函数
wav代表什么? 从下面的写函数 推测出 fwrite(wav,numsamples*2,1,f_wavfile); ,推测出 wav就是 音频数据,写到文件中,但是为啥要乘以2。
numsamples就是 音频数据的长度/2
还要处理两个事件,不懂
FILE *f_wavfile = NULL; 应该就是生成的.wav文件了。
samples_split 是样本
filetype 文件类型,已经提取是 .wav
static int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)
{//========================================================================
char fname[210];
//if(quiet) return(0); // -q quiet mode,应该是命令的
if(wav == NULL)
{
CloseWavFile(); //wav代表什么
return(0);
}
while(events->type != 0) //事件类型
{
if(events->type == espeakEVENT_SAMPLERATE) //取样频率
{
samplerate = events->id.number;
samples_split = samples_split_seconds * samplerate;
}
else
if(events->type == espeakEVENT_SENTENCE) //宣判,什么意思?
{
// start a new WAV file when the limit is reached, at this sentence boundary
if((samples_split > 0) && (samples_total > samples_split))
{
CloseWavFile();
samples_total = 0;
wavefile_count++;
}
}
events++;
}
if(f_wavfile == NULL)
{
if(samples_split > 0) //样本
{
sprintf(fname,"%s_%.2d%s",wavefile,wavefile_count+1,filetype);
if(OpenWavFile(fname, samplerate) != 0)
return(1);
}
else
{
if(OpenWavFile(wavefile, samplerate) != 0)
return(1);
}
}
if(numsamples > 0)
{
samples_total += numsamples;
fwrite(wav,numsamples*2,1,f_wavfile);
}
return(0);
}
3. fflush 函数,会强迫将缓冲区的数据写会参数stream 指定的文件中。是文件系统中的文件吗?
stout 是什么?一个宏,应该是指定某个文件!
函数 ftell 用于得到文件位置指针当前位置相对于文件首的偏移字节数。
static void CloseWavFile()
{
unsigned int pos;
if((f_wavfile==NULL) || (f_wavfile == stdout))
return;
fflush(f_wavfile);
pos = ftell(f_wavfile);
fseek(f_wavfile,4,SEEK_SET);
Write4Bytes(f_wavfile,pos - 8);
fseek(f_wavfile,40,SEEK_SET);
Write4Bytes(f_wavfile,pos - 44);
fclose(f_wavfile);
f_wavfile = NULL;
} // end of CloseWavFile
原文:https://www.cnblogs.com/429512065qhq/p/14838329.html