Beautifl - Flash Gallery

Thumbnail : Text To Speech(Google API) - Change Speed
Text To Speech(Google API) - Change Speed
daniwell 2010-06-15 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

/**
 * Text To Speech(Google API) - Change Speed
 * 
 * マウス位置に応じてGoogleのTTSの再生速度を変えてみるテスト。
 */
package  
{
	import com.bit101.components.*;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.SampleDataEvent;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	
	[SWF(backgroundColor = "0xffffff", frameRate = "30", width = "465", height = "465")]
	public class TextToSpeechTest extends Sprite
	{
		private const BUFFER_LENGTH :Number = 2048;
		
		private var _inputTx  :InputText;
		
		private var _apiSound :Sound;
		private var _sound    :Sound = new Sound();
		private var _samples  :ByteArray = new ByteArray();
		private var _channel  :SoundChannel = new SoundChannel();
		
		private var _pan      :Number;	// パン
		private var _speed    :Number;	// 再生速度
		private var _position :Number;	// 再生位置
		private var _total    :Number;
		
		
		public function TextToSpeechTest() 
		{
			_initView();
			stage.addEventListener(MouseEvent.MOUSE_MOVE, _mouseMoveHandler);
		}
		/* View */
		private function _initView():void
		{
			_inputTx = new InputText(this, 10, 10, "Mikkumiku ni shiteyanyo.");
			_inputTx.width = 160;
			
			new PushButton(this, 10, 32, "speech", _clickHandler);
			
			// line
			graphics.lineStyle(0, 0xaaaaaa);
			graphics.moveTo(0,   465/2); graphics.lineTo(465, 465/2);
			graphics.moveTo(465/2,   0); graphics.lineTo(465/2, 465);
			
			graphics.moveTo(465/2-4, 465/4);
			graphics.lineTo(465/2+4, 465/4);
			graphics.moveTo(465/2-4, 465/4*3);
			graphics.lineTo(465/2+4, 465/4*3);
			
			// speed
			new Label(this, 465/2-32, 0, "speed");
			new Label(this, 465/2+4, 0, "2");
			new Label(this, 465/2+4, 465/4, "1");
			new Label(this, 465/2+4, 465/2, "0");
			new Label(this, 465/2+4, 465/4*3, "-1");
			new Label(this, 465/2+4, 465-18, "-2");
			
			// pan
			new Label(this, 3, 465/2-20, "pan");
			new Label(this, 3, 465/2, "left");
			new Label(this, 465-26, 465/2, "right");
		}
		
		/* BUTTON CLICK */
		private function _clickHandler (evt :Event) :void
		{
			_channel.stop();
			_sound.removeEventListener(SampleDataEvent.SAMPLE_DATA, _sampleDataHandler);
			
			var path :String = "http://translate.google.com/translate_tts?tl=en&q=" + encodeURI(_inputTx.text);
			
			_apiSound = new Sound();
			_apiSound.addEventListener(Event.COMPLETE, _completeHandler);
			_apiSound.load(new URLRequest(path));
		}
		
		/* SOUND LOAD COMPLETE */
		private function _completeHandler (evt :Event) :void 
		{
			_apiSound.removeEventListener(Event.COMPLETE, _completeHandler);
			_position = 0;
			
			_samples = new ByteArray();
			_apiSound.extract(_samples, 1000000);
			_total = _samples.length / 8;
			
			_sound.addEventListener(SampleDataEvent.SAMPLE_DATA, _sampleDataHandler);
			_channel = _sound.play();
		}
		
		/* MOUSE MOVE */
		private function _mouseMoveHandler (evt :MouseEvent) :void 
		{
			_pan   = - (1 - mouseX * 2 / 465);
			_speed =   (1 - mouseY * 2 / 465) * 2;
		}
		
		/* SAMPLE DATA */
		private function _sampleDataHandler (evt :SampleDataEvent) :void 
		{
			var left :Number, right :Number;
			
			for (var c :int = 0; c < BUFFER_LENGTH; c ++)
			{
				_position += _speed;
				if      (_position < 0)			_position = _total-1;
				else if (_total-1 < _position)	_position = 0;
				
				_samples.position = int(_position) * 8;
				
				left  = (_pan < 0) ? _samples.readFloat():_samples.readFloat() * (1 - _pan);
				right = (0 < _pan) ? _samples.readFloat():_samples.readFloat() * (1 + _pan);
				
				evt.data.writeFloat(left);
				evt.data.writeFloat(right);
			}
		}
	}
}