42#include "KahanSummation.h"
137 const std::string&
color,
139 Unit xunit = Unit::UNIT_FS);
144 {
return m_filters; }
148 {
return m_filters.size(); }
158 m_filters.erase(
this);
165 const std::string& name,
175 {
AddStream(
Unit(Unit::UNIT_COUNTS), name, Stream::STREAM_TYPE_PROTOCOL); }
183 {
AddStream(
Unit(Unit::UNIT_COUNTS), name, Stream::STREAM_TYPE_DIGITAL); }
209 virtual void AddRef()
override;
210 virtual void Release()
override;
237 virtual float GetVoltageRange(
size_t stream)
override;
238 virtual void SetVoltageRange(
float range,
size_t stream)
override;
240 virtual float GetOffset(
size_t stream)
override;
241 virtual void SetOffset(
float offset,
size_t stream)
override;
361 cap->m_startTimestamp =
din->m_startTimestamp;
362 cap->m_startFemtoseconds =
din->m_startFemtoseconds;
363 cap->m_triggerPhase =
din->m_triggerPhase;
364 cap->m_timescale =
din->m_timescale;
391 static float InterpolateTime(
T*
cap,
size_t a,
float voltage)
393 AssertTypeIsAnalogWaveform(
cap);
396 float fa =
cap->m_samples[a];
397 float fb =
cap->m_samples[a+1];
398 bool ag = (fa > voltage);
399 bool bg = (fb > voltage);
400 if( (ag && bg) || (!ag && !bg) )
404 float slope = (fb - fa);
405 float delta = voltage - fa;
406 return delta / slope;
412 return InterpolateTime(
s, a, voltage);
414 return InterpolateTime(
u, a, voltage);
420 static float InterpolateTime(
425 size_t a,
float voltage)
428 return InterpolateTime(
sp,
sn, a, voltage);
430 return InterpolateTime(
up,
un, a, voltage);
446 AssertTypeIsAnalogWaveform(
cap);
450 for(
float f :
cap->m_samples)
465 vk::raii::CommandBuffer& cmdBuf,
466 std::shared_ptr<QueueHandle> queue,
475 AssertTypeIsAnalogWaveform(
cap);
492 scratchMin.PrepareForCpuAccessNonblocking(cmdBuf);
493 scratchMax.PrepareForCpuAccessNonblocking(cmdBuf);
496 queue->SubmitAndBlock(cmdBuf);
515 AssertTypeIsAnalogWaveform(
cap);
519 for(
float f :
cap->m_samples)
545 AssertTypeIsAnalogWaveform(
cap);
549 for(
float f :
cap->m_samples)
585 vk::raii::CommandBuffer& cmdBuf,
586 std::shared_ptr<QueueHandle> queue,
627 LogError(
"Filter::GetBaseAndTopVoltage called with both waveforms null\n");
639 vk::raii::CommandBuffer& cmdBuf,
640 std::shared_ptr<QueueHandle> queue,
649 AssertTypeIsAnalogWaveform(
cap);
657 float delta = vmax - vmin;
658 const int nbins = 100;
662 hist.PrepareForCpuAccess();
668 hist.PrepareForCpuAccess();
674 hist.MarkModifiedFromCpu();
715 AssertTypeIsAnalogWaveform(
cap);
721 float delta = vmax - vmin;
722 const int nbins = 100;
738 return fbin*delta + vmin;
759 AssertTypeIsAnalogWaveform(
cap);
765 float delta = vmax - vmin;
766 const int nbins = 100;
782 return fbin*delta + vmin;
803 AssertTypeIsAnalogWaveform(
cap);
807 for(
float f :
cap->m_samples)
809 return ksum.GetSum() /
cap->m_samples.size();
836 AssertTypeIsAnalogWaveform(
cap);
838 std::vector<size_t>
ret;
839 for(
size_t i=0;
i<bins;
i++)
848 for(
float v :
cap->m_samples)
855 bin = std::min(
bin, bins-1);
894 vk::raii::CommandBuffer& cmdBuf,
895 std::shared_ptr<QueueHandle> queue,
903 AssertTypeIsAnalogWaveform(
cap);
915 hist.PrepareForCpuAccess();
917 hist.MarkModifiedFromCpu();
931 hist.MarkModifiedFromGpu();
934 queue->SubmitAndBlock(cmdBuf);
950 AssertTypeIsAnalogWaveform(
cap);
952 std::vector<size_t>
ret;
953 for(
size_t i=0;
i<bins;
i++)
962 for(
float v :
cap->m_samples)
988 template<
class T,
class R,
class S>
993 AssertTypeIsDigitalWaveform(clock);
994 AssertSampleTypesAreSame(
data, &samples);
999 clock->PrepareForCpuAccess();
1000 data->PrepareForCpuAccess();
1001 samples.PrepareForCpuAccess();
1005 size_t len = clock->size();
1006 size_t dlen =
data->size();
1013 samples.Resize(clock->size());
1017 for(
size_t i=1;
i<len;
i++)
1020 if(clock->m_samples[
i] == clock->m_samples[
i-1])
1032 samples.m_samples[
nout] =
data->m_samples[ndata];
1035 samples.Resize(
nout);
1039 samples.Reserve(1 * 1024 * 1024);
1043 for(
size_t i=1;
i<len;
i++)
1046 if(clock->m_samples[
i] == clock->m_samples[
i-1])
1057 samples.m_offsets.push_back(
clkstart);
1058 samples.m_samples.push_back(
data->m_samples[ndata]);
1061 samples.MarkModifiedFromCpu();
1069 FillDurationsGeneric(samples);
1071 samples.MarkModifiedFromCpu();
1090 data->PrepareForCpuAccess();
1092 samples.PrepareForCpuAccess();
1102 else if(udata && sclock)
1104 else if(sdata && sclock)
1106 else if(sdata && uclock)
1122 template<
class T,
class R,
class S>
1127 AssertTypeIsDigitalWaveform(clock);
1128 AssertTypeIsSparseWaveform(&samples);
1129 AssertSampleTypesAreSame(
data, &samples);
1133 samples.Reserve(1 * 1024 * 1024);
1139 size_t len = clock->size();
1140 size_t dlen =
data->size();
1143 for(
size_t i=1;
i<len;
i++)
1146 if(!(clock->m_samples[
i] && !clock->m_samples[
i-1]))
1157 samples.m_offsets.push_back(
clkstart);
1158 samples.m_samples.push_back(
data->m_samples[ndata]);
1167 FillDurationsGeneric(samples);
1169 samples.MarkModifiedFromCpu();
1188 data->PrepareForCpuAccess();
1190 samples.PrepareForCpuAccess();
1200 else if(udata && sclock)
1202 else if(sdata && sclock)
1204 else if(sdata && uclock)
1220 template<
class T,
class R,
class S>
1225 AssertTypeIsDigitalWaveform(clock);
1226 AssertTypeIsSparseWaveform(&samples);
1227 AssertSampleTypesAreSame(
data, &samples);
1231 samples.Reserve(1 * 1024 * 1024);
1237 size_t len = clock->size();
1238 size_t dlen =
data->size();
1241 for(
size_t i=1;
i<len;
i++)
1244 if(!(!clock->m_samples[
i] && clock->m_samples[
i-1]))
1255 samples.m_offsets.push_back(
clkstart);
1256 samples.m_samples.push_back(
data->m_samples[ndata]);
1265 FillDurationsGeneric(samples);
1267 samples.MarkModifiedFromCpu();
1281 template<
class T,
class R>
1286 AssertTypeIsAnalogWaveform(
data);
1287 AssertTypeIsDigitalWaveform(clock);
1291 samples.
Reserve(1 * 1024 * 1024);
1297 size_t len = clock->size();
1298 size_t dlen =
data->size();
1301 for(
size_t i=1;
i<len;
i++)
1304 if(clock->m_samples[
i] == clock->m_samples[
i-1])
1317 float frac = delta * 1.0 /
data->m_timescale;
1330 FillDurationsGeneric(samples);
1351 data->PrepareForCpuAccess();
1353 samples.PrepareForCpuAccess();
1363 else if(udata && sclock)
1365 else if(sdata && sclock)
1367 else if(sdata && uclock)
1378 s->PrepareForCpuAccess();
1380 u->PrepareForCpuAccess();
1390 s->PrepareForGpuAccess();
1392 u->PrepareForGpuAccess();
1414 FindZeroCrossings(udata, threshold,
edges);
1416 FindZeroCrossings(sdata, threshold,
edges);
1428 static void FindFallingEdges(
1432 FindFallingEdges(sdata,
edges);
1434 FindFallingEdges(udata,
edges);
1437 static void FindPeaks(
1446 static void FindZeroCrossings(
1450 FindZeroCrossings(sdata, threshold,
edges);
1452 FindZeroCrossings(udata, threshold,
edges);
1455 static void FindZeroCrossings(
1459 FindZeroCrossings(sdata,
edges);
1461 FindZeroCrossings(udata,
edges);
1464 static void ClearAnalysisCache();
1468 FILTER_TYPE_LOWPASS,
1469 FILTER_TYPE_HIGHPASS,
1470 FILTER_TYPE_BANDPASS,
1480 static float Bessel(
float x);
1490 sigc::signal<
void()> signal_outputsChanged()
1505 typedef Filter* (*CreateProcType)(
const std::string&);
1506 static void DoAddDecoderClass(
const std::string& name, CreateProcType
proc);
1508 static void EnumProtocols(std::vector<std::string>&
names);
1509 static Filter* CreateFilter(
const std::string&
protocol,
const std::string&
color =
"#ffffff");
1513 typedef std::map< std::string, CreateProcType > CreateMapType;
1514 static CreateMapType m_createprocs;
1517 static std::set<Filter*> m_filters;
1520 static std::map<std::string, unsigned int> m_instanceCount;
1523 static std::mutex m_cacheMutex;
1524 static std::map<std::pair<WaveformBase*, float>, std::vector<int64_t> > m_zeroCrossingCache;
1527#define PROTOCOL_DECODER_INITPROC(T) \
1528 static Filter* CreateInstance(const std::string& color) \
1530 return new T(color); \
1532 virtual std::string GetProtocolDisplayName() override \
1533 { return GetProtocolName(); }
1535#define AddDecoderClass(T) Filter::DoAddDecoderClass(T::GetProtocolName(), T::CreateInstance)
Declaration of FlowGraphNode.
Declaration of OscilloscopeChannel.
Definition AcceleratorBuffer.h:204
A buffer of memory which may be used by GPU acceleration.
Definition AcceleratorBuffer.h:343
Encapsulates a Vulkan compute pipeline and all necessary resources to use it.
Definition ComputePipeline.h:55
Abstract base class for all filter graph blocks which are not physical instrument channels.
Definition Filter.h:105
void AddDigitalStream(const std::string &name)
Helper method for constructors that adds a new STREAM_TYPE_DIGITAL output stream.
Definition Filter.h:182
static void GetBaseAndTopVoltage(vk::raii::CommandBuffer &cmdBuf, std::shared_ptr< QueueHandle > queue, ComputePipeline &minmaxPipeline, std::shared_ptr< ComputePipeline > &histogramPipeline, AcceleratorBuffer< float > &scratchMin, AcceleratorBuffer< float > &scratchMax, AcceleratorBuffer< uint64_t > &hist, SparseAnalogWaveform *swfm, UniformAnalogWaveform *uwfm, float &base, float &top)
Gets the base and top voltage of a waveform which may be sparse or uniform.
Definition Filter.h:584
static float GetMaxVoltage(SparseAnalogWaveform *s, UniformAnalogWaveform *u)
Gets the lowest voltage of a waveform.
Definition Filter.h:560
virtual size_t AddStream(Unit yunit, const std::string &name, Stream::StreamType stype, uint8_t flags=0) override
Adds a new data stream to the channel.
Definition Filter.cpp:1491
__attribute__((noinline)) static void MakeHistogram(vk
Makes a histogram from a waveform with the specified number of bins.
Definition Filter.h:892
void UseDefaultName(bool use)
Specifies whether we're using an auto-generated name or not.
Definition Filter.h:195
bool VerifyAllInputsOKAndSparseOrUniformDigital()
Returns true if every input to the filter is non-NULL and has a non-empty, digital waveform present.
Definition Filter.cpp:247
SparseDigitalWaveform * SetupEmptySparseDigitalOutputWaveform(WaveformBase *din, size_t stream)
Sets up an digital output waveform and copies basic metadata from the input.
Definition Filter.cpp:1164
__attribute__((noinline)) static float GetAvgVoltage(T *cap)
Gets the average voltage of a waveform.
Definition Filter.h:800
static void FindRisingEdges(UniformAnalogWaveform *data, float threshold, std::vector< int64_t > &edges)
Find rising edges in a waveform, interpolating to sub-sample resolution as necessary.
Definition Filter.cpp:326
virtual bool ShouldPersistWaveform() override
Determine whether the channel's waveform(s) should be persisted to a session file.
Definition Filter.cpp:932
bool VerifyInputOK(size_t i, bool allowEmpty=false)
Returns true if a given input to the filter is non-NULL (and, optionally has a non-empty waveform pre...
Definition Filter.cpp:130
static int64_t GetNextEventTimestamp(SparseWaveformBase *wfm, size_t i, size_t len, int64_t timestamp)
Gets the timestamp of the next event (if any) on a waveform.
Definition Filter.cpp:1283
T * SetupEmptyWaveform(WaveformBase *din, size_t stream, bool clear=true)
Sets up an empty output waveform and copies basic metadata from the input.
Definition Filter.h:348
static void PrepareForCpuAccess(SparseWaveform< T > *s, UniformWaveform< T > *u)
Prepares a sparse or uniform analog waveform for CPU access.
Definition Filter.h:1375
__attribute__((noinline)) static void SampleOnAnyEdges(T *data
Samples a waveform on all edges of a clock.
static std::vector< size_t > MakeHistogram(SparseAnalogWaveform *s, UniformAnalogWaveform *u, float low, float high, size_t bins)
Makes a histogram from a waveform with the specified number of bins.
Definition Filter.h:871
virtual void ClearStreams() override
Clears out any existing streams.
Definition Filter.cpp:1484
static void AdvanceToTimestamp(SparseWaveformBase *wfm, size_t &i, size_t len, int64_t timestamp)
Advance the waveform to a given timestamp.
Definition Filter.cpp:1309
UniformAnalogWaveform * SetupEmptyUniformAnalogOutputWaveform(WaveformBase *din, size_t stream, bool clear=true)
Sets up an analog output waveform and copies basic metadata from the input.
Definition Filter.cpp:1050
__attribute__((noinline)) static void SampleOnAnyEdgesWithInterpolation(T *data
Samples an analog waveform on all edges of a clock, interpolating linearly to get sub-sample accuracy...
virtual void ClearSweeps()
Clears any integrated data from past triggers (e.g. eye patterns).
Definition Filter.cpp:80
static size_t GetNumInstances()
Get all currently existing filters.
Definition Filter.h:147
__attribute__((noinline)) static void SampleOnRisingEdgesBase(WaveformBase *data
Samples a waveform on rising edges of a clock.
static float GetMinVoltage(SparseAnalogWaveform *s, UniformAnalogWaveform *u)
Gets the lowest voltage of a waveform.
Definition Filter.h:530
SparseAnalogWaveform * SetupEmptySparseAnalogOutputWaveform(WaveformBase *din, size_t stream, bool clear=true)
Sets up an analog output waveform and copies basic metadata from the input.
Definition Filter.cpp:1090
Category m_category
Category this filter should be displayed under.
Definition Filter.h:265
static void PrepareForGpuAccess(SparseWaveform< T > *s, UniformWaveform< T > *u)
Prepares a sparse or uniform analog waveform for GPU access.
Definition Filter.h:1387
bool VerifyAllInputsOKAndSparseDigital()
Returns true if every input to the filter is non-NULL and has a non-empty, sparsely sampled digital w...
Definition Filter.cpp:221
virtual void SetDefaultName()
Sets the name of a filter based on its inputs.
Definition Filter.cpp:1464
std::vector< float > m_ranges
Y axis range of each output stream.
Definition Filter.h:246
void HideFromList()
Removes this filter from the global list.
Definition Filter.h:156
unsigned int m_instanceNum
Instance number (for auto naming)
Definition Filter.h:1502
__attribute__((noinline)) static float GetMinVoltage(T *cap)
Gets the lowest voltage of a waveform.
Definition Filter.h:512
static float Bessel(float x)
0th order Bessel function
Definition Filter.cpp:1441
static int64_t GetNextEventTimestampScaled(SparseWaveformBase *wfm, size_t i, size_t len, int64_t timestamp)
Gets the timestamp of the next event (if any) on a waveform.
Definition Filter.cpp:1330
UniformDigitalWaveform * SetupEmptyUniformDigitalOutputWaveform(WaveformBase *din, size_t stream)
Sets up an digital output waveform and copies basic metadata from the input.
Definition Filter.cpp:1129
std::vector< float > m_offsets
Y axis offset of each output stream.
Definition Filter.h:249
bool m_usingDefault
If true, we're using an auto-generated name.
Definition Filter.h:268
static int64_t GetNextEventTimestamp(SparseWaveformBase *swfm, UniformWaveformBase *uwfm, size_t i, size_t len, int64_t timestamp)
Gets the timestamp of the next sample in a waveform, which may be sparse or uniform.
Definition Filter.h:284
static void AdvanceToTimestampScaled(SparseWaveformBase *wfm, size_t &i, size_t len, int64_t timestamp)
Advance the waveform to a given timestamp.
Definition Filter.cpp:1356
__attribute__((noinline)) static std
Makes a histogram from a waveform with the specified number of bins.
Definition Filter.h:833
static float GetTopVoltage(SparseAnalogWaveform *swfm, UniformAnalogWaveform *uwfm)
Gets the top voltage of a waveform which may be sparse or uniform.
Definition Filter.h:788
bool IsUsingDefaultName()
Return true if we're using an autogenerated name, false if customized.
Definition Filter.h:203
Category GetCategory()
Returns the category for displaying this filter in the browser.
Definition Filter.h:216
__attribute__((noinline)) static void GetMinMaxVoltage(vk
Gets the min and max voltage of a waveform on the GPU.
Definition Filter.h:463
__attribute__((noinline)) static float GetBaseVoltage(T *cap)
Gets the most probable "0" level for a digital waveform.
Definition Filter.h:712
Category
Category the filter should be displayed under in the GUI.
Definition Filter.h:118
__attribute__((noinline)) static float GetTopVoltage(T *cap)
Gets the most probable "1" level for a digital waveform.
Definition Filter.h:756
SparseDigitalWaveform * SetupSparseDigitalOutputWaveform(SparseWaveformBase *din, size_t stream, size_t skipstart, size_t skipend)
Sets up a digital output waveform and copies timebase configuration from the input.
Definition Filter.cpp:1236
__attribute__((noinline)) static float GetMaxVoltage(T *cap)
Gets the highest voltage of a waveform.
Definition Filter.h:542
static float InterpolateValue(SparseAnalogWaveform *cap, size_t index, float frac_ticks)
Interpolates the actual value of a point between two samples.
Definition Filter.cpp:997
virtual void LoadParameters(const YAML::Node &node, IDTable &table) override
Load configuration from a save file.
Definition Filter.cpp:871
sigc::signal< void()> m_outputsChangedSignal
Signal emitted when the set of output streams changes.
Definition Filter.h:1495
__attribute__((noinline)) static void GetMinMaxVoltage(T *cap
Gets the lowest and highest voltage of a waveform.
__attribute__((noinline)) static void SampleOnAnyEdgesBaseWithInterpolation(WaveformBase *data
Samples an analog waveform on all edges of a clock, interpolating linearly to get sub-sample accuracy...
static float GetAvgVoltage(SparseAnalogWaveform *swfm, UniformAnalogWaveform *uwfm)
Gets the average voltage of a waveform which may be sparse or uniform.
Definition Filter.h:815
SparseAnalogWaveform * SetupSparseOutputWaveform(SparseWaveformBase *din, size_t stream, size_t skipstart, size_t skipend)
Sets up an analog output waveform and copies timebase configuration from the input.
Definition Filter.cpp:1202
virtual std::string GetProtocolDisplayName()=0
Gets the display name of this protocol (for use in menus, save files, etc). Must be unique.
__attribute__((noinline)) static void GetBaseAndTopVoltage(vk
Gets the most probable "0" and "1" level for a digital waveform.
Definition Filter.h:637
virtual void AutoscaleVertical(size_t stream)
Adjusts gain and offset such that the active waveform occupies the entire vertical area of the plot.
Definition Filter.cpp:1501
static float GetBaseVoltage(SparseAnalogWaveform *swfm, UniformAnalogWaveform *uwfm)
Gets the base voltage of a waveform which may be sparse or uniform.
Definition Filter.h:744
bool VerifyAllInputsOKAndUniformAnalog()
Returns true if every input to the filter is non-NULL and has a non-empty, uniformly sampled analog w...
Definition Filter.cpp:169
__attribute__((noinline)) static void SampleOnFallingEdges(T *data
Samples a waveform on the falling edges of a clock.
virtual YAML::Node SerializeConfiguration(IDTable &table) override
Serializes this trigger's configuration to a YAML string.
Definition Filter.cpp:831
__attribute__((noinline)) static float InterpolateTime(T *cap
Interpolates the actual time of a threshold crossing between two samples.
static const std::set< Filter * > & GetAllInstances()
Get all currently existing filters.
Definition Filter.h:143
bool VerifyAllInputsOKAndSparseAnalog()
Returns true if every input to the filter is non-NULL and has a non-empty, sparsely sampled analog wa...
Definition Filter.cpp:195
bool VerifyAllInputsOK(bool allowEmpty=false)
Returns true if every input to the filter is non-NULL (and, optionally has a non-empty waveform prese...
Definition Filter.cpp:155
void AddProtocolStream(const std::string &name)
Helper method for constructors that adds a new STREAM_TYPE_PROTOCOL output stream.
Definition Filter.h:174
static void CalculateFIRCoefficients(float fa, float fb, float stopbandAtten, FIRFilterType type, AcceleratorBuffer< float > &coefficients)
Calculates FIR coefficients.
Definition Filter.cpp:1393
Bidirectional table mapping integer IDs in scopesession files to object pointers.
Definition IDTable.h:49
void SetData(WaveformBase *pNew, size_t stream)
Sets the waveform data for a given stream, replacing any previous waveform.
Definition InstrumentChannel.cpp:144
WaveformBase * GetData(size_t stream)
Get the contents of a data stream.
Definition InstrumentChannel.h:189
Helper class for performing a Kahan summation on a large number of floating point numbers.
Definition KahanSummation.h:37
A single channel on an oscilloscope.
Definition OscilloscopeChannel.h:49
Wrapper around a Vulkan Queue object.
Definition QueueHandle.h:65
StreamType
General data type stored in a stream.
Definition Stream.h:57
A unit of measurement, plus conversion to pretty-printed output.
Definition Unit.h:59
int64_t GetOffsetScaled(T *wfm, size_t i)
Returns the offset of a sample from the start of the waveform, in X axis units.
Definition Waveform.h:841
bool g_hasShaderInt64
Indicates whether the int64 type is available for use in shaders and SSBOs.
Definition VulkanInit.cpp:171
bool g_hasShaderAtomicInt64
Indicates whether atomic operations on the int64 type are available in shaders.
Definition VulkanInit.cpp:195