// title: Bossa Nova + PopChord class // author: zepadovani // description: // code: //based on Andrea Valle class for jazz chords originally posted here: https://gist.github.com/vanderaalle/4a638991d313b20fc638f172e3b29add //also available here: https://gist.github.com/zepadovani/9f6f714a5dec827be2e0ad11a9e4a552 //Class: (see bossa nova example below) PopChord { var <>symbol, <>root, <>name, <>structure, <>transp ; classvar <>symbols ; classvar <>decay, <>release ; *initClass { var t ; decay = 0.5; release = 0.5 ; symbols = () ; t = " CM M Cmaj {0,4,7} Cm C- Cmin {0,3,7} C+ Caug CM#5 CM+5 C5+ {0, 4, 8} C° Cº Cdim Cmb5 Cm˚5 Cmº5 {0, 3, 6} C7 Cdom7 {0, 4, 7, 10} CM7 C7M CMa7 Cj7 Cmaj7 C7+ {0, 4, 7, 11} CmM7 Cm7M Cm#7 C−M7 Cminmaj7 Cm7+ {0, 3, 7, 11} Cm7 C-7 Cmin7 {0, 3, 7, 10} C+M7 C+7M Caugmaj7 CM7#5 CM7+5 C7M#5 C7M5+ {0, 4, 8, 11} C+7 Caug7 C7#5 C7+5 {0, 4, 8, 10} CØ CØ7 Cø Cø7 Cmin7dim5 Cm7b5 Cm7°5 C−7b5 C−7°5 {0, 3, 6, 10} Co7 C°7 Cdim7 {0, 3, 6, 9} C7b5 Cdom7dim5 {0, 4, 6, 10} CM9 Cmaj9 C7M9 C7M(9) CM7(9) {0, 4, 7, 11, 14} C9 Cdom9 C79 C7(9) {0, 4, 7, 10, 14} CmM9 C−M9 Cminmaj9 Cm7M(9) CmM7(9) {0, 3, 7, 11, 14} Cm9 C−9 Cmin9 Cm7(9) {0, 3, 7, 10, 14} C+M9 Caugmaj9 {0, 4, 8, 11, 14} C+9 C9#5 Caug9 {0, 4, 8, 10, 14} CØ9 {0, 3, 6, 10, 14} CØ9b9 {0, 3, 6, 10, 13} Cº9 C°9 Cdim9 {0, 3, 6, 9, 14} C°b9 Cºb9 Cdimb9 {0, 3, 6, 9, 13} C4 {0, 4, 7, 5} C11 Cdom11 {0, 4, 7, 10, 14, 17} C4+ C+4 {0, 4, 7, 6} C7(11) {0, 4, 7, 10, 17} CM11 Cmaj11 {0, 4, 7, 11, 14, 17} CmM11 C−M11 Cminmaj11 {0, 3, 7, 11, 14, 17} Cm4 {0, 3, 7, 5} Cm7(11) {0, 3, 7, 10, 17} Cm11 C−11 Cmin11 {0, 3, 7, 10, 14, 17} C+M11 Caugmaj11 {0, 4, 8, 11, 14, 17} C+11 C11#5 Caug11 {0, 4, 8, 10, 14, 17} CØ11 {0, 3, 6, 10, 13, 17} C°11 Cº11 {0, 3, 6, 9, 13, 16} CM13 Cmaj13 {0, 4, 7, 11, 14, 17, 21} C13 Cdom13 {0, 4, 7, 10, 14, 17, 21} CmM13 C−M13 Cminmaj13 {0, 3, 7, 11, 14, 17, 21} Cm13 C−13 Cmin13 {0, 3, 7, 10, 14, 17, 21} C+M13 Caugmaj13 {0, 4, 8, 11, 14, 17, 21} C+13 C13#5 Caug13 {0, 4, 8, 10, 14, 17, 21} CØ13 {0, 3, 6, 10, 14, 17, 21} C6 CM6 {0,4,7,9} C-6 CM-6 C6- CM6- {0,4,7,8} Cm6 Cminmaj6 {0,3,7,9} Cm-6 Cm6- {0,3,7,8} C7#9 C7(#9) {0, 4, 7, 10, 15} C7b9 C7(b9) {0, 4, 7, 10, 13} C7#11 C7(#11) {0, 4, 7, 10, 19} C7b11 C7(b11) {0, 4, 7, 10, 17} C7b13 C7(b13) {0, 4, 7, 10, 20}" .split($\n) .collect{|i| i.split($\t)}.collect{|i| [ i[0].split($\ ).collect{|j| // (j != "C").if({ j.replace("C", "").asSymbol // }) }, i[1].replace("{", "[").replace("}", "]").interpret ] }.collect{|ch| ch[0].do{|key| symbols[key] = ch[1] } }; // t[0].add(" "); /* t.postln; symbols.postln;*/ } *new { arg symbol; ^super.new.initC(symbol) } *audio { Server.local.waitForBoot{ SynthDef(\piano, {|note = 60, vol = -6, decay, release| Out.ar(0, MdaPiano.ar(note.midicps, decay:decay, release:release)* vol.dbamp*Line.kr(1,1,6, doneAction:2)) }).add } } /* ~getbass = {arg symbol ; var hasdifbass,bass; hasdifbass = symbol.includes($/); bass = ~getRoot.(symbol.split($/).at(1); bass; }*/ initC { arg aSymbol ; var data, sus, add ; var hasOtherBass=false, bass, bassString, bassIsLetter=false; var numBassDict; numBassDict = Dictionary.with(*[ "4".asSymbol->5, "4+".asSymbol->6, "+4".asSymbol->6, "5-".asSymbol->6, "-5".asSymbol->6, "5°".asSymbol->6, "5º".asSymbol->6, "5".asSymbol->7, "5+".asSymbol->8, "+5".asSymbol->8, "6".asSymbol->9, "7-".asSymbol->9, "-7".asSymbol->9, "7°".asSymbol->9, "7º".asSymbol->9, "6+".asSymbol->10, "+6".asSymbol->10, "7".asSymbol->10, "7+".asSymbol->11, "+7".asSymbol->11, "9-".asSymbol->1, "-9".asSymbol->1, "9".asSymbol->2, "9".asSymbol->2, "9+".asSymbol->3, "+9".asSymbol->3, "-10".asSymbol->3, "10-".asSymbol->3, "10".asSymbol->4, "+10".asSymbol->5, "10+".asSymbol->5, "11-".asSymbol->4, "-11".asSymbol->4, "11".asSymbol->5, "11+".asSymbol->6, "+11".asSymbol->6, "13-".asSymbol->8, "-13".asSymbol->8, "13".asSymbol->9, "13+".asSymbol->10, "+13".asSymbol->10, ]); symbol = aSymbol ; transp = 60 ; data = this.getRoot(symbol.asString) ; hasOtherBass = symbol.asString.includes($/); root = data[0] ; name = data[1]; // hasOtherBass.postln; hasOtherBass.if({ structure = symbols[symbol.asString.split($/).at(0).replace(name.asString, "") .replace("sus", "@").split($@)[0] .replace("add", "@").split($@)[0] .asSymbol] ; bassString = (symbol.asString.split($/).at(1)); ((bassString.at(0).ascii >= 65) && (bassString.at(0).ascii <= 71)).if({ bassIsLetter = true; }); bassIsLetter.if({ bass = this.getRoot(bassString)[0] - root; },{ bass = numBassDict.at(bassString.asSymbol); } ); },{ structure = symbols[symbol.asString.replace(name.asString, "") .replace("sus", "@").split($@)[0] .replace("add", "@").split($@)[0] .asSymbol] ; } ) ; // structure.postln; structure = structure.collect({arg i; i.asInteger}); sus = this.processSus(symbol) ; if (sus.notNil) { structure.remove(3) ; structure.remove(4) ; structure.add(sus.asInteger) } ; add = this.processAdd(symbol) ; if (add.notNil) { structure.add(add.asInteger) } ; if (bass.notNil) { structure = [bass] ++ structure; } ; // } processSus {|symbol| var sus = nil ; if (symbol.asString.contains("sus")){ sus = symbol.asString.replace("sus", "@").split($@)[1]; case {sus == ""}{sus = 5} {sus == [4]}{sus = 5} {sus == [2]}{sus = 2} } ; ^sus } processAdd {|symbol| var add = nil ; var base ; var dict = (\9: 14, \11: 17, \13: 21) ; if (symbol.asString.contains("add")){ add = symbol.asString.replace("add", "@").split($@)[1]; base = dict[add.replace("b", "").replace("#", "").asSymbol] ; add.postln ; case {add.split($b)[1].notNil}{ add = base-1 ; "flatten".postln } {add.split($#)[1].notNil}{ add = base+1 ; "sharpen".postln } {(add.split($#)[1].isNil) && (add.split($b)[1].isNil) } {add = base; "no alt".postln } } ; ^add } // c = C('CMadd9') ; // c.structure getRoot { arg symbol ; var chr, act, root, rootName, alt ; var noteBase = (\C:0,\D:2,\E:4,\F:5,\G:7,\A:9,\B:11) ; name = symbol[0] ; root = noteBase[name.asSymbol] ; if ([$b, $#].includes(symbol[1]) ){ name = name++symbol[1] ; root = root + [-1,1][[$b, $#].indexOf(symbol[1])] } ; ^[root, name.asSymbol] ; } play {|vol = -9| (transp+structure+root).do{|i| Synth(\piano, [\note, i, \vol, vol, \decay, decay, \release, release]) } } chordPitches {arg oct=4, men=0; var last; var sum = 0; var out; out = (structure.collect({arg i,j; (j == 0).if({ last = i; },{ (i < last).if({ sum = sum + 12; last = i; i = i + sum; },{ i = i + sum; } ); }); i - men })) + root + 12 + (oct*12); ^out } } /* ( SynthDef(\moogpluck, {arg outbus=0, freq=440, filter=3, amp=1,coef=0.5,dur=2,legato=1,mix=0,pan=0; var pluck,moog,noteOff,out; pluck = Pluck.ar(PinkNoise.ar,1,0.2,freq.reciprocal,dur*legato,coef); moog = MoogFF.ar(pluck, (freq*filter),2); out = SelectX.ar(mix,[LPF.ar(pluck,2500),moog]); noteOff = DetectSilence.ar(out,doneAction:2); Out.ar(outbus, Pan2.ar(out,pan)); }).add; ) ( {var chordnotes,bass,up; // https://www.youtube.com/watch?v=PHIe9B5plDI :)) var insensatez = "Bm7 F#/A# Am6 E7/G# G6 C7M/G C#m7/5- F#7(b13) Bm7 D7/A G#º G7M Em7(9) Bm7 D7/A C#7/G# G7M/5- F#7(b13) Bm7 Bm7 F#/A# Am6 E7/G# G6 C7M C#m7/5- F#7(b13) Bm7 D7/A G#º G7M Em7(9) Bm7 D7/A C#7/G# G7M/5- F#7(b13) Bm7"; var beatmul = (1!18 ++ 1.2 ++ 1!18 ++ 1.2).flat + ({(0.01).rand2}!insensatez.size); var upswing = 0.02; var insensatezsplit = insensatez.split($ ); var insensatezChords = insensatezsplit.collect({arg i; PopChord(i)}); inf.do({arg j; insensatezsplit[j.mod(insensatezsplit.size)].post; "\t".post; chordnotes = insensatezChords[j.mod(insensatezsplit.size)].chordPitches(2); chordnotes.midiname.postln; chordnotes = chordnotes; bass= [chordnotes[0]] ++ [chordnotes[1]] ++ [chordnotes[0]]; up= [chordnotes[0]] ++ [chordnotes.copyToEnd(2)] ++ [chordnotes.copyToEnd(2)]; Pbind(\instrument, \moogpluck, \freq, Pseq((bass).midicps,1), \amp, Pwhite(-2.0,0,3).dbamp, \dur, Pseq([0.5,0.5,1]*beatmul[j.mod(insensatezsplit.size)],1), \legato,2, \pan, Pwhite(-0.1,-0.3,3), \mix, Pwhite(0.2,0.3,3), ).play; Pbind(\instrument, \moogpluck, \freq, Pseq(up.midicps,1), \amp, Pwhite(-10,-8,3).dbamp, \dur,Pseq(([0.5,0.75,0.75]*beatmul[j.mod(insensatezsplit.size)]),1) + Pwhite(0 - upswing,upswing,3), \coef,0.2, \legato,6, \mix, Pwhite(0.7,0.8,3), \pan, Pwhite(0.1,0.3,3) ).play; (2*beatmul[j.mod(insensatezsplit.size)]).wait; }); }.fork ) )*/