MCPcopy Create free account
hub / github.com/aethersdr/AetherSDR / extractPatch

Method extractPatch

src/core/SpectrogramBuffer.cpp:20–81  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

18}
19
20QVector<float> SpectrogramBuffer::extractPatch(double sigFreqMhz,
21 double freqWidthMhz) const
22{
23 if (m_count < kMaxFrames) { return {}; }
24
25 // Use 2× signal width as the extraction window so the patch captures
26 // enough spectral context for the CNN to detect boundary shape.
27 const double halfWin = std::max(freqWidthMhz, 0.003) * 1.0; // ± 1× width
28
29 QVector<float> patch;
30 patch.resize(kMaxFrames * kPatchFreqBins, 0.0f);
31
32 // Iterate frames oldest → newest
33 for (int fi = 0; fi < kMaxFrames; ++fi) {
34 const int idx = (m_head + fi) % kMaxFrames; // m_head is next-write, so oldest is m_head
35 const Frame& fr = m_frames[idx];
36 if (fr.bins.isEmpty() || fr.bandwidthMhz <= 0.0) { continue; }
37
38 const int N = fr.bins.size();
39 const double startMhz = fr.centerMhz - fr.bandwidthMhz / 2.0;
40 const double hzPerBin = fr.bandwidthMhz * 1.0e6 / N;
41
42 // Resample N input bins into kPatchFreqBins output bins
43 // covering [sigFreqMhz - halfWin, sigFreqMhz + halfWin].
44 const double winStartMhz = sigFreqMhz - halfWin;
45 const double winEndMhz = sigFreqMhz + halfWin;
46
47 for (int pb = 0; pb < kPatchFreqBins; ++pb) {
48 const double fMhz = winStartMhz +
49 (pb + 0.5) / kPatchFreqBins * (winEndMhz - winStartMhz);
50 const double srcBinF = (fMhz - startMhz) / fr.bandwidthMhz * N - 0.5;
51 const int b0 = static_cast<int>(std::floor(srcBinF));
52 const int b1 = b0 + 1;
53 const float t = static_cast<float>(srcBinF - b0);
54 float val = 0.0f;
55 if (b0 >= 0 && b1 < N) {
56 val = fr.bins[b0] * (1.0f - t) + fr.bins[b1] * t;
57 } else if (b0 >= 0 && b0 < N) {
58 val = fr.bins[b0];
59 } else if (b1 >= 0 && b1 < N) {
60 val = fr.bins[b1];
61 }
62 patch[fi * kPatchFreqBins + pb] = val;
63 }
64 }
65
66 // Normalize to [0, 1] using the patch min/max
67 float minV = patch[0], maxV = patch[0];
68 for (float v : patch) {
69 minV = std::min(minV, v);
70 maxV = std::max(maxV, v);
71 }
72 const float range = maxV - minV;
73 if (range > 0.5f) {
74 for (float& v : patch) { v = (v - minV) / range; }
75 } else {
76 // Flat patch — no signal content; zero it so CNN returns ~0.5
77 patch.fill(0.0f);

Callers 1

Calls 2

isEmptyMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected