Learn R Programming

Ruido (version 1.0.1)

soundMat: Soundscape Saturation Matrix

Description

Get the Soundscape Saturation matrix with all threshold combinations instead of the combination with the most normal distribution

Usage

soundMat(
  soundpath,
  channel = "stereo",
  timeBin = 60,
  dbThreshold = -90,
  targetSampRate = NULL,
  wl = 512,
  window = signal::hamming(wl),
  overlap = ceiling(length(window)/2),
  histbreaks = "FD",
  powthr = c(5, 20, 1),
  bgnthr = c(0.5, 0.9, 0.05),
  backup = NULL
)

Value

A list containing five objects. The first and second objects (powthresh and bgnthresh) are the threshold values that yielded the most normal distribution of saturation values using the normality test set by the user. The third (normality) contains the statitics values of the normality test that yielded the most normal distribution. The fourth object (values) contains a data.frame with the the values of saturation for each bin of each recording and the size of the bin in seconds. The fifth contains a data.frame with errors that occurred with specific files during the function.

Arguments

soundpath

single directory or multiple directory to audio files. The directory must lead to a single folder or a combination of folders.

channel

channel where the saturation values will be extract from. Available channels are: "stereo", "mono", "left" or "right". Defaults to "stereo".

timeBin

size (in seconds) of the time bin. Defaults to 60.

dbThreshold

minimum allowed value of dB for the spectrograms. Defaults to -90, as set by Towsey.

targetSampRate

sample rate of the audios. Defaults to NULL to not change the sample rate. This argument is only used to down sample the audio.

wl

window length of the spectrogram. Defaults to 512.

window

window used to smooth the spectrogram. Defaults to signal::hammning(wl). Switch to signal::hanning(wl) if to use hanning instead.

overlap

overlap between the spectrogram windows. Defaults to wl/2 (half the window length)

histbreaks

breaks used to calculate Background Noise. Available breaks are: "FD", "Sturges", "scott" and 100. Defaults to "FD".
Can also be set to any number to limit or increase the amount of breaks.

powthr

vector of values to evaluate the activity matrix for Soundscape Power (in dB). The first value corresponds to the lowest dB value and the second corresponds to the highest, the third value is the step.
Defaults to c(5, 20, 1), which means the first thresholds starts at 5dB and jumps a whole number till 20dB.

bgnthr

vector of values to evaluate the activity matrix for Background Noise (in %). The first value corresponds to the lowest quantile value and the second corresponds to the highest, the third value is the step.
Defaults to c(0.5, 0.9, 0.05), which means the first thresholds starts at 50% and jumps 5% till 90%.

backup

path to backup the saturation values in case the computer is turned off during processing or in case you cannot be sure the computer will be on for the entire process. Defaults to NULL.
The backup will be updated every 5 recordings processed.

Details

Soundscape Saturation (SAT) is a measure of the proportion of frequency bins that are acoustically active in a determined window of time. It was developed by Burivalova et al. 2017 as an index to test the acoustic niche hypothesis. To calculate this function, first we need to generate an activity matrix for each time bin of your recording with the following formula:

$$a_{mf} = 1\ if (BGN_{mf} > \theta_{1})\ or\ (POW_{mf} > \theta_{2});\ otherwise,\ a_{mf} = 0,$$

Where \(\theta_{1}\) is the threshold of BGN values and \(\theta_{2}\) is a threshold of dB values. Since we define a interval for both the threshold, this means that an activity matrix will be generated for each bin of each recording. For each combination of threshold a SAT measure will be taken with the following formula:

$$S_{m} = \frac{\sum_{f = 1}^N a_{mf}}{N}$$

After these equations are done, we check every threshold combination for normality and pick the combination that yields the most normal distribution of saturation values.

If you set a path for the "path" argument, a single rds file will be written in your path. This objects can be loaded again through the "satBack" function to continue the calculation of saturation in case the process is suddenly stopped.

References

Burivalova, Z., Towsey, M., Boucher, T., Truskinger, A., Apelis, C., Roe, P., & Game, E. T. (2017). Using soundscapes to detect variable degrees of human influence on tropical forests in Papua New Guinea. Conservation Biology, 32(1), 205-215. https://doi.org/10.1111/cobi.12968

Examples

Run this code
# \donttest{
oldpar <- par(no.readonly = TRUE)
### Downloading audiofiles from public Zenodo library
dir <- tempdir()
recName <- paste0("GAL24576_20250401_", sprintf("%06d", seq(0, 200000, by = 50000)), ".wav")
recDir <- paste(dir, recName, sep = "/")

for (rec in recName) {
  print(rec)
  url <- paste0("https://zenodo.org/records/17575795/files/",
                rec,
                "?download=1")
  download.file(url, destfile = paste(dir, rec, sep = "/"), mode = "wb")
}

### Running the function
sat <- soundMat(dir)

### Plotting results
sides <- ifelse(grepl("left", sat$info$BIN), "left", "right")

thresholds <- colnames(sat$matrix)
split <- strsplit(thresholds, "/")

shapNorm <- apply(sat$matrix, 2, function(x)

  if (var(x) == 0) {
    0
  } else {
    shapiro.test(x)$statistic
  })

shapPos <- which.max(shapNorm)

par(mfrow = c(3, 2))

plot(
  sat$matrix[sides == "left", 1],
  main = paste0("POW = ", split[[1]][1], "dB | BGN = ", split[[1]][2], "%"),
  type = "b",
  ylim = c(0,1),
  xlab = "Time Index", ylab = "Soundsacpe Saturation (%)", col = "goldenrod"
)
points(sat$matrix[sides == "right", 1], col = "maroon", type = "b")

hist(sat$matrix[,1], main = paste("Histogram of POW = ", split[[1]][1],
"dB | BGN = ", split[[1]][2], "%"), xlab = "Soundscape Saturation (%)")

plot(
sat$matrix[sides == "left", 144],
main = paste0("POW = ", split[[144]][1], "dB | BGN = ", split[[144]][2], "%"),
type = "b",
ylim = c(0,1),
xlab = "Time Index", ylab = "Soundsacpe Saturation (%)", col = "goldenrod"
)
points(sat$matrix[sides == "right", 144], col = "maroon", type = "b")

hist(sat$matrix[,144], main = paste("Histogram of POW = ", split[[144]][1],
"dB | BGN = ", split[[144]][2], "%"), xlab = "Soundscape Saturation (%)")

plot(
  sat$matrix[sides == "left", shapPos],
  main = paste0(
    "POW = ",
    split[[shapPos]][1],
    "dB | BGN = ",
    split[[shapPos]][2],
    "%",
    "\nshapiro.test. statistic (W): ",
    which.max(shapNorm)
  ),
  type = "b",
  ylim = c(0,1),
  xlab = "Time Index", ylab = "Soundsacpe Saturation (%)", col = "goldenrod"
)
points(sat$matrix[sides == "right", shapPos], col = "maroon", type = "b")
hist(sat$matrix[,shapPos], main = paste("Histogram of POW = ",
split[[shapPos]][1], "dB | BGN = ", split[[shapPos]][2], "%"),
xlab = "Soundscape Saturation (%)")

unlink(recDir)
par(oldpar)
# }

Run the code above in your browser using DataLab