Index: /lang/actionscript/flmml/trunk/src/com/txt_nifty/sketch/flmml/MChannel.as
===================================================================
--- /lang/actionscript/flmml/trunk/src/com/txt_nifty/sketch/flmml/MChannel.as (revision 25651)
+++ /lang/actionscript/flmml/trunk/src/com/txt_nifty/sketch/flmml/MChannel.as (revision 26078)
@@ -188,5 +188,5 @@
         }
         public function setInput(i:int, p:int):void {
-            m_inSens = (1<<(i-1)) * (1.0 / 8.0) * MOscillator.TABLE_LEN;
+            m_inSens = (1<<(i-1)) * (1.0 / 8.0) * MOscillator.PHASE_LEN;
             m_inPipe = p;
         }
Index: /lang/actionscript/flmml/trunk/src/com/txt_nifty/sketch/flmml/MOscillator.as
===================================================================
--- /lang/actionscript/flmml/trunk/src/com/txt_nifty/sketch/flmml/MOscillator.as (revision 26077)
+++ /lang/actionscript/flmml/trunk/src/com/txt_nifty/sketch/flmml/MOscillator.as (revision 26078)
@@ -35,4 +35,6 @@
         protected static var   s_init:int = 0;
         protected static var   s_sinTable:Vector.<Number> = new Vector.<Number>(TABLE_LEN);
+        protected static var   s_sawTable:Vector.<Number> = new Vector.<Number>(TABLE_LEN);
+        protected static var   s_triTable:Vector.<Number> = new Vector.<Number>(TABLE_LEN);
         protected static var   s_rndTable:Vector.<Number> = new Vector.<Number>(TABLE_LEN);
         protected static var   s_tri16Table:Vector.<Number> = new Vector.<Number>(TRI16_TABLE_LEN);
@@ -50,10 +52,15 @@
         public static function boot():void {
             if (!s_init) {
-                var d:Number = 2.0 * Math.PI / TABLE_LEN;
-                var p:Number = 0.0;
+                var d0:Number = 2.0 * Math.PI / TABLE_LEN;
+                var d1:Number = 1.0 / TABLE_LEN;
+                var p0:Number;
+                var p1:Number;
                 var i:int;
-                for(i = 0; i < TABLE_LEN; i++) {
-                    s_sinTable[i] = Math.sin(p);
-                    p += d;
+                for(i = 0, p0 = 0.0, p1 = 0.0; i < TABLE_LEN; i++) {
+                    s_sinTable[i] = Math.sin(p0);
+                    s_sawTable[i] = p1 * 2.0 - 1.0;
+                    s_triTable[i] = (p1 < 0.5) ? (1 - 4 * p1) : (1 - 4 * (1 - p1));
+                    p0 += d0;
+                    p1 += d1;
                 }
                 for(i = 0; i < TABLE_LEN; i++) {
@@ -78,8 +85,7 @@
                 return Number(s_sinTable[phase >> PHASE_SFT]);
             case SAW:
-                return Number(phase) * (2.0 / PHASE_LEN) - 1.0;
+                return Number(s_sawTable[phase >> PHASE_SFT]);
             case TRIANGLE:
-                return ((phase < PHASE_HLF)
-                        ? (PHASE_LEN - 4 * phase) : (PHASE_LEN - 4 * (PHASE_LEN - phase))) / PHASE_LEN;
+                return Number(s_triTable[phase >> PHASE_SFT]);
             case PULSE:
                 return (phase < m_pwm) ? 1.0 : -1.0;
@@ -115,12 +121,11 @@
             case SAW:
                 for(i = start; i < end; i++) {
-                    samples[i] = Number(m_phase) * (2.0 / PHASE_LEN) - 1.0
-                        m_phase = (m_phase + m_frequency) & PHASE_MSK;
+                    samples[i] = s_sawTable[m_phase >> PHASE_SFT];
+                    m_phase = (m_phase + m_frequency) & PHASE_MSK;
                 }
                 break;
             case TRIANGLE:
                 for(i = start; i < end; i++) {
-                    samples[i] = ((m_phase < PHASE_HLF)
-                                  ? (PHASE_LEN - 4 * m_phase) : (PHASE_LEN - 4 * (PHASE_LEN - m_phase))) * (1.0 / PHASE_LEN);
+                    samples[i] = s_triTable[m_phase >> PHASE_SFT];
                     m_phase = (m_phase + m_frequency) & PHASE_MSK;
                 }
