Trying to use FFT to parse audio in Python

I am trying to use FFT to get the signal frequency, and I am having problems with this. I found a site that talked about using FFT to analyze and plot the signal here:

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

But I ran into a problem implementing it with Python 2.7. EDIT I ​​updated the code with an improved version. This actually works, and the graphs of the chart (a bit slow) on the chart. I am wondering if this is the correct method for reading frames, although I read that even the numbered array indices for the left channel (and therefore the odd numbers will be for the right ones, I suppose).

So, I assume that I should read as many frames, but divide it by the sample width, and then try every other even frame for the left channel, if it is stereo, huh?

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

The music I download is what I did myself.

EDIT: So now I get the audio file by reading frames and dividing the current number by reading by the number of channels and the number of bits per frame. Am I losing any data by doing this? This is the only way to get any data at all - otherwise there would be too much data for the file handler to read in the struct.unpack function. In addition, I am trying to separate the left channel from the right channel (to receive FFT data for each channel). How can i do this?

+4
source share
1 answer

I have not used the scipy version of numpy / numarray for a long time, but I am looking for the frombuffer function. This is much easier to use than trying to shuffle all data with struct.unpack . An example of reading data using 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') 

Keep in mind that wave files can have different types of data in them and several channels, so keep this in mind when unpacking.

0
source

Source: https://habr.com/ru/post/1401233/


All Articles