2010年11月2日火曜日

SL4AのPythonを使ってAndroid端末に日本語を喋らせてみた

このブログ記事をはてなブックマークに追加

先日、ドコモのGALAXY Sを購入した。丁度1年前に購入したHT-03Aからの機種変更になる。Androidのバージョンは1.6から2.2となり、性能は格段に良くなった。この1年での技術の進歩には驚かされる。GALAXY SでSL4Aが利用できるかは気になるところだが、実は購入する前に既に動作することを確認していたので、その点については心配なかった。もしSL4Aが使えなかったら、多分購入しなかったと思う。

この新しいAndroid機を使って、SL4AのPythonで日本語を喋らせてみることにした。英語であればttsSpeakのAPIを使えば一発なのだが漢字かな混じりの日本語では簡単には行かない。まずは日本語の発音を取得しなくてはならないが、それについてはYahoo! デベロッパーネットワーク日本語形態素解析を使うことにした。これなら助詞の「は」も「わ」という発音であることがわかるし、後々、応用が効くだろう。

作成したソースコードは最後に示してあるが、短いコードで簡単に実装できた。使い方も簡単で、入力ダイアログから喋らせたい文章を入力するだけだ。それを形態素解析のWeb APIでXMLとして取得し、Beautiful Soupで解析している。取得した平仮名をその発音に近い英語に直すだけだ。ローマ字に置き換えるだけでは日本語として正しく発音されないので、適当にいじってある。

実用的なプログラムにしたければ、Galatea Projectなどを利用して、ちゃんとした日本語を喋らせるようにしたほうが良いのだろうけど、形態素解析を使ってみたかったし、英語を無理やり日本語にするところも面白かったので、今回はこれで良しとした。やっぱり自分が楽しめないとね。

例によって、このプログラムを使って子供相手に遊んでみた。元の文章を知っていれば問題なく聞き取れるのだが、知らないと思ったよりも聞き取れないことを逆手に取って、何を喋っているかを当てるゲームをしてみた。こんな単純なことなのだが、子供たちは思いのほか楽しんでいたようだ。インチキ外国人ぽい雰囲気が面白いらしい。

作成したソースコードは以下の通り。

speak_ja.py

# -*- coding: utf-8 -*- import android import sys,os,urllib,urllib2 from BeautifulSoup import BeautifulSoup YAHOO_APP_ID='Yahoo!デベロッパーネットワークのアプリケーションID' KEITAISO_API='http://jlp.yahooapis.jp/MAService/V1/parse?appid=%s&results=ma&sentence=%s' KANA=[u'きゃ',u'きぃ',u'きゅ',u'きぇ',u'きょ', u'くぁ',u'くぃ',u'くぅ',u'くぇ',u'くぉ', u'ぎゃ',u'ぎぃ',u'ぎゅ',u'ぎぇ',u'ぎょ', u'ぐぁ',u'ぐぃ',u'ぐぅ',u'ぐぇ',u'ぐぉ', u'しゃ',u'しぃ',u'しゅ',u'しぇ',u'しょ', u'すぁ',u'すぃ',u'すぅ',u'すぇ',u'すぉ', u'じゃ',u'じぃ',u'じゅ',u'じぇ',u'じょ', u'ちゃ',u'ちぃ',u'ちゅ',u'ちぇ',u'ちょ', u'てゃ',u'てぃ',u'てゅ',u'てぇ',u'てょ', u'とぁ',u'とぃ',u'とぅ',u'とぇ',u'とぉ', u'ぢゃ',u'ぢぃ',u'ぢゅ',u'ぢぇ',u'ぢょ', u'でゃ',u'でぃ',u'でゅ',u'でぇ',u'でょ', u'どぁ',u'どぃ',u'どぅ',u'どぇ',u'どぉ', u'にゃ',u'にぃ',u'にゅ',u'にぇ',u'にょ', u'ひゃ',u'ひぃ',u'ひゅ',u'ひぇ',u'ひょ', u'ふぁ',u'ふぃ',u'ふぅ',u'ふぇ',u'ふぉ', u'びゃ',u'びぃ',u'びゅ',u'びぇ',u'びょ', u'ぴゃ',u'ぴぃ',u'ぴゅ',u'ぴぇ',u'ぴょ', u'みゃ',u'みぃ',u'みゅ',u'みぇ',u'みょ', u'りゃ',u'りぃ',u'りゅ',u'りぇ',u'りょ', u'うぁ',u'うぃ',u'うぇ',u'うぉ'] PRON=['kya','kyi','kyu','kyei','kio', 'qa','qi','qwu','qei','qo', 'gya','gyi','gyu','gyei','gyo', 'gwa','gwi','gwu','gwei','gwo', 'sha','syi','shu','shei','sho', 'swa','swi','swu','swei','swo', 'ja','zee','juu','jei','jo', 'cha','tyi','chu','chei','cho', 'tha','thi','thu','thei','tho', 'twa','twi','two','twei','two', 'dya','dyi','dyu','dyei','dyo', 'dha','dhi','dhu','dhei','dho', 'dwa','dwi','dwu','dwei','dwo', 'nya','nyi','nyu','nyei','nyo', 'hya','hyi','hyu','hyei','hyo', 'fa','fi','foo','fei','fo', 'bya','byi','byu','byei','byo', 'pya','pyi','pyu','pyei','pyo', 'mya','myi','myu','myei','myo', 'rya','ryi','ryu','ryei','ryo', 'wha','wi','wei','wo'] KANA+=u'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわゐゑをんがぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽぁぃぅぇぉ' PRON+=['a','ee','oo','ae','o', 'ka','kee','koo','kei','ko', 'sa','she','soo','sei','so', 'ta','chee','tsu','tei','toe', 'na','nee','nuu','neigh','no', 'ha','hee','foo','hey','ho', 'ma','mee','moo','mei','mo', 'yah','you','yor', 'ra','ree','roo','rei','ro', 'wa','ee','ae','wo','nn', 'ga','gee','goo','gei','go', 'za','zee','zoo','zei','zo', 'da','zee','doo','dei','do', 'ba','bee','boo','bei','bo', 'pa','pee','poo','pei','po', 'a','ee','oo','ae','o'] def get_keitaiso(text): xml=urllib2.urlopen(KEITAISO_API % (YAHOO_APP_ID,urllib.quote(text.encode('utf-8')))).read() ret='' for data in BeautifulSoup(xml)('ma_result'): for r,p in zip(data('reading'),data('pos')): d,x=r.renderContents(),p.renderContents() if x=='助詞' and d=='は': ret+='わ' elif x!='特殊': ret+=d ret=ret.decode('utf-8') T={} for i in range(86): T[ord(u'ァ')+i]=unichr(ord(u'ぁ')+i) ret=ret.translate(T) for k,r in zip(KANA,PRON): ret=ret.replace(k,r+' ') rett=ret; for i,c in enumerate(ret): c=c.encode('utf-8') if c=='ー': ret=ret.replace(u'ー',rett[i-2]+' ',1) if c=='っ': if len(rett)>i+1: ret=ret.replace(u'っ',rett[i+1],1) else: ret=ret.replace(u'っ','',1) return ret droid=android.Android() text=droid.dialogGetInput(u'日本語を喋ります',u'何を喋らせますか?').result.strip() droid.ttsSpeak(get_keitaiso(text)) droid.makeToast(text)

インチキ外国人なら喋る内容もインチキっぽくしようと思い付いたので、入力した文章をGoogleの翻訳APIで英訳し、それをまた和訳するという処理を挟んでみた。例えば「一番いいのを頼む。」と入力したら「最高のお問い合わせください。」と喋る。まあ、これはジョークプログラムにしかならないけど、形態素解析を利用した人工無脳に仕立て上げたりするのも楽しいかもしれない。

上記のspeak_ja.pyに以下の赤で示したコードを追加すればいい。

fake_japanese.py

# -*- coding: utf-8 -*- import android import sys,os,urllib,urllib2,simplejson from BeautifulSoup import BeautifulSoup ### 途中省略 def translator(text,from_lang,to_lang): url='http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=%s&langpair=%s%%7C%s' % (urllib.quote(text.encode('utf-8')),from_lang,to_lang) data=simplejson.loads(urllib2.urlopen(url).read()) return data['responseData']['translatedText'] droid=android.Android() text=droid.dialogGetInput(u'日本語を喋ります',u'何を喋らせますか?').result.strip() text=translator(translator(text,'ja','en'),'en','ja') droid.ttsSpeak(get_keitaiso(text)) droid.makeToast(text)

2 コメント:

匿名 さんのコメント...

今なら日本語しゃべらせるAPI使えますよ。
http://ma6works.mashupaward.jp/category/39244/

nox さんのコメント...

情報ありがとうございます。
NetVOCALOIDで喋らせることができるのですね。

他にもGalatea Talkを利用したAndroid JaTTSのようなライブラリもあるのですが、今回は既存のttsSpeakを使ったお遊びということでご了承ください。
http://gimite.net/pukiwiki/index.php?Android%20JaTTS