0

I know it is possible to create .wav file from frequency domain data (magnitude + phase) but I would like to know how close would that be to the real(orginal) sound ? Does it depend on the frequency step for example (or something else).

Second question: I need to write a code that takes a frequency domain data (magnitude + phase) to build a wav file. In order to do so, I started by the following code which creates a fake signal --> fft (at this point I have the kind of input(mag + phase) that I would expect for my target code). But it doesn't seem top work fine, could you please help

import numpy as np 
from scipy import pi 
import matplotlib.pyplot as plt
#%matplotlib inline
from scipy.fftpack import fft 

min=0
max=400

def calculateFFT (timeStep,micDataX,micDataY):

    n=micDataX.size

    FFT=np.fft.fft(micDataY)
    fft_amlitude=2*abs(FFT)/n
    fft_phase=np.angle(FFT)
    fft_freq= np.fft.fftfreq(n, d=timeStep) #not used created manually (7 lines) check pi_fFreqDomainCreateConstantBW it is kept here to compare sizes 
    upper_bound=int((n)/2)

    return fft_freq[1:upper_bound],fft_amlitude[1:upper_bound],fft_phase[1:upper_bound]


def calculateI_FFT (n,amplitude_spect,phase_spect):

    data=list()

    for mag,phase in zip(amplitude_spect,phase_spect):
        data.append((mag*n/2)*(np.cos(phase)+1j* np.sin(phase)))
    full_data=list(data)
    i_data=np.fft.irfft(data)
    return i_data

#sampling rate and time vector
start_time=0 #sec
end_time= 2 
sampling_rate=1000 #Hz
N=(end_time-start_time)*sampling_rate 

#Freq domain peaks
peak1_hz=60 # freq of peak 
peak1_mag= 25 

peak2_hz=270 # freq of peak 
peak2_mag= 2 

#Vibration data generation
time =np.linspace(start_time,end_time,N)
vib_data=peak1_mag*np.sin(2*pi*peak1_hz*time)+peak2_mag*np.sin(2*pi*peak2_hz*time)

#Data plotting 
plt.plot(time[min:max],vib_data[min:max])

# fft 
time_step=1/sampling_rate
fft_freq,fft_data,fft_phase=calculateFFT(time_step,time,vib_data)

#ifft 
i_data=calculateI_FFT(N,fft_data,fft_phase)

#plotting
plt.plot(time[min:max],i_data[min:max])
plt.xlabel("Time (s)")
plt.ylabel("Vibration (g)")
plt.title("Time domain")


plt.show()

The output signal screenshot is attached (blue for original signal Orange for the reconstructed one) enter image description here

Thank you!

Paul R
  • 208,748
  • 37
  • 389
  • 560
Ragnar
  • 1
  • 3
  • How close to what "real sound" ? – Paul R Aug 08 '18 at 08:38
  • At modern sampling rates, assuming the samples are all within the amplitude available to the both the file format and the reproduction hardware, the difference between sampled sound and "real" waveform sound is imperceptible to human ear. – Amadan Aug 08 '18 at 08:44
  • @PaulR I mean original sound – Ragnar Aug 08 '18 at 10:33
  • You mean if you go `sound.orig -> FFT -> IFFT -> sound.new`, will there be any noticeable difference between `sound.orig` and `sound.new` ? The answer is no, so long as you take care of any scaling factors in the FFT/IFFT and use sufficient precision. – Paul R Aug 08 '18 at 12:00
  • @PaulR thank you for your answer, this is the full process for testing, what if I start directly from a frequency domain data (so I don't know how it was converted) would I be able to get the original sound ? – Ragnar Aug 08 '18 at 13:03
  • Yes, this is a fairly standard way of synthesising time domain waveforms. – Paul R Aug 08 '18 at 13:12

0 Answers0