Closed mbaz closed 3 years ago
Some other notes. This is fine looping for several minutes:
julia> using SoapySDR, SoapyRTLSDR_jll
julia> channel = Devices()[1].rx[1]
julia> stream = SoapySDR.Stream(ComplexF32, [channel])
julia> SoapySDR.activate!(stream)
Allocating 15 zero-copy buffers
julia> n = Int64(SoapySDR.SoapySDRDevice_getStreamMTU(stream.d, stream))
131072
julia> while true; Base.read(stream, n); end
But this fails almost immediately:
julia> while true; Base.read(stream, 1000); end
OERROR: OVERFLOW
Stacktrace:
[1] SoapySDRDevice_readStream(device::SoapySDR.Device, stream::SoapySDR.Stream{ComplexF32}, buffs::Base.RefValue{Tuple{Ptr{ComplexF32}}}, numElems::Int64, timeoutUs::Float64)
@ SoapySDR ~/.julia/dev/SoapySDR/src/lowlevel/Device.jl:493
[2] #_read!#15
@ ~/.julia/dev/SoapySDR/src/highlevel.jl:517 [inlined]
[3] _read!(s::SoapySDR.Stream{ComplexF32}, buffers::Tuple{Vector{ComplexF32}})
@ SoapySDR ~/.julia/dev/SoapySDR/src/highlevel.jl:513
[4] read(s::SoapySDR.Stream{ComplexF32}, n::Int64; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ SoapySDR ~/.julia/dev/SoapySDR/src/highlevel.jl:535
[5] read(s::SoapySDR.Stream{ComplexF32}, n::Int64)
@ SoapySDR ~/.julia/dev/SoapySDR/src/highlevel.jl:534
[6] top-level scope
@ ./REPL[7]:1
Okay so some further investigation. I think this is actually expected behavior. The stream is buffered in the SoapySDR layer, and read by us. If we don't read fast enough, it will throw the buffer overflow error. Wrapping in SoapySDR.activate!
and SoapySDR.deactivate!
calls fixes this issue, like so:
SoapySDR.activate!(stream); read(stream, 1000); SoapySDR.deactivate!(stream)
This should be documented and explained, so I will leave this open for further discussion and ideation.
Related: https://github.com/pothosware/SoapyAirspy/issues/10#issuecomment-247165980
It seems that the ideal number of samples to request is sdr.getStreamMTU(readStream)
. Is that function wrapped in SoapySDR.jll? I couldn't find it.
It is not handled at the highlevel API yet, but the following should work:
julia> stream = SoapySDR.Stream(ComplexF32, [channel])
julia> SoapySDR.activate!(stream)
julia> n = Int64(SoapySDR.SoapySDRDevice_getStreamMTU(stream.d, stream))
I think a reasonable solution here will be to use readavailable
to implicitly read the MTU amount.
I really appreciate the testing and bug reports. I should be able to get the High Level API modified and documented in the next couple days to avoid these issues.
FYI with #18 this becomes simply:
julia> stream = SoapySDR.Stream([channel])
julia> SoapySDR.activate!(stream)
julia> samples = read(stream)
So the MTU is now baked-in and a stream type is no longer needed, we use the native format supported by the device (multiple dispatch FTW!).
With #22 these error should not occur. Please comment and reopen if otherwise.
This seems to happen a few times (from 1 to maybe 10) after
activate!()
is called. Onceread
succeeds, it never seems to fail again.