Take the 2-minute tour ×
Mathematics Stack Exchange is a question and answer site for people studying math at any level and professionals in related fields. It's 100% free, no registration required.

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';
share|improve this question
    
You might want to post this at StackOverflow as well, for more answers (or even avp.stackexchange.com under signal-processing). –  Jodles Sep 1 '11 at 23:01
2  
This should be on dsp.stackexchange.com –  endolith Dec 2 '11 at 21:10
    
How come this question has over 1k views?? –  Rahul Jul 28 '13 at 2:50

1 Answer 1

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')
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.