首页 > 其他 > 详细

开源语音代码eSpeak1.06 的移植到单片机的过程

时间:2021-06-01 19:18:14      阅读:30      评论:0      收藏:0      [点我收藏+]

以下所有的内容基于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 用于得到文件位置指针当前位置相对于文件首的偏移字节数。

找到 它的 定义,是个文件。应该是linux 的写法。 FILE *f_wavfile = NULL;
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

 

开源语音代码eSpeak1.06 的移植到单片机的过程

原文:https://www.cnblogs.com/429512065qhq/p/14838329.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!