* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef _WIN32
+// Windows: Avoid boost/thread namespace pollution (which includes windows.h).
+#define NOGDI
+#define NORESOURCE
+#endif
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
(shared_ptr<sigrok::Device> device, shared_ptr<Packet> packet) {
data_feed_in(device, packet);
});
- update_signals();
decode_traces_.clear();
+ update_signals();
device_selected();
}
return data;
}
+double Session::get_samplerate() const
+{
+ double samplerate = 0.0;
+
+ for (const shared_ptr<pv::data::SignalData> d : get_data()) {
+ assert(d);
+ const vector< shared_ptr<pv::data::Segment> > segments =
+ d->segments();
+ for (const shared_ptr<pv::data::Segment> &s : segments)
+ samplerate = std::max(samplerate, s->samplerate());
+ }
+
+ // If there is no sample rate given we use samples as unit
+ if (samplerate == 0.0)
+ samplerate = 1.0;
+
+ return samplerate;
+}
+
const unordered_set< shared_ptr<view::Signal> > Session::signals() const
{
shared_lock<shared_mutex> lock(signals_mutex_);
map<const srd_channel*, shared_ptr<view::LogicSignal> > channels;
shared_ptr<data::DecoderStack> decoder_stack;
- try
- {
+ try {
lock_guard<boost::shared_mutex> lock(signals_mutex_);
// Create the decoder
// Auto select the initial channels
for (const srd_channel *pdch : all_channels)
- for (shared_ptr<view::Signal> s : signals_)
- {
+ for (shared_ptr<view::Signal> s : signals_) {
shared_ptr<view::LogicSignal> l =
dynamic_pointer_cast<view::LogicSignal>(s);
if (l && QString::fromUtf8(pdch->name).
new view::DecodeTrace(*this, decoder_stack,
decode_traces_.size()));
decode_traces_.push_back(d);
- }
- catch(std::runtime_error e)
- {
+ } catch (std::runtime_error e) {
return false;
}
void Session::remove_decode_signal(view::DecodeTrace *signal)
{
for (auto i = decode_traces_.begin(); i != decode_traces_.end(); i++)
- if ((*i).get() == signal)
- {
+ if ((*i).get() == signal) {
decode_traces_.erase(i);
signals_changed();
return;
void Session::set_capture_state(capture_state state)
{
- lock_guard<mutex> lock(sampling_mutex_);
- const bool changed = capture_state_ != state;
- capture_state_ = state;
+ bool changed;
+
+ {
+ lock_guard<mutex> lock(sampling_mutex_);
+ changed = capture_state_ != state;
+ capture_state_ = state;
+ }
+
if (changed)
capture_state_changed(state);
}
try {
device_->start();
- } catch(Error e) {
+ } catch (Error e) {
error_handler(e.what());
return;
}
set_capture_state(Stopped);
// Confirm that SR_DF_END was received
- if (cur_logic_segment_)
- {
+ if (cur_logic_segment_) {
qDebug("SR_DF_END was not received.");
assert(0);
}
for (auto entry : meta->config()) {
switch (entry.first->id()) {
case SR_CONF_SAMPLERATE:
+ // We can't rely on the header to always contain the sample rate,
+ // so in case it's supplied via a meta packet, we use it.
+ if (!cur_samplerate_)
+ cur_samplerate_ = g_variant_get_uint64(entry.second.gobj());
+
/// @todo handle samplerate changes
break;
default:
signals_changed();
}
+void Session::feed_in_trigger()
+{
+ // The channel containing most samples should be most accurate
+ uint64_t sample_count = 0;
+
+ for (const shared_ptr<pv::data::SignalData> d : get_data()) {
+ assert(d);
+ uint64_t temp_count = 0;
+
+ const vector< shared_ptr<pv::data::Segment> > segments =
+ d->segments();
+ for (const shared_ptr<pv::data::Segment> &s : segments)
+ temp_count += s->get_sample_count();
+
+ if (temp_count > sample_count)
+ sample_count = temp_count;
+ }
+
+ trigger_event(sample_count / get_samplerate());
+}
+
void Session::feed_in_frame_begin()
{
if (cur_logic_segment_ || !cur_analog_segments_.empty())
const size_t sample_count = logic->data_length() / logic->unit_size();
- if (!logic_data_)
- {
+ if (!logic_data_) {
// The only reason logic_data_ would not have been created is
// if it was not possible to determine the signals when the
// device was created.
update_signals();
}
- if (!cur_logic_segment_)
- {
+ if (!cur_logic_segment_) {
// This could be the first packet after a trigger
set_capture_state(Running);
// frame_began is DecoderStack, but in future we need to signal
// this after both analog and logic sweeps have begun.
frame_began();
- }
- else
- {
+ } else {
// Append to the existing data segment
cur_logic_segment_->append_payload(logic);
}
const float *data = static_cast<const float *>(analog->data_pointer());
bool sweep_beginning = false;
- for (auto channel : channels)
- {
+ if (signals_.empty())
+ update_signals();
+
+ for (auto channel : channels) {
shared_ptr<data::AnalogSegment> segment;
// Try to get the segment of the channel
iterator iter = cur_analog_segments_.find(channel);
if (iter != cur_analog_segments_.end())
segment = (*iter).second;
- else
- {
- // If no segment was found, this means we havn't
+ else {
+ // If no segment was found, this means we haven't
// created one yet. i.e. this is the first packet
// in the sweep containing this segment.
sweep_beginning = true;
feed_in_meta(dynamic_pointer_cast<Meta>(packet->payload()));
break;
+ case SR_DF_TRIGGER:
+ feed_in_trigger();
+ break;
+
case SR_DF_FRAME_BEGIN:
feed_in_frame_begin();
break;