I need to generate a white noise signal with Matlab that has a maximum frequency of 5, 10 and 20 Hz. I know one way is to create the signal, then do a fourier transform, adjust the signal frequency and then inverse transform the signal back to the time domain. I can't really figure out how to do that in Matlab. Any help at all would be great
I need to generate a white noise signal with Matlab that has a maximum frequency of 5, 10 and 20 Hz.
That's the same as saying "I need a perfect circle, but it has to have exactly three edges". White noise doesn't have maximum frequencies; it's white because it spans all your bandwidth with the same expected noise energy.
Now, I presume you want to say "I want to have noise that is shaped a bit like signals that center around 5, 10 and 20 Hz". You'd still have to define the spectral shape -- but for the sake of argument, I assume you want to have gaussian shaped frequency response around these frequencies with a bandwidth of 2 Hz, with a sampling frequency of 50 Hz (has to be twice the highest frequency your signal has[in the real signal case], or else you'll get aliasing).
You can simply do that by using matlabs filter design toolbox, and applying the resulting filter to your signal. Usually, you'd just design one filter and shift it in frequency, but that doesn't seem to be your level of expertise yet -- which indicates that experimenting is an extremely good approach to becoming accustomed to DSP. Go wild!
Related
I have modeled noise in frequency domain(used matlab fft) and the the original signal also in frequency domain. I would like to adaptively subtract the model noise from the signal. I tried using wiener2, but it seems to work in pixels or i have no idea as it returns the input signal.Please inform which algorithm i used on matlab for adaptive subtraction in frequency domain?
Also a follow up question: the signal and noise is subband from 1 to 20 hz out of total of 250 hz. Although i have corrected for correct bin size. I need to confirm once i apply filter to 1 to 20 hz on the signal using noise model, do i need to replace these bins to the original full bins of the signal?
thanks
I'm trying to make a realtime(ish) monophonic guitar to midi program. I want a latency of <=6 milli secs. To find what note was played i aim to sample 256 points (should take approx 6 millis) , run an fft and analyze mag plot to determine pitch of note played.
When i do this in matlab, it gives me back very unstable/inaccurate results with peaks appearing in random places etc.
The note being inputted is 110Hz sampled # 44.1khz. I've applied a high pass filter at 500hz with a roll off of 48db/octave.. so only the higher harmonics of signal should remain. The audio last for 1 second ( filled with zeros after 256 samples)
Code:
%fft work
guitar = wavread('C:\Users\Donnacha\Desktop\Astring110hz.wav');
guitar(1:44100);
X = fft(guitar);
Xmag = abs(X);
plot(Xmag);
Zoomed in FFT plot
I was hoping to see all the harmonics of 110Hz (A note on guitar) starting at >500hz..
How would i achieve accurate results from an FFT with such little data?
You can't. (at least reliably for all notes in a guitar's range).
256 samples at 44.1kHz is less than one period of most low string guitar notes. One period of vibration from a guitar's open low E string takes around 535 samples, depending on the guitar's tuning and intonation.
Harmonics often require multiple periods (repetitions) of a guitar note waveform within the FFT window in order to reliably show up in the FFT's spectrum. The more periods within the FFT window, the more reliably and sharper the harmonics show up in the FFT spectrum. Even more periods are required if the data is Von Hann (et.al.) windowed to avoid "leakage" windowing artifacts. So you have to pick the minimum number of periods needed based on the lowest note needed, your window type, and your statistical reliability and frequency resolution requirements.
An alternative is to concatenate several sets of your 256 samples into a longer window, at least as long as several periods of the lowest pitch you want to reliably plot.
I am working with biological signal data, and am trying to count the number of regions with a high density of high amplitude peaks. As seen in the figure below, the regions of interest (as observed qualitatively) are contained in red boxes and 8 such regions were observed for this particular trial. The goal is to mathematically achieve this same result in near real time without the intervention or observation of the researcher.
The data seen plotted below is the result of raw data from a 24-bit ADC being processed by an FIR filter, with no other processing yet being done.
What I am looking for is a method, or ideally code, to help me detect such regions as identified while subsequently ignoring some of the higher amplitude peaks in between the regions of interest (i.e. between regions 3 and 4, 5 and 6, or 7 and 8 there is a narrow region of high amplitude which is not of concern). It is worth noting that the maximum is not known prior to computation.
Thanks for your help.
Data
https://www.dropbox.com/s/oejyy6tpf5iti3j/FIRData.mat
can you work with thresholds?
define:
(1) "amplitude threshold": if the signal is greater than the threshold it is considered a peak
(2) "window size" : of a fixed time duration
algorithm:
if n number of peaks was detected in a duration defined in "window size" than consider the signal within "window size" as cluster of peaks.(I worked with eye blink eeg data this way before, not sure if it is suitable for your application)
P.S. if you have data that are already labelled by human, you can train a classifier to find out your thresholds and window size.
Does it make sense in your problem to have some sort of "window size"? In other words, given a region of "high" amplitude, if you shrink the duration of the region, at what point will it become meaningless to your analysis?
If you can come up with a window, just apply this window to your data as it comes in and compute the energy within the window. Then, you can define some energy threshold and perform simple peak detection on the energy signal.
By inspection of your data, the regions with high amplitude peaks are repeated at what appears to be fairly uniform intervals. This suggests that you might fit a sine or cosine wave (or a combination of the two) to your data.
Excuse my crude sketch but what I mean is something like this:
Once you make this identification, you can use the FFT to get the dominant spatial frequencies. Keep in mind that the spatial frequency spectrum of your signal may be fairly complex, due to spurious data, but what you are after is one or two dominant frequencies of your data.
For example, I made up a sinusoid and you can do the calculation like this:
N = 255; % # of samples
x = linspace(-1/2, 1/2, N);
dx = x(2)-x(1);
nu = 8; % frequency in cycles/interval
vx = (1/(dx))*[-(N-1)/2:(N-1)/2]/N; % spatial frequency
y = sin(2*pi*nu*x); % this would be your data
F = fftshift(abs(fft(y))/N);
figure; set(gcf,'Color',[1 1 1]);
subplot(2,1,1);plot(x,y,'-b.'); grid on; xlabel('x'); grid on;
subplot(2,1,2);plot(vx,F,'-k.'); axis([-1.3*nu 1.3*nu 0 0.6]); xlabel('frequency'); grid on;
Which gives:
Note the peaks at ± nu, the dominant spatial frequency. Now once you have the dominant spatial frequencies you can reconstruct the sine wave using the frequencies that you have obtained from the FFT.
Finally, once you have your sine wave you can identify the boxes with centers at the peaks of the sine waves.
This is also a nice approach because it effectively filters out the spurious or less relevant spikes, helping you to properly place the boxes at your intended locations.
Since I don't have your data, I wasn't able to complete all of the code for you, but the idea is sound and you should be able to proceed from this point.
I'm working on a control system that measures the movement of a vibrating robot arm. Because there is some deadtime, I need to look into the future of the somewhat noisy signal.
My idea was to use the frequencies in the sampled signal and produce a fourier function that could be used for extrapolation.
My question: I already have the FFT of the signal vector (containing 60-100 values e.g.) and can see the main frequencies in the amplitude spectrum. Now I want to have a function f(t) which fits to the signal, removes some noise, and can be used to predict the near future of the signal. How do I calculate the coefficients for the sine/cosine functions out of the complex FFT data?
Thank you so much!
AFAIR FFT essentially produces output as a sum of sine functions with different frequencies. The importance of each frequency is the height of each peak. So what you really want to do here is filter out some frequencies (ie. high frequencies for the arm to move gently) and then come back to the time domain.
In matlab this should be like going through the vector of what you got from fft, setting some values to 0 (or doing something more complex to it) and then use ifft to come back to time domain and make the prediction based on what you get.
There's also one thing you should consider while doing this - Nyquist frequency - this means that the highest frequency that you get on your fft is half of the sampling frequency.
If you use an FFT for data that isn't periodic within the FFT aperture length, then you may need to use a window to reduce spurious frequencies due to "spectral leakage". Frequency estimation techniques to better estimate "between bin" frequency content may also be appropriate. The phase of each cosine sinusoid, relative to the edge of the window, is usually atan2(imag[i], real[i]). The frequency depends on the sample rate and bin number versus the length of the FFT.
You might also want to look into using a Kalman filter instead of an FFT.
Added: If your signal isn't exactly integer periodic in the FFT length, then you may want to do an fftshift before the FFT to move the resulting phase measurement reference point to the center of your data vector, instead of a possibly discontinuous circular edge.
I want to remove noises from a recorded sound and make the fft of it finding fundamental frequencies of that sound, but I don't know how to remove those noises. I'm recording the sound of falling objects from different heights. I want to find the relation between the height and the maximum frequency of the recorded sound.
[y,fs]=wavread('100cmfreefall.wav');
ch1=y(:,1);
time=(1/44100)*length(ch1);
t=linspace(0,time,length(ch1));
L=length(ch1);
NFFT = 2^nextpow2(L); % Next power of 2 from length of y
Y = fft(y,NFFT)/L;
Y1=log10(Y);
figure(1)
f = fs/2*linspace(0,1,NFFT/2+1);
plot(f,2*abs(Y1(1:NFFT/2+1))) ;
[b,a]=butter(10,3000/(44100/2),'high');
Y1=filtfilt(b,a,Y1);
% freqz(b,a)
figure(2)
plot(f,2*abs(Y1(1:NFFT/2+1))) ;
title('Single-Sided Amplitude Spectrum of y(t)');
xlabel('Frequency (Hz)');
ylabel('|Y(f)|')
xlim([0 50000])
% soundsc(ch1(1:100000),44100)
Saying that there is noise in your signal is very vague and doesn't convey much information at all. Some of the questions are:
Is the noise high frequency or low frequency?
Is it well separated from your signal's frequency band or is it mixed in?
Does the noise follow a statistical model? Can it be described as a stationary process?
Is the noise another deterministic interfering signal?
The approach you take will certainly depend on the answers to the above questions.
However, from the experiment setup that you described, my guess is that your noise is just a background noise, that in most cases, can be approximated to be white in nature. White noise refers to a statistical noise model that has a constant power at all frequencies.
The simplest approach will be to use a low pass filter or a band pass filter to retain only those frequencies that you are interested in (a quick look at the frequency spectrum should reveal this, if you do not know it already). In a previous answer of mine, to a related question on filtering using MATLAB, I provide examples of creating low-pass filters and common pitfalls. You can probably read through that and see if it helps you.
A simple example:
Consider a sinusoid with a frequency of 50 Hz, sampled at 1000 Hz. To that, I add Gaussian white noise such that the SNR is ~ -6dB. The original signal and the noisy signal can be seen in the top row of the figure below (only 50 samples are shown). As you can see, it almost looks as if there is no hope with the noisy signal as all structure seems to have been destroyed. However, taking an FFT, reveals the buried sinusoid (shown in the bottom row)
Filtering the noisy signal with a narrow band filter from 48 to 52 Hz, gives us a "cleaned" signal. There will of course be some loss in amplitude due to the noise. However, the signal has been retrieved from what looked like a lost cause at first.
How you proceed depends on your exact application. But I hope this helped you understand some of the basics of noise filtering.
EDIT
#Shabnam: It's been nearly 50 comments, and I really do not see you making any effort to understand or at the very least, try things on your own. You really should learn to read the documentation and learn the concepts and try it instead of running back for every single error. Anyway, please try the following (modified from your code) and show the output in the comments.
[y,fs]=wavread('100cmfreefall.wav');
ch1=y(:,1);
time=(1/fs)*length(ch1);
t=linspace(0,time,length(ch1));
L=length(ch1);
NFFT = 2^nextpow2(L);
f = fs/2*linspace(0,1,NFFT/2+1);
[b,a]=butter(10,3e3/(fs/2),'high');
y1=filtfilt(b,a,ch1);
figure(1)
subplot(2,1,1)
Y=fft(ch1,NFFT)/L;
plot(f,log10(abs(Y(1:NFFT/2+1))))
title('unfiltered')
subplot(2,1,2)
Y1=fft(y1,NFFT)/L;
plot(f,log10(abs(Y1(1:NFFT/2+1))))
title('filtered')
Answer to your question is highly dependent on the characteristics of what you call "noise" - its spectral distribution, the noise being stationary or not, the source of the noise (does it originate in the environment or the recording chain?).
If the noise is stationary, i.e its statistical characteristics do not change over time, you can try recording a few seconds (10-15 is a good initial guess) of noise only, preform FFT, and then subtract the value of the noise in FFT bin n from your measurement FFT bin n.
You can read some background here: http://en.wikipedia.org/wiki/Noise_reduction