#!/usr/bin/env node // Diagnostic-only replay: remove one measured WRONG free pitch from this // in-memory follower instance. It never changes static defaults or live code. import fs from 'node:fs'; import { dequantiseSal } from '../static/salience.js'; import { ScoreFollower, FOLLOWER_DEFAULTS } from '../static/follower.js'; const path=process.argv[2]||'/tmp/notepilot-left-loop/mic-follower-hold-diagnostics-20260918-v2.json'; const q=Number(process.argv[3]||78), tr=JSON.parse(fs.readFileSync(path,'utf8')), ev=tr.events, m=tr.meta||{}; const sr=m.follower?.sr||48000, hop=m.follower?.hop||512, opt=m.follower?.options||FOLLOWER_DEFAULTS; const sf=new ScoreFollower({solo:m.rh,sampleRate:sr,win:m.follower?.win||2048,hop,position:0,options:{...opt,diagnostic:()=>{}}}); sf._wrongPitches=sf._wrongPitches.filter(x=>x.midi!==q); const fired=new Set(), attempts=ev.filter(e=>e.type==='input.testEvent'), rows=[]; for(const f of ev.filter(e=>e.type==='follow.frame'&&Array.isArray(e.sal))){ for(let i=0;i{const prior=attempts.filter(a=>a.scoreEventId===r.to&&a.t<=r.t);return !prior.length;}); console.log(JSON.stringify({source:path,excludedQ:q,excludedName:`${q}`,advances:rows.length,advancesTo:rows.slice(-10),falseAdvances:falseAdv.length,falseAdvancesDetail:falseAdv},null,2));