1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-06-02 22:14:45 -04:00

git clone git://git.osmocom.org/sdrangelove.git

This commit is contained in:
Hexameron
2014-05-18 16:52:39 +01:00
commit 7d3bfb26fc
203 changed files with 27958 additions and 0 deletions
@@ -0,0 +1,87 @@
project(gnuradio)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
find_package(GnuradioRuntime)
find_package(GnuradioOsmosdr)
if(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64")
list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix
endif(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64")
find_package(Boost COMPONENTS system)
if(NOT GNURADIO_RUNTIME_FOUND AND GNURADIO_OSMOSDR_FOUND)
message(STATUS "GNU Radio not found, assuming built-in gr-osmosdr runtime.")
set(GNURADIO_RUNTIME_FOUND TRUE)
set(GNURADIO_RUNTIME_INCLUDE_DIRS "")
set(GNURADIO_RUNTIME_LIBRARIES "")
FOREACH(inc ${GNURADIO_OSMOSDR_INCLUDE_DIRS})
LIST(APPEND GNURADIO_RUNTIME_INCLUDE_DIRS "${inc}/osmosdr/runtime")
ENDFOREACH(inc)
LIST(APPEND GNURADIO_RUNTIME_LIBRARIES ${GNURADIO_OSMOSDR_LIBRARIES})
endif(NOT GNURADIO_RUNTIME_FOUND AND GNURADIO_OSMOSDR_FOUND)
if(Boost_FOUND AND GNURADIO_RUNTIME_FOUND AND GNURADIO_OSMOSDR_FOUND)
set(gnuradio_SOURCES
gnuradiogui.cpp
gnuradioinput.cpp
gnuradioplugin.cpp
gnuradiothread.cpp
)
set(gnuradio_HEADERS
gnuradiogui.h
gnuradioinput.h
gnuradioplugin.h
gnuradiothread.h
)
set(gnuradio_FORMS
gnuradiogui.ui
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/include-gpl
${Boost_INCLUDE_DIRS}
${GNURADIO_RUNTIME_INCLUDE_DIRS}
${GNURADIO_OSMOSDR_INCLUDE_DIRS}
)
add_definitions(${QT_DEFINITIONS})
add_definitions(-DQT_PLUGIN)
add_definitions(-DQT_SHARED)
add_definitions(-DBOOST_ALL_NO_LIB)
if(MSVC)
add_definitions(-DNOMINMAX)
endif()
qt5_wrap_ui(gnuradio_FORMS_HEADERS ${gnuradio_FORMS})
add_library(inputgnuradio SHARED
${gnuradio_SOURCES}
${gnuradio_HEADERS_MOC}
${gnuradio_FORMS_HEADERS}
)
target_link_libraries(inputgnuradio
${QT_LIBRARIES}
${Boost_LIBRARIES}
${GNURADIO_RUNTIME_LIBRARIES}
${GNURADIO_OSMOSDR_LIBRARIES}
sdrbase
)
qt5_use_modules(inputgnuradio Core Widgets OpenGL Multimedia)
endif(Boost_FOUND AND GNURADIO_RUNTIME_FOUND AND GNURADIO_OSMOSDR_FOUND)
@@ -0,0 +1,29 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_GNURADIO_OSMOSDR gnuradio-osmosdr)
FIND_PATH(
GNURADIO_OSMOSDR_INCLUDE_DIRS
NAMES osmosdr/api.h
HINTS $ENV{GNURADIO_OSMOSDR_DIR}/include
${PC_GNURADIO_OSMOSDR_INCLUDEDIR}
${CMAKE_INSTALL_PREFIX}/include
PATHS /usr/local/include
/usr/include
)
FIND_LIBRARY(
GNURADIO_OSMOSDR_LIBRARIES
NAMES gnuradio-osmosdr
HINTS $ENV{GNURADIO_OSMOSDR_DIR}/lib
${PC_GNURADIO_OSMOSDR_LIBDIR}
${CMAKE_INSTALL_PREFIX}/lib64
${CMAKE_INSTALL_PREFIX}/lib
PATHS /usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_OSMOSDR DEFAULT_MSG GNURADIO_OSMOSDR_LIBRARIES GNURADIO_OSMOSDR_INCLUDE_DIRS)
MARK_AS_ADVANCED(GNURADIO_OSMOSDR_LIBRARIES GNURADIO_OSMOSDR_INCLUDE_DIRS)
@@ -0,0 +1,29 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_GNURADIO_RUNTIME gnuradio-runtime)
FIND_PATH(
GNURADIO_RUNTIME_INCLUDE_DIRS
NAMES gnuradio/api.h
HINTS $ENV{GNURADIO_RUNTIME_DIR}/include
${PC_GNURADIO_RUNTIME_INCLUDEDIR}
${CMAKE_INSTALL_PREFIX}/include
PATHS /usr/local/include
/usr/include
)
FIND_LIBRARY(
GNURADIO_RUNTIME_LIBRARIES
NAMES gnuradio-runtime
HINTS $ENV{GNURADIO_RUNTIME_DIR}/lib
${PC_GNURADIO_RUNTIME_LIBDIR}
${CMAKE_INSTALL_PREFIX}/lib64
${CMAKE_INSTALL_PREFIX}/lib
PATHS /usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_RUNTIME DEFAULT_MSG GNURADIO_RUNTIME_LIBRARIES GNURADIO_RUNTIME_INCLUDE_DIRS)
MARK_AS_ADVANCED(GNURADIO_RUNTIME_LIBRARIES GNURADIO_RUNTIME_INCLUDE_DIRS)
@@ -0,0 +1,422 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
// written by Christian Daniel //
// Copyright (C) 2013 by Dimitri Stolnikov <horiz0n@gmx.net> //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include "gnuradiogui.h"
#include "ui_gnuradiogui.h"
#include <osmosdr/device.h>
#include <iostream>
#include <plugin/pluginapi.h>
#include <QHBoxLayout>
#include <QLabel>
#include <QSlider>
GNURadioGui::GNURadioGui(PluginAPI* pluginAPI, QWidget* parent) :
QWidget(parent),
ui(new Ui::GNURadioGui),
m_pluginAPI(pluginAPI),
m_settings(),
m_sampleSource(NULL)
{
ui->setupUi(this);
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
displaySettings();
m_sampleSource = new GNURadioInput(m_pluginAPI->getMainWindowMessageQueue());
m_pluginAPI->setSampleSource(m_sampleSource);
}
GNURadioGui::~GNURadioGui()
{
delete ui;
}
void GNURadioGui::destroy()
{
delete this;
}
void GNURadioGui::setName(const QString& name)
{
setObjectName(name);
}
void GNURadioGui::resetToDefaults()
{
m_generalSettings.resetToDefaults();
m_settings.resetToDefaults();
displaySettings();
sendSettings();
}
QByteArray GNURadioGui::serializeGeneral() const
{
return m_generalSettings.serialize();
}
bool GNURadioGui::deserializeGeneral(const QByteArray&data)
{
if(m_generalSettings.deserialize(data)) {
displaySettings();
sendSettings();
return true;
} else {
resetToDefaults();
return false;
}
}
quint64 GNURadioGui::getCenterFrequency() const
{
return m_generalSettings.m_centerFrequency;
}
QByteArray GNURadioGui::serialize() const
{
return m_settings.serialize();
}
bool GNURadioGui::deserialize(const QByteArray& data)
{
if(m_settings.deserialize(data)) {
displaySettings();
sendSettings();
return true;
} else {
resetToDefaults();
return false;
}
}
bool GNURadioGui::handleMessage(Message* message)
{
if(GNURadioInput::MsgReportGNURadio::match(message)) {
GNURadioInput::MsgReportGNURadio* rep = (GNURadioInput::MsgReportGNURadio*)message;
m_namedGains = rep->getNamedGains();
m_freqMin = rep->getFreqMin();
m_freqMax = rep->getFreqMax();
m_freqCorr = rep->getFreqCorr();
m_sampRates = rep->getSampRates();
m_antennas = rep->getAntennas();
m_dcoffs = rep->getDCOffs();
m_iqbals = rep->getIQBals();
m_bandwidths = rep->getBandwidths();
/* insert 0 which will become "Auto" in the combo box */
m_bandwidths.insert(m_bandwidths.begin(), 0);
displaySettings();
return true;
} else {
return false;
}
}
void GNURadioGui::displaySettings()
{
int oldIndex = 0;
oldIndex = ui->cboDevices->currentIndex();
ui->cboDevices->clear();
QString oldArgs = ui->txtDeviceArgs->text();
osmosdr::devices_t devices = osmosdr::device::find();
for ( int i = 0; i < devices.size(); i++ )
{
osmosdr::device_t dev = devices[i];
QString label;
if ( dev.count( "label" ) )
{
label = QString(dev[ "label" ].c_str());
dev.erase("label");
}
QPair< QString, QString > pair(label, dev.to_string().c_str());
m_devs.append(pair);
ui->cboDevices->addItem(label);
}
if ( ui->cboDevices->count() && oldIndex >= 0 )
{
if ( oldIndex > ui->cboDevices->count() - 1 )
oldIndex = 0;
ui->cboDevices->setCurrentIndex(oldIndex);
if ( oldArgs.length() == 0 )
ui->txtDeviceArgs->setText( m_devs[oldIndex].second );
}
if ( oldArgs.length() )
ui->txtDeviceArgs->setText( oldArgs );
ui->centerFrequency->setValueRange(7,
unsigned(m_freqMin / 1000.0),
unsigned(m_freqMax / 1000.0));
ui->centerFrequency->setValue(m_generalSettings.m_centerFrequency / 1000);
ui->sldFreqCorr->setRange(-100, +100);
ui->sldFreqCorr->setValue( m_freqCorr );
ui->lblFreqCorr->setText(tr("%1").arg(ui->sldFreqCorr->value()));
m_gainControls.clear();
QVBoxLayout *layoutGains = ui->verticalLayoutGains;
QLayoutItem *layoutItem;
while ( ( layoutItem = layoutGains->takeAt( 0 ) ) != NULL )
{
QLayout *layout = layoutItem->layout();
if ( !layout )
continue;
while ( ( layoutItem = layout->takeAt( 0 ) ) != NULL )
{
delete layoutItem->widget();
delete layoutItem;
}
delete layout;
}
for ( int i = 0; i < m_namedGains.size(); i++ )
{
std::pair< QString, std::vector<double> > pair = m_namedGains[i];
QHBoxLayout *layout = new QHBoxLayout();
QLabel *gainName = new QLabel( pair.first + " Gain" );
QSlider *gainSlider = new QSlider(Qt::Horizontal);
QLabel *gainLabel = new QLabel("0");
gainLabel->setMinimumWidth(30);
gainLabel->setAlignment(Qt::AlignHCenter | Qt::AlignHCenter);
QPair< QSlider*, QLabel* > pair2( gainSlider, gainLabel );
m_gainControls.push_back( pair2 );
connect(gainSlider, SIGNAL(valueChanged(int)),
this, SLOT(on_sldGain_valueChanged(int)));
layout->addWidget(gainName);
layout->addWidget(gainSlider);
layout->addWidget(gainLabel);
layoutGains->addLayout(layout);
std::vector<double> gain_values = pair.second;
if ( gain_values.size() ) {
gainSlider->setRange(0, gain_values.size() - 1);
gainSlider->setValue(gain_values.size() / 4);
gainSlider->setEnabled(true);
} else {
gainSlider->setEnabled(false);
}
}
oldIndex = ui->cboSampleRate->currentIndex();
ui->cboSampleRate->clear();
for ( int i = 0; i < m_sampRates.size(); i++ )
ui->cboSampleRate->addItem( QString::number(m_sampRates[i] / 1e6) );
if ( oldIndex > ui->cboSampleRate->count() - 1 )
oldIndex = 0;
if ( ui->cboSampleRate->count() && oldIndex >= 0 )
ui->cboSampleRate->setCurrentIndex(oldIndex);
if ( ui->cboSampleRate->count() ) {
ui->cboSampleRate->setEnabled(true);
} else {
ui->cboSampleRate->setEnabled(false);
}
oldIndex = ui->cboAntennas->currentIndex();
ui->cboAntennas->clear();
if ( m_antennas.size() ) {
for ( int i = 0; i < m_antennas.size(); i++ )
ui->cboAntennas->addItem( m_antennas[i] );
if ( oldIndex > ui->cboAntennas->count() - 1 )
oldIndex = 0;
if ( ui->cboAntennas->count() && oldIndex >= 0 )
ui->cboAntennas->setCurrentIndex(oldIndex);
ui->cboAntennas->setEnabled(true);
} else {
ui->cboAntennas->setEnabled(false);
}
oldIndex = ui->cboDCOffset->currentIndex();
ui->cboDCOffset->clear();
if ( m_dcoffs.size() ) {
for ( int i = 0; i < m_dcoffs.size(); i++ )
ui->cboDCOffset->addItem( m_dcoffs[i] );
if ( ui->cboDCOffset->count() && oldIndex >= 0 )
ui->cboDCOffset->setCurrentIndex(oldIndex);
ui->cboDCOffset->setEnabled(true);
} else {
ui->cboDCOffset->setEnabled(false);
}
oldIndex = ui->cboIQBalance->currentIndex();
ui->cboIQBalance->clear();
if ( m_iqbals.size() ) {
for ( int i = 0; i < m_iqbals.size(); i++ )
ui->cboIQBalance->addItem( m_iqbals[i] );
if ( ui->cboIQBalance->count() && oldIndex >= 0 )
ui->cboIQBalance->setCurrentIndex(oldIndex);
ui->cboIQBalance->setEnabled(true);
} else {
ui->cboIQBalance->setEnabled(false);
}
oldIndex = ui->cboBandwidth->currentIndex();
ui->cboBandwidth->clear();
for ( int i = 0; i < m_bandwidths.size(); i++ )
if ( 0.0 == m_bandwidths[i] )
ui->cboBandwidth->addItem( "Auto" );
else
ui->cboBandwidth->addItem( QString::number(m_bandwidths[i] / 1e6) );
if ( oldIndex > ui->cboBandwidth->count() - 1 )
oldIndex = 0;
if ( ui->cboBandwidth->count() && oldIndex >= 0 )
ui->cboBandwidth->setCurrentIndex(oldIndex);
if ( ui->cboBandwidth->count() ) {
ui->cboBandwidth->setEnabled(true);
} else {
ui->cboBandwidth->setEnabled(false);
}
}
void GNURadioGui::sendSettings()
{
if(!m_updateTimer.isActive())
m_updateTimer.start(100);
}
void GNURadioGui::updateHardware()
{
m_updateTimer.stop();
GNURadioInput::MsgConfigureGNURadio* msg = GNURadioInput::MsgConfigureGNURadio::create(m_generalSettings, m_settings);
msg->submit(m_pluginAPI->getDSPEngineMessageQueue());
}
void GNURadioGui::on_cboDevices_currentIndexChanged(int index)
{
if ( index < 0 || index >= m_devs.count() )
return;
ui->txtDeviceArgs->setText( m_devs[index].second );
}
void GNURadioGui::on_txtDeviceArgs_textChanged(const QString &arg1)
{
m_settings.m_args = arg1;
sendSettings();
}
void GNURadioGui::on_centerFrequency_changed(quint64 value)
{
m_generalSettings.m_centerFrequency = value * 1000;
sendSettings();
}
void GNURadioGui::on_sldFreqCorr_valueChanged(int value)
{
ui->lblFreqCorr->setText(tr("%1").arg(value));
m_settings.m_freqCorr = value;
sendSettings();
}
void GNURadioGui::on_sldGain_valueChanged(int value)
{
m_settings.m_namedGains.clear();
for ( int i = 0; i < m_gainControls.size(); i++ )
{
QPair< QSlider*, QLabel* > controls = m_gainControls[i];
QSlider *slider = controls.first;
QLabel *label = controls.second;
std::pair< QString, std::vector<double> > named_gain = m_namedGains[ i ];
int index = slider->value();
double gain = named_gain.second[index];
label->setText(tr("%1").arg(gain));
QPair< QString, double > named_gain2( named_gain.first, gain );
m_settings.m_namedGains.push_back( named_gain2 );
}
sendSettings();
}
void GNURadioGui::on_cboSampleRate_currentIndexChanged(int index)
{
if ( index < 0 || index >= m_sampRates.size() )
return;
m_settings.m_sampRate = m_sampRates[index];
sendSettings();
}
void GNURadioGui::on_cboAntennas_currentIndexChanged(const QString &arg1)
{
m_settings.m_antenna = arg1;
sendSettings();
}
void GNURadioGui::on_cboDCOffset_currentIndexChanged(const QString &arg1)
{
m_settings.m_dcoff = arg1;
sendSettings();
}
void GNURadioGui::on_cboIQBalance_currentIndexChanged(const QString &arg1)
{
m_settings.m_iqbal = arg1;
sendSettings();
}
void GNURadioGui::on_cboBandwidth_currentIndexChanged(int index)
{
if ( index < 0 || index >= m_bandwidths.size() )
return;
m_settings.m_bandwidth = m_bandwidths[index];
sendSettings();
}
@@ -0,0 +1,99 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
// written by Christian Daniel //
// Copyright (C) 2013 by Dimitri Stolnikov <horiz0n@gmx.net> //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_GNURADIOGUI_H
#define INCLUDE_GNURADIOGUI_H
#include <QTimer>
#include <QPair>
#include <QList>
#include <QString>
#include <QSlider>
#include <QLabel>
#include "plugin/plugingui.h"
#include "gnuradioinput.h"
namespace Ui {
class GNURadioGui;
}
class PluginAPI;
class GNURadioGui : public QWidget, public PluginGUI {
Q_OBJECT
public:
explicit GNURadioGui(PluginAPI* pluginAPI, QWidget* parent = NULL);
~GNURadioGui();
void destroy();
void setName(const QString& name);
void resetToDefaults();
QByteArray serializeGeneral() const;
bool deserializeGeneral(const QByteArray&data);
quint64 getCenterFrequency() const;
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
bool handleMessage(Message* message);
private:
Ui::GNURadioGui* ui;
PluginAPI* m_pluginAPI;
SampleSource* m_sampleSource;
QList< QPair<QString, QString> > m_devs;
std::vector< std::pair< QString, std::vector<double> > > m_namedGains;
double m_freqMin;
double m_freqMax;
double m_freqCorr;
std::vector<double> m_sampRates;
std::vector<QString> m_antennas;
std::vector<QString> m_dcoffs;
std::vector<QString> m_iqbals;
std::vector<double> m_bandwidths;
std::vector< QSlider* > m_gainSliders;
std::vector< QLabel* > m_gainLabels;
QList< QPair< QSlider*, QLabel* > > m_gainControls;
SampleSource::GeneralSettings m_generalSettings;
GNURadioInput::Settings m_settings;
QTimer m_updateTimer;
void displaySettings();
void sendSettings();
private slots:
void updateHardware();
void on_cboDevices_currentIndexChanged(int index);
void on_txtDeviceArgs_textChanged(const QString &arg1);
void on_centerFrequency_changed(quint64 value);
void on_sldFreqCorr_valueChanged(int value);
void on_sldGain_valueChanged(int value);
void on_cboSampleRate_currentIndexChanged(int index);
void on_cboAntennas_currentIndexChanged(const QString &arg1);
void on_cboDCOffset_currentIndexChanged(const QString &arg1);
void on_cboIQBalance_currentIndexChanged(const QString &arg1);
void on_cboBandwidth_currentIndexChanged(int index);
};
#endif // INCLUDE_GNURADIOGUI_H
@@ -0,0 +1,301 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GNURadioGui</class>
<widget class="QWidget" name="GNURadioGui">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>186</width>
<height>261</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Gnuradio Source</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QComboBox" name="cboDevices">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>false</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtDeviceArgs">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="ValueDial" name="centerFrequency" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>Monospace</family>
<pointsize>20</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Tuner center frequency in kHz</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Freq. Corr.</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="sldFreqCorr">
<property name="minimum">
<number>-100</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="tracking">
<bool>true</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblFreqCorr">
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayoutGains"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Sample Rate (MHz)</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboSampleRate">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Selected Antenna</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboAntennas">
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>DC Offset Corr. </string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboDCOffset"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>IQ Imbalance Corr.</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboIQBalance"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Bandwidth (MHz)</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboBandwidth"/>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ValueDial</class>
<extends>QWidget</extends>
<header>gui/valuedial.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,332 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
// written by Christian Daniel //
// Copyright (C) 2013 by Dimitri Stolnikov <horiz0n@gmx.net> //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <errno.h>
#include "util/simpleserializer.h"
#include "gnuradioinput.h"
#include "gnuradiothread.h"
#include "gnuradiogui.h"
MESSAGE_CLASS_DEFINITION(GNURadioInput::MsgConfigureGNURadio, Message)
MESSAGE_CLASS_DEFINITION(GNURadioInput::MsgReportGNURadio, Message)
GNURadioInput::Settings::Settings() :
m_args(""),
m_freqCorr(0),
m_sampRate(0),
m_antenna(""),
m_dcoff(""),
m_iqbal(""),
m_bandwidth(0)
{
}
void GNURadioInput::Settings::resetToDefaults()
{
m_args = "";
m_sampRate = 0;
m_freqCorr = 0;
m_antenna = "";
m_dcoff = "";
m_iqbal = "";
m_bandwidth = 0;
}
QByteArray GNURadioInput::Settings::serialize() const
{
SimpleSerializer s(1);
// s.writeString(1, m_args);
// s.writeDouble(2, m_freqCorr);
// s.writeDouble(3, m_sampRate);
// s.writeString(4, m_antenna);
// s.writeString(5, m_dcoff);
// s.writeString(5, m_iqbal);
return s.final();
}
bool GNURadioInput::Settings::deserialize(const QByteArray& data)
{
SimpleDeserializer d(data);
if(!d.isValid()) {
resetToDefaults();
return false;
}
if(d.getVersion() == 1) {
// d.readString(1, &m_args, "");
// d.readDouble(2, &m_freqCorr, 0);
// d.readDouble(3, &m_sampRate, 0);
// d.readString(4, &m_antenna, "");
// d.readString(5, &m_dcoff, "");
// d.readString(5, &m_iqbal, "");
return true;
} else {
resetToDefaults();
return false;
}
}
GNURadioInput::GNURadioInput(MessageQueue* msgQueueToGUI) :
SampleSource(msgQueueToGUI),
m_settings(),
m_GnuradioThread(NULL),
m_deviceDescription()
{
}
GNURadioInput::~GNURadioInput()
{
stopInput();
}
bool GNURadioInput::startInput(int device)
{
double freqMin = 0, freqMax = 0, freqCorr = 0;
std::vector< std::pair< QString, std::vector<double> > > namedGains;
std::vector< double > sampRates;
std::vector< QString > antennas;
std::vector< double > bandwidths;
QMutexLocker mutexLocker(&m_mutex);
if(m_GnuradioThread != NULL)
stopInput();
if(!m_sampleFifo.setSize( 2 * 1024 * 1024 )) {
qCritical("Could not allocate SampleFifo");
return false;
}
m_deviceDescription = m_settings.m_args;
// pass device arguments from the gui
m_GnuradioThread = new GnuradioThread(m_settings.m_args, &m_sampleFifo);
if(m_GnuradioThread == NULL) {
qFatal("out of memory");
goto failed;
}
m_GnuradioThread->startWork();
mutexLocker.unlock();
applySettings(m_generalSettings, m_settings, true);
if(m_GnuradioThread != NULL) {
osmosdr::source::sptr radio = m_GnuradioThread->radio();
try {
osmosdr::freq_range_t freq_rage = radio->get_freq_range();
freqMin = freq_rage.start();
freqMax = freq_rage.stop();
} catch ( std::exception &ex ) {
qDebug("%s", ex.what());
}
freqCorr = radio->get_freq_corr();
namedGains.clear();
m_settings.m_namedGains.clear();
std::vector< std::string > gain_names = radio->get_gain_names();
for ( int i = 0; i < gain_names.size(); i++ )
{
std::string gain_name = gain_names[i];
try {
std::vector< double > gain_values = \
radio->get_gain_range( gain_name ).values();
std::pair< QString, std::vector<double> > pair( gain_name.c_str(),
gain_values );
namedGains.push_back( pair );
QPair< QString, double > pair2( gain_name.c_str(), 0 );
m_settings.m_namedGains.push_back( pair2 );
} catch ( std::exception &ex ) {
qDebug("%s", ex.what());
}
}
try {
sampRates = radio->get_sample_rates().values();
} catch ( std::exception &ex ) {
qDebug("%s", ex.what());
}
antennas.clear();
std::vector< std::string > ant = radio->get_antennas();
for ( int i = 0; i < ant.size(); i++ )
antennas.push_back( QString( ant[i].c_str() ) );
m_dcoffs.clear();
m_dcoffs.push_back( "Off" );
m_dcoffs.push_back( "Keep" );
m_dcoffs.push_back( "Auto" );
m_iqbals.clear();
m_iqbals.push_back( "Off" );
m_iqbals.push_back( "Keep" );
m_iqbals.push_back( "Auto" );
try {
bandwidths = radio->get_bandwidth_range().values();
} catch ( std::exception &ex ) {
qDebug("%s", ex.what());
}
}
qDebug("GnuradioInput: start");
MsgReportGNURadio::create(freqMin, freqMax, freqCorr, namedGains,
sampRates, antennas, m_dcoffs, m_iqbals,
bandwidths)
->submit(m_guiMessageQueue);
return true;
failed:
stopInput();
return false;
}
void GNURadioInput::stopInput()
{
QMutexLocker mutexLocker(&m_mutex);
if(m_GnuradioThread != NULL) {
m_GnuradioThread->stopWork();
delete m_GnuradioThread;
m_GnuradioThread = NULL;
}
m_deviceDescription.clear();
}
const QString& GNURadioInput::getDeviceDescription() const
{
return m_deviceDescription;
}
int GNURadioInput::getSampleRate() const
{
return m_settings.m_sampRate;
}
quint64 GNURadioInput::getCenterFrequency() const
{
return m_generalSettings.m_centerFrequency;
}
bool GNURadioInput::handleMessage(Message* message)
{
if(MsgConfigureGNURadio::match(message)) {
MsgConfigureGNURadio* conf = (MsgConfigureGNURadio*)message;
if(!applySettings(conf->getGeneralSettings(), conf->getSettings(), false))
qDebug("Gnuradio config error");
return true;
} else {
return false;
}
}
bool GNURadioInput::applySettings(const GeneralSettings& generalSettings,
const Settings& settings,
bool force)
{
QMutexLocker mutexLocker(&m_mutex);
m_settings.m_args = settings.m_args;
if ( NULL == m_GnuradioThread )
return true;
osmosdr::source::sptr radio = m_GnuradioThread->radio();
try {
if((m_settings.m_freqCorr != settings.m_freqCorr) || force) {
m_settings.m_freqCorr = settings.m_freqCorr;
radio->set_freq_corr( m_settings.m_freqCorr );
}
if((m_generalSettings.m_centerFrequency != generalSettings.m_centerFrequency) || force) {
m_generalSettings.m_centerFrequency = generalSettings.m_centerFrequency;
radio->set_center_freq( m_generalSettings.m_centerFrequency );
}
for ( int i = 0; i < settings.m_namedGains.size(); i++ )
{
if((m_settings.m_namedGains[i].second != settings.m_namedGains[i].second) || force) {
m_settings.m_namedGains[i].second = settings.m_namedGains[i].second;
radio->set_gain( settings.m_namedGains[i].second,
settings.m_namedGains[i].first.toStdString() );
}
}
if((m_settings.m_sampRate != settings.m_sampRate) || force) {
m_settings.m_sampRate = settings.m_sampRate;
radio->set_sample_rate( m_settings.m_sampRate );
}
if((m_settings.m_antenna != settings.m_antenna) || force) {
m_settings.m_antenna = settings.m_antenna;
radio->set_antenna( m_settings.m_antenna.toStdString() );
}
if((m_settings.m_dcoff != settings.m_dcoff) || force) {
m_settings.m_dcoff = settings.m_dcoff;
for ( int i = 0; i < m_dcoffs.size(); i++ )
{
if ( m_dcoffs[i] != m_settings.m_dcoff )
continue;
radio->set_dc_offset_mode( i );
break;
}
}
if((m_settings.m_iqbal != settings.m_iqbal) || force) {
m_settings.m_iqbal = settings.m_iqbal;
for ( int i = 0; i < m_iqbals.size(); i++ )
{
if ( m_iqbals[i] != m_settings.m_iqbal )
continue;
radio->set_iq_balance_mode( i );
break;
}
}
if((m_settings.m_bandwidth != settings.m_bandwidth) ||
(0.0f == settings.m_bandwidth) || force) {
m_settings.m_bandwidth = settings.m_bandwidth;
/* setting the BW to 0.0 triggers automatic bandwidth
* selection when supported by device */
radio->set_bandwidth( m_settings.m_bandwidth );
}
} catch ( std::exception &ex ) {
qDebug("%s", ex.what());
return false;
}
return true;
}
@@ -0,0 +1,156 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
// written by Christian Daniel //
// Copyright (C) 2013 by Dimitri Stolnikov <horiz0n@gmx.net> //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_GNURADIOINPUT_H
#define INCLUDE_GNURADIOINPUT_H
#include "dsp/samplesource/samplesource.h"
#include <QString>
#include <QPair>
class GnuradioThread;
class GNURadioInput : public SampleSource {
public:
struct Settings {
QString m_args;
double m_freqMin;
double m_freqMax;
double m_freqCorr;
QList< QPair< QString, double > > m_namedGains;
double m_sampRate;
QString m_antenna;
QString m_dcoff;
QString m_iqbal;
double m_bandwidth;
Settings();
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
};
class MsgConfigureGNURadio : public Message {
MESSAGE_CLASS_DECLARATION
public:
const GeneralSettings& getGeneralSettings() const { return m_generalSettings; }
const Settings& getSettings() const { return m_settings; }
static MsgConfigureGNURadio* create(const GeneralSettings& generalSettings, const Settings& settings)
{
return new MsgConfigureGNURadio(generalSettings, settings);
}
protected:
GeneralSettings m_generalSettings;
Settings m_settings;
MsgConfigureGNURadio(const GeneralSettings& generalSettings, const Settings& settings) :
Message(),
m_generalSettings(generalSettings),
m_settings(settings)
{ }
};
class MsgReportGNURadio : public Message {
MESSAGE_CLASS_DECLARATION
public:
const std::vector< std::pair< QString, std::vector<double> > >& getNamedGains() const { return m_namedGains; }
const double getFreqMin() const { return m_freqMin; }
const double getFreqMax() const { return m_freqMax; }
const double getFreqCorr() const { return m_freqCorr; }
const std::vector<double>& getSampRates() const { return m_sampRates; }
const std::vector<QString>& getAntennas() const { return m_antennas; }
const std::vector<QString>& getDCOffs() const { return m_dcoffs; }
const std::vector<QString>& getIQBals() const { return m_iqbals; }
const std::vector<double>& getBandwidths() const { return m_bandwidths; }
static MsgReportGNURadio* create(const double freqMin,
const double freqMax,
const double freqCorr,
const std::vector< std::pair< QString, std::vector<double> > >& namedGains,
const std::vector<double>& sampRates,
const std::vector<QString>& antennas,
const std::vector<QString>& dcoffs,
const std::vector<QString>& iqbals,
const std::vector<double>& bandwidths)
{
return new MsgReportGNURadio(freqMin, freqMax, freqCorr, namedGains, sampRates, antennas, dcoffs, iqbals, bandwidths);
}
protected:
double m_freqMin;
double m_freqMax;
double m_freqCorr;
std::vector< std::pair< QString, std::vector<double> > > m_namedGains;
std::vector<double> m_sampRates;
std::vector<QString> m_antennas;
std::vector<QString> m_dcoffs;
std::vector<QString> m_iqbals;
std::vector<double> m_bandwidths;
MsgReportGNURadio(const double freqMin,
const double freqMax,
const double freqCorr,
const std::vector< std::pair< QString, std::vector<double> > >& namedGains,
const std::vector<double>& sampRates,
const std::vector<QString>& antennas,
const std::vector<QString>& dcoffs,
const std::vector<QString>& iqbals,
const std::vector<double>& bandwidths) :
Message(),
m_freqMin(freqMin),
m_freqMax(freqMax),
m_freqCorr(freqCorr),
m_namedGains(namedGains),
m_sampRates(sampRates),
m_antennas(antennas),
m_dcoffs(dcoffs),
m_iqbals(iqbals),
m_bandwidths(bandwidths)
{ }
};
GNURadioInput(MessageQueue* msgQueueToGUI);
~GNURadioInput();
bool startInput(int device);
void stopInput();
const QString& getDeviceDescription() const;
int getSampleRate() const;
quint64 getCenterFrequency() const;
bool handleMessage(Message* message);
private:
QMutex m_mutex;
Settings m_settings;
GnuradioThread* m_GnuradioThread;
QString m_deviceDescription;
std::vector< QString > m_dcoffs;
std::vector< QString > m_iqbals;
bool applySettings(const GeneralSettings& generalSettings,
const Settings& settings,
bool force);
};
#endif // INCLUDE_GNURADIOINPUT_H
@@ -0,0 +1,52 @@
#include <QtPlugin>
#include <QAction>
#include "plugin/pluginapi.h"
#include "util/simpleserializer.h"
#include "gnuradioplugin.h"
#include "gnuradiogui.h"
const PluginDescriptor GNURadioPlugin::m_pluginDescriptor = {
QString("GR-OsmoSDR Input"),
QString("1.0"),
QString("(c) Dimitri Stolnikov <horiz0n@gmx.net>"),
QString("http://sdr.osmocom.org/trac/wiki/GrOsmoSDR"),
true,
QString("http://cgit.osmocom.org/cgit/gr-osmosdr")
};
GNURadioPlugin::GNURadioPlugin(QObject* parent) :
QObject(parent)
{
}
const PluginDescriptor& GNURadioPlugin::getPluginDescriptor() const
{
return m_pluginDescriptor;
}
void GNURadioPlugin::initPlugin(PluginAPI* pluginAPI)
{
m_pluginAPI = pluginAPI;
m_pluginAPI->registerSampleSource("org.osmocom.sdr.samplesource.gr-osmosdr", this);
}
PluginInterface::SampleSourceDevices GNURadioPlugin::enumSampleSources()
{
SampleSourceDevices result;
result.append(SampleSourceDevice("GNURadio OsmoSDR Driver", "org.osmocom.sdr.samplesource.gr-osmosdr", QByteArray()));
return result;
}
PluginGUI* GNURadioPlugin::createSampleSource(const QString& sourceName, const QByteArray& address)
{
if(sourceName == "org.osmocom.sdr.samplesource.gr-osmosdr") {
GNURadioGui* gui = new GNURadioGui(m_pluginAPI);
m_pluginAPI->setInputGUI(gui);
return gui;
} else {
return NULL;
}
}
@@ -0,0 +1,27 @@
#ifndef INCLUDE_GNURADIOPLUGIN_H
#define INCLUDE_GNURADIOPLUGIN_H
#include <QObject>
#include "plugin/plugininterface.h"
class GNURadioPlugin : public QObject, PluginInterface {
Q_OBJECT
Q_INTERFACES(PluginInterface)
Q_PLUGIN_METADATA(IID "org.osmocom.sdr.samplesource.gr-osmosdr")
public:
explicit GNURadioPlugin(QObject* parent = NULL);
const PluginDescriptor& getPluginDescriptor() const;
void initPlugin(PluginAPI* pluginAPI);
SampleSourceDevices enumSampleSources();
PluginGUI* createSampleSource(const QString& sourceName, const QByteArray& address);
private:
static const PluginDescriptor m_pluginDescriptor;
PluginAPI* m_pluginAPI;
};
#endif // INCLUDE_GNURADIOPLUGIN_H
@@ -0,0 +1,144 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
// written by Christian Daniel //
// Copyright (C) 2013 by Dimitri Stolnikov <horiz0n@gmx.net> //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <errno.h>
#include "gnuradiothread.h"
#include "dsp/samplefifo.h"
#include <gnuradio/sync_block.h>
#include <gnuradio/io_signature.h>
////////////////////////////////////////////////////////////////////////////////
class gr_adaptor;
typedef boost::shared_ptr< gr_adaptor > gr_adaptor_sptr;
gr_adaptor_sptr make_gr_adaptor (SampleFifo* sampleFifo);
class gr_adaptor : public gr::sync_block
{
public:
gr_adaptor (SampleFifo* sampleFifo);
~gr_adaptor ();
int work (int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
private:
SampleFifo *m_sampleFifo;
};
gr_adaptor_sptr
make_gr_adaptor (SampleFifo *sampleFifo)
{
return gr_adaptor_sptr (new gr_adaptor (sampleFifo));
}
gr_adaptor::gr_adaptor (SampleFifo *sampleFifo)
: gr::sync_block("gr_adaptor",
gr::io_signature::make(1, 1, sizeof (gr_complex)),
gr::io_signature::make(0, 0, 0)),
m_sampleFifo(sampleFifo)
{
}
gr_adaptor::~gr_adaptor ()
{
}
int
gr_adaptor::work (int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const gr_complex *in = (const gr_complex *) input_items[0];
std::vector<qint16> buffer(noutput_items * 2, 0);
std::vector<qint16>::iterator it = buffer.begin();
for (int i = 0; i < noutput_items; i++)
{
*it++ = in[i].real() * 32000;
*it++ = in[i].imag() * 32000;
}
// we must push at least 4 bytes into the fifo
m_sampleFifo->write((const quint8*)buffer.data(),
(it - buffer.begin()) * sizeof(qint16));
// Tell runtime system how many input items we consumed on
// each input stream.
consume_each(noutput_items);
// Tell runtime system how many output items we produced.
return 0;
}
////////////////////////////////////////////////////////////////////////////////
GnuradioThread::GnuradioThread(QString args, SampleFifo* sampleFifo, QObject* parent) :
QThread(parent),
m_running(false),
m_args(args),
m_sampleFifo(sampleFifo)
{
}
GnuradioThread::~GnuradioThread()
{
stopWork();
}
void GnuradioThread::startWork()
{
m_startWaitMutex.lock();
start();
while(!m_running)
m_startWaiter.wait(&m_startWaitMutex, 100);
m_startWaitMutex.unlock();
}
void GnuradioThread::stopWork()
{
m_running = false;
m_top->stop();
wait();
}
void GnuradioThread::run()
{
m_top = gr::make_top_block( "flowgraph" );
m_src = osmosdr::source::make( m_args.toStdString() );
/* now since we've constructed our shared objects, we allow the calling
* thread to continue it's work and send some radio settings to us. */
m_running = true;
m_startWaiter.wakeAll();
gr_adaptor_sptr adaptor = make_gr_adaptor(m_sampleFifo);
m_top->connect(m_src, 0, adaptor, 0);
m_top->run();
m_running = false;
}
@@ -0,0 +1,64 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
// written by Christian Daniel //
// Copyright (C) 2013 by Dimitri Stolnikov <horiz0n@gmx.net> //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_GNURADIOTHREAD_H
#define INCLUDE_GNURADIOTHREAD_H
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <gnuradio/top_block.h>
#include <osmosdr/source.h>
class SampleFifo;
class GnuradioThread : public QThread {
Q_OBJECT
public:
GnuradioThread(QString args, SampleFifo* sampleFifo, QObject* parent = NULL);
~GnuradioThread();
void startWork();
void stopWork();
osmosdr::source::sptr radio() { return m_src; }
private:
#pragma pack(push, 1)
struct Sample {
qint16 i;
qint16 q;
};
#pragma pack(pop)
QMutex m_startWaitMutex;
QWaitCondition m_startWaiter;
bool m_running;
QString m_args;
SampleFifo* m_sampleFifo;
gr::top_block_sptr m_top;
osmosdr::source::sptr m_src;
void run();
};
#endif // INCLUDE_GNURADIOTHREAD_H