Pergunta

Ok, o que estou tentando fazer é um tipo de software de processamento de áudio que pode detectar uma frequência predominante e se a frequência for tocada por tempo suficiente (poucos MS), sei que tenho uma correspondência positiva. Sei que precisaria usar FFT ou algo semelhante, mas nesse campo de matemática eu sou péssimo, pesquisei na Internet, mas não encontrei um código que pudesse fazer apenas isso.

A meta que estou tentando acertar é fazer de mim um protocolo personalizado para enviar o som de dados, preciso de uma taxa de bits muito baixa por segundo (5-10bps), mas também sou muito limitado no final da transmissão, para que o software de recebimento precise ser capaz de ser personalizado ( não posso usar um modem de hardware/software real) também quero que este seja apenas software (sem hardware adicional, exceto o cartão sonoro)

Muito obrigado pela ajuda.

Foi útil?

Solução

o Aubio As bibliotecas foram embrulhadas com SWIG e, portanto, podem ser usadas pelo Python. Entre seus muitos recursos, incluem vários métodos para detecção/estimativa de tom, incluindo o Yin Algoritmo e alguns algoritmos de pente harmônicos.

No entanto, se você quiser algo mais simples, escrevi algum código para estimativa de afinação há algum tempo e você pode levá -lo ou deixá -lo. Não será tão preciso quanto usar os algoritmos em Aubio, mas pode ser bom o suficiente para suas necessidades. Basicamente, peguei a FFT dos Dados Times uma janela (uma janela Blackman neste caso), quadrei os valores da FFT, encontrei a lixeira que tinha o valor mais alto e usei uma interpolação quadrática ao redor do pico usando o log do valor máximo e seus dois valores vizinhos para encontrar a frequência fundamental. A interpolação quadrática que tirei de algum artigo que encontrei.

Funciona bastante bem em tons de teste, mas não será tão robusto ou preciso quanto os outros métodos mencionados acima. A precisão pode ser aumentada aumentando o tamanho do pedaço (ou reduzido diminuindo -o). O tamanho do pedaço deve ser um múltiplo de 2 para fazer pleno uso da FFT. Além disso, estou apenas determinando o tom fundamental para cada pedaço sem sobreposição. Eu usei Pyaudio para reproduzir o som enquanto escrevia o campo estimado.

Código fonte:

# 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()

Outras dicas

Se você vai usar FSK (Keying de mudança de frequência) Para codificar dados, você provavelmente é melhor usar o Algoritmo Goertzel Assim, você pode verificar apenas as frequências desejadas, em vez de um DFT/FFT completo.

Você pode encontrar o espectro de frequência das janelas deslizantes sobre o seu som de aqui e então verifique a presença da banda de frequência prevalente através de encontrar a área sob a curva de espectro de frequência para essa banda aqui.

Embora eu não tenha experimentado processamento de áudio com Python antes, talvez você possa construir algo baseado em Scipy (ou seu subprojeto Numpy), uma estrutura para computação numérica científica/engenharia eficiente? Você pode começar olhando para scipy.fftpack para o seu FFT.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top