ngscopeclient v0.2.2
Loading...
Searching...
No Matches
BaseMeasurement.h
Go to the documentation of this file.
1/***********************************************************************************************************************
2* *
3* libscopeprotocols *
4* *
5* Copyright (c) 2012-2026 Andrew D. Zonenberg and contributors *
6* All rights reserved. *
7* *
8* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
9* following conditions are met: *
10* *
11* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
12* following disclaimer. *
13* *
14* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
15* following disclaimer in the documentation and/or other materials provided with the distribution. *
16* *
17* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
18* derived from this software without specific prior written permission. *
19* *
20* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
21* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
22* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
23* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
25* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
26* POSSIBILITY OF SUCH DAMAGE. *
27* *
28***********************************************************************************************************************/
29
35#ifndef BaseMeasurement_h
36#define BaseMeasurement_h
37
39{
40public:
41 int64_t timescale;
42 int64_t triggerPhase;
43 uint32_t bufferPerThread;
44 uint32_t len;
45 float vmin;
46 float mid;
47 float range;
48 float global_base;
49};
50
51class BaseMeasurement : public Filter
52{
53public:
54 BaseMeasurement(const std::string& color);
55
56 virtual void Refresh(vk::raii::CommandBuffer& cmdBuf, std::shared_ptr<QueueHandle> queue) override;
57
58 static std::string GetProtocolName();
59
60 PROTOCOL_DECODER_INITPROC(BaseMeasurement)
61
62protected:
63
64 //Minmax calculation
65 ComputePipeline m_minmaxPipeline;
68
69 //Histogram calculation
70 std::shared_ptr<ComputePipeline> m_histogramPipeline;
71 AcceleratorBuffer<uint64_t> m_histogramBuf;
72
73 //Base calculation
74 std::shared_ptr<ComputePipeline> m_firstPassComputePipeline;
75 AcceleratorBuffer<int64_t> m_firstPassOffsets;
76 AcceleratorBuffer<float> m_firstPassSamples;
77 AcceleratorBuffer<int64_t> m_finalSampleCount;
78 std::shared_ptr<ComputePipeline> m_finalPassComputePipeline;
79 AcceleratorBuffer<float> m_partialSums;
80
81 template<class T>
82 void InnerLoop(
83 T* din,
85 size_t len,
86 float vmin,
87 float vmax,
88 float fbin)
89 {
90 cap->PrepareForCpuAccess();
91 din->PrepareForCpuAccess();
92
93 //Set temporary midpoint and range
94 float range = (vmax - vmin);
95 float mid = range/2 + vmin;
96 float global_base = fbin*range + vmin;
97
98 std::vector<float> samples;
99 bool first = true;
100 float delta = range * 0.1;
101 int64_t tfall = 0;
102 float last = vmin;
103
104 for(size_t i=0; i < len; i++)
105 {
106 //Wait for a rising edge (end of the low period)
107 auto cur = din->m_samples[i];
108 auto tnow = GetOffsetScaled(din, i);
109
110 //Find falling edge
111 if( (cur < mid) && (last >= mid) )
112 tfall = tnow;
113
114 //Find rising edge
115 if( (cur > mid) && (last <= mid) )
116 {
117 //Done, add the sample
118 if(!samples.empty())
119 {
120 if(first)
121 first = false;
122
123 else
124 {
125 //Average the middle 50% of the samples.
126 //Discard beginning and end as they include parts of the edge
127 float sum = 0;
128 int64_t count = 0;
129 size_t start = samples.size()/4;
130 size_t end = samples.size() - start;
131 for(size_t j=start; j<=end; j++)
132 {
133 sum += samples[j];
134 count ++;
135 }
136
137 float vavg = sum / count;
138
139 int64_t tmid = (tnow + tfall) / 2;
140
141 //Update duration for last sample
142 size_t n = cap->m_samples.size();
143 if(n)
144 cap->m_durations[n-1] = tmid - cap->m_offsets[n-1];
145
146 cap->m_offsets.push_back(tmid);
147 cap->m_durations.push_back(1);
148 cap->m_samples.push_back(vavg);
149 }
150
151 samples.clear();
152 }
153 }
154
155 //If the value is fairly close to the calculated base, average it
156 if(fabs(cur - global_base) < delta)
157 samples.push_back(cur);
158
159 last = cur;
160 }
161
162 cap->MarkModifiedFromCpu();
163 }
164};
165
166#endif
Definition AcceleratorBuffer.h:204
Definition BaseMeasurement.h:52
Definition BaseMeasurement.h:39
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
A waveform sampled at irregular intervals.
Definition Waveform.h:514
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