2015-08-07 7 views
6

Sto tentando di misurare la differenza tra due suoni utilizzando un nodo dell'analizzatore e getByteFrequencyData(). Ho pensato che sommando la differenza in ogni scomparto di frequenza potrei trovare un singolo numero per rappresentare quanto diversi fossero i due suoni. Quindi sarei in grado di cambiare i suoni e misurare nuovamente i numeri per vedere se il nuovo suono fosse più o meno diverso da prima.Come si misura la differenza tra due suoni utilizzando l'API Web Audio?

getByteFrequencyData() comprende completamente la rappresentazione di un suono o è necessario includere altre parti di dati per qualificare il suono?

Ecco il codice che sto utilizzando:

var Spectrogram = (function(){ 
    function Spectrogram(ctx) { 
     this.analyser = ctx.createAnalyser(); 
     this.analyser.fftSize = 2048; 
     this.sampleRate = 512; 

     this.scriptNode = ctx.createScriptProcessor(this.sampleRate, 1, 1); 
     this.scriptNode.onaudioprocess = this.process.bind(this); 

     this.analyser.connect(this.scriptNode); 

     this.startNode = this.analyser; 
     this.endNode = this.scriptNode; 

     this.data = []; 
    } 

    Spectrogram.prototype.process = function(e) { 
     var d = new Uint8Array(this.analyser.frequencyBinCount); 
     this.analyser.getByteFrequencyData(d); 
     this.data.push(d); 

     var inputBuffer = e.inputBuffer; 
     var outputBuffer = e.outputBuffer; 
     for(var channel = 0; channel < outputBuffer.numberOfChannels; channel++) { 
      var inputData = inputBuffer.getChannelData(channel); 
      var outputData = outputBuffer.getChannelData(channel); 
      for(var sample = 0; sample < inputBuffer.length; sample++) { 
       outputData[sample] = inputData[sample]; 
      } 
     } 
    }; 

    Spectrogram.prototype.compare = function(other) { 
     var fitness = 0; 
     for(var i=0; i<this.data.length; i++) { 
      if(other.data[i]) { 
       for(var k=0; k<this.data[i].length; k++) { 
        fitness += Math.abs(this.data[i][k] - other.data[i][k]); 
       } 
      } 
     } 
     return fitness; 
    } 

    return Spectrogram; 
})(); 
+1

È necessario considerare cosa significa per te che i suoni siano diversi. Certamente 'getByteFrequencyData' rappresenta il suono in qualche modo, ma non so se cattura ciò che vuoi. Pensa se hai un suono. Ora riduci l'ampiezza di un fattore 2. I suoni sono gli stessi? Dovrebbero essere considerati gli stessi suoni? È necessario definire cosa significhi essere lo "stesso" prima che tu possa trovare un algoritmo da dirti. –

+0

Immagino che i suoni siano gli stessi che suonerebbero allo stesso modo di un orecchio umano. Quindi l'ampiezza sarebbe una parte dell'equazione. Sui nodi dell'analizzatore esiste anche getByteTimeDomainData() la cui descrizione è "l'attuale dominio temporale o forma d'onda" che comprenderebbe l'ampiezza? – zorqy

+0

Sì, includerebbe informazioni sull'ampiezza. Ma probabilmente vorrai usare 'getFloatTimeDomainData' invece di' getByteTimeDomainData'. –

risposta

1

È possibile utilizzare la funzione spectralFlux fornito dal pacchetto Meyda per confrontare due segnali. Il flusso spettrale è, secondo wikipedia, "generalmente calcolato come la 2-norma (nota anche come distanza euclidea) tra i due spettri normalizzati."

Dopo runninng npm install --save meyda, si potrebbe fare qualcosa di simile:

const spectralFlux = require('meyda/src/extractors/spectralFlux'); 

const difference = spectralFlux({ 
    signal: [your first signal], 
    previousSignal: [your second signal] 
}); 

Sentitevi liberi di basta copiare il codice da here in modo che non c'è bisogno di gestire la dipendenza, la base di codice è opportunamente licenza.

Restituirà un coefficiente di come "diverso" i due segnali suonano. Puoi farlo nel dominio del tempo o nel dominio della frequenza. Otterrai numeri diversi, ma entrambi sarebbero correlati con quanto "diversi" i suoni sono l'uno dall'altro.

Ma "differenza" potrebbe non descrivere le differenze in modo sufficientemente accurato per il vostro caso d'uso. Ad esempio, potresti preoccuparti molto delle differenze di volume e non delle differenze timbriche, ma la metrica del flusso spettrale non tiene conto di questo. Potresti voler eseguire prima ciascun segnale tramite gli estrattori di feature, trovare altre statistiche sulle loro proprietà come il loro volume percettivo, la loro luminosità, ecc. E quindi prendere una distanza euclidea ponderata tra quei dati, che fornirebbe una "differenza" metrica più personalizzata a quello che ti serve per il tuo scopo.

Felice di elaborare ulteriormente, ma questo è già abbastanza lungo per una risposta SO.

+0

Grazie per aver indirizzato il tuo progetto su github! Sembra davvero utile Stai pensando di aggiungere altri strumenti di confronto sonoro? –

+0

@JustusRomijn Sono felice di aggiungere qualsiasi cosa sarebbe utile :) –

Problemi correlati