| multActivity | R Documentation |
Calculate the Acoustic Activity Matrix used in the the calculation of Soundscape Saturation using Burivalova 2018 methodology for a set of recordings
multActivity(
soundpath,
channel = "stereo",
timeBin = 60,
dbThreshold = -90,
targetSampRate = NULL,
wl = 512,
window = signal::hamming(wl),
overlap = ceiling(length(window)/2),
histbreaks = "FD",
DCfix = TRUE,
powthr = 10,
bgnthr = 0.8,
beta = TRUE,
backup = NULL
)
soundpath |
single or multiple directories to your |
channel |
channel where the saturation values will be extracted from. Available channels are: |
timeBin |
size (in seconds) of the time bin. Set to |
dbThreshold |
minimum allowed value of dB for the spectrograms. Set to |
targetSampRate |
desired sample rate of the audios. This argument is only used to down sample the audio. If |
wl |
window length of the spectrogram. Defaults to |
window |
window used to smooth the spectrogram. Switch to |
overlap |
overlap between the spectrogram windows. Defaults to |
histbreaks |
breaks used to calculate Background Noise. Available breaks are: |
DCfix |
if the DC offset should be removed before the metrics are calculated. Defaults to |
powthr |
single numeric value to calculate the activity matrix for soundscape power (in dB). Defaults to |
bgnthr |
single numeric value to calculate the activity matrix for background noise (in %). Defaults to |
beta |
how BGN thresholds are calculated. If |
backup |
directory to save the backup. Defaults to |
In this function, we only generate activity matrices for an directory using Burivalova 2018 methodology. For each time bin of the recording we apply the following formula:
a_{m,f} = \begin{cases} 1, & \text{if } BGN_{m,f} > \theta_1 \ \text{ or } POW_{m,f} > \theta_2 \\ 0, & \text{otherwise} \end{cases}
where \theta is a user-defined threshold applied uniformly to both BGN and POW. We set 1 to active and 0 to inactive frequency windows.
If backup is set to a valid directory, a file named "SATBACKUP.rds" is automatically saved after every batch of five processed files. This file stores the current processing state and allows interrupted runs (e.g., due to manual termination, session crashes, or system shutdowns) to be resumed using satBackup().
To resume processing, pass the saved file (e.g., "path/SATBACKUP.rds") to satBackup(). Once a backup has been created, all original arguments and file paths must remain unchanged, unless they are explicitly modified within the saved .RData object.
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.
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
activity() to run this on a single audio file, soundSat() and soundMat() to get saturation values instead. Also, check satBackup() if you are working with larger datasets and want some safety.
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)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.