Node.js × 音声認識 - 東京Node学園 2012 LT枠 6番目
-
Upload
hecomi -
Category
Technology
-
view
8.594 -
download
7
description
Transcript of Node.js × 音声認識 - 東京Node学園 2012 LT枠 6番目
Node.js で音声認識
Presented by@hecomi
X
LTの趣旨:C++ モジュール
色々出来て楽しいよ!
自己紹介
• 名前 : hecomi
• Node歴 : 半年とちょっと
• 言語 : C++ / JavaScript
• Web : http://d.hatena.ne.jp/hecomi/
最近は音声認識リモコンとか
未来のお部屋を作る活動をしています
賢いお部屋
集音マイクiRemocon
音声認識エンジン
ZigBee
音声合成
①エアコン26度!
③26度にします 今部屋30℃か…
⑤ピピッ!
④26℃の信号出します
②26度っすね
賢いお部屋
集音マイクiRemocon
音声認識エンジン
ZigBee
音声合成
①エアコン26度!
③26度にします 今部屋30℃か…
⑤ピピッ!
④26℃の信号出します
②26度っすね
Node.js 上で動かそうとしています
Node.js 上で動かそうとしています
賢いお部屋
集音マイクiRemocon
ZigBee
音声合成
①エアコン26度!
③26度にします 今部屋30℃か…
⑤ピピッ!
④26℃の信号出します
音声認識エンジン
②26度っすね
この部分について紹介します
Node.js 上で動かそうとしています
• オープンソースの音声認識エンジン– http://julius.sourceforge.jp/
• いろんな機能があります– 認識方法
• ディクテーション(文章自動筆記、誤認識多)
• ★文法認識 (特定の文章、 誤認識少)
– 実行方法• ★ローカル (普通に実行)
• サーバモード (認識結果を XML でくれます)
…(前略)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);…(後略)
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);…(後略)
C++/Juliusの設定ファイルを普通に書いていると…
S : NS_B KADEN_ NOISE PLEASE NS_ES : NS_B JUMON NS_EKADEN_ : KADENKADEN_ : KADEN WO% KADEN
…(前略)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);…(後略)
C++/Juliusの設定ファイルを普通に書いていると…
% KADENテレビ t e r e b i電気 d e n k i% WOを w oを o% PLEASEつけて t u k e t e消して k e s i t e切替 k i r i k a e次 t u g i前 m a e% JUMONバルス b a r u s u% NOISE<sp> sp% NS_B<s> silB% NS_E<s> silE S : NS_B KADEN_ NOISE PLEASE NS_E
S : NS_B JUMON NS_EKADEN_ : KADENKADEN_ : KADEN WO% KADEN
…(前略)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);…(後略)
C++/Juliusの設定ファイルを普通に書いていると…
% KADENテレビ t e r e b i電気 d e n k i% WOを w oを o% PLEASEつけて t u k e t e消して k e s i t e切替 k i r i k a e次 t u g i前 m a e% JUMONバルス b a r u s u% NOISE<sp> sp% NS_B<s> silB% NS_E<s> silE S : NS_B KADEN_ NOISE PLEASE NS_E
S : NS_B JUMON NS_EKADEN_ : KADENKADEN_ : KADEN WO% KADEN
<?xml version="1.0" encoding="UTF-8"?><iRemocon> <command word="テレビ(を|)(つけて|消して)" num="1" /> <command word="テレビ(を|)切替" num="2" /> <command word="テレビ(を|)次" num="3" /> <command word="テレビ(を|)前" num="4" /> <command word="電気(を|)つけて" num="11" /> <command word="電気(を|)消して" num="12" /></iRemocon>�
…(前略)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);…(後略)
C++/Juliusの設定ファイルを普通に書いていると…
% KADENテレビ t e r e b i電気 d e n k i% WOを w oを o% PLEASEつけて t u k e t e消して k e s i t e切替 k i r i k a e次 t u g i前 m a e% JUMONバルス b a r u s u% NOISE<sp> sp% NS_B<s> silB% NS_E<s> silE S : NS_B KADEN_ NOISE PLEASE NS_E
S : NS_B JUMON NS_EKADEN_ : KADENKADEN_ : KADEN WO% KADEN
<?xml version="1.0" encoding="UTF-8"?><iRemocon> <command word="テレビ(を|)(つけて|消して)" num="1" /> <command word="テレビ(を|)切替" num="2" /> <command word="テレビ(を|)次" num="3" /> <command word="テレビ(を|)前" num="4" /> <command word="電気(を|)つけて" num="11" /> <command word="電気(を|)消して" num="12" /></iRemocon>�
_人人人人人人人人人人_> <> <> <> <> < ̄Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
_,,..,,,,_/ ,' 3 `ヽーっl ⊃ ⌒_つ `'ー---‐'''''"面倒くさい!
もっと簡単にできるようにしたい!
どうせなら色んな機能と連携したい…
そうだ! Node.js のC++ モジュール化しよう!
C++ モジュール作ったことある方?
C++ モジュール 難しくないです!
• C++ ですが v8 / node.js のお作法に従うだけです• 例: hello() すると 'world' が返ってくる関数
#include <node.h> 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_MODULE(hello, init)
JavaScript に引き渡す関数
Node.js の世界へ C++ の
関数を送り出す
C++ モジュール 難しくないです!
• C++ ですが v8 / node.js のお作法に従うだけです• 例: hello() すると 'world' が返ってくる関数
#include <node.h> 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_MODULE(hello, init)
JavaScript に引き渡す関数
Node.js の世界へ C++ の
関数を送り出す
C++ モジュール作り方
• 公式サイト … 大体ひと通り書いてある– Node.js v0.8.14 マニュアル & ドキュメンテーション
• http://nodejs.jp/nodejs.org_ja/docs/v0.8/api/addons.html
• V8 について … v8 の世界について詳しく知りたい時– Embedder's 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
この辺りが今回のミソ
出来たモジュールを使ったコード1
var 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();});
認識したい言葉を覚えさせる
コールバックの登録
他にも発話のタイミング等
各種コールバック登録可
デモ(別途エントリ書きます)
まとめ
C++ モジュール楽しいです!
ご清聴ありがとうございました