2016-04-14 28 views
3

Ö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

+0

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? –

+0

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. –

cevap

1

Sorun, 1999 tarihli bir kağıdın algoritmasıdır. Bir kaba spektral frekans tahmincisi olan bir müzikal zift dedektörü/tahmincisi olmayan büyüklük zirveleri için FFT kullanıyor görünüyorsunuz. Polifonik akor tahmini daha da zor/karmaşık bir görevdir. Polifonik müzik çıkarımı için en son algoritmalara bakın: http://www.music-ir.org/mirex/wiki/2015:MIREX2015_Results

+0

Bunu doğru olarak işaretlemek için yeterli bilgiye sahip olduğumdan emin değilim. Algoritmayı 1999 tarihli makalede uygulamak istedim çünkü uygulamak istediğim bir şeymiş gibi görünüyor ve bir akort tespit algoritması olduğunu iddia ediyor. Ayrıca bu iki makalede de atıfta bulunulmuştur: http://www.fim.uni-passau.de/fileadmin/files/lehrstuhl/sauer/geyer/BA_MA_Arbeiten/BA-HausnerChristoph-201409.pdf ve https: //ccrma.stanford .edu/~ kglee/pubs/klee-ismir06.pdf 1999 tarihli kâğıtta akorları tespit eden algoritmasının çıktısı vardır. Belki gazeteden bir şey çıkardı? – user3220901

İlgili konular