161 lines
5.7 KiB
HTML
161 lines
5.7 KiB
HTML
<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> $\unit{\hertz}$<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> |