From abbe14bebb2935b017b980e6fc2bfc5e94052049 Mon Sep 17 00:00:00 2001 From: Arturs Artamonovs Date: Wed, 4 Dec 2024 11:07:17 +0000 Subject: AirSpyHFIQ: read samples from airspyhf and dump those to fc32 file --- Radio/Utils/AirSpyHFIQ/main.swift | 147 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 Radio/Utils/AirSpyHFIQ/main.swift (limited to 'Radio/Utils/AirSpyHFIQ') diff --git a/Radio/Utils/AirSpyHFIQ/main.swift b/Radio/Utils/AirSpyHFIQ/main.swift new file mode 100644 index 0000000..6fc7501 --- /dev/null +++ b/Radio/Utils/AirSpyHFIQ/main.swift @@ -0,0 +1,147 @@ +// +// main.swift +// AirSpyHFIQ +// +// Created by Jacky Jack on 02/12/2024. +// + +import Foundation +import ArgumentParser +import libairspyhf + +//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 = 192000 + @Option(name:.shortAndLong) var gain: Int = 0 + @Option(name:.shortAndLong) var frequency: Int = 100000000 + @Option(name:.shortAndLong) var nsamples: Int = 1024 + @Flag(help:"Version \(software_version)") var version: Bool = false + @Flag(name: .shortAndLong) var verbose: Bool = false +} + +let args = CommandLineArgs.parseOrExit() + +if (args.version) { + print("AirSpyHFIQ version \(software_version)") + exit(0) +} + +var libersion:airspyhf_lib_version_t = airspyhf_lib_version_t() + +airspyhf_lib_version(&libersion) +print("libairspyhf \(libersion.major_version).\(libersion.minor_version).\(libersion.revision)") + +let ndev = airspyhf_list_devices(nil, 0) +print("Found \(ndev) AirSpyHF devices") +if ndev < 0 { + exit(0) +} + +//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() +} + +//will try the first one first +var device:AirSpyHF? +do { + device = try AirSpyHF(idx: 0) +} catch { + print("Cant attach to device") +} + +let samplerates = device!.getSampleRates() +print(samplerates) + +if (!samplerates.contains(UInt32(args.samplerate))) { + print("Unsupported sample rate") + exit(0) +} + +//set sample rate +var fret:Int32 = -1 +fret = device!.setSampleRate(UInt32(args.samplerate)) +print("samplerate err=\(fret)") +fret = device!.setFreq(UInt32(args.frequency)) +print("setfreq err=\(fret)") +fret = device!.setHfAgc(1) +print("sethfagc err=\(fret)") +fret = device!.setHfAgcThreshold(0) +print("agcthreshold err=\(fret)") +fret = device!.setHfLNA(1) +print("hflna err=\(fret)") + +var sdr_run = true +var total_samples:Int32=0 +func rf_callback(_ transffer: UnsafeMutablePointer?) -> Int32 { + + let sample_count = transffer?.pointee.sample_count + let rx_bufffer = transffer?.pointee.samples + // samples are = float * IQ (I and Q) + let bytes_to_write = sample_count! * 4 * 2 + + total_samples += sample_count! + if total_samples > args.nsamples { + sdr_run = false + return 0 + } + + if let file = fileHandle { + let convertedData = Data(bytes: rx_bufffer!, count: Int(bytes_to_write)) + do { + try file.write(contentsOf: convertedData) + } catch { + print("Cant dump data to file") + } + } + + return 0 +} + +let _ = device!.start(rf_callback) + +let _ = device!.setFreq(UInt32(args.frequency)) + +var count=3 +var old_total:Int32=1 +while ((device!.isStreaming() == 1) && (sdr_run == true)) { + //print("Streaming ... total \(total_samples) bytes") + //check till the number of samples are written to file or aquired + sleep(1) + if (old_total == total_samples) { + count += 1 + } else { + count = 0 + } + old_total = total_samples + if (count > 10) { + break + } +} + +let _ = device!.stop() + +print("Closing device. Read \(total_samples) samples") +device!.close() + + + -- cgit v1.2.3