The time and frequency amplitude distributions of signals with a good signal-to-noise ratio can be used to automatically detect their time position (i.e. automatically annotate the audio files).
We will use as an example a recording from a long-billed hermit found in the folder “./examples/detection”. A long spectrogram will help to get an idea of the structure of the song in this species:
# cargar warbleR
library(warbleR)
# parametros globales
warbleR_options(wl = 200, ovlp = 90, wav.path = "PONER RUTA A 'ejemplos/deteccion' AQUI", flim = c(2, 11))
# spectrograma largo
full_spec(ovlp = 50, sxrow = 26.5 / 12, rows = 12)
The auto_detec()
function uses thresholds applied to amplitude envelopes as well as frequency range and duration filters to detect the position in time. The code below applies the following parameters to detect the songs:
ad <- autodetec(threshold = 14, mindur= 0.1, maxdur = 0.17, bp = c(2, 11), ssmooth = 400, ls = TRUE, sxrow = 26.5 / 12, rows = 12)
The detection looks like this:
Signals can be also be detected using spectrographic cross-correlation the package monitoR. This package aims to facilitate the detection of acoustic templates. The code here is similar but much less detailed than the vignette from monitoR, so I recommend Look at it if you want to get more information.
monitoR executes a cross-correlation between the sound files to search for the signals using previously defined templates. Therefore, templates must be clear samples of the signals we want to detect. Here is how the package works using the same recording as in the previous example.
First we need to create the template. We just have to provide the name of the sound file where the template is located, the beginning and the end, and the frequency range (an annotation). We will load the first song detected in the previous code:
library(monitoR)
pl1 <- makeCorTemplate("./examples/detection/LBH.374.SUR-2.wav", t.lim = c(ad$start[1], ad$end[1]), wl = 300, ovlp = 90, frq.lim = c(1, 11), dens = 1, name = "pl1")
##
## Automatic point selection.
##
## Done.
Now we can run the correlation over the entire file:
cscores <- corMatch(survey = "./examples/detection/LBH.374.SUR-2.wav", templates = pl1, parallel = FALSE, show.prog = FALSE, time.source = "fileinfo", cor.method = "pearson", warn = FALSE)
##
## Starting pl1 . . .
## Fourier transform on survey . . .
## Continuing. . .
##
## Done.
The detection peaks can be extracted with the findPeaks()
function and plot them like this:
cdetects <- findPeaks(cscores)
##
## Done with pl1
## Done
# graficar
plot(cdetects, hit.marker="points")
However, that display is not useful for long files. Alternatively we can extract the values of the detections and use warbleR to visualize them. Detections can be extracted like this:
dtcs <- cdetects@detections[[1]]
Convert the detections produced with monitorR to a selection table with the format of warbleR
Use the full_spec()
function to display the detections
To define the frequency range in an annotation usually involves “drawing” manually the selection boxes in Raven/Audacity/Syrinx. An alternative, and potentially less subjective, way is to infer the range using the energy distribution in the frequency domain by applying amplitude thresholds in the spectra. There are 2 functions of warbleR that do exactly that:
freq_range_detec()
: detects the frequency range of the signals in ‘wave’ objects (as a function sewave). You can produce images in the graphics window if plot = TRUE
.
freq_range()
: applies freq_range_detec()
iteratively to the signals in a selection table (like most warbleR functions). Image files are produced if img = TRUE
which includes a spectrogram and a frequency spectrum for each selection.
freq_range_detec()
works on ‘wave’ objects. In this example, we use it to detect the frequency range in the first ‘tico’ note:
w2 <- readWave("./examples/detection/LBH.374.SUR-2.wav", from = ad$start[1],
to = ad$end[1], units = "seconds")
data(tico)
tico1 <- cutw(tico, from = 0, to = 0.5, output = "Wave")
freq_range_detec(tico1, bp = c(2, 9.6), fsmooth = 1, threshold = 8)
## bottom.freq top.freq
## 1 2.49165 4.91715
As mentioned earlier, the frequency range can be calculated for the entire selection in a selection table using freq_range()
:
fr_ad <- freq_range(X = ad, bp = c(2, 12), fsmooth = 0.001, ovlp = 95,
wl = 200, threshold = 10, img = FALSE)
head(fr_ad)
## sound.files selec start end bottom.freq top.freq
## 1 LBH.374.SUR-2.wav 1 0.3325400 0.4673247 2.97675 8.70975
## 2 LBH.374.SUR-2.wav 2 0.8496606 0.9728126 2.97675 8.70975
## 3 LBH.374.SUR-2.wav 3 1.3889354 1.5192757 3.19725 8.48925
## 4 LBH.374.SUR-2.wav 4 1.9285731 2.0534712 3.19725 8.70975
## 5 LBH.374.SUR-2.wav 5 2.4643559 2.5838571 NA 8.70975
## 6 LBH.374.SUR-2.wav 6 2.9814085 3.1123383 2.97675 8.48925
Now we have a selection table with the “coordinates” of time and frequency for each song in the audio file.
Use the full_spec()
function to display the selections in the “fr_ad” selection table
selection_table()
)
Session information
## R version 3.6.1 (2019-07-05)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 18.04.3 LTS
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.7.1
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=es_CR.UTF-8 LC_COLLATE=en_US.UTF-8
## [5] LC_MONETARY=es_CR.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=es_CR.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=es_CR.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] monitoR_1.0.7 kableExtra_1.1.0 warbleR_1.1.16
## [4] NatureSounds_1.0.1 seewave_2.1.4 tuneR_1.3.3
## [7] maps_3.3.0
##
## loaded via a namespace (and not attached):
## [1] Rcpp_1.0.2 pracma_2.2.5 highr_0.8
## [4] pillar_1.4.2 compiler_3.6.1 bitops_1.0-6
## [7] iterators_1.0.12 tools_3.6.1 Sim.DiffProc_4.4
## [10] zeallot_0.1.0 digest_0.6.21 viridisLite_0.3.0
## [13] tibble_2.1.3 evaluate_0.14 pkgconfig_2.0.2
## [16] fftw_1.0-5 rlang_0.4.0 rstudioapi_0.10
## [19] yaml_2.2.0 parallel_3.6.1 xfun_0.9
## [22] xml2_1.2.2 httr_1.4.1 stringr_1.4.0
## [25] knitr_1.24 vctrs_0.2.0 hms_0.5.1
## [28] webshot_0.5.1 glue_1.3.1 R6_2.4.0
## [31] dtw_1.21-3 jpeg_0.1-8 pbapply_1.4-2
## [34] rmarkdown_1.15 soundgen_1.5.0 readr_1.3.1
## [37] magrittr_1.5 scales_1.0.0 backports_1.1.4
## [40] htmltools_0.3.6 MASS_7.3-51.4 rvest_0.3.4
## [43] colorspace_1.4-1 Deriv_3.8.5 stringi_1.4.3
## [46] proxy_0.4-23 munsell_0.5.0 signal_0.7-6
## [49] RCurl_1.95-4.12 crayon_1.3.4 rjson_0.2.20