-1

I would like to display a spectrogram in Swift for macOS. When displaying a wave file or a spectrum, I use a NSBezierPath. The lines don't change color.

Is this case, each FFT would be represented by a vertical line which points represent the magnitude of that FFT. I'd like to give a color for each point depending of the magnitude value, and it seems that it is difficult to do it in an optimized way with a NSBezierPath. Anyone could suggest an approach for that?

UPDATE: here is what I am trying to do:

func drawChunkFFT(rect: CGRect, spectrum: Array<Float>) {
    self.convertToPoints(spectrum: spectrum, samplesPerPixel: 2)
    var f = 0
    var x = 10
    let ctx = NSGraphicsContext.current?.cgContext
    ctx!.beginPath();
    ctx!.move(to: CGPoint(x:x,y:0))
    for _ in readFile.points{
        ctx!.move(to: CGPoint(x:ctx!.currentPointOfPath.x,y:ctx!.currentPointOfPath.y))
        ctx!.addLine(to: CGPoint(x:x, y:f))
        ctx!.setStrokeColor(red: readFile.points[f]/255, green: readFile.points[f]/255, blue: readFile.points[f]/255, alpha: 1.0)
        f += 1
    }
    ctx!.strokePath()
}

The values are:

55.76425552368164 for f 0
54.63053512573242 for f 1
216.34625244140625 for f 2
299.5468444824219 for f 3
71.74128723144531 for f 4
51.18459701538086 for f 5
17.891700744628906 for f 6
15.77481460571289 for f 7
18.720001220703125 for f 8

up to f=255, with decreasing values

I can see the vertical line at x=10, but all points have the same color while I was expecting grey levels

What am I doing wrong?

pm200107
  • 303
  • 1
  • 11
  • You need to set stroke color for each path. Or you need to draw. – E.Coms Oct 11 '18 at 20:25
  • so if I have 50 points to display, you suggest to use 50 Paths? – pm200107 Oct 11 '18 at 20:52
  • Drawing is performance preferred. – E.Coms Oct 11 '18 at 20:56
  • How about put strokepath inside for loop – E.Coms Oct 12 '18 at 01:14
  • yes, i tried both, but there was another error. you are right it has to be inside. Thanks. ctx!.currentPointOfPath.x or .y is always returning 0. I changed the ctx!.move(to: CGPoint(x:ctx!.currentPointOfPath.x,y:ctx!.currentPointOfPath.y)) to ctx!.move(to: x,y:f)) and then the line to y:f+1. Got a working grey scale now – pm200107 Oct 12 '18 at 18:34
  • @pm200107 - what is the `self.convertToPoints(spectrum: spectrum, samplesPerPixel: 2)` function? – koen Feb 22 '21 at 19:04

1 Answers1

0

Here is the answer to the question:

func drawChunkFFT(rect: CGRect, spectrum: Array<Float>) {
    self.convertToPoints(spectrum: spectrum, samplesPerPixel: 1)
    var f = 0
    var x = 10
    let ctx = NSGraphicsContext.current?.cgContext
    var value = 0
    ctx!.beginPath();
    ctx!.move(to: CGPoint(x:x,y:0))
    for _ in readFile.points{
        ctx!.move(to: CGPoint(x:x,y:f))
        ctx!.addLine(to: CGPoint(x:x, y:f+1))
        if(readFile.points[f] > 255) { value = 0} else { value = Int(255 - readFile.points[f])}
        ctx!.setStrokeColor(red: CGFloat(value)/255, green: CGFloat(value)/255, blue: CGFloat(value)/255, alpha: 1.0)
        f += 1
        ctx!.strokePath()
    }
}
Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
pm200107
  • 303
  • 1
  • 11