1. 新手求教 单片机TTS
你这个……用ARM吧(51应该也行),TTS我没用过,但基本思路是:
存储器里面要有这些东西:
1、所有拼音四个声调的频率或者模块
2、常用汉字拼音编码表(就是根据汉字查出拼音)
3、声音解码。
4、喇嘛。
这些只能实现非常简单的朗读,因为汉字多音字很多。
要是我做,需要一个8051,一个MP3解码芯片,一个汉字拼音编码表,一个SD卡模块
找真人录音,找个字典把前面按拼音查找的地方,把每个音都念一遍录下来变成MP3存在sd卡里面,然后汉字编码表有点大,89c516估计能放下,然后电脑串口输入的汉字经过编码表变成一个SD卡里面的文件地址,然后控制MP3解码芯片播放就行了。
这东西我没研究过……你参考一下吧……
2. 怎么让单片机阅读文字信息或者自动翻译图片上的文字
可以实现,
第一:你需要一个扫描器(千万别指望单片机内部来完成),最好这个扫描器能自动识出文字(有吗?我不知道,如果有也应该是扫描模块)。然后把这个扫描器连接到单片机上(如何连接,取决于扫描模块的接口,如I2C、PCI等);
第二:你需要外接一个语音合成芯片(别指望单片机来实现这个功能),将转换的文字信息交给语音芯片来合成;
第三:你需要外接一个扬声器,以便于发声。
呵呵!这样看来单片机只起到一个指挥的功能。
至于你说的用电脑来翻译,只是把我说的第一步由电脑来完成,另外两部分还是需要实现。至于让单片机来阅读你从电脑发送的(可通过串口或USB来实现)信息,还是别指望单片机来实现。
对了,由于信息量非常大,你可能需要扩展数据存储器,不够用。
3. 凌阳61单片机的优势以及其在语音识别方面上的优势
凌阳单片机本身具备语音识别功能,不需要外扩语音识别模块,虽然具有一点点DSP功能,就能做到语音识别功能。如常见的语音控制机器人,语音控制小车等。
我们所说的音频是指频率在20 Hz~20 kHz的声音信号,分为:波形声音、语音和音乐三种,其中波形声音就是自然界中所有的声音,是声音数字化的基础。语音也可以表示为波形声音,但波形声音表示不出语言、语音学的内涵。语音是对讲话声音的一次抽象。是语言的载体,是人类社会特有的一种信息系统,是社会交际工具的符号。音乐与语音相比更规范一些,是符号化了的声音。但音乐不能对所有的声音进行符号化。乐谱是符号化声音的符号组,表示比单个符号更复杂的声音信息内容。
将模拟的(连续的)声音波形数字符化(离散化),以便利数字计算机进行处理的过程,主要包括采样和量化两个方面。
数字音频的质量取决于:采样频率和量化位数这两个重要参数。此外,声道的数目、相应的音频设备也是影响音频质量的原因
语音压缩编码中的数据量是指:数据量=(采样频率×量化位数)/8(字节数) ×声道数目。
压缩编码的目的:通过对资料的压缩,达到高效率存储和转换资料的结果,即在保证一定声音质量的条件下,以最小的资料率来表达和传送声音信息。
压缩编码的必要性:实际应用中,未经压缩编码的音频资料量很大,进行传输或存储是不现实的。 所以要通过对信号趋势的预测和冗余信息处理,进行资料的压缩,这样就可以使我们用较少的资源建立更多的信息。
举个例子,没有压缩过的CD品质的资料,一分钟的内容需要11MB的内存容量来存储。如果将原始资料进行压缩处理,在确保声音品质不失真的前提下,将数据压缩一半,5.5MB就可以完全还原效果。而在实际操作中,可以依需要来选择合适的算法。
常见的几种音频压缩编码:
1) 波形编码:将时间域信号直接变换为数字代码,力图使重建语音波形保持原语音信号的波形形状。波形编码的基本原理是在时间轴上对模拟语音按一定的速率抽样,然后将幅度样本分层量化,并用代码表示。译码是其反过程,将收到的数字序列经过译码和滤波恢复成模拟信号。
如:脉冲编码调制(Pulse Code Molation,PCM)、差分脉冲编码调制(DPCM)、增量调制(DM)以及它们的各种改进型,如自适应差分脉冲编码调制(ADPCM)、自适应增量调制(ADM)、自适应传输编码(Adaptive Transfer Coding,ATC)和子带编码(SBC)等都属于波形编码技术。
波形编码特点:高话音质量、高码率,适于高保真音乐及语音。
2) 参数编码:参数编码又称为声源编码,是将信源信号在频率域或其它正交变换域提取特征参数,并将其变换成数字代码进行传输。译码为其反过程,将收到的数字序列经变换恢复特征参量,再根据特征参量重建语音信号。具体说,参数编码是通过对语音信号特征参数的提取和编码,力图使重建语音信号具有尽可能高的准确性,但重建信号的波形同原语音信号的波形可能会有相当大的差别。
如:线性预测编码(LPC)及其它各种改进型都属于参数编码。该编码比特率可压缩到2Kbit/s-4.8Kbit/s,甚至更低,但语音质量只能达到中等,特别是自然度较低。
参数编码特点:压缩比大,计算量大,音质不高,廉价!
3) 混合编码:混合编码使用参数编码技术和波形编码技术,计算机的发展为语音编码技术的研究提供了强有力的工具,大规模、超大规模集成电路的出现,则为语音编码的实现提供了基础。80年代以来,语音编码技术有了实质性的进展,产生了新一代的编码算法,这就是混合编码。它将波形编码和参数编码组合起来,克服了原有波形编码和参数编码的弱点,结合各自的长处,力图保持波形编码的高质量和参数编码的低速率。
如:多脉冲激励线性预测编码(MPLPC),规划脉冲激励线性预测编码(KPELPC),码本激励线性预测编码(CELP)等都是属于混合编码技术。其数据率和音质介于参数和波形编码之间。
总之,音频压缩技术之趋势有两个:
1)降低资料率,提高压缩比,用于廉价、低保真场合(如:电话)。
2)追求高保真度,复杂的压缩技术(如:CD)。
7.1.5 语音合成、辨识技术的介绍:
按照实现的功能来分,语音合成可分两个档次:
(1) 有限词汇的计算机语音输出
(2) 基于语音合成技术的文字语音转换(TTS:Text-to-Speech)
按照人类语言功能的不同层次,语音合成可分为三个层次:
(1) 从文字到语音的合成(Text-to-Speech)
(2) 从概念到语音的合成(Concept-to-Speech)
(3) 从意向到语音的合成(Intention-to-Speech)
早期只能辨认特定的使用者即特定语者(Speaker Dependent,SD)模式,使用者可针对特定语者辨认词汇(可由使用者自行定义,如人名声控拨号),作简单快速的训练纪录使用者的声音特性来加以辨认。随着技术的成熟,进入语音适应阶段SA(speaker adaptation),使用者只要对于语音辨识核心,经过一段时间的口音训练后,即可拥有不错的辨识率。
2)非特定语者模式(Speaker Independent,SI),使用者无需训练即可使用,并进行辨认。任何人皆可随时使用此技术,不限定语者即男性、女性、小孩、老人皆可。
连续语音:
1)单字音辨认:为了确保每个字音可以正确地切割出来,必须一个字一个字分开来念,非常不自然,与我们平常说话的连续方式,还是有点不同。
2)整个句子辨识:只要按照你正常说话的速度,直接将要表达的说出来,中间并不需要停顿,这种方式是最直接最自然的,难度也最高,现阶段连续语音的辨识率及正确率,虽然效果还不错但仍需再提高。然而,中文字有太多的同音字,因此目前所有的中文语音辨识系统,几乎都是以词为依据,来判断正确的同音字。
可辨认词汇数量:
内建的词汇数据库的多寡,也直接影响其辨识能力。因此就语音辨识 的词汇数量来说亦可分为三种:
1)小词汇量(10-100)
2)中词汇量(100-1000)
3)无限词汇量(即听写机)
压缩分无损压缩和有损压缩。
无损压缩一般指:磁盘文件,压缩比低:2:1~4:1。
而有损压缩则是指:音/视频文件,压缩比可高达100:1。
凌阳音频压缩算法根据不同的压缩比分为以下几种 (具体可参见语音压缩工具一节内容):
SACM-A2000:压缩比为8:1,8:1.25,8:1.5
SACM-S480: 压缩比为80:3,80:4.5
SACM-S240: 压缩比为80:1.5
按音质排序:A2000>S480>S240
凌阳的SPCE061A是16位单片机,具有DSP功能,有很强的信息处理能力,最高时钟频率可达到49MHz,具备运算速度高的优势等等,这些都无疑为语音的播放、录放、合成及辨识提供了条件。
凌阳压缩算法中SACM_A2000、SACM_S480、SACM_S240主要是用来放音,可用于语音提示,而DVR则用来录放音。对于音乐合成MS01,该算法较繁琐,而且需要具备音乐理论、配器法及和声学知识,所以对于特别爱好者可以到我们的网站去了解相关内容,这里只给出它的API函数介绍及程序代码的范例,仅供参考。
在前面我们已经介绍过语音辨识的一些相关的内容,在这里我们给出SPCE061的特定语者辨识SD(Speaker Dependent)的一个例子以供有兴趣者参考。SD即语音样板由单个人训练,也只能识别训练某人的语音命令,而他人的命令识别率较低或几乎不能识别。
同样语音辨识也将其一些功能作成模块,并通过API调用来实现这些功能,在这里我们为大家介绍一些常用的API函数,如果有兴趣者可以登陆我们的网站去获得更多的相关内容
初始化:
【API格式】C: int BSR_DeleteSDGroup(0);
ASM:F_BSR_DeleteSDGroup(0)
【功能说明】SRAM初始化。
【参 数】该参数是辨识的一个标识符,0代表选择SRAM,并初始化。
【返 回 值】当SRAM擦除成功返回0,否则,返回-1。
训练部分:
1) 【API格式】C:int BSR_Train (int CommandID, int TraindMode);
ASM:F_BSR_Train
【功能说明】训练函数。
【参 数】
CommandID:命令序号,范围从0x100到0x105,并且对于每组训练语句都是唯一的。
TraindMode:训练次数,要求使用者在应用之前训练一或两遍:
BSR_TRAIN_ONCE:要求训练一次。
BSR_TRAIN_TWICE要求训练两次。
【返 回 值】训练成功,返回0;没有声音返回-1;训练需要更多的语音数据来训练,返回-2;当环境太吵时,返回-3;当数据库满,返回-4;当两次输入命令不通,返回-5;当序号超出范围,返回-6。
【备 注】
① 在调用训练程序之前,确保识别器正确的初始化。
② 训练次数是2时,则两次一定会有差异,所以一定要保证两次训练结果接近
③ 为了增强可靠性,最好训练两次,否则辨识的命令就会倾向于噪音
④ 调用函数后,等待2秒开始训练,每条命令只有1 .3秒,也就是说,当训练命令超出1.3秒时,只有前1.3秒命令有效。
辨识部分:
1)【API格式】C: void BSR_InitRecognizer(int AudioSource)
ASM:F_BSR_InitRecognizer
【功能说明】辨识器初始化。
【参 数】 定义语音输入来源。通过MIC语音输入还是LINE_IN电压模拟量输入。
【返 回 值】无。
2)【API格式】C:int BSR_GetResult();
ASM:F_ BSR_GetResult
【返回值】=R1
【功能说明】辨识中获取数据。
【参 数】 无。
【返 回 值】
当无命令识别出来时,返回0;
识别器停止未初始化或识别未激活返回-1;
当识别不合格时返回-2;
当识别出来时返回命令的序号。
` 【备 注】 该函数用于启动辨识,BSR_GetResult();
3)【API格式】C: void BSR_StopRecognizer(void);
ASM:F_ BSR_StopRecognizer
【功能说明】停止辨识。
【参 数】无。
【返 回 值】 无。
【备 注】该函数是用于停止识别,当调用此函数时,FIQ_TMA中断将关闭。
中断部分:
【API格式】 ASM:_BSR_InitRecognizer
【功能说明】 在中断中调用,并通过中断将语音信号送DAC通道播放。
【参 数】无。
【返 回 值】无。
【备 注】
① 该函数在中断FIQ_TMA中调用
② 当主程序调用BSR_InitRecognizer时,辨识器便打开8K采样率的FIQ_TMA中断并开始将采样的语音数据填入辨识器的数据队列中。
③ 应用程序需要设置一下程序段在FIQ_TMA中:
.PUBLIC _FIQ
.EXTERNAL _BSR_FIQ_Routine //定义全局变量
.TEXT
_FIQ:
PUSH R1,R4 to [SP] //寄存器入栈保护
R1 = [P_INT_Ctrl]
CALL _BSR_FIQ_Routine //调用子程序
R1 = 0x2000 //清中断标志位
[P_INT_Clear] = R1
POP R1,R4 from [SP]; //寄存器组出栈
RETI
END
以下是特定人辨识的一个范例:
在程序中我们通过三条语句的训练演示特定人连续音识别,其中第一条语句为触发名称。另外两条为命令,训练完毕开始辨识当识别出触发名称后,开始发布命令,则会听到自己设置的应答,具体命令如下:
****************训练******************************************
提示音 输入语音
--------------------------------------------------------------------------------------------------------
"请输入触发名称" "警卫"
"请输入第一条命令" "开枪"
"请输入第二条命令" "你在干什么?"
"请再说一遍"(以上提示音每说完一遍出现此命令)
"没有听到任何声音"(当没有检测到声音时出现此命令)
"两次输入名称不相同"(当两次输入的名称不同时出现此命令)
"两次输入命令不相同"(当两次输入的命令有差异时出现此命令)
"准备就绪,请开始辨识"(以上三条语句全部训练成功时,进入识别)
*****************识别**********************************************************************
发布命令 应答
----------------------------------------------------------------------------------------------------------
"警卫" "在"/"长官"
"开枪" "枪声"
"你在干什么?" "我在巡逻"/"我在休息"/"我在等人"
注意:在每次提示音结束后2-3秒再输入命令或当上次应答结束2-3秒后再发布命令
#INCLUDE "bsrsd.h"
#DEFINE NAME_ID 0x100
#DEFINE COMMAND_ONE_ID 0x101
#DEFINE COMMAND_TWO_ID 0x102
#DEFINE RSP_INTR 0
#DEFINE RSP_NAME 1
#DEFINE RSP_FIRE 2
#DEFINE RSP_GUARD 3
#DEFINE RSP_AGAIN 4
#DEFINE RSP_NOVOICE 5
#DEFINE RSP_NAMEDIFF 6
#DEFINE RSP_CMDDIFF 7
#DEFINE RSP_STAR 8
#DEFINE RSP_MASTER 9
#DEFINE RSP_HERE 10
#DEFINE RSP_GUNSHOT 0
#DEFINE RSP_PATROL 11
#DEFINE RSP_READY 12
#DEFINE RSP_COPY 13
#DEFINE RSP_NOISY 14
//..................全程变量..................……………………………………………………………………….
int gActivated = 0;
//该变量用于检测是否有触发命令,当有识别出语句为触发名称则该位置1
int gTriggerRespond[] = {RSP_MASTER, RSP_HERE, RSP_MASTER};
//第一条命令应答
int gComm2Respond[] = {RSP_PATROL, RSP_READY, RSP_COPY};
//第二条命令应答
extern void ClearWatchDog();
int PlayFlag = 0;
void PlayRespond2(int Result)
//枪声放音子程序
{
BSR_StopRecognizer();
SACM_A2000_Initial(1);
SACM_A2000_Play(Result, 3, 3);
while((SACM_A2000_Status()&0x0001) != 0)
{
SACM_A2000_ServiceLoop();
ClearWatchDog();
}
SACM_A2000_Stop();
BSR_InitRecognizer(BSR_MIC);
BSR_EnableCPUIndicator();
}
void PlayRespond(int Result) //放音子程序
{
BSR_StopRecognizer();
SACM_S480_Initial(1);
SACM_S480_Play(Result, 3, 3);
while((SACM_S480_Status()&0x0001) != 0)
{
SACM_S480_ServiceLoop();
ClearWatchDog();
}
SACM_S480_Stop();
BSR_InitRecognizer(BSR_MIC);
BSR_EnableCPUIndicator(); //启动实时监控
}
int TrainWord(int WordID, int RespondID) //命令训练
{
int res;
PlayRespond(RespondID);
while(1)
{
res = BSR_Train(WordID,BSR_TRAIN_TWICE);
if(res == 0) break;
switch(res)
{
case -1: //没有检测出声音
PlayRespond(RSP_NOVOICE);
return -1;
case -2: //需要重新训练一遍
PlayRespond(RSP_AGAIN);
break;
case -3: //环境太吵
PlayRespond(RSP_NOISY);
return -1;
case -4: //数据库满
return -1;
case -5: //检测出声音不同
if(WordID == NAME_ID)
PlayRespond(RSP_NAMEDIFF); //两次输入名称不同
else
PlayRespond(RSP_CMDDIFF);//两次输入命令不同
return -1;
case -6: //序号错误
return -1;
}
}
return 0;
}
int main()
{
int res, timeCnt=0, random_no=0;
BSR_DeleteSDGroup(0); // 初始化存储器为RAM
PlayRespond(RSP_INTR); //播放开始训练的提示音
//..........训练名称..............................
while(TrainWord(NAME_ID,1) != 0) ;
//..........训练第一条命令.......................
while(TrainWord(COMMAND_ONE_ID,2) != 0) ;
//..........训练第二条命令.......................
while(TrainWord(COMMAND_TWO_ID,3) != 0) ;
//..........开始识别命令.........................
BSR_InitRecognizer(BSR_MIC); //辨识器初始化
BSR_EnableCPUIndicator();
PlayRespond(RSP_STAR); // 播放开始辨识的提示音
while(1)
{
random_no ++;
if(random_no >= 3) random_no = 0;
res = BSR_GetResult();
if(res > 0) //识别出命令
{
if(gActivated)
{
timeCnt = 0;
switch(res)
{
case NAME_ID:
PlayRespond(gTriggerRespond[random_no]);
break;
case COMMAND_ONE_ID:
PlayFlag = 1;
PlayRespond2(RSP_GUNSHOT);
PlayFlag = 0;
gActivated = 0;
break;
case COMMAND_TWO_ID:
PlayRespond(gComm2Respond[random_no]);
gActivated = 0;
}
}
else
{
if(res == NAME_ID)
{PlayRespond(gTriggerRespond[random_no]);
gActivated = 1;
timeCnt = 0;
}
}
}
else if (gActivated)
{
if (++timeCnt > 450) //超出定时
{PlayRespond(RSP_NOVOICE); //在设定时间内没有检测出声音
gActivated = 0;
timeCnt = 0;
}
}
}
}
中断程序:
.PUBLIC _FIQ
.EXTERNAL _BSR_FIQ_Routine
.EXTERNAL __gIsStopRecog //变量值 = 0 辨识器忙
// = 1 辨识器停止
.PUBLIC _BREAK,_IRQ0, _IRQ1, _IRQ2, _IRQ3, _IRQ4, _IRQ5, _IRQ6, _IRQ7
.EXTERNAL _PlayFlag
.INCLUDE s480.inc;
.INCLUDE A2000.inc;
.INCLUDE resource.inc
.INCLUDE hardware.inc
.TEXT
_FIQ:
push R1,R4 to [SP]
R1 = [P_INT_Ctrl]
R1 &= 0x2000
jz ?notTimerA //当不为TIQ_TMA,则转
R1 = [__gIsStopRecog]
jnz ?BSR_NotBusy
//[__gIsStopRecog]为1则转至放音处理
call _BSR_FIQ_Routine //为0,调用辨识子程序
jmp ?BSR_Busy //返回中断
?BSR_NotBusy: //放音处理
R2 = [_PlayFlag]
jnz ?Play2000 //[_PlayFlag]为1则是播放2000
call F_FIQ_Service_SACM_S480; //为0,播放480
jmp ?BSR_Busy //返回中断
?Play2000: //2000播放子程序
call F_FIQ_Service_SACM_A2000;
?BSR_Busy: //返回中断
R1 = 0x2000
[P_INT_Clear] = R1
pop R1,R4 from [SP];
reti;
?notTimerA:
R1 = 0x8800;
[P_INT_Clear] = R1;
pop R1,R4 from [SP];
reti;
.END
4. 单片机中的语音播报可以加入变量吗,例如速度在不断发生改变,播报的值也变化
可以的~~
使用TTS语音合成模块就可以,按照它的控制协议,构建播放内容数据,发给它就可以播放。
型号应该是SYN6288