/* Regenerates test/vectors/*.json from sim/engine.js. Only run this when you MEAN to change the music. Otherwise run check-vectors.js. */ var fs=require('fs'), path=require('path'); var E=require('../sim/engine.js'), C=require('./cases.js'), R=require('./render.js'); var dir=path.join(__dirname,'vectors'); var FORMAT='events: [tick, lane, voice, vel, len, track]. lane 0 = kit (voice 0 kick, 1 snare, 2 hat, 3 perc), lane 1 = synth (voice = MIDI pitch). scale/root: -1 = AUTO (the seed picks). Every track is listed; on/off is applied at output. Ticks: 840 per quarter, 210 per 16th.'; // 1. primitives: hash, RNG, genome. Port these first. var mixV=[], pairs=[[0,0],[1,0],[0,1],[0x5EEDB0C5,0x46494C],[0xFFFFFFFF,0xFFFFFFFF],[0xDEADBEEF,-1],[12345,0x4E55+7]]; pairs.forEach(function(p){ mixV.push({a:R.hex(p[0]>>>0),b:p[1]|0,out:R.hex(E.mix(p[0]>>>0,p[1]))}); }); var rngV=[]; [0,1,0x5EEDB0C5,0xDEADBEEF].forEach(function(s){ var r=new E.Rng(s), seq=[], below=[], ch=[]; for(var i=0;i<16;i++) seq.push(R.hex(r.next())); r=new E.Rng(s); for(i=0;i<16;i++) below.push(r.below(i+1)); r=new E.Rng(s); for(i=0;i<16;i++) ch.push(r.chance(i*4096)?1:0); rngV.push({seed:R.hex(s>>>0),next:seq,below_1_to_16:below,chance_i_times_4096:ch}); }); var genV=C.cases().filter(function(c,i,a){ return a.findIndex(function(d){ return d.seed===c.seed && d.salts.join()===c.salts.join(); })===i; }) .map(function(c){ return {seed:R.hex(c.seed),salts:c.salts,genome:E.genome(c.seed>>>0,c.salts)}; }); fs.writeFileSync(path.join(dir,'primitives.json'),JSON.stringify({note:'mix(a,b) hash, xorshift32 Rng (next, below(n), chance(p)) and genome(seed, salts). genome keys are the JS field names.',mix:mixV,rng:rngV,genomes:genV},null,1)+'\n'); // 2. full renders, one file per generator var byGen={}, index=[]; C.cases().forEach(function(c){ var out=R.renderCase(c,C.BARS), id=R.caseId(c); (byGen[c.gen]=byGen[c.gen]||[]).push({id:id,seed:R.hex(c.seed),salts:c.salts,gen:c.gen,keys:c.keys,energy:c.energy,drift:c.drift,fillBars:c.fillBars,scale:c.scale,root:c.root,checksum:out.checksum,bars:out.bars.map(function(b){ return {bar:b.bar,sec:b.sec,fill:b.fill,barTicks:b.barTicks,events:b.events}; })}); index.push({id:id,checksum:out.checksum}); }); Object.keys(byGen).forEach(function(g){ var s=JSON.stringify({generator:E.GEN_NAMES[g],format:FORMAT,cases:byGen[g]}); s=s.replace(/\],\[/g,'],\n['); // one event per line keeps git diffs readable fs.writeFileSync(path.join(dir,'gen'+g+'-'+E.GEN_NAMES[g].toLowerCase()+'.json'),s+'\n'); }); fs.writeFileSync(path.join(dir,'index.json'),JSON.stringify({bars:C.BARS,cases:index},null,1)+'\n'); console.log('wrote',index.length,'cases');