Commit f8b2d1e4 authored by DreamSourceLab's avatar DreamSourceLab

Add FFT function @ DSO mode

parent ced33961
......@@ -57,5 +57,16 @@
<file>icons/start_dis_cn.png</file>
<file>icons/settings.png</file>
<file>darkstyle/style.qss</file>
<file>icons/export.png</file>
<file>icons/single.png</file>
<file>icons/single_dis.png</file>
<file>icons/math.png</file>
<file>icons/math_dis.png</file>
<file>icons/fft.png</file>
<file>icons/Blackman.png</file>
<file>icons/Flat_top.png</file>
<file>icons/Hamming.png</file>
<file>icons/Hann.png</file>
<file>icons/Rectangle.png</file>
</qresource>
</RCC>
......@@ -29,4 +29,10 @@
#define begin_element(x) (&x[0])
#define end_element(x) (&x[countof(x)])
enum View_type {
TIME_VIEW,
FFT_VIEW,
ALL_VIEW
};
#endif // DSVIEW_EXTDEF_H
DSView/icons/about.png

954 Bytes | W: | H:

DSView/icons/about.png

1.03 KB | W: | H:

DSView/icons/about.png
DSView/icons/about.png
DSView/icons/about.png
DSView/icons/about.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/export.png

942 Bytes | W: | H:

DSView/icons/export.png

919 Bytes | W: | H:

DSView/icons/export.png
DSView/icons/export.png
DSView/icons/export.png
DSView/icons/export.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/file.png

1012 Bytes | W: | H:

DSView/icons/file.png

1.84 KB | W: | H:

DSView/icons/file.png
DSView/icons/file.png
DSView/icons/file.png
DSView/icons/file.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/file_dis.png

641 Bytes | W: | H:

DSView/icons/file_dis.png

1.85 KB | W: | H:

DSView/icons/file_dis.png
DSView/icons/file_dis.png
DSView/icons/file_dis.png
DSView/icons/file_dis.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/instant.png

1.06 KB | W: | H:

DSView/icons/instant.png

2.32 KB | W: | H:

DSView/icons/instant.png
DSView/icons/instant.png
DSView/icons/instant.png
DSView/icons/instant.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/instant_dis.png

1.23 KB | W: | H:

DSView/icons/instant_dis.png

2.32 KB | W: | H:

DSView/icons/instant_dis.png
DSView/icons/instant_dis.png
DSView/icons/instant_dis.png
DSView/icons/instant_dis.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/math.png

2.88 KB | W: | H:

DSView/icons/math.png

5.54 KB | W: | H:

DSView/icons/math.png
DSView/icons/math.png
DSView/icons/math.png
DSView/icons/math.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/math_dis.png

2.89 KB | W: | H:

DSView/icons/math_dis.png

3.5 KB | W: | H:

DSView/icons/math_dis.png
DSView/icons/math_dis.png
DSView/icons/math_dis.png
DSView/icons/math_dis.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/measure.png

1.11 KB | W: | H:

DSView/icons/measure.png

4.02 KB | W: | H:

DSView/icons/measure.png
DSView/icons/measure.png
DSView/icons/measure.png
DSView/icons/measure.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/measure_dis.png

1002 Bytes | W: | H:

DSView/icons/measure_dis.png

4.04 KB | W: | H:

DSView/icons/measure_dis.png
DSView/icons/measure_dis.png
DSView/icons/measure_dis.png
DSView/icons/measure_dis.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/params.png

1.18 KB | W: | H:

DSView/icons/params.png

3.43 KB | W: | H:

DSView/icons/params.png
DSView/icons/params.png
DSView/icons/params.png
DSView/icons/params.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/params_dis.png

1.13 KB | W: | H:

DSView/icons/params_dis.png

3.42 KB | W: | H:

DSView/icons/params_dis.png
DSView/icons/params_dis.png
DSView/icons/params_dis.png
DSView/icons/params_dis.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/protocol.png

967 Bytes | W: | H:

DSView/icons/protocol.png

4.08 KB | W: | H:

DSView/icons/protocol.png
DSView/icons/protocol.png
DSView/icons/protocol.png
DSView/icons/protocol.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/protocol_cn.png

1.21 KB | W: | H:

DSView/icons/protocol_cn.png

3.19 KB | W: | H:

DSView/icons/protocol_cn.png
DSView/icons/protocol_cn.png
DSView/icons/protocol_cn.png
DSView/icons/protocol_cn.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/protocol_dis.png

931 Bytes | W: | H:

DSView/icons/protocol_dis.png

4.1 KB | W: | H:

DSView/icons/protocol_dis.png
DSView/icons/protocol_dis.png
DSView/icons/protocol_dis.png
DSView/icons/protocol_dis.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/search-bar.png

1.48 KB | W: | H:

DSView/icons/search-bar.png

3.59 KB | W: | H:

DSView/icons/search-bar.png
DSView/icons/search-bar.png
DSView/icons/search-bar.png
DSView/icons/search-bar.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/search-bar_dis.png

1.36 KB | W: | H:

DSView/icons/search-bar_dis.png

3.58 KB | W: | H:

DSView/icons/search-bar_dis.png
DSView/icons/search-bar_dis.png
DSView/icons/search-bar_dis.png
DSView/icons/search-bar_dis.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/start.png

1.05 KB | W: | H:

DSView/icons/start.png

2.13 KB | W: | H:

DSView/icons/start.png
DSView/icons/start.png
DSView/icons/start.png
DSView/icons/start.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/start_dis.png

1.32 KB | W: | H:

DSView/icons/start_dis.png

2.13 KB | W: | H:

DSView/icons/start_dis.png
DSView/icons/start_dis.png
DSView/icons/start_dis.png
DSView/icons/start_dis.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/stop.png

628 Bytes | W: | H:

DSView/icons/stop.png

2.06 KB | W: | H:

DSView/icons/stop.png
DSView/icons/stop.png
DSView/icons/stop.png
DSView/icons/stop.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/trigger.png

840 Bytes | W: | H:

DSView/icons/trigger.png

4 KB | W: | H:

DSView/icons/trigger.png
DSView/icons/trigger.png
DSView/icons/trigger.png
DSView/icons/trigger.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/trigger_dis.png

820 Bytes | W: | H:

DSView/icons/trigger_dis.png

4 KB | W: | H:

DSView/icons/trigger_dis.png
DSView/icons/trigger_dis.png
DSView/icons/trigger_dis.png
DSView/icons/trigger_dis.png
  • 2-up
  • Swipe
  • Onion skin
DSView/icons/wiki.png

2.72 KB | W: | H:

DSView/icons/wiki.png

3.48 KB | W: | H:

DSView/icons/wiki.png
DSView/icons/wiki.png
DSView/icons/wiki.png
DSView/icons/wiki.png
  • 2-up
  • Swipe
  • Onion skin
#include "fftstack.h"
/*
* This file is part of the PulseView project.
*
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mathstack.h"
FftStack::FftStack()
#include <boost/foreach.hpp>
#include <boost/thread/thread.hpp>
#include <pv/data/dso.h>
#include <pv/data/dsosnapshot.h>
#include <pv/sigsession.h>
#include <pv/view/dsosignal.h>
#define PI 3.1415
using namespace boost;
using namespace std;
namespace pv {
namespace data {
const QString MathStack::windows_support[5] = {
"Rectangle",
"Hann",
"Hamming",
"Blackman",
"Flat_top"
};
const uint64_t MathStack::length_support[5] = {
1024,
2048,
4096,
8192,
16384,
};
MathStack::MathStack(pv::SigSession &session, int index) :
_session(session),
_index(index),
_dc_ignore(true),
_sample_interval(1),
_math_state(Init)
{
}
MathStack::~MathStack()
{
_xn.clear();
_xk.clear();
_power_spectrum.clear();
fftw_destroy_plan(_fft_plan);
}
void MathStack::clear()
{
}
int MathStack::get_index() const
{
return _index;
}
uint64_t MathStack::get_sample_num() const
{
return _sample_num;
}
void MathStack::set_sample_num(uint64_t num)
{
_sample_num = num;
_xn.resize(_sample_num);
_xk.resize(_sample_num);
_power_spectrum.resize(_sample_num/2+1);
_fft_plan = fftw_plan_r2r_1d(_sample_num, _xn.data(), _xk.data(),
FFTW_R2HC, FFTW_ESTIMATE);
}
int MathStack::get_windows_index() const
{
return _windows_index;
}
void MathStack::set_windows_index(int index)
{
_windows_index = index;
}
bool MathStack::dc_ignored() const
{
return _dc_ignore;
}
void MathStack::set_dc_ignore(bool ignore)
{
_dc_ignore = ignore;
}
int MathStack::get_sample_interval() const
{
return _sample_interval;
}
void MathStack::set_sample_interval(int interval)
{
_sample_interval = interval;
}
const std::vector<QString> MathStack::get_windows_support() const
{
std::vector<QString> windows;
for (size_t i = 0; i < sizeof(windows_support)/sizeof(windows_support[0]); i++)
{
windows.push_back(windows_support[i]);
}
return windows;
}
const std::vector<uint64_t> MathStack::get_length_support() const
{
std::vector<uint64_t> length;
for (size_t i = 0; i < sizeof(length_support)/sizeof(length_support[0]); i++)
{
length.push_back(length_support[i]);
}
return length;
}
const std::vector<double> MathStack::get_fft_spectrum() const
{
std::vector<double> empty;
if (_math_state == Stopped)
return _power_spectrum;
else
return empty;
}
const double MathStack::get_fft_spectrum(uint64_t index) const
{
if (_math_state == Stopped && index < _power_spectrum.size())
return _power_spectrum[index];
else
return -1;
}
void MathStack::calc_fft()
{
_math_state = Running;
// Get the dso data
boost::shared_ptr<pv::data::Dso> data;
boost::shared_ptr<pv::view::DsoSignal> dsoSig;
BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _session.get_signals()) {
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(s)) {
if (dsoSig->get_index() == _index && dsoSig->enabled()) {
data = dsoSig->dso_data();
break;
}
}
}
if (!data)
return;
// Check we have a snapshot of data
const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
data->get_snapshots();
if (snapshots.empty())
return;
_snapshot = snapshots.front();
if (_snapshot->get_sample_count() < _sample_num*_sample_interval)
return;
// Get the samplerate and start time
_start_time = data->get_start_time();
_samplerate = data->samplerate();
if (_samplerate == 0.0)
_samplerate = 1.0;
// prepare _xn data
const double offset = dsoSig->get_zeroValue();
const double vscale = dsoSig->get_vDialValue() * dsoSig->get_factor() * DS_CONF_DSO_VDIVS / (1000*255.0);
const uint16_t step = _snapshot->get_channel_num() * _sample_interval;
const uint8_t *const samples = _snapshot->get_samples(0, _sample_num*_sample_interval-1, _index);
double wsum = 0;
for (int i = 0; i < _sample_num; i++) {
double w = window(i, _windows_index);
_xn[i] = ((double)samples[i*step] - offset) * vscale * w;
wsum += w;
}
// fft
fftw_execute(_fft_plan);
// calculate power spectrum
_power_spectrum[0] = abs(_xk[0])/wsum; /* DC component */
for (int k = 1; k < (_sample_num + 1) / 2; ++k) /* (k < N/2 rounded up) */
_power_spectrum[k] = sqrt((_xk[k]*_xk[k] + _xk[_sample_num-k]*_xk[_sample_num-k]) * 2) / wsum;
if (_sample_num % 2 == 0) /* N is even */
_power_spectrum[_sample_num/2] = abs(_xk[_sample_num/2])/wsum; /* Nyquist freq. */
_math_state = Stopped;
}
double MathStack::window(uint64_t i, int type)
{
const double n_m_1 = _sample_num-1;
switch(type) {
case 1: // Hann window
return 0.5*(1-cos(2*PI*i/n_m_1));
case 2: // Hamming window
return 0.54-0.46*cos(2*PI*i/n_m_1);
case 3: // Blackman window
return 0.42659-0.49656*cos(2*PI*i/n_m_1) + 0.076849*cos(4*PI*i/n_m_1);
case 4: // Flat_top window
return 1-1.93*cos(2*PI*i/n_m_1)+1.29*cos(4*PI*i/n_m_1)-
0.388*cos(6*PI*i/n_m_1)+0.028*cos(8*PI*i/n_m_1);
default:
return 1;
}
}
} // namespace data
} // namespace pv
#ifndef FFTSTACK_H
#define FFTSTACK_H
/*
* This file is part of the PulseView project.
*
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef DSVIEW_PV_DATA_MATHSTACK_H
#define DSVIEW_PV_DATA_MATHSTACK_H
class FftStack
#include "signaldata.h"
#include <list>
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <fftw3.h>
#include <QObject>
#include <QString>
namespace pv {
class SigSession;
namespace view {
class DsoSignal;
}
namespace data {
class DsoSnapshot;
class Dso;
class MathStack : public QObject, public SignalData
{
Q_OBJECT
private:
static const QString windows_support[5];
static const uint64_t length_support[5];
public:
FftStack();
enum math_state {
Init,
Stopped,
Running
};
public:
MathStack(pv::SigSession &_session, int index);
virtual ~MathStack();
void clear();
int get_index() const;
uint64_t get_sample_num() const;
void set_sample_num(uint64_t num);
int get_windows_index() const;
void set_windows_index(int index);
const std::vector<QString> get_windows_support() const;
const std::vector<uint64_t> get_length_support() const;
bool dc_ignored() const;
void set_dc_ignore(bool ignore);
int get_sample_interval() const;
void set_sample_interval(int interval);
const std::vector<double> get_fft_spectrum() const;
const double get_fft_spectrum(uint64_t index) const;
void calc_fft();
double window(uint64_t i, int type);
signals:
private:
pv::SigSession &_session;
int _index;
uint64_t _sample_num;
int _windows_index;
bool _dc_ignore;
int _sample_interval;
boost::shared_ptr<pv::data::DsoSnapshot> _snapshot;
std::unique_ptr<boost::thread> _math_thread;
math_state _math_state;
fftw_plan _fft_plan;
std::vector<double> _xn;
std::vector<double> _xk;
std::vector<double> _power_spectrum;
};
#endif // FFTSTACK_H
} // namespace data
} // namespace pv
#endif // DSVIEW_PV_DATA_MATHSTACK_H
This diff is collapsed.
#ifndef FFTOPTIONS_H
#define FFTOPTIONS_H
/*
* This file is part of the DSView project.
* DSView is based on PulseView.
*
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
* Copyright (C) 2013 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class FftOptions
#ifndef DSVIEW_PV_FFTOPTIONS_H
#define DSVIEW_PV_FFTOPTIONS_H
#include <QDialog>
#include <QDialogButtonBox>
#include <QFormLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QCheckBox>
#include <QComboBox>
#include <boost/shared_ptr.hpp>
#include "../device/devinst.h"
namespace pv {
class SigSession;
namespace dialogs {
class FftOptions : public QDialog
{
Q_OBJECT
private:
public:
FftOptions();
FftOptions(QWidget *parent, SigSession &session);
protected:
void accept();
void reject();
private slots:
void window_changed(QString str);
void len_changed(int index);
private:
SigSession &_session;
uint64_t _sample_limit;
QComboBox *_len_combobox;
QComboBox *_interval_combobox;
QCheckBox *_en_checkbox;
QComboBox *_ch_combobox;
QComboBox *_window_combobox;
QCheckBox *_dc_checkbox;
QComboBox *_view_combobox;
QComboBox *_dbv_combobox;
QLabel *_hint_label;
QFormLayout *_flayout;
QHBoxLayout *_hlayout;
QVBoxLayout *_layout;
QDialogButtonBox _button_box;
};
#endif // FFTOPTIONS_H
} // namespace dialogs
} // namespace pv
#endif // DSVIEW_PV_FFTOPTIONS_H
......@@ -134,7 +134,7 @@ MeasureDock::MeasureDock(QWidget *parent, View &view, SigSession &session) :
connect(_t3_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update()));
connect(_fen_checkBox, SIGNAL(stateChanged(int)), &_view, SLOT(set_measure_en(int)));
connect(_view.get_viewport(), SIGNAL(measure_updated()), this, SLOT(measure_updated()));
connect(&_view, SIGNAL(measure_updated()), this, SLOT(measure_updated()));
this->setWidget(_widget);
_widget->setGeometry(0, 0, sizeHint().width(), 2000);
......@@ -222,10 +222,10 @@ void MeasureDock::cursor_update()
void MeasureDock::measure_updated()
{
_width_label->setText(_view.get_viewport()->get_measure("width"));
_period_label->setText(_view.get_viewport()->get_measure("period"));
_freq_label->setText(_view.get_viewport()->get_measure("frequency"));
_duty_label->setText(_view.get_viewport()->get_measure("duty"));
_width_label->setText(_view.get_measure("width"));
_period_label->setText(_view.get_measure("period"));
_freq_label->setText(_view.get_measure("frequency"));
_duty_label->setText(_view.get_measure("duty"));
}
void MeasureDock::cursor_moved()
......
......@@ -112,6 +112,7 @@ void MainWindow::setup_ui()
{
setObjectName(QString::fromUtf8("MainWindow"));
setMinimumHeight(680);
setMinimumWidth(300);
resize(1024, 768);
// Set the window icon
......@@ -129,7 +130,7 @@ void MainWindow::setup_ui()
// Setup the sampling bar
_sampling_bar = new toolbars::SamplingBar(_session, this);
_trig_bar = new toolbars::TrigBar(this);
_trig_bar = new toolbars::TrigBar(_session, this);
_file_bar = new toolbars::FileBar(_session, this);
_logo_bar = new toolbars::LogoBar(_session, this);
......@@ -295,18 +296,8 @@ void MainWindow::update_device_list()
#ifdef ENABLE_DECODE
_protocol_widget->del_all_protocol();
#endif
_trig_bar->close_all();
if (_session.get_device()->dev_inst()->mode == LOGIC) {
_trig_bar->enable_protocol(true);
} else {
_trig_bar->enable_protocol(false);
}
if (_session.get_device()->dev_inst()->mode == DSO) {
_sampling_bar->enable_toggle(false);
} else {
_sampling_bar->enable_toggle(true);
}
_trig_bar->reload();
_sampling_bar->reload();
shared_ptr<pv::device::DevInst> selected_device = _session.get_device();
_device_manager.add_device(selected_device);
......@@ -534,8 +525,7 @@ void MainWindow::closeEvent(QCloseEvent *event)
void MainWindow::on_protocol(bool visible)
{
#ifdef ENABLE_DECODE
if (_session.get_device()->dev_inst()->mode == LOGIC)
_protocol_dock->setVisible(visible);
_protocol_dock->setVisible(visible);
#endif
}
......
......@@ -42,12 +42,14 @@
#include "data/decoderstack.h"
#include "data/decode/decoder.h"
#include "data/decodermodel.h"
#include "data/mathstack.h"
#include "view/analogsignal.h"
#include "view/dsosignal.h"
#include "view/logicsignal.h"
#include "view/groupsignal.h"
#include "view/decodetrace.h"
#include "view/mathtrace.h"
#include <assert.h>
#include <stdexcept>
......@@ -496,7 +498,6 @@ set< boost::shared_ptr<data::SignalData> > SigSession::get_data() const
assert(sig);
data.insert(sig->data());
}
data.insert(_group_data);
return data;
}
......@@ -605,6 +606,12 @@ void SigSession::read_sample_rate(const sr_dev_inst *const sdi)
assert(data);
data->set_samplerate(sample_rate);
}
BOOST_FOREACH(const boost::shared_ptr<view::MathTrace> m, _math_traces)
{
assert(m);
m->get_math_stack()->set_samplerate(sample_rate);
}
_group_data->set_samplerate(sample_rate);
}
void SigSession::feed_in_header(const sr_dev_inst *sdi)
......@@ -791,10 +798,10 @@ void SigSession::init_signals()
_signals.clear();
vector< boost::shared_ptr<view::Signal> >().swap(_signals);
_signals = sigs;
signals_changed();