|
var line_of_fifths = [ |
|
"F\u266D", |
|
"C\u266D", |
|
"G\u266D", |
|
"D\u266D", |
|
"A\u266D", |
|
"E\u266D", |
|
"B\u266D", |
|
"F", |
|
"C", |
|
"G", |
|
"D", |
|
"A", |
|
"E", |
|
"B", |
|
"F\u266F", |
|
"C\u266F", |
|
"G\u266F", |
|
"D\u266F", |
|
"A\u266F", |
|
"E\u266F", |
|
"B\u266F", |
|
]; |
|
|
|
function show_notes_to_play() { |
|
|
|
var keyNoteElement = document.getElementById("key"); |
|
var keyModeElement = document.getElementById("mode"); |
|
var bassNoteElement = document.getElementById("bassNote"); |
|
var bassNote = bassNoteElement.options[bassNoteElement.selectedIndex].value; |
|
var keyNote = keyNoteElement.options[keyNoteElement.selectedIndex].text; |
|
var keyMode = keyModeElement.options[keyModeElement.selectedIndex].text; |
|
var scale = get_scale(keyNote, keyMode); |
|
var bassAccidentalElement = document.getElementById("accidental"); |
|
var bassAccidental = bassAccidentalElement.options[bassAccidentalElement.selectedIndex].text; |
|
if (bassAccidental == "\u00A0") { |
|
if (!scale.includes(bassNote)) { |
|
var index = scale.findIndex(note => note.startsWith(bassNote)); |
|
bassNote = scale[index]; |
|
} |
|
} |
|
bassNote += bassAccidental; |
|
getIntervalAboveWithinKey(scale, bassNote, 5, 1); |
|
|
|
var figures = document.querySelector('input[name="figures"]:checked').value; |
|
var notes = realizeFigures(scale, bassNote.trim(), figures); |
|
var bSorted = -1; |
|
notes.sort(); |
|
for (i = 0; bSorted != 1; i++) { |
|
if (notes[i] != null && compare(notes[i], bassNote) == -1) |
|
notes = mutableRotateLeft(notes); |
|
else |
|
bSorted = 1; |
|
} |
|
document.getElementById("demo").innerHTML = bassNote.trim() + "," + notes; |
|
notes.length = 0; |
|
|
|
} |
|
|
|
function compare(a, b) { |
|
if (a < b) |
|
return -1; |
|
else if (a > b) |
|
return 1; |
|
else |
|
return 0; |
|
} |
|
|
|
function mutableRotateLeft(arr) { |
|
arr.push(arr.shift()); |
|
return arr; |
|
} |
|
|
|
function get_scale(keyNote, keyMode) { |
|
var scale = []; |
|
var keyNoteIndex = line_of_fifths.indexOf(keyNote); |
|
|
|
if (keyMode == "Major") { |
|
scale.push(line_of_fifths[keyNoteIndex]); |
|
scale.push(line_of_fifths[keyNoteIndex + 2]); |
|
scale.push(line_of_fifths[keyNoteIndex + 4]); |
|
scale.push(line_of_fifths[keyNoteIndex - 1]); |
|
scale.push(line_of_fifths[keyNoteIndex + 1]); |
|
scale.push(line_of_fifths[keyNoteIndex + 3]); |
|
scale.push(line_of_fifths[keyNoteIndex + 5]); |
|
} |
|
else { |
|
scale.push(line_of_fifths[keyNoteIndex]); |
|
scale.push(line_of_fifths[keyNoteIndex + 2]); |
|
scale.push(line_of_fifths[keyNoteIndex - 3]); |
|
scale.push(line_of_fifths[keyNoteIndex - 1]); |
|
scale.push(line_of_fifths[keyNoteIndex + 1]); |
|
scale.push(line_of_fifths[keyNoteIndex - 4]); |
|
scale.push(line_of_fifths[keyNoteIndex - 2]); |
|
} |
|
return scale; |
|
} |
|
|
|
function getIntervalAboveWithinKey(scale, noteBass, nStepsUp, iAlter) { |
|
var startIndex = scale.findIndex(note => note.startsWith(noteBass.charAt(0))); |
|
var endIndex = startIndex + nStepsUp - 1; |
|
if (endIndex > 6) |
|
endIndex %= 7; |
|
var newNote = scale[endIndex]; |
|
switch (iAlter) { |
|
case -2: |
|
{ |
|
for (i = 0; i < 2; i++) { |
|
if (newNote.endsWith("\u266F")) |
|
newNote = newNote.substring(0, newNote.length - 1); |
|
else |
|
newNote += "\u266D"; |
|
} |
|
break; |
|
} |
|
case -1: |
|
{ |
|
if (newNote.endsWith("\u266F")) |
|
newNote = newNote.substring(0, newNote.length - 1); |
|
else |
|
newNote += "\u266D"; |
|
break; |
|
} |
|
case 1: |
|
{ |
|
if (newNote.endsWith("\u266D")) |
|
newNote = newNote.substring(0, newNote.length - 1); |
|
else |
|
newNote += "\u266F"; |
|
break; |
|
} |
|
case 2: |
|
{ |
|
for (i = 0; i < 2; i++) { |
|
if (newNote.endsWith("\u266D")) |
|
newNote = newNote.substring(0, newNote.length - 1); |
|
else |
|
newNote += "\u266F"; |
|
} |
|
break; |
|
} |
|
case 0: |
|
default: |
|
} |
|
|
|
return newNote; |
|
} |
|
|
|
function realizeFigures(scale, noteBass, sFB) { |
|
var figures = []; |
|
var notes = []; |
|
notes.push(noteBass); |
|
var iAlter = 0; |
|
|
|
for (index = 0; index < sFB.length; index++) { |
|
if (sFB.charAt(index) == '#' || sFB.charAt(index) == '+' || sFB.charAt(index) == '\u266F') |
|
iAlter += 1; |
|
else if (sFB.charAt(index) == 'b' || sFB.charAt(index) == '-' || sFB.charAt(index) == '\u266D') |
|
iAlter -= 1; |
|
else if (sFB.charAt(index) == 'T' || sFB.charAt(index) == '0') { |
|
figures.length = 0; |
|
figures.push(0); |
|
notes.length = 0; |
|
notes.push("none"); |
|
return notes; |
|
} |
|
else if (!isNaN(parseInt(sFB.charAt(index), 10))) |
|
{ |
|
var nSteps = parseInt(sFB.charAt(index), 10); |
|
var note = getIntervalAboveWithinKey(scale, noteBass, nSteps, iAlter); |
|
notes.push(note); |
|
figures.push(nSteps); |
|
iAlter = 0; |
|
|
|
} |
|
} |
|
if (!figures.includes(5)) |
|
if (!figures.includes(6)) { |
|
var note = getIntervalAboveWithinKey(scale, noteBass, 5, 0); |
|
notes.push(note); |
|
if (getNumberOfSecondsInChord(notes) > 1) { |
|
notes = arrayRemove(notes, note); |
|
note = getIntervalAboveWithinKey(scale, noteBass, 6, 0); |
|
notes.push(note); |
|
if (getNumberOfSecondsInChord(notes) > 1) |
|
notes = arrayRemove(notes, note); |
|
} |
|
} |
|
if (!figures.includes(3)) |
|
if (!figures.includes(4)) { |
|
if (sFB.length == 1 && (sFB == "#" || sFB == "+" || sFB == "\u266F")) |
|
var note = getIntervalAboveWithinKey(scale, noteBass, 3, 1); |
|
else if (sFB.length == 1 && (sFB == "b" || sFB == "-" || sFB == "\u266D")) |
|
var note = getIntervalAboveWithinKey(scale, noteBass, 3, -1); |
|
else |
|
var note = getIntervalAboveWithinKey(scale, noteBass, 3, iAlter); |
|
notes.push(note); |
|
if (getNumberOfSecondsInChord(notes) > 1) { |
|
notes = arrayRemove(notes, note); |
|
note = getIntervalAboveWithinKey(scale, noteBass, 4, 0); |
|
notes.push(note); |
|
if (getNumberOfSecondsInChord(notes) > 1) |
|
notes = arrayRemove(notes, note); |
|
} |
|
} |
|
notes.shift(); |
|
return notes; |
|
} |
|
|
|
function getNumberOfSecondsInChord(notes) { |
|
var nSteps = 0; |
|
notes.forEach(function (element) { |
|
notes.forEach(function (element2) { |
|
if (isStep(element, element2)) |
|
nSteps++; |
|
}); |
|
}); |
|
return nSteps; |
|
} |
|
|
|
function isStep(note1, note2) { |
|
switch (note1.charAt(0)) { |
|
case 'A': |
|
{ |
|
if (note2.charAt(0) == 'B') |
|
return true; |
|
else |
|
return false; |
|
} |
|
case 'B': |
|
{ |
|
if (note2.charAt(0) == 'C') |
|
return true; |
|
else |
|
return false; |
|
} |
|
case 'C': |
|
{ |
|
if (note2.charAt(0) == 'D') |
|
return true; |
|
else |
|
return false; |
|
} |
|
case 'D': |
|
{ |
|
if (note2.charAt(0) == 'E') |
|
return true; |
|
else |
|
return false; |
|
} |
|
case 'E': |
|
{ |
|
if (note2.charAt(0) == 'F') |
|
return true; |
|
else |
|
return false; |
|
} |
|
case 'F': |
|
{ |
|
if (note2.charAt(0) == 'G') |
|
return true; |
|
else |
|
return false; |
|
} |
|
case 'G': |
|
{ |
|
if (note2.charAt(0) == 'A') |
|
return true; |
|
else |
|
return false; |
|
} |
|
default: |
|
return false; |
|
} |
|
} |
|
|
|
|
|
function arrayRemove(arr, value) { |
|
|
|
return arr.filter(function (ele) { |
|
return ele != value; |
|
}); |
|
|
|
} |
|
|
|
function convert_pitch_to_int(name, accidental) { |
|
iStepClass = -1; |
|
switch (name) { |
|
case 'C': iStepClass = 0; break; |
|
case 'D': iStepClass = 1; break; |
|
case 'E': iStepClass = 2; break; |
|
case 'F': iStepClass = 3; break; |
|
case 'G': iStepClass = 4; break; |
|
case 'A': iStepClass = 5; break; |
|
case 'B': iStepClass = 6; break; |
|
default: break; |
|
} |
|
return iStepClass; |
|
} |
|
|
|
function change_mode() { |
|
var key = document.getElementById("key"); |
|
var mode = document.getElementById("mode"); |
|
var index = key.selectedIndex; |
|
if (mode.options[mode.selectedIndex].value == "Major") { |
|
key.options[0] = new Option('C\u266D', 'Cb'); |
|
key.options[1] = new Option('G\u266D', 'Gb'); |
|
key.options[2] = new Option('D\u266D', 'Db'); |
|
key.options[3] = new Option('A\u266D', 'Ab'); |
|
key.options[4] = new Option('E\u266D', 'Eb'); |
|
key.options[5] = new Option('B\u266D', 'Bb'); |
|
key.options[6] = new Option('F', 'F'); |
|
key.options[7] = new Option('C', 'C'); |
|
key.options[8] = new Option('G', 'G'); |
|
key.options[9] = new Option('D', 'D'); |
|
key.options[10] = new Option('A', 'A'); |
|
key.options[11] = new Option('E', 'E'); |
|
key.options[12] = new Option('B', 'B'); |
|
key.options[13] = new Option('F\u266F', 'F#'); |
|
key.options[14] = new Option('C\u266F', 'C#'); |
|
index += 3; |
|
if (index > 14) |
|
index -= 12; |
|
key.selectedIndex = index; |
|
} |
|
else { |
|
key.options[0] = new Option('A\u266D', 'Ab'); |
|
key.options[1] = new Option('E\u266D', 'Eb'); |
|
key.options[2] = new Option('B\u266D', 'Bb'); |
|
key.options[3] = new Option('F', 'F'); |
|
key.options[4] = new Option('C', 'C'); |
|
key.options[5] = new Option('G', 'G'); |
|
key.options[6] = new Option('D', 'D'); |
|
key.options[7] = new Option('A', 'A'); |
|
key.options[8] = new Option('E', 'E'); |
|
key.options[9] = new Option('B', 'B'); |
|
key.options[10] = new Option('F\u266F', 'F#'); |
|
key.options[11] = new Option('C\u266F', 'C#'); |
|
key.options[12] = new Option('G\u266F', 'G#'); |
|
key.options[13] = new Option('D\u266F', 'D#'); |
|
key.options[14] = new Option('A\u266F', 'A#'); |
|
index -= 3; |
|
if (index < 0) |
|
index += 12; |
|
key.selectedIndex = index; |
|
} |
|
} |
|
|
|
|
|
function close_dropdown() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
function deleteAllCookies() { |
|
var cookies = document.cookie.split(";"); |
|
|
|
for (var i = 0; i < cookies.length; i++) { |
|
var cookie = cookies[i]; |
|
var eqPos = cookie.indexOf("="); |
|
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie; |
|
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT"; |
|
} |
|
} |
|
|
|
function getCookie(cname) { |
|
var name = cname + "="; |
|
var decodedCookie = decodeURIComponent(document.cookie); |
|
var ca = decodedCookie.split(';'); |
|
for (var i = 0; i < ca.length; i++) { |
|
var c = ca[i]; |
|
while (c.charAt(0) == ' ') { |
|
c = c.substring(1); |
|
} |
|
if (c.indexOf(name) == 0) { |
|
return c.substring(name.length, c.length); |
|
} |
|
} |
|
return ""; |
|
} |