Skip to content

Commit

Permalink
Ändrat struktur och lagt till intervoice
Browse files Browse the repository at this point in the history
  • Loading branch information
staffanberglund committed Mar 2, 2024
1 parent 0fa101c commit 896dcf7
Show file tree
Hide file tree
Showing 12 changed files with 584 additions and 31 deletions.
37 changes: 37 additions & 0 deletions ackord/ackord.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato">
<link REL="stylesheet" TYPE="text/css" href="../style.css">
<title>Staffans gehörsapp</title>
<script src='../im-tonal.js'></script>
<script src="../soundfont-player.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vexflow@4.0.3/build/cjs/vexflow.js"></script>
</head>

<body>
<div class="kol" style="margin: auto">
<p style="text-align: center;" id='chordButtonPar'>
<button style="text-align: center;" class="button" id="chordButton">Spela</button>
</p>
<p style="text-align: center;" id='visaButton'>
<button style="text-align: center;" class="button" id="visaButton">Visa</button>
</p>
<p style="text-align: center;" id='reload'>
<button style="text-align: center;" class="button" id="reloadButton">Uppdatera</button>
</p>
<p style="text-align: center;" id='visaAckord'> </p>
</div>

<div id="output" class="kol" style="margin: auto">
<p style="text-align: center; margin: auto" id='visaSkala'> </p>
</div>
<div style="font-family: Lato; text-align:center">
<a href="../index.html">Tillbaka till startsida</a>
</div>

</body>
<script src='ackord.js' ></script>
</html>
185 changes: 185 additions & 0 deletions ackord/ackord.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
function main() {

const { pitchClass, octave } = Tonal.Note;

const { midiToNoteName, } = Tonal.Midi;

const { Scale, Chord, Note, Range, Key, Interval, Midi } = Tonal;

function filterTonal(set) {
const isIncluded = Tonal.PcSet.isNoteIncludedIn(set);
return function(notes) {
return notes.filter(isIncluded);
};
};

function scale(set, range) {
if (arguments.length === 1) {
return r => scale(set, r);
} else {
const notes = Range.chromatic(range);
const filtered = filterTonal(set)(notes);
return filtered;
}
};

let renderedBool;

Tonal.ScaleType.add(["1P", "2m", "3M", "4P", "5P", "6M", "7m"], "mixolydian b2");
Tonal.ScaleType.add(["1P", "2A", "3M", "4P", "5P", "6M", "7m"], "mixolydian #2");
Tonal.ScaleType.add(["1P", "2m", "3M", "4P", "5P", "6m", "7m"], "mixolydian b2 b6");
Tonal.ScaleType.add(["1P", "2A", "3M", "4A", "5P", "6M", "7m"], "lydian dominant #2");


let bassNote;
let bastonNote;
let bassNoteName;
let grundton;
let ack;
let ackVisa;
let skalaVar;

/*------------------------------*/
/* Slumpa fram ackord och skala */
/*------------------------------*/
async function ackord() {
document.getElementById('visaAckord').innerHTML = '';
document.getElementById('visaSkala').innerHTML = '';

vf.context.clear();
renderedBool = 0;

grundton = 48 + Math.floor((Math.random() * 11) + 1);
const tonart = Key.majorKey(pitchClass(midiToNoteName(grundton))).alteration;
bassNote = [grundton - 12];
bastonNote = Note.pitchClass(midiToNoteName(grundton));
bassNoteName = Midi.midiToNoteName(bassNote);

const [skalaResponse, ackordResponse] = await Promise.all([
fetch('scales.json'),
fetch('chords.json')
]);

const skala = await skalaResponse.json();
const ackord = await ackordResponse.json();
const index1 = Math.floor((Math.random() * skala.length));
skalaVar = skala[index1];


let voicings = ackord["sevenNotes"];
const index2 = Math.floor((Math.random() * voicings.length));
voicings[index2] = voicings[index2].filter(x => ( Tonal.Scale.get(skalaVar).intervals[2] == "3M" && Tonal.Scale.get(skalaVar).intervals[3] == "4P" ) ? x != 11 : x ) ; // Om durters & ren kvart, ta bort 11 från ackordet
voicings[index2] = voicings[index2].filter(x => ( Tonal.Scale.get(skalaVar).intervals[1] == "2m" && Tonal.Scale.get(skalaVar).intervals[2] == "3m" ) ? x != 9 : x ) ; // Om moll och b9, ta bort nia
ackPC = voicings[index2].map(Scale.degrees( Midi.midiToNoteName(grundton, {sharps: tonart > 0, pitchClass: true}) + ' ' + skalaVar));
voicingFirst = Scale.degrees(Midi.midiToNoteName(grundton, {sharps: tonart > 0, pitchClass: false}) + ' ' + skalaVar)(voicings[index2][0]);
ack = Scale.rangeOf(ackPC)(voicingFirst,Note.transpose(voicingFirst,'7M'));
ackVisa = ack.join(' ');

return [ack, skalaVar];
};


/*------------------------------*/
/* Spela upp ljud */
/*------------------------------*/
let piano;
let bass;

const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();

Promise.all([
Soundfont.instrument(audioContext, 'acoustic_grand_piano').then(function (x) {
piano = x;
}),

Soundfont.instrument(audioContext, 'acoustic_bass').then(function (x) {
bass = x;
})
]);

async function chord() {
if (!ack) {
await ackord();
}

const playPiano = ack.map(note => piano.play(note));
const playBass = bassNote.map(note => bass.play(note));

await Promise.all(playPiano,playBass);
};

async function visaAckord() {
if (!ack) {
await ackord();
}

document.getElementById('visaAckord').innerHTML = await '<br>' + Chord.detect([bastonNote].concat(ack),{assumePerfectFifth: true})[0];
document.getElementById('visaSkala').innerHTML = await '(slumpad skala: ' + bastonNote + ' ' + skalaVar + ')';
if (renderedBool == 0) {
visaNoter();
renderedBool = 1;
}

};

/*----------------------*/
/* Rita noter */
/*----------------------*/

const { System, Factory, EasyScore } = Vex.Flow;

const vf = new Factory({
renderer: {
elementId: 'output',
width: 250,
height: 250
},
});

async function visaNoter() {
if (!ack) {
await ackord();
}


console.log('(' + ackVisa + ')' + '/w');
const score = vf.EasyScore();
const system = vf.System({x:15,y:0,width: 180});
system
.addStave({
voices: [
score.voice(score.notes('(' + ackVisa + ')' + '/w', {
stem: 'up',
clef: 'treble'
})),
],
})
.addClef('treble')
.addTimeSignature('4/4')

system
.addStave({
voices: [
score.voice(score.notes(bassNoteName +'/w', {
stem: 'up',
clef: 'bass'
})),
],
})
.addClef('bass')
.addTimeSignature('4/4');

system.addConnector('singleLeft');
system.addConnector('brace');
system.addConnector('singleRight');

vf.draw();
};


document.getElementById('chordButton').addEventListener('click', chord);
document.getElementById('visaButton').addEventListener('click', visaAckord);
document.getElementById('reloadButton').addEventListener('click', ackord);
}
main();
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions brutnaAckord/brutnaAckord.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@
<button style="text-align: center;" class="button" id="firstNote">Första ton</button>
</p>
<p style="text-align: center;" id='chordButtonPar'>
<button style="text-align: center;" class="button" id="chordButton">Spela</button>
<button style="text-align: center;" class="button" id="chordButton">Facit</button>
</p>
<p style="text-align: center;" id='reload'>
<button style="text-align: center;" class="button" id="reloadButton">Uppdatera</button>
<button style="text-align: center;" class="button" id="reloadButton">Nytt ackord</button>
</p>
<p style="text-align: center;" id='visaAckord'> </p>
</div>

<div id="output" class="kol" style="margin: auto"></div>
<p style="text-align: center; margin: auto" id='visaSkala'> </p>
<div style="font-family: Lato; text-align:center">
<a href="../index.html">Tillbaka till ackord</a>
<a href="../index.html">Tillbaka till startsida</a>
</div>

</body>
Expand Down
34 changes: 10 additions & 24 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,23 @@
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato">
<link REL="stylesheet" TYPE="text/css" href="style.css">
<title>Staffans gehörsapp</title>
<script src='im-tonal.js'></script>
<script src="soundfont-player.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vexflow@4.0.3/build/cjs/vexflow.js"></script>
</head>

<body>
<div class="kol" style="margin: auto">
<p style="text-align: center;" id='chordButtonPar'>
<button style="text-align: center;" class="button" id="chordButton">Spela</button>
<h1>Vad vill du öva på?</h1>
<div class="kol" style="margin: auto; text-align: center; font-family: Lato;">
<p style="text-align: center;" >
<a href="intervoicing/intervoicing.html">Intervoice</a>
</p>
<p style="text-align: center;" id='visaButton'>
<button style="text-align: center;" class="button" id="visaButton">Visa</button>
<p style="text-align: center;" >
<a href="brutnaAckord/brutnaAckord.html">Brutna ackord</a>
</p>
<p style="text-align: center;" id='reload'>
<button style="text-align: center;" class="button" id="reloadButton">Uppdatera</button>
<p style="text-align: center;" >
<a href="ackord/ackord.html">Ackord med färgningar</a>
</p>
<p style="text-align: center;" id='visaAckord'> </p>
</div>

<div id="output" class="kol" style="margin: auto"></div>
<p style="text-align: center; margin: auto" id='visaSkala'> </p>

<div class="kol" style="margin: auto; text-align: center; font-family: Lato;">
<p style="text-align: center;" > </p>
<a href="brutnaAckord/brutnaAckord.html">Öva brutna ackord</a>
</p>
<p style="text-align: center;" > </p>
<a href="intonation/intonation.html">Öva intonation</a>
<p style="text-align: center;" >
<a href="intonation/intonation.html">Intonation</a>
</p>
</div>

</body>
<script src='index.js' ></script>
</html>
18 changes: 18 additions & 0 deletions intervoicing/chords.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"sevenNotes" :
[ [7,3,5]
, [3,7,9]
, [7,3,13]
, [3,13,7,9]
, [7,9,3,5]
, [7,9,3,13]
, [7,9,3,11,13]
, [7,3,11,13]
, [7,3,11]
, [7,1,3,5]
, [3,5,7,9] ],

"eightNotes" :
[ [4,8,11,15]
, [8,4,15,11] ]
}
43 changes: 43 additions & 0 deletions intervoicing/intervoicing.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato">
<link REL="stylesheet" TYPE="text/css" href="../style.css">
<title>Staffans gehörsapp</title>
<script src='../im-tonal.js'></script>
<script src="../soundfont-player.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vexflow@4.0.3/build/cjs/vexflow.js"></script>
</head>

<body>
<form id="ackordtyperForm" style="font-family: Lato;">
<!-- Checkboxes will be added here by JavaScript -->
</form>
<div class="kol" style="margin: auto">
<p style="text-align: center;" id='chordButtonPar'>
<button style="text-align: center;" class="button" id="chordButton">Spela</button>
</p>
<p style="text-align: center;" id='chordButtonNext'>
<button style="text-align: center;" class="button" id="chordButtonNext">Lägg till ton</button>
</p>
<p style="text-align: center;" id='visaButton'>
<button style="text-align: center;" class="button" id="visaButton">Facit</button>
</p>
<p style="text-align: center;" id='reload'>
<button style="text-align: center;" class="button" id="reloadButton">Nytt ackord</button>
</p>
<p style="text-align: center;" id='visaAckord'> </p>
</div>

<div id="output" class="kol" style="margin: auto">
<p style="text-align: center; margin: auto" id='visaSkala'> </p>
</div>
<div style="font-family: Lato; text-align:center">
<a href="../index.html">Tillbaka till startsida</a>
</div>

</body>
<script src='intervoicing.js' ></script>
</html>
Loading

0 comments on commit 896dcf7

Please sign in to comment.