     }
     public func startImmediately() { //skips the offset
         //this starts the recurring timer
-        //print("starting fade \((finalVolume > initialVolume ? "up" : "down"))")
+        let millis = NSDate().timeIntervalSince1970*1000
+        print("starting fade \(millis) \(directionString)")
         stepCounter = 0
         
-        if fadeTimer.valid {
-            fadeTimer.invalidate()
-        }
-        fadeTimer = NSTimer.scheduledTimerWithTimeInterval(controlRate,
-                                                           target: self,
-                                                           selector: #selector(updateFade),
-                                                           userInfo: nil,
-                                                           repeats: true)
-    }
-    
-    @objc func updateFade(timer: NSTimer) {
+        if cadUpdateTimer != nil{
+            cadUpdateTimer?.invalidate()
+        }
+        if numberOfSteps == 0{ //if no steps to run, go ahead and set the volume early
+            output!.gain = finalVolume
+        }
+        cadUpdateTimer = CADisplayLink(target: self, selector: #selector(updateFadeFromCADTimer))
+        cadUpdateTimer?.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
+        }
+    
+    @objc func updateFadeFromCADTimer() {
         let direction: Double = (initialVolume > finalVolume ? 1.0 : -1.0)
-        
-        if stepCount == 0{
+        let millis = NSDate().timeIntervalSince1970*1000
+        print("updatingFade fade \(millis) - \(stepCounter) \(directionString)")
+        if numberOfSteps == 0{
             endFade()
-        }else if stepCounter <= stepCount {
-            let controlAmount: Double = Double(stepCounter) / Double(stepCount) //normalized 0-1 value
+        }else if stepCounter <= numberOfSteps {
+            let controlAmount: Double = Double(stepCounter) / Double(numberOfSteps) //normalized 0-1 value
             var scaledControlAmount: Double = 0.0
             
             switch curveType {

                                    duration: Double = 1.0,
                                    type: CurveType = .Exponential,
                                    curvature: Double = 1.0,
                                    controlRate: Double = 1/30) -> [Double] {
        var curvePoints = [Double]()
        let stepCount = Int(floor(duration / controlRate))
        var counter = 0

    }//end updateFade
    
    func endFade(){
        let millis = NSDate().timeIntervalSince1970*1000
        print("ending fade \(millis) - \(numberOfSteps) \(directionString)")
        cadUpdateTimer?.invalidate()
        output!.gain = finalVolume
        stepCounter = 0
    }
