MyNixOS website logo
Description

Soundscape Background Noise, Power, and Saturation.

Accessible and flexible implementation of three ecoacoustic indices that are less commonly available in existing R frameworks: Background Noise, Soundscape Power and Soundscape Saturation. The functions were design to accommodate a variety of sampling designs. Users can tailor calculations by specifying spectrogram time bin size, amplitude thresholds and normality tests. By simplifying computation and standardizing reproducible methods, the package aims to support ecoacoustics studies. For more details about the indices read Towsey (2017) <https://eprints.qut.edu.au/110634/> and Burivalova (2017) <doi:10.1111/cobi.12968>.

Ruido: An R Package for Profiling Background Noise and Calculating Soundscape Saturation

CRANStatusBadge packageDownloads lastGitCommit status

Ruido is an R package that aims to provide a simple and accessible framework for calculating less common soundscape metrics that describes noise dynamics. It provides accessible tools for calculating less common, but ecologically meaningful soundscape metrics, helping researchers move beyond standard and classic indices.

The package implements methods to estimate:

  • Background Noise (BGN) and Soundscape Power (POW), following Towsey et al. (2017)
  • Soundscape Saturation (SAT), following Burivalova et al. (2018)

These metrics can be used to explore acoustic complexity, biotic activity, and environmental disturbance, making Ruido useful for ecological monitoring, bioacoustic surveys, or experimental soundscape studies.

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
  • Towsey, M. W. (2017). The calculation of acoustic indices derived from long-duration recordings of the natural environment. In eprints.qut.edu.au. https://eprints.qut.edu.au/110634/

Installation

CRAN Download:

install.packages("Ruido")
library(Ruido)

Github Download:

devtools::install_github("Arthurigorr/Ruido")
library(Ruido)

Examples:

To illustrate the package's use, we are going to use the recordings available at: <brUse https://zenodo.org/records/17575795 to use lighter recordings.

If you wish to temporary download the files using R to follow the examples, run:

options(timeout = 500)

dir <- tempdir()
recName <- paste0("GAL24576_20250401_", sprintf("%06d", seq(0, 230000, by = 10000)), ".wav")
recDir <- paste(dir, recName, sep = "/")

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

These examples use ggplot2 and patchwork to plot their results. Before running them, first run:

library(ggplot2)
library(patchwork)

Background Noise (BGN) and Soundscape Power (POW)

BGN_POW <- lapply(recDir, bgNoise)

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))
sampRate <- BGN_POW[[1]]$sampRate
kHz <- cumsum(c(0, rep(sampRate / 6, 6))) / 1000
breaks <- round(c(1, cumsum(rep(256 / 6, 6))))

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

plotList <- list()
plotN <- 1

for (ind in c("BGN", "POW")) {
  for (cha in c("left", "right")) {
    core <- do.call(cbind, lapply(BGN_POW, function(x) {
      x[[cha]][[ind]]
    }))
    
    dim(BGNLEFT)
    
    coreDf <- data.frame(
      TIME = as.character(rep(dateTime, each = sDim[1] * 3) + rep(rep(c(0, 60, 120), each = sDim[1]), sDim[2] / 3)),
      SPEC = rep(seq(sDim[1]), sDim[2]), VAL = c(unlist(core))
    )
    
    plotList[[plotN]] <- ggplot(coreDf, aes(x = TIME, y = SPEC, fill = VAL)) +
      geom_tile() +
      theme_classic() +
      scale_y_continuous(expand = c(0, 0), labels = kHz, breaks = breaks) +
      scale_x_discrete(expand = c(0, 0), labels = timeLabels, breaks = timeBreaks) +
      scale_fill_viridis_c(option = "magma", name = ind) +
      labs( x = "Time of Day", y = "Frequency (kHz)", title = paste(ind, "in the", cha, "channel")
      )
    
    plotN <- plotN + 1
    
  }
}

plotList[[1]] + plotList[[2]] + plotList[[3]] + plotList[[4]]

Soundscape Saturation (SAT)

sat <- soundSat(dir)
SAT <- sat$values

satForPlot <- cbind(
  aggregate(SAT ~ AUDIO + CHANNEL, data = SAT, sd),
  aggregate(SAT ~ AUDIO + CHANNEL, data = SAT, mean)$SAT,
  TIME = rep(substr(time, 1, 5), 2)
)
colnames(satForPlot)[c(3, 4)] <- c("sdSAT", "meanSAT")

ggplot(
  satForPlot,
  aes(x = TIME, y = meanSAT * 100, group = CHANNEL, fill = CHANNEL,
    ymin = pmax(meanSAT - sdSAT, 0) * 100, ymax = pmin(meanSAT + sdSAT, 100) * 100
  )
) +
  geom_ribbon(alpha = 0.5) +
  geom_line() +
  geom_point() +
  theme_classic() +
  scale_y_continuous(limits = c(0, 100), expand = c(0, 0)) +
  scale_x_discrete( expand = c(0, 0), breaks = c("00:00", "06:00", "12:00", "18:00", "23:00")
  ) +
  labs(y = "Soundscape Saturation (%)") +
  theme(
    axis.title.x = element_blank(), axis.text = element_text(size = 15),
    axis.title = element_text(size = 18, face = "bold"),
    legend.title = element_text(size = 15, face = "bold"),
    legend.text = element_text(size = 15)
  ) +
  guides(fill = guide_legend(title = "Side"))

Acoustic Activity

act <- multActivity(dir, powthr = sat$powthresh, bgnthr = sat$bgntresh / 100)

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))
sampRate <- act$info$SAMPRATE[[1]]
kHz <- cumsum(c(0, rep(sampRate / 6, 6))) / 1000
breaks <- round(c(1, cumsum(rep(256 / 6, 6))))

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

plotList <- list()
plotN <- 1

for (cha in c("left", "right")) {
  actCurrent <- act$values[, act$info$CHANNEL == cha]
  actCurrentDF <- data.frame(
    TIME = as.character(rep(dateTime, each = sDim[1] * 3) + rep(rep(c(0, 60, 120), each = sDim[1]), sDim[2] / 3)),
    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 = timeLabels, breaks = timeBreaks) +
    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(guides = "collect")
Metadata

Version

1.0.2

License

Unknown

Platforms (78)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    uefi
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-uefi
  • aarch64-windows
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-linux
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-uefi
  • x86_64-windows