diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 508f7073..85c13ceb 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -165,3 +165,26 @@ jobs: with: name: soapy-package path: SDDC_SOAPY.ZIP + + build-on-macos: + runs-on: macos-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + brew update + brew install soapysdr + brew install fftw + + - name: Build SoapySDR Module + run: | + mkdir -p build + cd build + cmake -DCMAKE_INSTALL_PREFIX=$(brew --prefix) .. + sudo make install + + - name: Check SoapySDR Installation + run: | + SoapySDRUtil --info diff --git a/Core/arch/linux/streaming.c b/Core/arch/linux/streaming.c index 7caba16b..fa3492d5 100644 --- a/Core/arch/linux/streaming.c +++ b/Core/arch/linux/streaming.c @@ -24,6 +24,7 @@ * - Ettus Research UHD libusb1_zero_copy.cpp: https://github.com/EttusResearch/uhd/blob/master/host/lib/transport/libusb1_zero_copy.cpp */ + #include #include #include @@ -62,7 +63,7 @@ typedef struct streaming { uint32_t sample_rate; uint32_t frame_size; uint32_t num_frames; - sddc_read_async_cb_t callback; + streaming_read_async_cb_t callback; void *callback_context; uint8_t **frames; struct libusb_transfer **transfers; @@ -108,7 +109,7 @@ int streaming_framesize(streaming_t *that) } streaming_t *streaming_open_async(usb_device_t *usb_device, uint32_t frame_size, - uint32_t num_frames, sddc_read_async_cb_t callback, + uint32_t num_frames, streaming_read_async_cb_t callback, void *callback_context) { streaming_t *ret_val = 0; @@ -128,7 +129,7 @@ streaming_t *streaming_open_async(usb_device_t *usb_device, uint32_t frame_size, } int iso_packets_per_frame = frame_size / usb_device->bulk_in_max_packet_size; - fprintf(stderr, "frame_size = %u, iso_packets_per_frame = %d\n", (unsigned)frame_size, iso_packets_per_frame); + // fprintf(stderr, "frame_size = %u, iso_packets_per_frame = %d\n", (unsigned)frame_size, iso_packets_per_frame); if (frame_size % max_xfer_size != 0) { fprintf(stderr, "frame size must be a multiple of %d\n", max_xfer_size); @@ -138,11 +139,20 @@ streaming_t *streaming_open_async(usb_device_t *usb_device, uint32_t frame_size, /* allocate frames for zerocopy USB bulk transfers */ uint8_t **frames = (uint8_t **) malloc(num_frames * sizeof(uint8_t *)); for (uint32_t i = 0; i < num_frames; ++i) { + #ifdef __linux__ frames[i] = libusb_dev_mem_alloc(usb_device->dev_handle, frame_size); + #elif defined(__APPLE__) + frames[i] = (uint8_t *) malloc(frame_size); + #endif + if (frames[i] == 0) { log_error("libusb_dev_mem_alloc() failed", __func__, __FILE__, __LINE__); for (uint32_t j = 0; j < i; j++) { + #ifdef __linux__ libusb_dev_mem_free(usb_device->dev_handle, frames[j], frame_size); + #elif defined(__APPLE__) + free(frames[j]); + #endif } return ret_val; } @@ -187,8 +197,12 @@ void streaming_close(streaming_t *this) } if (this->frames != 0) { for (uint32_t i = 0; i < this->num_frames; ++i) { + #ifdef __linux__ libusb_dev_mem_free(this->usb_device->dev_handle, this->frames[i], this->frame_size); + #elif defined(__APPLE__) + free(this->frames[i]); + #endif } free(this->frames); } @@ -254,17 +268,6 @@ int streaming_stop(streaming_t *this) } this->status = STREAMING_STATUS_CANCELLED; - /* cancel all the active transfers */ - for (uint32_t i = 0; i < this->num_frames; ++i) { - int ret = libusb_cancel_transfer(this->transfers[i]); - if (ret < 0) { - if (ret == LIBUSB_ERROR_NOT_FOUND) { - continue; - } - log_usb_error(ret, __func__, __FILE__, __LINE__); - this->status = STREAMING_STATUS_FAILED; - } - } /* flush all the events */ struct timeval noblock = { 0, 0 }; @@ -277,6 +280,19 @@ int streaming_stop(streaming_t *this) usleep(100); } + /* cancel all the active transfers */ + for (uint32_t i = 0; i < this->num_frames; ++i) { + int ret = libusb_cancel_transfer(this->transfers[i]); + if (ret < 0) { + if (ret == LIBUSB_ERROR_NOT_FOUND) { + continue; + } + log_usb_error(ret, __func__, __FILE__, __LINE__); + this->status = STREAMING_STATUS_FAILED; + } + } + + return 0; } diff --git a/Core/arch/linux/streaming.h b/Core/arch/linux/streaming.h index e0dd9135..ea676da1 100644 --- a/Core/arch/linux/streaming.h +++ b/Core/arch/linux/streaming.h @@ -31,14 +31,14 @@ extern "C" { typedef struct streaming streaming_t; -typedef void (*sddc_read_async_cb_t)(uint32_t data_size, uint8_t *data, +typedef void (*streaming_read_async_cb_t)(uint32_t data_size, uint8_t *data, void *context); streaming_t *streaming_open_sync(usb_device_t *usb_device); streaming_t *streaming_open_async(usb_device_t *usb_device, uint32_t frame_size, uint32_t num_frames, - sddc_read_async_cb_t callback, + streaming_read_async_cb_t callback, void *callback_context); void streaming_close(streaming_t *that); diff --git a/Core/fft_mt_r2iq.cpp b/Core/fft_mt_r2iq.cpp index 8dc7cc08..c3129051 100644 --- a/Core/fft_mt_r2iq.cpp +++ b/Core/fft_mt_r2iq.cpp @@ -227,8 +227,9 @@ void fft_mt_r2iq::Init(float gain, ringbuffer *input, ringbuffer #include #define cpuid(info, x) __cpuid_count(x, 0, info[0], info[1], info[2], info[3]) #define DETECT_AVX -#elif defined(__arm__) +#elif defined(__arm__) || defined(__aarch64__) #define DETECT_NEON + #if defined(__linux__) #include #include static bool detect_neon() @@ -236,6 +237,16 @@ void fft_mt_r2iq::Init(float gain, ringbuffer *input, ringbuffer unsigned long caps = getauxval(AT_HWCAP); return (caps & HWCAP_NEON); } + #elif defined(__APPLE__) + #include + static bool detect_neon() + { + int hasNeon = 0; + size_t len = sizeof(hasNeon); + sysctlbyname("hw.optional.neon", &hasNeon, &len, NULL, 0); + return hasNeon; + } + #endif #else #error Compiler does not identify an x86 or ARM core.. #endif diff --git a/Core/pffft/sse2neon.h b/Core/pffft/sse2neon.h index 20709e27..5f9de80e 100644 --- a/Core/pffft/sse2neon.h +++ b/Core/pffft/sse2neon.h @@ -1551,7 +1551,7 @@ FORCE_INLINE __m64 _mm_cvtps_pi8(__m128 a) __m128i res32 = _mm_or_si128(_mm_or_si128(max, min), cvt); int16x4_t res16 = vmovn_s32(vreinterpretq_s32_m128i(res32)); int8x8_t res8 = vmovn_s16(vcombine_s16(res16, res16)); - uint bitMask[2] = {0xFFFFFFFF, 0}; + unsigned int bitMask[2] = {static_cast(0xFFFFFFFF), 0}; int8x8_t mask = vreinterpret_s8_u32(vld1_u32(bitMask)); return vreinterpret_m64_s8(vorr_s8(vand_s8(mask, res8), vdup_n_s8(0)));