Обнаружение частоты Python - PullRequest
32 голосов
/ 15 апреля 2010

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

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

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

Ответы [ 4 ]

41 голосов
/ 16 апреля 2010

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

Однако, если вы хотите что-то более простое, я написал некоторый код для оценки высоты тона некоторое время назад, и вы можете взять его или оставить. Это не так точно, как использование алгоритмов в aubio, но может оказаться достаточно для ваших нужд. Я в основном просто взял FFT данных, умноженных на окно (в данном случае это окно 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()
6 голосов
/ 05 мая 2011

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

0 голосов
/ 04 июля 2019

Вы можете найти частотный спектр скользящих окон над вашим звуком из здесь , а затем проверить наличие преобладающей полосы частот, найдя область под кривой частотного спектра для этой полосы из здесь .

0 голосов
/ 15 апреля 2010

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

...