Masking Audio STFT Matlab - matlab

I want to implantation a masking time-frequency audio.
In first, I am using the function : S=spectrogram(x,window,noverlap,nfft) on Matlab, to extract the STFT of the noise+target signal (from WAV file). After that, I am forcing on some coefficients of the STFT(S variable) to be zero with decision of some threshold. But after doing ISTFT I get complex values ( not a real values like I am Expecting - like audio signal).
Can anyone explain where the problem is coming from? And what is the accepted solution to a problem of this kind?
Note:
If I were doing FFT and there doing manipulations on the signal, I would make sure that the signal has properties to be real in time, but how to keep the properties in the STFT plane?

Are you using the MATLAB function spectrogram() or stft()?
I think you should use stft() (because you can use istft() to go back to time domain).
Also whatever processing you do to the time-frequency domain, you should do the same processing to both positive frequencies and negative frequencies.

Related

Noisy Signal in Data (FFT) - MATLAB

I am plotting some data I collected at 10000 Hz, I attached a snip of some of the data in the form of an FFT and time. I am getting a repeating frequency around 10Hz that seems to be pretty obviously some sort of noise from the system i am testing. The signal shows up in the time domain and also the frequency domain.
I am looking to use MATLAB to remove these spikes.
Has anyone dealt with a similar issue and can provide any advice.
To filter out specific frequency components of a signal, you would normally use either a notch filter or a comb filter, for which MATLAB already has some commands in the DSP System Toolbox:
https://www.mathworks.com/help/dsp/ref/iirnotch.html
https://www.mathworks.com/help/dsp/ref/fdesign.comb.html
Alternatively, if you have the Signal Processing Toolbox, you can use the band-stop Butterworth filter to remove individual frequency components (ranges) using
https://www.mathworks.com/help/signal/ref/butter.html

MATLAB, averaging multiple fft's ,coherent integration

I have audio record.
I want to detect sinusoidal pattern.
If i do regular fft i have result with bad SNR.
for example
my signal contents 4 high frequencies:
fft result:
To reduce noise i want to do Coherent integration as described in this article: http://flylib.com/books/en/2.729.1.109/1/
but i cant find any MATLAB examples how to do it. Sorry for bad english. Please help )
I look at spectra almost every day, but I never heard of 'coherent integration' as a method to calculate one. As also mentioned by Jason, coherent integration would only work when your signal has a fixed phase during every FFT you average over.
It is more likely that you want to do what the article calls 'incoherent integration'. This is more commonly known as calculating a periodogram (or Welch's method, a slightly better variant), in which you average the squared absolute value of the individual FFTs to obtain a power-spectral-density. To calculate a PSD in the correct way, you need to pay attention to some details, like applying a suitable Fourier window before doing each FFT, doing the proper normalization (so that the result is properly calibrated in i.e. Volt^2/Hz) and using half-overlapping windows to make use of all your data. All of this is implemented in Matlab's pwelch function, which is part of the signal-processing toolbox. See my answer to a similar question about how to use pwelch.
Integration or averaging of FFT frames just amounts to adding the frames up element-wise and dividing by the number of frames. Since MATLAB provides vector operations, you can just add the frames with the + operator.
coh_avg = (frame1 + frame2 + ...) / Nframes
Where frameX are the complex FFT output frames.
If you want to do non-coherent averaging, you just need to take the magnitude of the complex elements before adding the frames together.
noncoh_avg = (abs(frame1) + abs(frame2) + ...) / Nframes
Also note that in order for coherent averaging to work the best, the starting phase of the signal of interest needs to be the same for each FFT frame. Otherwise, the FFT bin with the signal may add in such a way that the amplitudes cancel out. This is usually a tough requirement to ensure without some knowledge of the signal or some external triggering so it is more common to use non-coherent averaging.
Non-coherent integration will not reduce the noise power, but it will increase signal to noise ratio (how the signal power compares to the noise power), which is probably what you really want anyway.
I think what you are looking for is the "spectrogram" function in Matlab, which computes the short time Fourier transform(STFT) of an input signal.
STFT
Spectrogram

Notch or Bandstop filter and preparing data for it

I am new to matlab and signal processing methods, but i am trying to use its filter properties over a set of data I have. I have a collection of amplitude values obtained at different timestamps. When this is plotted, I get a waveform with several peaks that I can identify. I then perform calculations to derive the time between each consecutive peak and I want to eliminate the rates that are around the range of 48-52peaks per second.
What would be the correct way to go about processing this data step by step? Would a bandstop or notch filter be better if I want to eliminate those frequencies and not attenuate it simply? I am completely lost in the parameters required to feed into the filters for this. Please help...
periodogram is OK, but I would suggest using pwelch instead. It makes a more reasonable PSD estimate and the default parameters are well thought out (Hann windows, 50% overlap of segments, etc.)
If what you want is to remove signals in a wide band (e.g. 48-52 Hz) equally, rather than a single and unchanging frequency, than a bandstop filter is ideal. For example:
fs = 2048;
y = rand(fs*8, 1);
[b,a] = ellip(4, 2, 40, [46 54]/(fs/2));
yy = filter(b,a,y);
This will use a 4th order elliptic bandstop filter to filter the random data variable 'y'. filtfilt.m is also a nice function; it applies the filter forwards and backwards so you get twice the filter action and none of the phase lag or dispersion.
I am currently doing something similar to what you are doing.
I am processing a lot of signals from the Inertial Measurement Unit and motor drives. They all are asynchronously obtained, i.e. they all have very different timestamp and also very different acquisition frequency.
First thing I did was to interpolate all signals data in order to have all signals with same timestamp. You can use the matlab function interp to do this.
After this, you will have all signals with same sample frequency and also timestamp, which will be good in further analysis.
Ok, another thing you can do to analyse the frequency of the peaks is to perform the fourier transform. For beginners i advice the use of periodogram function and not the fft function.
Imagine you signal is x and your sample frequency (after interpolation) is Fs.
You can now use the function periodogram available in matlab like this:
[P,f] = periodogram(x,[],[length(t)],Fs);
This will give the power vs frequency of your signal. After that you will be able to plot and take a look at the frequencies of your signal. In other words, you be able to see the frequencies of the signals that make your acquired signal.
Plot the data this way:
plot(f,P); or semilogy(f,P);
The second is the same thing as the first, but with a logarithmic scale.
After this analysis you can use the Filter Desing and Analysis Tool to design you filter. Just type fdatool in matlab and it will open the design window. Choose the filter type, the cut and pass frequencies and click in design. This tool is very intuitive.
After designing you can export the filter to workspace.
Finally you can use the filter you designed in your signal to see if its what you wanted.
Use the functions filter os filtfilt for this.
Search in the web of the matlab help for the functions I wrote to get more details.
There are a lot of examples availables too.
I hope I could help you.
Good luck.

Wavelet Transform Output in MATLAB

I have a question regarding the output of performing a wavelet transform in MATLAB on an audio signal. I have an audio signal imported into MATLAB using the wavread function. I then perform a one level wavelet transform on the signal using the wavdec function (usually a haar or db4 transform). To transform the signal back to the original audio signal, I then perform an inverse wavelet transform on the signal using the function wavrec. The output of this function brings me back to the original audio signal. However, many data points are slightly off from the original signal (only by about a magnitude of 10^-16 so it is very slight). However, in theory the inverse transform should give me the exact original signal. I am not sure if I am doing something wrong, but is there a reason that after performing a wavelet transform and then performing the inverse that I am not getting an output of exactly the original signal? Thank you very much for any help!
Numbers in a computer are not as perfect as theoretical numbers.
In order to store your data in a finite amount of memory, it's necessary to round it to the nearest representable value. This rounding is very small, but so is the "error" you're seeing.
Go look for the article "What every Computer Scientist should know about Floating-Point Arithmetic", or one of the summaries (The article is great but long, the summaries are shorter but vary in quality).

Notch filters and harmonic noise in matlab

So basically, my problem is that I have a speech signal in .wav format that is corrupted by a harmonic noise source at some frequency. My goal is to identify the frequency at which this noise occurs, and use a notch filter to remove said noise. So far, I have read the speech signal into matlab using:
[data, Fs] = wavread('signal.wav');
My question is how can I identify the frequency at which the harmonic noise is occurring, and once I've done that, how can I go about implementing a notch filter at that frequency?
NOTE: I do not have access to the iirnotch() command or fdesign.notch() due to the version of MATLAB I am currently using (2010).
The general procedure would be to analyse the spectrum, to identify the frequency in question, then design a filter around that frequency. For most real applications it's all a bit woolly: the frequencies move around and there's no easy way to distinguish noise from signal, so you have to use clever techniques and a bit of guesswork. However if you know you have a monotonic corruption then, yes, an FFT and a notch filter will probably do the trick.
You can analyse the signal with fft and design a filter with, among others, fir1, which I believe is part of the signal processing toolbox. If you don't have the signal processing toolbox you can do it 'by hand', as in transform to the frequency domain, remove the frequency(ies) you don't want (by zeroing the relevant elements of the frequency vector) and transform back to time domain. There's a tutorial on exactly that here.
The fft and fir1 functions are well documented: search the Mathworks site to get code examples to get you up and running.
To add to/ammend xenoclast's answer, filtering in the frequency domain may or may not work for you. There are many thorny issues with filtering in the frequency domain, some of which are covered here: http://blog.bjornroche.com/2012/08/why-eq-is-done-in-time-domain.html
One additional issue is that if you try to process your entire file at once, the "width" or Q of the filters will depend on the length of your file. This might work out for you, or it might not. If you have many files of different lengths, don't expect similar results this way.
To design your own IIR notch filter, you could use the RBJ audio filter cookbook. If you need help, I wrote up a tutorial here:
http://blog.bjornroche.com/2012/08/basic-audio-eqs.html
My tutorial uses bell/peaking filter, but it's easy to follow that and then replace it with a notch filter from RBJ.
One final note: assuming this is actually an audio signal in your .wav file, you can also use your ears to find and fix the problem frequencies:
Open the file in an audio editing program that lets you adjust filter settings in real-time (I am not sure if audacity lets you do this, but probably).
Use a "boost" or "parametric" filter set to a high gain and sweep the frequency setting until you hear the noise accentuated the most.
replace the boost filter with a notch filter of the same frequency. You may need to tweak the width to trade off noise elimination vs. signal preservation.
repete as needed (due to the many harmonics).
save the resulting file.
Of course, some audio editing apps have built-in harmonic noise reduction features that work especially well for 50/60 Hz noise.