Understanding Decibel in a power spectral density plot - visualization

I wanted to plot the spectral content of my EEG data using MNE but I am unable to understand what this graph actually gives. I am having troubles in understanding the y-axis. From what I have gathered so far, a Decibel is calculated "relative" to something. In this case it is amplitude^2 per frequency. I think I am unable to understand what it truly means, and how do I relate it to this definition I found: "When expressing a power ratio, it is defined as ten times the logarithm in base 10. That is, a change in power by a factor of 10 corresponds to a 10 dB change in level."
This figure (reference) has power 20 decibels at 2 Hz, but what does it mean in terms of power/base 10?

Related

How do I model the RF propagation of a custom UWB transmission using MATLAB?

I've successfully plotted the signal strength coverage map for a generic narrow band (read single frequency) horn antenna using MATLAB's in-built functions design(), txsite() and coverage().
MATLAB uses the 'Longley-Rice' propagation model when terrain data is present which I downloaded and introduced using addCustomTerrain().
However, I don't want my antenna to be narrow band operating at a single frequency.
I want to model the coverage map I would get on location with a known ultra-wide band (UWB) transient pulsed signal. I have the time domain E-field of this waveform as well as the FFT and energy spectral density.
My plan was to loop over many tx antennas, each having an operating frequency equal to one of the ~1000 frequency bins in the UWB spectral content and an output power equal to the scaled energy spectral density (ESD) multiplied by the frequency step size (df) and divided by the total time period of the measured pulsed signal (to get power). P = ESD * (df/T).
However, when I ran this looped code, I got:
"Error using em.EmStructures/savesolution
The calculated result is invalid; possible cause is a coarse mesh. Please consider refining the mesh
manually."
I assume this means MATLAB can't model 1000 different antennas on the same exact location.. but any idea on this error?
Is what I'm trying to do possible in MATLAB?
Are there alternative methods?
Thank you for any help in advance!

what is the purpose of the frequency domain analysis

I had assumed that this was going to output a set frequency buckets that I could use to do pitch detection (like aubio pitch). But that doesn't seem to be what it does. I fired up the voice-omatic app and using it frequency display played various notes through my mic. Bars appear, all at the left hand end, almost no distinction between high and low notes. I upped the FFT size just to see if that changed anything, seems not. I found a picthdetect js project and saw that it used analyzer ,aha, here I will find the correct usage, but the meat of the code doesn't use frequency domain output, it feeds time domain into its own algorithm. So to solve my problem I will use that library, but I am still curious what the freqency domain data represents
It does exactly what you think it does, but the specific implementation on that site is not great for seeing that.
The values are mapped differently than is nescessary for seeing changes in pitch between high and low vocal range because the range is mapped linearly, not logrithmically. If you were to map each frequency bin in a logarithmic way you would get a far more useful diagram. Right now the right hand 3/4 of the visualizer is showing from 5000hz to 20000hz (roughly), which contains very very little data in an audio signal compared to 0-5000hz. The root frequency of the human voice (and most instruments) occupies mostly between 100-1000hz. There are harmonics above that, but at reducing amplitudes the higher you get.
I've tweaked the code to tell you the peak frequency and the size of each bucket. Use this app.js: https://puu.sh/Izcws/ded6aae55b.js - you can use a tone generator on your phone to see how accurate it is. https://puu.sh/Izcx3/d5a9d74764.png
The way the code works is it calculates how big each bucket is as described in my answer with var bucketSize = 1 / (analyser.fftSize / analyser.context.sampleRate); (and adds two spans to show the data) and then while drawing each bar calculate which bar is the biggest, and then multiply the size of each bucket by which bucket is the biggest to get the peak frequency (and write it in el2). You can play with the fftSize and see why using a small value will not work at all for determining whether you are playing A2(110 Hz) or A2#(116.5 Hz).
From https://stackoverflow.com/a/43369065/13801789:
I believe I understand what you mean exactly. The problem is not with your code, it is with the FFT underlying getByteFrequencyData. The core problem is that musical notes are logarithmically spaced while the FFT frequency bins are linearly spaced.
Notes are logarithmically spaced: The difference between consecutive low notes, say A2(110 Hz) and A2#(116.5 Hz) is 6.5 Hz while the difference between the same 2 notes on a higher octave A3(220 Hz) and A3#(233.1 Hz) is 13.1 Hz.
FFT bins are linearly spaced: Say we're working with 44100 samples per second, the FFT takes a window of 1024 samples (a wave), and multiplies it first with a wave as long as 1024 samples (let's call it wave1), so that would be a period of 1024/44100=0.023 seconds which is 43.48 Hz, and puts the resulting amplitude in the first bin. Then it multiplies it with a wave with frequency of wave1 * 2, which is 86.95 Hz, then wave1 * 3 = 130.43 Hz. So the difference between the frequencies is linear; it's always the same = 43.48, unlike the difference in musical notes which changes.
This is why close low notes will be bundled up in the same bin while close high notes are separated. This is the problem with FFT's frequency resolution. It can be solved by taking windows bigger than 1024 samples, but that would be a trade off for the time resolution.

How to convert scales to frequencies in Wavelet Transform

I'm dealing with CWT, and I have a big problem converting scales to frequencies. In the MAtlab Wavelet Tutorial they use this expression to convert scales to frequencies
But if i use the default function scal2freq I obtain different result.
I don't understand the role of the Morlet Fourier Factor
Thanks in advance
It is a pretty complicated concept, which I somewhat understand it. I'll write some points here so that you might figure it out yourself, rather easier.
A simple fact is that:
Scale is inversely proportional to frequency.
For example, imagine we have a 1-100 Hz range of frequencies in some time series data such as stock markets data or earthquake data. Scale is "supposed to be" the inverse of that. For instance, if scale would be in range of 1 to 100, we'd have had:
Scale(1/Hz) Frequency (Hz)
1 100
50 50
100 1
Therefore,
The frequency is not the real frequency of those time series data (e.g., stock market, earthquake) that we know of. They are only related, inversely.
And we can safely say that here we are calculating some "pseudo-frequencies", which MATLAB does that (by approximating that). You can read about the approximation process in the documentation in the section pseudo-frequencies:
MATlAB does calculate those pseudo-frequencies based on:
In wavelet analysis, the way to relate scales to frequencies is to determine the center frequency of the wavelet function:
which you can visually see in this image and of-course it would differ, when we would change the types of our function in the calculation. Thus, that center frequency will change everytime in our approximation process:
That "MorletFourierFactor" is a variable to approximate a constant so that when you would do the 1/scale, it would closely approximate those "pseudo-frequencies".
I thought this image about shifting (time axis) and scaling (frequency axis) might be a little helpful to look into as well:
The bottom line is that don't worry about pseudo-frequencies, you wouldn't probably need those. If you would want any frequency spectrum, you can likely go towards applying some of those frequency methods (such as Fast Fourier Transform) on whatever time series data that you have.
If you really really want to map that, you can also try to design some methods to approximate it yourself.
Source
Harvard Seismology

About conversion to dB

So I have been dealing with the hydrophone data and coding in matlab. I have couple of questions as follows -
1. I read all the .wav files in matlab and trying to compute the Power spectral density using pwelch in matlab which im able to do with ease. My question is conversion to dB. The hydrophone output is in Voltage/Micropascal. So in order to obtain the Power spectral density values in dB do I simply do 120 + 10*log10(Power)? This is what i did and the Power in brackets here is the output of using pwelch and the values are like 10 power of -6..
How do I get sound pressure levels(SPL (dB re 1 micropascal) from the power spectral density values in dB?
How do I chose specific frequency band of interest, say I want to look at power spectral density in the frequency 10 to 12kHz then how do i go about?
Many thanks .

findpeaks - MINPEAKDISTANCE

I'm trying to understand how MINPEAKDISTANCE works. I returned to the documentation, here, but it wasn't very clear how this parameter works.
Can you kindly clarify it a bit?
Thanks.
Minimum peak separation Specify the minimum peak distance, or minimum
separation between peaks as a positive integer. You can use the
'MINPEAKDISTANCE' option to specify that the algorithm ignore small
peaks that occur in the neighborhood of a larger peak. When you
specify a value for 'MINPEAKDISTANCE', the algorithm initially
identifies all the peaks in the input data and sorts those peaks in
descending order. Beginning with the largest peak, the algorithm
ignores all identified peaks not separated by more than the value of
'MINPEAKDISTANCE'. Default: 1
So if you consider your peak heights as values in the "y" direction, then the separation that this is talking about is in the "x" direction. So for example look at this image (from Matlab docs and if you have the image processing toolbox you can get the data too load noisyecg.mat):
lets say you just want to identify thos 4 big distinct peaks, but not the hundreds of little peaks caused by noise, setting MINPEAKDISTANCE is a feasible way accomplish this because the noisy peaks are at a much higher frequency, i.e. they are closer to each other in the "x" direction, or have a smaller distance separating them than the big peaks do. So choosing a large enough MINPEAKDISTANCE, say 100 or 350 for example depending on what peaks you're interested in, would help you to not detect these undesired noise peaks.
Try findpeaks on this data with different MINPEAKDISTANCE values and see what you get!
If you've got noisy data, you may find that instead of one solid peak, you get lots of small ones (see the folowing image).
The important data here is when the signal is high and when it is low - you don't care about small variations in value, you only want to use one of those peaks and not look at all the smaller local ones around it. If you know the frequency of your signal (i.e. how often the peaks should occur), you can tell the function to ensure that the peaks are separated by a certain amount.
In the above example, the peak is every 15 milliseconds and lasts for 5 milliseconds, so you might set your MINPEAKDISTANCE parameter to 15 or so.