File size: 5,025 Bytes
af6912c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<!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: Modify Synth Input Demo</title>

	<style>
		main {
			max-width: 770px;
			margin: 0 auto;
		}
		.abcjs-cursor {
			stroke: red;
		}
	</style>

	<script src="../dist/abcjs-basic.js" type="text/javascript"></script>
	<script type="text/javascript">
		var abc = "T: Cooley's\n" +
			"%%barnumbers 1\n" +
			"M: 4/4\n" +
			"L: 1/8\n" +
			"Q: 1/4=120\n" +
			"R: reel\n" +
			"K: Emin\n" +
			"EBBA B2 EB|~B2 AB dBAG|FDAD BDAD|FDAD dAFD|\n" +
			"EBBA B2 EB|B2 AB defg|afe^c dBAF|DEFD E2 gf|\n" +
			"|eB B2 efge|eB B2 gedB|A2 FA DAFA|A2 FA defg|\n" +
			"eB B2 eBgB|eB B2 defg|afe^c dBAF|DEFD E2 D2||";

		var synth = new ABCJS.synth.CreateSynth();

		function load() {
			// First draw the music - this supplies an object that has a lot of information about how to create the synth.
			// NOTE: If you want just the sound without showing the music, use "*" instead of "paper" in the renderAbc call.
			var visualObj = ABCJS.renderAbc("paper", abc, {
				responsive: "resize" })[0];

			var startAudioButton = document.querySelector(".activate-audio");
			var stopAudioButton = document.querySelector(".stop-audio");
			var explanationDiv = document.querySelector(".suspend-explanation");

			startAudioButton.addEventListener("click", function() {
				startAudioButton.setAttribute("style", "display:none;");
				explanationDiv.setAttribute("style", "opacity: 0;");
				if (ABCJS.synth.supportsAudio()) {
					stopAudioButton.setAttribute("style", "");

					// An audio context is needed - this can be passed in for two reasons:
					// 1) So that you can share this audio context with other elements on your page.
					// 2) So that you can create it during a user interaction so that the browser doesn't block the sound.
					// Setting this is optional - if you don't set an audioContext, then abcjs will create one.
					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.

						synth.init({
							audioContext: audioContext,
							visualObj: visualObj,
							options: {
								sequenceCallback: sequenceCallback
							}
						}).then(function () {
							synth.prime().then(function () {
								synth.start();
							});
						}).catch(function (error) {
							console.log("Audio Failed", error);
						});
					});
				} else {
					var audioError = document.querySelector(".audio-error");
					audioError.setAttribute("style", "");
				}
			});

			stopAudioButton.addEventListener("click", function() {
				startAudioButton.setAttribute("style", "");
				explanationDiv.setAttribute("style", "");
				stopAudioButton.setAttribute("style", "display:none;");
				synth.stop();
			});

			function sequenceCallback(tracks) {
				// The beats are 0.25 long so the amount of swing needs to be between 0 and 0.125,
				// but practically it needs to be a bit smaller so that it doesn't sound like a grace note.
				var swing = 0.1 - 0.1 / document.getElementById("swing").value;
				document.getElementById("coefficient").innerText = swing;
				var track = tracks[0];
				for (var i = 0; i < track.length; i++) {
					var event = track[i];
					if (event.start % 0.25) {
						// This is the off beat
						event.start += swing;
					} else {
						// This is the beat
						event.end += swing;
					}
				}
			}
		}
	</script>
</head>
<body onload="load()">
  <header>
    <img src="https://paulrosen.github.io/abcjs/img/abcjs_comp_extended_08.svg" alt="abcjs logo">
    <h1>Modify Synth Input</h1>
  </header>
  <div class="container">
    <main> 
      <p>Demonstration of changing the synth on the fly if you want to make adjustments.</p>
      <p>This example adds some "swing" to the tune.</p>
        <p><label>Amount of swing (1 to 6): <input id="swing" type="number" min="1" max="6" value="2"></label></p>
        <p><label>Calculated swing coefficient:</label> <code id="coefficient">??</code></p>
      <div id="paper"></div>
      <p class="suspend-explanation">Browsers won't allow audio to work unless the audio is started in response to a user action. This prevents auto-playing web sites. Therefore, the
        following button is needed to do the initialization:</p>
      <button class="activate-audio">Activate Audio Context And Play</button>
      <button class="stop-audio" style="display:none;">Stop Audio</button>
      <div class='audio-error' style="display:none;">Audio is not supported in this browser.</div>
    </main>
  </div>
</body>
</html>