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

GoogleText2Speech

http://jp.techcrunch.com/archives/20091214the-unofficial-google-text-to-speech-api/
Get Adobe Flash player
by miyaoka 15 Dec 2009
// 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)
			{
				init();
			}
			var text:String = lyrics[rowIndex]
			rowIndex++;
			var timer:Timer = new Timer(rowDelay, 1);
			timer.addEventListener(TimerEvent.TIMER_COMPLETE, function ():void 
			{
				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 / 8;
			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 = [

			//"Froms FROM-29827281-12:",
			//"Test Assessment Report",


			"This was a triumph.",
			"I'm making a note here:",
			"HUGE SUCCESS.",
			"It's hard to overstate my satisfaction.",
			"Aperture Science",
			"We do what we must",
			"because we can.",
			"For the good of all of us.",
			"Except the ones who are dead.",


			"But theres no sense",
			"crying over every mistake.",
			"You just keep on trying",
			"till you run out of cake.",
			"And the Science gets done.",
			"And you make a neat gun.",
			"For the people who are still alive.",



			//"Froms FROM-55551-5:",
			//"Personnel File Addendum:",

			//"Dear <<Subject Name Here>>,",


			"I'm not even angry.",
			"I'm being so sincere right now.",
			"Even though you broke my heart.",
			"And killed me.",
			"And tore me to pieces.",
			"And threw every piece into a fire.",
			"As they burned it hurt",
			"because I was so happy for you!",
			"Now these points of data",
			"make a beautiful line.",
			"And we're out of beta.",
			"We're releasing on time.",
			"So I'm GLaD.",
			"I got burned.",
			"Think of all the things we learned",
			"for the people who are still alive.",



			//"Froms FROM-55551-6:",
			//"Personnel File Addendum Addendum:",
			
			//"One last thing:",


			"Go ahead and leave me.",
			"I think I prefer to stay inside.",
			"Maybe you'll find someone else to help you.",
			"Maybe Black Mesa...",
			"THAT WAS A JOKE.",
			"FAT CHANCE.",
			"Anyway, this cake is great.",
			"It's so delicious and moist.",
			"Look at me still talking",
			"when there's Science to do.",
			"When I look out there,",
			"it makes me GLaD I'm not you.",
			"I've experiments to run.",
			"There is research to be done.",
			"On the people who are still alive.",


			"PS: And believe me I am still alive.",
			"PPS: I'm doing Science and I'm still alive.",
			"PPPS: I feel FANTASTIC and I'm still alive.",


			"FINAL THOUGHT:",
			"While you're dying I'll be still alive",


			"FINAL THOUGHT PS:",
			"And when you're dead I will be still alive",


			"STILL ALIVE"
			


		];		
	
	}
	
}