Re: NEW: comms/soapy-rtlsdr

Stuart Henderson <[email protected]> Fri, 31 Jul 2026 19:01:01 +0100
Newsgroups gmane.os.openbsd.ports
Message-ID <[email protected]>
On 2026/07/31 20:48, SASANO Takayoshi wrote:
> 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.

yes, there's a reason why I disabled the parts that required async in
the port of the earlier rtl-sdr versions...

> 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?

makes sense I think. (I can't test any of this now).

for rtl-sdr, perhaps it makes more sense to patch, rather than add
rtl_tcp_sync separately...


> -- 
> 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;
> + }
>