"""An original, explicitly composed 20-bar bebop chorus; no audio inputs.""" from pathlib import Path import json, re, shutil HERE=Path(__file__).resolve().parent ROOT=HERE.parents[1] s=json.loads((ROOT/'spanish-double-time-01/score.json').read_text()) # One slot = a double-time eighth (a sixteenth of the unchanged 116 BPM pulse). # :n holds n slots. R leaves space. These are composed phrases, not generated # scale insertions. Adjacent bars deliberately share pickups and resolutions. BARS=[ 'C5:4 Ab4 G4 F4 E4 Gb4 F4 Ab4 C5 Eb5 D5 Db5 C5', 'Db5 Bb4 G4 F4 Ab4 G4 F4 Db5 E5 Eb5 Db5 C5 Bb4 Ab4 G4 E4', 'F4 Ab4 C5 Eb5 G5 Gb5 F5 E5 F5:3 R C5 Ab4 G4 F4', 'A4 C5 Eb5 G5 F5 E5 Eb5 D5 Db5 C5 B4 Bb4 A4 Ab4 G4 A4', 'Bb4:3 R F5 Db5 C5 Bb4 Ab4 G4 F4 E4 Gb4 F4 Db4 C4', 'A3 C4 Eb4 G4 Bb4 A4 Ab4 G4 F4 E4 Eb4 D4 Db4 C4 A3:2', 'Bb3 Db4 F4 Ab4 C5 Db5 C5 Bb4 Ab4:3 R G4 Ab4 A4 Bb4', 'Db5 C5 Bb4 Ab4 G4 Gb4 F4 Db4 E4 G4 Bb4 Db5 E5 Eb5 Db5 C5', 'Ab4:2 G4 F4 E4 Gb4 F4 Ab4 C5:4 R:4', 'R:2 G4 Bb4 Db5 C5 B4 Bb4 A4 Ab4 G4 Gb4 F4 E4 Eb4 Db4', 'C4 Eb4 F4 A4 C5 Eb5 E5 F5 G5 Gb5 F5 E5 Eb5 D5 Db5 C5', 'A4:2 G4 F4 Eb4 D4 Db4 C4 B3 Bb3 A3 C4 Eb4 G4 R:2', 'F4 Ab4 Bb4 Db5 F5 E5 Eb5 Db5 G4 Bb4 Db5 F5 E5 Eb5 Db5 C5', 'C5 Eb5 G5 Bb5 A5 Ab5 G5 Eb5 F5 Ab5 C6 Bb5 Ab5 G5 Gb5 E5', 'F5 Ab5 Bb5 Ab5 Gb5 F5 Db5 C5 Bb4 G4 F4 Db4 E4 G4 Bb4 Db5', 'Eb5 G5 Bb5 D5 Eb5 G5 Bb5 G5 A5:2 G5 F5 Eb5:2 R:2', 'Db5 F5 Ab5 C6 Bb5 Ab5 G5 F5 G5 Gb5 F5 Eb5 Db5 C5 Bb4 Ab4', 'G4 Ab4 C5 Eb5 G5 F5 Eb5 C5 F5 Ab5 C6 Bb5 Ab5 G5 Gb5 F5', 'Db5 Bb4 G4 F4 Ab4 G4 F4 Db4 E4 G4 Bb4 Db5 C5 Bb4 Ab4 E4', 'F4 Ab4 C5 Eb5 D5 Db5 C5 Ab4 G4 E4 F4:4 R:2', ] def pitch(token): m=re.fullmatch(r'([A-G])([b#]?)([0-8])',token) letter,acc,octave=m.groups() return 12*(int(octave)+1)+dict(C=0,D=2,E=4,F=5,G=7,A=9,B=11)[letter]+{'':0,'b':-1,'#':1}[acc] events=[] for bar,line in enumerate(BARS): slots=0 unit=(s['soloBarStarts'][bar+1]-s['soloBarStarts'][bar])/16 for token in line.split(): name,_,length=token.partition(':');length=int(length or 1) if name!='R': p=pitch(name) # Deliberate phrase-level dynamic arch, stable accents, no random timing. crest=.055 if 12<=bar<=17 else .025 if 9<=bar<=11 else 0 accent=.045 if slots in (0,8) else .025 if slots%2 else 0 velocity=.54+crest+accent # Eight-note cells lightly lean on alternate double-time offbeats. The # displacement is only 4 ms; the original bar clock is never moved. delay=.004 if slots%2 else 0 time=s['soloBarStarts'][bar]+slots*unit+delay duration=length*unit*.93 if length>=3:duration=length*unit*.88 events.append(dict(part='guitar',pitch=p,bar=20+bar,beat=slots/4, time=time,duration=duration,velocity=velocity, string=5 if p>=64 else 4 if p>=59 else 3 if p>=55 else 2, role='original composed bebop chorus')) slots+=length assert slots==16,(bar,slots) s['events']=[e for e in s['events'] if not(e['part']=='guitar' and e['bar']>=20)]+events s['events'].sort(key=lambda e:e['time']) s['description']='Our Spanish Love Song: an original composed double-time bebop chorus.' s['arrangement']='Unchanged spanish-double-time-01 theme, bass, tempo and bar clock. New original 20-bar guitar chorus: linked arpeggio/chromatic phrases, thirds at dominant-to-minor arrivals, recurring descending cells, contrasting registers, rests after cadences and a rising middle-section intensity. No samples or additional instruments. Not a transcription or an assertion of perfect bebop.' s['acceptedBaseline']='spanish-double-time-01' s['revision']='Solo guitar composition only; theme and entire bass preserved.' s.pop('departureTime',None) (HERE/'score.json').write_text(json.dumps(s,indent=2)) print(len(events),'explicitly composed solo notes')