Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: a67cedbf97bf
Choose a base ref
...
head repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: b504dd68362a
Choose a head ref
  • 1 commit
  • 2 files changed
  • 1 contributor

Commits on Sep 19, 2020

  1. FFTFilter: detect peaks

    azonenberg committed Sep 19, 2020
    Copy the full SHA
    b504dd6 View commit details
Showing with 74 additions and 0 deletions.
  1. +51 −0 scopeprotocols/FFTFilter.cpp
  2. +23 −0 scopeprotocols/FFTFilter.h
51 changes: 51 additions & 0 deletions scopeprotocols/FFTFilter.cpp
Original file line number Diff line number Diff line change
@@ -54,6 +54,14 @@ FFTFilter::FFTFilter(string color)
//Default config
m_range = 70;
m_offset = 35;

m_numpeaksname = "Number of Peaks";
m_parameters[m_numpeaksname] = FilterParameter(FilterParameter::TYPE_INT, Unit(Unit::UNIT_COUNTS));
m_parameters[m_numpeaksname].SetIntVal(10);

m_peakwindowname = "Peak Window";
m_parameters[m_peakwindowname] = FilterParameter(FilterParameter::TYPE_FLOAT, Unit(Unit::UNIT_HZ));
m_parameters[m_peakwindowname].SetFloatVal(500000); //500 kHz between peaks
}

FFTFilter::~FFTFilter()
@@ -190,6 +198,49 @@ void FFTFilter::Refresh()
else
NormalizeOutput(cap, nouts, npoints);

//Peak search
int64_t max_peaks = m_parameters[m_numpeaksname].GetIntVal();
if(max_peaks > 0)
{
//Get peak search width in bins
float search_hz = m_parameters[m_peakwindowname].GetIntVal();
int64_t search_bins = ceil(search_hz / bin_hz);
int64_t search_rad = search_bins/2;

//Find peaks (TODO: can we vectorize/multithread this?)
//Start at index 1 so we don't waste a marker on the DC peak
vector<FFTPeak> peaks;
for(ssize_t i=1; i<(ssize_t)nouts; i++)
{
ssize_t max_delta = 0;
float max_value = -FLT_MAX;

for(ssize_t delta = -search_rad; delta <= search_rad; delta ++)
{
ssize_t index = i+delta ;
if( (index < 0) || (index >= (ssize_t)nouts) )
continue;

float amp = cap->m_samples[index];
if(amp > max_value)
{
max_value = amp;
max_delta = delta;
}
}

//If the highest point in the search window is at our location, we're a peak
if(max_delta == 0)
peaks.push_back(FFTPeak(bin_hz * i, max_value));
}

//Sort the peak table and pluck out the requested count
sort(peaks.rbegin(), peaks.rend(), less<FFTPeak>());
m_peaks.clear();
for(size_t i=0; i<(size_t)max_peaks && i<peaks.size(); i++)
m_peaks.push_back(peaks[i]);
}

SetData(cap, 0);
}

23 changes: 23 additions & 0 deletions scopeprotocols/FFTFilter.h
Original file line number Diff line number Diff line change
@@ -37,6 +37,21 @@

#include <ffts.h>

class FFTPeak
{
public:
FFTPeak(int64_t freq, float mag)
: m_freq(freq)
, m_mag(mag)
{}

bool operator<(const FFTPeak& rhs) const
{ return (m_mag < rhs.m_mag); }

int64_t m_freq;
float m_mag;
};

class FFTFilter : public Filter
{
public:
@@ -58,6 +73,9 @@ class FFTFilter : public Filter
virtual void SetVoltageRange(double range);
virtual void SetOffset(double offset);

const std::vector<FFTPeak>& GetPeaks()
{ return m_peaks; }

PROTOCOL_DECODER_INITPROC(FFTFilter)

protected:
@@ -71,6 +89,11 @@ class FFTFilter : public Filter

float m_range;
float m_offset;

std::string m_numpeaksname;
std::string m_peakwindowname;

std::vector<FFTPeak> m_peaks;
};

#endif