Learn R Programming

Ruido (version 1.0.2)

multActivity: Multiple Acoustic Activity Matrix

Description

Calculate the Acoustic Activity Matrix used in the the calculation of Soundscape Saturation using Burivalova 2018 methodology for a set of recordings

Usage

multActivity(
  soundpath,
  channel = "stereo",
  timeBin = 60,
  dbThreshold = -90,
  targetSampRate = NULL,
  wl = 512,
  window = signal::hamming(wl),
  overlap = ceiling(length(window)/2),
  histbreaks = "FD",
  powthr = 10,
  bgnthr = 0.8,
  beta = TRUE,
  backup = NULL
)

Value

A list containing five objects. The first and second objects (powthresh and bgnthresh) are the threshold values inputted as arguments into the function. The third (info) contains the following variables from every audio file: PATH, AUDIO, CHANNEL, DURATION, BIN, SAMPRATE.. The fourth object (values) contains a matrix with the the values of activity for each bin of each recording and the size of the bin in seconds. The fifth contains a list with errors that occurred with specific files during the function.

Arguments

soundpath

single or multiple directories to your audio files

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. Set to NULL to use the entire audio as a single bin. Defaults to 60

dbThreshold

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

targetSampRate

desired sample rate of the audios. This argument is only used to down sample the audio. If NULL, then audio's sample rate remains the same. Defaults to NULL

wl

window length of the spectrogram. Defaults to 512

window

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

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" or any numeric value (foe example = 100). Defaults to "FD"

powthr

single numeric value to calculate the activity matrix for soundscape power (in dB). Detauls to 10

bgnthr

single numeric value to calculate the activity matrix for background noise (in %). Detauls to 0.8

beta

how BGN thresholds are calculated. If TRUE, BGN thresholds are calculated using all recordings combined. If FALSE, BGN thresholds are calculated separately for each recording. Defaults to TRUE

backup

directory to save the backup. Defaults to NULL

Details

We generate an activity matrix using Burivalova 2018 methodology. For each time bin of the recording we apply 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. 1 = active and 0 = inactive.

If backup is set to a valid directory, a file named "SATBACKUP.RData" is saved after every batch of five processed files. If the function execution is interrupted (e.g., manual termination, an R session crash, or a system shutdown), this backup file can be passed to satBackup() (e.g., ~path/SATBACKUP.RData) to resume the original process. Once a backup is created, all arguments and file paths must remain unchanged, unless they are manually modified within the .RData object.

References

Burivalova, Z., Towsey, M., Boucher, T., Truskinger, A., Apelis, C., Roe, P., & Game, E. T. (2018). 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{
if (require("ggplot2") & require("patchwork")) {
  ### Generating an artificial audio for the example
  ## For this example we'll generate a sweep in a noisy soundscape
  library(ggplot2)
  library(patchwork)

  ### Downloading audiofiles from public Zenodo library
  dir <- paste0(tempdir(), "/forExamples")
  dir.create(dir)
  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")
  }

  time <- sapply(strsplit(recName, "_"), function(x)
    paste(substr(x[3], 1, 2), substr(x[3], 3, 4), substr(x[3], 5, 6), sep = ":"))
  date <- sapply(strsplit(recName, "_"), function(x)
    paste(substr(x[2], 1, 4), substr(x[2], 5, 6), substr(x[2], 7, 8), sep = "-"))

  dateTime <- as.POSIXct(paste(date, time))

  timeLabels <- time[c(1, 7, 13, 19, 24)]
  timeBreaks <- as.character(dateTime[c(1, 7, 13, 19, 24)])

  breaks <- round(c(1, cumsum(rep(256 / 6, 6))))

  ### Running the function
  act <- multActivity(dir)

  plotN <- 1

  sDim <- dim(act$values)

  sampRate <- act$info$SAMPRATE[1]
  kHz <- cumsum(c(0, rep(sampRate / 6, 6))) / 1000

  plotList <- list()

  for (cha in c("left", "right")) {
    actCurrent <- act$values[, act$info$CHANNEL == cha]
    actCurrentDF <- data.frame(
      TIME = as.character(rep(dateTime, each = sDim[1])),
      SPEC = rep(seq(sDim[1]), sDim[2]),
      VAL = factor(c(unlist(actCurrent)), levels = c(0, 1))
    )

    plotList[[plotN]] <- ggplot(actCurrentDF, aes(x = TIME, y = SPEC, fill = VAL)) +
      geom_tile() +
      theme_classic() +
      scale_y_continuous(expand = c(NA, NA),
                         labels = kHz,
                         breaks = breaks) +
      scale_x_discrete(expand = c(0, 0),
                       labels = time) +
      scale_fill_manual(values = c("white", "black"),
                        labels = c("Inactive", "Active")) +
      guides(fill = guide_legend(title = "Acoustic Activity")) +
      labs(
        x = "Time of Day",
        y = "Frequency (kHz)",
        title = paste("Acoustic Activity in the", cha, "channel")
      )

    plotN <- plotN + 1

  }

  plotList[[1]] + plotList[[2]] + plot_layout(guide = "collect")

  unlink(recDir)
  unlink(dir)

  }
# }

Run the code above in your browser using DataLab