xxxxxxxxxx
146
//Harmonic Flow
//created by Mirette Dahab
//November 17,2024
//Created for a Harmony study for The Code of Music
//version 3
var synth = new Tone.PolySynth(4, Tone.Synth).toMaster();
Tone.Transport.bpm.value = 120;
//definition of all 12 major chords
let majorChords = {
"C": ["C3", "E3", "G3"],
"G": ["B3", "D4", "G3"],
"D": ["A3", "D4", "F#3"],
"A": ["A3", "C#4", "E4"],
"E": ["G#3", "B3", "E4"],
"B": ["D#4", "B3", "F#4"],
"F#": ["C#4", "A#3", "F#4"],
"C#": ["C#4", "F4", "G#3"],
"Ab": ["C4", "D#4", "G#3"],
"Eb": ["G3", "D#4", "A#3"],
"Bb": ["D4", "F4", "A#3"],
"F": ["C4", "A3", "F3"],
};
let chordNames = Object.keys(majorChords); //storing chord names
let currentChordIndex = 0;
//arpeggio
var arpeggio = new Tone.Pattern(function (time, chord) {
synth.triggerAttackRelease(chord, "4n", time);
});
arpeggio.values = majorChords[chordNames[currentChordIndex]];
arpeggio.pattern = "random";
//definition of colors
let noteColors = {
"C": [255, 89, 191],
"C#": [168, 17, 110],
"D": [255, 104, 113],
"D#": [78, 26, 61],
"E": [149, 107, 235],
"F": [183, 216, 192],
"F#": [120, 137, 125],
"G": [223, 172, 144],
"G#": [115, 82, 64],
"A": [136, 151, 235],
"B": [237, 217, 139],
"A#": [76, 82, 112],
};
function preload() {
img = loadImage("pianoNotes.png");
}
function setup() {
createCanvas(600, 600);
Tone.Transport.start();
arpeggio.start();
}
function draw() {
background(242, 233, 245, 80);
let currentChordName = chordNames[currentChordIndex];
let currentChord = [new Set(arpeggio.values)];
if (currentChord) {
//for each note in the chord, draw multiple flowing lines
for (let i = 0; i < currentChord.length; i++) {
let note = currentChord[i].replace(/[0-9]/g, ""); //strip octave number
let baseColor = noteColors[note];
for (let j = 0; j < 10; j++) {
stroke(
baseColor[0] + random(-20, 20),
baseColor[1] + random(-20, 20),
baseColor[2] + random(-20, 20),
150 //transperancy so that lines blend well
);
strokeWeight(1 + j * 0.1); //gradually increasing thickness
noFill();
beginShape();
for (let x = 0; x < width; x += 10) {
// Perlin noise
let y = noise(
(x + j * 20) * 0.01,
i * 0.1,
frameCount * 0.01 + j * 0.05
) * height;
vertex(x, y);
}
endShape();
}
}
//displaying the Chord Name
textSize(600);
noStroke();
fill(126, 111, 130, 7);
text(currentChordName, -50, height);
//INSTRUCTIONS
fill(90);
noStroke();
ellipse(25, 25, 20);
fill(242, 233, 245);
textSize(14);
text("i", 23, 30);
if (mouseX > 15 && mouseX < 35 && mouseY > 15 && mouseY < 35) {
fill(242, 233, 245);
strokeWeight(8);
stroke(126, 111, 130);
rect(25, 15, 550, 420, 20);
fill(0);
noStroke();
textSize(28);
text("Instructions", 220, 58);
textSize(16);
text("- Click on the screen once to enable chord changes.", 50, 100);
text("- Press the up and down keys to alternate between different chords.", 50, 130);
text("- Press spacebar to play the triad.", 50, 160);
text("- Each note in the chord is assigned a unique color as follows:", 50, 190);
image(img, 135, 210, 320, 210);
}
}
}
function keyPressed() {
if (keyCode === UP_ARROW) {
currentChordIndex = (currentChordIndex + 1) % chordNames.length;
let newChord = majorChords[chordNames[currentChordIndex]];
arpeggio.values = newChord;
} else if (keyCode === DOWN_ARROW) {
currentChordIndex =
(currentChordIndex - 1 + chordNames.length) % chordNames.length;
let newChord = majorChords[chordNames[currentChordIndex]];
arpeggio.values = newChord;
} else if (keyCode === 32) { // Spacebar pressed
let currentChord = majorChords[chordNames[currentChordIndex]]; // Get the current chord
synth.triggerAttackRelease(currentChord, "8n"); // Play the triad as a chord
}
}