Some checks failed
check / check (push) Has been cancelled
- genome(seed, salts) now has three parts with their own RNG streams: shared (steps, form, swing, arc, layback, fill odds, phase offset), kit (density, frame, accent cycle, free snare) and keys (scale/root, progression, motif, hocket, bass tone, note lengths, range). ROLL KEYS now renews the harmony too; ROLL KIT leaves the keys alone. - Keys generators share one signature and can fix note lengths: MOTIF (the old line), 303 (acid bass, answers in the rests, drone or silent pad), TURING (8/16-bit shift register, DRIFT flips bits, 16-bar window), ARP (triad/7th arpeggio, roots on kicks). - Pages: KIT GEN, KEYS GEN; ROLL shows KIT / KEYS; slots keep both gens. - Flash record v3 (old settings ignored). Bring-up golden checksums updated. - C port matches; host test and ASan/UBSan pass. Intended music change: every seed sounds different (genome split, new generators). Vectors regenerated with npm run vectors; the case grid now crosses all kit and keys generators, with TURING runs past its window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
22 lines
1.6 KiB
JavaScript
22 lines
1.6 KiB
JavaScript
/* Re-renders every golden case with sim/engine.js and compares with test/vectors.
|
|
Exit code 0 = engine unchanged. Use the same files to test the C port. */
|
|
var fs=require('fs'), path=require('path');
|
|
var E=require('../sim/engine.js'), R=require('./render.js');
|
|
var dir=path.join(__dirname,'vectors'), fail=0, n=0;
|
|
var prim=JSON.parse(fs.readFileSync(path.join(dir,'primitives.json'),'utf8'));
|
|
prim.mix.forEach(function(v){ n++; if(R.hex(E.mix(parseInt(v.a,16)>>>0,v.b))!==v.out){ fail++; console.log('mix',v.a,v.b,'differs'); } });
|
|
prim.rng.forEach(function(v){ n++; var r=new E.Rng(parseInt(v.seed,16)>>>0); for(var i=0;i<16;i++) if(R.hex(r.next())!==v.next[i]){ fail++; console.log('rng',v.seed,'step',i,'differs'); break; } });
|
|
prim.genomes.forEach(function(v){ n++; if(JSON.stringify(E.genome(parseInt(v.seed,16)>>>0,v.salts))!==JSON.stringify(v.genome)){ fail++; console.log('genome',v.seed,'differs'); } });
|
|
fs.readdirSync(dir).filter(function(f){ return /^gen\d/.test(f); }).sort().forEach(function(f){
|
|
JSON.parse(fs.readFileSync(path.join(dir,f),'utf8')).cases.forEach(function(c){
|
|
n++;
|
|
var got=R.renderCase({seed:parseInt(c.seed,16)>>>0,salts:c.salts,gen:c.gen,keys:c.keys,energy:c.energy,drift:c.drift,fillBars:c.fillBars,scale:c.scale,root:c.root},c.bars.length);
|
|
if(got.checksum===c.checksum) return;
|
|
fail++;
|
|
for(var b=0;b<c.bars.length;b++){ var a=JSON.stringify(c.bars[b].events), g=JSON.stringify(got.bars[b].events);
|
|
if(a!==g){ console.log('FAIL',c.id,'first difference in bar',b); break; } }
|
|
});
|
|
});
|
|
console.log(fail? fail+' of '+n+' checks FAILED' : 'all '+n+' checks pass');
|
|
process.exit(fail?1:0);
|