-
Notifications
You must be signed in to change notification settings - Fork 0
/
midi.html
125 lines (107 loc) · 4.52 KB
/
midi.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
<!doctype html>
<html>
<head>
<title>Web MIDI monosynth using Web Audio</title>
<!-- Set up Web MIDI polyfill -->
<script src='js/cwilso.js'></script>
<script>
/* Copyright 2013 Chris Wilson
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var context=null; // the Web Audio "context" object
var midiAccess=null; // the MIDIAccess object.
var oscillator=null; // the single oscillator
var envelope=null; // the envelope for the single oscillator
var attack=0.05; // attack speed
var release=0.05; // release speed
var portamento=0.05; // portamento/glide speed
var activeNotes = []; // the stack of actively-pressed keys
window.addEventListener('load', function() {
// patch up prefixes
window.AudioContext=window.AudioContext||window.webkitAudioContext;
context = new AudioContext();
if (navigator.requestMIDIAccess)
navigator.requestMIDIAccess().then( onMIDIInit, onMIDIReject );
else
alert("No MIDI support present in your browser. You're gonna have a bad time.")
// set up the basic oscillator chain, muted to begin with.
oscillator = context.createOscillator();
oscillator.frequency.setValueAtTime(110, 0);
envelope = context.createGain();
oscillator.connect(envelope);
envelope.connect(context.destination);
envelope.gain.value = 0.0; // Mute the sound
oscillator.start(0); // Go ahead and start up the oscillator
} );
function hookUpMIDIInput() {
var haveAtLeastOneDevice=false;
var inputs=midiAccess.inputs.values();
for ( var input = inputs.next(); input && !input.done; input = inputs.next()) {
input.value.onmidimessage = MIDIMessageEventHandler;
haveAtLeastOneDevice = true;
}
var badtime = document.getElementById("badtime");
if (badtime)
badtime.style.visibility = haveAtLeastOneDevice ?
"hidden" : "visible";
}
function onMIDIInit(midi) {
midiAccess = midi;
hookUpMIDIInput();
midiAccess.onstatechange=hookUpMIDIInput;
}
function onMIDIReject(err) {
alert("The MIDI system failed to start. You're gonna have a bad time.");
}
function MIDIMessageEventHandler(event) {
// Mask off the lower nibble (MIDI channel, which we don't care about)
switch (event.data[0] & 0xf0) {
case 0x90:
if (event.data[2]!=0) { // if velocity != 0, this is a note-on message
noteOn(event.data[1]);
return;
}
// if velocity == 0, fall thru: it's a note-off. MIDI's weird, ya'll.
case 0x80:
noteOff(event.data[1]);
return;
}
}
function frequencyFromNoteNumber( note ) {
return 440 * Math.pow(2,(note-69)/12);
}
function noteOn(noteNumber) {
activeNotes.push( noteNumber );
oscillator.frequency.cancelScheduledValues(0);
oscillator.frequency.setTargetAtTime( frequencyFromNoteNumber(noteNumber), 0, portamento );
envelope.gain.cancelScheduledValues(0);
envelope.gain.setTargetAtTime(1.0, 0, attack);
}
function noteOff(noteNumber) {
var position = activeNotes.indexOf(noteNumber);
if (position!=-1) {
activeNotes.splice(position,1);
}
if (activeNotes.length==0) { // shut off the envelope
envelope.gain.cancelScheduledValues(0);
envelope.gain.setTargetAtTime(0.0, 0, release );
} else {
oscillator.frequency.cancelScheduledValues(0);
oscillator.frequency.setTargetAtTime( frequencyFromNoteNumber(activeNotes[activeNotes.length-1]), 0, portamento );
}
}
</script>
</head>
<body>
This example uses Web MIDI input (from all available ports and channels) to drive a Web Audio monophonic synthesizer. There is no UI. <a href="http://github.com/cwilso/monosynth">Source available on github.</a>
<h2 id="badtime" style="visibility:hidden">No MIDI input devices present. You're gonna have a bad time.</h2>
</body>
</html>