---
title: <center><font size="7"><b>baRulho</b></font></center>
subtitle: <center><font size="5">Quantifying (animal) acoustic signal transmission and degradation</font></center>
pagetitle: baRulho quantifying sound degradation
author: 
- <center><a href="https://marceloarayasalas.weebly.com">Marcelo Araya-Salas, PhD</a></center>
date:  <center>"`r Sys.Date()`"</center>
output:
  rmarkdown::html_document:
    self_contained: yes
    toc: true
    toc_depth: 3
    toc_float:
      collapsed: true
      smooth_scroll: true
vignette: >
  \usepackage[utf8]{inputenc}
  %\VignetteIndexEntry{1. Introduction to baRulho}
  %\VignetteEngine{knitr::rmarkdown}
editor_options: 
  chunk_output_type: console
---

<!-- <script> -->
<!--    $(document).ready(function() { -->
<!--      $head = $('#header'); -->
<!--      $head.prepend('<img src=\"logo.png\"/>') -->
<!--    }); -->
<!-- </script> -->

<!-- &nbsp;  -->


<!-- <center>![warbleR logo](logo.png)</center> -->

&nbsp; 

```{r eval= TRUE, echo=FALSE}

library(knitr)
opts_chunk$set(tidy = TRUE, fig.align = "center")

```


The [baRulho](https://cran.r-project.org/package=baRulho) package is intended to facilitate acoustic analysis of (animal) sound transmission experiments. Such studies typically aim to quantify changes in signal structure when transmitted in a given habitat by broadcasting and re-recording animal sounds at increasing distances. We will refer to these changes in signal structure 'degradation' for the sake of simplicity. The package offers a workflow with functions to prepare the data set for analysis as well as to calculate and visualize several degradation metrics. [baRulho](https://marce10.github.io/baRulho/) builds upon functions and data formats from the [warbleR](https://cran.r-project.org/package=warbleR) and [seewave](https://cran.r-project.org/package=seewave) packages, so some experience with these packages is advised.

The main features of the package are:

 - The use of loops to apply tasks through acoustic signals referenced in a selection table (sensu [warbleR](https://cran.r-project.org/package=warbleR))
 - The production of image files with graphic representations of sound in time and/or frequency that let users verify acoustic analyses 
 - The use of extended selection tables (sensu [warbleR](https://cran.r-project.org/package=warbleR)) as the object format to input acoustic data and annotations (except for `atmospheric_attenuation()`) and to output results 
 - The use of parallelization to distribute tasks among several cores to improve computational efficiency

The package can be install/load from CRAN as follows:

```{r, eval = FALSE}

# From CRAN would be
install.packages("baRulho")

#load package
library(baRulho)

```

To install the latest developmental version from [github](https://github.com/) you will need the R package [devtools](https://cran.r-project.org/package=devtools):

```{r, eval = FALSE}

# From github
devtools::install_github("maRce10/baRulho")

#load package
library(baRulho)

# also set a working directory, for this example we will use a temporary directory
td <- tempdir()

```

```{r, eval = TRUE, echo = FALSE, message=FALSE}

# global option chunks
knitr::opts_chunk$set(dpi = 70, fig.width = 8, fig.height = 6)

#load package
library(baRulho)
library(kableExtra)

# also set a working directory, for this example we will use a temporary directory
td <- tempdir()

```

For this vignette we will also need a few more packages:

```{r load packages, eval=TRUE, echo=TRUE, warning=FALSE, message=FALSE}

library(warbleR)
library(ggplot2)
library(viridis)

```


### Inputting acoustic data and annotations

The package requires the data to be input as extended selection tables. An extended selection table is an object class in R that contains both the annotations (locations of signals in time and frequency) and the corresponding acoustic data as wave objects. Therefore, these are **self-contained objects** since the original sound files are no longer needed to perform acoustic analyses. These objects are created by the `selection_table()` function from [warbleR](https://cran.r-project.org/package=warbleR). Take a look at the [intro to warbleR vignette](https://cran.r-project.org/package=warbleR/vignettes/Intro_to_warbleR.html) for more details.

<div class="alert alert-info">

<font size="5">Glossary</font> 

-**Model signal**: signal in which transmission properties will be studied, usually found in the original field recordings or synthetic sound files.

-**Reference signal**: signal to use as a pattern to compare against. Usually created by re-recording a model signal broadcast at 1 m from the source (speaker).

-**Signal type**: signal category. For instance song types (e.g. A, B, C), call types (alert, foraging, etc).

-**Ambient noise**: energy from background sounds in the recording, excluding signals of interest.  

-**Test signal**: signals re-recorded far from the source to test for transmission/degradation (also refer to as 're-recorded' signals).

-**Degradation**: term used to describe any changes in the structure of a signal when transmitted in a given habitat (note that there is no agreement on this terminology in the scientific community).

</div>

&nbsp;

--- 

# Workflow of sound processing and analysis

A common sequence of steps to experimentally test hypotheses related to signal transmission is depicted in the following diagram:

 <center><img src="analysis_workflow.jpg" alt="analysis workflow" width="620"></center>

&nbsp;

[baRulho](https://marce10.github.io/baRulho/) offers functions for critical steps in this workflow (those in black, including 'checks') that required acoustic data manipulation and analysis. Additional functions from [warbleR](https://cran.r-project.org/package=warbleR) can be used (and are used in this vignette) to complement functions in [baRulho](https://marce10.github.io/baRulho/). All these tools will be presented following the above workflow.

&nbsp;


# Synthesize sounds

We often want to figure out how transmission properties vary across a range of frequencies.
For instance, Tobias et al (2010) studied whether acoustic adaptation (a special case of sensory drive; Morton 1975), could explain song evolution in Amazonian avian communities.  To test this the authors created synthetic pure tone sounds that were used as playback and re-recorded in different habitats. This is the actual procedure of creating synthetic sounds as they described it: 

> "Tones were synthesized at six different frequencies (0.5, 1.0, 2.0, 3.0, 4.0, and 5.0 kHz) to encompass the range of maximum avian auditory sensitivity (Dooling 1982). At each frequency, we generated two sequences of two 100-msec tones. One sequence had  a  relatively  short  interval  of  150  msec,  close  to  the  mean internote interval in our sample (152± 4 msec). The other sequence had a longer interval of 250 msec, close to the mean maximum internote interval in our sample (283± 74 msec). The first sequence reflects a fast-paced song and the second a slower paced song  (sensu  Slabbekoorn  et  al.  2007).  The  master  file  (44100 Hz/16 bit WAV) thereby consisted of a series of 12 pairs of artificial 100-ms constant-frequency tones at six different frequencies (0.5, 1.0, 2.0, 3.0, 4.0, and 5.0 kHz)." 

We can synthesize the same pure tones using the function `sim_songs()` from the package [warbleR](https://cran.r-project.org/package=warbleR). The function requires 1) the number of tones to synthesize (argument `n`), 2) the duration of the tones (`durs`, in seconds), 3) the duration of the intervals (`gaps`, in seconds) and 4) the frequencies for each tone to be synthesized (`freqs`, in kHz). In addition, the argument `diff.fun` should be set to "pure.tone" and the argument `harm` to 1 to remove harmonics. In our case we need six tones of 100 ms at 0.5, 1, 2, 3, 4, and 5 kHz separated by intervals of 150 ms (at least for the first synthetic file described in Tobias et al 2010). We can also get a selection table (sensu [warbleR](https://cran.r-project.org/package=warbleR)) with the information about the time and frequency location of every sound. This would be required in order to make the master sound file. To get the selection table we need to set the argument `selec.table = TRUE`. This can be done as follows:


```{r, eval = FALSE}

# synthesize
synth.l <- sim_songs(n = 6, durs = 0.1, freqs = c(0.5, 1:5), harms = 1, gaps = 0.15, 
                     diff.fun = "pure.tone", selec.table = TRUE, path = td)

# plot spectro
spectro(synth.l$wave, scale = FALSE, palette = reverse.topo.colors, 
        grid = FALSE, flim = c(0,6), collevels = seq(-20, 0, 1))

```

 <img src="spectro_synth_song.png" alt="spectrogram syntehtic sounds" width="750">


&nbsp;

The function returns a list in which the first element is the selection table and the second one the wave object:

```{r, eval = FALSE}

class(synth.l) 


```

```{r, eval = TRUE, echo=FALSE}

c("list")

```

```{r, eval = FALSE}

names(synth.l)

```

```{r, eval = TRUE, echo=FALSE}

c("selec.table", "wave")

```

```{r, eval = FALSE}

synth.l$selec.table  

```

```{r, eval = FALSE, echo = FALSE}

kbl <- kable(synth.l$selec_table, align = "c", row.names = F,  format = "html", escape = F)

kbl <- kable_styling(kbl, bootstrap_options = "striped", font_size = 14)

kbl

```
<table class="table table-striped" style="font-size: 14px; margin-left: auto; margin-right: auto;">
 <thead>
  <tr>
   <th style="text-align:center;"> sound.files </th>
   <th style="text-align:center;"> selec </th>
   <th style="text-align:center;"> start </th>
   <th style="text-align:center;"> end </th>
   <th style="text-align:center;"> bottom.freq </th>
   <th style="text-align:center;"> top.freq </th>
  </tr>
 </thead>
<tbody>
  <tr>
   <td style="text-align:center;"> 2020-01-09_17:00:50.wav </td>
   <td style="text-align:center;"> 1 </td>
   <td style="text-align:center;"> 0.15 </td>
   <td style="text-align:center;"> 0.25 </td>
   <td style="text-align:center;"> 0.5 </td>
   <td style="text-align:center;"> 0.5 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> 2020-01-09_17:00:50.wav </td>
   <td style="text-align:center;"> 2 </td>
   <td style="text-align:center;"> 0.40 </td>
   <td style="text-align:center;"> 0.50 </td>
   <td style="text-align:center;"> 1.0 </td>
   <td style="text-align:center;"> 1.0 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> 2020-01-09_17:00:50.wav </td>
   <td style="text-align:center;"> 3 </td>
   <td style="text-align:center;"> 0.65 </td>
   <td style="text-align:center;"> 0.75 </td>
   <td style="text-align:center;"> 2.0 </td>
   <td style="text-align:center;"> 2.0 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> 2020-01-09_17:00:50.wav </td>
   <td style="text-align:center;"> 4 </td>
   <td style="text-align:center;"> 0.90 </td>
   <td style="text-align:center;"> 1.00 </td>
   <td style="text-align:center;"> 3.0 </td>
   <td style="text-align:center;"> 3.0 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> 2020-01-09_17:00:50.wav </td>
   <td style="text-align:center;"> 5 </td>
   <td style="text-align:center;"> 1.15 </td>
   <td style="text-align:center;"> 1.25 </td>
   <td style="text-align:center;"> 4.0 </td>
   <td style="text-align:center;"> 4.0 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> 2020-01-09_17:00:50.wav </td>
   <td style="text-align:center;"> 6 </td>
   <td style="text-align:center;"> 1.40 </td>
   <td style="text-align:center;"> 1.50 </td>
   <td style="text-align:center;"> 5.0 </td>
   <td style="text-align:center;"> 5.0 </td>
  </tr>
</tbody>
</table>

&nbsp;

The function also saves the associated '.wav' file in the working directory (in this example `tempdir()`). 

```{r}

list.files(path = td, pattern = "\\.wav$")

```


```{r, eval = TRUE, echo=FALSE}

c("2020-01-09_17:00:50.wav")

```


&nbsp;

# Create master sound file for playback

The function `master_sound_file()` creates a master sound file (as you probably guessed) for playback experiments. The function takes wave objects from an extended selection table containing the model signals and concatenates them in a single sound file (with some silence in between signals which length can be modified). `master_sound_file()` adds acoustic markers at the start and end of the playback that can be used to time-sync re-recorded signals, which streamlines quantification of acoustic degradation. 
The following example shows how to create a master sound file using the synthetic sounds generated above. For the synthetic sounds we need to add a little space between the top and bottom frequency because `sim_songs()` make those values exactly the same for pure tones: 

```{r, eval = FALSE, echo = TRUE}

# extract selection table
st <- synth.l$selec.table 

# add freq range (0.5 kHz)
st$bottom.freq <- st$bottom.freq - 0.25
st$top.freq <- st$top.freq + 0.25

# make an extended selection table
synth.est <- selection_table(X = st, extended = TRUE, pb = FALSE,
                             confirm.extended = FALSE, path = td)

# create master sound file
synth.master.sf <- master_sound_file(X = synth.est, file.name = "synthetic_master", 
dest.path = td, gap.duration = 0.15)

```

&nbsp;

The function saves the master sound file as a wave file and returns a selection table in the R environment with the time and frequency 'coordinates' of the signals in that file. We can look at the spectrogram of the output file using the [warbleR](https://cran.r-project.org/package=warbleR) function `spectrograms()` as follows:

```{r, eval=FALSE, echo=TRUE}

# plot spectro (saved in working directory)
spectrograms(synth.master.sf, path = td, by.song = "sound.files", 
           xl = 3, collevels = seq(-60, 0, 5), osci = TRUE)

```

 <img src="synthetic_master.wav.jpeg" alt="spectrogram of master file">

The function can also create a master sound file from sounds from different sounds files, as is likely the case with recordings collected in the field. The following example shows how to create a master sound file using several sound files. The code uses the example data and recordings from the package [warbleR](https://cran.r-project.org/package=warbleR):

```{r, eval = FALSE, echo = TRUE}

# load example data from warbleR
data(list = c("Phae.long1", "Phae.long2", "Phae.long3", "Phae.long4", 
"lbh_selec_table"))

# save sound files to temporary folder
writeWave(Phae.long1, file.path(td, "Phae.long1.wav"))
writeWave(Phae.long2, file.path(td, "Phae.long2.wav"))
writeWave(Phae.long3, file.path(td, "Phae.long3.wav"))
writeWave(Phae.long4, file.path(td, "Phae.long4.wav"))

# make an extended selection table
est <- selection_table(X = lbh_selec_table, extended = TRUE, confirm.extended = FALSE, 
path = td)

# create master sound file
master.sf <- master_sound_file(X = est, file.name = "example_master", 
dest.path = td, gap.duration = 0.3)

```

&nbsp;

Again, we can look at the spectrogram of the output file:

```{r, eval=FALSE, echo=TRUE}

spectrograms(master.sf, path = td, by.song = "sound.files", 
           xl = 3, collevels = seq(-60, 0, 5), osci = TRUE)

```


 <img src="example_master.wav.jpeg" alt="spectrogram of master file">

Note that the output could also be exported to [Raven sound analysis software](https://ravensoundsoftware.com/software/raven-pro) ([Cornell Lab of Ornithology](https://www.birds.cornell.edu/home)) for visualization or further manipulation using the function `exp_raven()` from the [Rraven](https://cran.r-project.org/package=Rraven) package. `exp_raven()` exports selections in the R environment to a '.txt' file that can be read in Raven:
 

```{r, eval = FALSE}
 
Rraven::exp_raven(master.sf, path = td, file.name = "example_master_selection_table")

```

&nbsp;

Both sound files and annotations can be visualized in Raven:

 <img src="example_master_table.jpg" alt="Raven view">

&nbsp;

Take a look at the [Rraven vignette](https://CRAN.R-project.org/package=Rraven/vignettes/Rraven.html) for more details. 

Note that the start and end markers are placed at relatively low amplitudes so they are less affected by degradation. The frequency range of markers can be set with argument `flim`. The relative amplitude of markers can also be adjusted with the `amp.marker` argument. Amplitude of markers will be multiplied by the value supplied so markers will be louder than signals. These two features should increases the chances of being "detected" at further distances regardless of the amplitude of signals. 

# Time sync re-recorded sounds

Once we went to the field (or lab) and re-recorded the master sound files at different distances, we are ready to start with data analysis. The first step for getting the data ready for analysis involves finding signals within the re-recorded sound files. We only need to align the start marker between the master playback and the re-recorded sound files, based on the fact that the time difference between the marker and the signals should be the same in both cases:


 <center><img src="align-crop-optimize.gif" alt="Align recordings diagram"  width="550"></center>

&nbsp;

To simulate re-recorded sound files we will make two copies of the master sound file, add some silence at the beginning (1 and 2 seconds) and add noise:    

```{r, eval = FALSE}

# read master
exmp.master <- readWave(file.path(td, "example_master.wav"))

# add 1 s silence and create first copy
exmp.test1 <- addsilw(wave = exmp.master, at = "start", d = 1, output = "Wave", f = exmp.master@samp.rate)

# add 2 s silence and create second copy
exmp.test2 <- addsilw(wave = exmp.master, at = "start", d = 2, output = "Wave", f = exmp.master@samp.rate)

# make noise
ns <- noisew(f = exmp.master@samp.rate, d = duration(exmp.test2) + 1, output = "Wave")

# make noise exactly the same length and add noise to 2 examples
exmp.test1@left <- exmp.test1@left + (ns@left[1:length(exmp.test1@left)] * 150)
exmp.test2@left <- exmp.test2@left + (ns@left[1:length(exmp.test2@left)] * 150)

# normalize both  before saving
exmp.test1 <- normalize(exmp.test1, unit = "16")
exmp.test2 <- normalize(exmp.test2, unit = "16")

# save simulated re-recorded sound files
writeWave(object = exmp.test1, filename = file.path(td, "example_test1.wav"), extensible = FALSE)

writeWave(object = exmp.test2, filename = file.path(td, "example_test2.wav"), extensible = FALSE)

```

&nbsp;

To find the location of the start marker on these (simulated) re-recorded sound files we use the functions `search_templates()` to run a cross-correlation of one or  more markers across the test (re-recorded) files to determine the exact time in which each marker is found: 

```{r, eval = FALSE}

found.starts <- search_templates(X = master.sf, template.rows = which(master.sf$orig.sound.file == "start_marker"), test.files = c("example_test1.wav", "example_test2.wav"), path = td); pks

```

```{r, eval = FALSE, echo=FALSE}

kbl <- kable(found.starts, align = "c", row.names = F,  format = "html", escape = F)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 14)

kbl

```

&nbsp;

<table class="table table-striped" style="font-size: 14px; margin-left: auto; margin-right: auto;">
 <thead>
  <tr>
   <th style="text-align:center;"> test.files </th>
   <th style="text-align:center;"> selec </th>
   <th style="text-align:center;"> start </th>
   <th style="text-align:center;"> end </th>
   <th style="text-align:center;"> template </th>
   <th style="text-align:center;"> time </th>
   <th style="text-align:center;"> score </th>
  </tr>
 </thead>
<tbody>
  <tr>
   <td style="text-align:center;"> example_test1.wav </td>
   <td style="text-align:center;"> 1 </td>
   <td style="text-align:center;"> 2.00062 </td>
   <td style="text-align:center;"> 2.99928 </td>
   <td style="text-align:center;"> example_master.wav-1 </td>
   <td style="text-align:center;"> 2.49995 </td>
   <td style="text-align:center;"> 0.882420 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav </td>
   <td style="text-align:center;"> 1 </td>
   <td style="text-align:center;"> 3.00084 </td>
   <td style="text-align:center;"> 3.99950 </td>
   <td style="text-align:center;"> example_master.wav-1 </td>
   <td style="text-align:center;"> 3.50017 </td>
   <td style="text-align:center;"> 0.879969 </td>
  </tr>
</tbody>
</table>

We could also use the end marker as template in case the start marker was masked by other sounds.

The output of `search_templates()` indicates that the start markers are found starting at ~2 s and ~3 s (2.00062 s and 3.00084 s), which was expected as `master_sound_file()` inserts a 1 second silence at the beginning of the master sound files and we added 1 s and 2 s to each simulated file respectively. With this information we can infer the position of all other selections in the new recordings. A selection table from re-recorded files can be generated using the function `align_test_files()`:

```{r, eval = FALSE}

alg.tests <- align_test_files(X =  master.sf, Y = found.starts, path = td, by.song = TRUE)

```

&nbsp;

By default the function returns an `extended_selection_table`  created 'by.song' (see '?selection_table()'), which is the data format that pretty much all [baRulho](https://marce10.github.io/baRulho/) functions take.  

```{r, eval = FALSE}

is_extended_selection_table(alg.est)

alg.est
```

```{r, eval = TRUE, echo = FALSE}

print(TRUE)

```

```{r, eval = FALSE,  echo = FALSE}

kbl <- kable(alg.tests, align = "c", row.names = F,  format = "html", escape = F)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 14)

kbl <- scroll_box(kbl, width = "800px", height = "300px")
kbl

```

<div style="border: 1px solid #ddd; padding: 0px; overflow-y: scroll; height:300px; overflow-x: scroll; width:800px; "><table class="table table-striped" style="font-size: 14px; margin-left: auto; margin-right: auto;">
 <thead>
  <tr>
   <th style="text-align:center;position: sticky; top:0; background-color: #FFFFFF;"> sound.files </th>
   <th style="text-align:center;position: sticky; top:0; background-color: #FFFFFF;"> selec </th>
   <th style="text-align:center;position: sticky; top:0; background-color: #FFFFFF;"> start </th>
   <th style="text-align:center;position: sticky; top:0; background-color: #FFFFFF;"> end </th>
   <th style="text-align:center;position: sticky; top:0; background-color: #FFFFFF;"> bottom.freq </th>
   <th style="text-align:center;position: sticky; top:0; background-color: #FFFFFF;"> top.freq </th>
   <th style="text-align:center;position: sticky; top:0; background-color: #FFFFFF;"> template </th>
  </tr>
 </thead>
<tbody>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 1 </td>
   <td style="text-align:center;"> 0.10000 </td>
   <td style="text-align:center;"> 1.09867 </td>
   <td style="text-align:center;"> 1.33333 </td>
   <td style="text-align:center;"> 2.66667 </td>
   <td style="text-align:center;"> start_marker </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 2 </td>
   <td style="text-align:center;"> 1.39867 </td>
   <td style="text-align:center;"> 1.57173 </td>
   <td style="text-align:center;"> 2.22011 </td>
   <td style="text-align:center;"> 8.60438 </td>
   <td style="text-align:center;"> Phae.long1.wav_1 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 3 </td>
   <td style="text-align:center;"> 1.87173 </td>
   <td style="text-align:center;"> 2.03484 </td>
   <td style="text-align:center;"> 2.16944 </td>
   <td style="text-align:center;"> 8.80705 </td>
   <td style="text-align:center;"> Phae.long1.wav_2 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 4 </td>
   <td style="text-align:center;"> 2.33484 </td>
   <td style="text-align:center;"> 2.50982 </td>
   <td style="text-align:center;"> 2.21829 </td>
   <td style="text-align:center;"> 8.75660 </td>
   <td style="text-align:center;"> Phae.long1.wav_3 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 5 </td>
   <td style="text-align:center;"> 2.80982 </td>
   <td style="text-align:center;"> 2.94244 </td>
   <td style="text-align:center;"> 2.31686 </td>
   <td style="text-align:center;"> 8.82232 </td>
   <td style="text-align:center;"> Phae.long2.wav_1 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 6 </td>
   <td style="text-align:center;"> 3.24244 </td>
   <td style="text-align:center;"> 3.36862 </td>
   <td style="text-align:center;"> 2.28401 </td>
   <td style="text-align:center;"> 8.88803 </td>
   <td style="text-align:center;"> Phae.long2.wav_2 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 7 </td>
   <td style="text-align:center;"> 3.66862 </td>
   <td style="text-align:center;"> 3.79987 </td>
   <td style="text-align:center;"> 3.00683 </td>
   <td style="text-align:center;"> 8.82232 </td>
   <td style="text-align:center;"> Phae.long3.wav_1 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 8 </td>
   <td style="text-align:center;"> 4.09987 </td>
   <td style="text-align:center;"> 4.23009 </td>
   <td style="text-align:center;"> 2.77684 </td>
   <td style="text-align:center;"> 8.88803 </td>
   <td style="text-align:center;"> Phae.long3.wav_2 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 9 </td>
   <td style="text-align:center;"> 4.53009 </td>
   <td style="text-align:center;"> 4.66133 </td>
   <td style="text-align:center;"> 2.31686 </td>
   <td style="text-align:center;"> 9.31515 </td>
   <td style="text-align:center;"> Phae.long3.wav_3 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 10 </td>
   <td style="text-align:center;"> 4.96133 </td>
   <td style="text-align:center;"> 5.10680 </td>
   <td style="text-align:center;"> 2.51400 </td>
   <td style="text-align:center;"> 9.21659 </td>
   <td style="text-align:center;"> Phae.long4.wav_1 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 11 </td>
   <td style="text-align:center;"> 5.40680 </td>
   <td style="text-align:center;"> 5.55102 </td>
   <td style="text-align:center;"> 2.57971 </td>
   <td style="text-align:center;"> 10.23512 </td>
   <td style="text-align:center;"> Phae.long4.wav_2 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 12 </td>
   <td style="text-align:center;"> 5.85102 </td>
   <td style="text-align:center;"> 5.99618 </td>
   <td style="text-align:center;"> 2.57971 </td>
   <td style="text-align:center;"> 9.74228 </td>
   <td style="text-align:center;"> Phae.long4.wav_3 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test1.wav-song_example_test1.wav </td>
   <td style="text-align:center;"> 13 </td>
   <td style="text-align:center;"> 6.29618 </td>
   <td style="text-align:center;"> 7.29484 </td>
   <td style="text-align:center;"> 1.33333 </td>
   <td style="text-align:center;"> 2.66667 </td>
   <td style="text-align:center;"> end_marker </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 1 </td>
   <td style="text-align:center;"> 0.10000 </td>
   <td style="text-align:center;"> 1.09867 </td>
   <td style="text-align:center;"> 1.33333 </td>
   <td style="text-align:center;"> 2.66667 </td>
   <td style="text-align:center;"> start_marker </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 2 </td>
   <td style="text-align:center;"> 1.39867 </td>
   <td style="text-align:center;"> 1.57173 </td>
   <td style="text-align:center;"> 2.22011 </td>
   <td style="text-align:center;"> 8.60438 </td>
   <td style="text-align:center;"> Phae.long1.wav_1 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 3 </td>
   <td style="text-align:center;"> 1.87173 </td>
   <td style="text-align:center;"> 2.03484 </td>
   <td style="text-align:center;"> 2.16944 </td>
   <td style="text-align:center;"> 8.80705 </td>
   <td style="text-align:center;"> Phae.long1.wav_2 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 4 </td>
   <td style="text-align:center;"> 2.33484 </td>
   <td style="text-align:center;"> 2.50982 </td>
   <td style="text-align:center;"> 2.21829 </td>
   <td style="text-align:center;"> 8.75660 </td>
   <td style="text-align:center;"> Phae.long1.wav_3 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 5 </td>
   <td style="text-align:center;"> 2.80982 </td>
   <td style="text-align:center;"> 2.94244 </td>
   <td style="text-align:center;"> 2.31686 </td>
   <td style="text-align:center;"> 8.82232 </td>
   <td style="text-align:center;"> Phae.long2.wav_1 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 6 </td>
   <td style="text-align:center;"> 3.24244 </td>
   <td style="text-align:center;"> 3.36862 </td>
   <td style="text-align:center;"> 2.28401 </td>
   <td style="text-align:center;"> 8.88803 </td>
   <td style="text-align:center;"> Phae.long2.wav_2 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 7 </td>
   <td style="text-align:center;"> 3.66862 </td>
   <td style="text-align:center;"> 3.79987 </td>
   <td style="text-align:center;"> 3.00683 </td>
   <td style="text-align:center;"> 8.82232 </td>
   <td style="text-align:center;"> Phae.long3.wav_1 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 8 </td>
   <td style="text-align:center;"> 4.09987 </td>
   <td style="text-align:center;"> 4.23009 </td>
   <td style="text-align:center;"> 2.77684 </td>
   <td style="text-align:center;"> 8.88803 </td>
   <td style="text-align:center;"> Phae.long3.wav_2 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 9 </td>
   <td style="text-align:center;"> 4.53009 </td>
   <td style="text-align:center;"> 4.66133 </td>
   <td style="text-align:center;"> 2.31686 </td>
   <td style="text-align:center;"> 9.31515 </td>
   <td style="text-align:center;"> Phae.long3.wav_3 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 10 </td>
   <td style="text-align:center;"> 4.96133 </td>
   <td style="text-align:center;"> 5.10680 </td>
   <td style="text-align:center;"> 2.51400 </td>
   <td style="text-align:center;"> 9.21659 </td>
   <td style="text-align:center;"> Phae.long4.wav_1 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 11 </td>
   <td style="text-align:center;"> 5.40680 </td>
   <td style="text-align:center;"> 5.55102 </td>
   <td style="text-align:center;"> 2.57971 </td>
   <td style="text-align:center;"> 10.23512 </td>
   <td style="text-align:center;"> Phae.long4.wav_2 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 12 </td>
   <td style="text-align:center;"> 5.85102 </td>
   <td style="text-align:center;"> 5.99618 </td>
   <td style="text-align:center;"> 2.57971 </td>
   <td style="text-align:center;"> 9.74228 </td>
   <td style="text-align:center;"> Phae.long4.wav_3 </td>
  </tr>
  <tr>
   <td style="text-align:center;"> example_test2.wav-song_example_test2.wav </td>
   <td style="text-align:center;"> 13 </td>
   <td style="text-align:center;"> 6.29618 </td>
   <td style="text-align:center;"> 7.29484 </td>
   <td style="text-align:center;"> 1.33333 </td>
   <td style="text-align:center;"> 2.66667 </td>
   <td style="text-align:center;"> end_marker </td>
  </tr>
</tbody>
</table></div>

&nbsp;

We can check the precision of the alignment by looking at the spectrograms:

```{r, eval = FALSE}

spectrograms(alg.tests, by.song = "sound.files", xl = 3, collevels = seq(-60, 0, 5), dest.path = td, osci = TRUE)

```


 <img src="example_test1.wav.jpeg" alt="test 1">

&nbsp;

 <img src="example_test2.wav.jpeg" alt="test 2">

&nbsp;

Below are some examples from actual test signals that were re-recorded in the field at 1, 30, 65, and 100 m respectively, and were later aligned using the start marker:

 <img src="tlalpan_playback.jpeg" alt="Re-recorded at Tlalpan">

&nbsp;


---

### Further aligning

When this process is done manually (or when broadcasting devices add some short delays as the case of some bluetooth transmitters) there could be some small misalignment between the inferred versus the actual start time of re-recorded signals. This is problematic for quantifying degradation in [baRulho](https://marce10.github.io/baRulho/) (and other sound analysis software) as precise alignment of signal is crucial for the accuracy of downstream measures of signal degradation. 

Misalignment can be fixed with the function `spcc_align()`. This function uses spectrogram cross-correlation to sync the position in time of signals with regard to a reference signal. `spcc_align()` takes the signal recorded at the closest distance to the source as the reference signal. The function calls [warbleR](https://cran.r-project.org/package=warbleR)'s `cross_correlation()` (just as we did above) internally to align signals using cross-correlation. 

[baRulho](https://marce10.github.io/baRulho/) comes with an example data set called  `playback_est_unaligned`, which contains signals in which the time position of signals is slightly unaligned. We can use this data to show how the function `spcc_align()` works: 

```{r, eval = FALSE}
 data("playback_est_unaligned")
 
 # method 1
playback_est_aligned <- spcc_align(X = playback_est_unaligned)

```

The output extended selection table contains the new start and end values after alignment. 

This is how the signals look before and after being aligned:

```{r, eval = FALSE}

# rename sound files so aligned and unaligned signals are intercalated
unalg <- rename_waves_est(playback_est_unaligned, playback_est_unaligned$sound.files, new.selec = seq(1, 200, by = 2)[1:nrow(playback_est_unaligned)])
alg <- rename_waves_est(playback_est_aligned, playback_est_aligned$sound.files, new.selec = seq(2, 200, by = 2)[1:nrow(playback_est_aligned)])

# add label 
unalg$type <- "Before aligning"
alg$type <- "After aligning"

# put together in a single ext sel tab
unalg.alg <- rbind(unalg, alg)

# create spectrograms
spectrograms(unalg.alg[unalg.alg$signal.type != "ambient", ], dest.path = tempdir(), res = 100, wl = 300, title.labels = "type", sel.labels = NULL)

```


<center><img src="spcc_align_results.gif" alt="time sync with spcc_align"></center>

&nbsp;

In case this doesn't work as expected there is a plan B. The function `seltailor()` from [warbleR](https://cran.r-project.org/package=warbleR) allows user to manually adjust the start and end of signals in a extended selection table.

&nbsp;

# Quantifying signal degradation

Most [baRulho](https://marce10.github.io/baRulho/) functions are design to quantify acoustic signal degradation. There are a few important things to keep in mind about functions for quantifying degradation:

- The package currently assumes that all recordings have been made with the same equipment and recording volume. This will be modified in future versions to allow for amplitude calibration of recordings.
- Wave envelope and frequency spectrum calculations are made after applying a bandpass filter within the frequency range of the reference signal ('bottom.freq' and 'top.freq' columns)
- The package offers two methods to compare signals to the reference: 
    1. Compare all signals with the counterpart that was recorded at the closest distance to source (e.g. compare a signal recorded at 5m, 10m and 15m with its counterpart recorded at 1m). This is the default method.
    1. Compare all signals with the counterpart recorded at the distance immediately before (e.g. a signal recorded at 10m compared with the one recorded at 5m, then signal recorded at 15m compared with the one recorded at 10m and so on).


## Required data structure

As mentioned above the data must be in `extended_selection_table` format. The data should also contain some additional information. [baRulho](https://marce10.github.io/baRulho/) comes with an example `extended_selection_table` data set that can be used to understand the required data structure:
s
```{r,eval=FALSE}

data("playback_est")

playback_est
```


```{r, eval = TRUE, echo = FALSE}

data("playback_est")

kbl <- kable(playback_est, align = "c", row.names = F,  format = "html", escape = F)

kbl <-  column_spec(kbl, 7:8, background = "#ccebff", bold = TRUE)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 12)

kbl <- scroll_box(kbl, height = "400px")

kbl

```
&nbsp;
 
 Note that besides the basic acoustic annotation information (e.g. sound file, time, frequency) the table also contains a **'signal.type' column, which refers to the signal type from which each signal belongs to**, and a **'distance' column that refers to the distance from the source at which each signal was recorded**. Signal type and distance are required for the comparison of signals. Also note that some selections are labeled as "ambient" in the 'signal.type'. These selections refer to ambient (background) noise. Ambient noise can be used by some functions to correct for amplitude differences due to non-target sounds.
 
In this example data there are 4 recordings at increasing distances: 1m, 5m, 10m and 15m:

```{r,eval=TRUE}

# count selection per recordings
unique(playback_est$sound.files)

```

The data contains selections for 5 signal types as well as 2 ambient noise selections at each distance/recording:

```{r, eval = FALSE}

table(playback_est$signal.type, playback_est$distance)

```

```{r, eval = TRUE, echo=FALSE}

tb <- table(playback_est$signal.type, playback_est$distance)

kbl <- kable(tb, align = "c", row.names = TRUE,  format = "html", escape = F)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 12)

kbl

```


## Degradation measurements  

### Blur ratio
 
Blur ratio quantifies the degradation of sound as a function of the change in signal energy in the time domain as described by Dabelsteen et al (1993). Blur ratio is measured as the mismatch between amplitude envelopes (expressed as probability density functions) of the reference signal and the re-recorded signal. Low values indicate low degradation of signals.  The function `blur_ratio()` measures the blur ratio of signals in which a reference playback has been re-recorded at different distances. The function compares each signal type to the corresponding reference signal within the supplied frequency range (e.g. bandpass) of the reference signal ('bottom.freq' and 'top.freq' columns in 'X'). The 'signal.type' column must be used to tell the function to only compare signals belonging to the same category (e.g. song-types). All wave objects in the extended selection table must have the same sampling rate so the length of envelopes is comparable.
Blur ratio can be calculated as follows:

```{r, eval = FALSE}

# run blur ratio
br <- blur_ratio(playback_est, method = 1, pb = FALSE)

# check output class
is_extended_selection_table(br)
```

```{r, eval = TRUE, echo = FALSE}

# run blur ratio
br <- blur_ratio(playback_est, method = 1, pb = FALSE)

# check output class
is_extended_selection_table(br)

```

```{r, eval = FALSE}

# see output
br

```

```{r, echo = FALSE}

kbl <- kable(br, align = "c", row.names = F,  format = "html", escape = F)

kbl <-  column_spec(kbl, 9:10, background = "#ccebff", bold = TRUE)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 10)

kbl <- scroll_box(kbl, height = "400px")

kbl

```
&nbsp;

The output data frame is similar to input data, except that it includes two new columns ('reference' and 'blur.ratio') with the reference signal and blur ratio values. Note that `NAs` are returned for signals used as reference and 'ambient' noise selections.

If `img = TRUE` it also returns 1 image file (in 'jpeg' format) for each comparison showing spectrograms of both signals and the overlaid amplitude envelopes (as probability mass functions (PMF)). 

```{r, eval = FALSE}

# run blur ratio
br <- blur_ratio(playback_est, method = 1, pb = FALSE, img = TRUE, ssmooth = 300, dest.path = td)

```

Output image files (in the working directory) look like these ones:

<center><img src="blur_ratio_example.gif" alt="time sync with spcc_align"></center>

&nbsp;

The image shows the spectrogram for the reference and re-recorded signal, as well as the envelopes of both signals overlaid in a single graph. Colors indicate to which signal spectrograms and envelopes belong to. The blur ratio value is also displayed.

The function can also return the amplitude spectrum contours when the argument `output = "list"`. The contours can be directly input into ggplot to visualize amplitude envelopes, and how they vary with distance and across signal types (and ambient noise if included):

```{r}

envs <- blur_ratio(X = playback_est, output = "list", ssmooth = 300, pb = FALSE)$envelopes

envs$distance <- as.factor(envs$distance)

ggplot(envs, aes(x= time, y = amp, col = distance)) +
    geom_line() +
    facet_wrap(~ signal.type) + 
    scale_color_viridis_d(alpha = 0.7) +  
    labs(x = "Time (s)", y = "Amplitude (PMF)") +
    theme_classic()
```

Note than the `smooth` argument could change envelope shapes and related measurements. The following code sets `smooth = 800`:

```{r}

envs <- blur_ratio(X = playback_est, output = "list", ssmooth = 1000, pb = FALSE)$envelopes

envs$distance <- as.factor(envs$distance)

ggplot(envs, aes(x= time, y = amp, col = distance)) +
    geom_line() +
    facet_wrap(~ signal.type) + 
    scale_color_viridis_d(alpha = 0.7) +  
    labs(x = "Time (s)", y = "Amplitude (PMF)") +
    theme_classic()

```

&nbsp;

### Spectral blur ratio
 
Spectral blur ratio (measured by `spectral_blur_ratio()`) quantifies the degradation of sound as a function of the change in signal energy across the frequency domain, analogous to the blur ratio described above for the time domain (and implemented in `blur_ratio()`). Low values also indicate low degradation of signals. Spectral blur ratio is measured as the mismatch between power spectra (expressed as probability density functions) of the reference signal and the re-recorded signal. It works in the same way than `blur_ratio()`, comparing each signal type to the corresponding reference signal, and the output and images are alike as well.

Spectral blur ratio can be calculated as follows:

```{r, eval = FALSE}

# run Spectral blur ratio
sbr <- spectral_blur_ratio(playback_est, method = 1, pb = FALSE, img = TRUE, dest.path = td)

# check output class
is_extended_selection_table(sbr)
```

```{r, eval = TRUE, echo = FALSE}

# run Spectral blur ratio
sbr <- spectral_blur_ratio(playback_est, method = 1, pb = FALSE)

# check output class
is_extended_selection_table(sbr)

```

```{r, eval = FALSE}

# see output
sbr

```

```{r, echo = FALSE}

kbl <- kable(sbr, align = "c", row.names = F,  format = "html", escape = F)

kbl <-  column_spec(kbl, 9:10, background = "#ccebff", bold = TRUE)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 10)

kbl <- scroll_box(kbl, height = "400px")

kbl

```
&nbsp;

<center><img src="spectral_blur_ratio_example.gif" alt="spectral blur-ratio"></center>

&nbsp;

As in `blur_ratio()`, `spectral_blur_ratio()` can also return the amplitude spectrum contours with the argument `output = "list"`:

```{r}

sbr <- spectral_blur_ratio(X = playback_est, output = "list", pb = FALSE)

spctr <- sbr$spectra

spctr$distance <- as.factor(spctr$distance)

ggplot(spctr, aes(y = amp, x = freq, col = distance)) +
  geom_line() +
  facet_wrap(~ signal.type) + 
  scale_color_viridis_d(alpha = 0.7) +  
  labs(x = "Frequency (kHz)", y = "Amplitude (PMF)") +
  coord_flip() +
  theme_classic()

```

We can also zoom in to the frequency range of the signals by subsetting the spectrum data:

```{r}

# get the frequencies higher than lowest bottom but lower than highest top freq
spctr <- spctr[spctr$freq > min(playback_est$bottom.freq) & spctr$freq < max(playback_est$top.freq), ]

ggplot(spctr, aes(y = amp, x = freq, col = distance)) +
  geom_line() +
  facet_wrap(~ signal.type) + 
  scale_color_viridis_d(alpha = 0.7) +  
  labs(x = "Frequency (kHz)", y = "Amplitude (PMF)") +
  coord_flip() +
  theme_classic()

```
&nbsp;

### Excess attenuation

With every doubling of distance, sounds attenuate with a 6 dB loss of amplitude (Morton, 1975; Marten & Marler, 1977). Any additional loss of amplitude results in excess attenuation, or energy loss in excess of that expected to occur with distance via spherical spreading, due to atmospheric conditions or habitat (Wiley & Richards, 1978). This degradation metric can be measured using the `excess_attenuation()` function. Low values indicate little signal attenuation. The function will then compare each signal type to the corresponding reference signal within the frequency range (e.g. bandpass) of the reference signal ('bottom.freq' and 'top.freq' columns in 'X'). Two methods for calculating excess attenuation are provided (see 'method' argument).

`excess_attenuation()`  can be measured like this:

```{r, eval = TRUE}

# run  envelope correlation
ea <- excess_attenuation(playback_est, method = 1, pb = FALSE)

# check output class
is_extended_selection_table(ea)

```


The output, similar to those of other functions, is an extended selection table with the input data, but also including two new columns ('reference' and  'excess.attenuation') with the reference signal and the excess attenuation:

```{r, eval = FALSE}
# print output
ea
```

```{r, echo = FALSE}

kbl <- kable(ea, align = "c", row.names = F,  format = "html", escape = F)

kbl <-  column_spec(kbl, 9:10, background = "#ccebff", bold = TRUE)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 10)

kbl <- scroll_box(kbl, height = "400px")

kbl

```

&nbsp;

### Envelope correlation

Amplitude envelope correlation measures the similarity of two signals in the time domain. The `envelope_correlation()` function measures the envelope correlation coefficients between reference playback and re-recorded signals. Values close to 1 means very similar amplitude envelopes (i.e. little degradation has occurred). If envelopes have different lengths (that is when signals have different lengths) cross-correlation is applied and the maximum correlation coefficient is returned. Cross-correlation is achieved by sliding the shortest signal along the largest one and calculating the correlation at each step. As in the functions detailed above, 'signal.type' column must be used to instruct the function to only compare signals that belong to the same category.

`envelope_correlation()` can be run as follows:

```{r, eval = TRUE}

# run  envelope correlation
ec <- envelope_correlation(playback_est, method = 1, pb = FALSE)

# check output class
is_extended_selection_table(ec)

```

The output is also similar to those of other functions; an extended selection table similar to input data, but also includes two new columns ('reference' and  'envelope.correlation')
with the reference signal and the amplitude envelope correlation coefficients:

```{r, eval = FALSE}
# print output
ec
```

```{r, echo = FALSE}

kbl <- kable(ec, align = "c", row.names = F,  format = "html", escape = F)

kbl <-  column_spec(kbl, 9:10, background = "#ccebff", bold = TRUE)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 10)

kbl <- scroll_box(kbl, height = "400px")

kbl

```

&nbsp;

Note that this function doesn't provide a graphical output. However, the graphs generated by `blur_ratio()` can be used to inspect the envelope shapes and the alignment of signals.

### Spectral correlation

Spectrum correlation measures the similarity of two signals in the frequency domain. This is similar to `spectral_correlation()`, but no cross-correlation is applied as both signals are compared within the frequency range of the reference signal (so both spectra have the same length). Again, values near 1 indicate identical frequency spectrum  (i.e. no degradation). 

```{r, eval = TRUE}

# run spectral correlation
sc <- spectral_correlation(playback_est, method = 1, pb = FALSE)

# check output class
is_extended_selection_table(sc)

```

The output is also similar to that of `envelope_correlation()`:

```{r, eval = FALSE}
# print output
sc
```

```{r, echo = FALSE}

kbl <- kable(sc, align = "c", row.names = F,  format = "html", escape = F)

kbl <-  column_spec(kbl, 9:10, background = "#ccebff", bold = TRUE)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 10)

kbl <- scroll_box(kbl, height = "400px")

kbl

```

&nbsp;

As in `envelope_correlation()`, `spectral_correlation()` doesn't provide a graphical output. However, the graphs generated by `spectral_blur_ratio()` can also be used to inspect the spectrum shapes and the signal alignment.

### Signal-to-noise ratio

Signal-to-noise ratio (SNR) quantifies signal amplitude level in relation to ambient noise as a metric of overall signal attenuation. Therefore, attenuation refers to the loss of energy as described by Dabelsteen et al (1993). This method is implemented in the function `signal_to_noise_ratio()`. The function requires a measurement of ambient noise, which could either be the noise right before each signal (`noise.ref = "adjacent"`) or one or more ambient noise measurements per recording (`noise.ref = "custom"`). For the latter, selections on signal parameters in which ambient noise will be measured must be specified. Alternatively, one or more selections of ambient noise can be used as reference (see 'noise.ref' argument). This can potentially provide a more accurate representation of ambient noise. When margins overlap with another acoustic signal nearby, SNR will be inaccurate, so margin length should be carefully considered. Any SNR less than or equal to one suggests background noise is equal to or overpowering the acoustic signal. SNR can be measured as follows:

```{r, eval = TRUE}

# run signal to noise ratio
sa <- signal_to_noise_ratio(playback_est,  pb = FALSE, noise.ref = "custom")

# check output class
is_extended_selection_table(sa)

```

The output is also similar to the other functions:

```{r, eval = FALSE}
# print output
sa
```

```{r, echo = FALSE}


kbl <- kable(sa, align = "c", row.names = F,  format = "html", escape = F)

kbl <-  column_spec(kbl, 9, background = "#ccebff", bold = TRUE)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 10)

kbl <- scroll_box(kbl, height = "400px")

kbl

```

&nbsp;

Note that this function does not compare signals to references, so no reference column is added.

### Tail-to-signal ratio

Tail-to-signal ratio (TSR) is used to quantify reverberations. Specifically TSR measures the ratio of energy in the reverberation tail  (the time segment right after the signal) to energy in the signal. A general margin in which reverberation tail will be measured must be specified. The function will measure TSR within the supplied frequency range (e.g. bandpass) of the reference signal ('bottom.freq' and 'top.freq' columns in 'X'). Two methods for calculating reverberations are provided (see 'type' argument). `Type 1` is based on the original description of TSR in Dabelsteen et al. (1993) while `type 2` is better referred to as "tail-to-noise ratio", given that it compares the amplitude of tails to those of ambient noise. For both types higher values represent more reverberations. TSR can be measured as follows:

```{r, eval = TRUE}

# run tail to signal ratio
tsr <- tail_to_signal_ratio(playback_est,  pb = FALSE, 
                           type = 1, mar = 0.05)

# check output class
is_extended_selection_table(tsr)

```

Again, the output is similar to other functions:

```{r, eval = FALSE}
# print output

tsr

```

```{r, echo = FALSE}


kbl <- kable(tsr, align = "c", row.names = F,  format = "html", escape = F)

kbl <-  column_spec(kbl, 9, background = "#ccebff", bold = TRUE)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 10)

kbl <- scroll_box(kbl, height = "400px")

kbl

```

&nbsp;

### Spectrogram distortion

Finally, the function `spcc()` measures spectrogram cross-correlation as a metric of signal distortion of signals. Values close to 1 means very similar spectrograms (i.e. little signal distortion). The function is a wrapper on [warbleR](https://cran.r-project.org/package=warbleR)'s `cross_correlation()`. It can be run as follows:

```{r, eval = TRUE}

# run spcc
spd <- spcc(X = playback_est, method = 1, pb = FALSE, wl = 512)

# check output class
is_extended_selection_table(spd)

```

And again, the output is similar to other functions:

```{r, eval = FALSE}
# print output
spd
```

```{r, echo = FALSE}

kbl <- kable(spd, align = "c", row.names = F,  format = "html", escape = F)

kbl <-  column_spec(kbl, 9:10, background = "#ccebff", bold = TRUE)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 10)

kbl <- scroll_box(kbl, height = "400px")

kbl

```

&nbsp;

## Other measurements

### Noise profiles

The function `noise_profile()` allows to estimate the frequency spectrum of ambient noise. This can be done on extended selection tables (using the segments containing no signal) or over complete sound files in the working directory (or path supplied). The function uses \code{\link[seewave]{meanspec}} internally to calculate frequency spectra. The following code measures the ambient noise profile for the recordings at distance >= 5m on the example extended selection table:

```{r, eval = TRUE}

# run noise profile
np <- noise_profile(X = playback_est[playback_est$distance > 5, ], mar = 0.05, pb = FALSE)

str(np)
```

The output is a data frame with amplitude values for the frequency bins for each wave object in the extended selection table:

```{r, eval = FALSE}
# print output
head(np, 20)

```

```{r, echo = FALSE}

kbl <- kable(np[1:20, ], align = "c", row.names = F,  format = "html", escape = F)

kbl <-  column_spec(kbl, 2:3, background = "#ccebff", bold = TRUE)

kbl <-  kable_styling(kbl, bootstrap_options = "striped", font_size = 10)

kbl <- scroll_box(kbl, height = "400px")

kbl

```

This can be graphically represented as follows:

```{r, eval = TRUE}

ggplot(np, aes(y = amp, x = freq, col = sound.files)) +
  geom_line(size = 1.4) +
   scale_color_viridis_d(begin = 0.2, end = 0.8, alpha = 0.5) +  
 labs(x = "Frequency (kHz)", y = "Amplitude (dBA)") +
  coord_flip() +
  theme_classic()

```

The output data is actually an average of several frequency spectra for each sound file. We can obtain the original spectra by setting the argument `averaged = FALSE`: 

```{r, eval = TRUE, warning = FALSE}

np <- noise_profile(X = playback_est[playback_est$distance > 5, ], 
      mar = 0.1, pb = FALSE, averaged = FALSE)

# make a column containing sound file and selection
np$sf.sl <- paste(np$sound.files, np$selec)

ggplot(np, aes(y = amp, x = freq, col = sound.files, group = sf.sl)) +
  geom_line(size = 1.4) +
    scale_color_viridis_d(begin = 0.2, end = 0.8, alpha = 0.5) +  
 labs(x = "Frequency (kHz)", y = "Amplitude (dBA)") +
  coord_flip() +
  theme_classic()

```

Note that we can limit the frequency range by using a bandpass filter ('bp' argument). In addition, the argument 'hop.size', which control the size of the time windows, affects the precision in the frequency domain. We can get a better precision by increasing 'hop.size' (or 'wl'):


```{r, eval = TRUE}

np <- noise_profile(X = playback_est[playback_est$distance > 5, ], 
      mar = 0.05, pb = FALSE, bp = c(0, 10), 
      averaged = FALSE, hop.size = 3)

# make a column containing sound file and selection
np$sf.sl <- paste(np$sound.files, np$selec)

ggplot(np, aes(y = amp, x = freq, col = sound.files, group = sf.sl)) +
  geom_line(size = 1.4) +
  scale_color_viridis_d(begin = 0.2, end = 0.8, alpha = 0.5) +  
  labs(x = "Frequency (kHz)", y = "Amplitude (dBA)") +
  coord_flip() +
  theme_classic()

```


The function can estimate noise profiles for complete sound files, by supplying a list of the files (argument 'files', and not supplying  'X') or by simply running it without supplying 'X' or 'files'. In this case it will run over all sound files in the working directory (or 'path' supplied). 

---

Please report any bugs [here](https://github.com/maRce10/baRulho/issues). 

The package [baRulho](https://marce10.github.io/baRulho/) should be cited as follows:

Araya-Salas, M. (2020), *baRulho: quantifying habitat-induced degradation of (animal) acoustic signals in R*. R package version 1.0.0.

---

# References

1. Araya-Salas, M. (2017). *Rraven: connecting R and Raven bioacoustic software*. R package version 1.0.0.

1.  Araya-Salas, M. (2020), *baRulho: quantifying habitat-induced degradation of (animal) acoustic signals in R*. R package version 1.0.0
  
1. Araya-Salas M, Smith-Vidaurre G (2017) *warbleR: An R package to streamline analysis of animal acoustic signals*. Methods Ecol Evol 8:184–191.

1. Dabelsteen, T., Larsen, O. N., & Pedersen, S. B. (1993). *Habitat-induced degradation of sound signals: Quantifying the effects of communication sounds and bird location on blur ratio, excess attenuation, and signal-to-noise ratio in blackbird song*. The Journal of the Acoustical Society of America, 93(4), 2206.

1. Marten, K., & Marler, P. (1977). *Sound transmission and its significance for animal vocalization. Behavioral* Ecology and Sociobiology, 2(3), 271-290.

1. Morton, E. S. (1975). *Ecological sources of selection on avian sounds*. The American Naturalist, 109(965), 17-34.

1. Tobias, J. A., Aben, J., Brumfield, R. T., Derryberry, E. P., Halfwerk, W., Slabbekoorn, H., & Seddon, N. (2010). *Song divergence by sensory drive in Amazonian birds*. Evolution, 64(10), 2820-2839.

---

<font size="4">Session information</font>

```{r session info, echo=F}

sessionInfo()

```
