package de.sciss.jcollider.test;
import java.io.IOException;
import java.util.*;
import de.sciss.jcollider.*;
import de.sciss.net.OSCBundle;
/**
* Static example generator
* to compare with SC examples
* found in the from-SC2.rtf file
*
* @author Hanns Holger Rutz
* @version 0.32, 24-Feb-08
*/
public abstract class DemoDefs
{
public static java.util.List create()
{
final java.util.List result = new ArrayList();
final Random rnd = new Random( System.currentTimeMillis() );
SynthDef def;
GraphElem f, g, h;
// AnalogBubbles
// NOTE : the graph tree shows a slightly different
// ordering of the top most LFSaw elements, have to check
f = UGen.kr( "midicps", UGen.kr( "MulAdd", UGen.kr( "LFSaw", UGen.ir( 0.4f ), UGen.ir( 0 )),
UGen.ir( 24 ), UGen.kr( "MulAdd", UGen.kr( "LFSaw", UGen.array( UGen.ir( 8 ), UGen.ir( 7.23f )), UGen.ir( 0 )),
UGen.ir( 3 ), UGen.ir( 80 ))));
g = UGen.ar( "CombN", UGen.ar( "*", UGen.ar( "SinOsc", f, UGen.ir( 0 )), UGen.ir( 0.04f )),
UGen.ir( 0.2f ), UGen.ir( 0.2f ), UGen.ir( 4 ));
def = new SynthDef( "JAnalogBubbles", UGen.ar( "Out", UGen.ir( 0 ), g ));
result.add( def );
// PulseModulation
f = UGen.ar( "CombL", UGen.ar( "RLPF", UGen.ar( "*", UGen.ar( "LFPulse",
UGen.kr( "MulAdd", UGen.kr( "FSinOsc", UGen.ir( 0.05f ), UGen.ir( 0 )), UGen.ir( 80 ), UGen.ir( 160 )),
UGen.ir( 0 ), UGen.ir( 0.4f )), UGen.ir( 0.05f )), UGen.kr( "MulAdd",
UGen.kr( "FSinOsc", UGen.array( UGen.ir( 0.6f ), UGen.ir( 0.7f )), UGen.ir( 0 )), UGen.ir( 3600 ), UGen.ir( 4000 )),
UGen.ir( 0.2f )), UGen.ir( 0.3f ), UGen.array( UGen.ir( 0.2f ), UGen.ir( 0.25f )), UGen.ir( 2 ));
def = new SynthDef( "JPulseModulation", UGen.ar( "Out", UGen.ir( 0 ), f ));
result.add( def );
// MotoRev
f = UGen.ar( "clip2", UGen.ar( "RLPF", UGen.ar( "LFPulse", UGen.kr( "MulAdd",
UGen.kr( "SinOsc", UGen.ir( 0.2f ), UGen.ir( 0 )), UGen.ir( 10 ), UGen.ir( 21 )),
UGen.ir( 0.1f )), UGen.ir( 100 ), UGen.ir( 0.1f )), UGen.ir( 0.4f ));
def = new SynthDef( "JMotoRev", UGen.ar( "Out", UGen.ir( 0 ), UGen.ar( "Pan2", f )));
result.add( def );
// Scratchy
// IMPORTANT NOTE : bringing one instance of BrownNoise together with a mul array
// into MulAdd will expand the channels but not duplicate BrownNoise
// (as in the SCLang source). So for equality, we put BrownNoise in the array!
f = UGen.ar( "RHPF", UGen.ar( "*", UGen.ar( "max", UGen.ar( "MulAdd",
UGen.array( UGen.ar( "BrownNoise" ), UGen.ar( "BrownNoise" )), UGen.ir( 0.5f ), UGen.ir( -0.49f )),
UGen.ir( 0 )), UGen.ir( 20 )), UGen.ir( 5000 ), UGen.ir( 1 ));
def = new SynthDef( "JScratchy", UGen.ar( "Out", UGen.ir( 0 ), f ));
result.add( def );
// Sprinkler
f = UGen.ar( "BPZ2", UGen.ar( "*", UGen.ar( "WhiteNoise" ), UGen.kr( "*", UGen.kr( "LFPulse",
UGen.kr( "MulAdd", UGen.kr( "LFPulse", UGen.ir( 0.09f ), UGen.ir( 0 ), UGen.ir( 0.16f )),
UGen.ir( 10 ), UGen.ir( 7 )), UGen.ir( 0 ), UGen.ir( 0.25f )), UGen.ir( 0.1f ))));
def = new SynthDef( "JSprinkler", UGen.ar( "Out", UGen.ir( 0 ), UGen.ar( "Pan2", f )));
result.add( def );
// HarmonicSwimming
{
float freq = 50;
int partials = 20;
GraphElem z = UGen.ir( 0.0f );
GraphElem offset = UGen.kr( "Line", UGen.ir( 0 ), UGen.ir( -0.02f ), UGen.ir( 60 ));
for( int i = 0; i < partials; i++ ) {
f = UGen.kr( "max", UGen.ir( 0 ), UGen.kr( "MulAdd", UGen.kr( "LFNoise1", UGen.array(
UGen.ir( 2 + rnd.nextFloat() * 8 ), UGen.ir( 2 + rnd.nextFloat() * 8 ))), UGen.ir( 0.02f ), offset ));
z = UGen.ar( "MulAdd", UGen.ar( "FSinOsc", UGen.ir( freq * (i + 1)), UGen.ir( 0 )), f, z );
}
def = new SynthDef( "JHarmonicSwimming", UGen.ar( "Out", UGen.ir( 0 ), z ));
result.add( def );
}
// HarmonicTumbling
{
float freq = 80;
float partials = 10;
GraphElem z = UGen.ir( 0.0f );
GraphElem trig = UGen.kr( "XLine", UGen.array( UGen.ir( 10 ), UGen.ir( 10 )), UGen.ir( 0.1f ), UGen.ir( 60 ));
for( int i = 0; i < partials; i++ ) {
f = UGen.kr( "Decay2", UGen.kr( "*", UGen.kr( "Dust", trig ), UGen.ir( 0.02f )), UGen.ir( 0.005f ),
UGen.ir( rnd.nextFloat() * 0.5f ));
z = UGen.ar( "MulAdd", UGen.ar( "FSinOsc", UGen.ir( freq * (i + 1)), UGen.ir( 0 )), f, z );
}
def = new SynthDef( "JHarmonicTumbling", UGen.ar( "Out", UGen.ir( 0 ), z ));
result.add( def );
}
// KlankReson
// NOTE : while in SClang the Klank constructor takes
// the array as the first argument before calling the
// super constructor, we follow the actual UGen spec
// where the array is the last argument; since we haven't
// provided a keyword constructor yet, it means we
// have to provide the three missing default arguments
// Also note that the concept of the the random panning
// was probably meant to vary along the partials
// (which won't happend in neither language ; see also the orphan 'n')
{
int partials = 15;
GraphElem[] flop = new GraphElem[ partials * 3 ];
float fl;
for( int i = 0, j = 0; i < partials; i++ ) {
fl = rnd.nextFloat();
flop[ j++ ] = UGen.ir( 80 + fl*fl*10000 ); // freq
flop[ j++ ] = UGen.ir( rnd.nextFloat() * 2 - 1 ); // amp
flop[ j++ ] = UGen.ir( 0.2f + rnd.nextFloat() * 8 ); // reson
}
f = UGen.ar( "Klank", UGen.ar( "*", UGen.ar( "Dust", UGen.ir( 0.7f )), UGen.ir( 0.04f )),
UGen.ir( 1.0f ), UGen.ir( 0.0f ), UGen.ir( 1.0f ), new GraphElemArray( flop ));
g = UGen.ar( "Pan2", f, UGen.ir( rnd.nextFloat() * 2 - 1 ));
def = new SynthDef( "JKlankReson", UGen.ar( "Out", UGen.ir( 0 ), g ));
result.add( def );
}
// PoliceState
// NOTE : don't ask me where Mix.arFill is contained
// in the sc sources, but it simply adds up all arguments
{
int num = 4;
f = null;
for( int i = 0; i < num; i++ ) {
g = UGen.ar( "Pan2", UGen.ar( "*", UGen.ar( "SinOsc", UGen.kr( "MulAdd",
UGen.kr( "SinOsc", UGen.ir( rnd.nextFloat() * 0.1f + 0.02f ), UGen.ir( rnd.nextFloat() * 2 * (float) Math.PI )),
UGen.ir( rnd.nextInt( 600 )), UGen.ir( rnd.nextInt( 600 ) + 700 )), UGen.ir( 0 )),
UGen.ar( "*", UGen.ar( "LFNoise2", UGen.ir( 80 + rnd.nextFloat() * 40 )), UGen.ir( 0.1f ))),
UGen.ir( rnd.nextFloat() * 2 - 1 ));
f = f == null ? g : UGen.ar( "+", f, g );
}
g = UGen.ar( "*", UGen.ar( "LFNoise2",
UGen.kr( "MulAdd", UGen.kr( "LFNoise2", UGen.array( UGen.ir( 0.4f ), UGen.ir( 0.4f ))),
UGen.ir( 90 ), UGen.ir( 620 ))),
UGen.kr( "MulAdd", UGen.kr( "LFNoise2", UGen.array( UGen.ir( 0.3f ), UGen.ir( 0.3f ))),
UGen.ir( 0.15f ), UGen.ir( 0.18f )));
h = UGen.ar( "CombL", UGen.ar( "+", f, g ), UGen.ir( 0.3f ), UGen.ir( 0.3f ), UGen.ir( 3 ));
def = new SynthDef( "JPoliceState", UGen.ar( "Out", UGen.ir( 0 ), h ));
result.add( def );
}
// SampleAndHoldLiquidities
{
GraphElem clockRate = UGen.kr( "MouseX", UGen.ir( 1 ), UGen.ir( 200 ), UGen.ir( 1 ));
GraphElem clockTime = UGen.kr( "reciprocal", clockRate );
GraphElem clock = UGen.kr( "Impulse", clockRate, UGen.ir( 0.4f ));
GraphElem centerFreq = UGen.kr( "MouseY", UGen.ir( 100 ), UGen.ir( 8000 ), UGen.ir( 1 ));
GraphElem freq = UGen.kr( "Latch", UGen.kr( "MulAdd", UGen.kr( "WhiteNoise" ),
UGen.kr( "*", centerFreq, UGen.ir( 0.5f )), centerFreq ), clock );
GraphElem panPos = UGen.kr( "Latch", UGen.kr( "WhiteNoise" ), clock );
f = UGen.ar( "*", UGen.ar( "SinOsc", freq ), UGen.kr( "Decay2", clock,
UGen.kr( "*", UGen.ir( 0.1f ), clockTime ), UGen.kr( "*", UGen.ir( 0.9f ), clockTime )));
g = UGen.ar( "Pan2", f, panPos );
h = UGen.ar( "CombN", g, UGen.ir( 0.3f ), UGen.ir( 0.3f ), UGen.ir( 2 ));
def = new SynthDef( "JSampleAndHoldLiquid", UGen.ar( "Out", UGen.ir( 0 ), h ));
result.add( def );
}
// AleatoricQuartet
{
float amp = 0.07f;
GraphElem density = UGen.kr( "MouseX", UGen.ir( 0.01f ), UGen.ir( 1 ));
GraphElem dmul = UGen.kr( "*", UGen.kr( "reciprocal", density ), UGen.ir( 0.5f * amp ));
GraphElem dadd = UGen.kr( "+", UGen.kr( "neg", dmul ), UGen.ir( amp ));
float[] fRange = new float[] { 1, 0.5f, 0.25f };
GraphElem excitation, freq;
f = null;
for( int i = 0; i < 4; i++ ) {
excitation = UGen.ar( "*", UGen.ar( "PinkNoise" ), UGen.kr( "max", UGen.ir( 0 ),
UGen.kr( "MulAdd", UGen.kr( "LFNoise1", UGen.ir( 8 )), dmul, dadd )));
freq = UGen.kr( "midicps", UGen.kr( "Lag", UGen.kr( "round", UGen.kr( "MulAdd",
UGen.kr( "LFNoise0", UGen.ir( fRange[ rnd.nextInt( 3 )])), UGen.ir( 7 ), UGen.ir( 36 + rnd.nextInt( 60 ))),
UGen.ir( 1 )), UGen.ir( 0.2f )));
g = UGen.ar( "Pan2", UGen.ar( "CombL", excitation, UGen.ir( 0.02f ), UGen.kr( "reciprocal", freq ),
UGen.ir( 3 )), UGen.ir( rnd.nextFloat() * 2 - 1 ));
f = f == null ? g : UGen.ar( "+", f, g );
}
for( int i = 0; i < 5; i++ ) {
f = UGen.ar( "AllpassN", f, UGen.ir( 0.05f ), UGen.array(
UGen.ir( rnd.nextFloat() * 0.05f ), UGen.ir( rnd.nextFloat() * 0.05f )), UGen.ir( 1 ));
}
f = UGen.ar( "LeakDC", f, UGen.ir( 0.995f ));
def = new SynthDef( "JAleatoricQuartet", UGen.ar( "Out", UGen.ir( 0 ), f ));
result.add( def );
}
// NoiseBusiness1
{
f = null;
for( int i = 0; i < 4; i++ ) {
g = UGen.ar( "*", UGen.ar( "LFSaw", UGen.kr( "midicps", UGen.kr( "MulAdd",
UGen.kr( "LFPulse", UGen.ir( 0.06f ), UGen.ir( 0 ), UGen.ir( 0.5f )),
UGen.ir( 2 ), UGen.array( UGen.ir( 34 + rand2( rnd, 0.1f )),
UGen.ir( 34 + rand2( rnd, 0.1f )))))),
UGen.ir( 0.01f ));
f = f == null ? g : UGen.ar( "+", f, g );
}
g = UGen.kr( "MouseY", UGen.ir( 0.1f ), UGen.ir( 0.7f ));
h = UGen.kr( "LinExp", UGen.kr( "SinOsc", UGen.ir( 0.07f )),
UGen.ir( -1 ), UGen.ir( 1 ), UGen.ir( 300 ), UGen.ir( 5000 ));
f = UGen.ar( "softclip", UGen.ar( "RLPF", f, h, g ));
f = UGen.ar( "softclip", UGen.ar( "RLPF", f, h, g ));
def = new SynthDef( "JNoiseBusiness1", UGen.ar( "Out", UGen.ir( 0 ), f ));
result.add( def );
}
// NoiseBusiness2
{
float pi2 = (float) Math.PI * 2;
f = UGen.ar( "SinOsc", UGen.ir( exprand( rnd, 0.3f, 8 ) * rrand( rnd, 0.7f, 1.3f )),
UGen.ir( rnd.nextFloat() * pi2 ));
g = UGen.ar( "SinOsc", UGen.ir( exprand( rnd, 0.3f, 8 )),
UGen.ir( rnd.nextFloat() * pi2 ));
f = UGen.ar( "max", UGen.ir( 0 ), UGen.ar( "*", UGen.ir( 0.1f ), UGen.ar( "+", f, g )));
h = UGen.ar( "SinOsc", UGen.ir( exprand( rnd, 6, 24 ) * rrand( rnd, 0.7f, 1.3f )),
UGen.ir( rnd.nextFloat() * pi2 ));
g = UGen.ar( "SinOsc", UGen.ir( exprand( rnd, 0.3f, 8 )),
UGen.ir( rnd.nextFloat() * pi2 ));
h = UGen.ar( "abs", UGen.ar( "*", UGen.ir( 0.1f ), UGen.ar( "+", h, g )));
f = UGen.ar( "*", UGen.ar( "SinOsc", UGen.ir( midicps( rrand( rnd, 24, 108 ))), UGen.ir( rnd.nextFloat() * pi2 )),
UGen.ar( "*", f, h ));
f = UGen.ar( "Pan2", f, UGen.ir( rand2( rnd, 1.0f )));
def = new SynthDef( "JNoiseBusiness2", UGen.ar( "Out", UGen.ir( 0 ), f ));
result.add( def );
}
// NoiseBusiness3
{
float pi2 = (float) Math.PI * 2;
f = UGen.ar( "SinOsc", UGen.ir( exprand( rnd, 0.3f, 8 ) * rrand( rnd, 0.7f, 1.3f )),
UGen.ir( rnd.nextFloat() * pi2 ));
g = UGen.ar( "SinOsc", UGen.ir( exprand( rnd, 0.3f, 8 )),
UGen.ir( rnd.nextFloat() * pi2 ));
f = UGen.ar( "max", UGen.ir( 0 ), UGen.ar( "*", UGen.ir( 0.04f ), UGen.ar( "+", f, g )));
h = UGen.ar( "SinOsc", UGen.ir( exprand( rnd, 6, 24 ) * rrand( rnd, 0.7f, 1.3f )),
UGen.ir( rnd.nextFloat() * pi2 ));
g = UGen.ar( "SinOsc", UGen.ir( exprand( rnd, 0.3f, 8 )),
UGen.ir( rnd.nextFloat() * pi2 ));
h = UGen.ar( "abs", UGen.ar( "+", h, g ));
f = UGen.ar( "*", UGen.ar( "LFTri", UGen.ir( midicps( rrand( rnd, 24, 108 ))), UGen.ir( rnd.nextFloat() * pi2 )),
UGen.ar( "*", f, h ));
f = UGen.ar( "Pan2", UGen.ar( "HPZ1", f ), UGen.ir( rand2( rnd, 1.0f )));
def = new SynthDef( "JNoiseBusiness3", UGen.ar( "Out", UGen.ir( 0 ), f ));
result.add( def );
}
// NoiseBusiness4
{
float pi2 = (float) Math.PI * 2;
f = UGen.ar( "SinOsc", UGen.ir( exprand( rnd, 0.3f, 8 ) * rrand( rnd, 0.7f, 1.3f )),
UGen.ir( rnd.nextFloat() * pi2 ));
g = UGen.ar( "SinOsc", UGen.ir( exprand( rnd, 0.3f, 8 )),
UGen.ir( rnd.nextFloat() * pi2 ));
f = UGen.ar( "max", UGen.ir( 0 ), UGen.ar( "*", UGen.ir( 0.04f ), UGen.ar( "+", f, g )));
h = UGen.ar( "SinOsc", UGen.ir( exprand( rnd, 6, 24 ) * rrand( rnd, 0.7f, 1.3f )),
UGen.ir( rnd.nextFloat() * pi2 ));
g = UGen.ar( "SinOsc", UGen.ir( exprand( rnd, 0.3f, 8 )),
UGen.ir( rnd.nextFloat() * pi2 ));
h = UGen.ar( "abs", UGen.ar( "+", h, g ));
f = UGen.ar( "*", UGen.ar( "LFPulse", UGen.ir( 80 * rrand( rnd, 1, 32 )), UGen.ir( rnd.nextFloat() * pi2 ), UGen.ir( 0.1f )),
UGen.ar( "*", f, h ));
f = UGen.ar( "Pan2", UGen.ar( "LPZ2", f ), UGen.ir( rand2( rnd, 1.0f )));
def = new SynthDef( "JNoiseBusiness4", UGen.ar( "Out", UGen.ir( 0 ), f ));
result.add( def );
}
// CombDist
// NOTE : here you see how controls are generated. We imitate
// SClang's SynthDef behaviour of grouping all controls of the
// same rate together in one UGen, therefore you pass an
// array to the contructor and access the indidual controls
// as the output channels.
// - Also note the explicit specifications of the number of channels
// for the In UGen, which is a seperate second int argument.
// - Also note how we have to treat 'reciprocal' in two different
// ways (Constant and UGen) to avoid extra overhead
// - Also note how we create a final GraphElemArray to include
// the two 'dead ends' of the graph (XOut and FreeSelfWhenDone).
// This is always necessary in cases where UGens do not have outlets
{
Control kCtrl = Control.kr( new String[] { "out", "freq", "decay", "wet", "gate" }, new float[] { 0, 400, 2, 1, 1 });
GraphElem zin = UGen.ar( "In", 2, kCtrl.getChannel( "out" ));
GraphElem freq = UGen.kr( "Lag3", kCtrl.getChannel( "freq" ), UGen.ir( 0.1f ));
GraphElem env = UGen.kr( "Linen", kCtrl.getChannel( "gate" ), UGen.ir( 1 ), UGen.ir( 1 ), UGen.ir( 1 ));
GraphElem wet = UGen.kr( "Ramp", kCtrl.getChannel( "wet" ), UGen.ir( 0.1f ));
GraphElem comb = UGen.ar( "CombN", zin, UGen.ir( 1.0f / midicps( 24 )), UGen.kr( "reciprocal", freq ),
kCtrl.getChannel( "decay" ));
// GraphElem zout = UGen.ar( "reverse", UGen.ar( "distort", comb ));
GraphElem zout = UGen.ar( "distort", comb );
f = UGen.ar( "XOut", kCtrl.getChannel( "out" ), UGen.kr( "*", wet, env ), zout );
g = UGen.kr( "FreeSelfWhenDone", env );
def = new SynthDef( "JCombDist", new GraphElemArray( new GraphElem[] { f, g }));
result.add( def );
}
// RingMod
{
Control kCtrl = Control.kr( new String[] { "out", "freq", "wet", "gate" }, new float[] { 0, 800, 1, 1 });
GraphElem freq = UGen.kr( "Ramp", kCtrl.getChannel( "freq" ), UGen.ir( 0.1f ));
GraphElem env = UGen.kr( "Linen", kCtrl.getChannel( "gate" ), UGen.ir( 1 ), UGen.ir( 1 ), UGen.ir( 1 ));
GraphElem wet = UGen.kr( "Ramp", kCtrl.getChannel( "wet" ), UGen.ir( 0.1f ));
GraphElem zin = UGen.ar( "In", 2, kCtrl.getChannel( "out" ));
GraphElem zout = UGen.ar( "*", zin, UGen.ar( "SinOsc", freq, UGen.array( UGen.ir( 0 ), UGen.ir( (float) Math.PI/2 ))));
f = UGen.ar( "XOut", kCtrl.getChannel( "out" ), UGen.kr( "*", wet, env ), zout );
g = UGen.kr( "FreeSelfWhenDone", env );
def = new SynthDef( "JRingMod", new GraphElemArray( new GraphElem[] { f, g }));
result.add( def );
}
return result;
}
public static void synthDefApiExample( Server myServer )
{
GraphElem f = null;
GraphElem g, h;
Control c = Control.kr( new String[] { "resinv" }, new float[] { 0.5f });
UGenChannel reso = c.getChannel( 0 );
Synth synth;
Random r = new Random( System.currentTimeMillis() );
String defName = "JNoiseBusiness1b";
OSCBundle bndl;
SynthDef def;
long time;
for( int i = 0; i < 4; i++ ) {
g = UGen.ar( "*", UGen.ar( "LFSaw", UGen.kr( "midicps", UGen.kr( "MulAdd",
UGen.kr( "LFPulse", UGen.ir( 0.06f ), UGen.ir( 0 ), UGen.ir( 0.5f )),
UGen.ir( 2 ), UGen.array( UGen.ir( 34 + r.nextFloat() * 0.2f ),
UGen.ir( 34 + r.nextFloat() * 0.2f ))))),
UGen.ir( 0.01f ));
f = (f == null) ? g : UGen.ar( "+", f, g );
}
h = UGen.kr( "LinExp", UGen.kr( "SinOsc", UGen.ir( 0.07f )),
UGen.ir( -1 ), UGen.ir( 1 ), UGen.ir( 300 ), UGen.ir( 5000 ));
f = UGen.ar( "softclip", UGen.ar( "RLPF", f, h, reso ));
f = UGen.ar( "softclip", UGen.ar( "RLPF", f, h, reso ));
def = new SynthDef( defName, UGen.ar( "Out", UGen.ir( 0 ), f ));
synth = Synth.basicNew( defName, myServer );
try {
def.send( myServer, synth.newMsg( myServer.asTarget(),
new String[] { "resinv" }, new float[] { 0.98f }));
time = System.currentTimeMillis();
for( int i = 500; i < 5000; i += 250 ) {
bndl = new OSCBundle( time + i );
bndl.addPacket( synth.setMsg( "resinv", r.nextFloat() * 0.8f + 0.015f ));
myServer.sendBundle( bndl );
}
bndl = new OSCBundle( time + 5500 );
bndl.addPacket( synth.freeMsg() );
myServer.sendBundle( bndl );
}
catch( IOException e1 ) {
System.err.println( e1 );
}
}
private static float exprand( Random rnd, float lo, float hi )
{
final double dlog = Math.log( hi ) - Math.log( lo );
return( (float) Math.exp( rnd.nextDouble() * dlog ) * lo );
}
private static float rrand( Random rnd, float lo, float hi )
{
return( rnd.nextFloat() * (hi - lo) + lo );
}
private static float rand2( Random rnd, float x )
{
return( rnd.nextFloat() * 2 * x - x );
}
private static float midicps( float midi )
{
return( (float) (Math.exp( (midi - 69) / 12 * Math.log( 2 )) * 440) );
}
}