Skip to content

Instantly share code, notes, and snippets.

@DanielFGray
Last active August 29, 2015 14:12
Show Gist options
  • Save DanielFGray/a10da40093c707ca3561 to your computer and use it in GitHub Desktop.
Save DanielFGray/a10da40093c707ca3561 to your computer and use it in GitHub Desktop.
var globals = {
naturals: ['C', 'D', 'E', 'F', 'G', 'A', 'B'],
degrees: ['R', 'm2', 'M2', 'm3', 'M3', 'P4', ['A4', 'D5'], 'P5', 'm6', 'M6', 'm7', 'M7'],
modeNames: ['Ionian', 'Dorian', 'Phrygian', 'Lydian', 'Mixolydian', 'Aeolian', 'Locrian'],
accidentals: {'-1': '♭', 0: '', 1: '♯'},
sharpScales: ['G', 'D', 'A', 'E', 'B', 'F♯'],
flatScales: ['F', 'B♭', 'E♭', 'A♭', 'D♭', 'G♭'],
scales: {
'Major': [2, 2, 1, 2, 2, 2, 1],
'Minor': [2, 1, 2, 2, 1, 2, 2],
'Harmonic Minor': [2, 1, 2, 2, 1, 3, 1],
'Diminished Arpeggio': [3, 3, 3, 3]
},
};
var Scale = function() {
this.key = null;
this.steps = null;
var private = {
modulate: function(arr, offset, steps) {
if(! Array.isArray(arr) || isNaN(offset) || (steps !== undefined && ! Array.isArray(steps))) {
throw 'invalid paramaters to modulate()';
}
var count = arr.length,
height = arr.length,
result = [];
if(steps !== undefined) {
result.push(arr[offset]);
count = steps.length;
}
for(var i = 0, j = 0; i < count; ++i) {
var node = offset + (steps ? j += steps[i] : i);
if(node >= height)
node %= height;
result.push(arr[node]);
}
return result;
},
};
this.getDegrees = function() {
if(this.steps === null) {
throw 'Undefined scale steps';
}
var degrees = private.modulate(globals.degrees, 0, this.steps);
degrees.pop();
if(Array.isArray(degrees[3])) {
degrees[3] = degrees[3][0];
}else if(Array.isArray(degrees[4])) {
degrees[4] = degrees[4][1];
}
return degrees;
};
this.keyOf = function(key) {
this.key = key;
return this;
};
this.modeOf = function(mode) {
this.steps = private.modulate(globals.scales.Major, globals.modeNames.indexOf(mode));
return this;
};
this.toArray = function() {
if(this.key === null || this.steps === null) {
throw 'Undefined key or scale steps';
}
var result = private.modulate(globals.naturals, globals.naturals.indexOf(this.key[0]));
var append = '', useflats = true;
if(this.key.length > 1)
append = this.key[1];
if(globals.sharpScales.indexOf(this.key) !== -1) {
useflats = false;
} else {
useflats = true;
}
result = result.map(function(e) {
//TODO: append or no?
return e + append;
});
return result;
};
};
var printModes = function(key) {
if(key.length === 2) {
if(key[1] == '#') {
key = key.replace('#', globals.accidentals['1']);
} else if(key[1] == 'b') {
key = key.replace('b', globals.accidentals['-1']);
}
}
globals.modeNames.forEach(function(mode) {
var newScale = new Scale().keyOf(key).modeOf(mode);
console.log(mode, newScale.getDegrees());
console.log(newScale.toArray());
});
};
printModes(process.argv[2]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment