1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
//
// FileSpectrum.swift
// PrySDR
//
// Created by Jacky Jack on 01/01/2025.
//
import Accelerate
import AppKit
import Combine
import CoreImage
class FileSpectrum: NSObject, ObservableObject {
static let default_width = 512
static let default_height = 512
static let defaultSleepTime:UInt32 = 1
var offset:Int=0
let fileReader = FileReader()
var dataBuffer:[Int8] = .init(repeating: 0, count: FileSpectrum.default_width)
var allData:[Int8]? = nil
let fft512 = NaiveFFT512()
var line_counter:Int = 0
let sessionQueue = DispatchQueue(label: "sessionQueue",
attributes: [],
autoreleaseFrequency: .workItem)
@Published var outputImage = emptyCGImage
let simpleImage = SimpleImage(width: 512, height: 512)
/// A 1x1 Core Graphics image.
static var emptyCGImage: CGImage = {
let buffer = vImage.PixelBuffer(
pixelValues: [0],
size: .init(width: 1, height: 1),
pixelFormat: vImage.Planar8.self)
let fmt = vImage_CGImageFormat(
bitsPerComponent: 8,
bitsPerPixel: 8 ,
colorSpace: CGColorSpaceCreateDeviceGray(),
bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue),
renderingIntent: .defaultIntent)
return buffer.makeCGImage(cgImageFormat: fmt!)!
}()
init(_ input_filename: String) {
//get data from u8 file
do {
try fileReader.open(filename: input_filename)
} catch {
print("Cant open file \(input_filename)")
exit(0)
}
var i8_arr:[Int8]? = nil
do {
try i8_arr = fileReader.readAll()
allData = i8_arr
} catch {
print("Got error \(error)")
}
fileReader.close()
}
func makeSpectrogramImage() -> NSImage {
return NSImage(cgImage: FileSpectrum.emptyCGImage, size: .zero)
}
//just get data time to time from databuffer and pretend to be realtime data
func dataFileProcessor() {
//all now is about 512pixels
let processingSlice = allData![offset...offset+FileSpectrum.default_width-1]
let dataBuffer = Array(processingSlice)
var transform_result:[Float] = .init(repeating: 0.0, count: FileSpectrum.default_width)
//DispatchQueue.main.async {
transform_result = self.fft512.computeLine(dataBuffer)
self.simpleImage.drawPalletLine(line: self.line_counter, pixelLine: transform_result)
if self.offset+FileSpectrum.default_width < allData!.count {
self.offset += FileSpectrum.default_width
self.line_counter += 1
}
//}
}
func startRunning() {
sessionQueue.async {
print("lets start the task for spectrum analysis")
for i in 0..<512 {
print("Process the task \(i)")
self.simpleImage.drawPixel(i, i, PixelData(a: 255, r: 255, g: 0, b: 0))
DispatchQueue.main.async {
self.dataFileProcessor()
self.outputImage = self.simpleImage.toCGImage()!
}
sleep(FileSpectrum.defaultSleepTime)
}
}
}
}
|