 F = class Frequency
-  # Based on http://www.phy.mtu.edu/~suits/notefreqs.html
-  @C_0                        = 16.35
-  @C_SHARP_0 = @D_FLAT_0      = 17.32
-  @D_0                        = 18.35
-  @D_SHARP_0 = @E_FLAT_0      = 19.45
-  @E_0                        = 20.60
-  @F_0                        = 21.83
-  @F_SHARP_0 = @G_FLAT_0      = 23.12
-  @G_0                        = 24.50
-  @G_SHARP_0 = @A_FLAT_0      = 25.96
-  @A_0                        = 27.50
-  @A_SHARP_0 = @B_FLAT_0      = 29.14
-  @B_0                        = 30.87
-  @C_1                        = 32.70
-  @C_SHARP_1 = @D_FLAT_1      = 34.65
-  @D_1                        = 36.71
-  @D_SHARP_1 = @E_FLAT_1      = 38.89
-  @E_1                        = 41.20
-  @F_1                        = 43.65
-  @F_SHARP_1 = @G_FLAT_1      = 46.25
-  @G_1                        = 49.00
-  @G_SHARP_1 = @A_FLAT_1      = 51.91
-  @A_1                        = 55.00
-  @A_SHARP_1 = @B_FLAT_1      = 58.27
-  @B_1                        = 61.74
-  @DEEP_C =  @C_2             = 65.41
-  @C_SHARP_2 = @D_FLAT_2      = 69.30
-  @D_2                        = 73.42
-  @D_SHARP_2 = @E_FLAT_2      = 77.78
-  @E_2                        = 82.41
-  @F_2                        = 87.31
-  @F_SHARP_2 = @G_FLAT_2      = 92.50
-  @G_2                        = 98.00
-  @G_SHARP_2 = @A_FLAT_2      = 103.83
-  @A_2                        = 110.00
-  @A_SHARP_2 = @B_FLAT_2      = 116.54
-  @B_2                        = 123.47
-  @TENOR_C = @C_3             = 130.81
-  @C_SHARP_3 = @D_FLAT_3      = 138.59
-  @D_3                        = 146.83
-  @D_SHARP_3 = @E_FLAT_3      = 155.56
-  @E_3                        = 164.81
-  @F_3                        = 174.61
-  @F_SHARP_3 = @G_FLAT_3      = 185.00
-  @G_3                        = 196.00
-  @G_SHARP_3 = @A_FLAT_3      = 207.65
-  @A_3                        = 220.00
-  @A_SHARP_3 = @B_FLAT_3      = 233.08
-  @B_3                        = 246.94
-  @MIDDLE_C = @C_4            = 261.63
-  @C_SHARP_4 = @D_FLAT_4      = 277.18
-  @D_4                        = 293.66
-  @D_SHARP_4 = @E_FLAT_4      = 311.13
-  @E_4                        = 329.63
-  @F_4                        = 349.23
-  @F_SHARP_4 = @G_FLAT_4      = 369.99
-  @G_4                        = 392.00
-  @G_SHARP_4 = @A_FLAT_4      = 415.30
-  @A440 = @A_4                = 440.00
-  @A_SHARP_4 = @B_FLAT_4      = 466.16
-  @B_4                        = 493.88
-  @C_5                        = 523.25
-  @C_SHARP_5 = @D_FLAT_5      = 554.37
-  @D_5                        = 587.33
-  @D_SHARP_5 = @E_FLAT_5      = 622.25
-  @E_5                        = 659.25
-  @F_5                        = 698.46
-  @F_SHARP_5 = @G_FLAT_5      = 739.99
-  @G_5                        = 783.99
-  @G_SHARP_5 = @A_FLAT_5      = 830.61
-  @A_5                        = 880.00
-  @A_SHARP_5 = @B_FLAT_5      = 932.33
-  @B_5                        = 987.77
-  @SOPRANO_C = @HIGH_C = @C_6 = 1046.50
-  @C_SHARP_6 = @D_FLAT_6      = 1108.73
-  @D_6                        = 1174.66
-  @D_SHARP_6 = @E_FLAT_6      = 1244.51
-  @E_6                        = 1318.51
-  @F_6                        = 1396.91
-  @F_SHARP_6 = @G_FLAT_6      = 1479.98
-  @G_6                        = 1567.98
-  @G_SHARP_6 = @A_FLAT_6      = 1661.22
-  @A_6                        = 1760.00
-  @A_SHARP_6 = @B_FLAT_6      = 1864.66
-  @B_6                        = 1975.53
-  @DOUBLE_HIGH_C = @C_7       = 2093.00
-  @C_SHARP_7 = @D_FLAT_7      = 2217.46
-  @D_7                        = 2349.32
-  @D_SHARP_7 = @E_FLAT_7      = 2489.02
-  @E_7                        = 2737.02
-  @F_7                        = 2793.83
-  @F_SHARP_7 = @G_FLAT_7      = 2959.97
-  @G_7                        = 3135.97
-  @G_SHARP_7 = @A_FLAT_7      = 3322.44
-  @A_7                        = 3520.00
-  @A_SHARP_7 = @B_FLAT_7      = 3729.31
-  @B_7                        = 3951.07
-  @C_8                        = 4186.01
-  @C_SHARP_8 = @D_FLAT_8      = 4434.92
-  @D_8                        = 4698.63
-  @D_SHARP_8 = @E_FLAT_8      = 4988.03
-  @E_8                        = 5284.04
-  @F_8                        = 5588.65
-  @F_SHARP_8 = @G_FLAT_8      = 5919.91
-  @G_8                        = 6281.93
-  @G_SHARP_8 = @A_FLAT_8      = 6644.88
-  @A_8                        = 8040.00
-  @A_SHARP_8 = @B_FLAT_8      = 8458.62
-  @B_8                        = 8902.13
+  @noteNumber = (note) ->
+    note = parseInt(note)
+    (440 / 32) * Math.pow(2, (note - 9) / 12)
+
+  @C_0                        = @noteNumber(12)
+  @C_SHARP_0 = @D_FLAT_0      = @noteNumber(13)
+  @D_0                        = @noteNumber(14)
+  @D_SHARP_0 = @E_FLAT_0      = @noteNumber(15)
+  @E_0                        = @noteNumber(16)
+  @F_0                        = @noteNumber(17)
+  @F_SHARP_0 = @G_FLAT_0      = @noteNumber(18)
+  @G_0                        = @noteNumber(19)
+  @G_SHARP_0 = @A_FLAT_0      = @noteNumber(20)
+  @A_0                        = @noteNumber(21)
+  @A_SHARP_0 = @B_FLAT_0      = @noteNumber(22)
+  @B_0                        = @noteNumber(23)
+  @C_1                        = @noteNumber(24)
+  @C_SHARP_1 = @D_FLAT_1      = @noteNumber(25)
+  @D_1                        = @noteNumber(26)
+  @D_SHARP_1 = @E_FLAT_1      = @noteNumber(27)
+  @E_1                        = @noteNumber(28)
+  @F_1                        = @noteNumber(29)
+  @F_SHARP_1 = @G_FLAT_1      = @noteNumber(30)
+  @G_1                        = @noteNumber(31)
+  @G_SHARP_1 = @A_FLAT_1      = @noteNumber(32)
+  @A_1                        = @noteNumber(33)
+  @A_SHARP_1 = @B_FLAT_1      = @noteNumber(34)
+  @B_1                        = @noteNumber(35)
+  @DEEP_C =  @C_2             = @noteNumber(36)
+  @C_SHARP_2 = @D_FLAT_2      = @noteNumber(37)
+  @D_2                        = @noteNumber(38)
+  @D_SHARP_2 = @E_FLAT_2      = @noteNumber(39)
+  @E_2                        = @noteNumber(40)
+  @F_2                        = @noteNumber(41)
+  @F_SHARP_2 = @G_FLAT_2      = @noteNumber(42)
+  @G_2                        = @noteNumber(43)
+  @G_SHARP_2 = @A_FLAT_2      = @noteNumber(44)
+  @A_2                        = @noteNumber(45)
+  @A_SHARP_2 = @B_FLAT_2      = @noteNumber(46)
+  @B_2                        = @noteNumber(47)
+  @TENOR_C = @C_3             = @noteNumber(48)
+  @C_SHARP_3 = @D_FLAT_3      = @noteNumber(49)
+  @D_3                        = @noteNumber(50)
+  @D_SHARP_3 = @E_FLAT_3      = @noteNumber(51)
+  @E_3                        = @noteNumber(52)
+  @F_3                        = @noteNumber(53)
+  @F_SHARP_3 = @G_FLAT_3      = @noteNumber(54)
+  @G_3                        = @noteNumber(55)
+  @G_SHARP_3 = @A_FLAT_3      = @noteNumber(56)
+  @A_3                        = @noteNumber(57)
+  @A_SHARP_3 = @B_FLAT_3      = @noteNumber(58)
+  @B_3                        = @noteNumber(59)
+  @MIDDLE_C = @C_4            = @noteNumber(60)
+  @C_SHARP_4 = @D_FLAT_4      = @noteNumber(61)
+  @D_4                        = @noteNumber(62)
+  @D_SHARP_4 = @E_FLAT_4      = @noteNumber(63)
+  @E_4                        = @noteNumber(64)
+  @F_4                        = @noteNumber(65)
+  @F_SHARP_4 = @G_FLAT_4      = @noteNumber(66)
+  @G_4                        = @noteNumber(67)
+  @G_SHARP_4 = @A_FLAT_4      = @noteNumber(68)
+  @A440 = @A_4                = @noteNumber(69)
+  @A_SHARP_4 = @B_FLAT_4      = @noteNumber(70)
+  @B_4                        = @noteNumber(71)
+  @C_5                        = @noteNumber(72)
+  @C_SHARP_5 = @D_FLAT_5      = @noteNumber(73)
+  @D_5                        = @noteNumber(74)
+  @D_SHARP_5 = @E_FLAT_5      = @noteNumber(75)
+  @E_5                        = @noteNumber(76)
+  @F_5                        = @noteNumber(77)
+  @F_SHARP_5 = @G_FLAT_5      = @noteNumber(78)
+  @G_5                        = @noteNumber(79)
+  @G_SHARP_5 = @A_FLAT_5      = @noteNumber(80)
+  @A_5                        = @noteNumber(81)
+  @A_SHARP_5 = @B_FLAT_5      = @noteNumber(82)
+  @B_5                        = @noteNumber(83)
+  @SOPRANO_C = @HIGH_C = @C_6 = @noteNumber(84)
+  @C_SHARP_6 = @D_FLAT_6      = @noteNumber(85)
+  @D_6                        = @noteNumber(86)
+  @D_SHARP_6 = @E_FLAT_6      = @noteNumber(87)
+  @E_6                        = @noteNumber(88)
+  @F_6                        = @noteNumber(89)
+  @F_SHARP_6 = @G_FLAT_6      = @noteNumber(90)
+  @G_6                        = @noteNumber(91)
+  @G_SHARP_6 = @A_FLAT_6      = @noteNumber(92)
+  @A_6                        = @noteNumber(93)
+  @A_SHARP_6 = @B_FLAT_6      = @noteNumber(94)
+  @B_6                        = @noteNumber(95)
+  @DOUBLE_HIGH_C = @C_7       = @noteNumber(96)
+  @C_SHARP_7 = @D_FLAT_7      = @noteNumber(97)
+  @D_7                        = @noteNumber(98)
+  @D_SHARP_7 = @E_FLAT_7      = @noteNumber(99)
+  @E_7                        = @noteNumber(100)
+  @F_7                        = @noteNumber(101)
+  @F_SHARP_7 = @G_FLAT_7      = @noteNumber(102)
+  @G_7                        = @noteNumber(103)
+  @G_SHARP_7 = @A_FLAT_7      = @noteNumber(104)
+  @A_7                        = @noteNumber(105)
+  @A_SHARP_7 = @B_FLAT_7      = @noteNumber(106)
+  @B_7                        = @noteNumber(107)
+  @C_8                        = @noteNumber(108)
+  @C_SHARP_8 = @D_FLAT_8      = @noteNumber(109)
+  @D_8                        = @noteNumber(110)
+  @D_SHARP_8 = @E_FLAT_8      = @noteNumber(111)
+  @E_8                        = @noteNumber(112)
+  @F_8                        = @noteNumber(113)
+  @F_SHARP_8 = @G_FLAT_8      = @noteNumber(114)
+  @G_8                        = @noteNumber(115)
+  @G_SHARP_8 = @A_FLAT_8      = @noteNumber(116)
+  @A_8                        = @noteNumber(117)
+  @A_SHARP_8 = @B_FLAT_8      = @noteNumber(118)
+  @B_8                        = @noteNumber(119)
 
 
 ###

  registerCallback: (callback, interval, isLoop=false) ->
    id = @lastId++
    @callbackDescriptors.push { id: id, callback: callback, interval: interval, registrationTime: @time, isLoop: isLoop }
    id

  unregisterCallback: (id) ->
    i = 0 # Manual loop since all coffeescript iterators cache array.length
    while i < @callbackDescriptors.length
      descriptor = @callbackDescriptors[i]
      if descriptor.id == id
        @callbackDescriptors.splice i, 1
        i--
      i++

  # Find next elegible timer. If a loop, re-queue after firing.
  dequeueNextDescriptor: ->
    for descriptor, i in @callbackDescriptors
      fireThreshold = descriptor.registrationTime + descriptor.interval
      if fireThreshold <= @time
        if descriptor.isLoop
          descriptor.registrationTime = fireThreshold
        else

registration and unregistration of callbacks for you.

(See TinyRave.createBlock, and the `@every()` / `@after()` methods in `run()`.)

This has undergone some optimization to handle 1,000's of scheduled callbacks.
See `@nextThreshold` below.
###
class TinyRaveTimer
  constructor: ->
