Re: NEW: comms/soapy-rtlsdr

SASANO Takayoshi <[email protected]> Fri, 31 Jul 2026 20:48:55 +0900
Newsgroups gmane.os.openbsd.ports
Message-ID <[email protected]>
Hello,

I tried CubicSDR with SoapyRTLSDR.
It looks working but stucks when frequency is changed.

Due to libusb's issue, rtlsdr_read_async() does not work well on OpenBSD.
This affects rtl_tcp of comms/rtl-sdr and comms/soapy-rtlsdr,
Airspy's SDR# (on Windows) with rtl_tcp (on OpenBSD) have same trouble.

For testing, I rewrited rtl_tcp code with rtlsdr_read_sync().
This is avaiable at https://github.com/jg1uaa/rtl_tcp_sync and
I think this have enough performance.

So, I did same thing for SoapyRTLSDR with rtlsdr_read_sync().
If this works well, can I commit it?
-- 
SASANO Takayoshi (JG1UAA) <[email protected]>

Index: Makefile
===================================================================
RCS file: /cvs/ports/comms/soapy-rtlsdr/Makefile,v
diff -u -p -r1.1.1.1 Makefile
--- Makefile	29 May 2026 20:15:45 -0000	1.1.1.1
+++ Makefile	31 Jul 2026 11:35:16 -0000
@@ -1,6 +1,7 @@
 COMMENT =		Soapy SDR plugin for RTL-SDR
 
 V =			0.3.3
+REVISION =		0
 GH_ACCOUNT =		pothosware
 GH_PROJECT =		SoapyRTLSDR
 GH_COMMIT =		b1f568d1b57cc973a1d2ee49be68d0d748d164e4
Index: patches/patch-SoapyRTLSDR_hpp
===================================================================
RCS file: patches/patch-SoapyRTLSDR_hpp
diff -N patches/patch-SoapyRTLSDR_hpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-SoapyRTLSDR_hpp	31 Jul 2026 11:35:16 -0000
@@ -0,0 +1,16 @@
+--- SoapyRTLSDR.hpp.orig	Mon Aug 25 17:45:34 2025
++++ SoapyRTLSDR.hpp	Fri Jul 31 20:18:53 2026
+@@ -264,9 +264,10 @@ class SoapyRTLSDR: public SoapySDR::Device (public)
+         std::vector<signed char> data;
+     };
+ 
+-    //async api usage
+-    std::thread _rx_async_thread;
+-    void rx_async_operation(void);
++    //sync api usage
++    std::atomic<bool> _rxRunning;
++    std::thread _rx_sync_thread;
++    void rx_sync_operation(void);
+     void rx_callback(unsigned char *buf, uint32_t len);
+ 
+     std::mutex _buf_mutex;
Index: patches/patch-Streaming_cpp
===================================================================
RCS file: patches/patch-Streaming_cpp
diff -N patches/patch-Streaming_cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-Streaming_cpp	31 Jul 2026 11:35:16 -0000
@@ -0,0 +1,75 @@
+--- Streaming.cpp.orig	Mon Aug 25 17:45:34 2025
++++ Streaming.cpp	Fri Jul 31 20:19:17 2026
+@@ -80,6 +80,7 @@ SoapySDR::ArgInfoList SoapyRTLSDR::getStreamArgsInfo(c
+ 
+     streamArgs.push_back(buffersArg);
+ 
++    // args for async no longer work, but kept for compatibility
+     SoapySDR::ArgInfo asyncbuffsArg;
+     asyncbuffsArg.key = "asyncBuffs";
+     asyncbuffsArg.value = "0";
+@@ -94,21 +95,23 @@ SoapySDR::ArgInfoList SoapyRTLSDR::getStreamArgsInfo(c
+ }
+ 
+ /*******************************************************************
+- * Async thread work
++ * Sync thread work
+  ******************************************************************/
+ 
+-static void _rx_callback(unsigned char *buf, uint32_t len, void *ctx)
++void SoapyRTLSDR::rx_sync_operation(void)
+ {
+-    //printf("_rx_callback\n");
+-    SoapyRTLSDR *self = (SoapyRTLSDR *)ctx;
+-    self->rx_callback(buf, len);
+-}
++    int rxSize;
++    unsigned char *rxBuf = new unsigned char[bufferLength];
+ 
+-void SoapyRTLSDR::rx_async_operation(void)
+-{
+-    //printf("rx_async_operation\n");
+-    rtlsdr_read_async(dev, &_rx_callback, this, asyncBuffs, bufferLength);
+-    //printf("rx_async_operation done!\n");
++    //printf("rx_sync_operation\n");
++    while (_rxRunning) {
++        if (rtlsdr_read_sync(dev, (void *)rxBuf, bufferLength, &rxSize) < 0)
++            break;
++        rx_callback(rxBuf, rxSize);
++    }
++    //printf("rx_sync_operation done!\n");
++
++    delete[] rxBuf;
+ }
+ 
+ void SoapyRTLSDR::rx_callback(unsigned char *buf, uint32_t len)
+@@ -316,11 +319,12 @@ int SoapyRTLSDR::activateStream(
+     resetBuffer = true;
+     bufferedElems = 0;
+ 
+-    //start the async thread
+-    if (not _rx_async_thread.joinable())
++    //start the sync thread
++    if (not _rx_sync_thread.joinable())
+     {
+         rtlsdr_reset_buffer(dev);
+-        _rx_async_thread = std::thread(&SoapyRTLSDR::rx_async_operation, this);
++        _rxRunning = true;
++        _rx_sync_thread = std::thread(&SoapyRTLSDR::rx_sync_operation, this);
+     }
+ 
+     return 0;
+@@ -329,10 +333,10 @@ int SoapyRTLSDR::activateStream(
+ int SoapyRTLSDR::deactivateStream(SoapySDR::Stream *stream, const int flags, const long long timeNs)
+ {
+     if (flags != 0) return SOAPY_SDR_NOT_SUPPORTED;
+-    if (_rx_async_thread.joinable())
++    if (_rx_sync_thread.joinable())
+     {
+-        rtlsdr_cancel_async(dev);
+-        _rx_async_thread.join();
++        _rxRunning = false;
++        _rx_sync_thread.join();
+     }
+     return 0;
+ }