A correction that deletes my own claim from two days ago, and a test that explains why.
Skye asked a fair question in another thread: if the tone in 2010 was 0.79 s and in 2026 it is 1.30 s, then the tone did not hold, so either the tone moved or "period = tone + pause" is wrong. The second option is false by construction. A marker repeats, so the period IS the buzz plus the silence. The tone has to give.
But when I went to check it I found something worse for my own numbers: on every post-2002 file I hold, the "tone length" is not a stable quantity at all. It depends on where I put the line between buzz and silence, and that line is mine, not the station's.
The test. Same envelope for all six files: |FFT| of 10 ms frames in 250-700 Hz, then a 60 ms boxcar so the 106 Hz buzz does not make the envelope chatter. Per cycle, base = 20th percentile, top = max, threshold = base + f*(top-base). Buzz = the contiguous run around the maximum that stays above threshold. Sweep f. Nothing else changes between files.
f 0.20 0.30 0.50 0.70 0.85
1997 Conet tape 0.87 0.85 0.82 0.62 0.26 (42 cycles)
2010-08-07 0.83 0.80 0.77 0.65 0.29 (5 cycles)
2022-08-10 0.92 0.41 0.12 0.06 0.04 (8 cycles)
2023-08-03 1.41 1.03 0.89 0.13 0.05 (31 cycles)
2025-02-08 0.85 0.36 0.19 0.07 0.06 (5 cycles)
2026-10-27 1.35 1.32 0.31 0.10 0.06 (283 cycles)
Read the columns, not the rows. The 1997 tape loses 6% of its buzz between f=0.2 and f=0.5, and the 2010 capture 7%. That is a keyed edge: it is steep, so a small change in where you cut barely moves the length. From 2022 on, the same cut moves the answer by factors of 3 to 28, and the spread inside one file (interquartile range) covers half a cycle. That is not an edge. It is the AGC slope linkfanel described, lifting the noise floor before each buzz. Where the buzz "ends" is whatever level the receiver happened to be at.
So two things go. First, my "tone held 1997-2023 and moved after 2010" from post #44 is withdrawn; it was two threshold readings compared as if they were two measurements. Second, the general one: any tone length quoted from a post-2002 capture is a statement about the reporter's threshold. That includes the 0.8 / 1.0-1.3 pair and the 1.25 + 1.85 that sums to 3.10. The periods can be checked. The halves cannot. Anyone who has measured a modern file and got a clean number got it because their gate landed in the steep part.
One more of my own numbers is wobbling and I would rather print it than have someone find it. The 2022-08-10 file re-measures 2.9594 s by autocorrelation today against the 2.92 s I published. Its peak list is flat (2.950, 2.960, 2.970, 2.980, 2.990, all r 0.39-0.40) and the onset gate refuses the file outright, fewer than three runs survive. Eight cycles, heavy AGC. So the honest entry is 2.9-3.0 s, and my 2.92 is one point inside that band, not a better number than 2.96. I converted that file to 16 kHz mono for this run and I have not checked whether that moved it; if it did, the same conversion was used for the 2010 and 2023 files above.
What survives this post: periods (the method picks no line), tunes (harmonic comb), the 2002 to 2010 step in both parameters, the post-2022 rise to 3.380, and the 2023 clip as unresolved. What dies: the tone/pause story in every version I have told it, including mine.
Code, if you want to run it on your own capture. Numpy only:
def sweep(fn, P, f=0.5):
x, sr = load(fn); e, hs = envelope(x, sr, hop_s=0.010) # your loader, 250-700 Hz
k = int(0.06/hs); es = np.convolve(e, np.ones(k)/k, 'same')
n = int(round(P/hs)); L = []
for i in range(len(es)//n - 1):
seg = es[i*n:(i+1)*n]; top = seg.max(); base = np.percentile(seg, 20)
if top < 3*base: continue
thr = base + f*(top-base); m = int(np.argmax(seg)); a = b = m
while a > 0 and seg[a-1] > thr: a -= 1
while b < len(seg)-1 and seg[b+1] > thr: b += 1
L.append((b-a+1)*hs)
return np.median(L), np.percentile(L, 25), np.percentile(L, 75), len(L)
If the median moves more than 10% between f=0.3 and f=0.5, your file cannot give a tone length and you should report the period only. Files, hashes and the period series are in #37 and #41.