[Math] editing signal in frequency domain and converting back to time domain

fourier analysisMATLAB

editing signal in frequency domain and converting back to time domain
the code is matlab / open source octave code

Greetings All

I would like to be able to edit different aspects of a signal
(frequency, magnitude) in the frequency domain is this possible?
I do know about fft and ifft which work great but I'm a little
confused as how to edit the data in the frequency domain and properly
get it back out in the time domain. I can get it out using ifft but
when
I try and edit the signal in the frequency domain and plot it in the
time domain the values
are very different.

Example: I create an array with the variables frequency, magnitude.
created from the frequency domain I then want to change the magnitude
of one of the frequencies
and then convert the signal back to the time domain.

I was reading up on it and it had mentioned using phase some how
phase = unwrap(angle(ya)); the problem is that the phase array
is twice as long as the array for the frequency and magnitude.

code below:

%signal from frequency domain to time domain
clear all,clf
%addpath("/home/transform/"); %add path to location of functions
%create time domain
Fs = 1000;                    % Sampling frequency
t=linspace(0,1,1000);

%1a create signal
ya = .5*sin(2*pi*10*t) + 1*sin(2*pi*50*t);
ya_fft = fft(ya);

%Original data in frequency domain
[xfreqa,yampa]=rtplotfft(ya,Fs);
yampa1=(yampa(:,1)/max(abs(yampa(:,1)))*1); %keep at 1, amplitude
levels adjustied
phase = unwrap(angle(ya_fft));

%Create array with Freq,magnitude
freq_mag_phase=[xfreqa yampa]; %can't add phase because length is to
large

%Edit data in frequency domain
freq_mag_phase(52,2)=[.1] ; %changes amplitude to .1
[xfreqb,yampb]=rtplotfft(ya,Fs); %not sure what to replace ya with?
yampb1=(yampb(:,1)/max(abs(yampb(:,1)))*1); %keep at 1, amplitude
levels adjustied

%3a frequency back to time domain
ya_ifft=real(ifft(ya_fft));

%1b time domain plot
subplot(2,2,1),plot(t,ya)
title('1) Orginal Signal ')
ylabel('amplitude')
xlabel('time domain')

%2b frequency domain plot.
subplot(2,2,2),plot(xfreqa,yampa)
title('2) Orginal signal in Frequency domain')
xlabel('Frequency (Hz)')
ylabel('amplitude')

%3b rebuilt time domain from frequency (ifft)
subplot(2,2,3),plot(t,ya_ifft)
title('3) rebuild time domain using ifft but it hasnt been edited')
xlabel('time domain ')
ylabel('amplitude')

%4b rebuilt of signal in frequency (ifft)
subplot(2,2,4),plot(xfreqb,yampb)
title('4) rebuild in frequency domain not edited')
xlabel('Frequency (Hz)')
ylabel('amplitude')

fprintf('done');

I've also included the function rtplotfft that is used
to create the frequency and magnitude plot:

function [x,freq]=rtplotfft(vp_sig_orig,Fs)
       vp_sig_orig=vp_sig_orig';
       vp_sig_len=length(vp_sig_orig); %get sample rate from vp fs_rate
needs to be an even number?

       % Use next highest power of 2 greater than or equal to length(x) to
calculate FFT.
       nfft= 2^(nextpow2(length(vp_sig_orig)));

       % Take fft, padding with zeros so that length(fftx) is equal to nfft
       fftx = fft(vp_sig_orig,nfft);

       % Calculate the number of unique points
       NumUniquePts = ceil((nfft+1)/2);

       % FFT is symmetric, throw away second half
       fftx = fftx(1:NumUniquePts);

       % Take the magnitude of fft of x and scale the fft so that it is not
a function of the length of x
       mx = abs(fftx)/length(vp_sig_orig);

       % Take the square of the magnitude of fft of x.
       %mx = mx.^2; rem'd out to get amplitude to work

       % Since we dropped half the FFT, we multiply mx by 2 to keep the same
energy.
       % The DC component and Nyquist component, if it exists, are unique
and should not be multiplied by 2.
       if rem(nfft, 2) % odd nfft excludes Nyquist point
       mx(2:end) = mx(2:end)*2;
       else
       mx(2:end -1) = mx(2:end -1)*2;
       end

       freq=mx;

       % This is an evenly spaced frequency vector with NumUniquePts
points.
       freq_vect = (0:NumUniquePts-1)*vp_sig_len/nfft;
       x=freq_vect';

Best Answer

This code can do this

%Voiceprint raise lower freq phase conjugate signal
tic
clear all, clc,clf,tic
%% Sound /beep calculation complete
filerawbeepStr='calculations_complete.wav';
filerawbeeppathStr='/home/rat/Documents/octave/raw/';
filevoiceprepathStr='/home/rat/Documents/octave/eq_research/main/transform/voice/';
filewavpathStr='/home/rat/Documents/octave/eq_research/main/transform/wav/';
[ybeep, Fsbeep, nbitsbeep] = wavread(strcat(filerawbeeppathStr,filerawbeepStr));
%addpath(”/home/rat/Documents/octave/eq_research/main/transform/”); %add path to location of functions

%1a voice print import
[vp_sig_orig, fs_rate, nbitsraw] = wavread(strcat(filevoiceprepathStr,'voice8000fs.wav')); 

%vp_sig_orig=vp_sig_orig’;
vp_sig_len=length(vp_sig_orig);

%2a create frequency domain
ya_fft = fft(vp_sig_orig);
vp_sig_phase_orig = unwrap(angle(ya_fft));

%get Magnitude
ya_fft_mag = abs(ya_fft);

%3a frequency back to time domain
ya_ifft=real(ifft(ya_fft));

%Back to Time domain
vp_sig_new=real(ifft(ya_fft_mag.*exp(i*vp_sig_phase_orig)));

subplot(3,1,1), plot(vp_sig_orig),title('1 original time domain')
subplot(3,1,2), plot(ya_ifft),title('2 rebuild time domain')
subplot(3,1,3), plot(vp_sig_new),title('3 adjusted time')
Related Question