In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: forked from: forked from: GoogleText2Speech

http://jp.techcrunch.com/archives/20091214the-unofficial-google-text-to-speech-api/
Get Adobe Flash player
by Geo877 02 Jan 2010
    Embed
// forked from Geo877's forked from: forked from: GoogleText2Speech
// forked from ongaeshi's forked from: GoogleText2Speech
// forked from miyaoka's GoogleText2Speech
// forked from TheCoolMuseum's mp3 可変速再生
package 
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flash.utils.ByteArray;
	import caurina.transitions.Tweener;	
	import flash.utils.Timer;
	import com.bit101.components.HUISlider;
	import com.bit101.components.PushButton;
	/**
	 * http://jp.techcrunch.com/archives/20091214the-unofficial-google-text-to-speech-api/
	 */
	
	[SWF(width = "465", height = "465", backgroundColor = 0xFFFFFF, frameRate = "60")]
	
	public class Text2Speech
	extends Sprite 
	{
		private const REQ_URL_BASE:String = "http://translate.google.com/translate_tts?tl=en&q=";
		
		private var _outputSnd:Sound = new Sound();
		private var _sampleTable:ByteArray;
		private var bufferLength:int = 2048;
		private var speed:Number = 1.3;
		private var vol:Number = 0.5;
		private var rowDelay:Number = 100;
		private var rowIndex:int = 0;
		
		
		private var tfd:TextField = new TextField();
		
		public function Text2Speech() 
		{
                        // スライダーの設定
			var spdSlider:HUISlider = new HUISlider(this, 50, 420, "speed", function ():void 
			{
				speed = spdSlider.value;
			});
			spdSlider.minimum = 0.2;
			spdSlider.maximum = 3.0;
			spdSlider.value = speed;
			spdSlider.width = 400;

                        // 読み上げテキスト表示の設定
			tfd.autoSize = TextFieldAutoSize.LEFT;
			tfd.wordWrap = true;
			tfd.width = 400;
			addChild(tfd);
			tfd.x = 20;
			tfd.defaultTextFormat = new TextFormat("OCRB", 24);

                        // サウンド設定
			_outputSnd.addEventListener(SampleDataEvent.SAMPLE_DATA, player);

                        // 初期化
			init();

                        // 読み上げ開始
			speachNext();
			
		}
		private function init():void 
		{
			rowIndex = 0;
			tfd.text = "";
			tfd.y = 350;
			
		}
		private function speachNext():void
		{
			if (rowIndex >= lyrics.length)
			{
                                return;
				init();
			}
			var text:String = lyrics[rowIndex]
			rowIndex++;
			var timer:Timer = new Timer(rowDelay, 1);
			timer.addEventListener(TimerEvent.TIMER_COMPLETE, function ():void 
			{
                                // arguments.calee → 現在実行中の関数への参照
				timer.removeEventListener(TimerEvent.TIMER_COMPLETE, arguments.callee);
				speach(text + "\n");				
			});
			timer.start();
		}
		
		private function appendChar(char:String):void
		{
			var lastHeight:Number = tfd.textHeight;
			tfd.appendText(char);
			tfd.y -= tfd.textHeight - lastHeight;
		}

		// 実際に音声を再生する
		private function speach(text:String):void
		{
			var sourceSnd:Sound = new Sound();
			sourceSnd.addEventListener(Event.COMPLETE, function (event:Event):void
			{		
				var txtLen:int = text.length;
				var charTime:Number = sourceSnd.length / speed / txtLen;
				var timers:Array = [];
				for (var i:int = 0; i < txtLen; i++)
				{
					timers.push(new Timer(charTime * i, 1));
				}
				
				timers.forEach(function(timer:Timer, index:int, arr:Array):void {
					var char:String = text.substr(index, 1);					
					timer.addEventListener(TimerEvent.TIMER_COMPLETE, function ():void 
					{
						timer.removeEventListener(TimerEvent.TIMER_COMPLETE, arguments.callee);
						appendChar(char);
					});
					timer.start();
					
				});				
				
				_sampleTable = new ByteArray();
				sourceSnd.extract(_sampleTable, sourceSnd.length / 1000 * 44100, 0);
				_sampleTable.position = 0;
				_outputSnd.play();
				
			});
			sourceSnd.load(new URLRequest(REQ_URL_BASE + encodeURI(text)));
		}

		private function player(event:SampleDataEvent):void {
			var pos:Number = _sampleTable.position / 6;
			var length:Number = _sampleTable.length / 8;
			for (var i:int = 0; i < bufferLength; i++ ) {
				pos += speed;
				if (pos > length-1)
				{
					speachNext();
					break;
				}
				_sampleTable.position = Math.round(pos) * 8;
				event.data.writeFloat(_sampleTable.readFloat() * vol);
				event.data.writeFloat(_sampleTable.readFloat() * vol);
			}
		}
		
		private var lyrics:Array = [
                    "Hello.",
                    "My name is George.",
		];		
	
	}
	
}