diff options
author | Arturs Artamonovs <arturs.artamonovs@protonmail.com> | 2024-11-29 11:28:01 +0000 |
---|---|---|
committer | Arturs Artamonovs <arturs.artamonovs@protonmail.com> | 2024-11-29 11:28:01 +0000 |
commit | 23fc08c8798d7c325a72fbee4175813efe4fe70f (patch) | |
tree | 0521f11441d267e60f7b9aa574c0defd43148b45 /Radio | |
parent | 77d1cfc27fb72e442b8d8e5cbe2be143723724e5 (diff) | |
download | PrySDR-23fc08c8798d7c325a72fbee4175813efe4fe70f.tar.gz PrySDR-23fc08c8798d7c325a72fbee4175813efe4fe70f.zip |
RtlSdrIQ: can read samples from rtlsdr and dump those to file
Diffstat (limited to 'Radio')
-rw-r--r-- | Radio/HW/RtlSdr/r820/r820.swift | 9 | ||||
-rw-r--r-- | Radio/Utils/RtlSdrIQ/main.swift | 77 |
2 files changed, 76 insertions, 10 deletions
diff --git a/Radio/HW/RtlSdr/r820/r820.swift b/Radio/HW/RtlSdr/r820/r820.swift index 3f6d4a9..4c8859f 100644 --- a/Radio/HW/RtlSdr/r820/r820.swift +++ b/Radio/HW/RtlSdr/r820/r820.swift @@ -189,8 +189,13 @@ public class R820Tuner { /// - len: input buffer length /// - n_read: number of bytes received /// - Returns: -1 if there is no device, 0 on success or one of LIBUSB error - /// LIBUSB_ERROR_TIMEOUT, LIBUSB_ERROR_PIPE,LIBUSB_ERROR_OVERFLOW - /// LIBUSB_ERROR_NO_DEVICE, LIBUSB_ERROR_BUSY LIBUSB_ERROR_INVALID_PARAM + /// on success, the number of bytes actually transferred + /// LIBUSB_ERROR_TIMEOUT if the transfer timed out + /// LIBUSB_ERROR_PIPE if the control request was not supported by the device + /// LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + /// LIBUSB_ERROR_BUSY if called from event handling context + /// LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than the operating system and/or hardware can support (see Transfer length limitations) + /// another LIBUSB_ERROR code on other failures /// func readSync(buf:UnsafeMutableRawPointer?,len: Int32,n_read:UnsafeMutablePointer<Int32>?) -> Int32 { return rtlsdr_read_sync(dev, buf, len, n_read); diff --git a/Radio/Utils/RtlSdrIQ/main.swift b/Radio/Utils/RtlSdrIQ/main.swift index 20573a9..c3d5732 100644 --- a/Radio/Utils/RtlSdrIQ/main.swift +++ b/Radio/Utils/RtlSdrIQ/main.swift @@ -9,13 +9,15 @@ 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 frequency: Int = 100000000 @Option(name:.shortAndLong) var nsamples: Int = 1024 @Flag(name: .shortAndLong) var verbose: Bool = false @Flag(name: .shortAndLong) var async: Bool = false @@ -40,6 +42,7 @@ if (args.device_idx < 0) || (args.device_idx > count-1) { 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 { @@ -48,15 +51,73 @@ if args.gain == 0 { let _ = device.setTunerGain(gain: Int32(args.gain)) } let _ = device.resetBuffer() -let buf_ptr = UnsafeMutableRawPointer.allocate(byteCount: args.nsamples, alignment: 1) + +//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 -let r = device.readSync(buf: buf_ptr, len: Int32(args.nsamples), n_read: &nbytes) -print("Reading samples return code (\(r)) read \(nbytes) bytes\n") -for i in 0..<args.nsamples { - let offsetByte = buf_ptr + i - print("\(String(format:"%02hhX ",offsetByte.load(as: UInt8.self)))",terminator: "") +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..<Int(nbytes) { + let offsetByte = buf_ptr + i + print("\(String(format:"%02hhX ",offsetByte.load(as: UInt8.self)))",terminator: "") + }*/ + if (args.verbose) { + for i in 0..<bufferU8.count { + print("\(String(format: "%02hhX", bufferU8[i]))", terminator: "") + } + } + + //dump data to file + + if let file = fileHandle { + //print(convertedData) + do { + //try convertedData.write(to: fileUrl) + try file.write(contentsOf: convertedData) + } catch { + print("Cant dump data to file") + } + } + } +} else { + print("ASYNC not implemented") } -device.close() +//clean after use all structures +device.close() buf_ptr.deallocate() |