Tôi đang tìm kiếm một cái gì đó tương tự và đã viết một câu trả lời ngu ngốc ở đây đã bị xóa. Tôi đã có một số ý tưởng nhưng không thực sự viết chúng đúng cách. Việc xóa đã cho tôi niềm tự hào về bản ngã thâm nhập vào internet nên tôi quyết định thử nghiệm vấn đề và tôi nghĩ nó đã hoạt động!
Thực sự cố gắng tìm một câu trả lời thực sự của một vị vua Adam Davis là rất khó nhưng làm một vị trí kiểu người (nhìn vào nguồn đầu tiên, bỏ qua tiếng vang, hoặc coi chúng là nguồn) không quá tệ, tôi nghĩ, mặc dù tôi không phải là chuyên gia xử lý tín hiệu bằng bất kỳ phương tiện nào.
Tôi đọc this và this. Điều này khiến tôi nhận ra rằng vấn đề thực sự là một trong những phát hiện sự thay đổi thời gian (tương quan chéo) giữa hai tín hiệu. Từ đó bạn sẽ tính toán góc sử dụng tốc độ âm thanh. Lưu ý bạn sẽ nhận được hai giải pháp (trước và sau).
Thông tin quan trọng mà tôi đã đọc nằm trong số this answer và các thông tin khác trên cùng một trang nói về cách thực hiện chuyển đổi nhanh chóng trong scipy, để tìm đường cong tương quan chéo.
Về cơ bản, bạn cần phải nhập tệp sóng vào python. Xem this.
Nếu tệp sóng (đầu vào) của bạn là một bộ dữ liệu với hai mảng numpy (trái, phải), không đệm ít nhất là chính nó (để dừng nó theo chiều thẳng đứng rõ ràng) mã theo sau câu trả lời của Gustavo. Tôi nghĩ rằng bạn cần phải nhận ra rằng ffts làm cho giả định về thời gian bất biến, có nghĩa là nếu bạn muốn nhận bất kỳ loại theo dõi dựa trên thời gian của các tín hiệu bạn cần phải 'cắn' các mẫu dữ liệu nhỏ.
Tôi đã đưa mã sau đây lại với nhau từ các nguồn được đề cập.Nó sẽ tạo ra một biểu đồ hiển thị thời gian trễ ước tính, theo khung, từ trái sang phải (âm/dương). Để chuyển đổi thành thời gian thực, chia cho tỷ lệ mẫu. Nếu bạn muốn biết những gì góc là bạn cần phải:
- giả mọi thứ đều trên mặt phẳng (không có yếu tố chiều cao)
- quên sự khác biệt giữa âm thanh ở phía trước và những người đằng sau (bạn không thể phân biệt)
Bạn cũng muốn sử dụng khoảng cách giữa hai micrô để đảm bảo bạn không nhận được tín hiệu lặp lại (thời gian trễ lớn hơn thời gian trễ 90 độ).
Tôi nhận ra rằng tôi đã vay rất nhiều ở đây, vì vậy cảm ơn tất cả những người vô tình đã đóng góp!
import wave
import struct
from numpy import array, concatenate, argmax
from numpy import abs as nabs
from scipy.signal import fftconvolve
from matplotlib.pyplot import plot, show
from math import log
def crossco(wav):
"""Returns cross correlation function of the left and right audio. It
uses a convolution of left with the right reversed which is the
equivalent of a cross-correlation.
"""
cor = nabs(fftconvolve(wav[0],wav[1][::-1]))
return cor
def trackTD(fname, width, chunksize=5000):
track = []
#opens the wave file using pythons built-in wave library
wav = wave.open(fname, 'r')
#get the info from the file, this is kind of ugly and non-PEPish
(nchannels, sampwidth, framerate, nframes, comptype, compname) = wav.getparams()
#only loop while you have enough whole chunks left in the wave
while wav.tell() < int(nframes/nchannels)-chunksize:
#read the audio frames as asequence of bytes
frames = wav.readframes(int(chunksize)*nchannels)
#construct a list out of that sequence
out = struct.unpack_from("%dh" % (chunksize * nchannels), frames)
# Convert 2 channels to numpy arrays
if nchannels == 2:
#the left channel is the 0th and even numbered elements
left = array (list (out[0::2]))
#the right is all the odd elements
right = array (list (out[1::2]))
else:
left = array (out)
right = left
#zero pad each channel with zeroes as long as the source
left = concatenate((left,[0]*chunksize))
right = concatenate((right,[0]*chunksize))
chunk = (left, right)
#if the volume is very low (800 or less), assume 0 degrees
if abs(max(left)) < 800 :
a = 0.0
else:
#otherwise computing how many frames delay there are in this chunk
cor = argmax(crossco(chunk)) - chunksize*2
#calculate the time
t = cor/framerate
#get the distance assuming v = 340m/s sina=(t*v)/width
sina = t*340/width
a = asin(sina) * 180/(3.14159)
#add the last angle delay value to a list
track.append(a)
#plot the list
plot(track)
show()
Tôi đã thử sử dụng một số âm thanh nổi mà tôi tìm thấy tại equilogy. Tôi đã sử dụng mẫu xe (tệp âm thanh nổi). Nó sản xuất this.
Để thực hiện việc này, tôi đoán bạn cần có nguồn âm thanh nổi đến mà bạn có thể 'nghe' trong một thời gian ngắn (tôi đã sử dụng 1000 khung = 0.0208s) và sau đó tính và lặp lại .
[sửa: tìm thấy bạn có thể dễ dàng sử dụng các chức năng FFT dây leo, bằng cách sử dụng chuỗi thời gian đảo ngược của một trong hai để tạo ra một mối tương quan]
Tôi đoán bạn muốn làm một rời rạc [tương quan chéo] (http://en.wikipedia.org/wiki/Cross-correlation) giữa hai kênh. –
@HotLicks: Điều đó không cho bạn biết nhiều. Biết được độ trễ tương đối giữa micrô trái và phải chỉ thu hẹp vị trí xuống bề mặt của một ellipsoid. –
BBN làm cho hàng triệu đô la bán một hệ thống thực hiện điều này. Họ không nói làm thế nào, hoặc nếu họ là họ đã cấp bằng sáng chế nó. – bmargulies