現在設定できているものは、
・「おはよう」、「こんにちは」などの挨拶に対して、挨拶しかえす。
・「ばか」などの悪口に対して、ランダムな表現で非難する。繰り返し悪口を言われるとすねる。調子に乗っていたのが戻る。
・「すごい」などの褒め言葉に対してランダムな表現で喜ぶ。すねていたのが戻る。繰り返し褒められると調子に乗る。
・「私の名前は○○です」と自己紹介すると名前を記憶する。以前記憶した相手には、「また会いましたね」と返答する。
です。
音声認識には Intel Perceptual Computing SDKを使って挑戦していますが、上手くいっていません。
音声合成は、こちらの掲示板のおかげで、上手くいっています。
プログラミング自体初心者なので、プログラムの改善点も含め、いろいろなアドバイスをいただければ
嬉しいです。よろしくお願いします。
最終目標は「学習」できるようになることですが、まだ学習の定義もわかりませんし、
とりあえずは、できるだけ自然な会話を目指します。
以下コードです。
// aitanaka.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <Windows.h>
#include <stdio.h>
#include <time.h>
#include "util_pipeline.h"
#include "voice_out.h"
#pragma comment( lib, "winmm.lib" )
using namespace std;
class Pipeline: public UtilPipeline {
public:
// 1.コンストラクタ
Pipeline(void)
: UtilPipeline()
{
// 必要なデータを有効にする
EnableVoiceRecognition();
}
// 2.音声エンジンのセットアップを行う
virtual void OnVoiceRecognitionSetup(PXCVoiceRecognition::ProfileInfo * finfo)
{
// 日本語の音声エンジンを探す
auto voiceRecognition = QueryVoiceRecognition();
for ( int i = 0; ; ++i ) {
PXCVoiceRecognition::ProfileInfo pinfo = { 0 };
auto ret = voiceRecognition->QueryProfile( i, &pinfo );
if ( ret != PXC_STATUS_NO_ERROR ) {
break;
}
if ( pinfo.language == PXCVoiceRecognition::ProfileInfo::LANGUAGE_JP_JAPANESE ) {
*finfo = pinfo;
std::cout << "日本語の音声エンジンを設定しました" << std::endl;
}
}
std::cout << "音声認識を開始します" << std::endl;
}
// 3.音声認識されたテキストを取得する
virtual void PXCAPI OnRecognized( PXCVoiceRecognition::Recognition *cmd ) {
std::wcout << L"認識した文: " << cmd->dictation << std::endl;
}
};
void widen(const std::string &src, std::wstring &dest) {
size_t returnvalue;
wchar_t *wcs = new wchar_t[src.length() + 1];
mbstowcs_s(&returnvalue,wcs,src.length() + 1, src.c_str(), src.length() + 1);
dest = wcs;
delete [] wcs;
}
void voicesyn(wstring message){
// 2.wide-charactorを扱えるようにする
std::locale::global(std::locale("japanese"));
// 3. UtilPipelineクラスをそのまま利用する
UtilPipeline pipeline;
pipeline.Init();
// 4. 音声合成の機能を利用可能にする
PXCVoiceSynthesis* synthesis = nullptr;
pipeline.QuerySession()->CreateImpl<PXCVoiceSynthesis>( &synthesis );
// 5. 音声エンジンを設定する
PXCVoiceSynthesis::ProfileInfo pinfo = { 0 };
for ( int i = 0; ; ++i ) {
auto ret = synthesis->QueryProfile( i, &pinfo );
if ( ret != PXC_STATUS_NO_ERROR ) {
break;
}
if ( pinfo.language == PXCVoiceRecognition::ProfileInfo::LANGUAGE_JP_JAPANESE ) {
synthesis->SetProfile( &pinfo );
break;
}
}
// 6.テキストを音声化し、スピーカーから出力する
VoiceOut voice( &pinfo );
// 音声合成のキューに入れる
pxcUID id=0;
synthesis->QueueSentence( (wchar_t*)message.c_str(), message.size(), &id );
for (;;) {
PXCSmartSP sp;
PXCAudio *sample;
// 音声合成を行う
auto ret = synthesis->ProcessAudioAsync(id, &sample, &sp);
if ( ret<PXC_STATUS_NO_ERROR ) {
break;
}
ret = sp->Synchronize();
if ( ret<PXC_STATUS_NO_ERROR ) {
break;
}
// 音声データをスピーカーに出力する
voice.RenderAudio(sample);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
string line,str;
wstring message,name2,str2;
int a,nameNo,lineNo,random,ang,prs;
setlocale(LC_CTYPE, "JPN");
ang=0;prs=0;
//try {
// // 4.wide-charactorを表示できるようにする
// std::locale::global(std::locale("japanese"));
// Pipeline pipeline;
// pipeline.LoopFrames();
// }
// catch ( std::exception& ex ) {
// std::cout << ex.what() << std::endl;
// }
cout<<"田中:会話しましょう"<<endl;
message=L"会話しましょう";
voicesyn(message);
cout<<"あなた:";
while(cin){
a=0;
cin>>line;
ifstream fs1("greeting.txt");//ファイル読み込みチェック
ifstream fs2("abuse.txt");
ifstream fs4("name.txt");
ifstream fs5("random.txt");
ifstream fs6("abuse_re.txt");
ifstream fs7("praise.txt");
ifstream fs8("praise_re.txt");
if (fs1.fail())
{
cerr << "失敗" << endl;
return -1;
}
if (fs2.fail())
{
cerr << "失敗" << endl;
return -1;
}
if (fs4.fail())
{
cerr << "失敗" << endl;
return -1;
}
if (fs5.fail())
{
cerr << "失敗" << endl;
return -1;
}
if (fs6.fail())
{
cerr << "失敗" << endl;
return -1;
}
if (fs7.fail())
{
cerr << "失敗" << endl;
return -1;
}
if (fs8.fail())
{
cerr << "失敗" << endl;
return -1;
}
while(getline(fs1,str)){
if((line.find(str)!=-1)&&(a==0)){
cout<<"田中:"<<str<<endl;
widen(str,str2);
message=str2;
voicesyn(message);
a++;
}
}
while((getline(fs2,str))&&(a==0)){
if((line.find(str)!=-1)&&(a==0)){//悪口を見つけた
lineNo=0;ang++;prs--;
if(ang>3){//激怒した
cout<<"田中:もう許しません"<<endl;
message=L"もう許しません";
voicesyn(message);
a++;
}else{//まだそんなに怒っていない
srand((unsigned int)time(NULL));
random=rand()%5+1;
while(getline(fs6,str)){
lineNo++;
if(lineNo==random){//ランダムに返答
cout<<"田中:"<<str<<endl;
widen(str,str2);
message=str2;
voicesyn(message);
}
}
}
a++;
}
}
while((getline(fs7,str))&&(a==0)){
if((line.find(str)!=-1)&&(a==0)){//褒め言葉を見つけた
lineNo=0;prs++;ang--;
if(prs>3){
cout<<"田中:そんなに褒めたら調子に乗りますよ"<<endl;
message=L"そんなに褒めたら調子に乗りますよ";
voicesyn(message);
a++;
}else{
srand((unsigned int)time(NULL));
random=rand()%5+1;
while(getline(fs8,str)){
lineNo++;
if(lineNo==random){
cout<<"田中:"<<str<<endl;
widen(str,str2);
message=str2;
voicesyn(message);
}
}
}
a++;
}
}
if((line.find("私の名前")!=-1)&&(a==0)){
nameNo=line.find("です")-line.find("名前は")-6;
string name(line,10,nameNo);
widen(name,name2);
ifstream fs4("name.txt");
while(getline(fs4,str)){
if(name.find(str)!=-1){
cout<<"田中:また会いましたね、"<<name<<"さん"<<endl;
message=L"また会いましたね";
voicesyn(message);
voicesyn(name2);
message=L"さん";
voicesyn(message);
a=1;
}
}
if(a==0){
ofstream fs3("name.txt",ios::app);
fs3<<name<<endl;
cout<<"田中:こんにちは、"<<name<<"さん"<<endl;
message=L"こんにちは";
voicesyn(message);
voicesyn(name2);
message=L"さん";
voicesyn(message);
}
a++;
}
if(a==0){
lineNo=0;
srand((unsigned int)time(NULL));
random=rand()%5+1;
while(getline(fs5,str)){
lineNo++;
if(lineNo==random){
cout<<"田中:"<<str<<endl;
widen(str,str2);
message=str2;
voicesyn(message);
}
}
}
cout<<"あなた:";
}
return 0;
}