From a0d12ecbac8fe327d1dcd4580fee594e24d4191b Mon Sep 17 00:00:00 2001
From: Arturs Artamonovs <arturs.artamonovs@protonmail.com>
Date: Mon, 6 Jan 2025 12:30:49 +0000
Subject: Waterfall: UI drawing from file

---
 Radio/Utils/WaterfallFile/NaiveFFT.swift    |  7 ---
 Radio/Utils/WaterfallFile/NaiveFFT512.swift | 49 +++++++++++++++++
 Radio/Utils/WaterfallFile/SimpleImage.swift |  2 +-
 Radio/Utils/WaterfallFile/main.swift        | 84 +++++++++--------------------
 4 files changed, 76 insertions(+), 66 deletions(-)
 delete mode 100644 Radio/Utils/WaterfallFile/NaiveFFT.swift
 create mode 100644 Radio/Utils/WaterfallFile/NaiveFFT512.swift

(limited to 'Radio')

diff --git a/Radio/Utils/WaterfallFile/NaiveFFT.swift b/Radio/Utils/WaterfallFile/NaiveFFT.swift
deleted file mode 100644
index 79393b7..0000000
--- a/Radio/Utils/WaterfallFile/NaiveFFT.swift
+++ /dev/null
@@ -1,7 +0,0 @@
-//
-//  NaiveFFT.swift
-//  PrySDR
-//
-//  Created by Jacky Jack on 05/01/2025.
-//
-
diff --git a/Radio/Utils/WaterfallFile/NaiveFFT512.swift b/Radio/Utils/WaterfallFile/NaiveFFT512.swift
new file mode 100644
index 0000000..b4dca7e
--- /dev/null
+++ b/Radio/Utils/WaterfallFile/NaiveFFT512.swift
@@ -0,0 +1,49 @@
+//
+//  NaiveFFT.swift
+//  PrySDR
+//
+//  Created by Jacky Jack on 05/01/2025.
+//
+
+import Foundation
+import Accelerate
+
+//SUpports now only fixed sizes and not flexible implementation just a PoC
+class NaiveFFT512 {
+    
+    static let sampleCount = 512
+    let forwardDCT = vDSP.DCT(count: sampleCount, transformType: .II)!
+    
+    init() {
+        
+    }
+    
+    func getSampleCount() -> Int {
+        return NaiveFFT512.sampleCount
+    }
+    
+    func computeLine(_ processingArray: [Int8]) -> [Float] {
+        
+        var dataFloat = [Float](repeating: 0.0, count: NaiveFFT512.sampleCount)
+        
+        if processingArray.count != NaiveFFT512.sampleCount {
+            print("Not supporting arrays not equail to \(NaiveFFT512.sampleCount)")
+            return []
+        }
+        
+        vDSP.convertElements(of: processingArray, to: &dataFloat)
+        //dataFloat = vDSP.add(127.0, dataFloat)
+        //print(dataFloat)
+        
+        //move from -127.0 to 128.0 range -1.0...1.0
+        //var adjusted = vDSP.divide(dataFloat, Float(sampleCount))
+        var adjusted = dataFloat
+        //print(adjusted)
+        
+        var transform_result = forwardDCT.transform(adjusted)
+        transform_result = vDSP.absolute(transform_result)
+        
+        return transform_result
+    }
+    
+}
diff --git a/Radio/Utils/WaterfallFile/SimpleImage.swift b/Radio/Utils/WaterfallFile/SimpleImage.swift
index c05709f..4f1bed8 100644
--- a/Radio/Utils/WaterfallFile/SimpleImage.swift
+++ b/Radio/Utils/WaterfallFile/SimpleImage.swift
@@ -32,7 +32,7 @@ public class SimpleImage {
     func drawPalletLine(line: Int, pixelLine:[Float]) {
         for i in 0..<self.width {
             var pixel = pixelLine[i]
-            if pixel>256.0 {
+            if pixel>255.0 {
                 //print("values to high")
                 pixel = 255.0
             }
diff --git a/Radio/Utils/WaterfallFile/main.swift b/Radio/Utils/WaterfallFile/main.swift
index cf72d56..039be72 100644
--- a/Radio/Utils/WaterfallFile/main.swift
+++ b/Radio/Utils/WaterfallFile/main.swift
@@ -7,84 +7,58 @@
 
 import Foundation
 import Accelerate
+import ArgumentParser
+
+//set the command line arguments
+struct CommandLineArgs: ParsableCommand {
+    @Argument var inputFile:String = ""
+    @Argument var outputFile:String = ""
+}
+
+let args = CommandLineArgs.parseOrExit()
 
 print("Read binary file")
 
-let input_filename="rtlsdr_100M_m.cu8"
+let input_filename=args.inputFile
 
 
 //get data from u8 file
-let dir = getCurrentExecutableDir()
-let filemgr = FileManager.default
-
-if !filemgr.fileExists(atPath: input_filename) {
-    print("Cant find file \(input_filename)")
+let fileReader = FileReader()
+do {
+    try fileReader.open(filename: input_filename)
+} catch {
+    print("Cant open file \(input_filename)")
     exit(0)
 }
-
-let fileHandle: FileHandle? = FileHandle(forReadingAtPath: dir+"/"+input_filename)
 var i8_arr:[Int8]? = nil
-if let file = fileHandle {
-    file.seek(toFileOffset: 0)
-    do {
-        if let databuf = try file.readToEnd() {
-            
-            print("read \(databuf.count) \(databuf) bytes")
-            //let temp_arr = [Int8](databuf)
-            i8_arr = [Int8](repeating: 0, count: databuf.count)
-            
-            for i in 0..<i8_arr!.count {
-                print(String(format:"%02X", databuf[i]),terminator: "")
-                //convert from 0..255 to -127..128
-                let val = databuf[i]
-                if val <= 127 {
-                    i8_arr![i] = Int8(val)-127
-                } else {
-                    i8_arr![i] = Int8(val-128)
-                }
-                //print(String(format:"%02X", i8_arr![i]),terminator: "")
-            }
-        }
-    } catch {
-        print(error)
-        exit(0)
-    }
-    
+do {
+    try i8_arr = fileReader.readAll()
+} catch {
+    print("Got error \(error)")
 }
-fileHandle?.closeFile()
+
+fileReader.close()
 
 //all data in buffer lets process data
 //convert all u8 data to float's
 
 //is there other ways to do that?
-/*for i in 0..<dataFloat.count {
-    dataFloat[i] = Float(u8_arr![i])
-}*/
 //will generate 512x512 image
 let sampleCount = 512
 let img = SimpleImage(width: sampleCount, height: sampleCount)
 let number_of_lines = (i8_arr!.count/sampleCount)
-let forwardDCT = vDSP.DCT(count: sampleCount, transformType: .II)!
 var frequencyDomain:[Float] = []
 var transform_result:[Float] = .init(repeating: 0.0, count: sampleCount)
-var dataFloat = [Float](repeating: 0.0, count: sampleCount)
+let fft512 = NaiveFFT512()
+
 for i in 0..<sampleCount {
     let sample_idx = i*sampleCount
     if i < number_of_lines {
         let processingSlice = i8_arr![sample_idx...sample_idx+512-1]
         let processingArray = Array(processingSlice)
-        vDSP.convertElements(of: processingArray, to: &dataFloat)
-        //dataFloat = vDSP.add(127.0, dataFloat)
-        //print(dataFloat)
-        
-        //move from -127.0 to 128.0 range -1.0...1.0
-        //var adjusted = vDSP.divide(dataFloat, Float(sampleCount))
-        var adjusted = dataFloat
-        //print(adjusted)
+        transform_result = fft512.computeLine(processingArray)
         
-        transform_result = forwardDCT.transform(adjusted)
-        transform_result = vDSP.absolute(transform_result)
-        let max = vDSP.maximum(transform_result)
+        //let max = vDSP.maximum(transform_result)
         //print("max=\(max)")
         //frequencyDomain.append(contentsOf: transform_result)
         img.drawPalletLine(line: i, pixelLine: transform_result)
@@ -99,15 +73,9 @@ img.drawPixel(0, 0, PixelData(a: 255, r: 255, g: 0, b: 0))
 img.drawPixel(sampleCount-1, 0, PixelData(a: 255, r: 0, g: 255, b: 0))
 img.drawPixel(0, sampleCount-1, PixelData(a: 255, r: 0, g: 255, b: 0))
 img.drawPixel(sampleCount-1, sampleCount-1, PixelData(a: 255, r: 0, g: 0, b: 255))
-
-
 //print(dataFloat)
 
-
-
 //output data to image file
-img.saveAsJPEG("fft_100m_512.jpeg")
-
-
+img.saveAsJPEG(args.outputFile)
 
 print("All computations are done")
-- 
cgit v1.2.3