Home > action script > Flashでテキストtoスピーチ

Flashでテキストtoスピーチ

speechSystem.jpg

TFM - HondaSweetMission」のコメントを音声出力してくれるシステムに感動して、2ヶ月ほど前に作ったFlashでText to Speechするサンプル。 10分ぐらいで作った程度のサンプルです。

あまりにもショボくて、封印していたのだけれど、最近、尊敬するロリポの社長さんの「教えてメカロリポおじさん」を見て、多少公開する勇気をもらったので(といってもメカロリポおじさんのように裏でナウい処理をしているわけではないのだけれど)、ソースごと公開します。

再生ボタンを押すとテキストを読み上げます。テキストを自由にタイプし直して、その通りに喋らせることができますが、ひらがなと句読点以外は読めず、すっとばします。(要FlashPlayer7以上)

speechSystem.swf

ソースも一応載せておきますが、適当に書き始めて整頓する前に飽きてしまったので汚いです。すいません。

var text_Arr:Array = new Array();
var str:String = textBox.text;
btn.onRelease = function() { text_Arr = new Array(); str = enterText.text; setArray(); setSound(); playSound(0); }; function setArray() { for (var i = 0; i<str.length; i++) { text_Arr.push({sound:str.substr(i, 1), mouth:0}); text_Arr[i].sound = changeKanaToRome(text_Arr[i].sound); if (text_Arr[i].sound == "bar") { var lastBoin = text_Arr[i-1].sound.substr(-1, 1); text_Arr[i].sound=lastBoin; } text_Arr[i].mouth = animateMouth(text_Arr[i].sound); } } function setSound() { for (var i = 0; i<text_Arr.length; i++) { this["s_"+i] = new Sound(); var sound = this["s_"+i]; sound.attachSound("s_"+text_Arr[i].sound); } } //サウンドオブジェクトを0から順に再帰的に再生していく関数 function playSound(num:Number) { if (num<text_Arr.length) { this["s_"+num].start(); chara.head.mouth.gotoAndStop(text_Arr[num].mouth); this["s_"+num].onSoundComplete = function() { playSound(num+1); }; } else { chara.head.mouth.gotoAndStop(1); } } function animateMouth(soundChara:String) { var lastChar = soundChara.substr(-1, 1); if (lastChar == "a") { return 2; } else if (lastChar == "i") { return 3; } else if (lastChar == "u") { return 4; } else if (lastChar == "e") { return 5; } else if (lastChar == "o") { return 6; } else { return 1; } } //text_Arrのひらがなをローマ字に変換する関数 function changeKanaToRome(kana:String) { var tmp:String = kana; if (tmp == "あ") { tmp = "a"; return tmp; } else if (tmp == "い") { tmp = "i"; return tmp; } else if (tmp == "う") { tmp = "u"; return tmp; } else if (tmp == "え") { tmp = "e"; return tmp; } else if (tmp == "お") { tmp = "o"; return tmp; } else if (tmp == "か") { tmp = "ka"; return tmp; } else if (tmp == "き") { tmp = "ki"; return tmp; } else if (tmp == "く") { tmp = "ku"; return tmp; } else if (tmp == "け") { tmp = "ke"; return tmp; } else if (tmp == "こ") { tmp = "ko"; return tmp; } else if (tmp == "さ") { tmp = "sa"; return tmp; } else if (tmp == "し") { tmp = "si"; return tmp; } else if (tmp == "す") { tmp = "su"; return tmp; } else if (tmp == "せ") { tmp = "se"; return tmp; } else if (tmp == "そ") { tmp = "so"; return tmp; } else if (tmp == "た") { tmp = "ta"; return tmp; } else if (tmp == "ち") { tmp = "ti"; return tmp; } else if (tmp == "つ") { tmp = "tu"; return tmp; } else if (tmp == "て") { tmp = "te"; return tmp; } else if (tmp == "と") { tmp = "to"; return tmp; } else if (tmp == "な") { tmp = "na"; return tmp; } else if (tmp == "に") { tmp = "ni"; return tmp; } else if (tmp == "ぬ") { tmp = "nu"; return tmp; } else if (tmp == "ね") { tmp = "ne"; return tmp; } else if (tmp == "の") { tmp = "no"; return tmp; } else if (tmp == "は") { tmp = "ha"; return tmp; } else if (tmp == "ひ") { tmp = "hi"; return tmp; } else if (tmp == "ふ") { tmp = "hu"; return tmp; } else if (tmp == "へ") { tmp = "he"; return tmp; } else if (tmp == "ほ") { tmp = "ho"; return tmp; } else if (tmp == "ま") { tmp = "ma"; return tmp; } else if (tmp == "み") { tmp = "mi"; return tmp; } else if (tmp == "む") { tmp = "mu"; return tmp; } else if (tmp == "め") { tmp = "me"; return tmp; } else if (tmp == "も") { tmp = "mo"; return tmp; } else if (tmp == "や") { tmp = "ya"; return tmp; } else if (tmp == "ゆ") { tmp = "yu"; return tmp; } else if (tmp == "よ") { tmp = "yo"; return tmp; } else if (tmp == "ら") { tmp = "ra"; return tmp; } else if (tmp == "り") { tmp = "ri"; return tmp; } else if (tmp == "る") { tmp = "ru"; return tmp; } else if (tmp == "れ") { tmp = "re"; return tmp; } else if (tmp == "ろ") { tmp = "ro"; return tmp; } else if (tmp == "わ") { tmp = "wa"; return tmp; } else if (tmp == "を") { tmp = "wo"; return tmp; } else if (tmp == "ん") { tmp = "nn"; return tmp; } else if (tmp == "が") { tmp = "ga"; return tmp; } else if (tmp == "ぎ") { tmp = "gi"; return tmp; } else if (tmp == "ぐ") { tmp = "gu"; return tmp; } else if (tmp == "げ") { tmp = "ge"; return tmp; } else if (tmp == "ご") { tmp = "go"; return tmp; } else if (tmp == "ざ") { tmp = "za"; return tmp; } else if (tmp == "じ") { tmp = "zi"; return tmp; } else if (tmp == "ず") { tmp = "zu"; return tmp; } else if (tmp == "ぜ") { tmp = "ze"; return tmp; } else if (tmp == "ぞ") { tmp = "zo"; return tmp; } else if (tmp == "だ") { tmp = "da"; return tmp; } else if (tmp == "ぢ") { tmp = "di"; return tmp; } else if (tmp == "づ") { tmp = "du"; return tmp; } else if (tmp == "で") { tmp = "de"; return tmp; } else if (tmp == "ど") { tmp = "do"; return tmp; } else if (tmp == "ば") { tmp = "ba"; return tmp; } else if (tmp == "び") { tmp = "bi"; return tmp; } else if (tmp == "ぶ") { tmp = "bu"; return tmp; } else if (tmp == "べ") { tmp = "be"; return tmp; } else if (tmp == "ぼ") { tmp = "bo"; return tmp; } else if (tmp == "ぱ") { tmp = "pa"; return tmp; } else if (tmp == "ぴ") { tmp = "pi"; return tmp; } else if (tmp == "ぷ") { tmp = "pu"; return tmp; } else if (tmp == "ぺ") { tmp = "pe"; return tmp; } else if (tmp == "ぽ") { tmp = "po"; return tmp; } else if (tmp == "ー") { tmp = "bar"; return tmp; } else if (tmp == "ぁ") { tmp = "a"; return tmp; } else if (tmp == "ぃ") { tmp = "i"; return tmp; } else if (tmp == "ぅ") { tmp = "u"; return tmp; } else if (tmp == "ぇ") { tmp = "e"; return tmp; } else if (tmp == "ぉ") { tmp = "o"; return tmp; } else if (tmp == "っ") { tmp = "tt"; return tmp; } else if (tmp == "ゃ") { tmp = "ya"; return tmp; } else if (tmp == "ゅ") { tmp = "yu"; return tmp; } else if (tmp == "ょ") { tmp = "yo"; return tmp; } else { tmp = "ttt"; return tmp; } }

作ってみると、ショボいなりにもいろいろ見えてくるものです。

問題点が山積みです。

  • 「は」の区別ができない
    「私は〜」の場合も「は」と読み上げてしまいます。こういうのって文脈から判別するのでしょうか?判別処理ライブラリとかあればいいのですが。
  • 声の抑揚が気持ち悪すぎる
    今回は自分でマイクに向かって「あいうえおかきく〜わをん」まで一連で録音し、Windowsフリーソフト「SoundEngine Free」で、一語づつ分割してます。抑揚のないようにPC音声で作るとか、抑揚を整えてくれるフリーソフトがあれば、もう少しましになるでしょう。
  • ちっちゃい「ゃ」とかが「や」になってる。
    面倒だったのでやってないだけで、条件分岐すればもうすこしましに仕上がると思います。
  • 「ま行」とか「ぱ行」とかは発声前に唇を一旦閉じないといけません。
    これも条件分岐すればいいです。さぼってしまいました。

ほどんど見所はありませんが、onSoundComplete()内での再帰処理の部分は、わりと使える気がします。 このたどたどしさを逆に活かしたコンテンツを作る機会をいつまでも待っています。

Comment:2

TK 2007-11-15 (木) 17:59

単語・文脈解析がIMEをそのまま使えると、”私「は」”の問題も解決できそうです。
また、抑揚の問題は、日本語が50音だけでないということで、辞書などを拡張していくことによって解決できそうですが…。
遠いな。

tera 2007-11-15 (木) 19:55

>TK様
情報ありがとうございます。
僕の方では yahoo の形態素解析を使えば、ちょっといい感じにできるのではないかなと考えたことがあります。助詞なら「は(ha)」にするとかで部分的にはできるかなぁと思ったのですが、根本的解決はできそうにない気がして、それ以来放置していました。
僕の方が遠いです(笑)

Comment Form

コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。

Remember personal info

Trackback:0

TrackBack URL for this entry
http://www.trick7.com/blog/mt-tb.cgi/183
Listed below are links to weblogs that reference
Flashでテキストtoスピーチ from trick7.com blog

Home > action script > Flashでテキストtoスピーチ

持っている Flash & ActionScript 関連本の中から、自分的おすすめの読む順番をご紹介。各書籍のレビューは books カテゴリからご覧頂けます。
この順番でどう?(AS3.0)
  • Adobe Flash CS3 詳細! ActionScript 3.0 入門ノート (DVD付)
    Adobe Flash CS3 詳細! ActionScript 3.0 入門ノート (DVD付)

    デザイン方面からFlashデビューして、そのままAS2.0を使うようになった人が、難しいと評判のAS3デビューする時の最初の1冊として、とにかく目を通しておくと良いかと思います。プログラミング経験の少ない方でも、サンプルをじっくり読めば、ゼロからのAS3デビュー可。
  • ActionScript 3.0 アニメーション
    ActionScript 3.0 アニメーション
    洋書「Making Things Move!」の日本語訳本。ActionScript3.0で数学的アニメーションを作ることがメインテーマなのですが、前半部分でAS3.0の基礎を分かり易く解説されています。後半の重力, IK, 3D表現等のアニメーション解説も楽しい。僕はこれのAS2.0洋書版を読んでFlashの面白さに気付きました。
  • Adobe Flash CS3 詳細! ActionScript3.0入門ノート2 (CD-ROM付)
    Adobe Flash CS3 詳細! ActionScript3.0入門ノート2 (CD-ROM付)
    この次の辞典のような洋書を読む前の事前知識としてこの本の内容を理解しておくといいかも。
  • Essential ActionScript 3.0 (Essential)
    Essential ActionScript 3.0 (Essential)

    900ページ以上ある相当分厚い本。基礎からOOPまでを解説。ほぼ網羅しているので、これを抑えておけばAS3博士になれそう。
  • Actionscript 3.0 Cookbook
    Actionscript 3.0 Cookbook

    ActionScript3.0のリファレンス本。問題とその解決法が1ページぐらいで細分化されているので空いた時間にちょっとずつ読み進められる。WebでAS3のソースを見て勉強する時の字引としても使う。ただ、時期的に初期の本なので、AS3自体が仕様変更してたりするので正誤表は必読。
  • Object-Oriented Actionscript 3.0
    Object-Oriented Actionscript 3.0

    7/23に発売されたFlash&OOP本。AS2.0版は持っているのだけど、オブジェクト指向の初歩的な解説から入って、後半は僕の理解を超える難度になっていきました。今度こそ理解できるか?
この順番でどう?(AS2.0)
  • Foundation Actionscript Animation: Making Things Move (Foundation)
    Foundation Actionscript Animation: Making Things Move (Foundation)

    スクリプトでアニメーションさせる方法を学べる。プログラムの知識というよりも数学や物理の知識が必要。バネの表現や3D表現など、汎用性の高いテクニックを身に付けられ、個人の表現力をレベルアップするのに最適。参考までに、僕が調べた英単語リスト。2007年4月に、AS3対応版も発売されました。
  • ゲーム開発のための数学・物理学入門 Beginning Math and Physics for Game Programmers
    ゲーム開発のための数学・物理学入門  Beginning Math and Physics for Game Programmers

    「Making Things Move!」の世界を突き詰めたい人用のステップアップのための本。行列や物理運動、2D/3D表現。Flashの本ではなく、じっくり読むタイプの本なので、あとまわしにしてもいいかも。
  • Flash 8 Essentials
    Flash 8 Essentials

    Flash8の新機能を紹介。全10章が独立した構成で、興味のある部分から読めます。フィルタやビットマップ、ビデオの使い方とかを、基礎から順を追って理解していけるので、ゼロからスクリプティングできるようになる。僕はビットマップ関連の作業の際のリファレンスとして常用しています。
  • .fla―Idea of Flash Creation
    .fla―Idea of Flash Creation

    上の本でFlash8の基本を身に付けて、それをどう面白い表現に落とし込むかを学べます。深津さんの、試行錯誤・実験しやすいスクリプティング、クラス設計に凄さを感じました。YouTubeやFlickrのAPI、PHPとの連携記事も。
  • FLASH ActionScript 2.0入門完全ガイド+実践サンプル集 [CD-ROM付]
    FLASH ActionScript 2.0入門完全ガイド+実践サンプル集 [CD-ROM付]

    ここまでで表現力が付き、テンションが上がるので、その勢いで難解なオブジェクト指向に挑戦。プログラム経験のない人がいきなり英語のOOP本を読むのは厳しい。この本で継承とかインターフェースとかポリモーフィズムとかの用語を理解しておくといいかも。
  • オブジェクト指向でなぜつくるのか―知っておきたいプログラミング、UML、設計の基礎知識―
    オブジェクト指向でなぜつくるのか―知っておきたいプログラミング、UML、設計の基礎知識―

    Flashの本ではありませんが、OOPの概念を気軽に読めるボリュームで解説してくれます。英語と日本語のOOP用語の対応を図るためにも「Object-oriented Actionscript for Flash 8」と併読するのがおすすめ。なんとなく読んでおくだけでも結構違うのでは。
  • Object-oriented Actionscript for Flash 8
    Object-oriented Actionscript for Flash 8

    前半はOOPの利便性や基本の紹介。デザインパターンやMVCの理解。13章からグッと難しくなって大変。Flash8対応。
  • Essential Actionscript 2.0
    Essential Actionscript 2.0

    上の本よりもさらにOOPプログラマ向け。同じOOP本ということでやや重複しており、こちらはMX2004時代の本なので見送ってもいいかも。分かりやすい英語で良著。この本のAS3版が出たら間違いなく買い。

Page Top