]> sigrok.org Git - pulseview.git/blame - pv/session.cpp
MainWindow: Prevent Qt from restoring the dock widgets
[pulseview.git] / pv / session.cpp
CommitLineData
2953961c 1/*
b3f22de0 2 * This file is part of the PulseView project.
2953961c 3 *
1bc6525b 4 * Copyright (C) 2012-14 Joel Holdsworth <joel@airwebreathe.org.uk>
2953961c
JH
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, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
35750e4d
UH
21#ifdef _WIN32
22// Windows: Avoid boost/thread namespace pollution (which includes windows.h).
23#define NOGDI
24#define NORESOURCE
25#endif
e71eb81c
JH
26#include <boost/thread/locks.hpp>
27#include <boost/thread/shared_mutex.hpp>
28
269528f5 29#ifdef ENABLE_DECODE
4e5a4405 30#include <libsigrokdecode/libsigrokdecode.h>
269528f5 31#endif
4e5a4405 32
f65cd27b 33#include "session.hpp"
2953961c 34
2acdb232 35#include "devicemanager.hpp"
119aff65 36
2acdb232 37#include "data/analog.hpp"
f3d66e52 38#include "data/analogsegment.hpp"
2acdb232
JH
39#include "data/decoderstack.hpp"
40#include "data/logic.hpp"
f3d66e52 41#include "data/logicsegment.hpp"
bf0edd2b 42#include "data/signalbase.hpp"
2acdb232 43#include "data/decode/decoder.hpp"
82c7f640 44
da30ecb7
JH
45#include "devices/hardwaredevice.hpp"
46#include "devices/sessionfile.hpp"
47
2acdb232
JH
48#include "view/analogsignal.hpp"
49#include "view/decodetrace.hpp"
50#include "view/logicsignal.hpp"
47e9e7bb
SA
51#include "view/signal.hpp"
52#include "view/view.hpp"
28a4c9c5 53
3b68d03d
JH
54#include <cassert>
55#include <mutex>
e92cd4e4
JH
56#include <stdexcept>
57
728e5ef7
JH
58#include <sys/stat.h>
59
79efbc53
JH
60#include <QDebug>
61
fe3a1c21 62#include <libsigrokcxx/libsigrokcxx.hpp>
e8d00928 63
aca64cac
JH
64using boost::shared_lock;
65using boost::shared_mutex;
66using boost::unique_lock;
67
f9abf97e 68using std::dynamic_pointer_cast;
d2344534 69using std::function;
3b68d03d 70using std::lock_guard;
d873f4d6 71using std::list;
819f4c25 72using std::map;
aca64cac 73using std::mutex;
8524a597 74using std::recursive_mutex;
02412f0b 75using std::set;
f9abf97e 76using std::shared_ptr;
819f4c25 77using std::string;
78b0af3e 78using std::unordered_set;
819f4c25 79using std::vector;
28a4c9c5 80
e8d00928
ML
81using sigrok::Analog;
82using sigrok::Channel;
83using sigrok::ChannelType;
84using sigrok::ConfigKey;
85using sigrok::DatafeedCallbackFunction;
e8d00928 86using sigrok::Error;
e8d00928
ML
87using sigrok::Header;
88using sigrok::Logic;
89using sigrok::Meta;
90using sigrok::Packet;
91using sigrok::PacketPayload;
92using sigrok::Session;
93using sigrok::SessionDevice;
94
95using Glib::VariantBase;
96using Glib::Variant;
51e77110 97
e8d00928 98namespace pv {
2b81ae46 99Session::Session(DeviceManager &device_manager) :
8dbbc7f0 100 device_manager_(device_manager),
ff008de6
JH
101 capture_state_(Stopped),
102 cur_samplerate_(0)
2953961c 103{
2953961c
JH
104}
105
2b81ae46 106Session::~Session()
2953961c 107{
04463625 108 // Stop and join to the thread
5b7cf66c 109 stop_capture();
2953961c
JH
110}
111
2b81ae46 112DeviceManager& Session::device_manager()
4cb0b033 113{
8dbbc7f0 114 return device_manager_;
4cb0b033
JH
115}
116
2b81ae46 117const DeviceManager& Session::device_manager() const
4cb0b033 118{
8dbbc7f0 119 return device_manager_;
4cb0b033
JH
120}
121
da30ecb7 122shared_ptr<sigrok::Session> Session::session() const
1f4caa77 123{
da30ecb7
JH
124 if (!device_)
125 return shared_ptr<sigrok::Session>();
126 return device_->session();
1f4caa77
JH
127}
128
da30ecb7 129shared_ptr<devices::Device> Session::device() const
dc0867ff 130{
8dbbc7f0 131 return device_;
dc0867ff
JH
132}
133
da30ecb7 134void Session::set_device(shared_ptr<devices::Device> device)
d64d1596 135{
da30ecb7
JH
136 assert(device);
137
82596f46
JH
138 // Ensure we are not capturing before setting the device
139 stop_capture();
140
4d6c6ea3
SA
141 if (device_)
142 device_->close();
143
86123e2e
SA
144 device_.reset();
145
cc9a7898 146 // Remove all stored data
bb7dd726 147 for (std::shared_ptr<pv::view::View> view : views_) {
47e9e7bb 148 view->clear_signals();
bb7dd726
SA
149#ifdef ENABLE_DECODE
150 view->clear_decode_traces();
151#endif
152 }
47e9e7bb
SA
153 for (const shared_ptr<data::SignalData> d : all_signal_data_)
154 d->clear();
cc9a7898 155 all_signal_data_.clear();
47e9e7bb 156 signalbases_.clear();
4b0d7046
SA
157 cur_logic_segment_.reset();
158
159 for (auto entry : cur_analog_segments_) {
160 shared_ptr<sigrok::Channel>(entry.first).reset();
161 shared_ptr<data::AnalogSegment>(entry.second).reset();
162 }
163
164 logic_data_.reset();
4b0d7046 165
86123e2e
SA
166 signals_changed();
167
da30ecb7 168 device_ = std::move(device);
7e0c99bf
SA
169
170 try {
171 device_->open();
172 } catch (const QString &e) {
173 device_.reset();
174 device_selected();
175 throw;
176 }
177
da30ecb7
JH
178 device_->session()->add_datafeed_callback([=]
179 (shared_ptr<sigrok::Device> device, shared_ptr<Packet> packet) {
180 data_feed_in(device, packet);
181 });
ae2d1bc5 182
4b8e787d 183 update_signals();
20f81a58 184 device_selected();
ae2d1bc5 185}
85843b14 186
2b81ae46 187void Session::set_default_device()
6fd0b639 188{
da30ecb7 189 const list< shared_ptr<devices::HardwareDevice> > &devices =
8dbbc7f0 190 device_manager_.devices();
6fd0b639 191
da30ecb7
JH
192 if (devices.empty())
193 return;
dc0867ff 194
da30ecb7
JH
195 // Try and find the demo device and select that by default
196 const auto iter = std::find_if(devices.begin(), devices.end(),
197 [] (const shared_ptr<devices::HardwareDevice> &d) {
198 return d->hardware_device()->driver()->name() ==
199 "demo"; });
200 set_device((iter == devices.end()) ? devices.front() : *iter);
dc0867ff
JH
201}
202
2b81ae46 203Session::capture_state Session::get_capture_state() const
5b7cf66c 204{
8dbbc7f0
JH
205 lock_guard<mutex> lock(sampling_mutex_);
206 return capture_state_;
5b7cf66c
JH
207}
208
2b81ae46 209void Session::start_capture(function<void (const QString)> error_handler)
2e2946fe 210{
34c11fa7
SA
211 if (!device_) {
212 error_handler(tr("No active device set, can't start acquisition."));
213 return;
214 }
215
5b7cf66c
JH
216 stop_capture();
217
6ac6242b 218 // Check that at least one channel is enabled
e6c1382e
JH
219 const shared_ptr<sigrok::Device> sr_dev = device_->device();
220 if (sr_dev) {
221 const auto channels = sr_dev->channels();
222 if (!std::any_of(channels.begin(), channels.end(),
223 [](shared_ptr<Channel> channel) {
224 return channel->enabled(); })) {
225 error_handler(tr("No channels enabled."));
226 return;
227 }
9c48fa57
JH
228 }
229
53ea4c6c 230 // Clear signal data
47e9e7bb
SA
231 for (const shared_ptr<data::SignalData> d : all_signal_data_)
232 d->clear();
53ea4c6c 233
9c48fa57 234 // Begin the session
8dbbc7f0 235 sampling_thread_ = std::thread(
2b05d311 236 &Session::sample_thread_proc, this, error_handler);
2e2946fe
JH
237}
238
2b81ae46 239void Session::stop_capture()
5b7cf66c 240{
04463625 241 if (get_capture_state() != Stopped)
da30ecb7 242 device_->stop();
5b7cf66c
JH
243
244 // Check that sampling stopped
8dbbc7f0
JH
245 if (sampling_thread_.joinable())
246 sampling_thread_.join();
5b7cf66c
JH
247}
248
47e9e7bb
SA
249void Session::register_view(std::shared_ptr<pv::view::View> view)
250{
251 views_.insert(view);
252}
253
254void Session::deregister_view(std::shared_ptr<pv::view::View> view)
255{
256 views_.erase(view);
257}
258
2220e942
SA
259double Session::get_samplerate() const
260{
261 double samplerate = 0.0;
262
47e9e7bb
SA
263 for (const shared_ptr<pv::data::SignalData> d : all_signal_data_) {
264 assert(d);
265 const vector< shared_ptr<pv::data::Segment> > segments =
266 d->segments();
267 for (const shared_ptr<pv::data::Segment> &s : segments)
268 samplerate = std::max(samplerate, s->samplerate());
2220e942 269 }
2220e942
SA
270 // If there is no sample rate given we use samples as unit
271 if (samplerate == 0.0)
272 samplerate = 1.0;
273
274 return samplerate;
275}
276
47e9e7bb
SA
277const std::unordered_set< std::shared_ptr<data::SignalBase> >
278 Session::signalbases() const
2e2946fe 279{
47e9e7bb 280 return signalbases_;
2e2946fe
JH
281}
282
269528f5 283#ifdef ENABLE_DECODE
2b81ae46 284bool Session::add_decoder(srd_decoder *const dec)
82c7f640 285{
04394ded 286 map<const srd_channel*, shared_ptr<data::SignalBase> > channels;
7491a29f 287 shared_ptr<data::DecoderStack> decoder_stack;
4e5a4405 288
2ad82c2e 289 try {
4e5a4405 290 // Create the decoder
7491a29f 291 decoder_stack = shared_ptr<data::DecoderStack>(
bdc5c3b0 292 new data::DecoderStack(*this, dec));
4e5a4405 293
6ac6242b
ML
294 // Make a list of all the channels
295 std::vector<const srd_channel*> all_channels;
f3290553 296 for (const GSList *i = dec->channels; i; i = i->next)
6ac6242b 297 all_channels.push_back((const srd_channel*)i->data);
f3290553 298 for (const GSList *i = dec->opt_channels; i; i = i->next)
6ac6242b 299 all_channels.push_back((const srd_channel*)i->data);
d2f46d27 300
6ac6242b
ML
301 // Auto select the initial channels
302 for (const srd_channel *pdch : all_channels)
04394ded
SA
303 for (shared_ptr<data::SignalBase> b : signalbases_) {
304 if (b->type() == ChannelType::LOGIC) {
305 if (QString::fromUtf8(pdch->name).toLower().
306 contains(b->name().toLower()))
307 channels[pdch] = b;
308 }
4e5a4405 309 }
4e5a4405 310
7491a29f
JH
311 assert(decoder_stack);
312 assert(!decoder_stack->stack().empty());
313 assert(decoder_stack->stack().front());
6ac6242b 314 decoder_stack->stack().front()->set_channels(channels);
4e5a4405
JH
315
316 // Create the decode signal
bf0edd2b
SA
317 shared_ptr<data::SignalBase> signalbase =
318 shared_ptr<data::SignalBase>(new data::SignalBase(nullptr));
319
bb7dd726
SA
320 signalbase->set_decoder_stack(decoder_stack);
321
322 for (std::shared_ptr<pv::view::View> view : views_)
323 view->add_decode_trace(signalbase);
2ad82c2e 324 } catch (std::runtime_error e) {
e92cd4e4
JH
325 return false;
326 }
327
82c7f640 328 signals_changed();
e92cd4e4 329
7491a29f
JH
330 // Do an initial decode
331 decoder_stack->begin_decode();
332
e92cd4e4 333 return true;
82c7f640
JH
334}
335
bb7dd726 336void Session::remove_decode_signal(shared_ptr<data::SignalBase> signalbase)
38eeddea 337{
bb7dd726
SA
338 for (std::shared_ptr<pv::view::View> view : views_)
339 view->remove_decode_trace(signalbase);
c51482b3 340}
269528f5 341#endif
c51482b3 342
2b81ae46 343void Session::set_capture_state(capture_state state)
6ac96c2e 344{
896936e5
TS
345 bool changed;
346
347 {
348 lock_guard<mutex> lock(sampling_mutex_);
349 changed = capture_state_ != state;
350 capture_state_ = state;
351 }
352
f3290553 353 if (changed)
2b49eeb0 354 capture_state_changed(state);
6ac96c2e
JH
355}
356
ffe00119 357void Session::update_signals()
b087ba7f 358{
076eefa4 359 if (!device_) {
47e9e7bb 360 signalbases_.clear();
076eefa4 361 logic_data_.reset();
bb7dd726 362 for (std::shared_ptr<pv::view::View> view : views_) {
47e9e7bb 363 view->clear_signals();
bb7dd726
SA
364#ifdef ENABLE_DECODE
365 view->clear_decode_traces();
366#endif
367 }
076eefa4
SA
368 return;
369 }
e6c1382e
JH
370
371 lock_guard<recursive_mutex> lock(data_mutex_);
b087ba7f 372
ffe00119 373 const shared_ptr<sigrok::Device> sr_dev = device_->device();
c6412b47 374 if (!sr_dev) {
47e9e7bb 375 signalbases_.clear();
c6412b47 376 logic_data_.reset();
bb7dd726 377 for (std::shared_ptr<pv::view::View> view : views_) {
47e9e7bb 378 view->clear_signals();
bb7dd726
SA
379#ifdef ENABLE_DECODE
380 view->clear_decode_traces();
381#endif
382 }
c6412b47
JH
383 return;
384 }
385
b087ba7f 386 // Detect what data types we will receive
c6412b47 387 auto channels = sr_dev->channels();
e8d00928
ML
388 unsigned int logic_channel_count = std::count_if(
389 channels.begin(), channels.end(),
390 [] (shared_ptr<Channel> channel) {
391 return channel->type() == ChannelType::LOGIC; });
b087ba7f 392
f3d66e52 393 // Create data containers for the logic data segments
b087ba7f 394 {
8524a597 395 lock_guard<recursive_mutex> data_lock(data_mutex_);
b087ba7f 396
3917ba77
JH
397 if (logic_channel_count == 0) {
398 logic_data_.reset();
399 } else if (!logic_data_ ||
400 logic_data_->num_channels() != logic_channel_count) {
8dbbc7f0 401 logic_data_.reset(new data::Logic(
6ac6242b 402 logic_channel_count));
8dbbc7f0 403 assert(logic_data_);
b087ba7f 404 }
b087ba7f
JH
405 }
406
47e9e7bb
SA
407 // Make the signals list
408 for (std::shared_ptr<pv::view::View> view : views_) {
409 unordered_set< shared_ptr<view::Signal> > prev_sigs(view->signals());
410 view->clear_signals();
b087ba7f 411
c6412b47 412 for (auto channel : sr_dev->channels()) {
bf0edd2b 413 shared_ptr<data::SignalBase> signalbase;
39e680c2 414 shared_ptr<view::Signal> signal;
39e680c2 415
3917ba77
JH
416 // Find the channel in the old signals
417 const auto iter = std::find_if(
418 prev_sigs.cbegin(), prev_sigs.cend(),
419 [&](const shared_ptr<view::Signal> &s) {
73a25a6e 420 return s->base()->channel() == channel;
3917ba77
JH
421 });
422 if (iter != prev_sigs.end()) {
423 // Copy the signal from the old set to the new
424 signal = *iter;
3917ba77 425 } else {
47e9e7bb
SA
426 // Find the signalbase for this channel if possible
427 signalbase.reset();
428 for (const shared_ptr<data::SignalBase> b : signalbases_)
429 if (b->channel() == channel)
430 signalbase = b;
bf0edd2b 431
3917ba77
JH
432 switch(channel->type()->id()) {
433 case SR_CHANNEL_LOGIC:
47e9e7bb
SA
434 if (!signalbase) {
435 signalbase = shared_ptr<data::SignalBase>(
436 new data::SignalBase(channel));
437 signalbases_.insert(signalbase);
438
439 all_signal_data_.insert(logic_data_);
440 signalbase->set_data(logic_data_);
441 }
442
3917ba77
JH
443 signal = shared_ptr<view::Signal>(
444 new view::LogicSignal(*this,
0aa57689 445 device_, signalbase));
47e9e7bb 446 view->add_signal(signal);
3917ba77
JH
447 break;
448
449 case SR_CHANNEL_ANALOG:
450 {
47e9e7bb
SA
451 if (!signalbase) {
452 signalbase = shared_ptr<data::SignalBase>(
453 new data::SignalBase(channel));
454 signalbases_.insert(signalbase);
455
456 shared_ptr<data::Analog> data(new data::Analog());
457 all_signal_data_.insert(data);
458 signalbase->set_data(data);
459 }
460
3917ba77
JH
461 signal = shared_ptr<view::Signal>(
462 new view::AnalogSignal(
cbd2a2de 463 *this, signalbase));
47e9e7bb 464 view->add_signal(signal);
3917ba77
JH
465 break;
466 }
467
468 default:
469 assert(0);
470 break;
471 }
b087ba7f
JH
472 }
473 }
fbd3e234 474 }
b087ba7f
JH
475
476 signals_changed();
477}
478
cbd2a2de 479shared_ptr<data::SignalBase> Session::signalbase_from_channel(
bf0edd2b 480 shared_ptr<sigrok::Channel> channel) const
3ddcc083 481{
bf0edd2b 482 for (shared_ptr<data::SignalBase> sig : signalbases_) {
3ddcc083 483 assert(sig);
6ac6242b 484 if (sig->channel() == channel)
3ddcc083
JH
485 return sig;
486 }
bf0edd2b 487 return shared_ptr<data::SignalBase>();
3ddcc083
JH
488}
489
2b05d311 490void Session::sample_thread_proc(function<void (const QString)> error_handler)
274d4f13 491{
f2edb557 492 assert(error_handler);
be73bdfa 493
34c11fa7
SA
494 if (!device_)
495 return;
45f0c7c9 496
b48daed6 497 cur_samplerate_ = device_->read_config<uint64_t>(ConfigKey::SAMPLERATE);
274d4f13 498
e7216ae0
SA
499 out_of_memory_ = false;
500
ae2d1bc5 501 try {
5237f0c5 502 device_->start();
2ad82c2e 503 } catch (Error e) {
e8d00928 504 error_handler(e.what());
eec446e1
JH
505 return;
506 }
507
da30ecb7 508 set_capture_state(device_->session()->trigger() ?
07dcf561 509 AwaitingTrigger : Running);
eec446e1 510
da30ecb7 511 device_->run();
eec446e1 512 set_capture_state(Stopped);
1a2fe44c
JH
513
514 // Confirm that SR_DF_END was received
2ad82c2e 515 if (cur_logic_segment_) {
bb2cdfff
JH
516 qDebug("SR_DF_END was not received.");
517 assert(0);
518 }
e7216ae0
SA
519
520 if (out_of_memory_)
521 error_handler(tr("Out of memory, acquisition stopped."));
eec446e1
JH
522}
523
da30ecb7 524void Session::feed_in_header()
eec446e1 525{
b48daed6 526 cur_samplerate_ = device_->read_config<uint64_t>(ConfigKey::SAMPLERATE);
be73bdfa
JH
527}
528
da30ecb7 529void Session::feed_in_meta(shared_ptr<Meta> meta)
be73bdfa 530{
e8d00928
ML
531 for (auto entry : meta->config()) {
532 switch (entry.first->id()) {
be73bdfa 533 case SR_CONF_SAMPLERATE:
8a7b603b
SA
534 // We can't rely on the header to always contain the sample rate,
535 // so in case it's supplied via a meta packet, we use it.
536 if (!cur_samplerate_)
537 cur_samplerate_ = g_variant_get_uint64(entry.second.gobj());
538
be73bdfa 539 /// @todo handle samplerate changes
be73bdfa
JH
540 break;
541 default:
542 // Unknown metadata is not an error.
543 break;
544 }
aba1dd16 545 }
74043039
JH
546
547 signals_changed();
aba1dd16
JH
548}
549
48257a69
SA
550void Session::feed_in_trigger()
551{
552 // The channel containing most samples should be most accurate
553 uint64_t sample_count = 0;
554
cc9a7898 555 {
cc9a7898
SA
556 for (const shared_ptr<pv::data::SignalData> d : all_signal_data_) {
557 assert(d);
558 uint64_t temp_count = 0;
559
560 const vector< shared_ptr<pv::data::Segment> > segments =
561 d->segments();
562 for (const shared_ptr<pv::data::Segment> &s : segments)
563 temp_count += s->get_sample_count();
564
565 if (temp_count > sample_count)
566 sample_count = temp_count;
567 }
48257a69
SA
568 }
569
570 trigger_event(sample_count / get_samplerate());
571}
572
2b81ae46 573void Session::feed_in_frame_begin()
82f50b10 574{
f3d66e52 575 if (cur_logic_segment_ || !cur_analog_segments_.empty())
82f50b10
JH
576 frame_began();
577}
578
2b81ae46 579void Session::feed_in_logic(shared_ptr<Logic> logic)
9c112671 580{
8524a597 581 lock_guard<recursive_mutex> lock(data_mutex_);
79efbc53 582
ff4bf6bd
SA
583 const size_t sample_count = logic->data_length() / logic->unit_size();
584
2ad82c2e 585 if (!logic_data_) {
e6c1382e
JH
586 // The only reason logic_data_ would not have been created is
587 // if it was not possible to determine the signals when the
588 // device was created.
589 update_signals();
79efbc53 590 }
be73bdfa 591
2ad82c2e 592 if (!cur_logic_segment_) {
bb2cdfff 593 // This could be the first packet after a trigger
2b49eeb0
JH
594 set_capture_state(Running);
595
f3d66e52
JH
596 // Create a new data segment
597 cur_logic_segment_ = shared_ptr<data::LogicSegment>(
598 new data::LogicSegment(
ff4bf6bd 599 logic, cur_samplerate_, sample_count));
f3d66e52 600 logic_data_->push_segment(cur_logic_segment_);
82f50b10
JH
601
602 // @todo Putting this here means that only listeners querying
603 // for logic will be notified. Currently the only user of
604 // frame_began is DecoderStack, but in future we need to signal
605 // this after both analog and logic sweeps have begun.
606 frame_began();
2ad82c2e 607 } else {
f3d66e52
JH
608 // Append to the existing data segment
609 cur_logic_segment_->append_payload(logic);
9c112671
JH
610 }
611
1f374035 612 data_received();
9c112671
JH
613}
614
2b81ae46 615void Session::feed_in_analog(shared_ptr<Analog> analog)
aba1dd16 616{
8524a597 617 lock_guard<recursive_mutex> lock(data_mutex_);
79efbc53 618
e8d00928
ML
619 const vector<shared_ptr<Channel>> channels = analog->channels();
620 const unsigned int channel_count = channels.size();
621 const size_t sample_count = analog->num_samples() / channel_count;
475f4d08 622 const float *data = static_cast<const float *>(analog->data_pointer());
bb2cdfff 623 bool sweep_beginning = false;
be73bdfa 624
47e9e7bb 625 if (signalbases_.empty())
a3f678a7 626 update_signals();
a3f678a7 627
2ad82c2e 628 for (auto channel : channels) {
f3d66e52 629 shared_ptr<data::AnalogSegment> segment;
2b49eeb0 630
f3d66e52
JH
631 // Try to get the segment of the channel
632 const map< shared_ptr<Channel>, shared_ptr<data::AnalogSegment> >::
633 iterator iter = cur_analog_segments_.find(channel);
634 if (iter != cur_analog_segments_.end())
635 segment = (*iter).second;
2ad82c2e 636 else {
39ccf9c3 637 // If no segment was found, this means we haven't
bb2cdfff 638 // created one yet. i.e. this is the first packet
f3d66e52 639 // in the sweep containing this segment.
bb2cdfff
JH
640 sweep_beginning = true;
641
f3d66e52
JH
642 // Create a segment, keep it in the maps of channels
643 segment = shared_ptr<data::AnalogSegment>(
644 new data::AnalogSegment(
ff4bf6bd 645 cur_samplerate_, sample_count));
f3d66e52 646 cur_analog_segments_[channel] = segment;
bb2cdfff 647
ff4bf6bd 648 // Find the analog data associated with the channel
cbd2a2de
SA
649 shared_ptr<data::SignalBase> base = signalbase_from_channel(channel);
650 assert(base);
bb2cdfff 651
cbd2a2de 652 shared_ptr<data::Analog> data(base->analog_data());
bb2cdfff
JH
653 assert(data);
654
f3d66e52
JH
655 // Push the segment into the analog data.
656 data->push_segment(segment);
bb2cdfff
JH
657 }
658
f3d66e52 659 assert(segment);
bb2cdfff 660
f3d66e52
JH
661 // Append the samples in the segment
662 segment->append_interleaved_samples(data++, sample_count,
6ac6242b 663 channel_count);
aba1dd16 664 }
bb2cdfff
JH
665
666 if (sweep_beginning) {
667 // This could be the first packet after a trigger
668 set_capture_state(Running);
aba1dd16
JH
669 }
670
1f374035 671 data_received();
aba1dd16 672}
9c112671 673
da30ecb7
JH
674void Session::data_feed_in(shared_ptr<sigrok::Device> device,
675 shared_ptr<Packet> packet)
b0e1d01d 676{
da30ecb7
JH
677 (void)device;
678
e8d00928 679 assert(device);
da30ecb7 680 assert(device == device_->device());
b0e1d01d
JH
681 assert(packet);
682
e8d00928 683 switch (packet->type()->id()) {
b0e1d01d 684 case SR_DF_HEADER:
da30ecb7 685 feed_in_header();
b0e1d01d
JH
686 break;
687
be73bdfa 688 case SR_DF_META:
da30ecb7 689 feed_in_meta(dynamic_pointer_cast<Meta>(packet->payload()));
aba1dd16
JH
690 break;
691
48257a69
SA
692 case SR_DF_TRIGGER:
693 feed_in_trigger();
694 break;
695
82f50b10
JH
696 case SR_DF_FRAME_BEGIN:
697 feed_in_frame_begin();
698 break;
699
2e2946fe 700 case SR_DF_LOGIC:
e7216ae0
SA
701 try {
702 feed_in_logic(dynamic_pointer_cast<Logic>(packet->payload()));
703 } catch (std::bad_alloc) {
704 out_of_memory_ = true;
705 device_->stop();
706 }
2953961c
JH
707 break;
708
aba1dd16 709 case SR_DF_ANALOG:
e7216ae0
SA
710 try {
711 feed_in_analog(dynamic_pointer_cast<Analog>(packet->payload()));
712 } catch (std::bad_alloc) {
713 out_of_memory_ = true;
714 device_->stop();
715 }
aba1dd16
JH
716 break;
717
2953961c 718 case SR_DF_END:
2e2946fe
JH
719 {
720 {
8524a597 721 lock_guard<recursive_mutex> lock(data_mutex_);
f3d66e52
JH
722 cur_logic_segment_.reset();
723 cur_analog_segments_.clear();
2e2946fe 724 }
1f374035 725 frame_ended();
2953961c
JH
726 break;
727 }
adb0a983
ML
728 default:
729 break;
2e2946fe 730 }
2953961c
JH
731}
732
51e77110 733} // namespace pv