<p>If you are using PAMGuard click detectors, consider checking out the R-package called <a href="https://github.com/TaikiSan21/PAMpal" rel="nofollow noreferrer">PAMpal</a>, developed by Taiki Sakai with NOAA Southwest Fisheries.</p>
<p>PAMpal automatically calculates a number of useful features from click (and whistle) detections, including 10 dB bandwidth. Check out the <a href="https://taikisan21.github.io/PAMpal/" rel="nofollow noreferrer">user-guide here</a></p>

CC BY-SA 4.0
2022-11-02T22:52:00.607Z
2023-04-19T11:56:56.170Z
2023-04-19T11:56:56.170Z
ASimonis
<p>Maybe the following example may help</p>
<pre><code>#Create a sequence of 100 equally spaced numbers between -4 and 4
x &lt;- seq(-4, 4, length=100)

# simulate a signal
y &lt;- dnorm(x)

# length based on 10 dB down from peak level
iu &lt;- which(y&gt;=max(y)/sqrt(10))

dev.new()
plot(x,y, type = &quot;l&quot;)
lines(x[iu],y[iu],type=&quot;l&quot;,lwd=3,col=&quot;red&quot;)

print(max(x[iu])-min(x[iu]))

# length based on 10%, 90% of energy
z &lt;- cumsum(y^2)
vu1&lt;-approx(z,x,max(z)*0.1)
vu2&lt;-approx(z,x,max(z)*0.9)

dev.new()
plot(x,z, type=&quot;l&quot;,col=&quot;black&quot;)
lines(vu1<span class="math-container">$y,vu1$</span>x, type = &quot;o&quot;, col = &quot;blue&quot;)
lines(vu2<span class="math-container">$y,vu2$</span>x, type = &quot;o&quot;, col = &quot;red&quot;)

print(vu2<span class="math-container">$y-vu1$</span>y)
</code></pre>
<p>For this I simulated a signal and estimated the length by 10dB down (sqrt(10) down for amplitude) and the more common estimate 10 to 90 % of signal energy.</p>
<p>Edit: as the context of the question is still confusing (see comment of @Rasmus) I would like to point out that the one should not estimate the duration of a broadband signal in the spectral domain (or after narrow-band filtering) as the estimated duration includes the filter window length. For a good spectral estimation one needs a long window (1 Hz resolution at 48 kHz means 1 second window). Only if your signal is much longer than the FFT/DFT window, narrowband filtered duration estimates could make sense (+/- filterlength)</p>
<p>Caveat: I'm not an R programmer, so script can be improved.</p>
<p>Edit: For those of us that simulate nice signals, the <a href="http://www.marinebioacoustics.com/files/2005/Madsen_2005.pdf" rel="nofollow noreferrer">Madsen RMS paper</a> may be of interest on why -3dB or -10dB down is not always a good idea for real signals.</p>

CC BY-SA 4.0
2022-08-28T19:42:19.447Z
2022-11-02T18:29:21.890Z
2022-11-02T18:29:21.890Z
WMXZ
<p>I have a different answer, which addresses finding signal duration at 10dB below the peak amplitude value of the oscillogram. Note the peak amplitude value of the oscillogram is NOT the same as the peak frequency of the power spectrum I described in my previous answer. This is the source of the confusion. The first answer is for those trying to find bandwidth values at 10dB below the peak of a power spectrum. This answer is for those trying to detect signal durations 10dB below the peak amplitude of the signal envelope, which seems to me was the original question.</p>
<p>Have a look at the function <em>timer()</em> in the package &quot;seewave&quot;.
This functions computes the envelope of the waveform of a signal (check the function <em>env()</em>) and uses a user defined threshold to find the begin and end times of the sound.</p>
<p>You need to define a windows length, and overlap percent, the type of windowing you will be using, and the amplitude threshold.</p>
<p>For the synthetic rocket frog signal, the duration of the signal at 10dB below the peak amplitude of the envelope can be obtained with:</p>
<pre><code>detectRf &lt;- timer(Rf_synth,
                  tlim = c(0, 0.2),
                  wl = 512,
                  ovlp = 90,
                  envt = &quot;hil&quot;,
                  threshold = 31.62)
axis(2, las = 1)
</code></pre>
<p>This will return you a figure showing the envelope, and the begin and end limits of the detected signal in red, and a list with the exact values:</p>
<p>:<a href="https://i.sstatic.net/gKJzP.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/gKJzP.png" alt="enter image description here" /></a></p>
<pre><code>&gt; detectRf
$s
[1] 0.01777979

$p
[1] 0.07960086 0.10261934

$r
[1] 0.09757312

$s.start
[1] 0.07960086

$s.end
[1] 0.09738066

$first
[1] &quot;pause&quot;
</code></pre>
<p>Note that the <em>timer()</em> function uses an user-defined amplitude threshold to automatically detect the begin and end time of the envelope of a signal
(not on the raw waveform, therefore how you construct the envelope will influence the detection limits). The threshold is expressed in percent relative to the peak, which is normalised to a maximum value of 1 and expressed on linear scale. Therefore, for -10dB below the peak amplitude, the percent value can be obtained with the following arithmetic:</p>
<p><span class="math-container">$$-10 dB = 20 \log_{10} \frac{X}{X_{ref}}$$</span></p>
<p>Where <span class="math-container">$X$</span> is the amplitude value you are looking for, and <span class="math-container">$X_{ref}$</span> is the reference value, which in this case is the peak amplitude and equals to 1.</p>
<p>This becomes</p>
<p><span class="math-container">$10^{-0.5} = X$</span></p>
<p><span class="math-container">$0.3162278 = X$</span></p>
<p>This is you threshold value at -10 dB expressed as a proportion, and therefore your threshold for the <em>timer()</em> function is 31.62%. Try it with 6dB and you will find your threshold to be 50%.</p>
<p>Hope this helps!</p>
<p>@Editors: feel free to join this answer with the previous one if you think its better. Although I consider they address different questions, and therefore should be two separate answers.</p>

CC BY-SA 4.0
2022-11-01T22:31:01.713Z
2022-11-02T13:44:01.243Z
2022-11-02T13:44:01.243Z
Matías Muñoz
<p>This can be done fairly easy in R.
Have a look at the function <em>Q()</em> in the &quot;seewave&quot; package, and the excellent article by Bennet-Clark:</p>
<p><em>Bennet-Clark, H. C. (1999). Which Qs to choose: questions of quality in bioacoustics?. Bioacoustics, 9(4), 351-359.</em></p>
<p>I show an example below with a synthetic rain forest rocket frog note. This is how the oscillogram and spectrogram of the note looks like:<a href="https://i.sstatic.net/FNKxZ.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/FNKxZ.png" alt="enter image description here" /></a></p>
<p>If I understood correctly, you want to obtain the bandwidth for the complete signal. Therefore, the first step is to compute the mean power spectrum for the complete sound using the <em>meanspec()</em> function (the <em>spec()</em> function would also work if you are interested in the peak at a given time point of your signal):</p>
<pre><code>spectroRf &lt;- meanspec(Rf_synth, #replace by your sound here.
                  wl = 512,     #define your own windows length depending on your signal.
                  ovlp = 90,    #define your own overlap depending on your signal.
                  from = 0, to = 0.2,
                  flim = c(5,8),
                  dB = &quot;max0&quot;) # scale the spectrum to max. 0 dB. This is necessary for using it later in the Q() function.
</code></pre>
<p>Then use this mean power spectrum as the first argument of the function <em>Q()</em>. Define the dB level below the peak that you are interested in (level = -10 in your case):</p>
<pre><code>Q(spectroRf, 
   level = -10,
   xlim = c(5, 8),
   las = 1)
</code></pre>
<p>This will return both an image of the mean power spectrum with the computed Q, and a list containing the values of the minimum, maximum and peak frequencies together with the bandwidth:<a href="https://i.sstatic.net/AcMhj.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/AcMhj.png" alt="enter image description here" /></a></p>
<pre><code>    $Q
       x 
9.822804 

$dfreq
       x 
6.459972 

$fmin
       x 
6.118846 

$fmax
       x 
6.776497 

$bdw
        x 
0.6576505 
</code></pre>
<p>Hope this helps!</p>
<p>EDIT: I subscribe to the previous answers saying that defining the duration of a sound signal out of spectral analyses is not the best way to go. But I hope this post will help you find the frequency values 10dB below the peak of your clicks.</p>

CC BY-SA 4.0
2022-11-01T21:27:27.703Z
2022-11-01T21:38:17.837Z
2022-11-01T21:38:17.837Z
Matías Muñoz
<p>I'm working with dolphins echolocation clicks and I'm trying to get the duration of each click. One criteria used for the duration is to get the points where the signal declines 10dB to both sides from the peak frequency. I'm having trouble finding how to do this with R, do you have any clues about it?</p>

CC BY-SA 4.0
2022-08-25T20:19:57.323Z
welcome @constanza! I edited the title of your question a bit to make it more detailed/specific and better fit the SE Q/A format. I hope to have maintained the essence of your question, but if not, please comment here or edit back. For more info see: [How do I write a good title?](https://meta.stackexchange.com/questions/10647/how-do-i-write-a-good-title)
selene
CC BY-SA 4.0
2022-08-26T06:03:06.963Z
The question cannot be answered. You can only quantify the band width (frequency domain) or the duration (time domain) separately  but not together (Uncertainty principle). This is especially true for echolocation clicks. Please reconsider or clarify the question
WMXZ
CC BY-SA 4.0
2022-08-26T06:33:42.597Z
Yes, I think the confusion is just that it's not appropriate to use the term **bandwidth** when you're referring to the duration. Simply remove that word from the question text
Dan Stowell
CC BY-SA 4.0
2022-08-27T19:47:32.123Z
Great, thanks for the contributions
Constanza Ordoñez
CC BY-SA 4.0
2022-08-31T13:56:33.833Z
I read either:
1. Find "peak frequency" (frequency of greatest amplitude, maybe with 1 Hz spacing?) and then find the -10 dB duration of this frequency.
or
2. "Peak frequency" should have been "peak pressure".

Can @ConstanzaOrdoñez which one is correct?
Rasmus
<r><echolocation-clicks>
How to calculate 10 dB duration in R
# How to calculate 10 dB duration in R

(Asked by: username_0 on 2022-08-25)

I'm working with dolphins echolocation clicks and I'm trying to get the duration of each click. One criteria used for the duration is to get the points where the signal declines 10dB to both sides from the peak frequency. I'm having trouble finding how to do this with R, do you have any clues about it?

**Tags:** r, echolocation-clicks

> **Comments:**
> **username_1**: welcome @username_0! I edited the title of your question a bit to make it more detailed/specific and better fit the SE Q/A format. I hope to have maintained the essence of your question, but if not, please comment here or edit back. For more info see: [How do I write a good title?](https://meta.stackexchange.com/questions/10647/how-do-i-write-a-good-title)  
> **username_2**: The question cannot be answered. You can only quantify the band width (frequency domain) or the duration (time domain) separately  but not together (Uncertainty principle). This is especially true for echolocation clicks. Please reconsider or clarify the question  
> **username_3**: Yes, I think the confusion is just that it's not appropriate to use the term **bandwidth** when you're referring to the duration. Simply remove that word from the question text  
> **username_0**: Great, thanks for the contributions  
> **username_4**: I read either: 1. Find "peak frequency" (frequency of greatest amplitude, maybe with 1 Hz spacing?) and then find the -10 dB duration of this frequency. or 2. "Peak frequency" should have been "peak pressure".  Can @username_0 which one is correct?  

---

## 4 answers

### Answer by username_5 on 2022-11-02. Score: 3

If you are using PAMGuard click detectors, consider checking out the R-package called [PAMpal](https://github.com/TaikiSan21/PAMpal), developed by Taiki Sakai with NOAA Southwest Fisheries.

PAMpal automatically calculates a number of useful features from click (and whistle) detections, including 10 dB bandwidth. Check out the [user-guide here](https://taikisan21.github.io/PAMpal/)


---

### Answer by username_2 on 2022-08-28. Score: 2

Maybe the following example may help

```
#Create a sequence of 100 equally spaced numbers between -4 and 4
x <- seq(-4, 4, length=100)

# simulate a signal
y <- dnorm(x)

# length based on 10 dB down from peak level
iu <- which(y>=max(y)/sqrt(10))

dev.new()
plot(x,y, type = "l")
lines(x[iu],y[iu],type="l",lwd=3,col="red")

print(max(x[iu])-min(x[iu]))

# length based on 10%, 90% of energy
z <- cumsum(y^2)
vu1<-approx(z,x,max(z)*0.1)
vu2<-approx(z,x,max(z)*0.9)

dev.new()
plot(x,z, type="l",col="black")
lines(vu1$y,vu1$x, type = "o", col = "blue")
lines(vu2$y,vu2$x, type = "o", col = "red")

print(vu2$y-vu1$y)

```

For this I simulated a signal and estimated the length by 10dB down (sqrt(10) down for amplitude) and the more common estimate 10 to 90 % of signal energy.

Edit: as the context of the question is still confusing (see comment of @username_4) I would like to point out that the one should not estimate the duration of a broadband signal in the spectral domain (or after narrow-band filtering) as the estimated duration includes the filter window length. For a good spectral estimation one needs a long window (1 Hz resolution at 48 kHz means 1 second window). Only if your signal is much longer than the FFT/DFT window, narrowband filtered duration estimates could make sense (+/- filterlength)

Caveat: I'm not an R programmer, so script can be improved.

Edit: For those of us that simulate nice signals, the [Madsen RMS paper](http://www.marinebioacoustics.com/files/2005/Madsen_2005.pdf) may be of interest on why -3dB or -10dB down is not always a good idea for real signals.


---

### Answer by username_6 on 2022-11-01. Score: 2

I have a different answer, which addresses finding signal duration at 10dB below the peak amplitude value of the oscillogram. Note the peak amplitude value of the oscillogram is NOT the same as the peak frequency of the power spectrum I described in my previous answer. This is the source of the confusion. The first answer is for those trying to find bandwidth values at 10dB below the peak of a power spectrum. This answer is for those trying to detect signal durations 10dB below the peak amplitude of the signal envelope, which seems to me was the original question.

Have a look at the function *timer()* in the package "seewave".
This functions computes the envelope of the waveform of a signal (check the function *env()*) and uses a user defined threshold to find the begin and end times of the sound.

You need to define a windows length, and overlap percent, the type of windowing you will be using, and the amplitude threshold.

For the synthetic rocket frog signal, the duration of the signal at 10dB below the peak amplitude of the envelope can be obtained with:

```
detectRf <- timer(Rf_synth,
                  tlim = c(0, 0.2),
                  wl = 512,
                  ovlp = 90,
                  envt = "hil",
                  threshold = 31.62)
axis(2, las = 1)

```

This will return you a figure showing the envelope, and the begin and end limits of the detected signal in red, and a list with the exact values:

:[![enter image description here](https://i.sstatic.net/gKJzP.png)](https://i.sstatic.net/gKJzP.png)

```
> detectRf
$s
[1] 0.01777979

$p
[1] 0.07960086 0.10261934

$r
[1] 0.09757312

$s.start
[1] 0.07960086

$s.end
[1] 0.09738066

$first
[1] "pause"

```

Note that the *timer()* function uses an user-defined amplitude threshold to automatically detect the begin and end time of the envelope of a signal
(not on the raw waveform, therefore how you construct the envelope will influence the detection limits). The threshold is expressed in percent relative to the peak, which is normalised to a maximum value of 1 and expressed on linear scale. Therefore, for -10dB below the peak amplitude, the percent value can be obtained with the following arithmetic:

$$-10 dB = 20 \log\_{10} \frac{X}{X\_{ref}}$$

Where $X$ is the amplitude value you are looking for, and $X\_{ref}$ is the reference value, which in this case is the peak amplitude and equals to 1.

This becomes

$10^{-0.5} = X$

$0.3162278 = X$

This is you threshold value at -10 dB expressed as a proportion, and therefore your threshold for the *timer()* function is 31.62%. Try it with 6dB and you will find your threshold to be 50%.

Hope this helps!

@Editors: feel free to join this answer with the previous one if you think its better. Although I consider they address different questions, and therefore should be two separate answers.


---

### Answer by username_6 on 2022-11-01. Score: 2

This can be done fairly easy in R.
Have a look at the function *Q()* in the "seewave" package, and the excellent article by Bennet-Clark:

*Bennet-Clark, H. C. (1999). Which Qs to choose: questions of quality in bioacoustics?. Bioacoustics, 9(4), 351-359.*

I show an example below with a synthetic rain forest rocket frog note. This is how the oscillogram and spectrogram of the note looks like:[![enter image description here](https://i.sstatic.net/FNKxZ.png)](https://i.sstatic.net/FNKxZ.png)

If I understood correctly, you want to obtain the bandwidth for the complete signal. Therefore, the first step is to compute the mean power spectrum for the complete sound using the *meanspec()* function (the *spec()* function would also work if you are interested in the peak at a given time point of your signal):

```
spectroRf <- meanspec(Rf_synth, #replace by your sound here.
                  wl = 512,     #define your own windows length depending on your signal.
                  ovlp = 90,    #define your own overlap depending on your signal.
                  from = 0, to = 0.2,
                  flim = c(5,8),
                  dB = "max0") # scale the spectrum to max. 0 dB. This is necessary for using it later in the Q() function.

```

Then use this mean power spectrum as the first argument of the function *Q()*. Define the dB level below the peak that you are interested in (level = -10 in your case):

```
Q(spectroRf, 
   level = -10,
   xlim = c(5, 8),
   las = 1)

```

This will return both an image of the mean power spectrum with the computed Q, and a list containing the values of the minimum, maximum and peak frequencies together with the bandwidth:[![enter image description here](https://i.sstatic.net/AcMhj.png)](https://i.sstatic.net/AcMhj.png)

```
    $Q
       x 
9.822804 

$dfreq
       x 
6.459972 

$fmin
       x 
6.118846 

$fmax
       x 
6.776497 

$bdw
        x 
0.6576505 

```

Hope this helps!

EDIT: I subscribe to the previous answers saying that defining the duration of a sound signal out of spectral analyses is not the best way to go. But I hope this post will help you find the frequency values 10dB below the peak of your clicks.


---

