<div class="wrapper">
<div id="chord-diagram"></div>
<audio id="jam-track" src="https://myguitarpal.com/wp-content/uploads/2014/09/12-Bar-Blues-in-A-Version-1.mp3" controls></audio>
<br>
<label>Beat: </label>
<div class="data" id="beat"></div>
<label>Measure: </label>
<div class="data" id="measure"></div>
<label>Section: </label>
<div class="data" id="section"></div>
<label>Chord: </label>
<div class="data" id="chord"></div>
<div id="chord-progression"></div>
</div>
.wrapper {
max-width: 400px;
}
#chord-progression {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid lightgray;
}
.section {
margin-bottom: 20px;
display: none;
}
.measure {
width: 25%;
display: inline-block;
}
.m-line {
float: right;
width: 10px;
}
audio {
width: 100%;
}
.data {
display: inline;
margin-right: 10px;
}
label {
font-weight: bold;
}
(function(){
// beats per minute
var BPM = 117;
// beats per second
var BPS = 60 / BPM;
// measures used for count in
var measuresCount = 1;
// time the track starts
var offsetSeconds = 0.2;
// time signature
var timeSigTop = 4;
var timeSigBottom = 4;
var sectionOne = ['A7', 'A7', 'A7', 'A7', 'D7', 'D7', 'A7', 'A7', 'E7', 'D7', 'A7', 'A7'];
var sectionTwo = ['A7', 'A7', 'A7', 'A7', 'D7', 'D7', 'A7', 'A7', 'E7', 'D7', 'A7', 'A7', 'A7', 'A7', 'A7', 'A7', 'A7', 'A7'];
var chordProgression = [
sectionOne,
sectionOne,
sectionOne,
sectionTwo
];
var currentSection;
var currentChord;
var cleanMeasure;
var measureBeat;
// every time the ontimeupdate event fires, run the jam station
var audio = document.getElementById('jam-track');
audio.ontimeupdate = function() {
jamStation();
};
function jamStation() {
var beat = (audio.currentTime - offsetSeconds + BPS) / BPS;
var measure = (beat - 1) / timeSigTop;
// round down for beat and measure
var cleanBeat = Math.floor(beat);
cleanMeasure = Math.floor(measure);
// find the current beat within the measure
measureBeat = ((cleanBeat - 1) % timeSigTop) + 1;
// set the current chord and section. s = section, m = measure
if (cleanMeasure > 0) {
// find the current section
var count = 0;
var br = false;
for(var s = 0; s < chordProgression.length; s++) {
for(var m = 0; m < chordProgression[s].length; m++) {
count++;
if (cleanMeasure == count) {
currentSection = s + 1;
currentChord = chordProgression[s][m];
br = true;
break;
}
}
if (br === true) {
break;
}
}
} else {
currentSection = null;
currentChord = null;
}
// display the jam staion and it's data
renderJamStation();
}
function renderJamStation() {
// show the beat within the measure, not overall
document.getElementById('beat').innerHTML = measureBeat;
// show the current measure, but only if the jam track is past the count in measures
var measureElem = document.getElementById('measure');
// only show the current measure if it's > 0
if (cleanMeasure > 0) {
measureElem.innerHTML = cleanMeasure;
} else {
measureElem.innerHTML = '';
}
// show the section number
document.getElementById('section').innerHTML = currentSection;
// show the current chord name
document.getElementById('chord').innerHTML = currentChord;
// hide all sections before displaying only the section we want to see
var allSections = document.getElementsByClassName('section');
for (var i = 0; i < allSections.length; i++) {
allSections[i].style.display = 'none';
}
// show the currently playing section
if (currentSection !== null) {
document.getElementById('section-' + currentSection).style.display = 'block';
} else {
allSections[0].style.display = 'block';
}
// style the current chord in the chord progression
if (cleanMeasure > 0) {
// style all measures black
var measures = document.getElementsByClassName('measure');
for (i = 0; i < measures.length; i++) {
measures[i].style.color = 'black';
}
// style current measure red
document.getElementById('measure-' + cleanMeasure).style.color = 'red';
}
}
// take the chordProgression array and render the HTML
function renderChordProgression() {
var progression = document.getElementById('chord-progression');
// make the sections
for (s = 0; s < chordProgression.length; s++) {
progression.innerHTML += '<div class="section" id="section-' + (s + 1) + '"></div>';
}
var count = 0;
for (var s = 0; s < chordProgression.length; s++) {
for (var m = 0; m < chordProgression[s].length; m++) {
count++;
var section = document.getElementById('section-' + (s + 1));
section.innerHTML += '<div class="measure" id="measure-' + count + '">'
+ chordProgression[s][m]
+ '<div class="m-line">|</div></div>';
}
}
}
renderChordProgression();
jamStation();
}());
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.