Georg Feil - Synth Sample 1985
Georg Feil - Synth Sample 1985
This is not considered as a tutorial rather optimized to smaller file size.
FP10 Sound Demo
@author Andre Michelle - http://blog.andre-michelle.com
@author Martin Jonasson - (slimmed down 469 bytes or about 20%) http://prototyprally.com/
package
{
import flash.display.Sprite;
import flash.media.Sound;
import flash.utils.ByteArray;
/**
* Georg Feil - Synth Sample 1985
*
* This is not considered as a tutorial rather optimized to smaller file size.
*
* FP10 Sound Demo
*
* @author Andre Michelle - http://blog.andre-michelle.com
* @author Martin Jonasson - (slimmed down 469 bytes or about 20%) http://prototyprally.com/
*/
[SWF(width='408',height='284',frameRate='44',backgroundColor='0xa0a0ff')]
public class SS extends Sprite
{
//-- SOUND REGISTER
//-- PitchPhase, PitchPhaseIncr, PulsePhase, Volume, Pan, LowPass
private const sr: Vector.<Number> = new Vector.<Number>( 18, true );
//-- DATA
private const bd: ByteArray = new ByteArray;
private const md: ByteArray = new ByteArray;
//-- QUARTER INDEX AND SAMPLE POSITION
private var qi: int;
private var qs: int;
//-- MELODY SHORT AND SAMPLE POSITION
private var msh: int;
private var ms: int;
//-- MASTER MIXER
private var run: Boolean;
private var vol: Number;
public function SS()
{
bd.writeUTFBytes("'.3.'.3.'.3.'.3.'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6,383,383(/4/(/4/#*/6#*/6'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6,383,383(/4/(/4/#*/6#*/6'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6,383,383(/4/(/4/#*/6#*/6'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6,383,383(/4/(/4/#*/6#*/6'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6,383,383(/4/(/4/#*/6#*/6'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6,383,383(/4/(/4/#*/6#*/6'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6,383,383(/4/(/4/#*/6#*/6'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6,383,383(/4/(/4/#*/6#*/6'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6,383,383(/4/(/4/#*/6#*/6'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6,383,383(/4/(/4/#*/6#*/6'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6,383,383(/4/(/4/#*/6#*/6'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6,383,383(/4/(/4/#*/6#*/6'.3.'.3.'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6'.3.'.3.#*/6#*/6'.3.'.3.")
md.writeUTFBytes("`?=;@?DBFDFG\nDGPNKBDKIF;?=;@?FDXWZh\nfdc\n_S ca_dc$cZ\\_\\ZWZW_^WZ^_\nac\\_acZX\nZ\\XWSWXZ\n\\_hfcZ\\cacWWUSXW\\Z^\\\\^_\\_hfc_^ZWZ^_ZWZ_^ZW^ZWZ^_ZWSSUWS\\ZWWXZW^Zchfdcac_\\ch\nfdc\n_S ca_dc$cZ\\_\\ZWZW_^WZ^_\nac\\_acZX\nZ\\XWSWXZ\n\\_hfcZ\\cacWWUSXW\\Z^\\\\^_\\_hfc_^ZWZ^_ZWZ_^ZW^ZWZ^_ZWSSUWS\\ZWWXZW^Zchfdcac_\\c");
md.position = 0;
graphics.beginFill( 0x4040e0 );
graphics.drawRect( 44, 42, 320, 200 );
//-- FIRST MELO NOTE
msh = md.readShort();
ms = int( ( ( ( msh >> 8 & 0xFF ) * .125 ) * 10584000 ) / 170 );
//-- PANNING
sr[4] = .25;
sr[10] = -.25;
run = true;
vol = .2;
var snd:* = new Sound();
snd.addEventListener( 'sampleData', sd );
snd.play();
}
private function sd( e:* ): void
{
var amp: Number;
var ml: Number;
var mr: Number;
var pl: Number;
var vi: int;
var vn: int;
for( var i: int = 0 ; i < 4096 ; ++i )
{
if( --qs < 0 ) //-- NEXT QUARTER NOTE
{
//-- SET REGISTER
vn = (qi&1) * 6;
// PitchPhase
sr[int(vn+0)] = 0;
// PitchPhaseIncr
sr[int(vn+1)] = 440 * Math.pow( 2, ( bd[ qi ] - 69 ) / 12 ) / 44100;
// Volume
sr[int(vn+3)] = .25;
// QUATER NOTE IN SAMPLES (170BPM)
qs = int( ( .25 * 10584000 ) / 170 );
++qi;
}
if( md.bytesAvailable >= 2 ) // MELODY DATA AVAIABLE
{
if( --ms < 0 ) // NEXT MELODY NOTE
{
// PitchPhase
sr[12] = 0;
// PitchPhaseIncr
sr[13] = 440 * Math.pow( 2, ( ( msh & 0xFF ) - 69 ) / 12 ) / 44100;
// Volume
sr[15] = .175;
//-- COMPUTE SAMPLE OFFSET TO NEXT NOTE
msh = md.readShort();
ms = int( ( ( ( msh >> 8 & 0xFF ) * .125 ) * 10584000 ) / 170 );
}
}
else
run = false;
//-- MASTER VOLUME
run ? vol += ( 1 - vol ) * .000003 : vol -= vol * .000003;
//-- MIX UP THE 3 CHANNELS
ml = 0;
mr = 0;
for( vi = 0 ; vi < 3 ; ++vi )
{
vn = vi * 6;
//-- PULSE
if( ( pl = sr[int(vn+2)] * 2 ) > 1 ) pl = 2 - pl;
//-- WAVEFORM (SQUARE WITH PULSE-MODULATION)
amp = sr[vn] < ( .2 + pl * .3 ) ? vol : -vol;
//-- VOLUME DECAY ENVELOPE
amp *= sr[int(vn+3)] *= .99996;
//-- LOWPASS FILTER TO AVOID ANTIALIASING
sr[int(vn+5)] += ( amp - sr[int(vn+5)] ) * .3;
//-- VOICE MIX
ml += ( 1 - sr[int(vn+4)] ) * sr[int(vn+5)];
mr += ( sr[int(vn+4)] + 1 ) * sr[int(vn+5)];
//-- PULSE INCR
if( ( sr[int(vn+2)] += .000033 ) >= 1 )
--sr[int(vn+2)];
//-- PITCH INCR
if( ( sr[vn] += sr[int(vn+1)] ) >= 1 )
--sr[vn];
}
//-- WRITE OUTPUT STREAM
e.data.writeFloat( ml );
e.data.writeFloat( mr );
}
if( vol < .001 )
e.target.removeEventListener( 'sampleData', sd );
}
}
}