2017-04-23 105 views
1

在updatepitch()函數中,我試圖將音高值存儲在單個數組中,但我的代碼正在做的是將所有值存儲在不同的數組中。值存儲在不同的陣列而不是單個陣列

有什麼方法可以將所有值存儲在單個數組中。

window.AudioContext = window.AudioContext || window.webkitAudioContext; 
 
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia; 
 
window.URL = window.URL || window.webkitURL; 
 
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; 
 

 

 
var audioContext = null; 
 
var isPlaying = false; 
 
var sourceNode = null; 
 
var analyser = null; 
 
var theBuffer = null; 
 

 
var mediaStreamSource = null; 
 
var detectorElem, 
 
    canvasElem, 
 
    waveCanvas, 
 
    pitchElem, 
 
    noteElem, 
 
    detuneElem, 
 
    detuneAmount; 
 

 
window.onload = function() { 
 
    audioContext = new AudioContext(); 
 
    MAX_SIZE = Math.max(4, Math.floor(audioContext.sampleRate/5000)); // corresponds to a 5kHz signal 
 

 

 
    detectorElem = document.getElementById("detector"); 
 
    canvasElem = document.getElementById("output"); 
 

 

 
    pitchElem = document.getElementById("pitch"); 
 

 
    noteElem = document.getElementById("note"); 
 
    detuneElem = document.getElementById("detune"); 
 
    detuneAmount = document.getElementById("detune_amt"); 
 

 

 

 

 

 
} 
 

 

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

 
function getUserMedia(dictionary, callback) { 
 
    try { 
 
    navigator.getUserMedia = 
 
     navigator.getUserMedia || 
 
     navigator.webkitGetUserMedia || 
 
     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); 
 

 
    // Connect it to the destination. 
 
    analyser = audioContext.createAnalyser(); 
 
    analyser.fftSize = 2048; 
 
    mediaStreamSource.connect(analyser); 
 
    updatePitch(); 
 
} 
 

 

 

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

 
} 
 

 

 
var rafID = null; 
 
var tracks = null; 
 
var buflen = 1024; 
 
var buf = new Float32Array(buflen); 
 

 
var noteStrings = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]; 
 

 
function noteFromPitch(frequency) { 
 
    var noteNum = 12 * (Math.log(frequency/440)/Math.log(2)); 
 
    return Math.round(noteNum) + 69; 
 
} 
 

 
function frequencyFromNoteNumber(note) { 
 
    return 440 * Math.pow(2, (note - 69)/12); 
 
} 
 

 
function centsOffFromPitch(frequency, note) { 
 
    return Math.floor(1200 * Math.log(frequency/frequencyFromNoteNumber(note))/Math.log(2)); 
 
} 
 

 
var MIN_SAMPLES = 0; // will be initialized when AudioContext is created. 
 
var GOOD_ENOUGH_CORRELATION = 0.9; // this is the "bar" for how close a correlation needs to be 
 

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

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

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

 
    for (var i = 0; i < MAX_SAMPLES; i++) { 
 
     correlation += Math.abs((buf[i]) - (buf[i + offset])); 
 
    } 
 
    correlation = 1 - (correlation/MAX_SAMPLES); 
 
    correlations[offset] = correlation; // store it, for the tweaking we need to do below. 
 
    if ((correlation > GOOD_ENOUGH_CORRELATION) && (correlation > lastCorrelation)) { 
 
     foundGoodCorrelation = true; 
 
     if (correlation > best_correlation) { 
 
     best_correlation = correlation; 
 
     best_offset = offset; 
 
     } 
 
    } else if (foundGoodCorrelation) { 
 

 
     var shift = (correlations[best_offset + 1] - correlations[best_offset - 1])/correlations[best_offset]; 
 
     return sampleRate/(best_offset + (8 * shift)); 
 
    } 
 
    lastCorrelation = correlation; 
 
    } 
 
    if (best_correlation > 0.01) { 
 
    // console.log("f = " + sampleRate/best_offset + "Hz (rms: " + rms + " confidence: " + best_correlation + ")") 
 
    return sampleRate/best_offset; 
 
    } 
 
    return -1; 
 
    // \t var best_frequency = sampleRate/best_offset; 
 
} 
 

 
function updatePitch(time) { 
 
    var cycles = new Array; 
 
    analyser.getFloatTimeDomainData(buf); 
 
    var ac = autoCorrelate(buf, audioContext.sampleRate); 
 
    // TODO: Paint confidence meter on canvasElem here. 
 

 

 

 
    if (ac == -1) { 
 
    detectorElem.className = "vague"; 
 
    pitchElem.innerText = "--"; 
 
    noteElem.innerText = "-"; 
 
    detuneElem.className = ""; 
 
    detuneAmount.innerText = "--"; 
 
    } else { 
 
    detectorElem.className = "confident"; 
 
    pitch = ac; 
 
    var arraypitch = []; 
 
    arraypitch.push(pitch); 
 
    console.log(arraypitch); 
 
    document.getElementById("pit").innerHTML = Math.max(arraypitch); 
 
    pitchElem.innerText = Math.round(pitch); 
 
    var note = noteFromPitch(pitch); 
 
    noteElem.innerHTML = noteStrings[note % 12]; 
 
    var detune = centsOffFromPitch(pitch, note); 
 

 
    } 
 

 
    if (!window.requestAnimationFrame) 
 
    window.requestAnimationFrame = window.webkitRequestAnimationFrame; 
 
    rafID = window.requestAnimationFrame(updatePitch); 
 
}
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; 
 
}
<link href='http://fonts.googleapis.com/css?family=Alike' rel='stylesheet' type='text/css'> 
 
<p> 
 

 
    <button onclick="toggleLiveInput()">use live input</button> 
 

 
    <!--<button onclick="updatePitch(0);">sample</button>--> 
 
</p> 
 
<canvas id="canvas"></canvas> 
 
<div id="detector" class="vague"> 
 
    <div class="pitch"><span id="pitch">--</span>Hz</div> 
 
    <div class="note"><span id="note">--</span></div> 
 
    <canvas id="output" width=300 height=42></canvas> 
 

 
    <div id="detune"><span id="detune_amt">--</span><span id="flat">cents &#9837;</span><span id="sharp">cents &#9839;</span></div> 
 
</div> 
 
<div id="pit"></div> 
 

 
</body> 
 

 
</html>

+0

我的控制檯輸出是這樣的: pitchdetect.js:217 [222.2222165511223] pitchdetect.js:217 [221.19803433497853] pitchdetect.js:217 [217.19550460493102] –

+0

移動變種arraypitch = [];功能外 – mplungjan

+0

如果我移動功能之外的arraypitch然後它將如何找到音調。它說間距沒有定義@mplungjan –

回答

1

貌似裏面updatePitch()這些線問題:

var arraypitch = []; 
arraypitch.push(pitch); 

由於每次updatePitch()被調用時,你正在創建一個新的數組,arraypitch。

聲明陣列arrayPitch外部函數updatePitch(),並且只需在updatePitch()中推送音高。

可能會有幫助!

+0

如果我把它移到函數外面,那麼它表示音高沒有被定義。 Beacude球場在功能內 –

+0

只需移動線var arraypitch = []。在var audioContext = null時聲明它; –

+0

我正在獲取console.log中的值。但是,每當我做arraypitch.max它說undefined –