xorg1990
New member
Hi, ich benötige für mein QRSSB Projekt eine Tone Erkennung, das macht man normalerwise mit den Görtzel Algorithmus
https://en.wikipedia.org/wiki/Goertzel_algorithm
Passenderweise gibt es sowas in JS schon.
https://github.com/Ravenstine/goertzeljs
Problem ist ich blicke da nicht ganz durch.
Ich möchte nach den Frequenzen 700,800 und 900 Hz suchen.
Erhalten tue ich in Goerzel.energies ein Object mit:
{
700 : float
800 : float
900 : flaot
}
Jetzt ist die frage wie groß müssen die Werte sein das man sagen kann 800Hz true??
Nutze ich den peak filter erhallte ich willkürlich true oder false aus Ausgabe. Obwohl nichts an die Soundkarte angeschlossen ist, erseiden ich Setze den sensitivity Wert auf 100.
Gebe ich ein 800Hz Sinus in die Soundkarte rein ändert sich daran nichts es ist einfach nur willkürlich.
Das mit den downsapling verstehe ich auch nicht so recht
In goertzeljs L116 steht
downSampledBufferLength = bufferLength / downSampleRate;
https://github.com/Ravenstine/goertzeljs/blob/master/build/goertzel.js#L116
Ja was nun? Ist nun ein Downsample Faktor gemeint ( z.b Faktor 2(Hälfte weniger) oder eine SampleRate zb 8000 Hz??
Geschrieben steht auch:
Wenn der Algorithmus integer verlangt dann hätte ich doch die Umwandlung in processSample gemacht, ohne das der zu nutzende User was davon mitbekommt
Meine Test Implementierung sieht so aus:
Zum testen nehme ich Online Tone Generator - Free, Simple and Easy to Use.
Gehe dann mit eine klinke zu klinke kabel vom Laptop zum PC.
https://en.wikipedia.org/wiki/Goertzel_algorithm
Passenderweise gibt es sowas in JS schon.
https://github.com/Ravenstine/goertzeljs
Problem ist ich blicke da nicht ganz durch.
Ich möchte nach den Frequenzen 700,800 und 900 Hz suchen.
Erhalten tue ich in Goerzel.energies ein Object mit:
{
700 : float
800 : float
900 : flaot
}
Jetzt ist die frage wie groß müssen die Werte sein das man sagen kann 800Hz true??
Nutze ich den peak filter erhallte ich willkürlich true oder false aus Ausgabe. Obwohl nichts an die Soundkarte angeschlossen ist, erseiden ich Setze den sensitivity Wert auf 100.
Gebe ich ein 800Hz Sinus in die Soundkarte rein ändert sich daran nichts es ist einfach nur willkürlich.
Das mit den downsapling verstehe ich auch nicht so recht
The downsampleRate value decides how much the buffers are downsampled(by skipping every Nth sample). Default setting is 1.
Habe ich gemacht.See dtmf.js on how samples can be downsampled.
In goertzeljs L116 steht
downSampledBufferLength = bufferLength / downSampleRate;
https://github.com/Ravenstine/goertzeljs/blob/master/build/goertzel.js#L116
Ja was nun? Ist nun ein Downsample Faktor gemeint ( z.b Faktor 2(Hälfte weniger) oder eine SampleRate zb 8000 Hz??
Geschrieben steht auch:
#var buffer = [...]; // array of int samples
Wenn der Algorithmus integer verlangt dann hätte ich doch die Umwandlung in processSample gemacht, ohne das der zu nutzende User was davon mitbekommt
Meine Test Implementierung sieht so aus:
Code:
<!DOCTYPE html>
<html>
<head>
<title>görtzel_test</title>
<script src="goertzel.js"></script>
<script type="text/javascript">
function run(){
function calcGoertzelRates(AudioRate){
switch(AudioRate){
case 22050 : return [Math.round(AudioRate/10),10];
break;
case 88200 : return [Math.round(AudioRate/10),10];
break;
case 48000 : return [Math.round(AudioRate/10),10];
break;
case 24000 : return [Math.round(AudioRate/10),10];
break;
case 96000 : return [Math.round(AudioRate/24),24];
break;
case 192000 : return [Math.round(AudioRate/40),40];
break;
default: return [Math.round(AudioRate/10),10];//44100Hz
}
}
var scriptNodes = {};
var keep = (function() {
var nextNodeID = 1;
return function(node) {
node.id = node.id || (nextNodeID++);
scriptNodes[node.id] = node;
return node;
};
}());
navigator.getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
var audioCtx = new(window.AudioContext || window.webkitAudioContext || mozAudioContext || oAudioContext || msAudioContext)();
var processor = keep((audioCtx.createScriptProcessor || audioCtx.createJavaScriptNode).call(audioCtx, 8192, 1, 1));
var targetFrequencies = [700,800,900];
var Fs = audioCtx.sampleRate;
var GoertzelRate = calcGoertzelRates(Fs)[0];
var GoertzelRateFactor = calcGoertzelRates(Fs)[1];
var goertzel = new Goertzel({
frequencies: targetFrequencies,
sampleRate: GoertzelRate
});
function detectTones(buffer){
Goertzel.Utilities.eachDownsample(buffer, GoertzelRateFactor, (function() {
return function(sample, i, downSampledBufferLength) {
var windowedSample = Goertzel.Utilities.exactBlackman(sample, i, downSampledBufferLength);
goertzel.processSample(windowedSample);
};
})());
}
function audioProcess(e){
var input = e.inputBuffer.getChannelData(0);
var output = e.outputBuffer.getChannelData(0);
for(var i=0;i<input.length;i++){
output[i]=input[i];
}
detectTones(input);
if(Object.values){
var peak = Goertzel.Utilities.peakFilter(Object.values(goertzel.energies), 1)
}else{
var dataArray = new Array;
for(var o in goertzel.energies) {
dataArray.push(goertzel.energies[o]);
}
var peak = Goertzel.Utilities.peakFilter(dataArray, 1)
}
console.log(goertzel.energies, peak)
goertzel.refresh();
}
var onRecordFail = function(e) {
processor.disconnect();
console.log(e);
alert("Error getting audio: "+e.message);
}
processor.onaudioprocess = audioProcess;
processor.connect(audioCtx.destination);
function init() {
console.log(Fs);
if(navigator.getUserMedia) {
navigator.getUserMedia({ video: false, audio: true }, function(stream) {
//fix https://bugzilla.mozilla.org/show_bug.cgi?id=934512
window.source = audioCtx.createMediaStreamSource(stream);
window.source.connect(processor);
}, onRecordFail);
}
};
init();
}
</script>
</head>
<body onload="run()">
</body>
</html>
Zum testen nehme ich Online Tone Generator - Free, Simple and Easy to Use.
Gehe dann mit eine klinke zu klinke kabel vom Laptop zum PC.