-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.html
133 lines (111 loc) · 4.37 KB
/
index.html
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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
/* keyboard ui */
.nlk-half-key {
display: inline-block;
width: 12px;
margin: 1px;
}
.nlk-key {
text-align: center;
width: 24px;
border: 0 none;
margin: 1px;
}
.nlk-white {
background-color: #eee;
color: #111;
}
.nlk-black {
background-color: #111;
color: #eee;
}
#renderedKeyboard {
margin: 20px;
}
/* startup modal */
#startupModal {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255,255,255,0.8);
}
#startupModal p {
text-align: center;
line-height: 100px;
}
#run {
display: block;
margin: 0 auto;
font-size: 24px;
}
</style>
</head>
<body>
<canvas id="osc1" width="2400" height="300" style="width: 1200px; height: 150px;"></canvas>
<div id="currentPatchName"></div>
<div id="renderedKeyboard"></div>
<div id="startupModal">
<p>Plug your MIDI instrument (if any), then click on the button.</p>
<button id="run">Start</button>
</div>
<!-- "fork me on github" ribbon -->
<a href="https://github.com/adrienjoly/webmidi-launchkey-mini"><p style="position: absolute; top: 0; right: 0; border: 0;">Fork me on GitHub</p></a>
<script src="keyboard-input.js"></script> <!-- imports initKeyboardInput() -->
<script src="webmidi-reader.js"></script> <!-- imports initWebMidiReader() -->
<script src="launchkey-state.js"></script> <!-- imports initLaunchkeyState() -->
<script src="render.js"></script> <!-- imports initKeyboardRenderer() -->
<script src="lib/riffwave.js"></script> <!-- imports RIFFWAVE -->
<script src="lib/sfxr.js"></script> <!-- imports SoundEffect -->
<script src="lib/scope.js"></script> <!-- imports Scope -->
<script src="sound-generator.js"></script> <!-- imports initSoundGenerator() -->
<script src="synth.js"></script> <!-- imports initSynth() -->
<script src="oscilloscope.js"></script> <!-- imports initOscilloscope() -->
<script src="note-player.js"></script> <!-- imports initNotePlayer() -->
<script>
// 0. Setup the UI
const keyboardDiv = document.getElementById('renderedKeyboard');
const keyboardUI = initKeyboardRenderer();
const renderKeyboardUI = (state) => keyboardDiv.innerHTML = keyboardUI.renderHTML(state);
renderKeyboardUI({}); // render with initial state
const patchNameDiv = document.getElementById('currentPatchName');
const onPatchChange = ({ name, type }) => patchNameDiv.innerHTML = `Patch / waveform: ${name || type}`;
// just to activate WebAudio after a user gesture
document.getElementById('run').onclick = function() {
// 1. Setup outputs
const audioContext = new (window.AudioContext || window.webkitAudioContext);
const oscilloscope = initOscilloscope({
Scope,
audioContext,
canvas: document.querySelector('#osc1')
});
const synth = initSynth({ audioContext, onPatchChange }); // creates an audio context for one "channel"
const soundGenerator = initSoundGenerator({ SoundEffect });
const notePlayer = initNotePlayer({ synth, soundGenerator, oscilloscope });
// 2. Pipe MIDI messages to synth and UI
const keyboardState = initLaunchkeyState();
function handleParsedMidiMessage(message) {
renderKeyboardUI(keyboardState.mutateFromParsedMidiMessage(message));
if (message.note) {
notePlayer.playParsedMidiMessage(message);
}
}
// 3. Setup and plug inputs
const computerKeyboard = initKeyboardInput();
const midiKeyboard = initWebMidiReader();
computerKeyboard.onKeyEvents((parsedMidiMessage) => handleParsedMidiMessage(parsedMidiMessage));
midiKeyboard.onMidiMessage((midiMessage) =>
handleParsedMidiMessage(midiKeyboard.parseMidiMessage(midiMessage))
);
// 4. Remove the startup modal
const startupModal = document.getElementById('startupModal');
startupModal.parentNode.removeChild(startupModal);
};
</script>
</body>
</html>