mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-04-04 18:48:38 -04:00
Initial experimental support for SoapySDR device input
This commit is contained in:
parent
7a01c436d6
commit
1918707304
147
CMakeLists.txt
147
CMakeLists.txt
@ -2,8 +2,8 @@ cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
SET(CUBICSDR_VERSION_MAJOR "0")
|
||||
SET(CUBICSDR_VERSION_MINOR "1")
|
||||
SET(CUBICSDR_VERSION_PATCH "6")
|
||||
SET(CUBICSDR_VERSION_REL "beta-issue140")
|
||||
SET(CUBICSDR_VERSION_PATCH "7")
|
||||
SET(CUBICSDR_VERSION_REL "beta-issue64")
|
||||
SET(CUBICSDR_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}-${CUBICSDR_VERSION_REL}")
|
||||
|
||||
SET(CPACK_PACKAGE_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}")
|
||||
@ -15,9 +15,9 @@ ADD_DEFINITIONS(
|
||||
-DCUBICSDR_VERSION="${CUBICSDR_VERSION}"
|
||||
)
|
||||
|
||||
IF (NOT APPLE)
|
||||
# IF (NOT APPLE)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
|
||||
ENDIF(NOT APPLE)
|
||||
# ENDIF(NOT APPLE)
|
||||
|
||||
|
||||
macro(configure_files srcDir destDir globStr)
|
||||
@ -80,11 +80,31 @@ SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR}/${EX_PLATFORM_NA
|
||||
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/${EX_PLATFORM_NAME})
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
IF (NOT WIN32)
|
||||
find_package(FFTW REQUIRED)
|
||||
find_package(Liquid REQUIRED)
|
||||
include_directories(${LIQUID_INCLUDES} ${FFTW_INCLUDES})
|
||||
SET(OTHER_LIBRARIES ${OTHER_LIBRARIES} ${LIQUID_LIBRARIES} ${FFTW_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
find_package(wxWidgets COMPONENTS gl core base REQUIRED)
|
||||
set(wxWidgets_CONFIGURATION mswu)
|
||||
include(${wxWidgets_USE_FILE})
|
||||
|
||||
SET(USE_SOAPY_SDR ON CACHE BOOL "Build with SoapySDR support instead of RTL-SDR.")
|
||||
IF (USE_SOAPY_SDR)
|
||||
find_package(SoapySDR NO_MODULE REQUIRED)
|
||||
include_directories(${SOAPY_SDR_INCLUDE_DIR})
|
||||
SET(OTHER_LIBRARIES ${SOAPY_SDR_LIBRARY} ${OTHER_LIBRARIES})
|
||||
ADD_DEFINITIONS(
|
||||
-DUSE_SOAPY_SDR=1
|
||||
)
|
||||
ELSE()
|
||||
SET(USE_RTL_SDR ON CACHE BOOL "Build with RTL-SDR support only.")
|
||||
ADD_DEFINITIONS(
|
||||
-DUSE_RTL_SDR=1
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF (WIN32)
|
||||
set(wxWidgets_USE_STATIC ON)
|
||||
@ -121,11 +141,16 @@ IF (WIN32)
|
||||
#ENDIF(USE_AUDIO_ASIO)
|
||||
|
||||
# FFTW
|
||||
include_directories ( ${PROJECT_SOURCE_DIR}/external/fftw-3.3.4 ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release )
|
||||
include_directories ( ${PROJECT_SOURCE_DIR}/external/fftw-3.3.4 )
|
||||
set(FFTW_LIB libfftw3f-3)
|
||||
|
||||
link_directories ( ${PROJECT_SOURCE_DIR}/external/fftw-3.3.4/${EX_PLATFORM} )
|
||||
configure_files(${PROJECT_SOURCE_DIR}/external/fftw-3.3.4/${EX_PLATFORM} ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} "*.dll")
|
||||
|
||||
IF(USE_RTL_SDR)
|
||||
include_directories( ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release )
|
||||
ENDIF()
|
||||
|
||||
include_directories ( ${PROJECT_SOURCE_DIR}/external/liquid-dsp/include )
|
||||
set(LIQUID_LIB libliquid)
|
||||
|
||||
@ -135,15 +160,19 @@ IF (WIN32)
|
||||
link_directories ( ${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM} )
|
||||
configure_files(${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM} ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME}/ "*.dll")
|
||||
# RTL-SDR
|
||||
link_directories ( ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/msvc/${EX_PLATFORM} )
|
||||
configure_files(${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/msvc/${EX_PLATFORM} ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} "*.dll")
|
||||
IF(USE_RTL_SDR)
|
||||
link_directories ( ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/msvc/${EX_PLATFORM} )
|
||||
configure_files(${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/msvc/${EX_PLATFORM} ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} "*.dll")
|
||||
ENDIF()
|
||||
ELSE (MSVC) # GCC
|
||||
# LIQUID
|
||||
link_directories ( ${PROJECT_SOURCE_DIR}/external/liquid-dsp/gcc/${EX_PLATFORM} )
|
||||
configure_files(${PROJECT_SOURCE_DIR}/external/liquid-dsp/gcc/${EX_PLATFORM} ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} "*.dll")
|
||||
# RTL-SDR
|
||||
link_directories ( ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/gcc/${EX_PLATFORM} )
|
||||
configure_files(${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/gcc/${EX_PLATFORM} ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} "*.dll")
|
||||
IF(USE_RTL_SDR)
|
||||
link_directories ( ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/gcc/${EX_PLATFORM} )
|
||||
configure_files(${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/gcc/${EX_PLATFORM} ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} "*.dll")
|
||||
ENDIF()
|
||||
ENDIF(MSVC)
|
||||
|
||||
# Copy DLL files to build dir
|
||||
@ -154,18 +183,20 @@ ENDIF (WIN32)
|
||||
IF (UNIX AND NOT APPLE)
|
||||
set(BUILD_DEB OFF CACHE BOOL "Build DEB")
|
||||
|
||||
set(RTLSDR_INCLUDE "/usr/local/include" CACHE FILEPATH "RTL-SDR Include Path")
|
||||
set(RTLSDR_LIB "/usr/local/lib" CACHE FILEPATH "RTL-SDR Lib Path")
|
||||
set(USE_AUDIO_PULSE ON CACHE BOOL "Use Pulse Audio")
|
||||
set(USE_AUDIO_JACK OFF CACHE BOOL "Use Jack Audio")
|
||||
set(USE_AUDIO_ALSA OFF CACHE BOOL "Use ALSA Audio")
|
||||
set(USE_AUDIO_OSS OFF CACHE BOOL "Use OSS Audio")
|
||||
include_directories(${RTLSDR_INCLUDE})
|
||||
link_directories(${RTLSDR_LIB})
|
||||
IF(USE_RTL_SDR)
|
||||
SET(RTLSDR_INCLUDE "/usr/local/include" CACHE FILEPATH "RTL-SDR Include Path")
|
||||
SET(RTLSDR_LIB "/usr/local/lib" CACHE FILEPATH "RTL-SDR Lib Path")
|
||||
include_directories(${RTLSDR_INCLUDE})
|
||||
link_directories(${RTLSDR_LIB})
|
||||
ENDIF()
|
||||
SET(USE_AUDIO_PULSE ON CACHE BOOL "Use Pulse Audio")
|
||||
SET(USE_AUDIO_JACK OFF CACHE BOOL "Use Jack Audio")
|
||||
SET(USE_AUDIO_ALSA OFF CACHE BOOL "Use ALSA Audio")
|
||||
SET(USE_AUDIO_OSS OFF CACHE BOOL "Use OSS Audio")
|
||||
|
||||
set(FFTW_LIB fftw3f)
|
||||
set(LIQUID_LIB liquid)
|
||||
set(OTHER_LIBRARIES dl)
|
||||
SET(FFTW_LIB fftw3f)
|
||||
SET(LIQUID_LIB liquid)
|
||||
SET(OTHER_LIBRARIES ${OTHER_LIBRARIES} dl)
|
||||
|
||||
IF(USE_AUDIO_PULSE)
|
||||
SET (OTHER_LIBRARIES ${OTHER_LIBRARIES} pulse-simple pulse)
|
||||
@ -203,21 +234,25 @@ ENDIF(USE_AUDIO_OSS)
|
||||
ENDIF(UNIX AND NOT APPLE)
|
||||
|
||||
IF (APPLE)
|
||||
set(RTLSDR_INCLUDE "/opt/local/include" CACHE FILEPATH "RTL-SDR Include Path")
|
||||
set(RTLSDR_LIB "/opt/local/lib" CACHE FILEPATH "RTL-SDR Lib Path")
|
||||
include_directories(${RTLSDR_INCLUDE})
|
||||
link_directories(${RTLSDR_LIB})
|
||||
set(LIB_DIRS "${LIB_DIRS} ${RTLSDR_LIB}")
|
||||
IF (USE_RTL_SDR)
|
||||
SET(RTLSDR_INCLUDE "/opt/local/include" CACHE FILEPATH "RTL-SDR Include Path")
|
||||
SET(RTLSDR_LIB "/opt/local/lib" CACHE FILEPATH "RTL-SDR Lib Path")
|
||||
include_directories(${RTLSDR_INCLUDE})
|
||||
link_directories(${RTLSDR_LIB})
|
||||
SET(LIB_DIRS ${LIB_DIRS} ${RTLSDR_LIB})
|
||||
ENDIF()
|
||||
|
||||
set(FFTW_LIB fftw3f)
|
||||
set(LIQUID_LIB liquid)
|
||||
SET(FFTW_LIB fftw3f)
|
||||
SET(LIQUID_LIB liquid)
|
||||
link_directories(/usr/local/lib)
|
||||
link_directories(/opt/local/lib)
|
||||
|
||||
ADD_DEFINITIONS(
|
||||
-D__MACOSX_CORE__
|
||||
)
|
||||
|
||||
FIND_LIBRARY(COREAUDIO_LIBRARY CoreAudio)
|
||||
SET (OTHER_LIBRARIES ${COREAUDIO_LIBRARY})
|
||||
SET (OTHER_LIBRARIES ${COREAUDIO_LIBRARY} ${OTHER_LIBRARIES})
|
||||
set(BUNDLE_APP OFF CACHE BOOL "Bundle Application")
|
||||
|
||||
ENDIF (APPLE)
|
||||
@ -230,7 +265,6 @@ SET (cubicsdr_sources
|
||||
src/FrequencyDialog.cpp
|
||||
src/IOThread.cpp
|
||||
src/sdr/SDRDeviceInfo.cpp
|
||||
src/sdr/SDRThread.cpp
|
||||
src/sdr/SDRPostThread.cpp
|
||||
src/demod/DemodulatorPreThread.cpp
|
||||
src/demod/DemodulatorThread.cpp
|
||||
@ -284,7 +318,6 @@ SET (cubicsdr_headers
|
||||
src/FrequencyDialog.h
|
||||
src/IOThread.h
|
||||
src/sdr/SDRDeviceInfo.h
|
||||
src/sdr/SDRThread.h
|
||||
src/sdr/SDRPostThread.h
|
||||
src/demod/DemodulatorPreThread.h
|
||||
src/demod/DemodulatorThread.h
|
||||
@ -347,6 +380,16 @@ SET (cubicsdr_headers
|
||||
external/cubicvr2/math/vec4.h
|
||||
)
|
||||
|
||||
|
||||
IF (USE_SOAPY_SDR)
|
||||
SET(cubicsdr_sources ${cubicsdr_sources} src/SDR/SoapySDRThread.cpp)
|
||||
SET(cubicsdr_headers ${cubicsdr_headers} src/SDR/SoapySDRThread.h)
|
||||
ELSE()
|
||||
SET(cubicsdr_sources ${cubicsdr_sources} src/SDR/SDRThread.cpp)
|
||||
SET(cubicsdr_headers ${cubicsdr_headers} src/SDR/SDRThread.h)
|
||||
ENDIF()
|
||||
|
||||
|
||||
set(REG_EXT "[^/]*([.]cpp|[.]c|[.]h|[.]hpp)$")
|
||||
|
||||
SOURCE_GROUP("Base" REGULAR_EXPRESSION src/${REG_EXT})
|
||||
@ -410,7 +453,10 @@ IF (NOT BUNDLE_APP)
|
||||
configure_files(${PROJECT_SOURCE_DIR}/font ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} "*.png")
|
||||
configure_files(${PROJECT_SOURCE_DIR}/icon ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} CubicSDR.ico)
|
||||
add_executable(CubicSDR ${cubicsdr_sources} ${cubicsdr_headers} ${RES_FILES})
|
||||
target_link_libraries(CubicSDR rtlsdr ${LIQUID_LIB} ${FFTW_LIB} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${OTHER_LIBRARIES})
|
||||
IF (USE_RTL_SDR)
|
||||
SET(OTHER_LIBRARIES rtlsdr ${OTHER_LIBRARIES})
|
||||
ENDIF()
|
||||
target_link_libraries(CubicSDR ${LIQUID_LIB} ${FFTW_LIB} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${OTHER_LIBRARIES})
|
||||
ENDIF (NOT BUNDLE_APP)
|
||||
|
||||
IF (MSVC)
|
||||
@ -479,7 +525,11 @@ IF (APPLE AND BUNDLE_APP)
|
||||
MACOSX_PACKAGE_LOCATION Resources
|
||||
)
|
||||
|
||||
target_link_libraries(CubicSDR rtlsdr ${LIQUID_LIB} ${FFTW_LIB} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${OTHER_LIBRARIES})
|
||||
IF (USE_RTL_SDR)
|
||||
SET(OTHER_LIBRARIES rtlsdr ${OTHER_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
target_link_libraries(CubicSDR ${LIQUID_LIB} ${FFTW_LIB} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${OTHER_LIBRARIES})
|
||||
SET_TARGET_PROPERTIES(CubicSDR PROPERTIES MACOSX_BUNDLE TRUE)
|
||||
|
||||
SET_TARGET_PROPERTIES(CubicSDR PROPERTIES
|
||||
@ -498,7 +548,7 @@ IF (APPLE AND BUNDLE_APP)
|
||||
INSTALL(CODE "
|
||||
SET(BU_COPY_FULL_FRAMEWORK_CONTENTS ON)
|
||||
include(BundleUtilities)
|
||||
fixup_bundle(\"${APPS}\" \"\" \"${RTLSDR_LIB}\")
|
||||
fixup_bundle(\"${APPS}\" \"\" \"/usr/local/lib\")
|
||||
VERIFY_APP(\"${APPS}\")
|
||||
" COMPONENT Runtime)
|
||||
|
||||
@ -550,17 +600,23 @@ IF (WIN32 AND BUILD_INSTALLER)
|
||||
${PROJECT_SOURCE_DIR}/external/fftw-3.3.4/${EX_PLATFORM}/libfftw3f-3.dll
|
||||
DESTINATION .)
|
||||
IF (MSVC)
|
||||
install(FILES
|
||||
${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM}/libliquid.dll
|
||||
${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/msvc/${EX_PLATFORM}/rtlsdr.dll
|
||||
${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/msvc/${EX_PLATFORM}/libusb-1.0.dll
|
||||
DESTINATION .)
|
||||
IF (USE_RTL_SDR)
|
||||
SET (OTHER_INSTALL_FILES ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/msvc/${EX_PLATFORM}/rtlsdr.dll)
|
||||
ENDIF()
|
||||
install(FILES
|
||||
${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM}/libliquid.dll
|
||||
${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/msvc/${EX_PLATFORM}/libusb-1.0.dll
|
||||
${OTHER_INSTALL_FILES}
|
||||
DESTINATION .)
|
||||
ELSE (MSVC)
|
||||
install(FILES
|
||||
${PROJECT_SOURCE_DIR}/external/liquid-dsp/gcc/${EX_PLATFORM}/libliquid.dll
|
||||
${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/gcc/${EX_PLATFORM}/librtlsdr.dll
|
||||
${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/gcc/${EX_PLATFORM}/libusb-1.0.dll
|
||||
DESTINATION .)
|
||||
IF (USE_RTL_SDR)
|
||||
SET (OTHER_INSTALL_FILES ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/gcc/${EX_PLATFORM}/librtlsdr.dll)
|
||||
ENDIF()
|
||||
install(FILES
|
||||
${PROJECT_SOURCE_DIR}/external/liquid-dsp/gcc/${EX_PLATFORM}/libliquid.dll
|
||||
${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/gcc/${EX_PLATFORM}/libusb-1.0.dll
|
||||
${OTHER_INSTALL_FILES}
|
||||
DESTINATION .)
|
||||
ENDIF(MSVC)
|
||||
|
||||
IF(MSVC AND EX_PLATFORM EQUAL 32)
|
||||
@ -585,7 +641,10 @@ IF (UNIX AND BUILD_DEB)
|
||||
|
||||
set(CPACK_GENERATOR DEB)
|
||||
set(CPACK_PACKAGE_NAME "CubicSDR")
|
||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS " librtlsdr0, libfftw3-single3, libwxgtk3.0-0, libpulse0")
|
||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS " libfftw3-single3, libwxgtk3.0-0, libpulse0")
|
||||
IF (USE_RTL_SDR)
|
||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS " librtlsdr0, ${CPACK_DEBIAN_PACKAGE_DEPENDS}")
|
||||
ENDIF()
|
||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Charles J. Cliffe <cj@cubicproductions.com>")
|
||||
SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION "CubicSDR Software Defined Radio application v${CUBICSDR_VERSION}")
|
||||
SET(CPACK_DEBIAN_PACKAGE_SECTION "comm")
|
||||
|
22
cmake/Modules/FindFFTW.cmake
Normal file
22
cmake/Modules/FindFFTW.cmake
Normal file
@ -0,0 +1,22 @@
|
||||
# - Find FFTW
|
||||
# Find the native FFTW includes and library
|
||||
#
|
||||
# FFTW_INCLUDES - where to find fftw3.h
|
||||
# FFTW_LIBRARIES - List of libraries when using FFTW.
|
||||
# FFTW_FOUND - True if FFTW found.
|
||||
|
||||
if (FFTW_INCLUDES)
|
||||
# Already in cache, be silent
|
||||
set (FFTW_FIND_QUIETLY TRUE)
|
||||
endif (FFTW_INCLUDES)
|
||||
|
||||
find_path (FFTW_INCLUDES fftw3.h)
|
||||
|
||||
find_library (FFTW_LIBRARIES NAMES fftw3)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set FFTW_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (FFTW DEFAULT_MSG FFTW_LIBRARIES FFTW_INCLUDES)
|
||||
|
||||
mark_as_advanced (FFTW_LIBRARIES FFTW_INCLUDES)
|
22
cmake/Modules/FindLiquid.cmake
Normal file
22
cmake/Modules/FindLiquid.cmake
Normal file
@ -0,0 +1,22 @@
|
||||
# - Find LIQUID
|
||||
# Find the native LIQUID includes and library
|
||||
#
|
||||
# LIQUID_INCLUDES - where to find LIQUID3.h
|
||||
# LIQUID_LIBRARIES - List of libraries when using LIQUID.
|
||||
# LIQUID_FOUND - True if LIQUID found.
|
||||
|
||||
if (LIQUID_INCLUDES)
|
||||
# Already in cache, be silent
|
||||
set (LIQUID_FIND_QUIETLY TRUE)
|
||||
endif (LIQUID_INCLUDES)
|
||||
|
||||
find_path (LIQUID_INCLUDES liquid/liquid.h)
|
||||
|
||||
find_library (LIQUID_LIBRARIES NAMES liquid)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set LIQUID_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (LIQUID DEFAULT_MSG LIQUID_LIBRARIES LIQUID_INCLUDES)
|
||||
|
||||
mark_as_advanced (LIQUID_LIBRARIES LIQUID_INCLUDES)
|
@ -14,7 +14,6 @@
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include "SDRThread.h"
|
||||
#include "DemodulatorMgr.h"
|
||||
#include "AudioThread.h"
|
||||
#include "CubicSDR.h"
|
||||
@ -284,6 +283,7 @@ AppFrame::AppFrame() :
|
||||
sampleRateMenuItems[wxID_BANDWIDTH_2880M] = menu->AppendRadioItem(wxID_BANDWIDTH_2880M, "2.88M");
|
||||
// sampleRateMenuItems[wxID_BANDWIDTH_3000M] = menu->AppendRadioItem(wxID_BANDWIDTH_3000M, "3.0M");
|
||||
sampleRateMenuItems[wxID_BANDWIDTH_3200M] = menu->AppendRadioItem(wxID_BANDWIDTH_3200M, "3.2M");
|
||||
sampleRateMenuItems[wxID_BANDWIDTH_MANUAL] = menu->AppendRadioItem(wxID_BANDWIDTH_MANUAL, "Manual Entry");
|
||||
|
||||
sampleRateMenuItems[wxID_BANDWIDTH_2400M]->Check(true);
|
||||
|
||||
@ -584,6 +584,12 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
case wxID_BANDWIDTH_3200M:
|
||||
wxGetApp().setSampleRate(3200000);
|
||||
break;
|
||||
case wxID_BANDWIDTH_MANUAL:
|
||||
long bw = wxGetNumberFromUser("Set the bandwidth manually", "Sample Rate (Hz), i.e. 2560000 for 2.56M", "Manual Bandwidth Entry", wxGetApp().getSampleRate(), 250000, 16000000, this);
|
||||
if (bw != -1) {
|
||||
wxGetApp().setSampleRate(bw);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
std::vector<SDRDeviceInfo *> *devs = wxGetApp().getDevices();
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define wxID_BANDWIDTH_2880M 2161
|
||||
//#define wxID_BANDWIDTH_3000M 2162
|
||||
#define wxID_BANDWIDTH_3200M 2163
|
||||
#define wxID_BANDWIDTH_MANUAL 2164
|
||||
|
||||
#define wxID_DEVICE_ID 3500
|
||||
|
||||
|
@ -97,19 +97,20 @@ bool CubicSDR::OnInit() {
|
||||
|
||||
std::vector<SDRDeviceInfo *>::iterator devs_i;
|
||||
|
||||
SDRThread::enumerate_rtl(&devs);
|
||||
// SDRThread::enumerate_rtl(&devs);
|
||||
devs = SDRThread::enumerate_devices();
|
||||
SDRDeviceInfo *dev = NULL;
|
||||
|
||||
if (devs.size() > 1) {
|
||||
if (devs->size() > 1) {
|
||||
wxArrayString choices;
|
||||
for (devs_i = devs.begin(); devs_i != devs.end(); devs_i++) {
|
||||
for (devs_i = devs->begin(); devs_i != devs->end(); devs_i++) {
|
||||
std::string devName = (*devs_i)->getName();
|
||||
if ((*devs_i)->isAvailable()) {
|
||||
devName.append(": ");
|
||||
devName.append((*devs_i)->getProduct());
|
||||
devName.append(" [");
|
||||
devName.append((*devs_i)->getSerial());
|
||||
devName.append("]");
|
||||
// devName.append(": ");
|
||||
// devName.append((*devs_i)->getProduct());
|
||||
// devName.append(" [");
|
||||
// devName.append((*devs_i)->getSerial());
|
||||
// devName.append("]");
|
||||
} else {
|
||||
devName.append(" (In Use?)");
|
||||
}
|
||||
@ -121,11 +122,11 @@ bool CubicSDR::OnInit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
dev = devs[devId];
|
||||
dev = (*devs)[devId];
|
||||
|
||||
sdrThread->setDeviceId(devId);
|
||||
} else if (devs.size() == 1) {
|
||||
dev = devs[0];
|
||||
} else if (devs->size() == 1) {
|
||||
dev = (*devs)[0];
|
||||
}
|
||||
|
||||
if (!dev) {
|
||||
@ -347,7 +348,7 @@ void CubicSDR::removeDemodulator(DemodulatorInstance *demod) {
|
||||
}
|
||||
|
||||
std::vector<SDRDeviceInfo*>* CubicSDR::getDevices() {
|
||||
return &devs;
|
||||
return devs;
|
||||
}
|
||||
|
||||
void CubicSDR::setDevice(int deviceId) {
|
||||
|
@ -10,7 +10,11 @@
|
||||
#include "PrimaryGLContext.h"
|
||||
|
||||
#include "ThreadQueue.h"
|
||||
#include "SDRThread.h"
|
||||
#ifdef USE_RTL_SDR
|
||||
#include "SDRThread.h"
|
||||
#else
|
||||
#include "SoapySDRThread.h"
|
||||
#endif
|
||||
#include "SDRPostThread.h"
|
||||
#include "AudioThread.h"
|
||||
#include "DemodulatorMgr.h"
|
||||
@ -86,7 +90,7 @@ private:
|
||||
AppFrame *appframe;
|
||||
AppConfig config;
|
||||
PrimaryGLContext *m_glContext;
|
||||
std::vector<SDRDeviceInfo *> devs;
|
||||
std::vector<SDRDeviceInfo *> *devs;
|
||||
|
||||
DemodulatorMgr demodMgr;
|
||||
|
||||
|
@ -1,6 +1,64 @@
|
||||
#include "SDRDeviceInfo.h"
|
||||
|
||||
|
||||
int SDRDeviceChannel::getChannel() const {
|
||||
return channel;
|
||||
}
|
||||
|
||||
void SDRDeviceChannel::setChannel(const int channel) {
|
||||
this->channel = channel;
|
||||
}
|
||||
|
||||
bool SDRDeviceChannel::isFullDuplex() {
|
||||
return fullDuplex;
|
||||
}
|
||||
|
||||
void SDRDeviceChannel::setFullDuplex(bool fullDuplex) {
|
||||
this->fullDuplex = fullDuplex;
|
||||
}
|
||||
|
||||
bool SDRDeviceChannel::isTx() {
|
||||
return tx;
|
||||
}
|
||||
|
||||
void SDRDeviceChannel::setTx(bool tx) {
|
||||
this->tx = tx;
|
||||
}
|
||||
|
||||
bool SDRDeviceChannel::isRx() {
|
||||
return rx;
|
||||
}
|
||||
|
||||
void SDRDeviceChannel::setRx(bool rx) {
|
||||
this->rx = rx;
|
||||
}
|
||||
|
||||
const SDRDeviceRange &SDRDeviceChannel::getGain() const {
|
||||
return rangeGain;
|
||||
}
|
||||
|
||||
const SDRDeviceRange &SDRDeviceChannel::getLNAGain() const {
|
||||
return rangeLNA;
|
||||
}
|
||||
|
||||
const SDRDeviceRange &SDRDeviceChannel::getFreqRange() const {
|
||||
return rangeFull;
|
||||
}
|
||||
|
||||
const SDRDeviceRange &SDRDeviceChannel::getRFRange() const {
|
||||
return rangeRF;
|
||||
}
|
||||
|
||||
const std::vector<long long> &SDRDeviceChannel::getSampleRates() const {
|
||||
return sampleRates;
|
||||
}
|
||||
|
||||
const std::vector<long long> &SDRDeviceChannel::getFilterBandwidths() const {
|
||||
return filterBandwidths;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SDRDeviceInfo::SDRDeviceInfo() : name(""), serial(""), available(false) {
|
||||
|
||||
}
|
||||
@ -9,12 +67,20 @@ std::string SDRDeviceInfo::getDeviceId() {
|
||||
std::string deviceId;
|
||||
|
||||
deviceId.append(getName());
|
||||
deviceId.append(" :: ");
|
||||
deviceId.append(getSerial());
|
||||
// deviceId.append(" :: ");
|
||||
// deviceId.append(getSerial());
|
||||
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
const int SDRDeviceInfo::getIndex() const {
|
||||
return index;
|
||||
}
|
||||
|
||||
void SDRDeviceInfo::setIndex(const int index) {
|
||||
this->index = index;
|
||||
}
|
||||
|
||||
bool SDRDeviceInfo::isAvailable() const {
|
||||
return available;
|
||||
}
|
||||
@ -63,3 +129,31 @@ void SDRDeviceInfo::setProduct(const std::string& product) {
|
||||
this->product = product;
|
||||
}
|
||||
|
||||
const std::string& SDRDeviceInfo::getDriver() const {
|
||||
return driver;
|
||||
}
|
||||
|
||||
void SDRDeviceInfo::setDriver(const std::string& driver) {
|
||||
this->driver = driver;
|
||||
}
|
||||
|
||||
const std::string& SDRDeviceInfo::getHardware() const {
|
||||
return hardware;
|
||||
}
|
||||
|
||||
void SDRDeviceInfo::setHardware(const std::string& hardware) {
|
||||
this->hardware = hardware;
|
||||
}
|
||||
|
||||
bool SDRDeviceInfo::hasTimestamps() const {
|
||||
return timestamps;
|
||||
}
|
||||
|
||||
void SDRDeviceInfo::setTimestamps(bool timestamps) {
|
||||
this->timestamps = timestamps;
|
||||
}
|
||||
|
||||
std::string SDRDeviceInfo::getDeviceArgs() {
|
||||
return "driver=" + driver;
|
||||
//+ "," + getDriver() + "=" + std::to_string(getIndex());
|
||||
}
|
||||
|
@ -1,6 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
----------------------------------------------------
|
||||
-- Device identification
|
||||
----------------------------------------------------
|
||||
driver=rtl
|
||||
hardware=rtl
|
||||
|
||||
----------------------------------------------------
|
||||
-- Peripheral summary
|
||||
----------------------------------------------------
|
||||
Channels: 1 Rx, 0 Tx
|
||||
Timestamps: NO
|
||||
|
||||
----------------------------------------------------
|
||||
-- RX Channel 0
|
||||
----------------------------------------------------
|
||||
Full-duplex: YES
|
||||
Antennas: RX
|
||||
Full gain range: [0, 49.6] dB
|
||||
LNA gain range: [0, 49.6] dB
|
||||
Full freq range: [24, 1766] MHz
|
||||
RF freq range: [24, 1766] MHz
|
||||
CORR freq range: MHz
|
||||
Sample rates: [0.25, 2.56] MHz
|
||||
Filter bandwidths: [] MHz
|
||||
*/
|
||||
|
||||
class SDRDeviceRange {
|
||||
public:
|
||||
SDRDeviceRange(float low, float high);
|
||||
|
||||
float getLow() const;
|
||||
void setLow(const float low);
|
||||
float getHigh() const;
|
||||
void setHigh(const float high);
|
||||
|
||||
private:
|
||||
float low, high;
|
||||
};
|
||||
|
||||
class SDRDeviceChannel {
|
||||
int getChannel() const;
|
||||
void setChannel(const int channel);
|
||||
|
||||
bool isFullDuplex();
|
||||
void setFullDuplex(bool fullDuplex);
|
||||
|
||||
bool isTx();
|
||||
void setTx(bool tx);
|
||||
|
||||
bool isRx();
|
||||
void setRx(bool rx);
|
||||
|
||||
const SDRDeviceRange &getGain() const;
|
||||
const SDRDeviceRange &getLNAGain() const;
|
||||
const SDRDeviceRange &getFreqRange() const;
|
||||
const SDRDeviceRange &getRFRange() const;
|
||||
|
||||
const std::vector<long long> &getSampleRates() const;
|
||||
const std::vector<long long> &getFilterBandwidths() const;
|
||||
|
||||
private:
|
||||
int channel;
|
||||
bool fullDuplex, tx, rx;
|
||||
SDRDeviceRange rangeGain, rangeLNA, rangeFull, rangeRF;
|
||||
std::vector<long long> sampleRates;
|
||||
std::vector<long long> filterBandwidths;
|
||||
};
|
||||
|
||||
|
||||
class SDRDeviceInfo {
|
||||
public:
|
||||
@ -8,6 +79,9 @@ public:
|
||||
|
||||
std::string getDeviceId();
|
||||
|
||||
const int getIndex() const;
|
||||
void setIndex(const int index);
|
||||
|
||||
bool isAvailable() const;
|
||||
void setAvailable(bool available);
|
||||
|
||||
@ -25,12 +99,24 @@ public:
|
||||
|
||||
const std::string& getProduct() const;
|
||||
void setProduct(const std::string& product);
|
||||
|
||||
const std::string& getDriver() const;
|
||||
void setDriver(const std::string& driver);
|
||||
|
||||
const std::string& getHardware() const;
|
||||
void setHardware(const std::string& hardware);
|
||||
|
||||
bool hasTimestamps() const;
|
||||
void setTimestamps(bool timestamps);
|
||||
|
||||
const std::vector<SDRDeviceChannel>& getChannels() const;
|
||||
|
||||
std::string getDeviceArgs();
|
||||
private:
|
||||
std::string name;
|
||||
std::string serial;
|
||||
std::string product;
|
||||
std::string manufacturer;
|
||||
std::string tuner;
|
||||
bool available;
|
||||
int index;
|
||||
std::string name, serial, product, manufacturer, tuner;
|
||||
std::string driver, hardware;
|
||||
bool timestamps, available;
|
||||
|
||||
std::vector<SDRDeviceChannel> channels;
|
||||
};
|
||||
|
@ -96,16 +96,22 @@ void SDRPostThread::run() {
|
||||
fpData.resize(dataSize);
|
||||
dataOut.resize(dataSize);
|
||||
}
|
||||
|
||||
if (swapIQ) {
|
||||
for (int i = 0; i < dataSize; i++) {
|
||||
fpData[i] = _lut_swap[*((uint16_t*)&data_in->data[2*i])];
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < dataSize; i++) {
|
||||
fpData[i] = _lut[*((uint16_t*)&data_in->data[2*i])];
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < dataSize; i++) {
|
||||
fpData[i].real = data_in->data[i*2];
|
||||
fpData[i].imag = data_in->data[i*2+1];
|
||||
}
|
||||
|
||||
// if (swapIQ) {
|
||||
// for (int i = 0; i < dataSize; i++) {
|
||||
// fpData[i] = _lut_swap[*((uint16_t*)&data_in->data[2*i])];
|
||||
// }
|
||||
// } else {
|
||||
// for (int i = 0; i < dataSize; i++) {
|
||||
// fpData[i] = _lut[*((uint16_t*)&data_in->data[2*i])];
|
||||
// }
|
||||
// }
|
||||
|
||||
iirfilt_crcf_execute_block(dcFilter, &fpData[0], dataSize, &dataOut[0]);
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#if USE_RTL_SDR
|
||||
#include "SDRThread.h"
|
||||
#else
|
||||
#include "SoapySDRThread.h"
|
||||
#endif
|
||||
#include <algorithm>
|
||||
|
||||
class SDRPostThread : public IOThread {
|
||||
|
459
src/sdr/SoapySDRThread.cpp
Normal file
459
src/sdr/SoapySDRThread.cpp
Normal file
@ -0,0 +1,459 @@
|
||||
#include "SoapySDRThread.h"
|
||||
#include "CubicSDRDefs.h"
|
||||
#include <vector>
|
||||
#include "CubicSDR.h"
|
||||
#include <string>
|
||||
|
||||
#include <SoapySDR/Version.hpp>
|
||||
#include <SoapySDR/Modules.hpp>
|
||||
#include <SoapySDR/Registry.hpp>
|
||||
#include <SoapySDR/Device.hpp>
|
||||
|
||||
std::vector<std::string> SDRThread::factories;
|
||||
std::vector<std::string> SDRThread::modules;
|
||||
std::vector<SDRDeviceInfo *> SDRThread::devs;
|
||||
|
||||
|
||||
SDRThread::SDRThread() : IOThread() {
|
||||
offset.store(0);
|
||||
deviceId.store(-1);
|
||||
// dev = NULL;
|
||||
sampleRate.store(DEFAULT_SAMPLE_RATE);
|
||||
}
|
||||
|
||||
SDRThread::~SDRThread() {
|
||||
// rtlsdr_close(dev);
|
||||
}
|
||||
|
||||
|
||||
std::vector<SDRDeviceInfo *> *SDRThread::enumerate_devices() {
|
||||
|
||||
if (SDRThread::devs.size()) {
|
||||
return &SDRThread::devs;
|
||||
}
|
||||
|
||||
std::cout << "SoapySDR init.." << std::endl;
|
||||
std::cout << "\tAPI Version: v" << SoapySDR::getAPIVersion() << std::endl;
|
||||
std::cout << "\tABI Version: v" << SoapySDR::getABIVersion() << std::endl;
|
||||
std::cout << "\tInstall root: " << SoapySDR::getRootPath() << std::endl;
|
||||
|
||||
modules = SoapySDR::listModules();
|
||||
for (size_t i = 0; i < modules.size(); i++) {
|
||||
std::cout << "\tModule found: " << modules[i] << std::endl;
|
||||
}
|
||||
if (modules.empty()) {
|
||||
std::cout << "No modules found!" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "\tLoading modules... " << std::flush;
|
||||
SoapySDR::loadModules();
|
||||
std::cout << "done" << std::endl;
|
||||
|
||||
if (SDRThread::factories.size()) {
|
||||
SDRThread::factories.erase(SDRThread::factories.begin(), SDRThread::factories.end());
|
||||
}
|
||||
|
||||
std::cout << "\tAvailable factories...";
|
||||
SoapySDR::FindFunctions factories = SoapySDR::Registry::listFindFunctions();
|
||||
for (SoapySDR::FindFunctions::const_iterator it = factories.begin(); it != factories.end(); ++it) {
|
||||
if (it != factories.begin()) {
|
||||
std::cout << ", ";
|
||||
}
|
||||
std::cout << it->first;
|
||||
SDRThread::factories.push_back(it->first);
|
||||
}
|
||||
if (factories.empty()) {
|
||||
std::cout << "No factories found!" << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
|
||||
std::vector<SoapySDR::Kwargs> results = SoapySDR::Device::enumerate();
|
||||
std::map<std::string, int> deviceIndexes;
|
||||
|
||||
for (size_t i = 0; i < results.size(); i++) {
|
||||
std::cout << "Found device " << i << std::endl;
|
||||
SDRDeviceInfo *dev = new SDRDeviceInfo();
|
||||
for (SoapySDR::Kwargs::const_iterator it = results[i].begin(); it != results[i].end(); ++it) {
|
||||
std::cout << " " << it->first << " = " << it->second << std::endl;
|
||||
if (it->first == "driver") {
|
||||
dev->setDriver(it->second);
|
||||
} else if (it->first == "label") {
|
||||
dev->setName(it->second);
|
||||
}
|
||||
// else if (it->first == dev->getDriver()) {
|
||||
// dev->setIndex(std::stoi(it->second.c_str()));
|
||||
// }
|
||||
}
|
||||
|
||||
dev->setIndex(deviceIndexes[dev->getDriver()]);
|
||||
deviceIndexes[dev->getDriver()]++;
|
||||
|
||||
std::cout << "Make device " << dev->getDeviceArgs() << std::endl;
|
||||
try {
|
||||
SoapySDR::Device *device = SoapySDR::Device::make(dev->getDeviceArgs());
|
||||
SoapySDR::Kwargs info = device->getHardwareInfo();
|
||||
for (SoapySDR::Kwargs::const_iterator it = info.begin(); it != info.end(); ++it) {
|
||||
std::cout << " " << it->first << "=" << it->second << std::endl;
|
||||
if (it->first == "hardware") {
|
||||
dev->setHardware(it->second);
|
||||
}
|
||||
}
|
||||
SoapySDR::Device::unmake(device);
|
||||
dev->setAvailable(true);
|
||||
} catch (const std::exception &ex) {
|
||||
std::cerr << "Error making device: " << ex.what() << std::endl;
|
||||
dev->setAvailable(false);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
SDRThread::devs.push_back(dev);
|
||||
}
|
||||
if (results.empty()) {
|
||||
std::cout << "No devices found!" << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
return &SDRThread::devs;
|
||||
}
|
||||
|
||||
void SDRThread::run() {
|
||||
//#ifdef __APPLE__
|
||||
// pthread_t tID = pthread_self(); // ID of this thread
|
||||
// int priority = sched_get_priority_max( SCHED_FIFO) - 1;
|
||||
// sched_param prio = { priority }; // scheduling priority of thread
|
||||
// pthread_setschedparam(tID, SCHED_FIFO, &prio);
|
||||
//#endif
|
||||
|
||||
std::cout << "SDR thread initializing.." << std::endl;
|
||||
|
||||
if (deviceId == -1 && devs.size() == 0) {
|
||||
std::cout << "No devices found.. SDR Thread exiting.." << std::endl;
|
||||
return;
|
||||
} else {
|
||||
if (deviceId == -1) {
|
||||
deviceId = 0;
|
||||
}
|
||||
std::cout << "Using device #" << deviceId << std::endl;
|
||||
}
|
||||
|
||||
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(devs[deviceId]->getDeviceId());
|
||||
|
||||
long long frequency = wxGetApp().getConfig()->getCenterFreq();
|
||||
int ppm = devConfig->getPPM();
|
||||
int direct_sampling_mode = devConfig->getDirectSampling();;
|
||||
// int buf_size = BUF_SIZE;
|
||||
offset.store(devConfig->getOffset());
|
||||
wxGetApp().setSwapIQ(devConfig->getIQSwap());
|
||||
|
||||
|
||||
SDRDeviceInfo *dev = devs[deviceId];
|
||||
std::vector<SoapySDR::Kwargs> dev_results = SoapySDR::Device::enumerate(dev->getDeviceArgs());
|
||||
SoapySDR::Device *device = SoapySDR::Device::make(dev_results[dev->getIndex()]);
|
||||
|
||||
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
|
||||
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load());
|
||||
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm);
|
||||
device->setGainMode(SOAPY_SDR_RX,0, true);
|
||||
|
||||
SoapySDR::Stream *stream = device->setupStream(SOAPY_SDR_RX,"CF32");
|
||||
device->activateStream(stream);
|
||||
|
||||
void *buffs[1];
|
||||
|
||||
buffs[0] = malloc(BUF_SIZE * sizeof(float));
|
||||
|
||||
int flags;
|
||||
long long timeNs;
|
||||
|
||||
ReBuffer<SDRThreadIQData> buffers;
|
||||
|
||||
SDRThreadIQDataQueue* iqDataOutQueue = (SDRThreadIQDataQueue*) getOutputQueue("IQDataOutput");
|
||||
SDRThreadCommandQueue* cmdQueue = (SDRThreadCommandQueue*) getInputQueue("SDRCommandQueue");
|
||||
|
||||
while (!terminated) {
|
||||
if (!cmdQueue->empty()) {
|
||||
bool freq_changed = false;
|
||||
bool offset_changed = false;
|
||||
bool rate_changed = false;
|
||||
bool device_changed = false;
|
||||
bool ppm_changed = false;
|
||||
bool direct_sampling_changed = false;
|
||||
long long new_freq = frequency;
|
||||
long long new_offset = offset.load();
|
||||
long long new_rate = sampleRate.load();
|
||||
int new_device = deviceId;
|
||||
int new_ppm = ppm;
|
||||
|
||||
while (!cmdQueue->empty()) {
|
||||
SDRThreadCommand command;
|
||||
cmdQueue->pop(command);
|
||||
|
||||
switch (command.cmd) {
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_TUNE:
|
||||
freq_changed = true;
|
||||
new_freq = command.llong_value;
|
||||
if (new_freq < sampleRate.load() / 2) {
|
||||
new_freq = sampleRate.load() / 2;
|
||||
}
|
||||
break;
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_OFFSET:
|
||||
offset_changed = true;
|
||||
new_offset = command.llong_value;
|
||||
std::cout << "Set offset: " << new_offset << std::endl;
|
||||
break;
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_SAMPLERATE:
|
||||
rate_changed = true;
|
||||
new_rate = command.llong_value;
|
||||
std::cout << "Set sample rate: " << new_rate << std::endl;
|
||||
break;
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_DEVICE:
|
||||
device_changed = true;
|
||||
new_device = (int) command.llong_value;
|
||||
std::cout << "Set device: " << new_device << std::endl;
|
||||
break;
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_PPM:
|
||||
ppm_changed = true;
|
||||
new_ppm = (int) command.llong_value;
|
||||
//std::cout << "Set PPM: " << new_ppm << std::endl;
|
||||
break;
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_DIRECT_SAMPLING:
|
||||
direct_sampling_mode = (int)command.llong_value;
|
||||
direct_sampling_changed = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (device_changed) {
|
||||
device->deactivateStream(stream);
|
||||
device->closeStream(stream);
|
||||
SoapySDR::Device::unmake(device);
|
||||
|
||||
SDRDeviceInfo *dev = devs[new_device];
|
||||
std::vector<SoapySDR::Kwargs> dev_results = SoapySDR::Device::enumerate(dev->getDeviceArgs());
|
||||
device = SoapySDR::Device::make(dev_results[dev->getIndex()]);
|
||||
|
||||
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
|
||||
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load());
|
||||
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm);
|
||||
device->setGainMode(SOAPY_SDR_RX,0, true);
|
||||
|
||||
SoapySDR::Stream *stream = device->setupStream(SOAPY_SDR_RX,"CF32");
|
||||
device->activateStream(stream);
|
||||
}
|
||||
|
||||
if (offset_changed) {
|
||||
if (!freq_changed) {
|
||||
new_freq = frequency;
|
||||
freq_changed = true;
|
||||
}
|
||||
offset.store(new_offset);
|
||||
}
|
||||
if (rate_changed) {
|
||||
device->setSampleRate(SOAPY_SDR_RX,0,new_rate);
|
||||
sampleRate.store(device->getSampleRate(SOAPY_SDR_RX,0));
|
||||
}
|
||||
if (freq_changed) {
|
||||
frequency = new_freq;
|
||||
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load());
|
||||
}
|
||||
if (ppm_changed) {
|
||||
ppm = new_ppm;
|
||||
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm);
|
||||
}
|
||||
if (direct_sampling_changed) {
|
||||
// rtlsdr_set_direct_sampling(dev, direct_sampling_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int n_read = device->readStream(stream, buffs, BUF_SIZE/2, flags, timeNs, 99999999);
|
||||
|
||||
// std::cout << n_read << ", " << timeNs << std::endl;
|
||||
|
||||
SDRThreadIQData *dataOut = buffers.getBuffer();
|
||||
|
||||
dataOut->setRefCount(1);
|
||||
dataOut->frequency = frequency;
|
||||
dataOut->sampleRate = sampleRate.load();
|
||||
|
||||
dataOut->data.resize(n_read * 2);
|
||||
memcpy(&dataOut->data[0],buffs[0],n_read * sizeof(float) * 2);
|
||||
|
||||
if (iqDataOutQueue != NULL) {
|
||||
iqDataOutQueue->push(dataOut);
|
||||
} else {
|
||||
dataOut->setRefCount(0);
|
||||
}
|
||||
|
||||
}
|
||||
device->deactivateStream(stream);
|
||||
device->closeStream(stream);
|
||||
SoapySDR::Device::unmake(device);
|
||||
|
||||
/*
|
||||
|
||||
|
||||
rtlsdr_open(&dev, deviceId);
|
||||
rtlsdr_set_sample_rate(dev, sampleRate.load());
|
||||
rtlsdr_set_center_freq(dev, frequency - offset.load());
|
||||
rtlsdr_set_freq_correction(dev, ppm);
|
||||
rtlsdr_set_agc_mode(dev, 1);
|
||||
rtlsdr_set_offset_tuning(dev, 0);
|
||||
rtlsdr_reset_buffer(dev);
|
||||
|
||||
// sampleRate = rtlsdr_get_sample_rate(dev);
|
||||
|
||||
std::cout << "Sample Rate is: " << sampleRate.load() << std::endl;
|
||||
|
||||
int n_read;
|
||||
double seconds = 0.0;
|
||||
|
||||
std::cout << "SDR thread started.." << std::endl;
|
||||
|
||||
ReBuffer<SDRThreadIQData> buffers;
|
||||
|
||||
SDRThreadIQDataQueue* iqDataOutQueue = (SDRThreadIQDataQueue*) getOutputQueue("IQDataOutput");
|
||||
SDRThreadCommandQueue* cmdQueue = (SDRThreadCommandQueue*) getInputQueue("SDRCommandQueue");
|
||||
|
||||
while (!terminated) {
|
||||
if (!cmdQueue->empty()) {
|
||||
bool freq_changed = false;
|
||||
bool offset_changed = false;
|
||||
bool rate_changed = false;
|
||||
bool device_changed = false;
|
||||
bool ppm_changed = false;
|
||||
bool direct_sampling_changed = false;
|
||||
long long new_freq = frequency;
|
||||
long long new_offset = offset.load();
|
||||
long long new_rate = sampleRate.load();
|
||||
int new_device = deviceId;
|
||||
int new_ppm = ppm;
|
||||
|
||||
while (!cmdQueue->empty()) {
|
||||
SDRThreadCommand command;
|
||||
cmdQueue->pop(command);
|
||||
|
||||
switch (command.cmd) {
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_TUNE:
|
||||
freq_changed = true;
|
||||
new_freq = command.llong_value;
|
||||
if (new_freq < sampleRate.load() / 2) {
|
||||
new_freq = sampleRate.load() / 2;
|
||||
}
|
||||
// std::cout << "Set frequency: " << new_freq << std::endl;
|
||||
break;
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_OFFSET:
|
||||
offset_changed = true;
|
||||
new_offset = command.llong_value;
|
||||
std::cout << "Set offset: " << new_offset << std::endl;
|
||||
break;
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_SAMPLERATE:
|
||||
rate_changed = true;
|
||||
new_rate = command.llong_value;
|
||||
if (new_rate <= 250000) {
|
||||
buf_size = BUF_SIZE/4;
|
||||
} else if (new_rate < 1500000) {
|
||||
buf_size = BUF_SIZE/2;
|
||||
} else {
|
||||
buf_size = BUF_SIZE;
|
||||
}
|
||||
std::cout << "Set sample rate: " << new_rate << std::endl;
|
||||
break;
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_DEVICE:
|
||||
device_changed = true;
|
||||
new_device = (int) command.llong_value;
|
||||
std::cout << "Set device: " << new_device << std::endl;
|
||||
break;
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_PPM:
|
||||
ppm_changed = true;
|
||||
new_ppm = (int) command.llong_value;
|
||||
//std::cout << "Set PPM: " << new_ppm << std::endl;
|
||||
break;
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_DIRECT_SAMPLING:
|
||||
direct_sampling_mode = (int)command.llong_value;
|
||||
direct_sampling_changed = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (device_changed) {
|
||||
rtlsdr_close(dev);
|
||||
rtlsdr_open(&dev, new_device);
|
||||
rtlsdr_set_sample_rate(dev, sampleRate.load());
|
||||
rtlsdr_set_center_freq(dev, frequency - offset.load());
|
||||
rtlsdr_set_freq_correction(dev, ppm);
|
||||
rtlsdr_set_agc_mode(dev, 1);
|
||||
rtlsdr_set_offset_tuning(dev, 0);
|
||||
rtlsdr_set_direct_sampling(dev, direct_sampling_mode);
|
||||
rtlsdr_reset_buffer(dev);
|
||||
}
|
||||
if (offset_changed) {
|
||||
if (!freq_changed) {
|
||||
new_freq = frequency;
|
||||
freq_changed = true;
|
||||
}
|
||||
offset.store(new_offset);
|
||||
}
|
||||
if (rate_changed) {
|
||||
rtlsdr_set_sample_rate(dev, new_rate);
|
||||
rtlsdr_reset_buffer(dev);
|
||||
sampleRate.store(rtlsdr_get_sample_rate(dev));
|
||||
}
|
||||
if (freq_changed) {
|
||||
frequency = new_freq;
|
||||
rtlsdr_set_center_freq(dev, frequency - offset.load());
|
||||
}
|
||||
if (ppm_changed) {
|
||||
ppm = new_ppm;
|
||||
rtlsdr_set_freq_correction(dev, ppm);
|
||||
}
|
||||
if (direct_sampling_changed) {
|
||||
rtlsdr_set_direct_sampling(dev, direct_sampling_mode);
|
||||
}
|
||||
}
|
||||
|
||||
rtlsdr_read_sync(dev, buf, buf_size, &n_read);
|
||||
|
||||
SDRThreadIQData *dataOut = buffers.getBuffer();
|
||||
|
||||
// std::lock_guard < std::mutex > lock(dataOut->m_mutex);
|
||||
dataOut->setRefCount(1);
|
||||
dataOut->frequency = frequency;
|
||||
dataOut->sampleRate = sampleRate.load();
|
||||
|
||||
if (dataOut->data.capacity() < n_read) {
|
||||
dataOut->data.reserve(n_read);
|
||||
}
|
||||
|
||||
if (dataOut->data.size() != n_read) {
|
||||
dataOut->data.resize(n_read);
|
||||
}
|
||||
|
||||
memcpy(&dataOut->data[0], buf, n_read);
|
||||
|
||||
double time_slice = (double) n_read / (double) sampleRate.load();
|
||||
seconds += time_slice;
|
||||
|
||||
if (iqDataOutQueue != NULL) {
|
||||
iqDataOutQueue->push(dataOut);
|
||||
}
|
||||
}
|
||||
|
||||
// buffers.purge();
|
||||
*/
|
||||
std::cout << "SDR thread done." << std::endl;
|
||||
}
|
||||
|
||||
|
||||
int SDRThread::getDeviceId() const {
|
||||
return deviceId.load();
|
||||
}
|
||||
|
||||
void SDRThread::setDeviceId(int deviceId) {
|
||||
this->deviceId.store(deviceId);
|
||||
}
|
73
src/sdr/SoapySDRThread.h
Normal file
73
src/sdr/SoapySDRThread.h
Normal file
@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "ThreadQueue.h"
|
||||
#include "DemodulatorMgr.h"
|
||||
#include "SDRDeviceInfo.h"
|
||||
|
||||
class SDRThreadCommand {
|
||||
public:
|
||||
enum SDRThreadCommandEnum {
|
||||
SDR_THREAD_CMD_NULL, SDR_THREAD_CMD_TUNE, SDR_THREAD_CMD_SET_OFFSET, SDR_THREAD_CMD_SET_SAMPLERATE, SDR_THREAD_CMD_SET_PPM, SDR_THREAD_CMD_SET_DEVICE, SDR_THREAD_CMD_SET_DIRECT_SAMPLING
|
||||
};
|
||||
|
||||
SDRThreadCommand() :
|
||||
cmd(SDR_THREAD_CMD_NULL), llong_value(0) {
|
||||
|
||||
}
|
||||
|
||||
SDRThreadCommand(SDRThreadCommandEnum cmd) :
|
||||
cmd(cmd), llong_value(0) {
|
||||
|
||||
}
|
||||
|
||||
SDRThreadCommandEnum cmd;
|
||||
long long llong_value;
|
||||
};
|
||||
|
||||
class SDRThreadIQData: public ReferenceCounter {
|
||||
public:
|
||||
long long frequency;
|
||||
long long sampleRate;
|
||||
// std::vector<unsigned char> data;
|
||||
std::vector<float> data;
|
||||
|
||||
SDRThreadIQData() :
|
||||
frequency(0), sampleRate(DEFAULT_SAMPLE_RATE) {
|
||||
|
||||
}
|
||||
|
||||
SDRThreadIQData(long long bandwidth, long long frequency, std::vector<signed char> *data) :
|
||||
frequency(frequency), sampleRate(bandwidth) {
|
||||
|
||||
}
|
||||
|
||||
~SDRThreadIQData() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
typedef ThreadQueue<SDRThreadCommand> SDRThreadCommandQueue;
|
||||
typedef ThreadQueue<SDRThreadIQData *> SDRThreadIQDataQueue;
|
||||
|
||||
class SDRThread : public IOThread {
|
||||
public:
|
||||
SDRThread();
|
||||
~SDRThread();
|
||||
|
||||
static std::vector<SDRDeviceInfo *> *enumerate_devices();
|
||||
|
||||
void run();
|
||||
|
||||
int getDeviceId() const;
|
||||
void setDeviceId(int deviceId);
|
||||
|
||||
protected:
|
||||
static std::vector<std::string> factories;
|
||||
static std::vector<std::string> modules;
|
||||
static std::vector<SDRDeviceInfo *> devs;
|
||||
std::atomic<uint32_t> sampleRate;
|
||||
std::atomic_llong offset;
|
||||
std::atomic_int deviceId;
|
||||
};
|
Loading…
Reference in New Issue
Block a user