Обнаружение частоты Python
Вопрос
Хорошо, что я пытаюсь сделать, это своего рода программное обеспечение для обработки аудио, которое может обнаружить распространенную частоту, если частота воспроизводится достаточно длинной (несколько мс), я знаю, что я получил положительный матч. Я знаю, что мне нужно будет использовать FFT или что-то Simiral, но в этой области математики я сосу, я искал интернет, но не нашел код, который мог сделать только это.
Цель, которую я пытаюсь ускорить, состоит в том, чтобы сделать себе нестандартный протокол для отправки данных Chrough Sound, нуждается в очень низком битреете в секунду (5-10 с / с), но я также очень ограничен на концом передачи, поэтому требуемое программное обеспечение должно быть возможности Не могу использовать фактическое оборудование / программное обеспечение Modem), также я хочу, чтобы это было только программное обеспечение (без дополнительного оборудования, кроме SoundCard)
Большое спасибо за помощь.
Решение
То aubio Библиотеки были обернуты с Swig и, таким образом, могут использоваться Python. Среди их множества функций включают в себя несколько методов обнаружения / оценки высоты тона, включая Йин алгоритм и некоторые гармонические комбинационные алгоритмы.
Однако, если вы хотите что-то проще, я написал какой-то код для оценки высоты тона некоторое время назад, и вы можете взять его или оставить его. Это не будет таким точным, как и использование алгоритмов в Aubio, но это может быть достаточно хорошо для ваших потребностей. Я в основном просто взял FFT времени данных в окно (окно Blackman в этом случае), в квадрате в квадрате в квадрате установлено, что BIN, который имел наибольшее значение, и использовал квадратичную интерполяцию вокруг пика, используя журнал максимального значения. и его два соседних значения, чтобы найти фундаментальную частоту. Квадратичная интерполяция, которую я взял из какой-то бумаги, которую я нашел.
Он работает довольно хорошо на тестовых тонах, но он не будет такой же надежной или такой же точностью, как и другие методы, упомянутые выше. Точность может быть увеличена путем увеличения размера чанка (или уменьшена, уменьшая его). Размер чанка должен быть кратным 2 для полного использования FFT. Кроме того, я только определяю фундаментальную высоту для каждого куска без перекрытия. Я использовал Pyaudio, чтобы сыграть звук, когда выписали предполагаемую высоту.
Исходный код:
# Read in a WAV and find the freq's
import pyaudio
import wave
import numpy as np
chunk = 2048
# open up a wave
wf = wave.open('test-tones/440hz.wav', 'rb')
swidth = wf.getsampwidth()
RATE = wf.getframerate()
# use a Blackman window
window = np.blackman(chunk)
# open stream
p = pyaudio.PyAudio()
stream = p.open(format =
p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = RATE,
output = True)
# read some data
data = wf.readframes(chunk)
# play stream and find the frequency of each chunk
while len(data) == chunk*swidth:
# write data out to the audio stream
stream.write(data)
# unpack the data and times by the hamming window
indata = np.array(wave.struct.unpack("%dh"%(len(data)/swidth),\
data))*window
# Take the fft and square each value
fftData=abs(np.fft.rfft(indata))**2
# find the maximum
which = fftData[1:].argmax() + 1
# use quadratic interpolation around the max
if which != len(fftData)-1:
y0,y1,y2 = np.log(fftData[which-1:which+2:])
x1 = (y2 - y0) * .5 / (2 * y1 - y2 - y0)
# find the frequency and output it
thefreq = (which+x1)*RATE/chunk
print "The freq is %f Hz." % (thefreq)
else:
thefreq = which*RATE/chunk
print "The freq is %f Hz." % (thefreq)
# read some more data
data = wf.readframes(chunk)
if data:
stream.write(data)
stream.close()
p.terminate()
Другие советы
Если вы собираетесь использовать FSK (клавиша переключения частоты) для кодирования данных, вы, вероятно, лучше используете Алгоритм Гордвижила Таким образом, вы можете проверить только частоты, которые вы хотите, вместо полного DFT / FFT.
Пока я не пробовал обработку аудио на Python, возможно, вы можете построить что-то на основе Каникул (или его subproject numpy), рамки для эффективных научных / инженерных численных вычислений? Вы можете начать, глядя на Scipy.ffftpack для вашего FFT.