AndroidでMicrosoft Translator V2 APIのSpeakメソッドを使う。
夏の計画停電。考えるだけでも恐ろしい。
さて、今回も例によって他人様のコードを借りまくりなのである。
そもそもAndroidでMicrosoft Translator(Bing Translator)を使いたいなんて思う人が居るのかどうか疑問だが、私がそう思ってしまったんだからしょうがない。
Google Text-To-Speechで間に合えば良かったのだが、訳あって日中韓の3ヶ国語を喋らせなくてはならなかったので、Microsoft Translatorの出番となった。
まずは、Bing Translator ツール 翻訳 API - katamari.wankuma.comに書いてある通り、Bing Developer CenterでAppIDを取得する。
あとはMicrosoft Translator for Business - Microsoft Translator for Businessを見て、HTTPインターフェースでSpeakメソッドを呼ぶだけ。
としたいところなのだが、残念ながら返ってくる合成音声データはWAVE形式なので、AndroidのMediaPlayerでは再生できない。そこで、AudioTrackを使ってWAVEデータを再生する - Tech Boosterに書いてあるとおり、AudioTrackを使って再生する。
ちなみにHTTPリクエストについては、Make in HTTP request with android - stackoverflowを参考にした。
で、結果としてできあがったコピペコードがこちら。
private void doTextToSpeech(String text) { String encodeText; String bingKey = [取得したAppId]; try { encodeText = URLEncoder.encode(text, "UTF-8"); String strUrl = "http://api.microsofttranslator.com/v2/Http.svc/Speak?appId=" + bingKey + "&text=" + encodeText + "&language=zh-CHS"; URI uri = new URI(strUrl); HttpClient httpclient = new DefaultHttpClient(); HttpResponse response = httpclient.execute(new HttpGet(uri)); StatusLine statusLine = response.getStatusLine(); if(statusLine.getStatusCode() == HttpStatus.SC_OK){ ByteArrayOutputStream out = new ByteArrayOutputStream(); response.getEntity().writeTo(out); out.close(); byteData = out.toByteArray(); // 必要となるバッファサイズを計算 // なぜかAndroidエミュレータはサンプリングレート8kしか受け付けない。 int bufSize = android.media.AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_8BIT); // AudioTrackインスタンス作成 audioTrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_8BIT, bufSize, AudioTrack.MODE_STREAM); // スレッドインスタンス作成 Thread play_thread = new Thread(this); play_thread.start(); } else{ // コネクションを閉じる。 response.getEntity().getContent().close(); } } catch (Exception e) { e.printStackTrace(); } } // 再生用スレッド処理 public void run() { if (audioTrack != null) { // 再生開始 // ノイズが入らないように127バイト目から再生しているが、何バイト目から再生するのが // 正しいのか分からない。 audioTrack.play(); audioTrack.write(byteData, 126, byteData.length - 126); } }
うん。参考にしたソースより明らかに劣化してる。