Skip to content

Instantly share code, notes, and snippets.

@shinout
Created February 21, 2013 12:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save shinout/5004487 to your computer and use it in GitHub Desktop.
Save shinout/5004487 to your computer and use it in GitHub Desktop.
transpose chords
/**
* transpose.js
* @author SHIN Suzuki
*
**/
/**
* function transpose
*
* @param chordStr (string): documents containing chords
* @param degree (number): e.g. 1: F -> F#, -3 F -> D
* @param toFlat (boolean): if true, all chords are expressed as flat.
* e.g. F# -> Gb
**/
function transpose(chordStr, degree, toFlat) {
if (!degree) degree = 0;
// validation
if (typeof degree != "number") throw "put number to 2nd argument";
degree = parseInt(degree);
var chordRegex = /[A-G][#b]?(maj|aug|dim|sus|[Mm0-9b#△])*(\/[A-G][#b]?)?$/g;
var toneRegex = /[A-G][#b]?/g;
var tonesArray = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
var flatToSharp = {"Db":"C#", "Eb":"D#", "Gb":"F#", "Ab":"G#", "Bb":"A#"};
var sharpToFlat = (function() {
var obj = {};
Object.keys(flatToSharp).forEach(function(flat) {
obj[flatToSharp[flat]] = flat;
});
return obj;
})();
return chordStr.split(/([ \t\n]+)/).map(function(word) {
if (!chordRegex.test(word)) return word;
// here, chords come, do transpose
return word.replace(toneRegex,function(tone) {
// flat to sharp
var sharpTone = flatToSharp[tone];
if (sharpTone) tone = sharpTone;
// transpose
var key = tonesArray.indexOf(tone);
var newKey = (key + degree + 12) % 12;
var newTone = tonesArray[newKey];
// flatize
if (toFlat) {
var flatTone = sharpToFlat[newTone];
if (flatTone) newTone = flatTone;
}
return newTone;
});
}).join("");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment