feature: add interactive applets
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
<html>
|
||||
<script src="https://www.50ohm.de/assets/jquery/3.7.1/jquery.min.js"></script>
|
||||
<script src="https://www.50ohm.de/assets/chartjs/4.4.1/chart.min.js"></script>
|
||||
|
||||
<p>
|
||||
Durch Druck auf den nächsten Button, wird das Mikrofon des Browsers
|
||||
aktiviert. Danach kann man das Spektrum der eigenen Sprache betrachten.
|
||||
</p>
|
||||
<p>
|
||||
<button onclick="start()">Mikrofon Einschalten</button>
|
||||
</p>
|
||||
<p>
|
||||
<canvas id="Spectrum" style="max-height:200px;"></canvas>
|
||||
</p>
|
||||
Stärkste Amplitude bei der Frequenz $f$ = <div id="mainfrequency" style="display:inline-block;">0</div> Hz<br>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
spectrum = new Chart("Spectrum", {
|
||||
type: 'scatter',
|
||||
data: {
|
||||
labels: [],
|
||||
datasets: [
|
||||
{
|
||||
fill: false,
|
||||
pointRadius: function(context) {
|
||||
var index = context.dataIndex;
|
||||
var value = context.dataset.data[index];
|
||||
var max = Math.max.apply(null,context.dataset.data);
|
||||
return value == max ? 6 : 0;
|
||||
},
|
||||
lineTension: 0.8,
|
||||
showLine: true,
|
||||
borderColor: function(context) {
|
||||
var index = context.dataIndex;
|
||||
var value = context.dataset.data[index];
|
||||
var max = Math.max.apply(null,context.dataset.data);
|
||||
return value == max ? "#FF756D" : "#00AEDF";
|
||||
},
|
||||
data: [],
|
||||
},
|
||||
]
|
||||
},
|
||||
options: {
|
||||
responsive:true,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false,
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
ticks: {
|
||||
callback: function(value, index, ticks) {
|
||||
return value + "%";
|
||||
}
|
||||
}
|
||||
},
|
||||
x: {
|
||||
min: 0,
|
||||
max: 24000,
|
||||
type: 'logarithmic',
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Frequenz'
|
||||
},
|
||||
ticks: {
|
||||
callback: function(val, index) {
|
||||
return val+"Hz";
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
var initialized = false;
|
||||
var binSize = 0;
|
||||
|
||||
const getBigBinIndex = (frequencyBins) => {
|
||||
let biggestIndex = 0;
|
||||
frequencyBins.forEach((bin, index) => {
|
||||
if (bin > frequencyBins[biggestIndex]) {
|
||||
biggestIndex = index;
|
||||
}
|
||||
});
|
||||
|
||||
return biggestIndex;
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
var fftSize = 2048;
|
||||
var audioContext;
|
||||
|
||||
var analyserNode;
|
||||
var frequencyData;
|
||||
var lastUpdate = 0;
|
||||
|
||||
try {
|
||||
window.AudioContext = window.AudioContext || window.webkitAudioContext;
|
||||
audioContext = new AudioContext();
|
||||
binSize = (audioContext.sampleRate) / fftSize; // Bin Size in Hz
|
||||
} catch (e) {
|
||||
alert('Die Web Audio API wird in diesem Browser leider nicht unterstützt!');
|
||||
}
|
||||
|
||||
const update = (timestamp) => {
|
||||
if (timestamp - lastUpdate > 50) {
|
||||
analyserNode.getByteFrequencyData(frequencyData);
|
||||
const bigBinIndex = getBigBinIndex(frequencyData);
|
||||
const mainFrequencyStart = Math.floor(bigBinIndex * audioContext.sampleRate / fftSize);
|
||||
|
||||
const mainfrequencyDomElement = document.getElementById('mainfrequency');
|
||||
mainfrequencyDomElement.textContent = mainFrequencyStart;
|
||||
|
||||
lastUpdate = timestamp;
|
||||
|
||||
// Reset all values:
|
||||
spectrum.data.datasets[0].data = [];
|
||||
spectrum.data.labels = [];
|
||||
|
||||
// Normalize Apmlitudes:
|
||||
for(let i = 0; i < analyserNode.frequencyBinCount; i++) {
|
||||
// Store Normalized Amplitude
|
||||
spectrum.data.datasets[0].data.push((frequencyData[i]/255)*100);
|
||||
spectrum.data.labels.push(i*binSize);
|
||||
}
|
||||
|
||||
// Update Graphs:
|
||||
spectrum.update();
|
||||
}
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
|
||||
// Acquire microphone access.
|
||||
navigator.mediaDevices.getUserMedia({
|
||||
audio: true,
|
||||
video: false
|
||||
}).then(stream => {
|
||||
var source = audioContext.createMediaStreamSource(stream);
|
||||
analyserNode = audioContext.createAnalyser(source);
|
||||
analyserNode.fftSize = fftSize;
|
||||
audioContext.resume();
|
||||
source.connect(analyserNode);
|
||||
console.log(analyserNode.frequencyBinCount);
|
||||
frequencyData = new Uint8Array(analyserNode.frequencyBinCount)
|
||||
window.requestAnimationFrame(update);
|
||||
});
|
||||
}
|
||||
|
||||
const start = () => {
|
||||
if(initialized == false){
|
||||
init();
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</html>
|
||||
Reference in New Issue
Block a user