Öncelikle ile Akor Algılama Algoritması: http://www.music.mcgill.ca/~jason/mumt621/papers5/fujishima_1999.pdfBu akor algılama algoritması uygulamak çalışıyorum Web Audio API
Başlangıçta benim mikrofonu kullanmak algoritmayı uygulamaya ama işe yaramadı. Bir test olarak, bir akort yapmak için üç osilatör oluşturdum, ancak algoritma hala çalışmıyor. Sanırım sadece C, E ve G için daha yüksek bir sayı görmeliyim ama tüm notaların sayılarını görüyorum. Algoritmamın uygulanmasında bir sorun mu var? veya benim N, fref veya fs değerin mi? İşte
önemli parçalarla kod snippet'idir:// Set audio Context
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var mediaStreamSource = null;
var analyser = null;
var N = 4096;//8192;//2048; // Samples of Sound
var bufferLen = null;
var buffer = null;
var PCP = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // Pitch Class Profiles
var fref = 261.63; // Reference frequency middle C (C4)
// fref = 65.4; // Reference frequency C2
// fref = 440.0; // Reference frequency A4
var audioContext = new AudioContext();
var fs = audioContext.sampleRate; // Retrieve sampling rate. Usually 48KHz
var useMicrophone = false;
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
// Create an analyzer node to process the audio
analyser = audioContext.createAnalyser();
analyser.fftSize = N;
bufferLen = N/2;
//bufferLen = analyser.frequencyBinCount;
console.log('bufferLen = ' + bufferLen);
buffer = new Float32Array(bufferLen);
if (useMicrophone) {
// Create an AudioNode from the stream.
mediaStreamSource = audioContext.createMediaStreamSource(stream);
// Connect it to the destination.
mediaStreamSource.connect(analyser);
}
else {
// As a test, feed a C chord directly into the analyzer
// C4, E4, G4
var freqs = [261.63, 329.63, 392.00];
for(var i=0; i < freqs.length; i++) {
var o = audioContext.createOscillator();
var g = audioContext.createGain(); //Create Gain Node
o.frequency.value = freqs[i];
o.connect(g);
g.gain.value = 0.25;
g.connect(audioContext.destination);
g.connect(analyser);
o.start(0);
//setTimeout(function(s) {s.stop(0)}, 1000, o);
}
}
// Call algorithm every 50 ms
setInterval(function() {
pcpAlg();
}, 50);
})
.catch(function(err) {
console.log(err.name + ": " + err.message);
});
function pcpAlg() {
analyser.getFloatTimeDomainData(buffer);
//analyser.getFloatFrequencyData(buffer);
// Reset PCP
PCP = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
// M(0)=-1 so we don't have to start at 0
for (var l = 1; l < bufferLen; l++) { // l = 0,1,...,[(N/2) - 1]
// Calculate M(l)
var ML = Math.round(12 * Math.log2((fs * (l/N))/fref)) % 12; //
//console.log(ML);
if (ML >= 0 && ML <= 11) {
PCP[ML] += Math.pow(Math.abs(buffer[l]), 2);
}
}
// Display Data on UI and also try to determine if the sound is a C or F chord
displayAndCategorize();
}
kendiniz çalıştırmayı deneyin isterseniz İşte benim tam codepen olduğunu. Uyarı UseMicrophone yanlış ayarlamak için ayarladım, bu yüzden bir c akoru sesi çıkaracaktır: https://codepen.io/mapmaps/pen/ONQPpw
Soğuk bir proje gibi görünüyor, ancak girişin doğru olduğundan emin misiniz? Çıktının bu durumda doğru olup olmadığını görmek için sahte kodlanmış giriş değerleriyle denediniz mi? –
Zaman aralığı verileri yerine float frekansı verilerini arabellekte almak istemiyor musunuz? Ayrıca, PCP'ye biriktirmek için uygun bölmeyi fft sonucundan çıkarmak istediğinizi varsayalım. Şu anda ilk zaman değerini aldınız. –