2010-04-15 4 views
29

Хорошо, что я пытаюсь сделать, это своего рода программное обеспечение для обработки звука, которое может обнаруживать распространенную частоту, если частота воспроизводится достаточно долго (несколько мс), я знаю, что я получил положительное совпадение. я знаю, что мне нужно будет использовать БПФ или что-то подобное, но в этой области математики я сосать, я действительно искал в Интернете, но не нашел кода, который мог бы сделать только это.Определение частоты на Python

Цель, которую я пытаюсь получить, - это сделать собственный протокол для передачи данных через звук, нужно очень низкое битрейт в секунду (5-10 бит/с), но им также очень ограничено на передающем конце, чтобы получающее программное обеспечение (возможно, использовать настоящий аппаратный/программный модем), также я хочу, чтобы это было только программное обеспечение (без дополнительного оборудования, кроме звуковой карты)

спасибо большое за помощь.

+1

Это может быть полезно (обязательно прочтите ответы): http://www.keyongtech.com/5003865-frequency-analysis-without-numpy – ChristopheD

ответ

37

Библиотеки aubio были обернуты SWIG и поэтому могут использоваться Python. Среди их многочисленных функций есть несколько методов определения/оценки тона, включая алгоритм YIN и некоторые алгоритмы гребенки гребенки.

Однако, если вы хотите что-то более простое, я написал код для оценки основного тона некоторое время назад, и вы можете его взять или оставить. Это будет не так точно, как использование алгоритмов в aubio, но оно может быть достаточно хорошим для ваших нужд. Я в основном просто взял БПФ данных раз окно (окно Blackman в этом случае), в квадрате значений FFT, нашел бит, который имел самое высокое значение, и использовал квадратичную интерполяцию вокруг пика, используя журнал максимального значения и его двух соседних значений, чтобы найти основную частоту. Квадратическую интерполяцию я взял из какой-то бумаги, которую я нашел.

Он хорошо работает на тестовых тонах, но он не будет таким же надежным и точным, как другие методы, упомянутые выше. Точность может быть увеличена за счет увеличения размера куска (или уменьшения его уменьшения). Размер блока должен быть кратным 2, чтобы полностью использовать БПФ. Кроме того, я определяю только основной шаг для каждого фрагмента без перекрытия. Я использовал 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() 
+0

wow большое спасибо, это похоже на то, что я сделаю сейчас, я только понял, как читать аудио в реальном времени с входа auido (микрофон) – MatijaG

+2

Перейдите на сайт PyAudio http://people.csail.mit.edu/hubert/pyaudio/ и прокрутите страницу вниз к примерам. Вы увидите некоторых, которые берут входные данные от микрофона. –

+0

uhm может помочь мне фигурировать почему эта ошибка происходит: " требуется больше 0 значений для распаковки " по следующей строке " y0, y1, y2 = np.log (fftData [which-1: which + 2:]) " – MatijaG

0

Хотя я еще не пробовал обрабатывать аудио с Python раньше, возможно, вы могли бы создать что-то на основе SciPy (или его подпроекта NumPy), рамки для эффективного научного/инженерного численного расчета? Вы можете начать с просмотра scipy.fftpack для вашего БПФ.

+1

ok Я нашел это http://www.swharden.com/ blog/2010-03-05-realtime-fft-graph-of-audio-wav-file-or-microphone-input-with-python-scipy-and-wckgraph/теперь мне интересно, как я найду диапазон частот, который находится на самом высоком уровне (также SciPy немного помог – MatijaG

+0

, так что вы выяснили, как это сделать? –

6

Если вы собираетесь использовать FSK (frequency shift keying) для кодирования данных, вы, вероятно, лучше использовать Goertzel algorithm так что вы можете проверить только те частоты, которые вы хотите, вместо полный DFT/FFT.

Смежные вопросы