LoginSignup
2
0

JavaScriptでサウンド再生

Posted at

Oscillator

簡単。

pipo1.html
<!DOCTYPE html>
<html>
<head></head>

<body>
<input type="button" value="play" onclick="play();" />
<script>

"use strict";

let ac;
let gain;

onload = function() {
	ac = new AudioContext();
	gain = ac.createGain();
	gain.gain.value = 0.1;
	gain.connect(ac.destination);
};

function play() {
	const ct = ac.currentTime;
	for (let i = 0; i < 2; i++) {
		const osc = ac.createOscillator();
		osc.type = "square";
		osc.frequency.value = 1000 * (2 - i);
		osc.connect(gain);
		osc.start(ct + i / 4);
		osc.stop(ct + (i + 1) / 4);
	}
}

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

BufferSource

任意の波形を再生できる。

pipo2.js
"use strict";

let ac;
let gain;

onload = function() {
	ac = new AudioContext();
	gain = ac.createGain();
	gain.gain.value = 0.1;
	gain.connect(ac.destination);
};

function play() {
	const buf = ac.createBuffer(1, 4000, 8000);
	const data = buf.getChannelData(0);
	for (let i = 0; i < 2000; i++) {
		data[i] = (i & 2) ? 1 : -1;
	}
	for (let i = 2000; i < 4000; i++) {
		data[i] = (i & 4) ? 1 : -1;
	}

	const src = ac.createBufferSource();
	src.buffer = buf;
	src.connect(gain);
	src.start();
}

wavファイル

wavファイルをダウンロードできる。

pipo3.js
"use strict";

let objUrl;
let view;
let offset;

onload = function() {
	const datalen = 4000;
	const wave = new ArrayBuffer(44 + datalen);
	view = new DataView(wave);
	offset = 0;

	writeFcc("RIFF");
	write(4, 36 + datalen);
	writeFcc("WAVE");
	writeFcc("fmt ");
	write(4, 16);
	write(2, 1);
	write(2, 1);
	write(4, 8000);
	write(4, 8000);
	write(2, 1);
	write(2, 8);
	writeFcc("data");
	write(4, datalen);

	const data = new Uint8Array(wave, offset);
	for (let i = 0; i < 2000; i++) {
		data[i] = (i & 2) ? 0x90 : 0x70;
	}
	for (let i = 2000; i < 4000; i++) {
		data[i] = (i & 4) ? 0x90 : 0x70;
	}

	const blob = new Blob([wave], { type:"audio/wav" });
	objUrl = URL.createObjectURL(blob);
};

function writeFcc(str) {
	for (let i = 0; i < 4; i++) {
		view.setUint8(offset++, str.charCodeAt(i));
	}
}

function write(len, val) {
	if (len == 2) view.setUint16(offset, val, true);
	if (len == 4) view.setUint32(offset, val, true);
	offset += len;
}

function play() {
	const sound = new Audio(objUrl);
	sound.play();
}

function download() {
	const a = document.createElement("a");
	a.download = "pipo.wav";
	a.href = objUrl;
	a.click();
}

2
0
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
2
0