123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- #include "tts.h"
- #include "app.h"
- #include "lsapi_tts.h"
- #include "lsapi_audio.h"
- #include "mallocSw.h"
- #define TTS_MAX_LEN (20+4*200) //max 200 chinese
- typedef struct{
- T_UINT8 plyNow:1;
- T_UINT8 ttsType;
- T_UINT16 ttsLen;
- T_UINT8 ttsData[TTS_MAX_LEN+2];//should have 2 '"'
- }TTS_DEF;
- TTS_DEF tts={
- .plyNow=0,
- };
- T_BOOL preTTSHandler(unsigned char *data, T_UINT16 *len,int data_size,unsigned char type){
- int i,j;
- T_BOOL ret=FALSE;
- unsigned char ch,lachIsZimu=0;
- if(type!=LSAPI_TTS_GBK) return TRUE;
- unsigned char *tbuf=(unsigned char *)wmalloc(data_size);
- if(tbuf==NULL) return FALSE;
- j=0;
- for(i=0;i<*len;i++){
- ch=data[i];
- if(ch >0x9f){
- if(lachIsZimu!=0){//要插入一个逗号
- if(j<data_size) tbuf[j++]=',';
- else goto ERR_END;
- }
- if(j<data_size) tbuf[j++]=data[i];
- else goto ERR_END;
- if(j<data_size) tbuf[j++]=data[i+1];
- else goto ERR_END;
- i++;
- lachIsZimu=0;
- }else if((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')){
- if(j<data_size) tbuf[j++]=ch;
- else goto ERR_END;
- lachIsZimu=1;
- }else{
- if(j<data_size) tbuf[j++]=ch;
- else goto ERR_END;
- lachIsZimu=0;
- }
- }
- *len=j;
- memcpy(data,tbuf,j);
- ret=TRUE;
- ERR_END:
- wfree(tbuf);
- return ret;
- }
- static void prvLsTtsPlayerEvCb(LSAPI_AUD_PlayerEvent_t event){
- wlog_info("tts event:%d",event);
- if(LSAPI_AUD_EVENT_FINISHED==event){//播放完毕
- msgToOutter("+LSHTTS: END\r\n");
- wlog_warn("tts end");
- app.media=MEDIA_IDLE;
- }
- }
- static int tts_speak(void){
- int result=-1;
- LSAPI_AUD_SetPlayerEvCb(prvLsTtsPlayerEvCb);
- result=LSAPI_TTS_Play(tts.ttsData, tts.ttsLen, tts.ttsType);
- wlog_info("TTS:%d,%d", tts.ttsType,tts.ttsLen);
- return result;
- }
- void tts_stop(void){
- LSAPI_TTS_Stop();
- }
- PT_THREAD (ptTTSTask(pt_timer_t *ptPool, struct pt *pt)){
- static pt_timer_t ptTimer;
- bool status;
- PT_BEGIN(pt);
- while(1){
- if(tts.plyNow==1){
- if(MEDIA_PCM==app.media){
- //media is taken by poc, need to wait it stop
- app.media=MEDIA_SHUT_PCM;
- PTTimerStart(ptPool, &ptTimer,1000);//wait 200ms to shut poc
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer)||MEDIA_PCM_PENDING==app.media);
- app.media=MEDIA_PCM_PENDING;
- }
- status=LSAPI_TTS_IsPlaying();
- if(MEDIA_TTS==app.media || true==status){
- //media is taken by tts, need to shut the current pro if it is on
- wlog_info("call tts stop");
- tts_stop();
- PTTimerStart(ptPool, &ptTimer,1000);//wait 1000ms to stop
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer)|| false==(status=LSAPI_TTS_IsPlaying()));
- }
- if(false==status) wlog_info("tts stop ok");
- else{
- wlog_info("tts stop failed, continue");
- continue;
- }
- //start new tts
- if(0==tts_speak()){
- wlog_info("tts play ok");
- app.media=MEDIA_TTS;
- }else{
- msgToOutter("+LSHTTS: END\r\n");
- wlog_info("tts play failed");
- }
- tts.plyNow=0;
- }
- PTTimerStart(ptPool, &ptTimer,1);//can be fast
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
- }
- PT_END(pt);
- }
- char checkTtsData(unsigned char *data, int len){
- int i;
- unsigned char ch;
- for(i=0;i<len;i++){
- ch=data[i];
- if((ch>='0' && ch <= '9') ||
- (ch>='a' && ch <= 'f') ||
- (ch>='A' && ch <= 'F')) {}else return 1;
- }
- return 0;
- }
- void cmdTTSHandler(T_UINT8 *data, T_UINT16 len){
- //AT+LSHTTS=x,"vvvvvv"//没有回车换行了
- //x,"vvvvvv"
- T_UINT32 thisTime,i,j,k;
- T_UINT8 *ptr=data+10,type,tmp;
- T_BOOL ttsErr=FALSE;
- //wlog_warn("*****%d,%s",len,data);
- //如果是停止指令
- if(len==11 && ptr[0]=='0'){
- tts_stop();
- return;
- }
- //如果是播放指令
- if(len<15 || ptr[1] != ',' || (ptr[0] != '1' && ptr[0] != '2' && ptr[0] != '3') || ptr[2]!='"' || data[len-1] != '"'){
- wlog_warn("tts invalid1");
- goto TTS_ERROR;
- }
- type=ptr[0]-0x30;
- ptr += 3;//VVVVVVV"
- k=len-10-3-1;
- //检测数据合法性
- if(type==1 || type==2){//GBK/UNICODE的十六进制字符串
- if(type==1) tmp=k%2;
- else tmp=k%4;
- if(0!=checkTtsData(ptr,k) || tmp){
- wlog_warn("tts invalid2");
- goto TTS_ERROR;
- }
- if(0!=restoreDataFormatByHex(ptr,k)){
- wlog_warn("tts invalid3");
- goto TTS_ERROR;
- }
- k /= 2;
- type --;
- }else type=0;
- if(k>TTS_MAX_LEN){
- wlog_warn("tts len over");
- goto TTS_LENOV;
- }
- tts.ttsLen=k;
- tts.ttsType=type;
- memcpy(tts.ttsData,ptr,tts.ttsLen);
- if(FALSE==preTTSHandler(tts.ttsData,&tts.ttsLen,sizeof(tts.ttsData),tts.ttsType)) goto TTS_ERROR;
- tts.plyNow=1;
- return;
- TTS_ERROR:
- msgToOutter("+LSHTTS: ERROR\r\n");
- return;
- TTS_LENOV:
- msgToOutter("+LSHTTS: LENOV\r\n");
- }
|