技术点:

C++STL
● http第三方库
● 图灵机器人
百度语音识别和语音识别
● Linux系统/网络编程
● 各种第三方库和第三方工具的安装与使用

项目简介

  • 使用C++编写一个智能AI对话和语音命令执行的语音管理工具,其中可执行命令支持配置。
  • 主要采用C++进程编写,当程序启动后,加载配置文件,启动录音功能进行录音,调用百度语音识别平台对所录音文件进行识别;再对所识别到的文字进行判断,是命令还是普通对话,命令则执行系统命令执行模块;普通对话则交给图灵机器人进行交流,所返回的文字交给百度语音合成平台,启动播放功能,则成功进行对话。

准备工作

  • 使用图灵机器人实现对话,需要注册图灵机器人,拥有一个属于自己的机器人
  • 使用百度语音识别和语音合成,同样也需要注册,在之后的使用中,我们选择的技术文档为C++SDK,需要下载百度C++语音识别SDK
  • 安装jsoncpp、 安装openssl、安装libcurl(需要支持https)
  • 还要准备录音和播放工具,在我的Centos 7上有系统自带的录音工具arecord,安装vlc/cvlc播放器

编码过程

● 先建立项目目录,创建工程文件,引入百度语音识别SDK

#mkdir Boyfriend
#ls build.sh
  • 构建项目的shell脚本,简单实现 command.etc
  • 语音命令配置文件 Boyfriend.cc
  • 源文件 Boyfriend.hpp
  • 核心代码 Makefile speech
  • 百度语音识别SDK temp_file
  • 保存临时语音文件目录

核心代码

LInux语音AI相关代码

  #Boyfriend.hpp//1、创建相关类,包含相关头文件#pragma once#include <map>#include <iostream>#include <cstdio>#include <sstream>#include <memory>#include <fstream>#include <unistd.h>#include <stdlib.h>#include <unordered_map>#include <json/json.h>#include <string>#include <pthread.h>#include "base/http.h"#include "speech.h"//#define TTS_PATH "temp_file/tts.mp3"#define TTS_PATH "temp_file/tts.wav"#define ASR_PATH "temp_file/asr.wav"#define CMD_ETC "command.etc"#define LOG "log.txt"class Util{private:static pthread_t id;public:static bool Exec(std::string command, bool is_print){if(!is_print){command += ">/dev/null 2>&1";}FILE *fp = popen(command.c_str(), "r");if(nullptr == fp){std::cerr << "popen exec \'" << command << "\' Error" << std::endl;return false;}if(is_print){char ch;while(fread(&ch,1,1,fp) >0){fwrite(&ch,1,1,stdout);}}pclose(fp);return true;}static void *ThreadRun(void *arg){const char *tips = (char*)arg;int i = 0;char bar[103] = {0};const char *lable = "|/-\\";for(; i<=50;i++){printf("%s[%-51s][%d%%][%c]\r",tips,bar,i*2,lable[i%4]);fflush(stdout);bar[i] = '=';bar[i+1] = '>';//bar[i+2] = 0;usleep(49000*2);}printf("\n");}static void PrintStart(std::string tips){pthread_create(&id,NULL,ThreadRun,(void*)tips.c_str());}static void PrintEnd(){pthread_cancel(id);}};pthread_t Util::id;//2、采用图灵机器人,进行智能对话class Robot{private:std::string url;std::string api_key;std::string user_id;aip::HttpClient client;private:bool IsCodeLegal(int code){bool result = false;switch(code){case 5000:case 6000:break;case 10004:result = true;break;default:result = true;break;}return result;}std::string MessageToJson(std::string &message){Json::Value root;Json::StreamWriterBuilder wb;std::ostringstream ss;Json::Value item_;item_["text"] = message ;Json::Value item;item["inputText"] = item_ ;root["reqType"] = 0;//textroot["perception"] = item;item.clear();item["apiKey"] = api_key;item["userId"] = user_id;root["userInfo"] = item;std::unique_ptr<Json::StreamWriter> sw(wb.newStreamWriter());sw->write(root,&ss);std::string json_string = ss.str();//std::cout<<"debug: "<<json_string<<std::endl;return json_string;}std::string RequestTL(std::string &request_json){std::string response;int status_code = client.post(url,nullptr,request_json,nullptr,&response);if (status_code != CURLcode::CURLE_OK) {std::cerr << "post error" << std::endl;return "";}return response;}std::string JsonToEchoMessage(std::string &str){//std::cout <<"JsonToEchoMessage:"<< str << std::endl;JSONCPP_STRING errs;Json::Value root;Json::CharReaderBuilder rb;std::unique_ptr<Json::CharReader> const cr(rb.newCharReader());bool res = cr->parse(str.data(),str.data()+str.size(), &root,&errs);if(!res || !errs.empty()) {std::cerr << "parse error!"<<std::endl;return "";}int code = root["intent"]["code"].asInt();if(!IsCodeLegal(code)){std::cerr<< "response code error!" <<std::endl;return "";}Json::Value item = root["results"][0];std::string msg = item["values"]["text"].asString();return msg;}public:Robot(std::string id = "1"){this->url = "http://openapi.tuling123.com/openapi/api/v2";this->api_key = "b7fa07e47cbe46a191b8190cc004ed60";this->user_id = id;}std::string Talk(std::string message){std::string json = MessageToJson(message);std::string responce = RequestTL(json);std::string echo_message = JsonToEchoMessage(responce);return echo_message ;}~Robot(){}};//3、语音识别Speech Recognitionclass SpeechRec{private://填写appid,填写Api Key,填写Secret Key.std::string app_id;std::string api_key;std::string secret_key;aip::Speech *client;private:bool IsCodeLegal(int code){bool result = false;switch(code){case 0:result=true;break;default:break;}return result;}public:SpeechRec(){app_id = "16943059";api_key = "q9vkbqwjwKjvoPgt69NTt36F";secret_key = "8lbil7MTruiGKHQdSsIT1WB97rX4ncsl";client = new aip::Speech(app_id, api_key, secret_key);}//4、语音识别Automatic Speech Recognitionbool ASR(std::string path,std::string &out){std::map<std::string,std::string> options;options["dev_pid"] = "1536";std::string file_content;aip::get_file_content(ASR_PATH,&file_content);Json::Value result = client->recognize(file_content,"wav",16000,options);//std::cout << "debug: " << result.toStyledString() << std::endl;int code = result["err_no"].asInt();if(!IsCodeLegal(code)){std::cerr << "recognize error" << std::endl;return false;}out = result["result"][0].asString();return true;}//5、语音合成Text To Speechbool TTS(std::string message){bool ret;std::ofstream ofile;std::string ret_file;std::map<std::string,std::string> options;options["spd"]="5"; //speech speed 0~15options["pit"]="7"; //0-15options["vol"]="15"; //0-15options["per"]="110"; //1 0 3 4 度博文=106 度小童=110 度小萌=111 度米朵=103 度小娇=5options["aue"]="6";ofile.open(TTS_PATH,std::ios::out|std::ios::binary);Json::Value result=client->text2audio(message,options,ret_file);if(!ret_file.empty()){ofile << ret_file;ofile.close();ret = true;}else{std::cerr <<result.toStyledString() << std::endl;ret = false;}ofile.close();return ret;}~SpeechRec(){}};//6、核心代码-服务器&&系统相关class Boyfriend{private:Robot rt;SpeechRec sr;std::unordered_map<std::string,std::string> commands;private:bool Record(){//std::cout << "debug:" << "Record ..." << std::endl;Util::PrintStart("录音中");std::string command = "arecord -t wav -c 1 -r 16000 -d 5 -f S16_LE ";command += ASR_PATH;bool ret = Util::Exec(command,false);//std::cout << "debug:Recoed ... done" <<std::endl;Util::PrintEnd();return ret;}bool Play(){std::string command = "cvlc --play-and-exit ";command += TTS_PATH;return Util::Exec(command,false);}public:Boyfriend(){};bool LoadEtc(){std::ifstream in(CMD_ETC);if(!in.is_open()){std::cerr <<"open error" <<std::endl;return false;}std::string sep = ":";char line[256];while(in.getline(line,sizeof(line))){std::string str = line;std::size_t pos = str.find(sep);if(std::string::npos == pos){std::cerr << "not find :" << std::endl;continue;}std::string k = str.substr(0,pos);std::string v = str.substr(pos+sep.size());k+="。";commands.insert(std::make_pair(k,v));//commands.insert({k,v});}std::cerr <<"Load command erc done ... success"<< std::endl;in.close();return true;}bool IsCommand(std::string message,std::string &cmd){auto iter = commands.find(message);if(iter ==commands.end()){return false;}cmd = iter->second;}void Run(){#ifdef _LOG_int fd = open(LOG,O_WRONLY|O_CREAT,0644);if(fd<0){return 1;}dup2(fd,2);//int fd = open("/dev/null",O_WRONLY);#endifvolatile bool quit = false;while(!quit){if(this->Record()){std::string message;if(sr.ASR(ASR_PATH,message)){//1.commandstd::string cmd="";if(IsCommand(message,cmd)){std::cout << "[Boyfriend@localhost]$ "<<cmd <<std::endl;Util::Exec(cmd,true);continue;}std::cout<<"我# "<<message <<std::endl;if(message =="你走吧。"){std::string quit_message = "那我就走了,不要太想我哦!";std::cout<<"Boyfriend# " << quit_message<< std::endl;if(sr.TTS(quit_message)){this->Play();}exit(0);}//2.Tuling// std::cout<<"我# "<<message <<std::endl;std::string echo = rt.Talk(message);std::cout<<"Boyfriend# " << echo<< std::endl;if(sr.TTS(echo)){this->Play();}}//      else{//         std::cerr<<"Recognize error..." << std::endl;//      }}else{std::cerr << "Record error..." << std::endl;}// sleep(2);}#ifdef _LOG_close(fd);#endif}~Boyfriend(){}};

● 调用逻辑

#Boyfriend.cc#include "Boyfriend.hpp"using namespace std;int main(){//Robot r;//string str;//volatile bool quit = false;//while(!quit){//  cout << "我# ";//  cin >> str;//  std::string s = r.Talk(str);//  cout << "Tom$ " << s << endl;//    }//  std::string s = r.Talk("你好吗?");//  cout << s << endl;Boyfriend *bf = new Boyfriend();if(!bf->LoadEtc()){return 1;}bf->Run();return 0;}

● command.etc命令配置文件

#command.etc查看当前目录:ls -l关闭防火墙:systemctl stop firewalld打开防火墙:systemctl start firewalld跑火车:sl黑客帝国:cmatrix -B -C blue查看黑名单:cat black_name.txt你给我闺蜜唱首歌:aplay 李森茂_-_生日快乐歌(吉他改编版).wav

● Makefile配置环境变量

#MakefileCC=g++#编译器bin=Boyfriend#生成的可执行文件src=Boyfriend.cc#依赖的源文件INCLUDE=-Ispeech/LIB=-ljsoncpp  -lcurl -lcrypto -lpthread$(bin):$(src)#生成bin,依赖的src$(CC) -o $@ $^ $(INCLUDE) $(LIB)#方法.PHONY:cleanclean:rm -f $(bin)

代码实现

智能语音对话AI

难点

jsoncpp的使用方法讲解

  • 什么是json
  • 有什么特点
  • 为什么要用它
  • StreamWriterBuilder、StreamWriter、CharReaderBuilder、CharReader、write函数、parse函数与Json:Value的使用
//序列化
#include <iostream>
#include <sstream>
#include <memory>
#include <string>
#include <json/json.h>
int main()
{
Json::Value root;
Json::StreamWriterBuilder wb;
std::ostringstream os;
root["Name"] = "zhangsan";
root["Age"] = 26;
root["Lang"] = "c++";
std::unique_ptr<Json::StreamWriter>
jsonWriter(wb.newStreamWriter());
jsonWriter->write(root, &os);
std::string
s = os.str();
std::cout << s << std::endl;
return 0;
}
#打印序列化结果
{"Age" : 26,"Lang" : "c++","Name" : "zhangsan"
}

总结:json还支持嵌套,如json里面包含“json”,甚至json还包含”json数组“等,但是目前jsoncpp我们以简单使用为主。

总结&项目扩展

  • 整体来讲,项目的难度不大,核心点在于对各个工具,平台的熟悉程度
  • 我从这个项目中吸收的东西是: 学会使用第三方平台,第三方工具,就能完成很有意思的功能

扩展:

  • 将该项目移植到windows中, 语音控制windows上各个软件的打开和关闭,岂不酷炫
  • 能否移植到手机端呢?如找一个js页面,在服务器上部署服务,使用手机远程控制服务器(笔记本)
  • 可以在树莓派上,安装一些第三方驱动或者组件(如,灯),语音控制灯的开启和关闭灯,再调研一下百度的其他语音或者文本功能做这类项目,就应该玩起来。

项目:智能语音对话机器人相关推荐

  1. 一个基于nao机器人平台的高校迎新智能语音对话机器人

    一.利用nao录制语音 nao录制音频保存在本地 # -*- coding: UTF-8 -*- #利用的naoqi中的ALProxy包import argparse from naoqi impor ...

  2. Rasa项目实战之银行金融Financial Bot智能业务对话机器人业务功能微服务解析与调试(九十二)

    一.Rasa项目实战之银行金融Financial Bot智能业务对话机器人支付业务流程解析与演示 支付业务是银行金融业务中的核心功能,对于本项目来说,先来看一下这个业务流程是如何工作的.首先运行Ras ...

  3. Gavin老师Transformer直播课感悟 - Rasa项目实战之银行金融Financial Bot智能业务对话机器人业务功能微服务解析与调试(八十九)

    本文继续围绕工业级业务对话平台和框架Rasa,对Rasa项目实战之银行金融Financial Bot智能业务对话机器人的主要业务功能所使用的微服务进行解析,并通过Rasa Interactive的调试 ...

  4. 19小时精通Rasa 3.X 项目实战之教育行业Education Bot智能业务对话机器人

    课程标题:19小时精通Rasa 3.X 项目实战之教育行业EducationBot智能业务对话机器人 课程关键字:Rasa Application.EducationBot.Debugging.San ...

  5. Gavin老师Transformer直播课感悟 - Rasa项目实战之电商零售智能业务对话机器人配置详解与Debugging演示(八十七)

    本文继续围绕工业级业务对话平台和框架Rasa,对Rasa项目实战之电商零售智能业务对话机器人系统所使用的各项配置进行详细剖析,并通过debug模式来理解在下面展示的Rasa graph archite ...

  6. Gavin老师Transformer直播课感悟 - Rasa项目实战之银行金融Financial Bot智能业务对话机器人业务功能微服务解析与调试(八十一)

    本文继续围绕工业级业务对话平台和框架Rasa,对Rasa项目实战之银行金融Financial Bot智能业务对话机器人的主要业务功能所使用的微服务进行解析,并通过Rasa Interactive的调试 ...

  7. Gavin老师Transformer直播课感悟 - Rasa项目实战之银行金融Financial Bot智能业务对话机器人架构与流程及Rasa Interactive实验剖析(八十)

    本文继续围绕工业级业务对话平台和框架Rasa,对Rasa项目实战之银行金融Financial Bot智能业务对话机器人架构.流程进行解析,并通过Rasa Interactive分析配置文件中各个组件的 ...

  8. Gavin老师Transformer直播课感悟 - Rasa项目实战之电商零售智能业务对话机器人业务功能微服务解析与调试演示(八十二)

    本文继续围绕工业级业务对话平台和框架Rasa,对Rasa项目实战之电商零售Customer Service智能业务对话机器人主要业务功能所使用的微服务进行解析,并通过Rasa Interactive的 ...

  9. Gavin老师Transformer直播课感悟 - Rasa项目实战之电商零售智能业务对话机器人业务功能微服务解析与调试演示(八十三)

    本文继续围绕工业级业务对话平台和框架Rasa,对Rasa项目实战之电商零售Customer Service智能业务对话机器人业务功能的微服务如何结合数据库使用进行解析,并通过Rasa Interact ...

  10. Gavin老师Transformer直播课感悟 - Rasa项目实战之电商零售智能业务对话机器人ResponseSelector使用详解与Debugging演示(八十八)

    本文继续围绕工业级业务对话平台和框架Rasa,对Rasa项目实战之电商零售智能业务对话机器人系统如何使用Rasa框架提供的ResponseSelector组件处理常见问题和用户闲聊内容的过程,以及如何 ...

最新文章

  1. Java线程:线程的调度-合并
  2. python 自定义log
  3. NGINX限流的一些思考
  4. Leet Code OJ 1. Two Sum [Difficulty: Easy]
  5. Chrome remote debugging protocol在自动化测试中的应用和实践
  6. #3551. [ONTAK2010]Peaks加强版(kruskal 重构树 + 主席树)
  7. bzoj 2296: 【POJ Challenge】随机种子
  8. 北京玉渊潭开启春节模式 五大版块吸引游客
  9. 一起学设计模式 - 桥接模式
  10. 达观杯文本智能处理(1)
  11. m3u8简单教程之我不是药神下载
  12. 8.计蒜客ACM题库.A2019 Save the Room
  13. 使用mysql打开什么文件格式_dbf是什么文件怎么打开
  14. 国外PHP免费空间速度评测
  15. 《让×××飞》经典影评
  16. 如何在基于vue-cli的项目中,使用精灵图 css sprite
  17. 表格新增的属性及高级表单
  18. 合肥工业大学2020-2021学年《数据挖掘》实验报告(Python实现)
  19. 约瑟夫生者死者小游戏
  20. 深天马A第一季度净利润为2.89亿元 同比减少35.4%

热门文章

  1. 浅谈Unity中的优化
  2. 快速批量改变图片格式
  3. linux 2.6 内核配置说明
  4. 海康威视工业相机SDK的开发使用笔记
  5. MSDTC不可用解决办法
  6. 宝塔/Linux下自动更新maccms到github原版的最新版
  7. 用友NC合同编码自定义
  8. 用友nc java下载_用友nc的java插件下载
  9. 代理工具及使用技巧Proxy Hunter
  10. java中ejb项目_创建EJB项目