             AVLinearPCMIsNonInterleaved: false
         ]
 
-        let readerOutput = AVAssetReaderTrackOutput(track: assetTrack, outputSettings: outputSettingsDict)
+        let readerOutput = AVAssetReaderTrackOutput(track: audioContext.assetTrack, outputSettings: outputSettingsDict)
         readerOutput.alwaysCopiesSampleData = false
         reader.add(readerOutput)
 
         var channelCount = 1
-        let formatDesc = assetTrack.formatDescriptions
+        let formatDesc = audioContext.assetTrack.formatDescriptions
         for item in formatDesc {
+            // TODO: handle error here
             guard let fmtDesc = CMAudioFormatDescriptionGetStreamBasicDescription(item as! CMAudioFormatDescription) else { return }    // TODO: Can the forced downcast in here be safer?
             channelCount = Int(fmtDesc.pointee.mChannelsPerFrame)
         }
 
         var sampleMax = noiseFloor
+        // TODO: bad things happen if target samples is 0
         let samplesPerPixel = max(1, channelCount * slice.count / targetSamples)
         let filter = [Float](repeating: 1.0 / Float(samplesPerPixel), count: samplesPerPixel)
 

        print("\(frame) -- \(imageView.frame)")
    }

    func renderAsset() {
        guard !renderingInProgress else { return }

        renderingInProgress = true
        delegate?.waveformViewWillRender?(self)
        let displayRange = zoomEndSamples - zoomStartSamples

        guard displayRange > 0 else { return }

        let renderStartSamples = minMaxX(zoomStartSamples - Int(CGFloat(displayRange) * horizontalTargetBleed), min: 0, max: totalSamples)
        let renderEndSamples = minMaxX(zoomEndSamples + Int(CGFloat(displayRange) * horizontalTargetBleed), min: 0, max: totalSamples)
        let widthInPixels = Int(frame.width * UIScreen.main.scale * horizontalTargetOverdraw)
        let heightInPixels = frame.height * UIScreen.main.scale * horizontalTargetOverdraw

        sliceAsset(withRange: renderStartSamples..<renderEndSamples, andDownsampleTo: widthInPixels) {
            (samples, sampleMax) in
            self.plotLogGraph(samples, maximumValue: sampleMax, zeroValue: self.noiseFloor, imageHeight: heightInPixels) {
                (image, selectedImage) in
                DispatchQueue.main.async {
                    self.imageView.image = image
                    self.highlightedImage.image = selectedImage
                    self.cachedSampleRange = renderStartSamples ..< renderEndSamples
                    self.renderingInProgress = false
                    self.setNeedsLayout()
                    self.delegate?.waveformViewDidRender?(self)
                }
            }
        }
    }

    /// Read the asset and create create a lower resolution set of samples
    func sliceAsset(withRange slice: Range<Int>, andDownsampleTo targetSamples: Int, done: (_ samples: [CGFloat], _ sampleMax: CGFloat) -> Void) {
        guard slice.count > 0 else { return }
        guard let asset = asset else { return }
        guard let assetTrack = assetTrack else { return }
        guard let reader = try? AVAssetReader(asset: asset) else { return }

        reader.timeRange = CMTimeRange(start: CMTime(value: Int64(slice.lowerBound), timescale: asset.duration.timescale), duration: CMTime(value: Int64(slice.count), timescale: asset.duration.timescale))
        let outputSettingsDict: [String : Any] = [
            AVFormatIDKey: Int(kAudioFormatLinearPCM),
            AVLinearPCMBitDepthKey: 16,

            NSLog("FDWaveformView failed to get waveform image from context")
            return
        }

        // TODO: handle the progress image differently?
//        let drawRect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
//        context.setFillColor(progressColor.cgColor)
//        UIRectFillUsingBlendMode(drawRect, .sourceAtop)
//        guard let tintedImage = UIGraphicsGetImageFromCurrentImageContext() else {
//            NSLog("FDWaveformView failed to get tinted image from context")
//            return
//        }
//        UIGraphicsEndImageContext()
        done(image)
    }
}

