PulseView  unreleased development snapshot
A Qt-based sigrok GUI
session.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of the PulseView project.
3  *
4  * Copyright (C) 2012-14 Joel Holdsworth <joel@airwebreathe.org.uk>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef PULSEVIEW_PV_SESSION_HPP
21 #define PULSEVIEW_PV_SESSION_HPP
22 
23 #ifdef ENABLE_FLOW
24 #include <atomic>
25 #include <condition_variable>
26 #endif
27 
28 #include <deque>
29 #include <functional>
30 #include <map>
31 #include <memory>
32 #include <mutex>
33 #include <set>
34 #include <string>
35 #include <thread>
36 #include <vector>
37 
38 #include <glibmm/datetime.h>
39 
40 #include <QObject>
41 #include <QSettings>
42 #include <QString>
43 #include <QElapsedTimer>
44 
45 #ifdef ENABLE_FLOW
46 #include <gstreamermm.h>
47 #include <libsigrokflow/libsigrokflow.hpp>
48 #endif
49 
50 #include "metadata_obj.hpp"
51 #include "util.hpp"
52 #include "views/viewbase.hpp"
53 
54 using std::deque;
55 using std::function;
56 using std::map;
57 using std::mutex;
58 using std::recursive_mutex;
59 using std::shared_ptr;
60 using std::string;
61 using std::unordered_set;
62 
63 #ifdef ENABLE_FLOW
64 using Glib::RefPtr;
65 using Gst::AppSink;
66 using Gst::Element;
67 using Gst::Pipeline;
68 #endif
69 
70 struct srd_decoder;
71 struct srd_channel;
72 
73 namespace sigrok {
74 class Analog;
75 class Channel;
76 class Device;
77 class InputFormat;
78 class Logic;
79 class Meta;
80 class Option;
81 class OutputFormat;
82 class Packet;
83 class Session;
84 } // namespace sigrok
85 
86 using sigrok::Option;
87 
88 namespace pv {
89 
90 class DeviceManager;
91 
92 namespace data {
93 class Analog;
94 class AnalogSegment;
95 class DecodeSignal;
96 class Logic;
97 class LogicSegment;
98 class SignalBase;
99 class SignalData;
100 class SignalGroup;
101 }
102 
103 namespace devices {
104 class Device;
105 }
106 
107 namespace toolbars {
108 class MainBar;
109 }
110 
111 namespace views {
112 class ViewBase;
113 }
114 
115 using pv::views::ViewType;
116 
117 class Session : public QObject
118 {
119  Q_OBJECT
120 
121 public:
125  Running
126  };
127 
128  static shared_ptr<sigrok::Context> sr_context;
129 
130 public:
131  Session(DeviceManager &device_manager, QString name);
132 
133  ~Session();
134 
135  DeviceManager& device_manager();
136 
137  const DeviceManager& device_manager() const;
138 
139  shared_ptr<sigrok::Session> session() const;
140 
141  shared_ptr<devices::Device> device() const;
142 
143  QString name() const;
144  void set_name(QString name);
145 
146  QString save_path() const;
147  void set_save_path(QString path);
148 
149  const vector< shared_ptr<views::ViewBase> > views() const;
150 
151  shared_ptr<views::ViewBase> main_view() const;
152  shared_ptr<pv::toolbars::MainBar> main_bar() const;
153  void set_main_bar(shared_ptr<pv::toolbars::MainBar> main_bar);
154 
158  bool data_saved() const;
159 
160  void save_setup(QSettings &settings) const;
161  void save_settings(QSettings &settings) const;
162  void restore_setup(QSettings &settings);
163  void restore_settings(QSettings &settings);
164 
168  void select_device(shared_ptr<devices::Device> device);
169 
173  void set_device(shared_ptr<devices::Device> device);
174  void set_default_device();
175  bool using_file_device() const;
176 
177  void load_init_file(const string &file_name, const string &format,
178  const string &setup_file_name);
179 
180  void load_file(QString file_name, QString setup_file_name = QString(),
181  shared_ptr<sigrok::InputFormat> format = nullptr,
182  const map<string, Glib::VariantBase> &options =
183  map<string, Glib::VariantBase>());
184 
185  capture_state get_capture_state() const;
186  void start_capture(function<void (const QString)> error_handler);
187  void stop_capture();
188 
189  double get_samplerate() const;
190  Glib::DateTime get_acquisition_start_time() const;
191 
192  uint32_t get_highest_segment_id() const;
193  uint64_t get_segment_sample_count(uint32_t segment_id) const;
194 
195  vector<util::Timestamp> get_triggers(uint32_t segment_id) const;
196 
197  void register_view(shared_ptr<views::ViewBase> view);
198  void deregister_view(shared_ptr<views::ViewBase> view);
199  bool has_view(shared_ptr<views::ViewBase> view);
200 
201  const vector< shared_ptr<data::SignalBase> > signalbases() const;
202  uint32_t get_signal_count(data::SignalBase::ChannelType type) const;
203  uint32_t get_next_signal_index(data::SignalBase::ChannelType type);
204 
205  void add_generated_signal(shared_ptr<data::SignalBase> signal);
206  void remove_generated_signal(shared_ptr<data::SignalBase> signal);
207 
208 #ifdef ENABLE_DECODE
209  shared_ptr<data::DecodeSignal> add_decode_signal();
210 
211  void remove_decode_signal(shared_ptr<data::DecodeSignal> signal);
212 #endif
213 
214  bool all_segments_complete(uint32_t segment_id) const;
215 
216  MetadataObjManager* metadata_obj_manager();
217 
218 private:
219  void set_capture_state(capture_state state);
220 
221  void update_signals();
222 
223  shared_ptr<data::SignalBase> signalbase_from_channel(
224  shared_ptr<sigrok::Channel> channel) const;
225 
226  static map<string, Glib::VariantBase> input_format_options(
227  vector<string> user_spec,
228  map<string, shared_ptr<Option>> fmt_opts);
229 
230  void sample_thread_proc(function<void (const QString)> error_handler);
231 
232  void free_unused_memory();
233 
234  void signal_new_segment();
235  void signal_segment_completed();
236 
237 #ifdef ENABLE_FLOW
238  bool on_gst_bus_message(const Glib::RefPtr<Gst::Bus>& bus, const Glib::RefPtr<Gst::Message>& message);
239 
240  Gst::FlowReturn on_gst_new_sample();
241 #endif
242 
243  void feed_in_header();
244  void feed_in_meta(shared_ptr<sigrok::Meta> meta);
245  void feed_in_trigger();
246  void feed_in_frame_begin();
247  void feed_in_frame_end();
248  void feed_in_logic(shared_ptr<sigrok::Logic> logic);
249  void feed_in_analog(shared_ptr<sigrok::Analog> analog);
250 
251  void data_feed_in(shared_ptr<sigrok::Device> device,
252  shared_ptr<sigrok::Packet> packet);
253 
254 Q_SIGNALS:
255  void capture_state_changed(int state);
256  void device_changed();
257 
258  void signals_changed();
259 
260  void name_changed();
261 
262  void trigger_event(int segment_id, util::Timestamp location);
263 
264  void new_segment(int new_segment_id);
265  void segment_completed(int segment_id);
266 
267  void data_received();
268 
269  void add_view(ViewType type, Session *session);
270  void session_error_raised(const QString text, const QString info_text);
271 
272 public Q_SLOTS:
273  void on_data_saved();
274 
275 #ifdef ENABLE_DECODE
276  void on_new_decoders_selected(vector<const srd_decoder*> decoders);
277 #endif
278 
279 private:
281 
283  shared_ptr<devices::Device> device_;
284  QString default_name_, name_, save_path_;
285 
286  vector< shared_ptr<views::ViewBase> > views_;
287  shared_ptr<pv::views::ViewBase> main_view_;
288 
289  shared_ptr<pv::toolbars::MainBar> main_bar_;
290 
291  mutable mutex sampling_mutex_;
293 
294  vector< shared_ptr<data::SignalBase> > signalbases_;
295  unordered_set< shared_ptr<data::SignalData> > all_signal_data_;
296  deque<data::SignalGroup*> signal_groups_;
297  map<uint8_t, uint32_t> next_index_list_; // signal type -> index counter
298 
300  vector< std::pair<uint32_t, util::Timestamp> > trigger_list_;
301 
302  mutable recursive_mutex data_mutex_;
303  shared_ptr<data::Logic> logic_data_;
304  uint64_t cur_samplerate_;
305  shared_ptr<data::LogicSegment> cur_logic_segment_;
306  map< shared_ptr<sigrok::Channel>, shared_ptr<data::AnalogSegment> >
309  vector<uint64_t> segment_sample_count_;
310 
311  std::thread sampling_thread_;
312 
316 
317  QElapsedTimer acq_time_;
318  Glib::DateTime acq_start_time_;
319 
321 
322 #ifdef ENABLE_FLOW
323  RefPtr<Pipeline> pipeline_;
324  RefPtr<Element> source_;
325  RefPtr<AppSink> sink_;
326 
327  mutable mutex pipeline_done_mutex_;
328  mutable condition_variable pipeline_done_cond_;
329  atomic<bool> pipeline_done_interrupt_;
330 #endif
331 };
332 
333 } // namespace pv
334 
335 #endif // PULSEVIEW_PV_SESSION_HPP
shared_ptr< devices::Device > device_
Definition: session.hpp:283
libsigrok allows users to import and export data from files in various formats some of them as generic as others very specific For a list and make sure to check not so common and outright exotic ways to represent data and sigrok tries to suit as many needs as it can To see which formats your version of PulseView just click on the small arrow next to the _Open_ PulseView will ask for the file name to open Once you picked the you may be asked to specify the details of the format
bool data_saved_
Definition: session.hpp:314
vector< shared_ptr< data::SignalBase > > signalbases_
Definition: session.hpp:294
uint64_t cur_samplerate_
Definition: session.hpp:304
vector< std::pair< uint32_t, util::Timestamp > > trigger_list_
trigger_list_ contains pairs of <segment_id, timestamp> values
Definition: session.hpp:300
std::thread sampling_thread_
Definition: session.hpp:311
bool out_of_memory_
Definition: session.hpp:313
unordered_set< shared_ptr< data::SignalData > > all_signal_data_
Definition: session.hpp:295
map< uint8_t, uint32_t > next_index_list_
Definition: session.hpp:297
MetadataObjManager metadata_obj_manager_
Definition: session.hpp:320
static shared_ptr< sigrok::Context > sr_context
Definition: session.hpp:128
shared_ptr< data::LogicSegment > cur_logic_segment_
Definition: session.hpp:305
Mac OS X or Android For some we provide binary for others we provide installers and for others we provide AppImage containers that you can run without the need to install anything Check the the usual way to install PulseView is to install the packages provided by your distro s package manager sometimes only outdated packages are made available to you In that you have two options
Definition: installation.txt:2
shared_ptr< pv::toolbars::MainBar > main_bar_
Definition: session.hpp:289
int32_t highest_segment_id_
Definition: session.hpp:308
Glib::DateTime acq_start_time_
Definition: session.hpp:318
bool shutting_down_
Definition: session.hpp:280
static std::string data()
Definition: exprtk.hpp:39024
map< shared_ptr< sigrok::Channel >, shared_ptr< data::AnalogSegment > > cur_analog_segments_
Definition: session.hpp:307
bool frame_began_
Definition: session.hpp:315
shared_ptr< data::Logic > logic_data_
Definition: session.hpp:303
recursive_mutex data_mutex_
Definition: session.hpp:302
DeviceManager & device_manager_
Definition: session.hpp:282
deque< data::SignalGroup * > signal_groups_
Definition: session.hpp:296
shared_ptr< pv::views::ViewBase > main_view_
Definition: session.hpp:287
QElapsedTimer acq_time_
Definition: session.hpp:317
vector< shared_ptr< views::ViewBase > > views_
Definition: session.hpp:286
boost::multiprecision::number< boost::multiprecision::cpp_dec_float< 24 >, boost::multiprecision::et_off > Timestamp
Timestamp type providing yoctosecond resolution.
Definition: util.hpp:67
capture_state capture_state_
Definition: session.hpp:292
QString save_path_
Definition: session.hpp:284
vector< uint64_t > segment_sample_count_
Definition: session.hpp:309
mutex sampling_mutex_
Protects access to capture_state_.
Definition: session.hpp:291