2016-10-06 23 views
0

замедлить/задержки отображения частоты

window.AudioContext = window.AudioContext || window.webkitAudioContext; 
 

 
var audioContext = null; 
 
var isPlaying = false; 
 
var sourceNode = null; 
 
var analyser = null; 
 
var theBuffer = null; 
 
var DEBUGCANVAS = null; 
 
var mediaStreamSource = null; 
 
var detectorElem, 
 
\t pitchElem ; 
 
var testdelay = null; 
 

 
window.onload = function() { 
 
\t audioContext = new AudioContext(); 
 
\t 
 
\t //test delay 
 
\t //testdelay = audioContext.createDelay(5.0); 
 
\t //testdelay.delayTime.value = 3.0; 
 
\t 
 
\t MAX_SIZE = Math.max(4,Math.floor(audioContext.sampleRate/5000)); \t // corresponds to a 5kHz signal 
 
\t var request = new XMLHttpRequest(); 
 
\t request.open("GET", "../sounds/whistling3.ogg", true); 
 
\t request.responseType = "arraybuffer"; 
 
\t request.onload = function() { 
 
\t audioContext.decodeAudioData(request.response, function(buffer) { 
 
\t  \t theBuffer = buffer; 
 
\t \t }); 
 
\t } 
 
\t request.send(); 
 

 
\t detectorElem = document.getElementById("detector"); 
 
\t pitchElem = document.getElementById("pitch"); 
 

 

 
\t detectorElem.ondragenter = function() { 
 
\t \t this.classList.add("droptarget"); 
 
\t \t return false; }; 
 
\t detectorElem.ondragleave = function() { this.classList.remove("droptarget"); return false; }; 
 
\t detectorElem.ondrop = function (e) { 
 
    \t \t this.classList.remove("droptarget"); 
 
    \t \t e.preventDefault(); 
 
\t \t theBuffer = null; 
 

 
\t \t var reader = new FileReader(); 
 
\t \t reader.onload = function (event) { 
 
\t \t \t audioContext.decodeAudioData(event.target.result, function(buffer) { 
 
\t  \t \t theBuffer = buffer; 
 
\t \t \t }, function(){alert("error loading!");}); 
 

 
\t \t }; 
 
\t \t reader.onerror = function (event) { 
 
\t \t \t alert("Error: " + reader.error); 
 
\t \t }; 
 
\t \t reader.readAsArrayBuffer(e.dataTransfer.files[0]); 
 
\t \t return false; 
 
\t }; 
 
} 
 

 
function error() { 
 
    alert('Stream generation failed.'); 
 
} 
 

 
function getUserMedia(dictionary, callback) { 
 
    try { 
 
     navigator.getUserMedia = 
 
     \t navigator.getUserMedia || 
 
     \t navigator.webkitGetUserMedia || 
 
     \t navigator.mozGetUserMedia; 
 
     navigator.getUserMedia(dictionary, callback, error); 
 
    } catch (e) { 
 
     alert('getUserMedia threw exception :' + e); 
 
    } 
 
} 
 

 
function gotStream(stream) { 
 
    // Create an AudioNode from the stream. 
 
    mediaStreamSource = audioContext.createMediaStreamSource(stream); 
 
\t 
 
    // Connect it to the destination. 
 
    analyser = audioContext.createAnalyser(); 
 

 
\t //test delay 
 
\t //testdelay = audioContext.createDelay(5.0); 
 
\t //testdelay.delayTime.value = 3.0; 
 
\t 
 
\t 
 
\t //analyser.smoothingTimeConstant = 0.8; 
 
\t 
 
    analyser.fftSize = 8192; 
 
    mediaStreamSource.connect(analyser); 
 
\t 
 
    updatePitch(); 
 
} 
 

 
function toggleLiveInput() { 
 
    if (isPlaying) { 
 
     //stop playing and return 
 
     sourceNode.stop(0); 
 
     sourceNode = null; 
 
     analyser = null; 
 
     isPlaying = false; 
 
\t \t if (!window.cancelAnimationFrame) 
 
\t \t \t window.cancelAnimationFrame = window.webkitCancelAnimationFrame; 
 
     window.cancelAnimationFrame(rafID); 
 
    } 
 
    getUserMedia(
 
    \t { 
 
      "audio": { 
 
       "mandatory": { 
 
        "googEchoCancellation": "false", 
 
        "googAutoGainControl": "false", 
 
        "googNoiseSuppression": "false", 
 
        "googHighpassFilter": "false" 
 
       }, 
 
       "optional": [] 
 
      }, 
 
     }, gotStream); 
 
} 
 

 

 
var buf = new Float32Array(1024); 
 

 

 
var MIN_SAMPLES = 0; // will be initialized when AudioContext is created. 
 

 
function autoCorrelate(buf, sampleRate) { 
 
\t var SIZE = buf.length; 
 
\t var MAX_SAMPLES = Math.floor(SIZE/2); 
 
\t var best_offset = -1; 
 
\t var best_correlation = 0; 
 
\t var rms = 0; 
 
\t var foundGoodCorrelation = false; 
 
\t var correlations = new Array(MAX_SAMPLES); 
 

 
\t for (var i=0;i<SIZE;i++) { 
 
\t \t var val = buf[i]; 
 
\t \t rms += val*val; 
 
\t } 
 
\t 
 
\t rms = Math.sqrt(rms/SIZE); 
 
\t if (rms<0.01) // not enough signal 
 
\t \t return -1; 
 

 
\t 
 
\t var lastCorrelation=1; 
 
\t for (var offset = MIN_SAMPLES; offset < MAX_SAMPLES; offset++) { 
 
\t \t var correlation = 0; 
 

 
\t \t for (var i=0; i<MAX_SAMPLES; i++) { 
 
\t \t \t correlation += Math.abs((buf[i])-(buf[i+offset])); 
 
\t \t } 
 
\t \t 
 
\t \t correlation = 1 - (correlation/MAX_SAMPLES); 
 
\t \t 
 
\t \t // store it, for the tweaking we need to do below. 
 
\t \t correlations[offset] = correlation; 
 
\t \t 
 
\t \t if ((correlation>0.9) && (correlation > lastCorrelation)) { 
 
\t \t \t foundGoodCorrelation = true; 
 
\t \t \t if (correlation > best_correlation) { 
 
\t \t \t \t best_correlation = correlation; 
 
\t \t \t \t best_offset = offset; 
 
\t \t \t } 
 
\t \t } else if (foundGoodCorrelation) { 
 
\t \t \t var shift = (correlations[best_offset+1] - correlations[best_offset-1])/correlations[best_offset]; 
 
\t \t \t return sampleRate/(best_offset+(8*shift)); 
 
\t \t } 
 
\t \t 
 
\t \t lastCorrelation = correlation; 
 
\t } 
 
\t if (best_correlation > 0.01) { 
 
\t \t // console.log("f = " + sampleRate/best_offset + "Hz (rms: " + rms + " confidence: " + best_correlation + ")") 
 
\t \t return sampleRate/best_offset; 
 
\t } 
 
\t return -1; 
 
// \t var best_frequency = sampleRate/best_offset; 
 
} 
 

 

 
//Fungsi untuk melakukan Update/perubahan data frequensi 
 
function updatePitch(time) { 
 
\t var cycles = new Array; 
 
\t analyser.getFloatTimeDomainData(buf); 
 
\t analyser.smoothingTimeConstant = 0.8; 
 
\t var ac = autoCorrelate(buf, audioContext.sampleRate); 
 
\t 
 
\t //menampilkan data pada form 
 
\t //jika tidak ditemukanya gelombang maka data akan kosong, dan warna tampilan akan abu2 
 
    \t if (ac == -1) { 
 
    \t \t detectorElem.className = "vague"; 
 
\t \t pitchElem.innerText = ""; 
 

 
\t //jika ditemukanya gelombang maka data akan kosong, dan warna tampilan akan hitam dan data akan ditampilkan 
 
    \t } else { 
 
\t \t detectorElem.className = "confident"; 
 
\t \t pitch = ac; 
 
\t \t 
 
\t \t //menampilkan data "pitch" (--Hz) pada halaman Web 
 
\t \t pitchElem.innerText = Math.round(pitch) ; 
 
\t } 
 

 
\t if (!window.requestAnimationFrame) 
 
\t \t window.requestAnimationFrame = window.webkitRequestAnimationFrame; 
 
\t rafID = window.requestAnimationFrame(updatePitch); 
 
}
<!doctype html> 
 
<html> 
 
<head> 
 
<title>Pitch Detector</title> 
 
<link href='http://fonts.googleapis.com/css?family=Alike' rel='stylesheet' type='text/css'> 
 
<style> 
 
body { font: 14pt 'Alike', sans-serif;} 
 
#note { font-size: 164px; } 
 
.droptarget { background-color: #348781} 
 
div.confident { color: black; } 
 
div.vague { color: lightgrey; } 
 
#note { display: inline-block; height:180px; text-align: left;} 
 

 
#detector { width: 300px; height: 300px; border: 4px solid gray; border-radius: 8px; text-align: center; padding-top: 10px;} 
 
#output { width: 300px; height: 42px; } 
 
#flat { display: none; } 
 
#sharp { display: none; } 
 
.flat #flat { display: inline; } 
 
.sharp #sharp { display: inline; } 
 
</style> 
 

 
</head> 
 
<body> 
 
<script src="js/pitchdetect.js"></script> 
 
    
 
<!-- <button onclick="this.innerText = togglePlayback()">use demo audio</button> --> 
 
<center> 
 
<button onclick="toggleLiveInput()">use live input</button> 
 

 
<!--<button onclick="updatePitch(0);">sample</button>--> 
 

 
<div id="detector" class="vague"> 
 
\t <div class="pitch"><span id="pitch">--</span>Hz</div> 
 
\t <div class="note"><span id="note">--</span></div> 
 
\t <canvas id="output" width=300 height=42></canvas> 
 
\t <div id="detune"><span id="detune_amt">--</span><span id="flat">cents &#9837;</span><span id="sharp">cents &#9839;</span></div> 
 
</div> 
 

 

 
<!-- just used for debugging 
 
<canvas id="waveform" width="512" height="256"></canvas> 
 
--> 
 

 
<script type="text/javascript"> 
 

 
    var _gaq = _gaq || []; 
 
    _gaq.push(['_setAccount', 'UA-35593052-1']); 
 
    _gaq.push(['_trackPageview']); 
 

 
    (function() { 
 
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; 
 
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 
 
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); 
 
    })(); 
 

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

ли кто-нибудь есть опыт делает живой частотомер на веб (PHP, JavaScript) с помощью микрофона?

У меня есть проект, чтобы сделать онлайн-частотомер. для отображения номера частоты, чтобы мы могли записать, был ли продукт хорошим или нет. , но частотное число работает слишком быстро.

Может ли кто-нибудь мне помочь, как пропустить некоторое обновлениеPicht() или каким-то образом отложить отображение, чтобы упростить просмотр? или способ сглаживания значения ...

ответ

0

Думаю, вам в основном нужно сгладить частотную оценку, которую вы получаете от updatePitch() самостоятельно. Либо вызывать updatePitch реже, что, вероятно, не то, что вы хотите, либо какое-то среднее значение для значений, возвращаемых updatePitch.

+0

Я попробовал, но это не сработало ... Можете ли вы исправить мой код? Или вы можете привести пример для этого? –

+0

Ну, один простой подход. Пусть 'f' будет выводиться из' updatePitch() '. Вместо отображения 'updatePitch()', вычислите 'f = a * updatePitch() + (1-a) * f', где' a' - некоторое небольшое число, возможно, 0.25? Вам придется немного поэкспериментировать, но чем меньше 'a', тем меньше вариаций будет на поле, но вы также не поймаете внезапные изменения высоты тона. –