PulseView  unreleased development snapshot
A Qt-based sigrok GUI
decodesignal.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the PulseView project.
3  *
4  * Copyright (C) 2017 Soeren Apel <soeren@apelpie.net>
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 #include "config.h"
21 
22 #include <cstring>
23 #include <forward_list>
24 #include <limits>
25 
26 #include <QDebug>
27 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
28 #include <QRegularExpression>
29 #endif
30 
31 #include "logic.hpp"
32 #include "logicsegment.hpp"
33 #include "decodesignal.hpp"
34 #include "signaldata.hpp"
35 
37 #include <pv/data/decode/row.hpp>
38 #include <pv/globalsettings.hpp>
39 #include <pv/session.hpp>
40 
41 using std::dynamic_pointer_cast;
42 using std::lock_guard;
43 using std::make_shared;
44 using std::min;
45 using std::out_of_range;
46 using std::shared_ptr;
47 using std::unique_lock;
50 
51 namespace pv {
52 namespace data {
53 
54 const double DecodeSignal::DecodeMargin = 1.0;
55 const double DecodeSignal::DecodeThreshold = 0.2;
56 const int64_t DecodeSignal::DecodeChunkLength = 256 * 1024;
57 
58 
61  session_(session),
62  srd_session_(nullptr),
63  logic_mux_data_invalid_(false),
64  stack_config_changed_(true),
65  current_segment_id_(0)
66 {
67  connect(&session_, SIGNAL(capture_state_changed(int)),
68  this, SLOT(on_capture_state_changed(int)));
69 }
70 
72 {
73  reset_decode(true);
74 }
75 
77 {
79 
81 }
82 
84 {
85  SignalBase::set_color(color);
86 
88 }
89 
90 const vector< shared_ptr<Decoder> >& DecodeSignal::decoder_stack() const
91 {
92  return stack_;
93 }
94 
95 void DecodeSignal::stack_decoder(const srd_decoder *decoder, bool restart_decode)
96 {
97  assert(decoder);
98 
99  // Set name if this decoder is the first in the list or the name is unchanged
100  const srd_decoder* prev_dec = stack_.empty() ? nullptr : stack_.back()->get_srd_decoder();
101  const QString prev_dec_name = prev_dec ? QString::fromUtf8(prev_dec->name) : QString();
102 
103  if ((stack_.empty()) || ((stack_.size() > 0) && (name() == prev_dec_name)))
104  set_name(QString::fromUtf8(decoder->name));
105 
106  const shared_ptr<Decoder> dec = make_shared<Decoder>(decoder, stack_.size());
107  stack_.push_back(dec);
108 
109  connect(dec.get(), SIGNAL(annotation_visibility_changed()),
110  this, SLOT(on_annotation_visibility_changed()));
111 
112  // Include the newly created decode channels in the channel lists
114 
115  stack_config_changed_ = true;
116  auto_assign_signals(dec);
119 
120  decoder_stacked((void*)dec.get());
121 
122  if (restart_decode)
123  begin_decode();
124 }
125 
127 {
128  assert(index >= 0);
129  assert(index < (int)stack_.size());
130 
131  // Find the decoder in the stack
132  auto iter = stack_.begin() + index;
133  assert(iter != stack_.end());
134 
135  shared_ptr<Decoder> dec = *iter;
136 
137  decoder_removed(dec.get());
138 
139  // Delete the element
140  stack_.erase(iter);
141 
142  // Update channels and decoded data
143  stack_config_changed_ = true;
145  begin_decode();
146 }
147 
149 {
150  auto iter = stack_.cbegin();
151  for (int i = 0; i < index; i++, iter++)
152  assert(iter != stack_.end());
153 
154  shared_ptr<Decoder> dec = *iter;
155 
156  // Toggle decoder visibility
157  bool state = false;
158  if (dec) {
159  state = !dec->visible();
160  dec->set_visible(state);
161  }
162 
163  return state;
164 }
165 
166 void DecodeSignal::reset_decode(bool shutting_down)
167 {
168  resume_decode(); // Make sure the decode thread isn't blocked by pausing
169 
170  if (stack_config_changed_ || shutting_down)
172  else
174 
175  if (decode_thread_.joinable()) {
176  decode_interrupt_ = true;
177  decode_input_cond_.notify_one();
178  decode_thread_.join();
179  }
180 
181  if (logic_mux_thread_.joinable()) {
182  logic_mux_interrupt_ = true;
183  logic_mux_cond_.notify_one();
184  logic_mux_thread_.join();
185  }
186 
188  segments_.clear();
189 
190  for (const shared_ptr<decode::Decoder>& dec : stack_)
191  if (dec->has_logic_output())
192  output_logic_[dec->get_srd_decoder()]->clear();
193 
194  logic_mux_data_.reset();
196 
197  if (!error_message_.isEmpty()) {
198  error_message_.clear();
199  // TODO Emulate noquote()
200  qDebug().nospace() << name() << ": Error cleared";
201  }
202 
203  decode_reset();
204 }
205 
207 {
208  if (decode_thread_.joinable()) {
209  decode_interrupt_ = true;
210  decode_input_cond_.notify_one();
211  decode_thread_.join();
212  }
213 
214  if (logic_mux_thread_.joinable()) {
215  logic_mux_interrupt_ = true;
216  logic_mux_cond_.notify_one();
217  logic_mux_thread_.join();
218  }
219 
220  reset_decode();
221 
222  if (stack_.size() == 0) {
223  set_error_message(tr("No decoders"));
224  return;
225  }
226 
227  assert(channels_.size() > 0);
228 
229  if (get_assigned_signal_count() == 0) {
230  set_error_message(tr("There are no channels assigned to this decoder"));
231  return;
232  }
233 
234  // Make sure that all assigned channels still provide logic data
235  // (can happen when a converted signal was assigned but the
236  // conversion removed in the meanwhile)
237  for (decode::DecodeChannel& ch : channels_)
238  if (ch.assigned_signal && !(ch.assigned_signal->logic_data() != nullptr))
239  ch.assigned_signal = nullptr;
240 
241  // Check that all decoders have the required channels
242  for (const shared_ptr<Decoder>& dec : stack_)
243  if (!dec->have_required_channels()) {
244  set_error_message(tr("One or more required channels "
245  "have not been specified"));
246  return;
247  }
248 
249  // Free the logic data and its segment(s) if it needs to be updated
251  logic_mux_data_.reset();
252 
253  if (!logic_mux_data_) {
254  const uint32_t ch_count = get_assigned_signal_count();
255  logic_mux_unit_size_ = (ch_count + 7) / 8;
256  logic_mux_data_ = make_shared<Logic>(ch_count);
257  }
258 
259  if (get_input_segment_count() == 0)
260  set_error_message(tr("No input data"));
261 
262  // Make sure the logic output data is complete and up-to-date
263  logic_mux_interrupt_ = false;
264  logic_mux_thread_ = std::thread(&DecodeSignal::logic_mux_proc, this);
265 
266  // Decode the muxed logic data
267  decode_interrupt_ = false;
268  decode_thread_ = std::thread(&DecodeSignal::decode_proc, this);
269 }
270 
272 {
273  decode_paused_ = true;
274 }
275 
277 {
278  // Manual unlocking is done before notifying, to avoid waking up the
279  // waiting thread only to block again (see notify_one for details)
280  decode_pause_mutex_.unlock();
281  decode_pause_cond_.notify_one();
282  decode_paused_ = false;
283 }
284 
286 {
287  return decode_paused_;
288 }
289 
290 const vector<decode::DecodeChannel> DecodeSignal::get_channels() const
291 {
292  return channels_;
293 }
294 
295 void DecodeSignal::auto_assign_signals(const shared_ptr<Decoder> dec)
296 {
297  bool new_assignment = false;
298 
299  // Disconnect all input signal notifications so we don't have duplicate connections
301 
302  // Try to auto-select channels that don't have signals assigned yet
303  for (decode::DecodeChannel& ch : channels_) {
304  // If a decoder is given, auto-assign only its channels
305  if (dec && (ch.decoder_ != dec))
306  continue;
307 
308  if (ch.assigned_signal)
309  continue;
310 
311  QString ch_name = ch.name.toLower();
312 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
313  ch_name = ch_name.replace(QRegularExpression("[-_.]"), " ");
314 #else
315  ch_name = ch_name.replace(QRegExp("[-_.]"), " ");
316 #endif
317 
318  shared_ptr<data::SignalBase> match;
319  for (const shared_ptr<data::SignalBase>& s : session_.signalbases()) {
320  if (!s->enabled())
321  continue;
322 
323  QString s_name = s->name().toLower();
324 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
325  s_name = s_name.replace(QRegularExpression("[-_.]"), " ");
326 #else
327  s_name = s_name.replace(QRegExp("[-_.]"), " ");
328 #endif
329 
330  if (s->logic_data() &&
331  ((ch_name.contains(s_name)) || (s_name.contains(ch_name)))) {
332  if (!match)
333  match = s;
334  else {
335  // Only replace an existing match if it matches more characters
336  int old_unmatched = ch_name.length() - match->name().length();
337  int new_unmatched = ch_name.length() - s->name().length();
338  if (abs(new_unmatched) < abs(old_unmatched))
339  match = s;
340  }
341  }
342  }
343 
344  // Prevent using a signal more than once as D1 would match e.g. D1 and D10
345  bool signal_not_already_used = true;
346  for (decode::DecodeChannel& ch : channels_)
347  if (ch.assigned_signal && (ch.assigned_signal == match))
348  signal_not_already_used = false;
349 
350  if (match && signal_not_already_used) {
351  ch.assigned_signal = match;
352  new_assignment = true;
353  }
354  }
355 
356  if (new_assignment) {
357  // Receive notifications when new sample data is available
359 
361  stack_config_changed_ = true;
364  }
365 }
366 
367 void DecodeSignal::assign_signal(const uint16_t channel_id, shared_ptr<const SignalBase> signal)
368 {
369  // Disconnect all input signal notifications so we don't have duplicate connections
371 
372  for (decode::DecodeChannel& ch : channels_)
373  if (ch.id == channel_id) {
374  ch.assigned_signal = signal;
376  }
377 
378  // Receive notifications when new sample data is available
380 
381  stack_config_changed_ = true;
384  begin_decode();
385 }
386 
388 {
389  // Count all channels that have a signal assigned to them
390  return count_if(channels_.begin(), channels_.end(),
391  [](decode::DecodeChannel ch) { return ch.assigned_signal.get(); });
392 }
393 
395 {
396  for (const shared_ptr<decode::Decoder>& dec : stack_) {
397  assert(dec);
398 
399  if (dec->has_logic_output()) {
400  const vector<decode::DecoderLogicOutputChannel> logic_channels =
401  dec->logic_output_channels();
402 
403  // All signals of a decoder share the same LogicSegment, so it's
404  // sufficient to check for only the first channel
405  const decode::DecoderLogicOutputChannel& first_ch = logic_channels[0];
406 
407  bool ch_exists = false;
408  for (const shared_ptr<SignalBase>& signal : output_signals_)
409  if (signal->internal_name() == first_ch.id)
410  ch_exists = true;
411 
412  if (!ch_exists) {
413  shared_ptr<Logic> logic_data = make_shared<Logic>(logic_channels.size());
414  logic_data->set_samplerate(get_samplerate());
415  output_logic_[dec->get_srd_decoder()] = logic_data;
416  output_logic_muxed_data_[dec->get_srd_decoder()] = vector<uint8_t>();
417 
418  shared_ptr<LogicSegment> logic_segment = make_shared<data::LogicSegment>(
419  *logic_data, 0, (logic_data->num_channels() + 7) / 8, get_samplerate());
420  logic_data->push_segment(logic_segment);
421 
422  uint index = 0;
423  for (const decode::DecoderLogicOutputChannel& logic_ch : logic_channels) {
424  shared_ptr<data::SignalBase> signal =
425  make_shared<data::SignalBase>(nullptr, LogicChannel);
426  signal->set_internal_name(logic_ch.id);
427  signal->set_index(index);
428  signal->set_data(logic_data);
429  output_signals_.push_back(signal);
431  index++;
432  }
433  } else {
434  shared_ptr<Logic> logic_data = output_logic_[dec->get_srd_decoder()];
435  logic_data->set_samplerate(get_samplerate());
436  for (shared_ptr<LogicSegment>& segment : logic_data->logic_segments())
437  segment->set_samplerate(get_samplerate());
438  }
439  }
440  }
441 
442  for (shared_ptr<SignalBase> s : output_signals_) {
443  s->set_name(s->internal_name() + " (" + name() + ")");
444  s->set_color(color());
445  }
446 
447  // TODO Assert that all sample rates are the same as the session's
448 }
449 
450 void DecodeSignal::set_initial_pin_state(const uint16_t channel_id, const int init_state)
451 {
452  for (decode::DecodeChannel& ch : channels_)
453  if (ch.id == channel_id)
454  ch.initial_pin_state = init_state;
455 
456  stack_config_changed_ = true;
458  begin_decode();
459 }
460 
462 {
463  double result = 0;
464 
465  // TODO For now, we simply return the first samplerate that we have
466  if (segments_.size() > 0)
467  result = segments_.front().samplerate;
468 
469  return result;
470 }
471 
473 {
474  pv::util::Timestamp result;
475 
476  // TODO For now, we simply return the first start time that we have
477  if (segments_.size() > 0)
478  result = segments_.front().start_time;
479 
480  return result;
481 }
482 
483 int64_t DecodeSignal::get_working_sample_count(uint32_t segment_id) const
484 {
485  // The working sample count is the highest sample number for
486  // which all used signals have data available, so go through all
487  // channels and use the lowest overall sample count of the segment
488 
489  int64_t count = std::numeric_limits<int64_t>::max();
490  bool no_signals_assigned = true;
491 
492  for (const decode::DecodeChannel& ch : channels_)
493  if (ch.assigned_signal) {
494  if (!ch.assigned_signal->logic_data())
495  return 0;
496 
497  no_signals_assigned = false;
498 
499  const shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
500  if (logic_data->logic_segments().empty())
501  return 0;
502 
503  if (segment_id >= logic_data->logic_segments().size())
504  return 0;
505 
506  const shared_ptr<const LogicSegment> segment = logic_data->logic_segments()[segment_id]->get_shared_ptr();
507  if (segment)
508  count = min(count, (int64_t)segment->get_sample_count());
509  }
510 
511  return (no_signals_assigned ? 0 : count);
512 }
513 
514 int64_t DecodeSignal::get_decoded_sample_count(uint32_t segment_id,
515  bool include_processing) const
516 {
517  lock_guard<mutex> decode_lock(output_mutex_);
518 
519  int64_t result = 0;
520 
521  if (segment_id >= segments_.size())
522  return result;
523 
524  if (include_processing)
525  result = segments_[segment_id].samples_decoded_incl;
526  else
527  result = segments_[segment_id].samples_decoded_excl;
528 
529  return result;
530 }
531 
532 vector<Row*> DecodeSignal::get_rows(bool visible_only)
533 {
534  vector<Row*> rows;
535 
536  for (const shared_ptr<Decoder>& dec : stack_) {
537  assert(dec);
538  if (visible_only && !dec->visible())
539  continue;
540 
541  for (Row* row : dec->get_rows())
542  rows.push_back(row);
543  }
544 
545  return rows;
546 }
547 
548 vector<const Row*> DecodeSignal::get_rows(bool visible_only) const
549 {
550  vector<const Row*> rows;
551 
552  for (const shared_ptr<Decoder>& dec : stack_) {
553  assert(dec);
554  if (visible_only && !dec->visible())
555  continue;
556 
557  for (const Row* row : dec->get_rows())
558  rows.push_back(row);
559  }
560 
561  return rows;
562 }
563 
564 uint64_t DecodeSignal::get_annotation_count(const Row* row, uint32_t segment_id) const
565 {
566  if (segment_id >= segments_.size())
567  return 0;
568 
569  const DecodeSegment* segment = &(segments_.at(segment_id));
570 
571  auto row_it = segment->annotation_rows.find(row);
572 
573  const RowData* rd;
574  if (row_it == segment->annotation_rows.end())
575  return 0;
576  else
577  rd = &(row_it->second);
578 
579  return rd->get_annotation_count();
580 }
581 
582 void DecodeSignal::get_annotation_subset(deque<const Annotation*> &dest,
583  const Row* row, uint32_t segment_id, uint64_t start_sample,
584  uint64_t end_sample) const
585 {
586  lock_guard<mutex> lock(output_mutex_);
587 
588  if (segment_id >= segments_.size())
589  return;
590 
591  const DecodeSegment* segment = &(segments_.at(segment_id));
592 
593  auto row_it = segment->annotation_rows.find(row);
594 
595  const RowData* rd;
596  if (row_it == segment->annotation_rows.end())
597  return;
598  else
599  rd = &(row_it->second);
600 
601  rd->get_annotation_subset(dest, start_sample, end_sample);
602 }
603 
604 void DecodeSignal::get_annotation_subset(deque<const Annotation*> &dest,
605  uint32_t segment_id, uint64_t start_sample, uint64_t end_sample) const
606 {
607  for (const Row* row : get_rows())
608  get_annotation_subset(dest, row, segment_id, start_sample, end_sample);
609 }
610 
611 uint32_t DecodeSignal::get_binary_data_chunk_count(uint32_t segment_id,
612  const Decoder* dec, uint32_t bin_class_id) const
613 {
614  if ((segments_.size() == 0) || (segment_id >= segments_.size()))
615  return 0;
616 
617  const DecodeSegment *segment = &(segments_[segment_id]);
618 
619  for (const DecodeBinaryClass& bc : segment->binary_classes)
620  if ((bc.decoder == dec) && (bc.info->bin_class_id == bin_class_id))
621  return bc.chunks.size();
622 
623  return 0;
624 }
625 
626 void DecodeSignal::get_binary_data_chunk(uint32_t segment_id,
627  const Decoder* dec, uint32_t bin_class_id, uint32_t chunk_id,
628  const vector<uint8_t> **dest, uint64_t *size)
629 {
630  if (segment_id >= segments_.size())
631  return;
632 
633  const DecodeSegment *segment = &(segments_[segment_id]);
634 
635  for (const DecodeBinaryClass& bc : segment->binary_classes)
636  if ((bc.decoder == dec) && (bc.info->bin_class_id == bin_class_id)) {
637  if (dest) *dest = &(bc.chunks.at(chunk_id).data);
638  if (size) *size = bc.chunks.at(chunk_id).data.size();
639  return;
640  }
641 }
642 
644  const Decoder* dec, uint32_t bin_class_id, uint64_t start_sample,
645  uint64_t end_sample, vector<uint8_t> *dest) const
646 {
647  assert(dest != nullptr);
648 
649  if (segment_id >= segments_.size())
650  return;
651 
652  const DecodeSegment *segment = &(segments_[segment_id]);
653 
654  const DecodeBinaryClass* bin_class = nullptr;
655  for (const DecodeBinaryClass& bc : segment->binary_classes)
656  if ((bc.decoder == dec) && (bc.info->bin_class_id == bin_class_id))
657  bin_class = &bc;
658 
659  // Determine overall size before copying to resize dest vector only once
660  uint64_t size = 0;
661  uint64_t matches = 0;
662  for (const DecodeBinaryDataChunk& chunk : bin_class->chunks)
663  if ((chunk.sample >= start_sample) && (chunk.sample < end_sample)) {
664  size += chunk.data.size();
665  matches++;
666  }
667  dest->resize(size);
668 
669  uint64_t offset = 0;
670  uint64_t matches2 = 0;
671  for (const DecodeBinaryDataChunk& chunk : bin_class->chunks)
672  if ((chunk.sample >= start_sample) && (chunk.sample < end_sample)) {
673  memcpy(dest->data() + offset, chunk.data.data(), chunk.data.size());
674  offset += chunk.data.size();
675  matches2++;
676 
677  // Make sure we don't overwrite memory if the array grew in the meanwhile
678  if (matches2 == matches)
679  break;
680  }
681 }
682 
684  const Decoder* dec, uint32_t bin_class_id, uint64_t start, uint64_t end,
685  vector<uint8_t> *dest) const
686 {
687  assert(dest != nullptr);
688 
689  if (segment_id >= segments_.size())
690  return;
691 
692  const DecodeSegment *segment = &(segments_[segment_id]);
693 
694  const DecodeBinaryClass* bin_class = nullptr;
695  for (const DecodeBinaryClass& bc : segment->binary_classes)
696  if ((bc.decoder == dec) && (bc.info->bin_class_id == bin_class_id))
697  bin_class = &bc;
698 
699  // Determine overall size before copying to resize dest vector only once
700  uint64_t size = 0;
701  uint64_t offset = 0;
702  for (const DecodeBinaryDataChunk& chunk : bin_class->chunks) {
703  if (offset >= start)
704  size += chunk.data.size();
705  offset += chunk.data.size();
706  if (offset >= end)
707  break;
708  }
709  dest->resize(size);
710 
711  offset = 0;
712  uint64_t dest_offset = 0;
713  for (const DecodeBinaryDataChunk& chunk : bin_class->chunks) {
714  if (offset >= start) {
715  memcpy(dest->data() + dest_offset, chunk.data.data(), chunk.data.size());
716  dest_offset += chunk.data.size();
717  }
718  offset += chunk.data.size();
719  if (offset >= end)
720  break;
721  }
722 }
723 
725  const Decoder* dec, uint32_t bin_class_id) const
726 {
727  if (segment_id >= segments_.size())
728  return nullptr;
729 
730  const DecodeSegment *segment = &(segments_[segment_id]);
731 
732  for (const DecodeBinaryClass& bc : segment->binary_classes)
733  if ((bc.decoder == dec) && (bc.info->bin_class_id == bin_class_id))
734  return &bc;
735 
736  return nullptr;
737 }
738 
739 const deque<const Annotation*>* DecodeSignal::get_all_annotations_by_segment(
740  uint32_t segment_id) const
741 {
742  if (segment_id >= segments_.size())
743  return nullptr;
744 
745  const DecodeSegment *segment = &(segments_[segment_id]);
746 
747  return &(segment->all_annotations);
748 }
749 
751 {
752  SignalBase::save_settings(settings);
753 
754  settings.setValue("decoders", (int)(stack_.size()));
755 
756  // Save decoder stack
757  int decoder_idx = 0;
758  for (const shared_ptr<Decoder>& decoder : stack_) {
759  settings.beginGroup("decoder" + QString::number(decoder_idx++));
760 
761 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
762  settings.setValue("id", (const char *)decoder->get_srd_decoder()->id);
763 #else
764  settings.setValue("id", decoder->get_srd_decoder()->id);
765 #endif
766  settings.setValue("visible", decoder->visible());
767 
768  // Save decoder options
769  const map<string, GVariant*>& options = decoder->options();
770 
771  settings.setValue("options", (int)options.size());
772 
773  // Note: Decoder::options() returns only the options
774  // that differ from the default. See binding::Decoder::getter()
775  int i = 0;
776  for (auto& option : options) {
777  settings.beginGroup("option" + QString::number(i));
778  settings.setValue("name", QString::fromStdString(option.first));
779  GlobalSettings::store_gvariant(settings, option.second);
780  settings.endGroup();
781  i++;
782  }
783 
784  // Save row properties
785  i = 0;
786  for (const Row* row : decoder->get_rows()) {
787  settings.beginGroup("row" + QString::number(i));
788  settings.setValue("visible", row->visible());
789  settings.endGroup();
790  i++;
791  }
792 
793  // Save class properties
794  i = 0;
795  for (const AnnotationClass* ann_class : decoder->ann_classes()) {
796  settings.beginGroup("ann_class" + QString::number(i));
797  settings.setValue("visible", ann_class->visible());
798  settings.endGroup();
799  i++;
800  }
801 
802  settings.endGroup();
803  }
804 
805  // Save channel mapping
806  settings.setValue("channels", (int)channels_.size());
807 
808  for (unsigned int channel_id = 0; channel_id < channels_.size(); channel_id++) {
809  auto channel = find_if(channels_.begin(), channels_.end(),
810  [&](decode::DecodeChannel ch) { return ch.id == channel_id; });
811 
812  if (channel == channels_.end()) {
813  qDebug() << "ERROR: Gap in channel index:" << channel_id;
814  continue;
815  }
816 
817  settings.beginGroup("channel" + QString::number(channel_id));
818 
819  settings.setValue("name", channel->name); // Useful for debugging
820  settings.setValue("initial_pin_state", channel->initial_pin_state);
821 
822  if (channel->assigned_signal)
823  settings.setValue("assigned_signal_name", channel->assigned_signal->name());
824 
825  settings.endGroup();
826  }
827 
828  // TODO Save logic output signal settings
829 }
830 
832 {
834 
835  // Restore decoder stack
836  GSList *dec_list = g_slist_copy((GSList*)srd_decoder_list());
837 
838  int decoders = settings.value("decoders").toInt();
839 
840  for (int decoder_idx = 0; decoder_idx < decoders; decoder_idx++) {
841  settings.beginGroup("decoder" + QString::number(decoder_idx));
842 
843  QString id = settings.value("id").toString();
844 
845  for (GSList *entry = dec_list; entry; entry = entry->next) {
846  const srd_decoder *dec = (srd_decoder*)entry->data;
847  if (!dec)
848  continue;
849 
850  if (QString::fromUtf8(dec->id) == id) {
851  shared_ptr<Decoder> decoder = make_shared<Decoder>(dec, stack_.size());
852 
853  connect(decoder.get(), SIGNAL(annotation_visibility_changed()),
854  this, SLOT(on_annotation_visibility_changed()));
855 
856  stack_.push_back(decoder);
857  decoder->set_visible(settings.value("visible", true).toBool());
858 
859  // Restore decoder options that differ from their default
860  int options = settings.value("options").toInt();
861 
862  for (int i = 0; i < options; i++) {
863  settings.beginGroup("option" + QString::number(i));
864  QString name = settings.value("name").toString();
865  GVariant *value = GlobalSettings::restore_gvariant(settings);
866  decoder->set_option(name.toUtf8(), value);
867  settings.endGroup();
868  }
869 
870  // Include the newly created decode channels in the channel lists
872 
873  // Restore row properties
874  int i = 0;
875  for (Row* row : decoder->get_rows()) {
876  settings.beginGroup("row" + QString::number(i));
877  row->set_visible(settings.value("visible", true).toBool());
878  settings.endGroup();
879  i++;
880  }
881 
882  // Restore class properties
883  i = 0;
884  for (AnnotationClass* ann_class : decoder->ann_classes()) {
885  settings.beginGroup("ann_class" + QString::number(i));
886  ann_class->set_visible(settings.value("visible", true).toBool());
887  settings.endGroup();
888  i++;
889  }
890 
891  break;
892  }
893  }
894 
895  settings.endGroup();
897  }
898 
899  // Restore channel mapping
900  unsigned int channels = settings.value("channels").toInt();
901 
902  const vector< shared_ptr<data::SignalBase> > signalbases =
904 
905  for (unsigned int channel_id = 0; channel_id < channels; channel_id++) {
906  auto channel = find_if(channels_.begin(), channels_.end(),
907  [&](decode::DecodeChannel ch) { return ch.id == channel_id; });
908 
909  if (channel == channels_.end()) {
910  qDebug() << "ERROR: Non-existant channel index:" << channel_id;
911  continue;
912  }
913 
914  settings.beginGroup("channel" + QString::number(channel_id));
915 
916  QString assigned_signal_name = settings.value("assigned_signal_name").toString();
917 
918  for (const shared_ptr<data::SignalBase>& signal : signalbases)
919  if ((signal->name() == assigned_signal_name) && (signal->type() != SignalBase::DecodeChannel))
920  channel->assigned_signal = signal;
921 
922  channel->initial_pin_state = settings.value("initial_pin_state").toInt();
923 
924  settings.endGroup();
925  }
926 
928 
929  // Update the internal structures
930  stack_config_changed_ = true;
934 
935  // TODO Restore logic output signal settings
936 
937  begin_decode();
938 }
939 
940 bool DecodeSignal::all_input_segments_complete(uint32_t segment_id) const
941 {
942  bool all_complete = true;
943 
944  for (const decode::DecodeChannel& ch : channels_)
945  if (ch.assigned_signal) {
946  if (!ch.assigned_signal->logic_data())
947  continue;
948 
949  const shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
950  if (logic_data->logic_segments().empty())
951  return false;
952 
953  if (segment_id >= logic_data->logic_segments().size())
954  return false;
955 
956  const shared_ptr<const LogicSegment> segment = logic_data->logic_segments()[segment_id]->get_shared_ptr();
957  if (segment && !segment->is_complete())
958  all_complete = false;
959  }
960 
961  return all_complete;
962 }
963 
965 {
966  uint64_t count = std::numeric_limits<uint64_t>::max();
967  bool no_signals_assigned = true;
968 
969  for (const decode::DecodeChannel& ch : channels_)
970  if (ch.assigned_signal) {
971  no_signals_assigned = false;
972 
973  const shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
974  if (!logic_data || logic_data->logic_segments().empty())
975  return 0;
976 
977  // Find the min value of all segment counts
978  if ((uint64_t)(logic_data->logic_segments().size()) < count)
979  count = logic_data->logic_segments().size();
980  }
981 
982  return (no_signals_assigned ? 0 : count);
983 }
984 
985 double DecodeSignal::get_input_samplerate(uint32_t segment_id) const
986 {
987  double samplerate = 0;
988 
989  for (const decode::DecodeChannel& ch : channels_)
990  if (ch.assigned_signal) {
991  const shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
992  if (!logic_data || logic_data->logic_segments().empty())
993  continue;
994 
995  try {
996  const shared_ptr<const LogicSegment> segment =
997  logic_data->logic_segments().at(segment_id)->get_shared_ptr();
998  if (segment)
999  samplerate = segment->samplerate();
1000  } catch (out_of_range&) {
1001  // Do nothing
1002  }
1003  break;
1004  }
1005 
1006  return samplerate;
1007 }
1008 
1009 Decoder* DecodeSignal::get_decoder_by_instance(const srd_decoder *const srd_dec)
1010 {
1011  for (shared_ptr<Decoder>& d : stack_)
1012  if (d->get_srd_decoder() == srd_dec)
1013  return d.get();
1014 
1015  return nullptr;
1016 }
1017 
1019 {
1020  vector<decode::DecodeChannel> prev_channels = channels_;
1021  channels_.clear();
1022 
1023  uint16_t id = 0;
1024 
1025  // Copy existing entries, create new as needed
1026  for (shared_ptr<Decoder>& decoder : stack_) {
1027  const srd_decoder* srd_dec = decoder->get_srd_decoder();
1028  const GSList *l;
1029 
1030  // Mandatory channels
1031  for (l = srd_dec->channels; l; l = l->next) {
1032  const struct srd_channel *const pdch = (struct srd_channel *)l->data;
1033  bool ch_added = false;
1034 
1035  // Copy but update ID if this channel was in the list before
1036  for (decode::DecodeChannel& ch : prev_channels)
1037  if (ch.pdch_ == pdch) {
1038  ch.id = id++;
1039  channels_.push_back(ch);
1040  ch_added = true;
1041  break;
1042  }
1043 
1044  if (!ch_added) {
1045  // Create new entry without a mapped signal
1046  decode::DecodeChannel ch = {id++, 0, false, nullptr,
1047  QString::fromUtf8(pdch->name), QString::fromUtf8(pdch->desc),
1048  SRD_INITIAL_PIN_SAME_AS_SAMPLE0, decoder, pdch};
1049  channels_.push_back(ch);
1050  }
1051  }
1052 
1053  // Optional channels
1054  for (l = srd_dec->opt_channels; l; l = l->next) {
1055  const struct srd_channel *const pdch = (struct srd_channel *)l->data;
1056  bool ch_added = false;
1057 
1058  // Copy but update ID if this channel was in the list before
1059  for (decode::DecodeChannel& ch : prev_channels)
1060  if (ch.pdch_ == pdch) {
1061  ch.id = id++;
1062  channels_.push_back(ch);
1063  ch_added = true;
1064  break;
1065  }
1066 
1067  if (!ch_added) {
1068  // Create new entry without a mapped signal
1069  decode::DecodeChannel ch = {id++, 0, true, nullptr,
1070  QString::fromUtf8(pdch->name), QString::fromUtf8(pdch->desc),
1071  SRD_INITIAL_PIN_SAME_AS_SAMPLE0, decoder, pdch};
1072  channels_.push_back(ch);
1073  }
1074  }
1075  }
1076 
1077  // Invalidate the logic output data if the channel assignment changed
1078  if (prev_channels.size() != channels_.size()) {
1079  // The number of channels changed, there's definitely a difference
1080  logic_mux_data_invalid_ = true;
1081  } else {
1082  // Same number but assignment may still differ, so compare all channels
1083  for (size_t i = 0; i < channels_.size(); i++) {
1084  const decode::DecodeChannel& p_ch = prev_channels[i];
1085  const decode::DecodeChannel& ch = channels_[i];
1086 
1087  if ((p_ch.pdch_ != ch.pdch_) ||
1088  (p_ch.assigned_signal != ch.assigned_signal)) {
1089  logic_mux_data_invalid_ = true;
1090  break;
1091  }
1092  }
1093 
1094  }
1095 
1096  channels_updated();
1097 }
1098 
1100 {
1101  // Submit channel list to every decoder, containing only the relevant channels
1102  for (shared_ptr<Decoder> dec : stack_) {
1103  vector<decode::DecodeChannel*> channel_list;
1104 
1105  for (decode::DecodeChannel& ch : channels_)
1106  if (ch.decoder_ == dec)
1107  channel_list.push_back(&ch);
1108 
1109  dec->set_channels(channel_list);
1110  }
1111 
1112  // Channel bit IDs must be in sync with the channel's apperance in channels_
1113  int id = 0;
1114  for (decode::DecodeChannel& ch : channels_)
1115  if (ch.assigned_signal)
1116  ch.bit_id = id++;
1117 }
1118 
1119 void DecodeSignal::mux_logic_samples(uint32_t segment_id, const int64_t start, const int64_t end)
1120 {
1121  // Enforce end to be greater than start
1122  if (end <= start)
1123  return;
1124 
1125  // Fetch the channel segments and their data
1126  vector<shared_ptr<const LogicSegment> > segments;
1127  vector<const uint8_t*> signal_data;
1128  vector<uint8_t> signal_in_bytepos;
1129  vector<uint8_t> signal_in_bitpos;
1130 
1131  for (decode::DecodeChannel& ch : channels_)
1132  if (ch.assigned_signal) {
1133  const shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
1134 
1135  shared_ptr<const LogicSegment> segment;
1136  if (segment_id < logic_data->logic_segments().size()) {
1137  segment = logic_data->logic_segments().at(segment_id)->get_shared_ptr();
1138  } else {
1139  qDebug() << "Muxer error for" << name() << ":" << ch.assigned_signal->name() \
1140  << "has no logic segment" << segment_id;
1141  logic_mux_interrupt_ = true;
1142  return;
1143  }
1144 
1145  if (!segment)
1146  return;
1147 
1148  segments.push_back(segment);
1149 
1150  uint8_t* data = new uint8_t[(end - start) * segment->unit_size()];
1151  segment->get_samples(start, end, data);
1152  signal_data.push_back(data);
1153 
1154  const int bitpos = ch.assigned_signal->logic_bit_index();
1155  signal_in_bytepos.push_back(bitpos / 8);
1156  signal_in_bitpos.push_back(bitpos % 8);
1157  }
1158 
1159  shared_ptr<LogicSegment> output_segment;
1160  try {
1161  output_segment = logic_mux_data_->logic_segments().at(segment_id);
1162  } catch (out_of_range&) {
1163  qDebug() << "Muxer error for" << name() << ": no logic mux segment" \
1164  << segment_id << "in mux_logic_samples(), mux segments size is" \
1165  << logic_mux_data_->logic_segments().size();
1166  logic_mux_interrupt_ = true;
1167  return;
1168  }
1169 
1170  // Perform the muxing of signal data into the output data
1171  uint8_t* output = new uint8_t[(end - start) * output_segment->unit_size()];
1172  unsigned int signal_count = signal_data.size();
1173 
1174  for (int64_t sample_cnt = 0; !logic_mux_interrupt_ && (sample_cnt < (end - start));
1175  sample_cnt++) {
1176 
1177  int bitpos = 0;
1178  uint8_t bytepos = 0;
1179 
1180  const int out_sample_pos = sample_cnt * output_segment->unit_size();
1181  for (unsigned int i = 0; i < output_segment->unit_size(); i++)
1182  output[out_sample_pos + i] = 0;
1183 
1184  for (unsigned int i = 0; i < signal_count; i++) {
1185  const int in_sample_pos = sample_cnt * segments[i]->unit_size();
1186  const uint8_t in_sample = 1 &
1187  ((signal_data[i][in_sample_pos + signal_in_bytepos[i]]) >> (signal_in_bitpos[i]));
1188 
1189  const uint8_t out_sample = output[out_sample_pos + bytepos];
1190 
1191  output[out_sample_pos + bytepos] = out_sample | (in_sample << bitpos);
1192 
1193  bitpos++;
1194  if (bitpos > 7) {
1195  bitpos = 0;
1196  bytepos++;
1197  }
1198  }
1199  }
1200 
1201  output_segment->append_payload(output, (end - start) * output_segment->unit_size());
1202  delete[] output;
1203 
1204  for (const uint8_t* data : signal_data)
1205  delete[] data;
1206 }
1207 
1209 {
1210  uint32_t input_segment_count;
1211  do {
1212  input_segment_count = get_input_segment_count();
1213  if (input_segment_count == 0) {
1214  // Wait for input data
1215  unique_lock<mutex> logic_mux_lock(logic_mux_mutex_);
1216  logic_mux_cond_.wait(logic_mux_lock);
1217  }
1218  } while ((!logic_mux_interrupt_) && (input_segment_count == 0));
1219 
1221  return;
1222 
1223  assert(logic_mux_data_);
1224 
1225  uint32_t segment_id = 0;
1226 
1227  // Create initial logic mux segment
1228  shared_ptr<LogicSegment> output_segment =
1229  make_shared<LogicSegment>(*logic_mux_data_, segment_id, logic_mux_unit_size_, 0);
1230  logic_mux_data_->push_segment(output_segment);
1231 
1232  output_segment->set_samplerate(get_input_samplerate(0));
1233 
1234  // Logic mux data is being updated
1235  logic_mux_data_invalid_ = false;
1236 
1237  uint64_t samples_to_process;
1238  do {
1239  do {
1240  const uint64_t input_sample_count = get_working_sample_count(segment_id);
1241  const uint64_t output_sample_count = output_segment->get_sample_count();
1242 
1243  samples_to_process =
1244  (input_sample_count > output_sample_count) ?
1245  (input_sample_count - output_sample_count) : 0;
1246 
1247  if (samples_to_process > 0) {
1248  const uint64_t unit_size = output_segment->unit_size();
1249  const uint64_t chunk_sample_count = DecodeChunkLength / unit_size;
1250 
1251  uint64_t processed_samples = 0;
1252  do {
1253  const uint64_t start_sample = output_sample_count + processed_samples;
1254  const uint64_t sample_count =
1255  min(samples_to_process - processed_samples, chunk_sample_count);
1256 
1257  mux_logic_samples(segment_id, start_sample, start_sample + sample_count);
1258  processed_samples += sample_count;
1259 
1260  // ...and process the newly muxed logic data
1261  decode_input_cond_.notify_one();
1262  } while (!logic_mux_interrupt_ && (processed_samples < samples_to_process));
1263  }
1264  } while (!logic_mux_interrupt_ && (samples_to_process > 0));
1265 
1266  if (!logic_mux_interrupt_) {
1267  // samples_to_process is now 0, we've exhausted the currently available input data
1268 
1269  // If the input segments are complete, we've completed this segment
1270  if (all_input_segments_complete(segment_id)) {
1271  if (!output_segment->is_complete())
1272  output_segment->set_complete();
1273 
1274  if (segment_id < get_input_segment_count() - 1) {
1275 
1276  // Process next segment
1277  segment_id++;
1278 
1279  output_segment =
1280  make_shared<LogicSegment>(*logic_mux_data_, segment_id,
1282  logic_mux_data_->push_segment(output_segment);
1283 
1284  output_segment->set_samplerate(get_input_samplerate(segment_id));
1285  } else {
1286  // Wait for more input data if we're processing the currently last segment
1287  unique_lock<mutex> logic_mux_lock(logic_mux_mutex_);
1288  logic_mux_cond_.wait(logic_mux_lock);
1289  }
1290  } else {
1291  // Input segments aren't all complete yet but samples_to_process is 0, wait for more input data
1292  unique_lock<mutex> logic_mux_lock(logic_mux_mutex_);
1293  logic_mux_cond_.wait(logic_mux_lock);
1294  }
1295  }
1296  } while (!logic_mux_interrupt_);
1297 }
1298 
1300  const int64_t abs_start_samplenum, const int64_t sample_count,
1301  const shared_ptr<const LogicSegment> input_segment)
1302 {
1303  const int64_t unit_size = input_segment->unit_size();
1304  const int64_t chunk_sample_count = DecodeChunkLength / unit_size;
1305 
1306  for (int64_t i = abs_start_samplenum;
1307  !decode_interrupt_ && (i < (abs_start_samplenum + sample_count));
1308  i += chunk_sample_count) {
1309 
1310  const int64_t chunk_end = min(i + chunk_sample_count,
1311  abs_start_samplenum + sample_count);
1312 
1313  {
1314  lock_guard<mutex> lock(output_mutex_);
1315  // Update the sample count showing the samples including currently processed ones
1316  segments_.at(current_segment_id_).samples_decoded_incl = chunk_end;
1317  }
1318 
1319  int64_t data_size = (chunk_end - i) * unit_size;
1320  uint8_t* chunk = new uint8_t[data_size];
1321  input_segment->get_samples(i, chunk_end, chunk);
1322 
1323  if (srd_session_send(srd_session_, i, chunk_end, chunk,
1324  data_size, unit_size) != SRD_OK) {
1325  set_error_message(tr("Decoder reported an error"));
1326  decode_interrupt_ = true;
1327  }
1328 
1329  delete[] chunk;
1330 
1331  {
1332  lock_guard<mutex> lock(output_mutex_);
1333  // Now that all samples are processed, the exclusive sample count catches up
1334  segments_.at(current_segment_id_).samples_decoded_excl = chunk_end;
1335  }
1336 
1337  // Notify the frontend that we processed some data and
1338  // possibly have new annotations as well
1339  new_annotations();
1340 
1341  if (decode_paused_) {
1342  unique_lock<mutex> pause_wait_lock(decode_pause_mutex_);
1343  decode_pause_cond_.wait(pause_wait_lock);
1344  }
1345  }
1346 }
1347 
1349 {
1350  current_segment_id_ = 0;
1351 
1352  // If there is no input data available yet, wait until it is or we're interrupted
1353  do {
1354  if (logic_mux_data_->logic_segments().size() == 0) {
1355  // Wait for input data
1356  unique_lock<mutex> input_wait_lock(input_mutex_);
1357  decode_input_cond_.wait(input_wait_lock);
1358  }
1359  } while ((!decode_interrupt_) && (logic_mux_data_->logic_segments().size() == 0));
1360 
1361  if (decode_interrupt_)
1362  return;
1363 
1364  shared_ptr<const LogicSegment> input_segment = logic_mux_data_->logic_segments().front()->get_shared_ptr();
1365  if (!input_segment)
1366  return;
1367 
1368  // Create the initial segment and set its sample rate so that we can pass it to SRD
1370  segments_.at(current_segment_id_).samplerate = input_segment->samplerate();
1371  segments_.at(current_segment_id_).start_time = input_segment->start_time();
1372 
1374 
1375  uint64_t samples_to_process = 0;
1376  uint64_t abs_start_samplenum = 0;
1377  do {
1378  // Keep processing new samples until we exhaust the input data
1379  do {
1380  samples_to_process = input_segment->get_sample_count() - abs_start_samplenum;
1381 
1382  if (samples_to_process > 0) {
1383  decode_data(abs_start_samplenum, samples_to_process, input_segment);
1384  abs_start_samplenum += samples_to_process;
1385  }
1386  } while (!decode_interrupt_ && (samples_to_process > 0));
1387 
1388  if (!decode_interrupt_) {
1389  // samples_to_process is now 0, we've exhausted the currently available input data
1390 
1391  // If the input segment is complete, we've exhausted this segment
1392  if (input_segment->is_complete()) {
1393 #if defined HAVE_SRD_SESSION_SEND_EOF && HAVE_SRD_SESSION_SEND_EOF
1394  // Tell protocol decoders about the end of
1395  // the input data, which may result in more
1396  // annotations being emitted
1397  (void)srd_session_send_eof(srd_session_);
1398  new_annotations();
1399 #endif
1400 
1401  if (current_segment_id_ < (logic_mux_data_->logic_segments().size() - 1)) {
1402  // Process next segment
1404 
1405  try {
1406  input_segment = logic_mux_data_->logic_segments().at(current_segment_id_);
1407  } catch (out_of_range&) {
1408  qDebug() << "Decode error for" << name() << ": no logic mux segment" \
1409  << current_segment_id_ << "in decode_proc(), mux segments size is" \
1410  << logic_mux_data_->logic_segments().size();
1411  decode_interrupt_ = true;
1412  return;
1413  }
1414  abs_start_samplenum = 0;
1415 
1416  // Create the next segment and set its metadata
1418  segments_.at(current_segment_id_).samplerate = input_segment->samplerate();
1419  segments_.at(current_segment_id_).start_time = input_segment->start_time();
1420 
1421  // Reset decoder state but keep the decoder stack intact
1423  } else {
1424  // All segments have been processed
1425  if (!decode_interrupt_)
1426  decode_finished();
1427 
1428  // Wait for more input data
1429  unique_lock<mutex> input_wait_lock(input_mutex_);
1430  decode_input_cond_.wait(input_wait_lock);
1431  }
1432  } else {
1433  // Input segment isn't complete yet but samples_to_process is 0, wait for more input data
1434  unique_lock<mutex> input_wait_lock(input_mutex_);
1435  decode_input_cond_.wait(input_wait_lock);
1436  }
1437 
1438  }
1439  } while (!decode_interrupt_);
1440 }
1441 
1443 {
1444  // If there were stack changes, the session has been destroyed by now, so if
1445  // it hasn't been destroyed, we can just reset and re-use it
1446  if (srd_session_) {
1447  // When a decoder stack was created before, re-use it
1448  // for the next stream of input data, after terminating
1449  // potentially still executing operations, and resetting
1450  // internal state. Skip the rather expensive (teardown
1451  // and) construction of another decoder stack.
1452 
1453  // TODO Reduce redundancy, use a common code path for
1454  // the meta/start sequence?
1456 
1457  // Metadata is cleared also, so re-set it
1458  uint64_t samplerate = 0;
1459  if (segments_.size() > 0)
1460  samplerate = segments_.at(current_segment_id_).samplerate;
1461  if (samplerate)
1462  srd_session_metadata_set(srd_session_, SRD_CONF_SAMPLERATE,
1463  g_variant_new_uint64(samplerate));
1464  for (const shared_ptr<Decoder>& dec : stack_)
1465  dec->apply_all_options();
1466  srd_session_start(srd_session_);
1467 
1468  return;
1469  }
1470 
1471  // Update the samplerates for the output logic channels
1473 
1474  // Create the session
1475  srd_session_new(&srd_session_);
1476  assert(srd_session_);
1477 
1478  // Create the decoders
1479  srd_decoder_inst *prev_di = nullptr;
1480  for (const shared_ptr<Decoder>& dec : stack_) {
1481  srd_decoder_inst *const di = dec->create_decoder_inst(srd_session_);
1482 
1483  if (!di) {
1484  set_error_message(tr("Failed to create decoder instance"));
1485  srd_session_destroy(srd_session_);
1486  srd_session_ = nullptr;
1487  return;
1488  }
1489 
1490  if (prev_di)
1491  srd_inst_stack(srd_session_, prev_di, di);
1492 
1493  prev_di = di;
1494  }
1495 
1496  // Start the session
1497  if (segments_.size() > 0)
1498  srd_session_metadata_set(srd_session_, SRD_CONF_SAMPLERATE,
1499  g_variant_new_uint64(segments_.at(current_segment_id_).samplerate));
1500 
1501  srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_ANN,
1503 
1504  srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_BINARY,
1506 
1507  srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_LOGIC,
1509 
1510  srd_session_start(srd_session_);
1511 
1512  // We just recreated the srd session, so all stack changes are applied now
1513  stack_config_changed_ = false;
1514 }
1515 
1517 {
1518  // Call the "terminate and reset" routine for the decoder stack
1519  // (if available). This does not harm those stacks which already
1520  // have completed their operation, and reduces response time for
1521  // those stacks which still are processing data while the
1522  // application no longer wants them to.
1523  if (srd_session_) {
1524 #if defined HAVE_SRD_SESSION_SEND_EOF && HAVE_SRD_SESSION_SEND_EOF
1525  (void)srd_session_send_eof(srd_session_);
1526 #endif
1527  srd_session_terminate_reset(srd_session_);
1528 
1529  // Metadata is cleared also, so re-set it
1530  uint64_t samplerate = 0;
1531  if (segments_.size() > 0)
1532  samplerate = segments_.at(current_segment_id_).samplerate;
1533  if (samplerate)
1534  srd_session_metadata_set(srd_session_, SRD_CONF_SAMPLERATE,
1535  g_variant_new_uint64(samplerate));
1536  for (const shared_ptr<Decoder>& dec : stack_)
1537  dec->apply_all_options();
1538  }
1539 }
1540 
1542 {
1543  if (srd_session_) {
1544  // Destroy the session
1545  srd_session_destroy(srd_session_);
1546  srd_session_ = nullptr;
1547 
1548  // Mark the decoder instances as non-existant since they were deleted
1549  for (const shared_ptr<Decoder>& dec : stack_)
1550  dec->invalidate_decoder_inst();
1551  }
1552 }
1553 
1555 {
1556  // Connect the currently used signals to our slot
1557  for (decode::DecodeChannel& ch : channels_) {
1558  if (!ch.assigned_signal)
1559  continue;
1560  const data::SignalBase *signal = ch.assigned_signal.get();
1561 
1562  connect(signal, SIGNAL(samples_cleared()),
1563  this, SLOT(on_data_cleared()), Qt::UniqueConnection);
1564  connect(signal, SIGNAL(samples_added(uint64_t, uint64_t, uint64_t)),
1565  this, SLOT(on_data_received()), Qt::UniqueConnection);
1566 
1567  if (signal->logic_data())
1568  connect(signal->logic_data().get(), SIGNAL(segment_completed()),
1569  this, SLOT(on_input_segment_completed()), Qt::UniqueConnection);
1570  }
1571 }
1572 
1574 {
1575  // Disconnect the notification slot from the previous set of signals
1576  for (decode::DecodeChannel& ch : channels_) {
1577  if (!ch.assigned_signal)
1578  continue;
1579  const data::SignalBase *signal = ch.assigned_signal.get();
1580  disconnect(signal, nullptr, this, SLOT(on_data_cleared()));
1581  disconnect(signal, nullptr, this, SLOT(on_data_received()));
1582 
1583  if (signal->logic_data())
1584  disconnect(signal->logic_data().get(), nullptr, this, SLOT(on_input_segment_completed()));
1585  }
1586 }
1587 
1589 {
1590  // Create annotation segment
1591  segments_.emplace_back();
1592 
1593  // Add annotation classes
1594  for (const shared_ptr<Decoder>& dec : stack_)
1595  for (Row* row : dec->get_rows())
1596  segments_.back().annotation_rows.emplace(row, RowData(row));
1597 
1598  // Prepare our binary output classes
1599  for (const shared_ptr<Decoder>& dec : stack_) {
1600  uint32_t n = dec->get_binary_class_count();
1601 
1602  for (uint32_t i = 0; i < n; i++)
1603  segments_.back().binary_classes.push_back(
1604  {dec.get(), dec->get_binary_class(i), deque<DecodeBinaryDataChunk>()});
1605  }
1606 }
1607 
1608 void DecodeSignal::annotation_callback(srd_proto_data *pdata, void *decode_signal)
1609 {
1610  assert(pdata);
1611  assert(decode_signal);
1612 
1613  DecodeSignal *const ds = (DecodeSignal*)decode_signal;
1614  assert(ds);
1615 
1616  if (ds->decode_interrupt_)
1617  return;
1618 
1619  if (ds->segments_.empty())
1620  return;
1621 
1622  lock_guard<mutex> lock(ds->output_mutex_);
1623 
1624  // Get the decoder and the annotation data
1625  assert(pdata->pdo);
1626  assert(pdata->pdo->di);
1627  const srd_decoder *const srd_dec = pdata->pdo->di->decoder;
1628  assert(srd_dec);
1629 
1630  const srd_proto_data_annotation *const pda = (const srd_proto_data_annotation*)pdata->data;
1631  assert(pda);
1632 
1633  // Find the row
1634  Decoder* dec = ds->get_decoder_by_instance(srd_dec);
1635  assert(dec);
1636 
1637  AnnotationClass* ann_class = dec->get_ann_class_by_id(pda->ann_class);
1638  if (!ann_class) {
1639  qWarning() << "Decoder" << ds->display_name() << "wanted to add annotation" <<
1640  "with class ID" << pda->ann_class << "but there are only" <<
1641  dec->ann_classes().size() << "known classes";
1642  return;
1643  }
1644 
1645  const Row* row = ann_class->row;
1646 
1647  if (!row)
1648  row = dec->get_row_by_id(0);
1649 
1650  RowData& row_data = ds->segments_[ds->current_segment_id_].annotation_rows.at(row);
1651 
1652  // Add the annotation to the row
1653  const Annotation* ann = row_data.emplace_annotation(pdata);
1654 
1655  // We insert the annotation into the global annotation list in a way so that
1656  // the annotation list is sorted by start sample and length. Otherwise, we'd
1657  // have to sort the model, which is expensive
1658  deque<const Annotation*>& all_annotations =
1659  ds->segments_[ds->current_segment_id_].all_annotations;
1660 
1661  if (all_annotations.empty()) {
1662  all_annotations.emplace_back(ann);
1663  } else {
1664  const uint64_t new_ann_len = (pdata->end_sample - pdata->start_sample);
1665  bool ann_has_earlier_start = (pdata->start_sample < all_annotations.back()->start_sample());
1666  bool ann_is_longer = (new_ann_len >
1667  (all_annotations.back()->end_sample() - all_annotations.back()->start_sample()));
1668 
1669  if (ann_has_earlier_start && ann_is_longer) {
1670  bool ann_has_same_start;
1671  auto it = all_annotations.end();
1672 
1673  do {
1674  it--;
1675  ann_has_earlier_start = (pdata->start_sample < (*it)->start_sample());
1676  ann_has_same_start = (pdata->start_sample == (*it)->start_sample());
1677  ann_is_longer = (new_ann_len > (*it)->length());
1678  } while ((ann_has_earlier_start || (ann_has_same_start && ann_is_longer)) && (it != all_annotations.begin()));
1679 
1680  // Allow inserting at the front
1681  if (it != all_annotations.begin())
1682  it++;
1683 
1684  all_annotations.emplace(it, ann);
1685  } else
1686  all_annotations.emplace_back(ann);
1687  }
1688 
1689  // When emplace_annotation() inserts instead of appends an annotation,
1690  // the pointers in all_annotations that follow the inserted annotation and
1691  // point to annotations for this row are off by one and must be updated
1692  if (&(row_data.annotations().back()) != ann) {
1693  // Search backwards until we find the annotation we just added
1694  auto row_it = row_data.annotations().end();
1695  auto all_it = all_annotations.end();
1696  do {
1697  all_it--;
1698  if ((*all_it)->row_data() == &row_data)
1699  row_it--;
1700  } while (&(*row_it) != ann);
1701 
1702  // Update the annotation addresses for this row's annotations until the end
1703  do {
1704  if ((*all_it)->row_data() == &row_data) {
1705  *all_it = &(*row_it);
1706  row_it++;
1707  }
1708  all_it++;
1709  } while (all_it != all_annotations.end());
1710  }
1711 }
1712 
1713 void DecodeSignal::binary_callback(srd_proto_data *pdata, void *decode_signal)
1714 {
1715  assert(pdata);
1716  assert(decode_signal);
1717 
1718  DecodeSignal *const ds = (DecodeSignal*)decode_signal;
1719  assert(ds);
1720 
1721  if (ds->decode_interrupt_)
1722  return;
1723 
1724  // Get the decoder and the binary data
1725  assert(pdata->pdo);
1726  assert(pdata->pdo->di);
1727  const srd_decoder *const srd_dec = pdata->pdo->di->decoder;
1728  assert(srd_dec);
1729 
1730  const srd_proto_data_binary *const pdb = (const srd_proto_data_binary*)pdata->data;
1731  assert(pdb);
1732 
1733  // Find the matching DecodeBinaryClass
1734  DecodeSegment* segment = &(ds->segments_.at(ds->current_segment_id_));
1735 
1736  DecodeBinaryClass* bin_class = nullptr;
1737  for (DecodeBinaryClass& bc : segment->binary_classes)
1738  if ((bc.decoder->get_srd_decoder() == srd_dec) &&
1739  (bc.info->bin_class_id == (uint32_t)pdb->bin_class))
1740  bin_class = &bc;
1741 
1742  if (!bin_class) {
1743  qWarning() << "Could not find valid DecodeBinaryClass in segment" <<
1744  ds->current_segment_id_ << "for binary class ID" << pdb->bin_class <<
1745  ", segment only knows" << segment->binary_classes.size() << "classes";
1746  return;
1747  }
1748 
1749  // Add the data chunk
1750  bin_class->chunks.emplace_back();
1751  DecodeBinaryDataChunk* chunk = &(bin_class->chunks.back());
1752 
1753  chunk->sample = pdata->start_sample;
1754  chunk->data.resize(pdb->size);
1755  memcpy(chunk->data.data(), pdb->data, pdb->size);
1756 
1757  Decoder* dec = ds->get_decoder_by_instance(srd_dec);
1758 
1759  ds->new_binary_data(ds->current_segment_id_, (void*)dec, pdb->bin_class);
1760 }
1761 
1762 void DecodeSignal::logic_output_callback(srd_proto_data *pdata, void *decode_signal)
1763 {
1764  assert(pdata);
1765  assert(decode_signal);
1766 
1767  DecodeSignal *const ds = (DecodeSignal*)decode_signal;
1768  assert(ds);
1769 
1770  if (ds->decode_interrupt_)
1771  return;
1772 
1773  lock_guard<mutex> lock(ds->output_mutex_);
1774 
1775  assert(pdata->pdo);
1776  assert(pdata->pdo->di);
1777  const srd_decoder *const decc = pdata->pdo->di->decoder;
1778  assert(decc);
1779 
1780  const srd_proto_data_logic *const pdl = (const srd_proto_data_logic*)pdata->data;
1781  assert(pdl);
1782 
1783  // FIXME Only one group supported for now
1784  if (pdl->logic_group > 0) {
1785  qWarning() << "Received logic output state change for group" << pdl->logic_group << "from decoder" \
1786  << QString::fromUtf8(decc->name) << "but only group 0 is currently supported";
1787  return;
1788  }
1789 
1790  shared_ptr<Logic> output_logic = ds->output_logic_.at(decc);
1791 
1792  vector< shared_ptr<Segment> > segments = output_logic->segments();
1793 
1794  shared_ptr<LogicSegment> last_segment;
1795 
1796  if (!segments.empty())
1797  last_segment = dynamic_pointer_cast<LogicSegment>(segments.back());
1798  else {
1799  // Happens when the data was cleared - all segments are gone then
1800  // segment_id is always 0 as it's the first segment
1801  last_segment = make_shared<data::LogicSegment>(
1802  *output_logic, 0, (output_logic->num_channels() + 7) / 8, output_logic->get_samplerate());
1803  output_logic->push_segment(last_segment);
1804  }
1805 
1806  if (pdata->start_sample < pdata->end_sample) {
1807  vector<uint8_t> data;
1808  const unsigned int unit_size = last_segment->unit_size();
1809  data.resize(unit_size * (1 + pdl->repeat_count));
1810 
1811  if (unit_size == 1)
1812  for (unsigned int i = 0; i <= pdl->repeat_count; i++)
1813  data.data()[i * unit_size] = *((uint8_t*)pdl->data);
1814  else if (unit_size == 2)
1815  for (unsigned int i = 0; i <= pdl->repeat_count; i++)
1816  data.data()[i * unit_size] = *((uint16_t*)pdl->data);
1817  else if (unit_size <= 4)
1818  for (unsigned int i = 0; i <= pdl->repeat_count; i++)
1819  data.data()[i * unit_size] = *((uint32_t*)pdl->data);
1820  else if (unit_size <= 8)
1821  for (unsigned int i = 0; i <= pdl->repeat_count; i++)
1822  data.data()[i * unit_size] = *((uint64_t*)pdl->data);
1823  else
1824  for (unsigned int i = 0; i <= pdl->repeat_count; i++)
1825  memcpy((void*)&data.data()[i * unit_size], (void*)pdl->data, unit_size);
1826 
1827  last_segment->append_payload(data.data(), data.size());
1828  } else
1829  qWarning() << "Ignoring malformed logic output state change for group" << pdl->logic_group << "from decoder" \
1830  << QString::fromUtf8(decc->name) << "from" << pdata->start_sample << "to" << pdata->end_sample;
1831 }
1832 
1834 {
1835  // If a new acquisition was started, we need to start decoding from scratch
1836  if (state == Session::Running) {
1837  logic_mux_data_invalid_ = true;
1838  begin_decode();
1839  }
1840 }
1841 
1843 {
1844  reset_decode();
1845 }
1846 
1848 {
1849  // If we detected a lack of input data when trying to start decoding,
1850  // we have set an error message. Bail out if we still don't have data
1851  // to work with
1852  if ((!error_message_.isEmpty()) && (get_input_segment_count() == 0))
1853  return;
1854 
1855  if (!error_message_.isEmpty()) {
1856  error_message_.clear();
1857  // TODO Emulate noquote()
1858  qDebug().nospace() << name() << ": Input data available, error cleared";
1859  }
1860 
1861  if (!logic_mux_thread_.joinable())
1862  begin_decode();
1863  else
1864  logic_mux_cond_.notify_one();
1865 }
1866 
1868 {
1869  if (!logic_mux_thread_.joinable())
1870  logic_mux_cond_.notify_one();
1871 }
1872 
1874 {
1876 }
1877 
1878 } // namespace data
1879 } // namespace pv
manual pdf if(NOT EXISTS"${CMAKE_CURRENT_BINARY_DIR}/images") message(STATUS"creating symlink for manual's images/ subdirectory") execute_process(COMMAND $
Definition: CMakeLists.txt:42
static void store_gvariant(QSettings &settings, GVariant *v)
atomic< bool > decode_interrupt_
map< const srd_decoder *, shared_ptr< Logic > > output_logic_
const vector< shared_ptr< Decoder > > & decoder_stack() const
vector< decode::DecodeChannel > channels_
shared_ptr< pv::data::SignalData > data() const
Definition: signalbase.cpp:333
deque< const Annotation * > all_annotations
const vector< shared_ptr< data::SignalBase > > signalbases() const
Definition: session.cpp:957
Decoder * get_decoder_by_instance(const srd_decoder *const srd_dec)
AnnotationClass * get_ann_class_by_id(size_t id)
Definition: decoder.cpp:294
int64_t get_working_sample_count(uint32_t segment_id) const
deque< DecodeSegment > segments_
int64_t get_decoded_sample_count(uint32_t segment_id, bool include_processing) const
vector< shared_ptr< Decoder > > stack_
const srd_decoder * get_srd_decoder() const
Definition: decoder.cpp:122
const srd_channel * pdch_
Definition: decoder.hpp:89
CMake option(DISABLE_WERROR"Build without -Werror"TRUE) option(ENABLE_SIGNALS"Build with UNIX signals"TRUE) option(ENABLE_STACKTRACE"Enable stack trace when crashing"FALSE) option(ENABLE_DECODE"Build with libsigrokdecode"TRUE) option(ENABLE_FLOW"Build with libsigrokflow"FALSE) option(ENABLE_TESTS"Enable unit tests"FALSE) option(STATIC_PKGDEPS_LIBS"Statically link to (pkg-config) libraries"FALSE) option(ENABLE_TS_UPDATE"Update .ts source files (Qt l10n)"FALSE) if(WIN32) set(STATIC_PKGDEPS_LIBS TRUE) set(ENABLE_SIGNALS FALSE) endif() if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING"Choose the type of build (None
void assign_signal(const uint16_t channel_id, shared_ptr< const SignalBase > signal)
void decoder_stacked(void *decoder)
decoder is of type decode::Decoder*
virtual void set_name(QString name)
deque< DecodeBinaryDataChunk > chunks
T value(details::expression_node< T > *n)
Definition: exprtk.hpp:12358
vector< DecodeBinaryClass > binary_classes
static const double DecodeMargin
shared_ptr< sigrok::Channel > channel() const
Definition: signalbase.cpp:153
static void binary_callback(srd_proto_data *pdata, void *decode_signal)
condition_variable decode_pause_cond_
void get_merged_binary_data_chunks_by_sample(uint32_t segment_id, const Decoder *dec, uint32_t bin_class_id, uint64_t start_sample, uint64_t end_sample, vector< uint8_t > *dest) const
static const int64_t DecodeChunkLength
const DecodeBinaryClass * get_binary_data_class(uint32_t segment_id, const Decoder *dec, uint32_t bin_class_id) const
std::thread logic_mux_thread_
virtual void save_settings(QSettings &settings) const
void mux_logic_samples(uint32_t segment_id, const int64_t start, const int64_t end)
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
const deque< const Annotation * > * get_all_annotations_by_segment(uint32_t segment_id) const
void add_generated_signal(shared_ptr< data::SignalBase > signal)
Definition: session.cpp:974
map< const Row *, RowData > annotation_rows
virtual void save_settings(QSettings &settings) const
Definition: signalbase.cpp:565
T max(const T v0, const T v1)
Definition: exprtk.hpp:1411
void stack_decoder(const srd_decoder *decoder, bool restart_decode=true)
virtual double get_samplerate() const
bool all_input_segments_complete(uint32_t segment_id) const
virtual void set_error_message(QString msg)
Definition: signalbase.cpp:867
static const double DecodeThreshold
static std::string data()
Definition: exprtk.hpp:39024
uint64_t get_annotation_count() const
Definition: rowdata.cpp:51
virtual void set_name(QString name)
Definition: signalbase.cpp:236
map< const srd_decoder *, vector< uint8_t > > output_logic_muxed_data_
void get_annotation_subset(deque< const pv::data::decode::Annotation * > &dest, uint64_t start_sample, uint64_t end_sample) const
Definition: rowdata.cpp:56
const pv::util::Timestamp start_time() const
void auto_assign_signals(const shared_ptr< Decoder > dec)
QString display_name() const
Definition: signalbase.cpp:228
vector< Row * > get_rows(bool visible_only=false)
uint32_t get_input_segment_count() const
void set_initial_pin_state(const uint16_t channel_id, const int init_state)
T min(const T v0, const T v1)
Definition: exprtk.hpp:1404
virtual void restore_settings(QSettings &settings)
const vector< decode::DecodeChannel > get_channels() const
Row * get_row_by_id(size_t id)
Definition: decoder.cpp:266
const Annotation * emplace_annotation(srd_proto_data *pdata)
Definition: rowdata.cpp:103
int get_assigned_signal_count() const
uint64_t get_annotation_count(const Row *row, uint32_t segment_id) const
void decoder_removed(void *decoder)
decoder is of type decode::Decoder*
DecodeSignal(pv::Session &session)
QColor color() const
Definition: signalbase.cpp:246
void get_annotation_subset(deque< const Annotation * > &dest, const Row *row, uint32_t segment_id, uint64_t start_sample, uint64_t end_sample) const
virtual void set_color(QColor color)
double get_input_samplerate(uint32_t segment_id) const
virtual void restore_settings(QSettings &settings)
Definition: signalbase.cpp:581
Protocol Decoder channel using libsigrokdecode.
Definition: signalbase.hpp:96
static void logic_output_callback(srd_proto_data *pdata, void *decode_signal)
atomic< bool > logic_mux_interrupt_
bool toggle_decoder_visibility(int index)
shared_ptr< Logic > logic_mux_data_
static GVariant * restore_gvariant(QSettings &settings)
boost::multiprecision::number< boost::multiprecision::cpp_dec_float< 24 >, boost::multiprecision::et_off > Timestamp
Timestamp type providing yoctosecond resolution.
Definition: util.hpp:67
shared_ptr< pv::data::Logic > logic_data() const
Definition: signalbase.cpp:317
QString name() const
Definition: signalbase.cpp:210
condition_variable logic_mux_cond_
struct srd_session * srd_session_
virtual void set_color(QColor color)
Definition: signalbase.cpp:251
uint32_t get_binary_data_chunk_count(uint32_t segment_id, const Decoder *dec, uint32_t bin_class_id) const
static void annotation_callback(srd_proto_data *pdata, void *decode_signal)
void get_merged_binary_data_chunks_by_offset(uint32_t segment_id, const Decoder *dec, uint32_t bin_class_id, uint64_t start, uint64_t end, vector< uint8_t > *dest) const
void remove_decoder(int index)
condition_variable decode_input_cond_
const deque< Annotation > & annotations() const
Definition: rowdata.cpp:98
shared_ptr< const pv::data::SignalBase > assigned_signal
Definition: decoder.hpp:85
const DecodeBinaryClassInfo * info
void reset_decode(bool shutting_down=false)
unsigned int index() const
Definition: signalbase.cpp:182
uint64_t sample
Number of the sample where this data was provided by the PD.
void on_capture_state_changed(int state)
vector< const AnnotationClass * > ann_classes() const
Definition: decoder.cpp:274
void decode_data(const int64_t abs_start_samplenum, const int64_t sample_count, const shared_ptr< const LogicSegment > input_segment)
void new_binary_data(unsigned int segment_id, void *decoder, unsigned int bin_class_id)
void samples_added(uint64_t segment_id, uint64_t start_sample, uint64_t end_sample)
void get_binary_data_chunk(uint32_t segment_id, const Decoder *dec, uint32_t bin_class_id, uint32_t chunk_id, const vector< uint8_t > **dest, uint64_t *size)
vector< shared_ptr< SignalBase > > output_signals_