Попытка использовать БПФ для анализа звукового сигнала в Python - PullRequest
4 голосов
/ 13 марта 2012

Я пытался использовать БПФ для получения частоты сигнала, и у меня возникли некоторые проблемы с этим.Я нашел сайт, на котором говорилось об использовании БПФ для анализа и построения сигнала здесь:

http://macdevcenter.com/pub/a/python/2001/01/31/numerically.html?page=2

Но я столкнулся с проблемой, реализующей его с помощью Python 2.7.РЕДАКТИРОВАТЬ Я обновил код с улучшенной версией.На самом деле, этот работает и отображает осциллограммы (немного медленно) на графике.Мне интересно, если это правильный метод для чтения фреймов, хотя - я читал, что четные индексы массива для левого канала (и поэтому нечетные индексы будут для правого, я полагаю).

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

import scipy
import wave
import struct
import numpy
import pylab

fp = wave.open('./music.wav', 'rb')

samplerate = fp.getframerate()
totalsamples = fp.getnframes()
fft_length = 256 # Guess
num_fft = (totalsamples / fft_length) - 2

#print (samplerate)

temp = numpy.zeros((num_fft, fft_length), float)

leftchannel = numpy.zeros((num_fft, fft_length), float)
rightchannel = numpy.zeros((num_fft, fft_length), float)

for i in range(num_fft):

tempb = fp.readframes(fft_length / fp.getnchannels() / fp.getsampwidth());

up = (struct.unpack("%dB"%(fft_length), tempb))

temp[i,:] = numpy.array(up, float) - 128.0

temp = temp * numpy.hamming(fft_length)

temp.shape = (-1, fp.getnchannels())

fftd = numpy.fft.fft(temp)

pylab.plot(abs(fftd[:,1]))

pylab.show()

Музыка, которую я загружаю, это то, что я сделал сам.

РЕДАКТИРОВАТЬ: Итак, теперь я получаю аудиофайл, прочитанный через чтение кадров, и делю текущее число для чтения на числоканалов и количество бит на кадр.Я теряю какие-либо данные, делая это?Это единственный способ получить какие-либо данные вообще - в противном случае обработчик файлов будет читать слишком много данных в функции struct.unpack.Также я пытаюсь отделить левый канал от правого канала (получить данные FFT для каждого канала).Как мне это сделать?

1 Ответ

0 голосов
/ 13 марта 2012

Я давно не использовал версию numpy / numarray от scipy, но искал функцию frombuffer.Это гораздо проще использовать, чем пытаться перетасовать все данные через struct.unpack.Пример чтения данных с использованием numpy:

fp = wave.open('./music.wav', 'rb')
assert fp.getnchannels() == 1, "Assumed 1 channel"
assert fp.getsampwidth() == 2, "Assuming int16 data"
numpy.frombuffer(fp.getnframes(fp.readframes()), 'i2')

Имейте в виду, что в волновых файлах могут быть разные типы данных и несколько каналов, поэтому помните об этом при распаковке.

...