Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ifft(fft(audio)) is just noise

Tags:

numpy

fft

ifft

whether i just nest them (iff(fft(audio))) or try window-by-window (window the audio, do the fft, do the ifft, then invert the window, replacing zero with eps, then merge the samples back (trying abs here and there in the pipelines)) i get only noise.

i know the ifft is only inverse to the fft with infinite precision arithmetic, infinitely many samples, etc (right?) i'm working with 64bit floating point and 44kHZ sample rate. but, i would expect to be able to at least hear the original audio.

is my error practical or theoretical? i can give code, if it's a bug.

like image 989
sam boosalis Avatar asked Jan 29 '13 01:01

sam boosalis


Video Answer


1 Answers

Building on JoeKington's comment, I have downloaded this file, and tried the following

>>> import scipy.io.wavfile
>>> rate, data = scipy.io.wavfile.read('wahoo.wav')
>>> data
array([134, 134, 134, ..., 124, 124, 124], dtype=uint8)
>>> data_bis = np.fft.ifft(np.fft.fft(data))
>>> data_bis
array([ 134. +6.68519934e-14j,  134. -4.57982480e-14j,
        134. -1.78967708e-14j, ...,  124. -2.09835513e-14j,
        124. -1.61750469e-14j,  124. -2.14867343e-14j])
>>> data_bis = data_bis.astype('uint8')
C:\Users\Jaime y Eva\Desktop\stack_exchange.py:1: ComplexWarning: Casting complex values to real discards the imaginary part
  # -*- coding: utf-8 -*-
>>> data_bis
array([134, 133, 133, ..., 123, 123, 123], dtype=uint8)
>>> scipy.io.wavfile.write('wahoo_bis.wav', rate, data_bis)

And the resulting file plays exactly the same as the original one.

So turning the return complex values into reals is only half the problem (and you may want to go with np.abs rather than data.real, as the code above implicitly does), and you then also need to recast your floating point numbers to uints of the apropriate bit-depth.

like image 142
Jaime Avatar answered Sep 22 '22 04:09

Jaime