]> sigrok.org Git - pulseview.git/commitdiff
Moved data and snapshot classes into pv::data namespace
authorJoel Holdsworth <redacted>
Thu, 20 Dec 2012 21:34:43 +0000 (21:34 +0000)
committerJoel Holdsworth <redacted>
Mon, 24 Dec 2012 15:26:08 +0000 (15:26 +0000)
36 files changed:
CMakeLists.txt
pv/analogdata.cpp [deleted file]
pv/analogdata.h [deleted file]
pv/analogdatasnapshot.cpp [deleted file]
pv/analogdatasnapshot.h [deleted file]
pv/data/analog.cpp [new file with mode: 0644]
pv/data/analog.h [new file with mode: 0644]
pv/data/analogsnapshot.cpp [new file with mode: 0644]
pv/data/analogsnapshot.h [new file with mode: 0644]
pv/data/logic.cpp [new file with mode: 0644]
pv/data/logic.h [new file with mode: 0644]
pv/data/logicsnapshot.cpp [new file with mode: 0644]
pv/data/logicsnapshot.h [new file with mode: 0644]
pv/data/signaldata.cpp [new file with mode: 0644]
pv/data/signaldata.h [new file with mode: 0644]
pv/data/snapshot.cpp [new file with mode: 0644]
pv/data/snapshot.h [new file with mode: 0644]
pv/datasnapshot.cpp [deleted file]
pv/datasnapshot.h [deleted file]
pv/logicdata.cpp [deleted file]
pv/logicdata.h [deleted file]
pv/logicdatasnapshot.cpp [deleted file]
pv/logicdatasnapshot.h [deleted file]
pv/signaldata.cpp [deleted file]
pv/signaldata.h [deleted file]
pv/sigsession.cpp
pv/sigsession.h
pv/view/analogsignal.cpp
pv/view/analogsignal.h
pv/view/logicsignal.cpp
pv/view/logicsignal.h
pv/view/signal.h
pv/view/view.cpp
test/CMakeLists.txt
test/data/logicsnapshot.cpp [new file with mode: 0644]
test/logicdatasnapshot.cpp [deleted file]

index e1893b6c1c47a90edd29434b7de4f5e236a22889..e9ae0e76e4de201664c3d640ec59d4b9ce24038c 100644 (file)
@@ -80,15 +80,15 @@ configure_file (
 
 set(pulseview_SOURCES
        main.cpp
-       pv/analogdata.cpp
-       pv/analogdatasnapshot.cpp
-       pv/datasnapshot.cpp
-       pv/logicdata.cpp
-       pv/logicdatasnapshot.cpp
        pv/mainwindow.cpp
        pv/samplingbar.cpp
-       pv/signaldata.cpp
        pv/sigsession.cpp
+       pv/data/analog.cpp
+       pv/data/analogsnapshot.cpp
+       pv/data/logic.cpp
+       pv/data/logicsnapshot.cpp
+       pv/data/signaldata.cpp
+       pv/data/snapshot.cpp
        pv/dialogs/about.cpp
        pv/view/analogsignal.cpp
        pv/view/cursor.cpp
diff --git a/pv/analogdata.cpp b/pv/analogdata.cpp
deleted file mode 100644 (file)
index 8cfa7a6..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include "analogdata.h"
-#include "analogdatasnapshot.h"
-
-using namespace boost;
-using namespace std;
-
-namespace pv {
-
-AnalogData::AnalogData(const sr_datafeed_meta_analog &meta,
-       uint64_t samplerate) :
-       SignalData(samplerate)
-{
-}
-
-void AnalogData::push_snapshot(
-       boost::shared_ptr<AnalogDataSnapshot> &snapshot)
-{
-       _snapshots.push_front(snapshot);
-}
-
-deque< shared_ptr<AnalogDataSnapshot> >& AnalogData::get_snapshots()
-{
-       return _snapshots;
-}
-
-} // namespace pv
diff --git a/pv/analogdata.h b/pv/analogdata.h
deleted file mode 100644 (file)
index e1c4ee6..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef PULSEVIEW_PV_ANALOGDATA_H
-#define PULSEVIEW_PV_ANALOGDATA_H
-
-#include "signaldata.h"
-
-#include <boost/shared_ptr.hpp>
-#include <deque>
-
-extern "C" {
-#include <libsigrok/libsigrok.h>
-}
-
-namespace pv {
-
-class AnalogDataSnapshot;
-
-class AnalogData : public SignalData
-{
-public:
-       AnalogData(const sr_datafeed_meta_analog &meta,
-               uint64_t samplerate);
-
-       void push_snapshot(
-               boost::shared_ptr<AnalogDataSnapshot> &snapshot);
-
-       std::deque< boost::shared_ptr<AnalogDataSnapshot> >&
-               get_snapshots();
-
-private:
-       std::deque< boost::shared_ptr<AnalogDataSnapshot> >
-               _snapshots;
-};
-
-} // namespace pv
-
-#endif // PULSEVIEW_PV_ANALOGDATA_H
diff --git a/pv/analogdatasnapshot.cpp b/pv/analogdatasnapshot.cpp
deleted file mode 100644 (file)
index c66e9b9..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include <extdef.h>
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include <boost/foreach.hpp>
-
-#include "analogdatasnapshot.h"
-
-using namespace boost;
-using namespace std;
-
-namespace pv {
-
-AnalogDataSnapshot::AnalogDataSnapshot(
-       const sr_datafeed_analog &analog) :
-       DataSnapshot(sizeof(float))
-{
-       lock_guard<recursive_mutex> lock(_mutex);
-       append_payload(analog);
-}
-
-void AnalogDataSnapshot::append_payload(
-       const sr_datafeed_analog &analog)
-{
-       lock_guard<recursive_mutex> lock(_mutex);
-       append_data(analog.data, analog.num_samples);
-}
-
-const float* AnalogDataSnapshot::get_samples() const
-{
-       return (const float*)_data;
-}
-
-} // namespace pv
diff --git a/pv/analogdatasnapshot.h b/pv/analogdatasnapshot.h
deleted file mode 100644 (file)
index ce8a99d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef PULSEVIEW_PV_ANALOGDATASNAPSHOT_H
-#define PULSEVIEW_PV_ANALOGDATASNAPSHOT_H
-
-#include "datasnapshot.h"
-
-#include <utility>
-#include <vector>
-
-namespace pv {
-
-class AnalogDataSnapshot : public DataSnapshot
-{
-public:
-       AnalogDataSnapshot(const sr_datafeed_analog &analog);
-
-       void append_payload(const sr_datafeed_analog &analog);
-
-       const float* get_samples() const;
-};
-
-} // namespace pv
-
-#endif // PULSEVIEW_PV_ANALOGDATASNAPSHOT_H
diff --git a/pv/data/analog.cpp b/pv/data/analog.cpp
new file mode 100644 (file)
index 0000000..9e43e86
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "analog.h"
+#include "analogsnapshot.h"
+
+using namespace boost;
+using namespace std;
+
+namespace pv {
+namespace data {
+
+Analog::Analog(const sr_datafeed_meta_analog &meta,
+       uint64_t samplerate) :
+       SignalData(samplerate)
+{
+}
+
+void Analog::push_snapshot(shared_ptr<AnalogSnapshot> &snapshot)
+{
+       _snapshots.push_front(snapshot);
+}
+
+deque< shared_ptr<AnalogSnapshot> >& Analog::get_snapshots()
+{
+       return _snapshots;
+}
+
+} // namespace data
+} // namespace pv
diff --git a/pv/data/analog.h b/pv/data/analog.h
new file mode 100644 (file)
index 0000000..2e2ade6
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef PULSEVIEW_PV_DATA_ANALOG_H
+#define PULSEVIEW_PV_DATA_ANALOG_H
+
+#include "signaldata.h"
+
+#include <boost/shared_ptr.hpp>
+#include <deque>
+
+extern "C" {
+#include <libsigrok/libsigrok.h>
+}
+
+namespace pv {
+namespace data {
+
+class AnalogSnapshot;
+
+class Analog : public SignalData
+{
+public:
+       Analog(const sr_datafeed_meta_analog &meta,
+               uint64_t samplerate);
+
+       void push_snapshot(
+               boost::shared_ptr<AnalogSnapshot> &snapshot);
+
+       std::deque< boost::shared_ptr<AnalogSnapshot> >&
+               get_snapshots();
+
+private:
+       std::deque< boost::shared_ptr<AnalogSnapshot> > _snapshots;
+};
+
+} // namespace data
+} // namespace pv
+
+#endif // PULSEVIEW_PV_DATA_ANALOG_H
diff --git a/pv/data/analogsnapshot.cpp b/pv/data/analogsnapshot.cpp
new file mode 100644 (file)
index 0000000..2bcb99f
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <extdef.h>
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <boost/foreach.hpp>
+
+#include "analogsnapshot.h"
+
+using namespace boost;
+using namespace std;
+
+namespace pv {
+namespace data {
+
+AnalogSnapshot::AnalogSnapshot(const sr_datafeed_analog &analog) :
+       Snapshot(sizeof(float))
+{
+       lock_guard<recursive_mutex> lock(_mutex);
+       append_payload(analog);
+}
+
+void AnalogSnapshot::append_payload(
+       const sr_datafeed_analog &analog)
+{
+       lock_guard<recursive_mutex> lock(_mutex);
+       append_data(analog.data, analog.num_samples);
+}
+
+const float* AnalogSnapshot::get_samples() const
+{
+       return (const float*)_data;
+}
+
+} // namespace data
+} // namespace pv
diff --git a/pv/data/analogsnapshot.h b/pv/data/analogsnapshot.h
new file mode 100644 (file)
index 0000000..9ca08f1
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef PULSEVIEW_PV_DATA_ANALOGSNAPSHOT_H
+#define PULSEVIEW_PV_DATA_ANALOGSNAPSHOT_H
+
+#include "snapshot.h"
+
+#include <utility>
+#include <vector>
+
+namespace pv {
+namespace data {
+
+class AnalogSnapshot : public Snapshot
+{
+public:
+       AnalogSnapshot(const sr_datafeed_analog &analog);
+
+       void append_payload(const sr_datafeed_analog &analog);
+
+       const float* get_samples() const;
+};
+
+} // namespace data
+} // namespace pv
+
+#endif // PULSEVIEW_PV_DATA_ANALOGSNAPSHOT_H
diff --git a/pv/data/logic.cpp b/pv/data/logic.cpp
new file mode 100644 (file)
index 0000000..7b42e47
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "logic.h"
+#include "logicsnapshot.h"
+
+using namespace boost;
+using namespace std;
+
+namespace pv {
+namespace data {
+
+Logic::Logic(const sr_datafeed_meta_logic &meta,
+       uint64_t samplerate) :
+       SignalData(samplerate),
+       _num_probes(meta.num_probes)
+{
+}
+
+int Logic::get_num_probes() const
+{
+       return _num_probes;
+}
+
+void Logic::push_snapshot(
+       shared_ptr<LogicSnapshot> &snapshot)
+{
+       _snapshots.push_front(snapshot);
+}
+
+deque< shared_ptr<LogicSnapshot> >& Logic::get_snapshots()
+{
+       return _snapshots;
+}
+
+} // namespace data
+} // namespace pv
diff --git a/pv/data/logic.h b/pv/data/logic.h
new file mode 100644 (file)
index 0000000..4b70b8f
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef PULSEVIEW_PV_DATA_LOGIC_H
+#define PULSEVIEW_PV_DATA_LOGIC_H
+
+#include "signaldata.h"
+
+#include <boost/shared_ptr.hpp>
+#include <deque>
+
+extern "C" {
+#include <libsigrok/libsigrok.h>
+}
+
+namespace pv {
+namespace data {
+
+class LogicSnapshot;
+
+class Logic : public SignalData
+{
+public:
+       Logic(const sr_datafeed_meta_logic &meta, uint64_t samplerate);
+
+       int get_num_probes() const;
+
+       void push_snapshot(
+               boost::shared_ptr<LogicSnapshot> &snapshot);
+
+       std::deque< boost::shared_ptr<LogicSnapshot> >&
+               get_snapshots();
+
+private:
+       const int _num_probes;
+       std::deque< boost::shared_ptr<LogicSnapshot> > _snapshots;
+};
+
+} // namespace data
+} // namespace pv
+
+#endif // PULSEVIEW_PV_DATA_LOGIC_H
diff --git a/pv/data/logicsnapshot.cpp b/pv/data/logicsnapshot.cpp
new file mode 100644 (file)
index 0000000..03e6a54
--- /dev/null
@@ -0,0 +1,366 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <extdef.h>
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <boost/foreach.hpp>
+
+#include "logicsnapshot.h"
+
+using namespace boost;
+using namespace std;
+
+namespace pv {
+namespace data {
+
+const int LogicSnapshot::MipMapScalePower = 4;
+const int LogicSnapshot::MipMapScaleFactor = 1 << MipMapScalePower;
+const float LogicSnapshot::LogMipMapScaleFactor = logf(MipMapScaleFactor);
+const uint64_t LogicSnapshot::MipMapDataUnit = 64*1024;        // bytes
+
+LogicSnapshot::LogicSnapshot(const sr_datafeed_logic &logic) :
+       Snapshot(logic.unitsize),
+       _last_append_sample(0)
+{
+       lock_guard<recursive_mutex> lock(_mutex);
+       memset(_mip_map, 0, sizeof(_mip_map));
+       append_payload(logic);
+}
+
+LogicSnapshot::~LogicSnapshot()
+{
+       lock_guard<recursive_mutex> lock(_mutex);
+       BOOST_FOREACH(MipMapLevel &l, _mip_map)
+               free(l.data);
+}
+
+void LogicSnapshot::append_payload(
+       const sr_datafeed_logic &logic)
+{
+       assert(_unit_size == logic.unitsize);
+
+       lock_guard<recursive_mutex> lock(_mutex);
+
+       append_data(logic.data, logic.length);
+
+       // Generate the first mip-map from the data
+       append_payload_to_mipmap();
+}
+
+void LogicSnapshot::reallocate_mip_map(MipMapLevel &m)
+{
+       const uint64_t new_data_length = ((m.length + MipMapDataUnit - 1) /
+               MipMapDataUnit) * MipMapDataUnit;
+       if (new_data_length > m.data_length)
+       {
+               m.data_length = new_data_length;
+               m.data = realloc(m.data, new_data_length * _unit_size);
+       }
+}
+
+void LogicSnapshot::append_payload_to_mipmap()
+{
+       MipMapLevel &m0 = _mip_map[0];
+       uint64_t prev_length;
+       const uint8_t *src_ptr;
+       uint8_t *dest_ptr;
+       uint64_t accumulator;
+       unsigned int diff_counter;
+
+       // Expand the data buffer to fit the new samples
+       prev_length = m0.length;
+       m0.length = _sample_count / MipMapScaleFactor;
+
+       // Break off if there are no new samples to compute
+       if (m0.length == prev_length)
+               return;
+
+       reallocate_mip_map(m0);
+
+       dest_ptr = (uint8_t*)m0.data + prev_length * _unit_size;
+
+       // Iterate through the samples to populate the first level mipmap
+       accumulator = 0;
+       diff_counter = MipMapScaleFactor;
+       const uint8_t *end_src_ptr = (uint8_t*)_data +
+               m0.length * _unit_size * MipMapScaleFactor;
+       for (src_ptr = (uint8_t*)_data +
+               prev_length * _unit_size * MipMapScaleFactor;
+               src_ptr < end_src_ptr;)
+       {
+               // Accumulate transitions which have occurred in this sample
+               accumulator = 0;
+               diff_counter = MipMapScaleFactor;
+               while (diff_counter-- > 0)
+               {
+                       const uint64_t sample = *(uint64_t*)src_ptr;
+                       accumulator |= _last_append_sample ^ sample;
+                       _last_append_sample = sample;
+                       src_ptr += _unit_size;
+               }
+
+               *(uint64_t*)dest_ptr = accumulator;
+               dest_ptr += _unit_size;
+       }
+
+       // Compute higher level mipmaps
+       for (unsigned int level = 1; level < ScaleStepCount; level++)
+       {
+               MipMapLevel &m = _mip_map[level];
+               const MipMapLevel &ml = _mip_map[level-1];
+
+               // Expand the data buffer to fit the new samples
+               prev_length = m.length;
+               m.length = ml.length / MipMapScaleFactor;
+
+               // Break off if there are no more samples to computed
+               if (m.length == prev_length)
+                       break;
+
+               reallocate_mip_map(m);
+
+               // Subsample the level lower level
+               src_ptr = (uint8_t*)ml.data +
+                       _unit_size * prev_length * MipMapScaleFactor;
+               const uint8_t *end_dest_ptr =
+                       (uint8_t*)m.data + _unit_size * m.length;
+               for (dest_ptr = (uint8_t*)m.data +
+                       _unit_size * prev_length;
+                       dest_ptr < end_dest_ptr;
+                       dest_ptr += _unit_size)
+               {
+                       accumulator = 0;
+                       diff_counter = MipMapScaleFactor;
+                       while (diff_counter-- > 0)
+                       {
+                               accumulator |= *(uint64_t*)src_ptr;
+                               src_ptr += _unit_size;
+                       }
+
+                       *(uint64_t*)dest_ptr = accumulator;
+               }
+       }
+}
+
+uint64_t LogicSnapshot::get_sample(uint64_t index) const
+{
+       assert(_data);
+       assert(index >= 0 && index < _sample_count);
+
+       return *(uint64_t*)((uint8_t*)_data + index * _unit_size);
+}
+
+void LogicSnapshot::get_subsampled_edges(
+       std::vector<EdgePair> &edges,
+       uint64_t start, uint64_t end,
+       float min_length, int sig_index)
+{
+       uint64_t index = start;
+       unsigned int level;
+       bool last_sample;
+       bool fast_forward;
+
+       assert(start >= 0);
+       assert(end <= get_sample_count());
+       assert(start <= end);
+       assert(min_length > 0);
+       assert(sig_index >= 0);
+       assert(sig_index < SR_MAX_NUM_PROBES);
+
+       lock_guard<recursive_mutex> lock(_mutex);
+
+       const uint64_t block_length = (uint64_t)max(min_length, 1.0f);
+       const unsigned int min_level = max((int)floorf(logf(min_length) /
+               LogMipMapScaleFactor) - 1, 0);
+       const uint64_t sig_mask = 1ULL << sig_index;
+
+       // Store the initial state
+       last_sample = (get_sample(start) & sig_mask) != 0;
+       edges.push_back(pair<int64_t, bool>(index++, last_sample));
+
+       while (index + block_length <= end)
+       {
+               //----- Continue to search -----//
+               level = min_level;
+               fast_forward = true;
+
+               if (min_length < MipMapScaleFactor)
+               {
+                       // Search individual samples up to the beginning of
+                       // the next first level mip map block
+                       const uint64_t final_index = min(end,
+                               pow2_ceil(index, MipMapScalePower));
+
+                       for (; index < final_index &&
+                               (index & ~(~0 << MipMapScalePower)) != 0;
+                               index++)
+                       {
+                               const bool sample =
+                                       (get_sample(index) & sig_mask) != 0;
+
+                               // If there was a change we cannot fast forward
+                               if (sample != last_sample) {
+                                       fast_forward = false;
+                                       break;
+                               }
+                       }
+               }
+               else
+               {
+                       // If resolution is less than a mip map block,
+                       // round up to the beginning of the mip-map block
+                       // for this level of detail
+                       const int min_level_scale_power =
+                               (level + 1) * MipMapScalePower;
+                       index = pow2_ceil(index, min_level_scale_power);
+                       if (index >= end)
+                               break;
+
+                       // We can fast forward only if there was no change
+                       const bool sample =
+                               (get_sample(index) & sig_mask) != 0;
+                       fast_forward = last_sample == sample;
+               }
+
+               if (fast_forward) {
+
+                       // Fast forward: This involves zooming out to higher
+                       // levels of the mip map searching for changes, then
+                       // zooming in on them to find the point where the edge
+                       // begins.
+
+                       // Slide right and zoom out at the beginnings of mip-map
+                       // blocks until we encounter a change
+                       while (1) {
+                               const int level_scale_power =
+                                       (level + 1) * MipMapScalePower;
+                               const uint64_t offset =
+                                       index >> level_scale_power;
+                               assert(offset >= 0);
+
+                               // Check if we reached the last block at this
+                               // level, or if there was a change in this block
+                               if (offset >= _mip_map[level].length ||
+                                       (get_subsample(level, offset) &
+                                               sig_mask))
+                                       break;
+
+                               if ((offset & ~(~0 << MipMapScalePower)) == 0) {
+                                       // If we are now at the beginning of a
+                                       // higher level mip-map block ascend one
+                                       // level
+                                       if (level + 1 >= ScaleStepCount ||
+                                               !_mip_map[level + 1].data)
+                                               break;
+
+                                       level++;
+                               } else {
+                                       // Slide right to the beginning of the
+                                       // next mip map block
+                                       index = pow2_ceil(index + 1,
+                                               level_scale_power);
+                               }
+                       }
+
+                       // Zoom in, and slide right until we encounter a change,
+                       // and repeat until we reach min_level
+                       while (1) {
+                               assert(_mip_map[level].data);
+
+                               const int level_scale_power =
+                                       (level + 1) * MipMapScalePower;
+                               const uint64_t offset =
+                                       index >> level_scale_power;
+                               assert(offset >= 0);
+
+                               // Check if we reached the last block at this
+                               // level, or if there was a change in this block
+                               if (offset >= _mip_map[level].length ||
+                                       (get_subsample(level, offset) &
+                                               sig_mask)) {
+                                       // Zoom in unless we reached the minimum
+                                       // zoom
+                                       if (level == min_level)
+                                               break;
+
+                                       level--;
+                               } else {
+                                       // Slide right to the beginning of the
+                                       // next mip map block
+                                       index = pow2_ceil(index + 1,
+                                               level_scale_power);
+                               }
+                       }
+
+                       // If individual samples within the limit of resolution,
+                       // do a linear search for the next transition within the
+                       // block
+                       if (min_length < MipMapScaleFactor) {
+                               for (; index < end; index++) {
+                                       const bool sample = (get_sample(index) &
+                                               sig_mask) != 0;
+                                       if (sample != last_sample)
+                                               break;
+                               }
+                       }
+               }
+
+               //----- Store the edge -----//
+
+               // Take the last sample of the quanization block
+               const int64_t final_index = index + block_length;
+               if (index + block_length > end)
+                       break;
+
+               // Store the final state
+               const bool final_sample =
+                       (get_sample(final_index - 1) & sig_mask) != 0;
+               edges.push_back(pair<int64_t, bool>(index, final_sample));
+
+               index = final_index;
+               last_sample = final_sample;
+       }
+
+       // Add the final state
+       edges.push_back(pair<int64_t, bool>(end,
+               get_sample(end) & sig_mask));
+}
+
+uint64_t LogicSnapshot::get_subsample(int level, uint64_t offset) const
+{
+       assert(level >= 0);
+       assert(_mip_map[level].data);
+       return *(uint64_t*)((uint8_t*)_mip_map[level].data +
+               _unit_size * offset);
+}
+
+uint64_t LogicSnapshot::pow2_ceil(uint64_t x, unsigned int power)
+{
+       const uint64_t p = 1 << power;
+       return (x + p - 1) / p * p;
+}
+
+} // namespace data
+} // namespace pv
diff --git a/pv/data/logicsnapshot.h b/pv/data/logicsnapshot.h
new file mode 100644 (file)
index 0000000..8a851ac
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef PULSEVIEW_PV_DATA_LOGICSNAPSHOT_H
+#define PULSEVIEW_PV_DATA_LOGICSNAPSHOT_H
+
+#include "snapshot.h"
+
+#include <utility>
+#include <vector>
+
+namespace LogicSnapshotTest {
+       class Pow2;
+       class Basic;
+       class LargeData;
+       class Pulses;
+       class LongPulses;
+}
+
+namespace pv {
+namespace data {
+
+class LogicSnapshot : public Snapshot
+{
+private:
+       struct MipMapLevel
+       {
+               uint64_t length;
+               uint64_t data_length;
+               void *data;
+       };
+
+private:
+       static const unsigned int ScaleStepCount = 10;
+       static const int MipMapScalePower;
+       static const int MipMapScaleFactor;
+       static const float LogMipMapScaleFactor;
+       static const uint64_t MipMapDataUnit;
+
+public:
+       typedef std::pair<int64_t, bool> EdgePair;
+
+public:
+       LogicSnapshot(const sr_datafeed_logic &logic);
+
+       virtual ~LogicSnapshot();
+
+       void append_payload(const sr_datafeed_logic &logic);
+
+private:
+       void reallocate_mip_map(MipMapLevel &m);
+
+       void append_payload_to_mipmap();
+
+       uint64_t get_sample(uint64_t index) const;
+
+public:
+       /**
+        * Parses a logic data snapshot to generate a list of transitions
+        * in a time interval to a given level of detail.
+        * @param[out] edges The vector to place the edges into.
+        * @param[in] start The start sample index.
+        * @param[in] end The end sample index.
+        * @param[in] min_length The minimum number of samples that
+        * can be resolved at this level of detail.
+        * @param[in] sig_index The index of the signal.
+        **/
+       void get_subsampled_edges(std::vector<EdgePair> &edges,
+               uint64_t start, uint64_t end,
+               float min_length, int sig_index);
+
+private:
+       uint64_t get_subsample(int level, uint64_t offset) const;
+
+       static uint64_t pow2_ceil(uint64_t x, unsigned int power);
+
+private:
+       struct MipMapLevel _mip_map[ScaleStepCount];
+       uint64_t _last_append_sample;
+
+       friend class LogicSnapshotTest::Pow2;
+       friend class LogicSnapshotTest::Basic;
+       friend class LogicSnapshotTest::LargeData;
+       friend class LogicSnapshotTest::Pulses;
+       friend class LogicSnapshotTest::LongPulses;
+};
+
+} // namespace data
+} // namespace pv
+
+#endif // PULSEVIEW_PV_DATA_LOGICSNAPSHOT_H
diff --git a/pv/data/signaldata.cpp b/pv/data/signaldata.cpp
new file mode 100644 (file)
index 0000000..2c6e3c6
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "signaldata.h"
+
+namespace pv {
+namespace data {
+
+SignalData::SignalData(double samplerate) :
+       _samplerate(samplerate),
+       _start_time(0)
+{
+}
+
+double SignalData::get_samplerate() const
+{
+       return _samplerate;
+}
+
+double SignalData::get_start_time() const
+{
+       return _start_time;
+}
+
+} // namespace data
+} // namespace pv
diff --git a/pv/data/signaldata.h b/pv/data/signaldata.h
new file mode 100644 (file)
index 0000000..7f64bdb
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef PULSEVIEW_PV_DATA_SIGNALDATA_H
+#define PULSEVIEW_PV_DATA_SIGNALDATA_H
+
+#include <stdint.h>
+
+namespace pv {
+namespace data {
+
+class SignalData
+{
+public:
+       SignalData(double samplerate);
+
+public:
+       double get_samplerate() const;
+       double get_start_time() const;
+
+protected:
+       const double _samplerate;
+       const double _start_time;
+};
+
+} // namespace data
+} // namespace pv
+
+#endif // PULSEVIEW_PV_DATA_SIGNALDATA_H
diff --git a/pv/data/snapshot.cpp b/pv/data/snapshot.cpp
new file mode 100644 (file)
index 0000000..f3855e0
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "snapshot.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+using namespace boost;
+
+namespace pv {
+namespace data {
+
+Snapshot::Snapshot(int unit_size) :
+       _data(NULL),
+       _sample_count(0),
+       _unit_size(unit_size)
+{
+       lock_guard<recursive_mutex> lock(_mutex);
+       assert(_unit_size > 0);
+}
+
+Snapshot::~Snapshot()
+{
+       lock_guard<recursive_mutex> lock(_mutex);
+       free(_data);
+}
+
+uint64_t Snapshot::get_sample_count()
+{
+       lock_guard<recursive_mutex> lock(_mutex);
+       return _sample_count;
+}
+
+void Snapshot::append_data(void *data, uint64_t samples)
+{
+       lock_guard<recursive_mutex> lock(_mutex);
+       _data = realloc(_data, (_sample_count + samples) * _unit_size);
+       memcpy((uint8_t*)_data + _sample_count * _unit_size,
+               data, samples * _unit_size);
+       _sample_count += samples;
+}
+
+} // namespace data
+} // namespace pv
diff --git a/pv/data/snapshot.h b/pv/data/snapshot.h
new file mode 100644 (file)
index 0000000..7f36ee7
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef PULSEVIEW_PV_DATA_SNAPSHOT_H
+#define PULSEVIEW_PV_DATA_SNAPSHOT_H
+
+extern "C" {
+#include <libsigrok/libsigrok.h>
+}
+
+#include <boost/thread.hpp>
+
+namespace pv {
+namespace data {
+
+class Snapshot
+{
+public:
+       Snapshot(int unit_size);
+
+       virtual ~Snapshot();
+
+       uint64_t get_sample_count();
+
+protected:
+       void append_data(void *data, uint64_t samples);
+
+protected:
+       mutable boost::recursive_mutex _mutex;
+       void *_data;
+       uint64_t _sample_count;
+       int _unit_size;
+};
+
+} // namespace data
+} // namespace pv
+
+#endif // PULSEVIEW_PV_DATA_SNAPSHOT_H
diff --git a/pv/datasnapshot.cpp b/pv/datasnapshot.cpp
deleted file mode 100644 (file)
index 040d506..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include "datasnapshot.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-using namespace boost;
-
-namespace pv {
-
-DataSnapshot::DataSnapshot(int unit_size) :
-       _data(NULL),
-       _sample_count(0),
-       _unit_size(unit_size)
-{
-       lock_guard<recursive_mutex> lock(_mutex);
-       assert(_unit_size > 0);
-}
-
-DataSnapshot::~DataSnapshot()
-{
-       lock_guard<recursive_mutex> lock(_mutex);
-       free(_data);
-}
-
-uint64_t DataSnapshot::get_sample_count()
-{
-       lock_guard<recursive_mutex> lock(_mutex);
-       return _sample_count;
-}
-
-void DataSnapshot::append_data(void *data, uint64_t samples)
-{
-       lock_guard<recursive_mutex> lock(_mutex);
-       _data = realloc(_data, (_sample_count + samples) * _unit_size);
-       memcpy((uint8_t*)_data + _sample_count * _unit_size,
-               data, samples * _unit_size);
-       _sample_count += samples;
-}
-
-} // namespace pv
diff --git a/pv/datasnapshot.h b/pv/datasnapshot.h
deleted file mode 100644 (file)
index 2a6651e..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef PULSEVIEW_PV_DATASNAPSHOT_H
-#define PULSEVIEW_PV_DATASNAPSHOT_H
-
-extern "C" {
-#include <libsigrok/libsigrok.h>
-}
-
-#include <boost/thread.hpp>
-
-namespace pv {
-
-class DataSnapshot
-{
-public:
-       DataSnapshot(int unit_size);
-
-       virtual ~DataSnapshot();
-
-       uint64_t get_sample_count();
-
-protected:
-       void append_data(void *data, uint64_t samples);
-
-protected:
-       mutable boost::recursive_mutex _mutex;
-       void *_data;
-       uint64_t _sample_count;
-       int _unit_size;
-};
-
-} // namespace pv
-
-#endif // PULSEVIEW_PV_DATASNAPSHOT_H
diff --git a/pv/logicdata.cpp b/pv/logicdata.cpp
deleted file mode 100644 (file)
index 492961f..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include "logicdata.h"
-#include "logicdatasnapshot.h"
-
-using namespace boost;
-using namespace std;
-
-namespace pv {
-
-LogicData::LogicData(const sr_datafeed_meta_logic &meta,
-       uint64_t samplerate) :
-       SignalData(samplerate),
-       _num_probes(meta.num_probes)
-{
-}
-
-int LogicData::get_num_probes() const
-{
-       return _num_probes;
-}
-
-void LogicData::push_snapshot(
-       boost::shared_ptr<LogicDataSnapshot> &snapshot)
-{
-       _snapshots.push_front(snapshot);
-}
-
-deque< shared_ptr<LogicDataSnapshot> >& LogicData::get_snapshots()
-{
-       return _snapshots;
-}
-
-} // namespace pv
diff --git a/pv/logicdata.h b/pv/logicdata.h
deleted file mode 100644 (file)
index af1d32e..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef PULSEVIEW_PV_LOGICDATA_H
-#define PULSEVIEW_PV_LOGICDATA_H
-
-#include "signaldata.h"
-
-#include <boost/shared_ptr.hpp>
-#include <deque>
-
-extern "C" {
-#include <libsigrok/libsigrok.h>
-}
-
-namespace pv {
-
-class LogicDataSnapshot;
-
-class LogicData : public SignalData
-{
-public:
-       LogicData(const sr_datafeed_meta_logic &meta, uint64_t samplerate);
-
-       int get_num_probes() const;
-
-       void push_snapshot(
-               boost::shared_ptr<LogicDataSnapshot> &snapshot);
-
-       std::deque< boost::shared_ptr<LogicDataSnapshot> >&
-               get_snapshots();
-
-private:
-       const int _num_probes;
-       std::deque< boost::shared_ptr<LogicDataSnapshot> >
-               _snapshots;
-};
-
-} // namespace pv
-
-#endif // PULSEVIEW_PV_LOGICDATA_H
diff --git a/pv/logicdatasnapshot.cpp b/pv/logicdatasnapshot.cpp
deleted file mode 100644 (file)
index bd2404a..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include <extdef.h>
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include <boost/foreach.hpp>
-
-#include "logicdatasnapshot.h"
-
-using namespace boost;
-using namespace std;
-
-namespace pv {
-
-const int LogicDataSnapshot::MipMapScalePower = 4;
-const int LogicDataSnapshot::MipMapScaleFactor = 1 << MipMapScalePower;
-const float LogicDataSnapshot::LogMipMapScaleFactor = logf(MipMapScaleFactor);
-const uint64_t LogicDataSnapshot::MipMapDataUnit = 64*1024;    // bytes
-
-LogicDataSnapshot::LogicDataSnapshot(
-       const sr_datafeed_logic &logic) :
-       DataSnapshot(logic.unitsize),
-       _last_append_sample(0)
-{
-       lock_guard<recursive_mutex> lock(_mutex);
-       memset(_mip_map, 0, sizeof(_mip_map));
-       append_payload(logic);
-}
-
-LogicDataSnapshot::~LogicDataSnapshot()
-{
-       lock_guard<recursive_mutex> lock(_mutex);
-       BOOST_FOREACH(MipMapLevel &l, _mip_map)
-               free(l.data);
-}
-
-void LogicDataSnapshot::append_payload(
-       const sr_datafeed_logic &logic)
-{
-       assert(_unit_size == logic.unitsize);
-
-       lock_guard<recursive_mutex> lock(_mutex);
-
-       append_data(logic.data, logic.length);
-
-       // Generate the first mip-map from the data
-       append_payload_to_mipmap();
-}
-
-void LogicDataSnapshot::reallocate_mip_map(MipMapLevel &m)
-{
-       const uint64_t new_data_length = ((m.length + MipMapDataUnit - 1) /
-               MipMapDataUnit) * MipMapDataUnit;
-       if (new_data_length > m.data_length)
-       {
-               m.data_length = new_data_length;
-               m.data = realloc(m.data, new_data_length * _unit_size);
-       }
-}
-
-void LogicDataSnapshot::append_payload_to_mipmap()
-{
-       MipMapLevel &m0 = _mip_map[0];
-       uint64_t prev_length;
-       const uint8_t *src_ptr;
-       uint8_t *dest_ptr;
-       uint64_t accumulator;
-       unsigned int diff_counter;
-
-       // Expand the data buffer to fit the new samples
-       prev_length = m0.length;
-       m0.length = _sample_count / MipMapScaleFactor;
-
-       // Break off if there are no new samples to compute
-       if (m0.length == prev_length)
-               return;
-
-       reallocate_mip_map(m0);
-
-       dest_ptr = (uint8_t*)m0.data + prev_length * _unit_size;
-
-       // Iterate through the samples to populate the first level mipmap
-       accumulator = 0;
-       diff_counter = MipMapScaleFactor;
-       const uint8_t *end_src_ptr = (uint8_t*)_data +
-               m0.length * _unit_size * MipMapScaleFactor;
-       for (src_ptr = (uint8_t*)_data +
-               prev_length * _unit_size * MipMapScaleFactor;
-               src_ptr < end_src_ptr;)
-       {
-               // Accumulate transitions which have occurred in this sample
-               accumulator = 0;
-               diff_counter = MipMapScaleFactor;
-               while (diff_counter-- > 0)
-               {
-                       const uint64_t sample = *(uint64_t*)src_ptr;
-                       accumulator |= _last_append_sample ^ sample;
-                       _last_append_sample = sample;
-                       src_ptr += _unit_size;
-               }
-
-               *(uint64_t*)dest_ptr = accumulator;
-               dest_ptr += _unit_size;
-       }
-
-       // Compute higher level mipmaps
-       for (unsigned int level = 1; level < ScaleStepCount; level++)
-       {
-               MipMapLevel &m = _mip_map[level];
-               const MipMapLevel &ml = _mip_map[level-1];
-
-               // Expand the data buffer to fit the new samples
-               prev_length = m.length;
-               m.length = ml.length / MipMapScaleFactor;
-
-               // Break off if there are no more samples to computed
-               if (m.length == prev_length)
-                       break;
-
-               reallocate_mip_map(m);
-
-               // Subsample the level lower level
-               src_ptr = (uint8_t*)ml.data +
-                       _unit_size * prev_length * MipMapScaleFactor;
-               const uint8_t *end_dest_ptr =
-                       (uint8_t*)m.data + _unit_size * m.length;
-               for (dest_ptr = (uint8_t*)m.data +
-                       _unit_size * prev_length;
-                       dest_ptr < end_dest_ptr;
-                       dest_ptr += _unit_size)
-               {
-                       accumulator = 0;
-                       diff_counter = MipMapScaleFactor;
-                       while (diff_counter-- > 0)
-                       {
-                               accumulator |= *(uint64_t*)src_ptr;
-                               src_ptr += _unit_size;
-                       }
-
-                       *(uint64_t*)dest_ptr = accumulator;
-               }
-       }
-}
-
-uint64_t LogicDataSnapshot::get_sample(uint64_t index) const
-{
-       assert(_data);
-       assert(index >= 0 && index < _sample_count);
-
-       return *(uint64_t*)((uint8_t*)_data + index * _unit_size);
-}
-
-void LogicDataSnapshot::get_subsampled_edges(
-       std::vector<EdgePair> &edges,
-       uint64_t start, uint64_t end,
-       float min_length, int sig_index)
-{
-       uint64_t index = start;
-       unsigned int level;
-       bool last_sample;
-       bool fast_forward;
-
-       assert(start >= 0);
-       assert(end <= get_sample_count());
-       assert(start <= end);
-       assert(min_length > 0);
-       assert(sig_index >= 0);
-       assert(sig_index < SR_MAX_NUM_PROBES);
-
-       lock_guard<recursive_mutex> lock(_mutex);
-
-       const uint64_t block_length = (uint64_t)max(min_length, 1.0f);
-       const unsigned int min_level = max((int)floorf(logf(min_length) /
-               LogMipMapScaleFactor) - 1, 0);
-       const uint64_t sig_mask = 1ULL << sig_index;
-
-       // Store the initial state
-       last_sample = (get_sample(start) & sig_mask) != 0;
-       edges.push_back(pair<int64_t, bool>(index++, last_sample));
-
-       while (index + block_length <= end)
-       {
-               //----- Continue to search -----//
-               level = min_level;
-               fast_forward = true;
-
-               if (min_length < MipMapScaleFactor)
-               {
-                       // Search individual samples up to the beginning of
-                       // the next first level mip map block
-                       const uint64_t final_index = min(end,
-                               pow2_ceil(index, MipMapScalePower));
-
-                       for (; index < final_index &&
-                               (index & ~(~0 << MipMapScalePower)) != 0;
-                               index++)
-                       {
-                               const bool sample =
-                                       (get_sample(index) & sig_mask) != 0;
-
-                               // If there was a change we cannot fast forward
-                               if (sample != last_sample) {
-                                       fast_forward = false;
-                                       break;
-                               }
-                       }
-               }
-               else
-               {
-                       // If resolution is less than a mip map block,
-                       // round up to the beginning of the mip-map block
-                       // for this level of detail
-                       const int min_level_scale_power =
-                               (level + 1) * MipMapScalePower;
-                       index = pow2_ceil(index, min_level_scale_power);
-                       if (index >= end)
-                               break;
-
-                       // We can fast forward only if there was no change
-                       const bool sample =
-                               (get_sample(index) & sig_mask) != 0;
-                       fast_forward = last_sample == sample;
-               }
-
-               if (fast_forward) {
-
-                       // Fast forward: This involves zooming out to higher
-                       // levels of the mip map searching for changes, then
-                       // zooming in on them to find the point where the edge
-                       // begins.
-
-                       // Slide right and zoom out at the beginnings of mip-map
-                       // blocks until we encounter a change
-                       while (1) {
-                               const int level_scale_power =
-                                       (level + 1) * MipMapScalePower;
-                               const uint64_t offset =
-                                       index >> level_scale_power;
-                               assert(offset >= 0);
-
-                               // Check if we reached the last block at this
-                               // level, or if there was a change in this block
-                               if (offset >= _mip_map[level].length ||
-                                       (get_subsample(level, offset) &
-                                               sig_mask))
-                                       break;
-
-                               if ((offset & ~(~0 << MipMapScalePower)) == 0) {
-                                       // If we are now at the beginning of a
-                                       // higher level mip-map block ascend one
-                                       // level
-                                       if (level + 1 >= ScaleStepCount ||
-                                               !_mip_map[level + 1].data)
-                                               break;
-
-                                       level++;
-                               } else {
-                                       // Slide right to the beginning of the
-                                       // next mip map block
-                                       index = pow2_ceil(index + 1,
-                                               level_scale_power);
-                               }
-                       }
-
-                       // Zoom in, and slide right until we encounter a change,
-                       // and repeat until we reach min_level
-                       while (1) {
-                               assert(_mip_map[level].data);
-
-                               const int level_scale_power =
-                                       (level + 1) * MipMapScalePower;
-                               const uint64_t offset =
-                                       index >> level_scale_power;
-                               assert(offset >= 0);
-
-                               // Check if we reached the last block at this
-                               // level, or if there was a change in this block
-                               if (offset >= _mip_map[level].length ||
-                                       (get_subsample(level, offset) &
-                                               sig_mask)) {
-                                       // Zoom in unless we reached the minimum
-                                       // zoom
-                                       if (level == min_level)
-                                               break;
-
-                                       level--;
-                               } else {
-                                       // Slide right to the beginning of the
-                                       // next mip map block
-                                       index = pow2_ceil(index + 1,
-                                               level_scale_power);
-                               }
-                       }
-
-                       // If individual samples within the limit of resolution,
-                       // do a linear search for the next transition within the
-                       // block
-                       if (min_length < MipMapScaleFactor) {
-                               for (; index < end; index++) {
-                                       const bool sample = (get_sample(index) &
-                                               sig_mask) != 0;
-                                       if (sample != last_sample)
-                                               break;
-                               }
-                       }
-               }
-
-               //----- Store the edge -----//
-
-               // Take the last sample of the quanization block
-               const int64_t final_index = index + block_length;
-               if (index + block_length > end)
-                       break;
-
-               // Store the final state
-               const bool final_sample =
-                       (get_sample(final_index - 1) & sig_mask) != 0;
-               edges.push_back(pair<int64_t, bool>(index, final_sample));
-
-               index = final_index;
-               last_sample = final_sample;
-       }
-
-       // Add the final state
-       edges.push_back(pair<int64_t, bool>(end,
-               get_sample(end) & sig_mask));
-}
-
-uint64_t LogicDataSnapshot::get_subsample(int level, uint64_t offset) const
-{
-       assert(level >= 0);
-       assert(_mip_map[level].data);
-       return *(uint64_t*)((uint8_t*)_mip_map[level].data +
-               _unit_size * offset);
-}
-
-uint64_t LogicDataSnapshot::pow2_ceil(uint64_t x, unsigned int power)
-{
-       const uint64_t p = 1 << power;
-       return (x + p - 1) / p * p;
-}
-
-} // namespace pv
diff --git a/pv/logicdatasnapshot.h b/pv/logicdatasnapshot.h
deleted file mode 100644 (file)
index 6368020..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef PULSEVIEW_PV_LOGICDATASNAPSHOT_H
-#define PULSEVIEW_PV_LOGICDATASNAPSHOT_H
-
-#include "datasnapshot.h"
-
-#include <utility>
-#include <vector>
-
-namespace LogicDataSnapshotTest {
-       class Pow2;
-       class Basic;
-       class LargeData;
-       class Pulses;
-       class LongPulses;
-}
-
-namespace pv {
-
-class LogicDataSnapshot : public DataSnapshot
-{
-private:
-       struct MipMapLevel
-       {
-               uint64_t length;
-               uint64_t data_length;
-               void *data;
-       };
-
-private:
-       static const unsigned int ScaleStepCount = 10;
-       static const int MipMapScalePower;
-       static const int MipMapScaleFactor;
-       static const float LogMipMapScaleFactor;
-       static const uint64_t MipMapDataUnit;
-
-public:
-       typedef std::pair<int64_t, bool> EdgePair;
-
-public:
-       LogicDataSnapshot(const sr_datafeed_logic &logic);
-
-       virtual ~LogicDataSnapshot();
-
-       void append_payload(const sr_datafeed_logic &logic);
-
-private:
-       void reallocate_mip_map(MipMapLevel &m);
-
-       void append_payload_to_mipmap();
-
-       uint64_t get_sample(uint64_t index) const;
-
-public:
-       /**
-        * Parses a logic data snapshot to generate a list of transitions
-        * in a time interval to a given level of detail.
-        * @param[out] edges The vector to place the edges into.
-        * @param[in] start The start sample index.
-        * @param[in] end The end sample index.
-        * @param[in] min_length The minimum number of samples that
-        * can be resolved at this level of detail.
-        * @param[in] sig_index The index of the signal.
-        **/
-       void get_subsampled_edges(std::vector<EdgePair> &edges,
-               uint64_t start, uint64_t end,
-               float min_length, int sig_index);
-
-private:
-       uint64_t get_subsample(int level, uint64_t offset) const;
-
-       static uint64_t pow2_ceil(uint64_t x, unsigned int power);
-
-private:
-       struct MipMapLevel _mip_map[ScaleStepCount];
-       uint64_t _last_append_sample;
-
-       friend class LogicDataSnapshotTest::Pow2;
-       friend class LogicDataSnapshotTest::Basic;
-       friend class LogicDataSnapshotTest::LargeData;
-       friend class LogicDataSnapshotTest::Pulses;
-       friend class LogicDataSnapshotTest::LongPulses;
-};
-
-} // namespace pv
-
-#endif // PULSEVIEW_PV_LOGICDATASNAPSHOT_H
diff --git a/pv/signaldata.cpp b/pv/signaldata.cpp
deleted file mode 100644 (file)
index 1763b41..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include "signaldata.h"
-
-namespace pv {
-
-SignalData::SignalData(double samplerate) :
-       _samplerate(samplerate),
-       _start_time(0)
-{
-}
-
-double SignalData::get_samplerate() const
-{
-       return _samplerate;
-}
-
-double SignalData::get_start_time() const
-{
-       return _start_time;
-}
-
-} // namespace pv
diff --git a/pv/signaldata.h b/pv/signaldata.h
deleted file mode 100644 (file)
index 94268ae..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef PULSEVIEW_PV_SIGNALDATA_H
-#define PULSEVIEW_PV_SIGNALDATA_H
-
-#include <stdint.h>
-
-namespace pv {
-
-class SignalData
-{
-public:
-       SignalData(double samplerate);
-
-public:
-       double get_samplerate() const;
-       double get_start_time() const;
-
-protected:
-       const double _samplerate;
-       const double _start_time;
-};
-
-} // namespace pv
-
-#endif // PULSEVIEW_PV_SIGNALDATA_H
index b7e910e3a4839268792b9bf970033ac2d6c1c69c..03cf238ac42f11b766979a4d6068e5ac995ae10b 100644 (file)
 
 #include "sigsession.h"
 
-#include "analogdata.h"
-#include "analogdatasnapshot.h"
-#include "logicdata.h"
-#include "logicdatasnapshot.h"
+#include "data/analog.h"
+#include "data/analogsnapshot.h"
+#include "data/logic.h"
+#include "data/logicsnapshot.h"
 #include "view/analogsignal.h"
 #include "view/logicsignal.h"
 
@@ -103,7 +103,7 @@ vector< shared_ptr<view::Signal> > SigSession::get_signals()
        return _signals;
 }
 
-boost::shared_ptr<LogicData> SigSession::get_data()
+boost::shared_ptr<data::Logic> SigSession::get_data()
 {
        return _logic_data;
 }
@@ -188,8 +188,8 @@ void SigSession::feed_in_meta_logic(const struct sr_dev_inst *sdi,
                lock_guard<mutex> data_lock(_data_mutex);
                lock_guard<mutex> sampling_lock(_sampling_mutex);
 
-               // Create an empty LogicData for coming data snapshots
-               _logic_data.reset(new LogicData(meta_logic, _sample_rate));
+               // Create an empty data::Logic for coming data snapshots
+               _logic_data.reset(new data::Logic(meta_logic, _sample_rate));
                assert(_logic_data);
                if (!_logic_data)
                        return;
@@ -224,8 +224,8 @@ void SigSession::feed_in_meta_analog(const struct sr_dev_inst *sdi,
                lock_guard<mutex> data_lock(_data_mutex);
                lock_guard<mutex> sampling_lock(_sampling_mutex);
 
-               // Create an empty AnalogData for coming data snapshots
-               _analog_data.reset(new AnalogData(
+               // Create an empty data::Analog for coming data snapshots
+               _analog_data.reset(new data::Analog(
                        meta_analog, _sample_rate));
                assert(_analog_data);
                if (!_analog_data)
@@ -250,8 +250,8 @@ void SigSession::feed_in_logic(const sr_datafeed_logic &logic)
        if (!_cur_logic_snapshot)
        {
                // Create a new data snapshot
-               _cur_logic_snapshot = shared_ptr<LogicDataSnapshot>(
-                       new LogicDataSnapshot(logic));
+               _cur_logic_snapshot = shared_ptr<data::LogicSnapshot>(
+                       new data::LogicSnapshot(logic));
                _logic_data->push_snapshot(_cur_logic_snapshot);
        }
        else
@@ -269,8 +269,8 @@ void SigSession::feed_in_analog(const sr_datafeed_analog &analog)
        if (!_cur_analog_snapshot)
        {
                // Create a new data snapshot
-               _cur_analog_snapshot = shared_ptr<AnalogDataSnapshot>(
-                       new AnalogDataSnapshot(analog));
+               _cur_analog_snapshot = shared_ptr<data::AnalogSnapshot>(
+                       new data::AnalogSnapshot(analog));
                _analog_data->push_snapshot(_cur_analog_snapshot);
        }
        else
index 308b082730d13548f884b931e7bdc92cf46baf0f..d5ec200a6498a9233e47be0fc4ac1d65389b2657 100644 (file)
@@ -36,10 +36,12 @@ extern "C" {
 
 namespace pv {
 
-class AnalogData;
-class AnalogDataSnapshot;
-class LogicData;
-class LogicDataSnapshot;
+namespace data {
+class Analog;
+class AnalogSnapshot;
+class Logic;
+class LogicSnapshot;
+}
 
 namespace view {
 class Signal;
@@ -72,7 +74,7 @@ public:
        std::vector< boost::shared_ptr<view::Signal> >
                get_signals();
 
-       boost::shared_ptr<LogicData> get_data();
+       boost::shared_ptr<data::Logic> get_data();
 
 private:
        void set_capture_state(capture_state state);
@@ -108,10 +110,10 @@ private:
        std::vector< boost::shared_ptr<view::Signal> > _signals;
 
        mutable boost::mutex _data_mutex;
-       boost::shared_ptr<LogicData> _logic_data;
-       boost::shared_ptr<LogicDataSnapshot> _cur_logic_snapshot;
-       boost::shared_ptr<AnalogData> _analog_data;
-       boost::shared_ptr<AnalogDataSnapshot> _cur_analog_snapshot;
+       boost::shared_ptr<data::Logic> _logic_data;
+       boost::shared_ptr<data::LogicSnapshot> _cur_logic_snapshot;
+       boost::shared_ptr<data::Analog> _analog_data;
+       boost::shared_ptr<data::AnalogSnapshot> _cur_analog_snapshot;
 
        std::auto_ptr<boost::thread> _sampling_thread;
 
index 126ecb1f0b1330515c774f2f69fce673b3268ab4..fb5eba6103ad6ba9f3f22936d86fe831d07a5d66 100644 (file)
@@ -23,8 +23,8 @@
 #include <math.h>
 
 #include "analogsignal.h"
-#include "../analogdata.h"
-#include "../analogdatasnapshot.h"
+#include "pv/data/analog.h"
+#include "pv/data/analogsnapshot.h"
 
 using namespace boost;
 using namespace std;
@@ -32,7 +32,7 @@ using namespace std;
 namespace pv {
 namespace view {
 
-AnalogSignal::AnalogSignal(QString name, shared_ptr<AnalogData> data) :
+AnalogSignal::AnalogSignal(QString name, shared_ptr<data::Analog> data) :
        Signal(name),
        _data(data)
 {
@@ -45,12 +45,12 @@ void AnalogSignal::paint(QPainter &p, const QRect &rect, double scale,
        assert(scale > 0);
        assert(_data);
 
-       const deque< shared_ptr<pv::AnalogDataSnapshot> > &snapshots =
+       const deque< shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
                _data->get_snapshots();
        if (snapshots.empty())
                return;
 
-       const shared_ptr<pv::AnalogDataSnapshot> &snapshot =
+       const shared_ptr<pv::data::AnalogSnapshot> &snapshot =
                snapshots.front();
 
        const double pixels_offset = offset / scale;
index b3cafd2f9310cdbeac34e665294c53e22631403d..7bc0ed6eb6aaf25d9a605a22c1ab038dec3103a6 100644 (file)
@@ -27,7 +27,9 @@
 
 namespace pv {
 
-class AnalogData;
+namespace data {
+class Analog;
+}
 
 namespace view {
 
@@ -35,7 +37,7 @@ class AnalogSignal : public Signal
 {
 public:
        AnalogSignal(QString name,
-               boost::shared_ptr<pv::AnalogData> data);
+               boost::shared_ptr<pv::data::Analog> data);
 
        /**
         * Paints the signal with a QPainter
@@ -57,7 +59,7 @@ private:
        int get_nominal_offset(const QRect &rect) const;
 
 private:
-       boost::shared_ptr<pv::AnalogData> _data;
+       boost::shared_ptr<pv::data::Analog> _data;
 };
 
 } // namespace view
index 03d6aa253bd008a2381c1be3e880f36c157a01c5..d23da5bbf021815a5b668ccfb624ebfb401d9e38 100644 (file)
@@ -23,8 +23,8 @@
 #include <math.h>
 
 #include "logicsignal.h"
-#include "../logicdata.h"
-#include "../logicdatasnapshot.h"
+#include "pv/data/logic.h"
+#include "pv/data/logicsnapshot.h"
 
 using namespace boost;
 using namespace std;
@@ -51,7 +51,7 @@ const QColor LogicSignal::LogicSignalColours[10] = {
        QColor(0xEE, 0xEE, 0xEC),       // White
 };
 
-LogicSignal::LogicSignal(QString name, shared_ptr<LogicData> data,
+LogicSignal::LogicSignal(QString name, shared_ptr<data::Logic> data,
        int probe_index) :
        Signal(name),
        _probe_index(probe_index),
@@ -75,12 +75,12 @@ void LogicSignal::paint(QPainter &p, const QRect &rect, double scale,
        const float high_offset = rect.top() + 0.5f;
        const float low_offset = rect.bottom() + 0.5f;
 
-       const deque< shared_ptr<pv::LogicDataSnapshot> > &snapshots =
+       const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
                _data->get_snapshots();
        if (snapshots.empty())
                return;
 
-       const shared_ptr<pv::LogicDataSnapshot> &snapshot =
+       const shared_ptr<pv::data::LogicSnapshot> &snapshot =
                snapshots.front();
 
        const double pixels_offset = offset / scale;
@@ -102,7 +102,7 @@ void LogicSignal::paint(QPainter &p, const QRect &rect, double scale,
        QLineF *const edge_lines = new QLineF[edge_count];
        line = edge_lines;
 
-       for (vector<pv::LogicDataSnapshot::EdgePair>::const_iterator i =
+       for (vector<pv::data::LogicSnapshot::EdgePair>::const_iterator i =
                        edges.begin() + 1;
                i != edges.end() - 1; i++) {
                const float x = ((*i).first / samples_per_pixel -
@@ -135,7 +135,7 @@ void LogicSignal::paint_caps(QPainter &p, QLineF *const lines,
 {
        QLineF *line = lines;
 
-       for (vector<pv::LogicDataSnapshot::EdgePair>::const_iterator i =
+       for (vector<pv::data::LogicSnapshot::EdgePair>::const_iterator i =
                edges.begin(); i != (edges.end() - 1); i++)
                if ((*i).second == level) {
                        *line++ = QLineF(
index 4241f80138705359e7df2b4cde134bcace28ee99..e20f13c7a9fdb803a285d19c1fd19657f3476513 100644 (file)
@@ -27,7 +27,9 @@
 
 namespace pv {
 
-class LogicData;
+namespace data {
+class Logic;
+}
 
 namespace view {
 
@@ -44,7 +46,7 @@ private:
 
 public:
        LogicSignal(QString name,
-               boost::shared_ptr<pv::LogicData> data,
+               boost::shared_ptr<pv::data::Logic> data,
                int probe_index);
 
        /**
@@ -72,7 +74,7 @@ private:
 
 private:
        int _probe_index;
-       boost::shared_ptr<pv::LogicData> _data;
+       boost::shared_ptr<pv::data::Logic> _data;
 };
 
 } // namespace view
index 72d42cc2fd094098a634eea00b77a7cce606e77e..72019032e06a74e221f92c4d9ea0ddf57fa968e6 100644 (file)
@@ -32,7 +32,9 @@
 
 namespace pv {
 
+namespace data {
 class SignalData;
+}
 
 namespace view {
 
index 8fca4be28b9af9cc059d6e4df04ad47ad853f17f..64ecf83a6079ba4362496077299f26f3f0581233 100644 (file)
@@ -34,9 +34,9 @@
 #include "view.h"
 #include "viewport.h"
 
-#include "../logicdata.h"
-#include "../logicdatasnapshot.h"
-#include "../sigsession.h"
+#include "pv/sigsession.h"
+#include "pv/data/logic.h"
+#include "pv/data/logicsnapshot.h"
 
 using namespace boost;
 using namespace std;
@@ -189,7 +189,7 @@ void View::normalize_layout()
 
 void View::get_scroll_layout(double &length, double &offset) const
 {
-       const shared_ptr<SignalData> sig_data = _session.get_data();
+       const shared_ptr<data::SignalData> sig_data = _session.get_data();
        if (!sig_data)
                return;
 
@@ -319,11 +319,11 @@ void View::data_updated()
 {
        // Get the new data length
        _data_length = 0;
-       shared_ptr<LogicData> sig_data = _session.get_data();
+       shared_ptr<data::Logic> sig_data = _session.get_data();
        if (sig_data) {
-               deque< shared_ptr<LogicDataSnapshot> > &snapshots =
+               deque< shared_ptr<data::LogicSnapshot> > &snapshots =
                        sig_data->get_snapshots();
-               BOOST_FOREACH(shared_ptr<LogicDataSnapshot> s, snapshots)
+               BOOST_FOREACH(shared_ptr<data::LogicSnapshot> s, snapshots)
                        if (s)
                                _data_length = max(_data_length,
                                        s->get_sample_count());
index 6da1a2475b3908b02d1fb7db42adeaf50bb272f9..5fff12b044748cc93f52e7834329e9e5bd84b0b7 100644 (file)
@@ -21,9 +21,9 @@
 find_package(Boost 1.46 COMPONENTS unit_test_framework REQUIRED)
 
 set(pulseview_TEST_SOURCES
-       ${PROJECT_SOURCE_DIR}/pv/datasnapshot.cpp
-       ${PROJECT_SOURCE_DIR}/pv/logicdatasnapshot.cpp
-       logicdatasnapshot.cpp
+       ${PROJECT_SOURCE_DIR}/pv/data/snapshot.cpp
+       ${PROJECT_SOURCE_DIR}/pv/data/logicsnapshot.cpp
+       data/logicsnapshot.cpp
        test.cpp
 )
 
diff --git a/test/data/logicsnapshot.cpp b/test/data/logicsnapshot.cpp
new file mode 100644 (file)
index 0000000..1c53679
--- /dev/null
@@ -0,0 +1,475 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <extdef.h>
+
+#define __STDC_LIMIT_MACROS
+#include <stdint.h>
+
+#include <boost/test/unit_test.hpp>
+
+#include "../../pv/data/logicsnapshot.h"
+
+using namespace std;
+
+using pv::data::LogicSnapshot;
+
+BOOST_AUTO_TEST_SUITE(LogicSnapshotTest)
+
+void push_logic(LogicSnapshot &s, unsigned int length, uint8_t value)
+{
+       sr_datafeed_logic logic;
+       logic.unitsize = 1;
+       logic.length = length;
+       logic.data = new uint8_t[length];
+       memset(logic.data, value, length * logic.unitsize);
+       s.append_payload(logic);
+       delete[] (uint8_t*)logic.data;
+}
+
+BOOST_AUTO_TEST_CASE(Pow2)
+{
+       BOOST_CHECK_EQUAL(LogicSnapshot::pow2_ceil(0, 0), 0);
+       BOOST_CHECK_EQUAL(LogicSnapshot::pow2_ceil(1, 0), 1);
+       BOOST_CHECK_EQUAL(LogicSnapshot::pow2_ceil(2, 0), 2);
+
+       BOOST_CHECK_EQUAL(
+               LogicSnapshot::pow2_ceil(INT64_MIN, 0), INT64_MIN);
+       BOOST_CHECK_EQUAL(
+               LogicSnapshot::pow2_ceil(INT64_MAX, 0), INT64_MAX);
+
+       BOOST_CHECK_EQUAL(LogicSnapshot::pow2_ceil(0, 1), 0);
+       BOOST_CHECK_EQUAL(LogicSnapshot::pow2_ceil(1, 1), 2);
+       BOOST_CHECK_EQUAL(LogicSnapshot::pow2_ceil(2, 1), 2);
+       BOOST_CHECK_EQUAL(LogicSnapshot::pow2_ceil(3, 1), 4);
+}
+
+BOOST_AUTO_TEST_CASE(Basic)
+{
+       // Create an empty LogicSnapshot object
+       sr_datafeed_logic logic;
+       logic.length = 0;
+       logic.unitsize = 1;
+       logic.data = NULL;
+
+       LogicSnapshot s(logic);
+
+       //----- Test LogicSnapshot::push_logic -----//
+
+       BOOST_CHECK(s.get_sample_count() == 0);
+       for (unsigned int i = 0; i < LogicSnapshot::ScaleStepCount; i++)
+       {
+               const LogicSnapshot::MipMapLevel &m = s._mip_map[i];
+               BOOST_CHECK_EQUAL(m.length, 0);
+               BOOST_CHECK_EQUAL(m.data_length, 0);
+               BOOST_CHECK(m.data == NULL);
+       }
+
+       // Push 8 samples of all zeros
+       push_logic(s, 8, 0);
+
+       BOOST_CHECK(s.get_sample_count() == 8);
+
+       // There should not be enough samples to have a single mip map sample
+       for (unsigned int i = 0; i < LogicSnapshot::ScaleStepCount; i++)
+       {
+               const LogicSnapshot::MipMapLevel &m = s._mip_map[i];
+               BOOST_CHECK_EQUAL(m.length, 0);
+               BOOST_CHECK_EQUAL(m.data_length, 0);
+               BOOST_CHECK(m.data == NULL);
+       }
+
+       // Push 8 samples of 0x11s to bring the total up to 16
+       push_logic(s, 8, 0x11);
+
+       // There should now be enough data for exactly one sample
+       // in mip map level 0, and that sample should be 0
+       const LogicSnapshot::MipMapLevel &m0 = s._mip_map[0];
+       BOOST_CHECK_EQUAL(m0.length, 1);
+       BOOST_CHECK_EQUAL(m0.data_length, LogicSnapshot::MipMapDataUnit);
+       BOOST_REQUIRE(m0.data != NULL);
+       BOOST_CHECK_EQUAL(((uint8_t*)m0.data)[0], 0x11);
+
+       // The higher levels should still be empty
+       for (unsigned int i = 1; i < LogicSnapshot::ScaleStepCount; i++)
+       {
+               const LogicSnapshot::MipMapLevel &m = s._mip_map[i];
+               BOOST_CHECK_EQUAL(m.length, 0);
+               BOOST_CHECK_EQUAL(m.data_length, 0);
+               BOOST_CHECK(m.data == NULL);
+       }
+
+       // Push 240 samples of all zeros to bring the total up to 256
+       push_logic(s, 240, 0);
+
+       BOOST_CHECK_EQUAL(m0.length, 16);
+       BOOST_CHECK_EQUAL(m0.data_length, LogicSnapshot::MipMapDataUnit);
+
+       BOOST_CHECK_EQUAL(((uint8_t*)m0.data)[1], 0x11);
+       for (unsigned int i = 2; i < m0.length; i++)
+               BOOST_CHECK_EQUAL(((uint8_t*)m0.data)[i], 0);
+
+       const LogicSnapshot::MipMapLevel &m1 = s._mip_map[1];
+       BOOST_CHECK_EQUAL(m1.length, 1);
+       BOOST_CHECK_EQUAL(m1.data_length, LogicSnapshot::MipMapDataUnit);
+       BOOST_REQUIRE(m1.data != NULL);
+       BOOST_CHECK_EQUAL(((uint8_t*)m1.data)[0], 0x11);
+
+       //----- Test LogicSnapshot::get_subsampled_edges -----//
+
+       // Test a full view at full zoom.
+       vector<LogicSnapshot::EdgePair> edges;
+       s.get_subsampled_edges(edges, 0, 255, 1, 0);
+       BOOST_REQUIRE_EQUAL(edges.size(), 4);
+
+       BOOST_CHECK_EQUAL(edges[0].first, 0);
+       BOOST_CHECK_EQUAL(edges[1].first, 8);
+       BOOST_CHECK_EQUAL(edges[2].first, 16);
+       BOOST_CHECK_EQUAL(edges[3].first, 255);
+
+       // Test a subset at high zoom
+       edges.clear();
+       s.get_subsampled_edges(edges, 6, 17, 0.05f, 0);
+       BOOST_REQUIRE_EQUAL(edges.size(), 4);
+
+       BOOST_CHECK_EQUAL(edges[0].first, 6);
+       BOOST_CHECK_EQUAL(edges[1].first, 8);
+       BOOST_CHECK_EQUAL(edges[2].first, 16);
+       BOOST_CHECK_EQUAL(edges[3].first, 17);
+}
+
+BOOST_AUTO_TEST_CASE(LargeData)
+{
+       uint8_t prev_sample;
+       const unsigned int Length = 1000000;
+
+       sr_datafeed_logic logic;
+       logic.unitsize = 1;
+       logic.length = Length;
+       logic.data = new uint8_t[Length];
+       uint8_t *data = (uint8_t*)logic.data;
+
+       for (unsigned int i = 0; i < Length; i++)
+               *data++ = (uint8_t)(i >> 8);
+
+       LogicSnapshot s(logic);
+       delete[] (uint8_t*)logic.data;
+
+       BOOST_CHECK(s.get_sample_count() == Length);
+
+       // Check mip map level 0
+       BOOST_CHECK_EQUAL(s._mip_map[0].length, 62500);
+       BOOST_CHECK_EQUAL(s._mip_map[0].data_length,
+               LogicSnapshot::MipMapDataUnit);
+       BOOST_REQUIRE(s._mip_map[0].data != NULL);
+
+       prev_sample = 0;
+       for (unsigned int i = 0; i < s._mip_map[0].length;)
+       {
+               BOOST_TEST_MESSAGE("Testing mip_map[0].data[" << i << "]");
+
+               const uint8_t sample = (uint8_t)((i*16) >> 8);
+               BOOST_CHECK_EQUAL(s.get_subsample(0, i++) & 0xFF,
+                       prev_sample ^ sample);
+               prev_sample = sample;
+
+               for (int j = 1; i < s._mip_map[0].length && j < 16; j++)
+               {
+                       BOOST_TEST_MESSAGE("Testing mip_map[0].data[" << i << "]");
+                       BOOST_CHECK_EQUAL(s.get_subsample(0, i++) & 0xFF, 0);
+               }
+       }
+
+       // Check mip map level 1
+       BOOST_CHECK_EQUAL(s._mip_map[1].length, 3906);
+       BOOST_CHECK_EQUAL(s._mip_map[1].data_length,
+               LogicSnapshot::MipMapDataUnit);
+       BOOST_REQUIRE(s._mip_map[1].data != NULL);
+
+       prev_sample = 0;
+       for (unsigned int i = 0; i < s._mip_map[1].length; i++)
+       {
+               BOOST_TEST_MESSAGE("Testing mip_map[1].data[" << i << "]");
+
+               const uint8_t sample = i;
+               const uint8_t expected = sample ^ prev_sample;
+               prev_sample = i;
+
+               BOOST_CHECK_EQUAL(s.get_subsample(1, i) & 0xFF, expected);
+       }
+
+       // Check mip map level 2
+       BOOST_CHECK_EQUAL(s._mip_map[2].length, 244);
+       BOOST_CHECK_EQUAL(s._mip_map[2].data_length,
+               LogicSnapshot::MipMapDataUnit);
+       BOOST_REQUIRE(s._mip_map[2].data != NULL);
+
+       prev_sample = 0;
+       for (unsigned int i = 0; i < s._mip_map[2].length; i++)
+       {
+               BOOST_TEST_MESSAGE("Testing mip_map[2].data[" << i << "]");
+
+               const uint8_t sample = i << 4;
+               const uint8_t expected = (sample ^ prev_sample) | 0x0F;
+               prev_sample = sample;
+
+               BOOST_CHECK_EQUAL(s.get_subsample(2, i) & 0xFF, expected);
+       }
+
+       // Check mip map level 3
+       BOOST_CHECK_EQUAL(s._mip_map[3].length, 15);
+       BOOST_CHECK_EQUAL(s._mip_map[3].data_length,
+               LogicSnapshot::MipMapDataUnit);
+       BOOST_REQUIRE(s._mip_map[3].data != NULL);
+
+       for (unsigned int i = 0; i < s._mip_map[3].length; i++)
+               BOOST_CHECK_EQUAL(*((uint8_t*)s._mip_map[3].data + i),
+                       0xFF);
+
+       // Check the higher levels
+       for (unsigned int i = 4; i < LogicSnapshot::ScaleStepCount; i++)
+       {
+               const LogicSnapshot::MipMapLevel &m = s._mip_map[i];
+               BOOST_CHECK_EQUAL(m.length, 0);
+               BOOST_CHECK_EQUAL(m.data_length, 0);
+               BOOST_CHECK(m.data == NULL);
+       }
+
+       //----- Test LogicSnapshot::get_subsampled_edges -----//
+       // Check in normal case
+       vector<LogicSnapshot::EdgePair> edges;
+       s.get_subsampled_edges(edges, 0, Length-1, 1, 7);
+
+       BOOST_CHECK_EQUAL(edges.size(), 32);
+
+       for (unsigned int i = 0; i < edges.size() - 1; i++)
+       {
+               BOOST_CHECK_EQUAL(edges[i].first, i * 32768);
+               BOOST_CHECK_EQUAL(edges[i].second, i & 1);
+       }
+
+       BOOST_CHECK_EQUAL(edges[31].first, 999999);
+
+       // Check in very low zoom case
+       edges.clear();
+       s.get_subsampled_edges(edges, 0, Length-1, 50e6f, 7);
+
+       BOOST_CHECK_EQUAL(edges.size(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(Pulses)
+{
+       const int Cycles = 3;
+       const int Period = 64;
+       const int Length = Cycles * Period;
+
+       vector<LogicSnapshot::EdgePair> edges;
+
+       //----- Create a LogicSnapshot -----//
+       sr_datafeed_logic logic;
+       logic.unitsize = 1;
+       logic.length = Length;
+       logic.data = (uint64_t*)new uint8_t[Length];
+       uint8_t *p = (uint8_t*)logic.data;
+
+       for (int i = 0; i < Cycles; i++) {
+               *p++ = 0xFF;
+               for (int j = 1; j < Period; j++)
+                       *p++ = 0x00;
+       }
+
+       LogicSnapshot s(logic);
+       delete[] (uint8_t*)logic.data;
+
+       //----- Check the mip-map -----//
+       // Check mip map level 0
+       BOOST_CHECK_EQUAL(s._mip_map[0].length, 12);
+       BOOST_CHECK_EQUAL(s._mip_map[0].data_length,
+               LogicSnapshot::MipMapDataUnit);
+       BOOST_REQUIRE(s._mip_map[0].data != NULL);
+
+       for (unsigned int i = 0; i < s._mip_map[0].length;) {
+               BOOST_TEST_MESSAGE("Testing mip_map[0].data[" << i << "]");
+               BOOST_CHECK_EQUAL(s.get_subsample(0, i++) & 0xFF, 0xFF);
+
+               for (int j = 1;
+                       i < s._mip_map[0].length &&
+                       j < Period/LogicSnapshot::MipMapScaleFactor; j++) {
+                       BOOST_TEST_MESSAGE(
+                               "Testing mip_map[0].data[" << i << "]");
+                       BOOST_CHECK_EQUAL(s.get_subsample(0, i++) & 0xFF, 0x00);
+               }
+       }
+
+       // Check the higher levels are all inactive
+       for (unsigned int i = 1; i < LogicSnapshot::ScaleStepCount; i++) {
+               const LogicSnapshot::MipMapLevel &m = s._mip_map[i];
+               BOOST_CHECK_EQUAL(m.length, 0);
+               BOOST_CHECK_EQUAL(m.data_length, 0);
+               BOOST_CHECK(m.data == NULL);
+       }
+
+       //----- Test get_subsampled_edges at reduced scale -----//
+       s.get_subsampled_edges(edges, 0, Length-1, 16.0f, 2);
+       BOOST_REQUIRE_EQUAL(edges.size(), Cycles + 2);
+
+       BOOST_CHECK_EQUAL(0, false);
+       for (unsigned int i = 1; i < edges.size(); i++)
+               BOOST_CHECK_EQUAL(edges[i].second, false);
+}
+
+BOOST_AUTO_TEST_CASE(LongPulses)
+{
+       const int Cycles = 3;
+       const int Period = 64;
+       const int PulseWidth = 16;
+       const int Length = Cycles * Period;
+
+       int j;
+       vector<LogicSnapshot::EdgePair> edges;
+
+       //----- Create a LogicSnapshot -----//
+       sr_datafeed_logic logic;
+       logic.unitsize = 8;
+       logic.length = Length;
+       logic.data = (uint64_t*)new uint64_t[Length];
+       uint64_t *p = (uint64_t*)logic.data;
+
+       for (int i = 0; i < Cycles; i++) {
+               for (j = 0; j < PulseWidth; j++)
+                       *p++ = ~0;
+               for (; j < Period; j++)
+                       *p++ = 0;
+       }
+
+       LogicSnapshot s(logic);
+       delete[] (uint64_t*)logic.data;
+
+       //----- Check the mip-map -----//
+       // Check mip map level 0
+       BOOST_CHECK_EQUAL(s._mip_map[0].length, 12);
+       BOOST_CHECK_EQUAL(s._mip_map[0].data_length,
+               LogicSnapshot::MipMapDataUnit);
+       BOOST_REQUIRE(s._mip_map[0].data != NULL);
+
+       for (unsigned int i = 0; i < s._mip_map[0].length;) {
+               for (j = 0; i < s._mip_map[0].length && j < 2; j++) {
+                       BOOST_TEST_MESSAGE(
+                               "Testing mip_map[0].data[" << i << "]");
+                       BOOST_CHECK_EQUAL(s.get_subsample(0, i++), ~0);
+               }
+
+               for (; i < s._mip_map[0].length &&
+                       j < Period/LogicSnapshot::MipMapScaleFactor; j++) {
+                       BOOST_TEST_MESSAGE(
+                               "Testing mip_map[0].data[" << i << "]");
+                       BOOST_CHECK_EQUAL(s.get_subsample(0, i++), 0);
+               }
+       }
+
+       // Check the higher levels are all inactive
+       for (unsigned int i = 1; i < LogicSnapshot::ScaleStepCount; i++) {
+               const LogicSnapshot::MipMapLevel &m = s._mip_map[i];
+               BOOST_CHECK_EQUAL(m.length, 0);
+               BOOST_CHECK_EQUAL(m.data_length, 0);
+               BOOST_CHECK(m.data == NULL);
+       }
+
+       //----- Test get_subsampled_edges at a full scale -----//
+       s.get_subsampled_edges(edges, 0, Length-1, 16.0f, 2);
+       BOOST_REQUIRE_EQUAL(edges.size(), Cycles * 2 + 1);
+
+       for (int i = 0; i < Cycles; i++) {
+               BOOST_CHECK_EQUAL(edges[i*2].first, i * Period);
+               BOOST_CHECK_EQUAL(edges[i*2].second, true);
+               BOOST_CHECK_EQUAL(edges[i*2+1].first, i * Period + PulseWidth);
+               BOOST_CHECK_EQUAL(edges[i*2+1].second, false);
+       }
+
+       BOOST_CHECK_EQUAL(edges.back().first, Length-1);
+       BOOST_CHECK_EQUAL(edges.back().second, false);
+
+       //----- Test get_subsampled_edges at a simplified scale -----//
+       edges.clear();
+       s.get_subsampled_edges(edges, 0, Length-1, 17.0f, 2);
+
+       BOOST_CHECK_EQUAL(edges[0].first, 0);
+       BOOST_CHECK_EQUAL(edges[0].second, true);
+       BOOST_CHECK_EQUAL(edges[1].first, 16);
+       BOOST_CHECK_EQUAL(edges[1].second, false);
+       
+       for (int i = 1; i < Cycles; i++) {
+               BOOST_CHECK_EQUAL(edges[i+1].first, i * Period);
+               BOOST_CHECK_EQUAL(edges[i+1].second, false);
+       }
+
+       BOOST_CHECK_EQUAL(edges.back().first, Length-1);
+       BOOST_CHECK_EQUAL(edges.back().second, false);
+}
+
+BOOST_AUTO_TEST_CASE(LisaMUsbHid)
+{
+       /* This test was created from the beginning of the USB_DM signal in
+        * sigrok-dumps-usb/lisa_m_usbhid/lisa_m_usbhid.sr
+        */
+
+       const int Edges[] = {
+               7028, 7033, 7036, 7041, 7044, 7049, 7053, 7066, 7073, 7079,
+               7086, 7095, 7103, 7108, 7111, 7116, 7119, 7124, 7136, 7141,
+               7148, 7162, 7500
+       };
+       const int Length = Edges[countof(Edges) - 1];
+
+       bool state = false;
+       int lastEdgePos = 0;
+
+       //----- Create a LogicSnapshot -----//
+       sr_datafeed_logic logic;
+       logic.unitsize = 1;
+       logic.length = Length;
+       logic.data = new uint8_t[Length];
+       uint8_t *data = (uint8_t*)logic.data;
+
+       for (unsigned int i = 0; i < countof(Edges); i++) {
+               const int edgePos = Edges[i];
+               memset(&data[lastEdgePos], state ? 0x02 : 0,
+                       edgePos - lastEdgePos - 1);
+
+               lastEdgePos = edgePos;
+               state = !state;
+       }
+
+       LogicSnapshot s(logic);
+       delete[] (uint64_t*)logic.data;
+
+       vector<LogicSnapshot::EdgePair> edges;
+
+
+       /* The trailing edge of the pulse train is falling in the source data.
+        * Check this is always true at different scales
+        */
+
+       edges.clear();
+       s.get_subsampled_edges(edges, 0, Length-1, 33.333332f, 1);
+       BOOST_CHECK_EQUAL(edges[edges.size() - 2].second, false);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/logicdatasnapshot.cpp b/test/logicdatasnapshot.cpp
deleted file mode 100644 (file)
index 07d34f2..0000000
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include <extdef.h>
-
-#define __STDC_LIMIT_MACROS
-#include <stdint.h>
-
-#include <boost/test/unit_test.hpp>
-
-#include "../pv/logicdatasnapshot.h"
-
-using namespace std;
-
-using pv::LogicDataSnapshot;
-
-BOOST_AUTO_TEST_SUITE(LogicDataSnapshotTest)
-
-void push_logic(LogicDataSnapshot &s, unsigned int length, uint8_t value)
-{
-       sr_datafeed_logic logic;
-       logic.unitsize = 1;
-       logic.length = length;
-       logic.data = new uint8_t[length];
-       memset(logic.data, value, length * logic.unitsize);
-       s.append_payload(logic);
-       delete[] (uint8_t*)logic.data;
-}
-
-BOOST_AUTO_TEST_CASE(Pow2)
-{
-       BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(0, 0), 0);
-       BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(1, 0), 1);
-       BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(2, 0), 2);
-
-       BOOST_CHECK_EQUAL(
-               LogicDataSnapshot::pow2_ceil(INT64_MIN, 0), INT64_MIN);
-       BOOST_CHECK_EQUAL(
-               LogicDataSnapshot::pow2_ceil(INT64_MAX, 0), INT64_MAX);
-
-       BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(0, 1), 0);
-       BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(1, 1), 2);
-       BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(2, 1), 2);
-       BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(3, 1), 4);
-}
-
-BOOST_AUTO_TEST_CASE(Basic)
-{
-       // Create an empty LogicDataSnapshot object
-       sr_datafeed_logic logic;
-       logic.length = 0;
-       logic.unitsize = 1;
-       logic.data = NULL;
-
-       LogicDataSnapshot s(logic);
-
-       //----- Test LogicDataSnapshot::push_logic -----//
-
-       BOOST_CHECK(s.get_sample_count() == 0);
-       for (unsigned int i = 0; i < LogicDataSnapshot::ScaleStepCount; i++)
-       {
-               const LogicDataSnapshot::MipMapLevel &m = s._mip_map[i];
-               BOOST_CHECK_EQUAL(m.length, 0);
-               BOOST_CHECK_EQUAL(m.data_length, 0);
-               BOOST_CHECK(m.data == NULL);
-       }
-
-       // Push 8 samples of all zeros
-       push_logic(s, 8, 0);
-
-       BOOST_CHECK(s.get_sample_count() == 8);
-
-       // There should not be enough samples to have a single mip map sample
-       for (unsigned int i = 0; i < LogicDataSnapshot::ScaleStepCount; i++)
-       {
-               const LogicDataSnapshot::MipMapLevel &m = s._mip_map[i];
-               BOOST_CHECK_EQUAL(m.length, 0);
-               BOOST_CHECK_EQUAL(m.data_length, 0);
-               BOOST_CHECK(m.data == NULL);
-       }
-
-       // Push 8 samples of 0x11s to bring the total up to 16
-       push_logic(s, 8, 0x11);
-
-       // There should now be enough data for exactly one sample
-       // in mip map level 0, and that sample should be 0
-       const LogicDataSnapshot::MipMapLevel &m0 = s._mip_map[0];
-       BOOST_CHECK_EQUAL(m0.length, 1);
-       BOOST_CHECK_EQUAL(m0.data_length, LogicDataSnapshot::MipMapDataUnit);
-       BOOST_REQUIRE(m0.data != NULL);
-       BOOST_CHECK_EQUAL(((uint8_t*)m0.data)[0], 0x11);
-
-       // The higher levels should still be empty
-       for (unsigned int i = 1; i < LogicDataSnapshot::ScaleStepCount; i++)
-       {
-               const LogicDataSnapshot::MipMapLevel &m = s._mip_map[i];
-               BOOST_CHECK_EQUAL(m.length, 0);
-               BOOST_CHECK_EQUAL(m.data_length, 0);
-               BOOST_CHECK(m.data == NULL);
-       }
-
-       // Push 240 samples of all zeros to bring the total up to 256
-       push_logic(s, 240, 0);
-
-       BOOST_CHECK_EQUAL(m0.length, 16);
-       BOOST_CHECK_EQUAL(m0.data_length, LogicDataSnapshot::MipMapDataUnit);
-
-       BOOST_CHECK_EQUAL(((uint8_t*)m0.data)[1], 0x11);
-       for (unsigned int i = 2; i < m0.length; i++)
-               BOOST_CHECK_EQUAL(((uint8_t*)m0.data)[i], 0);
-
-       const LogicDataSnapshot::MipMapLevel &m1 = s._mip_map[1];
-       BOOST_CHECK_EQUAL(m1.length, 1);
-       BOOST_CHECK_EQUAL(m1.data_length, LogicDataSnapshot::MipMapDataUnit);
-       BOOST_REQUIRE(m1.data != NULL);
-       BOOST_CHECK_EQUAL(((uint8_t*)m1.data)[0], 0x11);
-
-       //----- Test LogicDataSnapshot::get_subsampled_edges -----//
-
-       // Test a full view at full zoom.
-       vector<LogicDataSnapshot::EdgePair> edges;
-       s.get_subsampled_edges(edges, 0, 255, 1, 0);
-       BOOST_REQUIRE_EQUAL(edges.size(), 4);
-
-       BOOST_CHECK_EQUAL(edges[0].first, 0);
-       BOOST_CHECK_EQUAL(edges[1].first, 8);
-       BOOST_CHECK_EQUAL(edges[2].first, 16);
-       BOOST_CHECK_EQUAL(edges[3].first, 255);
-
-       // Test a subset at high zoom
-       edges.clear();
-       s.get_subsampled_edges(edges, 6, 17, 0.05f, 0);
-       BOOST_REQUIRE_EQUAL(edges.size(), 4);
-
-       BOOST_CHECK_EQUAL(edges[0].first, 6);
-       BOOST_CHECK_EQUAL(edges[1].first, 8);
-       BOOST_CHECK_EQUAL(edges[2].first, 16);
-       BOOST_CHECK_EQUAL(edges[3].first, 17);
-}
-
-BOOST_AUTO_TEST_CASE(LargeData)
-{
-       uint8_t prev_sample;
-       const unsigned int Length = 1000000;
-
-       sr_datafeed_logic logic;
-       logic.unitsize = 1;
-       logic.length = Length;
-       logic.data = new uint8_t[Length];
-       uint8_t *data = (uint8_t*)logic.data;
-
-       for (unsigned int i = 0; i < Length; i++)
-               *data++ = (uint8_t)(i >> 8);
-
-       LogicDataSnapshot s(logic);
-       delete[] (uint8_t*)logic.data;
-
-       BOOST_CHECK(s.get_sample_count() == Length);
-
-       // Check mip map level 0
-       BOOST_CHECK_EQUAL(s._mip_map[0].length, 62500);
-       BOOST_CHECK_EQUAL(s._mip_map[0].data_length,
-               LogicDataSnapshot::MipMapDataUnit);
-       BOOST_REQUIRE(s._mip_map[0].data != NULL);
-
-       prev_sample = 0;
-       for (unsigned int i = 0; i < s._mip_map[0].length;)
-       {
-               BOOST_TEST_MESSAGE("Testing mip_map[0].data[" << i << "]");
-
-               const uint8_t sample = (uint8_t)((i*16) >> 8);
-               BOOST_CHECK_EQUAL(s.get_subsample(0, i++) & 0xFF,
-                       prev_sample ^ sample);
-               prev_sample = sample;
-
-               for (int j = 1; i < s._mip_map[0].length && j < 16; j++)
-               {
-                       BOOST_TEST_MESSAGE("Testing mip_map[0].data[" << i << "]");
-                       BOOST_CHECK_EQUAL(s.get_subsample(0, i++) & 0xFF, 0);
-               }
-       }
-
-       // Check mip map level 1
-       BOOST_CHECK_EQUAL(s._mip_map[1].length, 3906);
-       BOOST_CHECK_EQUAL(s._mip_map[1].data_length,
-               LogicDataSnapshot::MipMapDataUnit);
-       BOOST_REQUIRE(s._mip_map[1].data != NULL);
-
-       prev_sample = 0;
-       for (unsigned int i = 0; i < s._mip_map[1].length; i++)
-       {
-               BOOST_TEST_MESSAGE("Testing mip_map[1].data[" << i << "]");
-
-               const uint8_t sample = i;
-               const uint8_t expected = sample ^ prev_sample;
-               prev_sample = i;
-
-               BOOST_CHECK_EQUAL(s.get_subsample(1, i) & 0xFF, expected);
-       }
-
-       // Check mip map level 2
-       BOOST_CHECK_EQUAL(s._mip_map[2].length, 244);
-       BOOST_CHECK_EQUAL(s._mip_map[2].data_length,
-               LogicDataSnapshot::MipMapDataUnit);
-       BOOST_REQUIRE(s._mip_map[2].data != NULL);
-
-       prev_sample = 0;
-       for (unsigned int i = 0; i < s._mip_map[2].length; i++)
-       {
-               BOOST_TEST_MESSAGE("Testing mip_map[2].data[" << i << "]");
-
-               const uint8_t sample = i << 4;
-               const uint8_t expected = (sample ^ prev_sample) | 0x0F;
-               prev_sample = sample;
-
-               BOOST_CHECK_EQUAL(s.get_subsample(2, i) & 0xFF, expected);
-       }
-
-       // Check mip map level 3
-       BOOST_CHECK_EQUAL(s._mip_map[3].length, 15);
-       BOOST_CHECK_EQUAL(s._mip_map[3].data_length,
-               LogicDataSnapshot::MipMapDataUnit);
-       BOOST_REQUIRE(s._mip_map[3].data != NULL);
-
-       for (unsigned int i = 0; i < s._mip_map[3].length; i++)
-               BOOST_CHECK_EQUAL(*((uint8_t*)s._mip_map[3].data + i),
-                       0xFF);
-
-       // Check the higher levels
-       for (unsigned int i = 4; i < LogicDataSnapshot::ScaleStepCount; i++)
-       {
-               const LogicDataSnapshot::MipMapLevel &m = s._mip_map[i];
-               BOOST_CHECK_EQUAL(m.length, 0);
-               BOOST_CHECK_EQUAL(m.data_length, 0);
-               BOOST_CHECK(m.data == NULL);
-       }
-
-       //----- Test LogicDataSnapshot::get_subsampled_edges -----//
-       // Check in normal case
-       vector<LogicDataSnapshot::EdgePair> edges;
-       s.get_subsampled_edges(edges, 0, Length-1, 1, 7);
-
-       BOOST_CHECK_EQUAL(edges.size(), 32);
-
-       for (unsigned int i = 0; i < edges.size() - 1; i++)
-       {
-               BOOST_CHECK_EQUAL(edges[i].first, i * 32768);
-               BOOST_CHECK_EQUAL(edges[i].second, i & 1);
-       }
-
-       BOOST_CHECK_EQUAL(edges[31].first, 999999);
-
-       // Check in very low zoom case
-       edges.clear();
-       s.get_subsampled_edges(edges, 0, Length-1, 50e6f, 7);
-
-       BOOST_CHECK_EQUAL(edges.size(), 2);
-}
-
-BOOST_AUTO_TEST_CASE(Pulses)
-{
-       const int Cycles = 3;
-       const int Period = 64;
-       const int Length = Cycles * Period;
-
-       vector<LogicDataSnapshot::EdgePair> edges;
-
-       //----- Create a LogicDataSnapshot -----//
-       sr_datafeed_logic logic;
-       logic.unitsize = 1;
-       logic.length = Length;
-       logic.data = (uint64_t*)new uint8_t[Length];
-       uint8_t *p = (uint8_t*)logic.data;
-
-       for (int i = 0; i < Cycles; i++) {
-               *p++ = 0xFF;
-               for (int j = 1; j < Period; j++)
-                       *p++ = 0x00;
-       }
-
-       LogicDataSnapshot s(logic);
-       delete[] (uint8_t*)logic.data;
-
-       //----- Check the mip-map -----//
-       // Check mip map level 0
-       BOOST_CHECK_EQUAL(s._mip_map[0].length, 12);
-       BOOST_CHECK_EQUAL(s._mip_map[0].data_length,
-               LogicDataSnapshot::MipMapDataUnit);
-       BOOST_REQUIRE(s._mip_map[0].data != NULL);
-
-       for (unsigned int i = 0; i < s._mip_map[0].length;) {
-               BOOST_TEST_MESSAGE("Testing mip_map[0].data[" << i << "]");
-               BOOST_CHECK_EQUAL(s.get_subsample(0, i++) & 0xFF, 0xFF);
-
-               for (int j = 1;
-                       i < s._mip_map[0].length &&
-                       j < Period/LogicDataSnapshot::MipMapScaleFactor; j++) {
-                       BOOST_TEST_MESSAGE(
-                               "Testing mip_map[0].data[" << i << "]");
-                       BOOST_CHECK_EQUAL(s.get_subsample(0, i++) & 0xFF, 0x00);
-               }
-       }
-
-       // Check the higher levels are all inactive
-       for (unsigned int i = 1; i < LogicDataSnapshot::ScaleStepCount; i++) {
-               const LogicDataSnapshot::MipMapLevel &m = s._mip_map[i];
-               BOOST_CHECK_EQUAL(m.length, 0);
-               BOOST_CHECK_EQUAL(m.data_length, 0);
-               BOOST_CHECK(m.data == NULL);
-       }
-
-       //----- Test get_subsampled_edges at reduced scale -----//
-       s.get_subsampled_edges(edges, 0, Length-1, 16.0f, 2);
-       BOOST_REQUIRE_EQUAL(edges.size(), Cycles + 2);
-
-       BOOST_CHECK_EQUAL(0, false);
-       for (unsigned int i = 1; i < edges.size(); i++)
-               BOOST_CHECK_EQUAL(edges[i].second, false);
-}
-
-BOOST_AUTO_TEST_CASE(LongPulses)
-{
-       const int Cycles = 3;
-       const int Period = 64;
-       const int PulseWidth = 16;
-       const int Length = Cycles * Period;
-
-       int j;
-       vector<LogicDataSnapshot::EdgePair> edges;
-
-       //----- Create a LogicDataSnapshot -----//
-       sr_datafeed_logic logic;
-       logic.unitsize = 8;
-       logic.length = Length;
-       logic.data = (uint64_t*)new uint64_t[Length];
-       uint64_t *p = (uint64_t*)logic.data;
-
-       for (int i = 0; i < Cycles; i++) {
-               for (j = 0; j < PulseWidth; j++)
-                       *p++ = ~0;
-               for (; j < Period; j++)
-                       *p++ = 0;
-       }
-
-       LogicDataSnapshot s(logic);
-       delete[] (uint64_t*)logic.data;
-
-       //----- Check the mip-map -----//
-       // Check mip map level 0
-       BOOST_CHECK_EQUAL(s._mip_map[0].length, 12);
-       BOOST_CHECK_EQUAL(s._mip_map[0].data_length,
-               LogicDataSnapshot::MipMapDataUnit);
-       BOOST_REQUIRE(s._mip_map[0].data != NULL);
-
-       for (unsigned int i = 0; i < s._mip_map[0].length;) {
-               for (j = 0; i < s._mip_map[0].length && j < 2; j++) {
-                       BOOST_TEST_MESSAGE(
-                               "Testing mip_map[0].data[" << i << "]");
-                       BOOST_CHECK_EQUAL(s.get_subsample(0, i++), ~0);
-               }
-
-               for (; i < s._mip_map[0].length &&
-                       j < Period/LogicDataSnapshot::MipMapScaleFactor; j++) {
-                       BOOST_TEST_MESSAGE(
-                               "Testing mip_map[0].data[" << i << "]");
-                       BOOST_CHECK_EQUAL(s.get_subsample(0, i++), 0);
-               }
-       }
-
-       // Check the higher levels are all inactive
-       for (unsigned int i = 1; i < LogicDataSnapshot::ScaleStepCount; i++) {
-               const LogicDataSnapshot::MipMapLevel &m = s._mip_map[i];
-               BOOST_CHECK_EQUAL(m.length, 0);
-               BOOST_CHECK_EQUAL(m.data_length, 0);
-               BOOST_CHECK(m.data == NULL);
-       }
-
-       //----- Test get_subsampled_edges at a full scale -----//
-       s.get_subsampled_edges(edges, 0, Length-1, 16.0f, 2);
-       BOOST_REQUIRE_EQUAL(edges.size(), Cycles * 2 + 1);
-
-       for (int i = 0; i < Cycles; i++) {
-               BOOST_CHECK_EQUAL(edges[i*2].first, i * Period);
-               BOOST_CHECK_EQUAL(edges[i*2].second, true);
-               BOOST_CHECK_EQUAL(edges[i*2+1].first, i * Period + PulseWidth);
-               BOOST_CHECK_EQUAL(edges[i*2+1].second, false);
-       }
-
-       BOOST_CHECK_EQUAL(edges.back().first, Length-1);
-       BOOST_CHECK_EQUAL(edges.back().second, false);
-
-       //----- Test get_subsampled_edges at a simplified scale -----//
-       edges.clear();
-       s.get_subsampled_edges(edges, 0, Length-1, 17.0f, 2);
-
-       BOOST_CHECK_EQUAL(edges[0].first, 0);
-       BOOST_CHECK_EQUAL(edges[0].second, true);
-       BOOST_CHECK_EQUAL(edges[1].first, 16);
-       BOOST_CHECK_EQUAL(edges[1].second, false);
-       
-       for (int i = 1; i < Cycles; i++) {
-               BOOST_CHECK_EQUAL(edges[i+1].first, i * Period);
-               BOOST_CHECK_EQUAL(edges[i+1].second, false);
-       }
-
-       BOOST_CHECK_EQUAL(edges.back().first, Length-1);
-       BOOST_CHECK_EQUAL(edges.back().second, false);
-}
-
-BOOST_AUTO_TEST_CASE(LisaMUsbHid)
-{
-       /* This test was created from the beginning of the USB_DM signal in
-        * sigrok-dumps-usb/lisa_m_usbhid/lisa_m_usbhid.sr
-        */
-
-       const int Edges[] = {
-               7028, 7033, 7036, 7041, 7044, 7049, 7053, 7066, 7073, 7079,
-               7086, 7095, 7103, 7108, 7111, 7116, 7119, 7124, 7136, 7141,
-               7148, 7162, 7500
-       };
-       const int Length = Edges[countof(Edges) - 1];
-
-       bool state = false;
-       int lastEdgePos = 0;
-
-       //----- Create a LogicDataSnapshot -----//
-       sr_datafeed_logic logic;
-       logic.unitsize = 1;
-       logic.length = Length;
-       logic.data = new uint8_t[Length];
-       uint8_t *data = (uint8_t*)logic.data;
-
-       for (unsigned int i = 0; i < countof(Edges); i++) {
-               const int edgePos = Edges[i];
-               memset(&data[lastEdgePos], state ? 0x02 : 0,
-                       edgePos - lastEdgePos - 1);
-
-               lastEdgePos = edgePos;
-               state = !state;
-       }
-
-       LogicDataSnapshot s(logic);
-       delete[] (uint64_t*)logic.data;
-
-       vector<LogicDataSnapshot::EdgePair> edges;
-
-
-       /* The trailing edge of the pulse train is falling in the source data.
-        * Check this is always true at different scales
-        */
-
-       edges.clear();
-       s.get_subsampled_edges(edges, 0, Length-1, 33.333332f, 1);
-       BOOST_CHECK_EQUAL(edges[edges.size() - 2].second, false);
-}
-
-
-BOOST_AUTO_TEST_SUITE_END()