Làm cách nào để triển khai tương quan chéo để chứng minh hai tệp âm thanh giống nhau?


58

Tôi phải làm tương quan chéo của hai tệp âm thanh để chứng minh chúng giống nhau. Tôi đã lấy FFT của hai tệp âm thanh và có các giá trị phổ công suất của chúng trong các mảng riêng biệt.

Làm thế nào tôi nên tiến hành hơn nữa để tương quan chéo với chúng và chứng minh rằng chúng giống nhau? Có cách nào tốt hơn để làm điều đó? Bất kỳ ý tưởng cơ bản sẽ hữu ích cho tôi để tìm hiểu và áp dụng nó.


Cho tương quan chéo của hai vectơ tín hiệu ngẫu nhiên. Làm thế nào để bạn thực hiện ngược lại để có được hai vectơ trong MATLAB. John Muhehe

Câu trả lời:


56

Tương quan chéo và tích chập có liên quan chặt chẽ. Nói tóm lại, để thực hiện tích chập với FFT, bạn

  1. zero-pad các tín hiệu đầu vào (thêm số không vào cuối để ít nhất một nửa sóng "trống")
  2. lấy FFT của cả hai tín hiệu
  3. nhân các kết quả với nhau (phép nhân phần tử)
  4. làm FFT nghịch đảo

conv(a, b) = ifft(fft(a_and_zeros) * fft(b_and_zeros))

Bạn cần thực hiện phần đệm bằng 0 vì phương pháp FFT thực sự là tương quan chéo tròn , nghĩa là tín hiệu bao quanh ở hai đầu. Vì vậy, bạn thêm số không đủ để loại bỏ sự chồng lấp, để mô phỏng tín hiệu bằng không đến vô cùng.

Để có được mối tương quan chéo thay vì tích chập, bạn cần phải đảo ngược thời gian một trong các tín hiệu trước khi thực hiện FFT hoặc lấy liên hợp phức tạp của một trong các tín hiệu sau FFT:

  • corr(a, b) = ifft(fft(a_and_zeros) * fft(b_and_zeros[reversed]))
  • corr(a, b) = ifft(fft(a_and_zeros) * conj(fft(b_and_zeros)))

cái nào dễ hơn với phần cứng / phần mềm của bạn. Đối với tự tương quan (tương quan chéo của tín hiệu với chính nó), tốt hơn là thực hiện liên hợp phức tạp, bởi vì sau đó bạn chỉ cần tính toán FFT một lần.

Nếu các tín hiệu là có thật, bạn có thể sử dụng các FFT thực (RFFT / IRFFT) và tiết kiệm một nửa thời gian tính toán của bạn bằng cách chỉ tính một nửa phổ.

Ngoài ra, bạn có thể tiết kiệm thời gian tính toán bằng cách đệm vào kích thước lớn hơn mà FFT được tối ưu hóa (chẳng hạn như số 5 số cho FFTPACK, số ~ 13 số cho FFTW hoặc công suất 2 cho việc triển khai phần cứng đơn giản).

Đây là một ví dụ về tương quan Python của FFT so với tương quan brute-force: https://stackoverflow.com/a/1768140/125507

Điều này sẽ cung cấp cho bạn hàm tương quan chéo, là thước đo tương tự so với bù. Để có được độ lệch mà tại đó các sóng được "xếp hàng" với nhau, sẽ có một đỉnh trong hàm tương quan:

đỉnh trong hàm tương quan

Giá trị x của đỉnh là giá trị bù, có thể âm hoặc dương.

Tôi chỉ thấy điều này được sử dụng để tìm sự bù giữa hai sóng. Bạn có thể có được ước tính chính xác hơn về độ lệch (tốt hơn độ phân giải của các mẫu) bằng cách sử dụng phép nội suy parabol / bậc hai trên đỉnh.

Để có giá trị tương tự giữa -1 và 1 (giá trị âm biểu thị một trong các tín hiệu giảm khi các tín hiệu khác tăng), bạn cần phải điều chỉnh biên độ theo độ dài của đầu vào, độ dài của FFT, triển khai FFT cụ thể của bạn chia tỷ lệ, v.v ... Việc tự tương quan của một sóng sẽ tự cung cấp cho bạn giá trị của kết quả khớp tối đa có thể.

Lưu ý rằng điều này sẽ chỉ hoạt động trên các sóng có hình dạng tương tự. Nếu chúng đã được lấy mẫu trên các phần cứng khác nhau hoặc có thêm một số nhiễu, nhưng nếu không vẫn có hình dạng giống nhau, thì phép so sánh này sẽ hoạt động, nhưng nếu hình dạng sóng đã được thay đổi bằng cách lọc hoặc dịch pha, chúng có thể phát ra âm thanh giống nhau, nhưng đã thắng 't tương quan là tốt.


3
Phần đệm bằng 0 nên có ít nhất N = size (a) + size (b) -1, tốt nhất là làm tròn thành lũy thừa 2. Để có giá trị giữa -1 và 1, chia cho định mức (a) * Norm (b) ), cung cấp cosin của góc giữa hai vectơ trong không gian N cho độ trễ cho trước (tức là modulo N thay đổi tròn). Ở độ trễ cực cao, không có nhiều mẫu chồng chéo (chỉ có một mẫu ở cực xa), do đó, chia cho định mức (a) * định mức (b) sẽ làm lệch các mối tương quan này về 0 (nghĩa là hiển thị tính trực giao tương đối của chúng trong không gian N) .
Eryk CN

1
Tôi nghĩ rằng có thể có một lỗi trong mô tả. Không nên nhân các FFT với nhau theo thuật ngữ cho FFT về độ chập của các tín hiệu, chứ không phải FFT của mối tương quan chéo ? Theo tôi hiểu, để có được FFT của mối tương quan chéo, cần phải sử dụng liên hợp phức tạp của một trong các vectơ FFT trong phép nhân theo thuật ngữ trước khi sử dụng iFFT.
Dilip Sarwate

@DilipSarwate: Vâng, bạn đúng. Bạn cũng có thể đảo ngược một tín hiệu theo hướng thời gian mà tôi đã thêm vào câu trả lời.
endolith

1
x[i]ix[±i]x[i](Ni)x[Ni]iităng chi phí dây, độ trễ dây (và do đó làm giảm tốc độ xung nhịp tối đa có thể đạt được), và cũng bởi vì tất cả các dây phải giao nhau, tạo ra các vấn đề định tuyến. Nó nên được tránh nếu có thể, và trong trường hợp này, nó có thể tránh được.
Dilip Sarwate

1
@Leo nhân phần tử khôn ngoan. n-by-1 mảng x n-by-1 mảng = n-by-1 mảng Tôi đã gọi đây là "sample-by-sample" trong câu trả lời.
endolith

17

Tương quan là một cách để thể hiện sự giống nhau của hai thời gian (mẫu âm thanh trong trường hợp của bạn) trong một số. Đây là một sự thích ứng của hiệp phương sai được thực hiện như sau:

period = 1/sampleFrequency;
covariance=0;

for (iSample = 0; iSample<nSamples; iSample++)
    covariance += (timeSeries_1(iSample)*timeSeries_2(iSample))/period;
    //Dividing by `period` might not even be necessary

Mối tương quan là phiên bản chuẩn hóa của hiệp phương sai, là hiệp phương sai chia cho tích của độ lệch chuẩn của cả hai chuỗi thời gian. Tương quan sẽ mang lại 0 khi không có tương quan (hoàn toàn không tương tự) và 1 cho tổng tương quan (hoàn toàn tương tự).

Bạn có thể tưởng tượng rằng hai mẫu âm thanh có thể giống nhau nhưng không được đồng bộ hóa. Đó là nơi có mối tương quan chéo . Bạn tính toán mối tương quan giữa chuỗi thời gian mà bạn có một trong số chúng được dịch chuyển bởi một mẫu:

for (iShift=0; iShift<nSamples; iShift++)
    xcorr(iShift) = corr(timeSeries_1, timeSeries_2_shifted_one_sample);

Sau đó tìm kiếm giá trị tối đa trong corrchuỗi và bạn đã hoàn thành. (hoặc dừng lại nếu bạn đã tìm thấy một mối tương quan đầy đủ) Tất nhiên có nhiều hơn một chút so với nó. Bạn phải thực hiện độ lệch chuẩn và bạn phải thực hiện một số quản lý bộ nhớ và thực hiện các công cụ dịch chuyển thời gian. Nếu tất cả các mẫu âm thanh của bạn có độ dài bằng nhau, bạn có thể làm mà không bình thường hóa hiệp phương sai và tiếp tục và tính toán hiệp phương sai.

Một mối quan hệ tuyệt vời cho câu hỏi trước đây của bạn : phân tích Fourier chỉ là một sự thích ứng của hiệp phương sai. Thay vì dịch chuyển một chuỗi thời gian và tính toán hiệp phương sai với tín hiệu khác, bạn tính toán hiệp phương sai giữa một tín hiệu và một số sóng (co) có tần số khác nhau. Tất cả đều dựa trên cùng một nguyên tắc.


1
Bạn đã đề cập rằng 0 không có tương quan và 1 là tổng tương quan. Tôi chỉ muốn lưu ý rằng -1 là hoàn toàn tương quan nghịch. Như trong, -1 ngụ ý rằng mẫu 1 trái ngược với mẫu 2. Nếu bạn nghĩ về nó trên đồ thị X, Y, thì đó là một đường có độ dốc dương so với đường có độ dốc âm. Và khi bạn tiến gần đến 0, dòng sẽ "béo hơn".
Kellenjb

@kellenjb, Có, nhưng tôi có thể nói từ đó, mức độ tương quan mà bạn có thể quan tâm. 1 hoặc -1 có nghĩa là các tín hiệu ảnh hưởng trực tiếp lẫn nhau.
Kortuk

14

Trong xử lý tín hiệu, tương quan chéo (xcorr trong MATLAB) là một phép toán tích chập với một trong hai chuỗi được đảo ngược. Vì đảo ngược thời gian tương ứng với liên hợp phức tạp trong miền tần số, bạn có thể sử dụng DFT để tính toán tương quan chéo như sau:

R_xy = ifft(fft(x,N) * conj(fft(y,N)))

Trong đó N = size (x) + size (y) - 1 (tốt nhất là làm tròn thành lũy thừa 2) là chiều dài của DFT.

Phép nhân của DFT tương đương với tích chập tuần hoàn trong thời gian. Không đệm cả hai vectơ theo chiều dài N giữ cho các thành phần chuyển dịch tròn của y không bị trùng với x, làm cho kết quả giống hệt với tích chập tuyến tính của x và thời gian đảo ngược y.

Độ trễ bằng 1 là độ dịch chuyển tròn phải của y, trong khi độ trễ -1 là độ dịch chuyển tròn trái. Mối tương quan chéo đơn giản là chuỗi các sản phẩm chấm cho tất cả độ trễ. Dựa trên thứ tự fft tiêu chuẩn, chúng sẽ nằm trong một mảng có thể được truy cập như sau. Chỉ số 0 đến kích thước (x) -1 là độ trễ dương. Chỉ số N-size (y) +1 đến N-1 là độ trễ âm theo thứ tự ngược lại. (Trong Python, độ trễ âm có thể được truy cập thuận tiện với các chỉ số âm như R_xy [-1].)

Bạn có thể nghĩ về các x và y không đệm là các vectơ N chiều. Sản phẩm chấm của x và y cho độ trễ cho trước là |x|*|y|*cos(theta). Các chỉ tiêu của x và y là hằng số cho các dịch chuyển tròn, do đó, việc chia chúng ra chỉ để lại cosin khác nhau của góc theta. Nếu x và y (đối với độ trễ cho trước) là trực giao trong không gian N, thì tương quan là 0 (tức là theta = 90 độ). Nếu chúng cùng tuyến tính, giá trị là 1 (tương quan dương) hoặc -1 (tương quan nghịch, tức là theta = 180 độ). Điều này dẫn đến mối tương quan chéo được chuẩn hóa thành sự thống nhất:

R_xy = ifft(fft(x,N) * conj(fft(y,N))) / (norm(x) * norm(y))

Điều này có thể được thực hiện không thiên vị bằng cách tính toán lại các chỉ tiêu cho các phần chồng chéo, nhưng sau đó bạn cũng có thể thực hiện toàn bộ tính toán trong miền thời gian. Ngoài ra, bạn sẽ thấy các phiên bản chuẩn hóa khác nhau. Thay vì được chuẩn hóa thành thống nhất, đôi khi mối tương quan chéo được chuẩn hóa bởi M (bias), trong đó M = max (size (x), size (y)) hoặc M- | m | (một ước tính không thiên vị của độ trễ mth).

Đối với ý nghĩa thống kê tối đa, giá trị trung bình (độ lệch DC) phải được loại bỏ trước khi tính toán tương quan. Điều này được gọi là hiệp phương sai (xcov trong MATLAB):

x2 = x - mean(x)
y2 = y - mean(y)
phi_xy = ifft(fft(x2,N) * conj(fft(y2,N))) / (norm(x2) * norm(y2))

Điều này có nghĩa là kích thước cuối cùng của mảng nên 2*size (a) + size(b) - 1hay 2*size (b) + size (a) - 1? Nhưng trong cả hai trường hợp, hai mảng đệm có kích thước khác nhau. Hậu quả của việc đệm với quá nhiều số không là gì?

2

@RobertKJ: Bạn đang trượt bdọc a, với một đầu ra trên mỗi ca, sự chồng chéo tối thiểu của một mẫu. Điều đó mang size(a)lại độ trễ dương và độ size(b) - 1trễ âm. Sử dụng biến đổi nghịch đảo của sản phẩm của các DFT điểm N, các chỉ số 0thông qua size(a)-1là độ trễ dương và các chỉ số N-size(b)+1thông qua N-1là độ trễ âm theo thứ tự ngược lại.
Eryk CN

3

nếu bạn đang sử dụng Matlab, hãy thử chức năng tương quan chéo:

c= xcorr(x,y)

Đây là tài liệu Matlab:

xcorrước tính trình tự tương quan chéo của một quá trình ngẫu nhiên. Autocorrelation được xử lý như một trường hợp đặc biệt.

...

c = xcorr(x,y)trả về chuỗi tương quan chéo trong một vectơ 2 * N-1 có độ dài , trong đó xyNcác vectơ có chiều dài ( N > 1). Nếu xykhông cùng chiều dài, vectơ ngắn hơn được đệm bằng 0 với chiều dài của vectơ dài hơn.

tương quan http://www.mathworks.com/help/toolbox/signal/ref/eqn1263487323.gif


Các liên kết dường như bị phá vỡ.
Danijel

2

Một cách nhanh chóng và đơn giản để so sánh các tập tin âm thanh. Lấy tệp âm thanh, tạo một bản sao, trong một daw, dán chúng cạnh nhau, trong 2 kênh âm thanh nổi, đảo ngược pha trên một trong các rãnh âm thanh, căn chỉnh cả hai tệp ở đầu ở chế độ thu phóng, hãy chắc chắn rằng cả hai tệp có cùng biên độ lúc đầu, sau đó phát, nếu có sự im lặng hoàn toàn, thì cả hai tệp đều giống hệt nhau, nếu có sự khác biệt bạn sẽ nghe thấy nó khá rõ ràng!.


1

Như hầu hết ở đây đã viết bạn nên sử dụng tương quan.

Chỉ cần xem xét 2 yếu tố:

  1. Nếu âm lượng được chia tỷ lệ khác nhau, bạn nên bình thường hóa mối tương quan.
  2. Nếu có tỷ lệ thời gian thì bạn có thể sử dụng Độ cong thời gian động.

1

Đối với các tín hiệu không định kỳ (kích thước (y) -1) phải được trừ khỏi chỉ số của R_xy để có độ trễ thực tế.

N = kích thước (x) + kích thước (y) - 1;

độ trễ = [0, N] - (kích thước (y) - 1);


0

Cách dễ nhất để tìm sự khác biệt, IMO, là trừ hai tín hiệu âm thanh trong miền thời gian. Nếu chúng bằng nhau, kết quả tại mọi thời điểm sẽ bằng không. Nếu chúng không bằng nhau, sự khác biệt giữa chúng sẽ được để lại sau khi trừ và bạn có thể nghe trực tiếp. Một thước đo nhanh về mức độ giống nhau của chúng sẽ là giá trị RMS của sự khác biệt này. Điều này thường được thực hiện trong việc trộn và làm chủ âm thanh để nghe sự khác biệt của tệp MP3 và WAV chẳng hạn. (Đảo ngược pha của một tín hiệu và thêm chúng cũng giống như trừ. Đây là phương pháp được sử dụng khi thực hiện trong phần mềm DAW.) Chúng phải được căn chỉnh thời gian hoàn hảo để nó hoạt động. Nếu chúng không phải là bạn có thể phát triển một thuật toán để căn chỉnh chúng, chẳng hạn như phát hiện mười đỉnh hàng đầu, tính toán độ lệch trung bình của các đỉnh và dịch chuyển một tín hiệu.

Chuyển đổi sang miền tần số và so sánh phổ công suất của các tín hiệu như bạn đề xuất là bỏ qua một số thông tin miền thời gian. Ví dụ, âm thanh được phát ngược lại sẽ có cùng phổ khi phát về phía trước. Do đó, hai tín hiệu âm thanh rất khác nhau có thể có cùng phổ chính xác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.