Skip to content

Instantly share code, notes, and snippets.

@zepadovani
Forked from vanderaalle/C.sc
Last active July 21, 2018 11:24
Show Gist options
  • Save zepadovani/9f6f714a5dec827be2e0ad11a9e4a552 to your computer and use it in GitHub Desktop.
Save zepadovani/9f6f714a5dec827be2e0ad11a9e4a552 to your computer and use it in GitHub Desktop.
SuperCollider Chord Generator
// 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
)
)*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment