import flash.media.Sound;
/*
hxsynth Copyright (C) 2008 Alex McLean
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
The formant filter is by alex@smartelectronix.com, taken from
http://www.musicdsp.org/ . Thanks!
*/
class Synth {
static var delay : Array = new Array();
static var delayPos : Int = 0;
static var gain:Float = 0.5;
static var prev:Float = 0;
static var input : Array = new Array();
static var maxDelaySz : Int = 512;
static var delaySz : Int = Math.floor(maxDelaySz / 2);
static var switcheroo : Float = 0;
static var sustain : Float = 0;
static var samplesPerCall : Int = 2048;
static function main() {
trace("Flash version: " + flash.system.Capabilities.version);
var i;
var ctx = new haxe.remoting.Context();
ctx.addObject("Synth",Synth);
var js = haxe.remoting.ExternalConnection.jsConnect("default",ctx);
var buffer = new Sound();
for (i in 0 ... maxDelaySz) {
delay.push(0.0);
}
buffer.addEventListener("sampleData", onSamplesCallback);
buffer.play();
play(100);
}
static function play(dur : Null) {
for (i in 0 ... dur) {
input.push((Math.random() - 0.5) * gain);
}
}
static function setDelaySz(sz : Null) {
if (sz > 1) {
sz = 1;
}
if (sz < 0) {
sz = 0;
}
delaySz = Math.floor(sz * maxDelaySz);
}
static function setSwitcheroo(i : Float) {
if (i > 1) {
i = 1;
}
else if (i < 0) {
i = 0;
}
switcheroo = i;
}
static function setSustain(i : Float) {
if (i > 1) {
i = 1;
}
else if (i < 0) {
i = 0;
}
sustain = (1 - i) * 0.1;
}
static function onSamplesCallback(event) {
for (i in 0 ... (samplesPerCall)) {
// get sample from end of delay ring buffer
var sample = delay[delayPos];
// low pass filter
var tmp = prev;
prev = sample;
sample = (tmp + sample) * 0.5;
// write out samples
event.data.writeFloat(sample); // left
event.data.writeFloat(sample); // right
sample = sample * (1 - sustain);
// pipe in input if there is some
if (input.length > 0) {
sample += input.shift();
}
// 'percussiveness' filter
if (switcheroo > 0 && (Math.random() < switcheroo)) {
sample = 0 - sample;
}
// write sample back into the delay
delay[delayPos] = sample;
// iterate delay
if (++delayPos >= delaySz) {
delayPos = 0;
}
}
}
}