1
1

More than 1 year has passed since last update.

MIDI.js Soundfontsを使ってみた

Posted at

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>

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();
}

ドレミファソラシド

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);
	}
}

キーボード演奏

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;
		});
	});
}

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1