When we use following Matlab function
signal=awgn(signal,5,'measured')
How much SNR do we have added to original signal?
I mean the SNR is 5 dB?
How can I add 20 dB noise to signal by using this command?
Like Dan has mentioned in the comments, the second argument is used to set the value of SNR.
However, this is under the assumption that your signal has a power of 0 dBW. In case the signal power is different, you need to increase (or decrease) the value of the snr argument appropriately.
Related
How can I make gaussian noise with mean= 18 and variance= 0.1 in simulink? I can't use AWGN block since I'm not able to specify mean value in it.
I want to generate the below signal which is gaussian noise with mean= 18 and variance= 0.1:
Construct the model as follows. From the Library Browser select the DSP System Toolbox, then choose the Random Source block.
Now, adjust the block parameters Source type, Mean and Variance:
Construct the model by adding a Scope block as follows:
After running the model for 10 sec., you will see the generated Gaussian noise waveform by double-clicking the Scope block. You will notice the plot is not similar to the image you posted, this is how the default plot works in Simulink.
Now, to make sure it's the correct signal, send the signal to MATLAB using the To Workspace block and plot it. This is how this noise waveform is plotted in MATLAB, the same as your image.
The mean just says how much the noise is shifted so if you take a constant function of value 18 and then add a gaussian noise of variance .1 you will get what you want.
This is assuming your noise is one-dimensional:
variance = 0.1;
std_deviation = sqrt(variance);
mean = 18;
n = 1000; % number of samples
noise = std_deviation .* randn(n, 1) + mean;
I have a signal like this
And now i need to mark the points that are considered noisy in the signal. How to do that?
Noisy parts are just as shown in the zoomed in version of the plot and how to mark the noisy points in this signal by using matlab?
Following code might work:
array=abs([0 diff(signal)])
threshold_for_noisy=15
for i=1:size(array,2)
if array(i)>threshold_for_noisy
noisy_ind(i)=1;
else
noisy_ind(i)=0;
end
end
abnormal=zeros(1,size(array,2));
ch_pt=find(noisy_ind==1)
for i=1:2:size(ch_pt,2)-1
abnormal(ch_pt(i):ch_pt(i+1))=1
end
The elements in abnormal will be 1 whenever your signal exceeds the threshold and continues until it reaches back to normal (threshold_for_noisy).
Since the dataset you presented here doesn't have too much variance, simple comparison of past-future values as I suggested in my code will work. But if you have higher variance in your data, you can consider using a built-in function from Signal Processing Toolbox.
See Matlab ischange function documentation
Is the Matlab code available anywhere?
I'm trying to understand what exactly does it do. As I understood, it divides the data into segments with length tau (when tau increases each time) and then averages the data within each segment. After that, it compares the value attained from successive segments.
Am I correct in my understanding?
Thanks in advance!
You can view the code by typing edit allanvar into the command window.
Of course, this assumes you've already downloaded the associated toolbox.
I tried the same approach, but was also UNable to open the allanvar.p file. Despite the documentation I've found, if I use simple white noise and run allanvar on it, when I plot sqrt(this output), I get a line with a slope of -1/2 on a log-log scale (one order of magnitude drop in ADEV for two orders of magnitude increase in averaging interval value). A simple program to compute the OVERLAPPING Allan variance yields a -1/1 slope. Thus I am suspicious that the allanvar function does not compute the overlapping version!
I want to analyze an audiodata (.wav with pcm, 32k as sampling rate) and create the psd of it with the axes Sxx (watts/hertz not db) and f (hertz).
So I would start by reading out the audiodata with:
[x,fs]=audioread('test.wav');
After this I'm having some problems because I dont really know how to proceed and also Matlab always tells me that psd functions won't be supported in the future and that I should use pwelch.. (also tried to build the autocorr and afterwards use fourier to get to the Sxx but it didn't work out really well)
So could anybody tell me how I can get from my vector x to a vector with the psdvalues in watts/hertz and plot it afterwards?
very grateful for every kind of help! :)
Update1: Yes I did read the documentation of pwelch but I'm afraid my english is too bad to understand it completly.
So if I use the psd documentation:
nfft = 2^nextpow2(length(x));
Pxx = abs(fft(x,nfft)).^2/length(x)/fs;
Hpsd = dspdata.psd(Pxx(1:length(Pxx)/2),'fs',fs);
plot(Hpsd)
I'm able to get the plot in db with the peak at the right frequency. (I dont know how dspdata.psd work though)
I tried out:
[Pyy,f]=pwelch(x,fs)
plot(Pyy)
this gives me a non db-scale but the peak is at the wrong frequency
Update 2:
First of all, thanks a lot for your detailed answer! At the moment I'm working on my matlabskills as well as my english language but all the specific technical terms give me a hard time..
When using your example of pwelch on a wav-data with a clear frequency of 1khz, the plot shows me the peak at round about 0.14, could it maybe still be a special-scaled x-axis?
If I try it this way:
[y,fs]=audioread('test.wav');
N=length(y);
bin_vals=0:N-1;
fax_Hz= bin_vals*fs/N;
N_2=ceil(N/2);
Y=fft(y);
pyy=Y.*conj(Y);
plot(fax_Hz(1:N_2),pyy(1:N_2))
the result seems right (is this way correct?), but I still need some time to search for a proper way to display the y-axis in W/Hz, since I dont know how the audiosignal was created.
Update 3:
http://s000.tinyupload.com/index.php?file_id=33803229773204653857
This wav file should have a dominant frequency at 1khz with a duration of 3 seconds and a sampling frequency of 44100Hz. (If I plot the data received from audioread the oscillation seems reasonable)
with
[y,fs]=audioread('1khz.wav');
[pyy,f]=pwelch(y,fs);
plot(f,pyy)
I get a peak at 0.14 on the x-axis.
if I use
[y,fs]=audioread('1khz.wav');
[pyy,f]=pwelch(y,[],[],[],fs);
plot(f,pyy)
instead, the peak is at the 1000. Is this way right? And how could I interpret the difference scaling on the y-axis? (pwelch vs. square of abs)
I also wanted to ask if it is possible to get a flat psd of awgn in matlab? (since you just have finite elements I don't know to get there)
Thanks again for your detailed support!
Update 4
#A.Donda
So I have a new Problem for which I think it is probably necessary to go a bit more into detail. So my plan is basically to do the following:
Read and Audiodata ([y,fs]) and generate white Noise with a certain SNR ([n,fs])
Generate a Filter H which shapes the PSD(y) similiar to the PSD(n)
Generate an inverse Filter G=H^(-1) which reverts the effect of H.
My problem is that with using pwelch, the resulting vectorlength of pyy is way smaller than the vectorlength of y. Since my Filter is determined by P=sqrt(pnn/pyy), I can't multiply fft(y)*H and therefore get no results.
Do you know any help for this Problem?
Or is there a way to go back from a PSD (Welch estimated) to a normal signal (like an inverse function for pwelch)?
In the example you have from the psd documentation, you compute a psd estimate yourself, then put it into a dspdata.psd container and plot it. What dspdata.psd data does here for you is basically compute the frequency axis and provide it to the plot command, nothing more. You get a plot of the spectral density estimate, but that's the one you compute yourself using fft, which is the simplest and worst psd estimate you can get, a so-called periodogram.
Your use of pwelch is almost correct, you just forgot to use the frequency axis information in your plot.
[Pyy,f]=pwelch(x,fs)
plot(f,Pyy)
should give you the peak at the correct frequency.
Your use of pwelch is almost correct, but you have to give the sampling frequency as the 5th argument, and then use the frequency axis information in your plot.
[Pyy,f]=pwelch(y,[],[],[],fs);
plot(f,Pyy)
should give you the peak at the correct frequency.
What pwelch gives you is the spectral density of the signal over Hz. Correct axis labels would therefore be
xlabel('frequency (Hz)')
ylabel('psd (1/Hz)')
The signal you give pwelch is a pure sequence of numbers without physical dimensions. By specifying the sampling rate, the time axis gets a physical unit, s, therefore the resulting frequency is in Hz and the density is in 1/Hz. But still your time series values have no physical dimension, and therefore the density cannot be related to something like W. Has your audiosignal been obtained by a calibrated A/D converter? If yes, you should be able to relate your data to a physical dimension and units, but that's a nontrivial step.
On a personal note, I'd really advise you to brush up on your English, because using software, especially programming interfaces, without properly understanding the documentation is a recipe for disaster.
I'm trying to generate an AR(2) process with MATLAB's filter() function, as shown here:
A=[1 -2.7607 3.8106 -2.6535 0.9238];
% AR(4) coefficients
y=filter(1,A,0.2*randn(1024,1));
% Filter a white noise input to create AR(4) process
[ar_coeffs,nv] =arburg(y,4);
%compare the results in ar_coeffs to the vector A.
I have a time series data set and would like to approximately match the 'total' variance of the data in a simulated data set. When I use nv in place of 0.2 in the second line of code, I get a variance in the simulated that is much too small.
Can anyone help me rectify this situation to generate a look-alike simulated AR(N) data set?
Thanks,
Mark
If you look at nv in this example it is 0.0392, this is variance. To create a white noise with variance a^2 you need to multiply that sequence by a. If a^2 = 0.392 then a is 0.198 (very close to 0.2). So Colin T is right and you need to multiply your randn(1024,1) by sqrt(nv) not by nv.