// // main.swift // RtlSdrIQ // // Created by Jacky Jack on 27/11/2024. // import Foundation import libr820 import ArgumentParser let NUM_SAMPLES=1024 //set the command line arguments struct CommandLineArgs: ParsableCommand { @Argument var file:String = "" @Option(name:.shortAndLong) var device_idx: Int = 0 @Option(name:.shortAndLong) var samplerate: Int = 2048000 @Option(name:.shortAndLong) var gain: Int = 0 @Option(name:.shortAndLong) var frequency: Int = 100000000 @Option(name:.shortAndLong) var nsamples: Int = 1024 @Flag(name: .shortAndLong) var verbose: Bool = false @Flag(name: .shortAndLong) var async: Bool = false } let args = CommandLineArgs.parseOrExit() //check that there is any devices let count = getDeviceCount() if count < 1 { print("There is not R820 tunner found on this machine") exit(0) } //check that argument index is withing range if (args.device_idx < 0) || (args.device_idx > count-1) { print("Index is out of range, devices found \(count)") exit(0) } //initialise structure without a connected driver let device = R820Tuner() device.open(index: UInt32(args.device_idx)) //prepare dongle to receive some data let _ = device.setSampleRate(samplerate: UInt32(args.samplerate)) let _ = device.setCenterFreq(freq: UInt32(args.frequency)) if args.gain == 0 { let _ = device.setAgcMode(on: 1) } else { let _ = device.setTunerGain(gain: Int32(args.gain)) } let _ = device.resetBuffer() //prepare file descriptor if args specify that let currentExePath = Process().currentDirectoryPath var fileDescriptor = FileManager.default var fileArgUrl:URL? var fileHandle:FileHandle? if args.file != "" { fileArgUrl = URL(fileURLWithFileSystemRepresentation: args.file, isDirectory: false, relativeTo: nil) if (checkIfFileExists(args.file)) { //remove file do { try fileDescriptor.removeItem(atPath: fileArgUrl!.path()) } catch { print("Couldn't delete file that exists \(fileArgUrl!.path())") } } //create file fileDescriptor.createFile(atPath: fileArgUrl!.path(), contents: nil) try fileHandle = FileHandle(forWritingTo: fileArgUrl!) try fileHandle?.seekToEnd() } //prepare loop buffers to process data let buf_ptr = UnsafeMutableRawPointer.allocate(byteCount: NUM_SAMPLES, alignment: 1) var nbytes:Int32 = 0 var total_bytes:Int32 = 0 if (args.async == false) { while (total_bytes < args.nsamples) { let ret = device.readSync(buf: buf_ptr, len: Int32(NUM_SAMPLES), n_read: &nbytes) if ret<0 { print("data read sync returned <0 = \(ret)") break; } print("Reading samples read \(nbytes) bytes") total_bytes += nbytes let dataU8 = buf_ptr.bindMemory(to: UInt8.self, capacity: NUM_SAMPLES) let bufferU8 = UnsafeBufferPointer(start: dataU8, count: NUM_SAMPLES) let convertedData = Data(bufferU8) /*for i in 0..