MIDI.js Soundfontsを使ってみた

https://github.com/gleitz/midi-js-soundfonts

# mp3を鳴らす

```play1.html
<!DOCTYPE html>
<html>
<head></head>

<body>
<p><a href="https://github.com/gleitz/midi-js-soundfonts">
GitHub - gleitz/midi-js-soundfonts: Pre-rendered General MIDI soundfonts that can be used immediately with MIDI.js
</a></p>
<input type="button" value="play" onclick="play();">
<script>

"use strict";

let audio;

onload = function() {
	const soundfont = "https://gleitz.github.io/midi-js-soundfonts/FluidR3_GM/";
	const instrument = "acoustic_grand_piano";
	const note = "C4";
	audio = new Audio(`${soundfont}${instrument}-mp3/${note}.mp3`);
};

function play() {
	audio.play();
}

</script>
</body>
</html>
```

https://jsfiddle.net/19Lav30m/

# mp3をデコード

```play2.js
"use strict";

let ac;
let buffer;

onload = function() {
	ac = new AudioContext();

	const soundfont = "https://gleitz.github.io/midi-js-soundfonts/FluidR3_GM/";
	const instrument = "acoustic_grand_piano";
	const note = "C4";
	const resource = `${soundfont}${instrument}-mp3/${note}.mp3`;

	fetch(resource)
	.then(response => response.arrayBuffer())
	.then(compressed => {
		ac.decodeAudioData(compressed)
		.then(decoded => {
			buffer = decoded;
		});
	});
};

function play() {
	const src = ac.createBufferSource();
	src.buffer = buffer;
	src.connect(ac.destination);
	src.start();
}
```

https://jsfiddle.net/90voexzm/

# ドレミファソラシド

```play3.js
"use strict";

let ac;
const buffers = {};
const notes = ["C4","D4","E4","F4","G4","A4","B4","C5"];

onload = function() {
	ac = new AudioContext();

	for (const note of notes) {
		load(note);
	}
};

function load(note) {
	const soundfont = "https://gleitz.github.io/midi-js-soundfonts/FluidR3_GM/";
	const instrument = "acoustic_grand_piano";
	const resource = `${soundfont}${instrument}-mp3/${note}.mp3`;

	fetch(resource)
	.then(response => response.arrayBuffer())
	.then(compressed => {
		ac.decodeAudioData(compressed)
		.then(decoded => {
			buffers[note] = decoded;
		});
	});
}

function play() {
	const ct = ac.currentTime;
	for (let i = 0; i < notes.length; i++) {
		const note = notes[i];
		const src = ac.createBufferSource();
		src.buffer = buffers[note];
		src.connect(ac.destination);
		src.start(ct + i / 4);
		src.stop(ct + (i+1) / 4);
	}
}
```

https://jsfiddle.net/cpxfu8Lr/

# キーボード演奏

```play4.js
"use strict";

let ac;
const buffers = {};
const sources = {};
const keys = {
	67: "C4",
	86: "D4",
	66: "E4",
	78: "F4",
	77: "G4",
	188: "A4",
	190: "B4",
	191: "C5",
};

onload = function() {
	ac = new AudioContext();

	for (const note of Object.values(keys)) {
		load(note);
	}

	onkeydown = function(event) {
		const note = keys[event.keyCode];
		if (! note) return;
		if (sources[note]) return;

		const src = ac.createBufferSource();
		src.buffer = buffers[note];
		src.connect(ac.destination);
		src.start();
		sources[note] = src;
	};

	onkeyup = function(event) {
		const note = keys[event.keyCode];
		if (! note) return;

		if (sources[note]) {
			sources[note].stop();
			sources[note] = null;
		}
	}
};

function load(note) {
	const soundfont = "https://gleitz.github.io/midi-js-soundfonts/FluidR3_GM/";
	const instrument = "acoustic_grand_piano";
	const resource = `${soundfont}${instrument}-mp3/${note}.mp3`;

	fetch(resource)
	.then(response => response.arrayBuffer())
	.then(compressed => {
		ac.decodeAudioData(compressed)
		.then(decoded => {
			buffers[note] = decoded;
		});
	});
}
```

https://jsfiddle.net/hpjawryt/