"""Original synthetic stereo-routing fixture. Python standard library only.
Run: python3 generate.py --out ./run
No recording, instrument sample, or commercial music is used.
"""
import argparse,math,struct,wave,json,hashlib,sys
from pathlib import Path
p=argparse.ArgumentParser();p.add_argument('--out',default='run');a=p.parse_args();out=Path(a.out);out.mkdir(parents=True,exist_ok=True)
rate=44100;seq=[60,64,67,72,69,65,62,60];left=[];right=[];schedule=[]
for n,pitch in enumerate(seq):
 schedule.append({'pitch':pitch,'start':n*.4,'end':n*.4+.3,'source_channel':'left' if n%2==0 else 'right'})
 for i in range(17640):
  t=i/rate;env=max(0,min(1,t/.01,(.3-t)/.02));value=2*round(32767*.2*env*math.sin(2*math.pi*440*2**((pitch-69)/12)*t))
  left.append(value if n%2==0 else 0);right.append(value if n%2 else 0)
mono=[(l+r)//2 for l,r in zip(left,right)]
for name,channels,samples in [('alternating-stereo.wav',2,[v for pair in zip(left,right) for v in pair]),('downmix-mono.wav',1,mono)]:
 with wave.open(str(out/name),'wb') as w:w.setparams((channels,2,rate,len(left),'NONE','not compressed'));w.writeframes(struct.pack('<'+'h'*len(samples),*samples))
record={'source':'Original synthesized sine tones generated by this script; not real music.','python':sys.version,'sampleRate':rate,'bits':16,'frames':len(left),'durationSeconds':len(left)/rate,'schedule':schedule,'mono_formula':'(left PCM integer + right PCM integer) / 2; stereo integers are even, so no rounding is needed','files':{name:hashlib.sha256((out/name).read_bytes()).hexdigest() for name in ['alternating-stereo.wav','downmix-mono.wav']}}
(out/'input-record.json').write_text(json.dumps(record,indent=2)+'\n');print(json.dumps(record,indent=2))
