Fidelity of sound created from frequency domain data

41 Views Asked by At

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!

0

There are 0 best solutions below