Experiment - WebAudio API mit Visualisierung

von Alexander Schwirjow

Ein kleiner Frankenstein, gemischt aus StackOverflow, altem Code und was sonst noch so alles in Sinn kam. Lautstärke aufdrehen und mit ASDFGH spielen. Nothing Else Matters beginnt übrigens mit h,d,s,a,s,d h,d,s,a,s,d h,d,s,a,s,d h,d,s,a,s - weiter kommt man nicht wirklich.

Quellen: stackoverflow.com, mein Gehirn und Google

CSS

svg {
	display: inline-block;
	stroke-width: 4;
	fill: none;
	padding: 10px;
	width: 100%;
}

HTML

<svg height="200" width="1080" viewbox="0 0 1080 200" preserveAspectRatio="none"><polygon/></svg>

JavaScript

// Global variables
window.tone = 0.1;
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var svg = document.querySelector('svg');
var polygon = svg.querySelector('polygon');
var counter = 0;
var width = svg.getAttribute('width');
var height = svg.getAttribute('height')/2;

// Populate polygon
function move(amplitude, frequency, length, i){
	var points = [0,amplitude*2];
	var width = length;
	var x = 0, y;
	while (x++ <= width) {
		y = Math.sin(x*frequency+i);
		points.push([(x),(y*amplitude/2 + amplitude/2)].join(' '));
	}
	points.push([length,amplitude*2].join(' '));
	points.push([0,amplitude*2].join(' '));
	return points;
}
// Repeat animation
function draw(){
	var c = ++counter/20;
	polygon.setAttribute('points', move(height,window.tone,width,c));
	svg.setAttribute('stroke',`hsl(${c*10},100%,50%)`);
	requestAnimationFrame(draw);
}
draw();
// Play wave
function playSound(arr) {
    var buf = new Float32Array(arr.length);
    for (var i = 0; i < arr.length; i++) {
    	buf[i] = arr[i];
    }
    var buffer = context.createBuffer(1, buf.length, context.sampleRate);
    buffer.copyToChannel(buf, 0);
    var source = context.createBufferSource();
    source.buffer = buffer;
    source.connect(context.destination);
    source.start(0);
}
// Calculate wave
function sineWaveAt(sampleNumber, tone) {
    var sampleFreq = context.sampleRate / tone;
    return Math.sin(sampleNumber / (sampleFreq / (Math.PI*2)));
}
// Create wave and play it
function playNote(tone) {
	var arr = [], volume = 0.2, seconds = 0.3;
	for (var i = 0; i < context.sampleRate * seconds; i++) {
        arr[i] = sineWaveAt(i, tone) * volume;
    }
    window.tone = Math.round(1000/tone);
    playSound(arr);
}
// Event listeners
window.addEventListener('keydown', function(e) {
	e = e || window.event;
	/*
	65 = a = E = 329.63
	83 = s = B = 246.94
	68 = d = G = 196.00
	70 = f = D = 146.83
	71 = g = A = 110.00
	72 = h = E = 82.41
	*/
	switch (e.keyCode) {
		case 65: playNote(329.63);
		break;
		case 83: playNote(246.94);
		break;
		case 68: playNote(196.00);
		break;
		case 70: playNote(146.83);
		break;
		case 71: playNote(110.00);
		break;
		case 72: playNote(82.41);
		break;
	}
}, false);
window.addEventListener('keyup', function() {
	window.tone = 0.1;
}, false);

Zurück