pothosware / SoapySDR

Vendor and platform neutral SDR support library.
https://github.com/pothosware/SoapySDR/wiki
Boost Software License 1.0
1.09k stars 176 forks source link

Using timeStamps to control the data flow #398

Closed lamasJose closed 1 year ago

lamasJose commented 1 year ago

Hello, I hope someone can help here. I have a python script based on the python example of the repository. I modified it a bit to open a stream of x seconds and save the samples in a file. The problem is that each time I call the function readStream I think I reading the same samples again and again, but I need to read the samples coming of the stream continuously, without interruption. I saw some examples of how you can control this using the parameter timeNs of the function, but all of the examples are in c++, and I dont know how to use the timestamps in python. This is my script:

import SoapySDR from SoapySDR import * #SOAPYSDR constants import numpy #use numpy for buffers import sys import time

setParameters

filename = str(sys.argv[1]) mode = str(sys.argv[2]) samplingFreq = float(sys.argv[3]) streamTime = float(sys.argv[4]) carrierFreq = float(sys.argv[5])

enumerate devices

results = SoapySDR.Device.enumerate() for result in results: print(result)

create device instance

sdr = SoapySDR.Device.make()

query device info

freqs = sdr.getFrequencyRange(SOAPY_SDR_RX, 0)

apply settings

sdr.setSampleRate(SOAPY_SDR_RX, 0, samplingFreq) sdr.setFrequency(SOAPY_SDR_RX, 0, carrierFreq)

setup a stream (complex floats)

rxStream = sdr.setupStream(SOAPY_SDR_RX, mode) sdr.activateStream(rxStream) #start streaming

create a re-usable buffer for rx samples

buff = numpy.array([0] * 1024, numpy.complex64)

receive some samples

data = [] samplesReceived = 0 end_time = time.time() + streamTime

while time.time() < end_time: sr = sdr.readStream(rxStream, [buff], len(buff)) timeStamp = sr.timeNs # get timestamp samplesReceived = samplesReceived + sr.ret data.append(buff)

data = numpy.concatenate(data) data.tofile(filename) print(samplesReceived)

shutdown the stream

sdr.deactivateStream(rxStream) #stop streaming sdr.closeStream(rxStream)

zuckschwerdt commented 1 year ago

You need to check sr.ret -- it is the number of samples actually read into you buffer. If it is 0 your buffer will stay the same -- that is likely what you observed.

Why would you get 0 samples read? If you are reading too fast there are no new samples to copy.

Also no sample will ever be delivered twice, it's just that you kept them in your buffer and blindly used data.append(buff). Better to just extend/copy with buff[..sr.ret] -- but only if sr.ret > 0

lamasJose commented 1 year ago

Thanks for que quick response. Now, I see how this fix the problem of watching the same samples, but not the problem of the data flow.

What I refer with data flow is for example: If in the first iteration are read the first 50 samples of the stream, in the second iteration I want to read the next 50 samples that the SDR received.

Maybe it is that Im not understanding how SoapySDR works but I checked and it seems that readStream returns what is streaming in the very moment and not the full streaming in the correct order.

zuckschwerdt commented 1 year ago

readStream() is buffered. It always reads the exact next samples, not "a this moment sample". There is usually no gap. You need to read fast otherwise things will break. Do no read 50 samples. read much bigger buffers like 1024 or other powers of 2.