I'm working with some audio files in Python using scipy.fftpack and scipy.io packages. What this implies is I have wave files that I am importing, playing around with them using Fourier transforms, and then outputting to a new wave file. I am however having running into issues where in after running these transforms, the wave file will not play and is roughly 4 times the size of the original file.
Currently I'm just importing the song, taking the rate, data pieces from the import, doing ifft(fft(data)) and then outputting this. I have tried taking these float values and converting it to integers and calculating the difference between the initial imported data and the ifft(fft(data)) and saw that it was exactly zero.
So following are questions I have:
Would anyone know why the wave files I am attempting to play after doing fourier transforms won't play?
Are there any restrictions on wave files that coud be causing a issues in general. Or does the data have to be in integers?
It's late and I feel like my post may be scatter-brained, so if you need more information please ask and I will do my best to give better description.
You need to convert your data after processing to an integer type of appropriate bit depth. Using this file as an example:
>>> import scipy.io.wavfile
>>> rate, data = scipy.io.wavfile.read('Happy Tree Friends.wav')
>>> rate
8000
>>> data
array([ 5, -5, 5, ..., 0, -1, 0], dtype=int16)
>>> data_bis = np.fft.ifft(np.fft.fft(data))
>>> data_bis
array([ 5.00000000e+00 -1.55406753e-11j,
-5.00000000e+00 +1.95349676e-11j,
5.00000000e+00 +1.41131140e-11j, ...,
8.06674092e-12 -7.58643463e-13j,
-1.00000000e+00 -2.21611283e-12j, -2.04999489e-11 +4.55890751e-12j])
>>> data_bis.dtype
dtype('complex128')
Even though the values in data
are really close to the ones in data_bis
, they are very different beasts, as the following shows:
>>> scipy.io.wavfile.write('test.wav', rate, data_bis)
>>> scipy.io.wavfile.read('test.wav')
TypeError: data type not understood
But if you simply convert your processed results back to the original dtype
, everything works nicely again:
>>> scipy.io.wavfile.write('test.wav', rate, data_bis.astype(data.dtype))
__main__:1: ComplexWarning: Casting complex values to real discards the imaginary part
>>> scipy.io.wavfile.read('test.wav')
(8000, array([ 4, -5, 4, ..., 0, -1, 0], dtype=int16))