----------------------------------------------------------------------- How to add a new device ----------------------------------------------------------------------- While perhaps not so interesting for most users, one with interest in programming and in possession of yet another device might wonder whether or not it is difficult to add such a device to the list of supported devices. In this txt an overview is given of what steps to take when adding a device to the list of supported devices. ----------------------------------------------------------------------- The interface ----------------------------------------------------------------------- The qt-dab software assumes a device to support the interface to the device implemented as a class derived from the class "deviceHandler" class deviceHandler: public QObject { public: deviceHandler (void); virtual ~deviceHandler (void); virtual int32_t getVFOFrequency (void); virtual int32_t defaultFrequency(void); virtual bool restartReader (int32_t); virtual void stopReader (void); virtual int32_t getSamples (std::complex *, int32_t); virtual int32_t Samples (void); virtual void resetBuffer (void); virtual int16_t bitDepth (void) { return 10;} virtual void show (); virtual void hide (); virtual bool isHidden (); }; The constructor of the class for the new device driver is supposed to throw an exception when the device cannot be handled. The functions setVFOFrequency and getVFOFrequency are pretty obvious, just set the VFO of the device to a frequency (specified in Hz) and get the current value. defaultFrequency may just return a frequency with the range of valid frequencies for the device. the function restartReader is supposed to start or restart the generation of samples from the device. Note that while not specified explicitly the assumed samplerate is 2048000, with a bandwidth of 1536000 Hz. The parameter indicates the frequency to be selected the function stopReader will do the opposite, it will stop the generation of the samplestream. The airspy is one of the devices where the samplerate cannot be set to 2048000, so in that driver the software takes care of translating the samplerate to 2048000. The function Samples will tell the amount of samples currently available, the qt-dab software will use that function to check whether or not sufficient samples are available to continue processing. getSamples will try to extract the specified amount of samples - I/Q samples as complex float numbers - from the buffer from the device driver. It will return the amount actually read, in case the buffer in the device driver contains less than the requested amount, it will not wait. It assumes that the samplerate is just 2048000, i.e. rate conversions need to be done in the device handler. The function resetBuffer will clear the buffer in the device driver, it is used when switching channels. The function bitDepth returns - as the name suggests - the number of bits in the (elements of the) sample. E.g dabsticks provide 8 bits, SDRplay 12. The value is used to scale the Y-axis of the scopes. The device driver might have a small GUI, with probably a slider or spinbox for gain, and maybe other settings. See one of the existing device drivers for examples. if the driver does contain its own GUI, the function "show" is called whenever it should be visible, the function "hide" when it should be hidden and the function "isHidden" to return the status, being hidden or not. -------------------------------------------------------------------------- Modifications to the file radio.cpp -------------------------------------------------------------------------- The file radio.cpp needs to be "informed" about the new device. Let us assume the device driver for the new device is implemented in a class newDevice, implemented in files new-device.h and new-device.cpp. step 1. In the list of includes add #ifdef __HAVE_NEWDEVICE__ #include "new-device.h" #endif step 2. The selectable devices are listed in a combobox on the main GUI. Add the lines #ifdef __HAVE_NEWDEVICE__ deviceSelector -> addItem ("newDevice"); #endif around line 300. step 3 Of course, when selection of the device is possible, the device driver needs to be part of the configuration. To handle that properly, add in the function setDevice (app line 1022) the following lines #ifdef __HAVE_NEWDEVICE__ if (s == "newDevice") { try { inputDevice = new newDevice (..parameters..); showButtons (); } catch (int e) { QMessageBox::warning (this, tr ("Warning"), tr ("newDevice not found\n")); return nullptr; } } else #endif where the appropriate parameters are passed on to the constructor. That is it, however ... -------------------------------------------------------------------- Modifying the qt-dab.pro file --------------------------------------------------------------------- To generate an executable, the qt-dab.pro file (or the CMakeLists.txt file) needs to be informed on the modified configuration step 1. add - around line 273 in the qt-dab file - the line CONFIG += newDevice step 2. add - somewhere in the qt-dab.pro file - the section describing the files needed for handling the new device. Assuming you created a directory "new-device" in the directory "devices", and assuming the GUI file is desscribed in the xml file newdevice-widget.ui, the paragraph would look like newDevice { DEFINES += HAVE_NEWDEVICE INCLUDEPATH += ./devices/new-device HEADERS += ./devices/new-device/new-device.h \ .. add further includes to development files SOURCES += ./devices/new-device/new-device.cpp FORMS += ./devices/new-device/newdevice-widget.ui LIBS += .. add here libraries to be included } Modifications for the CMakeLists.txt are left as an exercise.