forked from: forked from: 音声合成もどき
// forked from Nully's forked from: 音声合成もどき
// forked from wanson's 音声合成もどき
package {
import flash.display.*;
import flash.events.*;
import flash.media.*;
import flash.geom.*;
[SWF(width=465, height=465, backgroundColor=0x0, frameRate=30)]
public class Voice extends Sprite {
private var phase:Number = 0, time:Number = 0;
private var tap:Array = [0, 0];
private const FL:Array = [
[800., 0.8], // あ
[250., 1.4],// い
[250., 1.2],// う
[450., 0.9],// え
[450., 0.8]// お
];
private var bitmap:BitmapData = new BitmapData(465,465,true,0);
public function Voice() {
rect.width = 1; rect.height = 1;
addChild(new Bitmap(bitmap));
var sound:Sound = new Sound();
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
sound.play();
}
private var rect:Rectangle = new Rectangle();
private function setPixcel(x:int, y:int,c:int):void {
rect.x = x;
rect.y = y;
bitmap.fillRect(rect, c);
}
private function onSampleData(event:SampleDataEvent):void {
bitmap.fillRect(bitmap.rect,0);
for (var i:int = 0; i < 8192; i++) {
// params
var time2:Number = time / 1.5 * 5;
var time3:Number = time / 1.7 * 5;
const vow1:int = Math.floor(time2) % FL.length;// あいうえおのうち1つ選択
const vow2:int = (vow1 + 1) % FL.length;// vow1の次の母音選択
const amp:Number = (.65);// 音の大きさ
const freq:Number = 260;// + 100 * Math.cos(time /2* Math.PI );// 周波数
// synthesize
var s:Number = .4 * ((phase - Math.floor(phase)))
* FL[vow1][1] * amp;// 三角波を作る?
setPixcel(i/2,-s*200+150, 0xffff0000);
s = 0.2*(Math.sin(phase*8)+1)*FL[vow1][1]*amp;
setPixcel(i/2,-s*200+150, 0xffff00ff);
const ff:Number = FL[vow1][0];// たとえば"あ"と"い"の中間をとる。
/*
// 指数関数を使っていいかんじにffを拡張する。
//const r:Number = Math.exp(
// -Math.PI * 50. * (1. + ff * ff * 1e-7 ) / 44100.);
const r:Number = 0.99
const a1:Number = 2. * r *
Math.cos(2.0 * Math.PI * ff / 44100.);
// tap[0]は1つ前
// tap[1]は2つ前
s = s
+ ( a1 * (tap[0]-s))
- (r * r * (tap[1]-s))
*/
const r:Number = Math.exp(
-Math.PI * 50. * (1. + ff * ff * 1e-7 ) / 44100.);
const a1:Number = 2. * r *
Math.cos(2.0 * Math.PI * ff / 44100.);
// tap[0]は1つ前
// tap[1]は2つ前
s = s
+ (a1 * (tap[0]-s))
- (r*r* (tap[1]-s))
setPixcel(i/2, -s*200+150, 0xff00ffff);
tap[1] = tap[0]; tap[0] = s;
// 音をステレオで出力
event.data.writeFloat(s); event.data.writeFloat(s);
// 周波数分進める。
phase += freq / 44100.;
// 時間を1フレーム分(1/44100秒)進める
time += 1.0 / 44100.;
}
}
}
}