Node.js × 音声認識 - 東京Node学園 2012 LT枠 6番目

10,385 views
10,442 views

Published on

2012/11/18 に行われた東京 Node 学園の LT セッション、6 番目の発表です。
デモの解説はこちら:http://d.hatena.ne.jp/hecomi/20121123/1353843800

Published in: Technology
0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
10,385
On SlideShare
0
From Embeds
0
Number of Embeds
5,563
Actions
Shares
0
Downloads
21
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide

Node.js × 音声認識 - 東京Node学園 2012 LT枠 6番目

  1. 1. Node.js で音声認識 X Presented by @hecomi
  2. 2. LTの趣旨: C++ モジュール色々出来て楽しいよ!
  3. 3. 自己紹介•  名前 : hecomi•  Node歴 : 半年とちょっと•  言語 : C++ / JavaScript•  Web : http://d.hatena.ne.jp/hecomi/ 最近は音声認識リモコンとか 未来のお部屋を作る活動をしています
  4. 4. 賢いお部屋 ⑤ピピッ!①エアコン26度! ④26℃の信号出します 音声認識エンジン 集音マイク iRemocon ②26度っすね 音声合成 ③26度にします 今部屋30℃か… ZigBee
  5. 5. 賢いお部屋 ⑤ピピッ!①エアコン26度! ④26℃の信号出します 音声認識エンジン 集音マイク iRemocon ②26度っすね 音声合成 ③26度にします 上で動かそうとしています今部屋30℃か… Node.js ZigBee
  6. 6. 賢いお部屋 ⑤ピピッ! Node.js 上で動かそうとしています①エアコン26度! ④26℃の信号出します 音声認識エンジン 集音マイク iRemocon ②26度っすね この部分について紹介します 音声合成 ③26度にします 上で動かそうとしています今部屋30℃か… Node.js ZigBee
  7. 7. •  オープンソースの音声認識エンジン –  http://julius.sourceforge.jp/•  いろんな機能があります –  認識方法 •  ディクテーション(文章自動筆記、誤認識多) •  ★文法認識   (特定の文章、 誤認識少) –  実行方法 •  ★ローカル   (普通に実行) •  サーバモード (認識結果を XML でくれます)
  8. 8. C++/Juliusの設定ファイルを
 普通に書いていると……(前略)Jconf *jconf = j_config_load_args_new(j_argc, const_cast<char**>(j_argv));if (jconf == nullptr) { std::cout << "Error @ j_config_load_args_new" << std::endl; return -1;}Recog *recog = j_create_instance_from_jconf(jconf);if (recog == nullptr) { std::cout << "Error @ j_create_instance_from_jconf" << std::endl; return -1;}callback_add(recog, CALLBACK_EVENT_SPEECH_READY, [](Recog *recog, void*) { std::cout << "<<< PLEASE SPEAK! >>>" << std::endl;}, nullptr);callback_add(recog, CALLBACK_EVENT_SPEECH_START, [](Recog *recog, void*) { std::cout << "...SPEECH START..." << std::endl;}, nullptr);callback_add(recog, CALLBACK_RESULT, OnOutputResult, nullptr);…(後略)
  9. 9. C++/Juliusの設定ファイルを
 普通に書いていると……(前略)Jconf *jconf = j_config_load_args_new(j_argc, const_cast<char**>(j_argv));if (jconf == nullptr) { std::cout << "Error @ j_config_load_args_new" << std::endl; return -1;}Recog *recog = j_create_instance_from_jconf(jconf);if (recog == nullptr) { std::cout << "Error @ j_create_instance_from_jconf" << std::endl; return -1;}callback_add(recog, CALLBACK_EVENT_SPEECH_READY, [](Recog *recog, void*) { std::cout << "<<< PLEASE SPEAK! >>>" << std::endl;}, nullptr);callback_add(recog, CALLBACK_EVENT_SPEECH_START, [](Recog *recog, void*) { S : NS_B KADEN_ NOISE PLEASE NS_E std::cout << "...SPEECH START..." NS_B JUMON NS_E S : << std::endl;}, nullptr); KADEN_ : KADEN KADEN_ : KADEN WO% KADENcallback_add(recog, CALLBACK_RESULT, OnOutputResult, nullptr);…(後略)
  10. 10. C++/Juliusの設定ファイルを
 普通に書いていると… …(前略) Jconf *jconf = j_config_load_args_new(j_argc, const_cast<char**>(j_argv));% KADENテレビ t eif (jconf == nullptr) { r e b i電気 d e n k i% WO std::cout << "Error @ j_config_load_args_new" << std::endl;を w o return -1;を o }% PLEASEつけて t uRecog t*recog = j_create_instance_from_jconf(jconf); k e e消して k eif (recog == nullptr) { s i t e切替 k i r i k a e std::cout << "Error @ j_create_instance_from_jconf" << std::endl;次 t u g i return -1;前 m a e }% JUMONバルス b a r u s u callback_add(recog, CALLBACK_EVENT_SPEECH_READY, [](Recog *recog, void*) {% NOISE<sp> sp std::cout << "<<< PLEASE SPEAK! >>>" << std::endl;% NS_B }, nullptr);<s> silB% NS_E callback_add(recog, CALLBACK_EVENT_SPEECH_START, [](Recog *recog, void*) {<s> silE S : NS_B KADEN_ NOISE PLEASE NS_E std::cout << "...SPEECH START..." NS_B JUMON NS_E S : << std::endl; }, nullptr); KADEN_ : KADEN KADEN_ : KADEN WO% KADEN callback_add(recog, CALLBACK_RESULT, OnOutputResult, nullptr); …(後略)
  11. 11. C++/Juliusの設定ファイルを
 普通に書いていると… …(前略) Jconf *jconf = j_config_load_args_new(j_argc, const_cast<char**>(j_argv));% KADENテレビ t eif (jconf == nullptr) { r e b i電気 d e n k i% WO std::cout << "Error @ j_config_load_args_new" << std::endl;を w o return -1;を o } <?xml version="1.0" encoding="UTF-8"?>% PLEASE <iRemocon>つけて k e e <command word="テレビ(を|)(つけて|消して)" num="1" /> t uRecog t*recog = j_create_instance_from_jconf(jconf);消して k eif (recog == nullptr) { s i t e <command word="テレビ(を|)切替" num="2" />切替 k i r i k a e <command word="テレビ(を|)次" num="3" /> std::cout << "Error @ j_create_instance_from_jconf" << std::endl; <command word="テレビ(を|)前" num="4" />次 t u g i return -1; <command word="電気(を|)つけて" num="11" />前 m a e } <command word="電気(を|)消して" num="12" />% JUMONバルス b a r u s u </iRemocon> callback_add(recog, CALLBACK_EVENT_SPEECH_READY, [](Recog *recog, void*) {% NOISE<sp> sp std::cout << "<<< PLEASE SPEAK! >>>" << std::endl;% NS_B }, nullptr);<s> silB% NS_E callback_add(recog, CALLBACK_EVENT_SPEECH_START, [](Recog *recog, void*) {<s> silE S : NS_B KADEN_ NOISE PLEASE NS_E std::cout << "...SPEECH START..." NS_B JUMON NS_E S : << std::endl; }, nullptr); KADEN_ : KADEN KADEN_ : KADEN WO% KADEN callback_add(recog, CALLBACK_RESULT, OnOutputResult, nullptr); …(後略)
  12. 12. C++/Juliusの設定ファイルを
 普通に書いていると… …(前略) Jconf *jconf = j_config_load_args_new(j_argc, const_cast<char**>(j_argv));% KADENテレビ t eif (jconf == nullptr) { r e b i電気 d e n k i% WO std::cout << "Error @ j_config_load_args_new" << std::endl;をを o } _人人人人人人人人人人_ w o return -1; <?xml version="1.0" encoding="UTF-8"?> <iRemocon>% PLEASEつけて消して k e >               < e    _,,..,,,,_ k eif (recog == nullptr) { s i t e <command word="テレビ(を|)(つけて|消して)" num="1" /> t uRecog t*recog = j_create_instance_from_jconf(jconf); <command word="テレビ(を|)切替" num="2" /> <command word="テレビ(を|)次" num="3" />切替次前 t u g i m a e >               < k i r i k a e /  ,  3   `ヽーっ std::cout << "Error @ j_create_instance_from_jconf" << std::endl; return -1; <command word="テレビ(を|)前" num="4" /> <command word="電気(を|)つけて" num="11" /> l    ⊃ ⌒_つ >               < } <command word="電気(を|)消して" num="12" />% JUMONバルス b a r u s u </iRemocon> callback_add(recog, CALLBACK_EVENT_SPEECH_READY, [](Recog *recog, void*) {% NOISE<sp>% NS_B sp >               <  `ー---­‐" std::cout << "<<< PLEASE SPEAK! >>>" << std::endl; }, nullptr);<s>% NS_E<s> silB >               < 面倒くさい! callback_add(recog, CALLBACK_EVENT_SPEECH_START, [](Recog *recog, void*) { silE S : NS_B KADEN_ NOISE PLEASE NS_E  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y ̄ std::cout << "...SPEECH START..." NS_B JUMON NS_E S : << std::endl; }, nullptr); KADEN_ : KADEN KADEN_ : KADEN WO% KADEN callback_add(recog, CALLBACK_RESULT, OnOutputResult, nullptr); …(後略)
  13. 13. もっと簡単にできるようにしたい!
  14. 14. どうせなら色んな機能と連携したい…
  15. 15. そうだ! Node.js のC++ モジュール化しよう!
  16. 16. C++ モジュール作ったことある方?
  17. 17. C++ モジュール 難しくないです!•  C++ ですが v8 / node.js のお作法に従うだけです•  例: hello() すると world が返ってくる関数 #include <node.h> JavaScript に引き渡す関数 using namespace v8; Handle<Value> Method(const Arguments& args) { HandleScope scope; return scope.Close( String::New("world") ); } void init(Handle<Object> target) { NODE_SET_METHOD (target, "hello", Method); Node.js の世界へ C++ の } 関数を送り出す NODE_MODULE(hello, init)
  18. 18. C++ モジュール 難しくないです!•  C++ ですが v8 / node.js のお作法に従うだけです•  例: hello() すると world が返ってくる関数 #include <node.h> JavaScript に引き渡す関数 using namespace v8; Handle<Value> Method(const Arguments& args) { HandleScope scope; return scope.Close( String::New("world") ); } void init(Handle<Object> target) { NODE_SET_METHOD (target, "hello", Method); Node.js の世界へ C++ の } 関数を送り出す NODE_MODULE(hello, init)
  19. 19. C++ モジュール作り方 この辺りが今回のミソ•  公式サイト … 大体ひと通り書いてある –  Node.js v0.8.14 マニュアル & ドキュメンテーション •  http://nodejs.jp/nodejs.org_ja/docs/v0.8/api/addons.html•  V8 について … v8 の世界について詳しく知りたい時 –  Embedders Guide - V8 JavaScript Engine •  http://javascript.g.hatena.ne.jp/edvakf/20100407/1270626241•  EventEmitter 利用方法 … libuv 用お作法 –  Node.js で C++ アドオンから EventEmitter のイベントリスナ を呼ぶ - 凹みTips •  http://d.hatena.ne.jp/hecomi/20121020/1350764244•  マルチスレッド対応方法 … libuv の uv_queue_work を利用 –  Node.js でマルチスレッド対応のネイティブモジュールを作成 する- 凹みTips •  http://d.hatena.ne.jp/hecomi/20121021/1350819390
  20. 20. 出来たモジュールを使ったコード1var Julius  = require(julius) , grammar = new Julius.Grammar() ;   認識したい言葉を覚えさせるgrammar.add((テレビ|エアコン)を?(つけて|消して));grammar.add(‘お早う御座います);grammar.compile(function(err, result) { if (err) throw err; var julius = new Julius( grammar.getJconf() ); julius.on(result, function(str) { console.log(認識結果:, str); }); コールバックの登録 julius.start(); 他にも発話のタイミング等}); 各種コールバック登録可
  21. 21. デモ(別途エントリ書きます)
  22. 22. まとめC++ モジュール 楽しいです!
  23. 23. ご清聴ありがとうございました

×