千家信息网

如何实现基于树莓派的语音机器人

发表于:2024-10-04 作者:千家信息网编辑
千家信息网最后更新 2024年10月04日,这篇文章将为大家详细讲解有关如何实现基于树莓派的语音机器人,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。准备工作:树莓派,音频模块,stm32单片机,百度语音识别接
千家信息网最后更新 2024年10月04日如何实现基于树莓派的语音机器人

这篇文章将为大家详细讲解有关如何实现基于树莓派的语音机器人,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

准备工作:树莓派,音频模块,stm32单片机,百度语音识别接口,喇叭。

整体思路:

1. 由于树莓派没有ADC模块,所以这里借助于stm32的ADC模块来实现将语音信号转换成数字信号,然后通过串口传 输 到树莓派你中,树莓派你将数据组装成wave文件,便于语音识别。

2. 通过http协议将组装的语音文件上传到百度语音识别平台进行识别。文档说明(免费调用)

3. 根据识别结果做出相应的处理。

4. 对于需要播放语音时,根据百度语音合成接口合成语音然后使用mplayer播放出来。mplayer安装参考 博客

部分代码:

将音频转换成wave文件

#include #include #include #include #include  #include #include #include #include #include "listen.h"//gcc -o uart uart.c -lwiringPitypedef struct WAV_Format WAVHEADER; #define MAX_LISTEN_SIZES 1024*70 //定义接收数据的大小#define bty 460800//串口的波特率struct listen*listenUart(){ int fd,file; char buff,buff2; struct listen*liste=(struct listen*)malloc(sizeof(struct listen));  unsigned short size; unsigned short*music,temp=0; unsigned short max=0,min=0; char*result=NULL;//存储最后的返回值 int index=0,i=0; char stop=1; WAVHEADER wavHead; music=(unsigned short*)malloc(MAX_LISTEN_SIZES*2); result=(char*)malloc(MAX_LISTEN_SIZES*2+sizeof(WAVHEADER)); if(wiringPiSetup() < 0)return NULL; if((fd = serialOpen ("/dev/ttyAMA0",bty))<0) { return NULL;  printf("serial err\n"); } //file=open("abc.wav", O_RDWR|O_CREAT); printf("oepn success\n"); //serialPrintf(fd,"Hello World!!!");  //需要对音频信号作出处理,当大于或者阈值时开始统计,知道录制完成 int countTotal=0; int countNumber= 1000;//统计个数 int countMax=2860;//最大值 int countMin=2840;//最小值 int startCount=1; while(1) {  if(index==MAX_LISTEN_SIZES)  {  break;  }  buff=serialGetchar(fd);  buff2=serialGetchar(fd);  if((buff2&0x0F0)!=0)  {   buff2=serialGetchar(fd);  }  else  {   size=buff2;   size=size<<8;   size=(size&0xFF00)|(buff&0xFF);   music[index]=size;   if(startCount==1)   {   countTotal=countTotal+size;   if(index>=countNumber)   {    int temp=countTotal/(countNumber+1);    if(temp>countMax||tempmax)  {  max=temp;  }  if(templength=sizeof(WAVHEADER)+MAX_LISTEN_SIZES*2; liste->data=result; return liste;}

将音频识别成文字

#include "convertText.h"static Buffer *listen_buff2=NULL;size_t listen_getData2(void *ptr, size_t size, size_t nmemb, void *stream) { appendBuffer(listen_buff2,ptr,nmemb); return nmemb;}int listenText(char*result2){ listen_buff2=initBuffer(); struct listen*lsn=listenUart(); char*base; int fileLength=lsn->length; int result=1; int baseSize=(lsn->length/3)*4+(lsn->length%3)*2+1; base=(char*)malloc(baseSize); base64_encode(lsn->data,lsn->length,base); //发送请求 free(lsn->data); free(lsn); int code=initToken(); if(code==1) { char*token=getToken(); ///开始创建json字符串 cJSON * root = cJSON_CreateObject(); cJSON_AddItemToObject(root, "format", cJSON_CreateString("wav")); cJSON_AddItemToObject(root, "rate", cJSON_CreateString("16000")); cJSON_AddItemToObject(root, "channel", cJSON_CreateString("1")); cJSON_AddItemToObject(root, "cuid", cJSON_CreateString("34-68-95-91-77-43")); cJSON_AddItemToObject(root, "token", cJSON_CreateString(token)); cJSON_AddItemToObject(root, "dev_pid", cJSON_CreateString("1537")); cJSON_AddItemToObject(root, "speech", cJSON_CreateString(base)); cJSON_AddItemToObject(root, "len", cJSON_CreateNumber(fileLength)); char*jsonParam=cJSON_PrintUnformatted(root);  char*apiurl="http://vop.baidu.com/server_api";  CURL* curl; CURLcode res;  // ptr = curl_easy_escape(NULL, (char *)a, asize);  curl = curl_easy_init(); struct curl_slist* headers = NULL; headers = curl_slist_append(headers, "Content-Type:application/json"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_URL, apiurl); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60);  curl_easy_setopt(curl, CURLOPT_POST, 1);  //http://vop.baidu.com/server_api  //CURLOPT_POSTFIELDS,CURLOPT_POSTFIELDSIZE  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonParam);  curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(jsonParam)); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, listen_getData2); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); res = curl_easy_perform(curl);  curl_easy_cleanup(curl); cJSON_Delete(root);  curl_slist_free_all(headers); free(token); free(jsonParam); if (res == CURLE_OK)  { char*chars; char*tempresult=(char*)malloc(listen_buff2->length+1); memcpy(tempresult,listen_buff2->buff,listen_buff2->length); tempresult[listen_buff2->length]=0; cJSON *json; cJSON * item = NULL; cJSON*errCode;   json=cJSON_Parse(tempresult);   item=cJSON_GetObjectItem(json, "result"); errCode=cJSON_GetObjectItem(json, "err_no"); if(errCode->valueint!=0) {  return -3; } chars=cJSON_GetArrayItem(item,0)->valuestring; strcpy(result2,chars); free(tempresult); cJSON_Delete(json); return 0;  } else { return -3; }  } else { return -2; } return -1;}

主程序

#include #include #include "convertText.h"#include "mp3.h"#include "led.h"#include "say.h" //gcc -o robot robot.o mp3.o Buffer.o base64.o token.o cJSON.o listen.o convertText.o led.o say.o -lcurl -lm -lwiringPi -lmad void sayChina(char*china){ int resp=initSay(china); printf("resp:%d\n",resp); if(resp==1) { int tte=playData("temp.mp3"); printf("tte:%d\n",tte); }}int main(){ char text[100]={0}; sayChina("你好,我是小志,有什么可以为你服务"); while(1) { printf(";;;;;;;;"); int code= listenText(text); if(code==0) { printf("result:%s\n",text); if(strstr(text,"播放音乐,")!=NULL||strstr(text,"打开音乐,")!=NULL) { sayChina("正在为你打开音乐"); musicPlayFile("mu.mp3"); } if(strstr(text,"打开灯,")!=NULL||strstr(text,"打开,")!=NULL) { sayChina("好的"); printf("正在打开"); ledOn(); } if(strstr(text,"关闭灯,")!=NULL||strstr(text,"关闭,")!=NULL||strstr(text,"完毕,")!=NULL) { sayChina("好的"); printf("正在关闭"); ledOff(); } if(strstr(text,"你叫什么")!=NULL||strstr(text,"你叫什么名字")!=NULL||strstr(text,"名字")!=NULL) { sayChina("我叫小志"); } if(strstr(text,"今天天气咋样")!=NULL||strstr(text,"天气")!=NULL) { sayChina("外面在下雨,有点冷"); } if(strstr(text,"中午好")!=NULL||strstr(text,"中午")!=NULL) { sayChina("好什么啊,我还没吃饭呢"); } if(strstr(text,"你多大了")!=NULL||strstr(text,"今年几岁")!=NULL||strstr(text,"几岁")!=NULL) { sayChina("我才出生,还没满月"); } } else { printf("error\n"); } } return 0;}

关于"如何实现基于树莓派的语音机器人"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

0