2015-08-07 13 views
6

Tôi đang cố gắng đo sự khác biệt giữa hai âm thanh bằng cách sử dụng nút phân tích và getByteFrequencyData(). Tôi nghĩ rằng bằng cách tổng hợp sự khác biệt trong mỗi bin tần số tôi có thể đưa ra một số duy nhất để đại diện cho hai âm thanh khác nhau như thế nào. Sau đó, tôi sẽ có thể thay đổi âm thanh và đo các con số một lần nữa để xem âm thanh mới có nhiều hay ít khác biệt so với trước đây.Bạn đo lường sự khác biệt giữa hai âm thanh bằng cách sử dụng API âm thanh web như thế nào?

Có getByteFrequencyData() hoàn toàn bao gồm biểu diễn âm thanh hoặc tôi có cần bao gồm các phần dữ liệu khác để đủ điều kiện âm thanh không?

Đây là mã Tôi đang sử dụng:

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

Bạn cần cân nhắc ý nghĩa của âm thanh đối với bạn. Chắc chắn 'getByteFrequencyData' đại diện cho âm thanh theo một cách nào đó, nhưng tôi không biết nếu nó nắm bắt những gì bạn muốn. Hãy xem xét nếu bạn có một âm thanh. Bây giờ giảm biên độ theo hệ số 2. Âm thanh có giống nhau không? Họ có nên được coi là những âm thanh giống nhau không? Bạn cần phải xác định ý nghĩa của nó là "giống nhau" trước khi bạn có thể đưa ra một thuật toán để cho bạn biết. –

+0

Tôi đoán là âm thanh giống nhau, âm thanh giống như tai người. Vì vậy biên độ sẽ là một phần của phương trình. Trên các nút phân tích cũng có getByteTimeDomainData() mô tả là "miền thời gian hiện tại hoặc dạng sóng" sẽ bao gồm biên độ? – zorqy

+0

Có, nó sẽ bao gồm thông tin biên độ. Nhưng bạn có thể muốn sử dụng 'getFloatTimeDomainData' thay vì' getByteTimeDomainData'. –

Trả lời

1

Bạn có thể sử dụng chức năng spectralFlux được cung cấp bởi các gói Meyda để so sánh hai tín hiệu. Quang phổ là, theo wikipedia, "thường được tính như 2-norm (còn được gọi là khoảng cách Euclide) giữa hai phổ chuẩn hóa."

Sau runninng npm install --save meyda, bạn sẽ làm điều gì đó như:

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

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

thoải mái chỉ cần sao chép mã từ here để bạn không cần phải xử lý phụ thuộc, các codebase được cấp phép một cách thích hợp.

Nó sẽ trả về hệ số "hai tín hiệu" khác nhau như thế nào. Bạn có thể thực hiện việc này trong miền thời gian hoặc miền tần số. Bạn sẽ nhận được các con số khác nhau, nhưng cả hai sẽ tương quan với cách "khác nhau" âm thanh từ mỗi khác.

Nhưng "sự khác biệt" có thể không mô tả sự khác biệt chính xác đủ cho trường hợp sử dụng của bạn. Ví dụ, bạn có thể quan tâm rất nhiều về sự khác biệt về khối lượng, và không có nhiều sự khác biệt về timbral, nhưng chỉ số thông lượng quang phổ không tính đến điều đó. Trước tiên, bạn có thể chạy từng tín hiệu thông qua các trình trích xuất tính năng, tìm các thống kê khác về các thuộc tính của chúng như khối lượng cảm nhận, độ sáng, v.v ... và sau đó lấy khoảng cách euclid có trọng số giữa các dữ liệu đó. với những gì bạn cần cho mục đích của bạn.

Vui lòng xây dựng thêm, nhưng điều này đã khá dài đối với câu trả lời SO.

+0

Cảm ơn bạn đã trỏ đến dự án của mình trên github! Trông rất hữu ích. Bạn có dự định thêm nhiều công cụ so sánh âm thanh hơn không? –

+0

@JustusRomijn Tôi rất vui khi thêm bất kỳ điều gì hữu ích :) –

Các vấn đề liên quan