abcjs / examples /tempo.html
KEXEL's picture
Upload 337 files
af6912c verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="examples-styles.css"/>
<link rel="icon" href="favicon.ico" type="image/x-icon"/>
<title>abcjs: Tempo Demo</title>
<script src="../dist/abcjs-basic.js" type="text/javascript"></script>
<script type="text/javascript">
var abc = "T: Cooley's\n" +
"M: 4/4\n" +
"L: 1/8\n" +
"R: reel\n" +
"K: Emin\n" +
"|:D2|EB{c}BA B2 EB|~B2 AB dBAG|FDAD BDAD|FDAD dAFD|\n" +
"EBBA B2 EB|B2 AB defg|afe^c dBAF|DEFD E2:|\n" +
"|:gf|eB B2 efge|eB B2 gedB|A2 FA DAFA|A2 FA defg|\n" +
"eB B2 eBgB|eB B2 defg|afe^c dBAF|DEFD E2:|";
var abcQ = "T: Cooley's\n" +
"M: 4/4\n" +
"L: 1/8\n" +
"R: reel\n" +
"Q: 1/4=150\n" +
"K: Emin\n" +
"|:D2|EB{c}BA B2 EB|~B2 AB dBAG|FDAD BDAD|FDAD dAFD|\n" +
"EBBA B2 EB|B2 AB defg|afe^c dBAF|DEFD E2:|\n" +
"|:gf|eB B2 efge|eB B2 gedB|A2 FA DAFA|A2 FA defg|\n" +
"eB B2 eBgB|eB B2 defg|afe^c dBAF|DEFD E2:|";
function load() {
var visualObjQ = ABCJS.renderAbc("paper-q", abcQ, {
responsive: "resize" })[0];
var visualObjP = ABCJS.renderAbc("paper-param", abcQ, {
responsive: "resize" })[0];
var visualObjD = ABCJS.renderAbc("paper-default", abc, {
responsive: "resize" })[0];
var visualObjDQ = ABCJS.renderAbc("paper-default-q", abcQ, {
responsive: "resize" })[0];
var visualObjs = {
q: visualObjQ,
param: visualObjP,
default: visualObjD,
defaultQ: visualObjDQ,
}
var options = {
q: { visualObj: visualObjQ },
param: { visualObj: visualObjP, options: { qpm: 100 } },
default: { visualObj: visualObjD, options: { defaultQpm: 60 } },
defaultQ: { visualObj: visualObjDQ, options: { defaultQpm: 60 } },
}
// This object is the class that will contain the buffer
var midiBuffer;
var startAudioButton = document.querySelectorAll(".activate-audio");
var stopAudioButton = document.querySelectorAll(".stop-audio");
for (var i = 0; i < startAudioButton.length; i++) {
startAudioButton[i].addEventListener("click", startAudio);
}
for (i = 0; i < stopAudioButton.length; i++) {
stopAudioButton[i].addEventListener("click", stopAudio);
}
function startAudio() {
var type = this.dataset.type;
this.setAttribute("style", "display:none;");
if (ABCJS.synth.supportsAudio()) {
var stopButton = document.querySelector('.stop-audio[data-type="' + type + '"]');
stopButton.setAttribute("style", "");
window.AudioContext = window.AudioContext ||
window.webkitAudioContext ||
navigator.mozAudioContext ||
navigator.msAudioContext;
var audioContext = new window.AudioContext();
audioContext.resume().then(function () {
// In theory the AC shouldn't start suspended because it is being initialized in a click handler, but iOS seems to anyway.
midiBuffer = new ABCJS.synth.CreateSynth();
options[type].audioContext = audioContext;
return midiBuffer.init(options[type]).then(function (response) {
return midiBuffer.prime();
}).then(function () {
midiBuffer.start();
return Promise.resolve();
}).catch(function (error) {
if (error.status === "NotSupported") {
stopButton.setAttribute("style", "display:none;");
var audioError = document.querySelector(".audio-error");
audioError.setAttribute("style", "");
} else
console.warn("synth error", error);
});
});
} else {
var audioError = document.querySelector(".audio-error");
audioError.setAttribute("style", "");
}
}
function stopAudio() {
var type = this.dataset.type;
var startButton = document.querySelector('.activate-audio[data-type="' + type + '"]');
startButton.setAttribute("style", "");
this.setAttribute("style", "display:none;");
if (midiBuffer)
midiBuffer.stop();
}
}
</script>
</head>
<body onload="load()">
<main>
<header>
<img src="https://paulrosen.github.io/abcjs/img/abcjs_comp_extended_08.svg" alt="abcjs logo">
<h1>Tempo</h1>
</header>
<div class="container">
<p>Tempo can be set in various ways: it can be specified in the ABC string, it can be specified in the
parameters passed in, or a default can be set that is only used if the tempo is not in the string.
</p>
<div class='audio-error' style="display:none;">Audio is not supported in this browser.</div>
<h2>Specified in the ABC String</h2>
<p>The tempo is set using the <span class="code">Q: 1/4=150</span> line.</p>
<div id="paper-q"></div>
<div class="row">
<div>
<button class="activate-audio" data-type="q">Activate Audio Context And Play</button>
<button class="stop-audio" data-type="q" style="display:none;">Stop Audio</button>
</div>
</div>
<h2>Passed in as a Parameter</h2>
<p>The tempo is set using the <span class="code">{ qpm: 100 }</span> attribute. Notice that this overrides the tempo in the <span class="code">Q:</span> line.</p>
<div id="paper-param"></div>
<div class="row">
<div>
<button class="activate-audio" data-type="param">Activate Audio Context And Play</button>
<button class="stop-audio" data-type="param" style="display:none;">Stop Audio</button>
</div>
</div>
<h2>Using a default</h2>
<p>The tempo is set using the <span class="code">{ defaultQpm: 60 }</span> attribute. Notice there is no <span class="code">Q:</span> line.</p>
<div id="paper-default"></div>
<div class="row">
<div>
<button class="activate-audio" data-type="default">Activate Audio Context And Play</button>
<button class="stop-audio" data-type="default" style="display:none;">Stop Audio</button>
</div>
</div>
<p>The tempo is set using the <span class="code">{ defaultQpm: 60 }</span> attribute. However, there is a <span class="code">Q:</span> line, so that takes precedence.</p>
<div id="paper-default-q"></div>
<div class="row">
<div>
<button class="activate-audio" data-type="defaultQ">Activate Audio Context And Play</button>
<button class="stop-audio" data-type="defaultQ" style="display:none;">Stop Audio</button>
</div>
</div>
</div>
</main>
</body>
</html>