Nothing
#' Fix .wav files to allow importing them into R
#'
#' \code{fix_wavs} fixes sound files in .wav format so they can be imported into R.
#' @usage fix_wavs(checksels = NULL, files = NULL, samp.rate = NULL, bit.depth = NULL,
#' path = NULL, mono = FALSE)
#' @param checksels Data frame with results from \code{\link{check_sels}}. Default is \code{NULL}. If both 'checksels' and 'files' are \code{NULL}
#' then all files in 'path' are converted. Note that it only fixes/convert sound files in .wav format.
#' @param files Character vector with the names of the .wav files to fix. Default is \code{NULL}. If both 'checksels' and 'files' are \code{NULL}
#' then all files in 'path' are converted.
#' @param samp.rate Numeric vector of length 1 with the sampling rate (in kHz) for output files. Default is \code{NULL}.
#' (remain unchanged).
#' @param bit.depth Numeric vector of length 1 with the dynamic interval (i.e. bit depth) for output files.
#' Default is \code{NULL} (remain unchanged).
#' @param path Character string containing the directory path where the sound files are located.
#' If \code{NULL} (default) then the current working directory is used.
#' @param mono Logical indicating if stereo (2 channel) files should be converted to mono (1 channel). Default is \code{FALSE} (remain unchanged).
# #' @param sox Logical indicating if \href{https://sox.sourceforge.net/sox.html}{SOX} should be used for resampling. If \code{TRUE} SOX must be installed. Default is \code{FALSE}.
#' @return A folder inside the working directory (or path provided) all 'converted_sound_files', containing
#' sound files in a format that can be imported in R.
#' @export
#' @name fix_wavs
#' @details This function aims to simplify the process of converting sound files that cannot be imported into R and/or homogenizing sound files. Problematic files can be determined using \code{\link{check_wavs}} or \code{\link{check_sels}}. The
#' \code{\link{check_sels}} output can be directly input using the argument 'checksels'. Alternatively a vector of file
#' names to be "fixed" can be provided (argument 'files'). If neither of those 2 are provided the function will convert
#' all .wav sound files in the working directory to the specified sample rate/bit depth. Files are saved in a new directory
#' ('converted_sound_files'). Internally the function calls \href{https://sox.sourceforge.net/sox.html}{SOX} (\href{https://sox.sourceforge.net/sox.html}{SOX} must be installed). If both 'checksels' and 'files' are \code{NULL}
#' then all files in 'path' are converted. Note that it only fixes/convert sound files in .wav format.
#'
#' @examples
#' \dontrun{
#' # Load example files and save to temporary working directory
# data(list = c("Phae.long1", "Phae.long2", "Phae.long3", "Phae.long4", "lbh_selec_table"))
# writeWave(Phae.long1, file.path(tempdir(), "Phae.long1.wav"))
# writeWave(Phae.long2, file.path(tempdir(), "Phae.long2.wav"))
# writeWave(Phae.long3, file.path(tempdir(), "Phae.long3.wav"))
# writeWave(Phae.long4, file.path(tempdir(), "Phae.long4.wav"))
#' #
# fix_wavs(files = lbh_selec_table$sound.files, path = tempdir())
#'
#' # check this folder
#' tempdir()
#' }
#'
#' @references {
#' Araya-Salas, M., & Smith-Vidaurre, G. (2017). warbleR: An R package to streamline analysis of animal acoustic signals. Methods in Ecology and Evolution, 8(2), 184-191.
#' }
#' @author Marcelo Araya-Salas (\email{marcelo.araya@@ucr.ac.cr})
# last modification on oct-22-2018 (MAS)
fix_wavs <- function(checksels = NULL, files = NULL, samp.rate = NULL, bit.depth = NULL, path = NULL, mono = FALSE) {
# error message if bioacoustics is not installed
if (!requireNamespace("bioacoustics", quietly = TRUE) & !is.null(samp.rate)) {
stop2("must install 'bioacoustics' to use for changing sampling rate")
}
#### set arguments from options
# get function arguments
argms <- methods::formalArgs(fix_wavs)
# get warbleR options
opt.argms <- if (!is.null(getOption("warbleR"))) getOption("warbleR") else SILLYNAME <- 0
# remove options not as default in call and not in function arguments
opt.argms <- opt.argms[!sapply(opt.argms, is.null) & names(opt.argms) %in% argms]
# get arguments set in the call
call.argms <- as.list(base::match.call())[-1]
# remove arguments in options that are in call
opt.argms <- opt.argms[!names(opt.argms) %in% names(call.argms)]
# set options left
if (length(opt.argms) > 0) {
for (q in seq_len(length(opt.argms))) {
assign(names(opt.argms)[q], opt.argms[[q]])
}
}
# check path to working directory
if (is.null(path)) {
path <- getwd()
} else if (!dir.exists(path)) {
stop2("'path' provided does not exist")
} else {
path <- normalizePath(path)
}
# If both 'checksels' and 'files' are NULL
if (is.null(checksels) & is.null(files)) files <- list.files(path = path, pattern = ".wav$", ignore.case = TRUE)
if (!is.null(checksels)) {
fls <- unique(checksels$sound.files[checksels$check.res == "Sound file can't be read" | checksels$check.res == "file header corrupted"])
if (length(fls) == 0) stop2("All files were OK according tochecksels")
# if X is not a data frame
if (!is(checksels, "data.frame")) stop2("checksels is not a data frame")
if (!all(c("sound.files", "check.res") %in% colnames(checksels))) {
stop2(paste(paste(c("sound.files", "check.res")[!(c("sound.files", "check.res") %in% colnames(checksels))], collapse = ", "), "column(s) not found in data frame (does not seem to be the output of checksels)"))
}
} else {
fls <- unique(files)
}
if (length(list.files(pattern = "\\.wav$", ignore.case = TRUE, path = path)) == 0) if (is.null(path)) stop2("No .wav files in working directory") else stop2("No .wav files in 'path' provided")
if (!is.null(samp.rate)) {
if (!is.vector(samp.rate)) stop2("'samp.rate' must be a numeric vector of length 1") else if (!length(samp.rate) == 1) stop2("'samp.rate' must be a numeric vector of length 1")
}
if (!is.null(bit.depth)) {
if (!is.vector(bit.depth)) stop2("'bit.depth' must be a numeric vector of length 1") else if (!length(bit.depth) == 1) stop2("'bit.depth' must be a numeric vector of length 1")
}
if (!is.null(samp.rate) & is.null(bit.depth)) bit.depth <- 16
dir.create(file.path(path, "converted_sound_files"), showWarnings = FALSE)
# fix_bio_FUN <- function(x) {
#
# # read waves
# wv <- try(warbleR::read_wave(X = x, path = path), silent = TRUE)
#
# # downsample and filter if samp.rate different than mp3
# if(is(wv, "Wave") & !is.null(samp.rate))
# {
# if (wv@samp.rate != samp.rate * 1000) {
#
# # filter first to avoid aliasing
# if (wv@samp.rate > samp.rate * 1000)
# wv <- seewave::fir(wave = wv , f = wv@samp.rate, from = 0, to = samp.rate * 1000 / 2, bandpass = TRUE, output = "Wave")
#
# #downsample
# wv <- warbleR::resample(wave = wv, to = samp.rate * 1000)
# }
#
# # normalize
# wv <- tuneR::normalize(object = wv, unit = as.character(bit.depth))
# }
#
# wv <- try(tuneR::writeWave(extensible = FALSE, object = wv, filename = file.path(path, "converted_sound_files", paste0(substr(x, 0, nchar(x) - 4), ".wav"))), silent = TRUE)
#
# return(NULL)
# }
fix_sox_FUN <- function(x) {
x <- normalizePath(file.path(path, x))
# name and path of original file
cll <- paste0("sox '", x, "' -t wavpcm")
if (!is.null(bit.depth)) {
cll <- paste(cll, paste("-b", bit.depth))
}
cll <- paste0(cll, " '", file.path(normalizePath(path), "converted_sound_files/", basename(x)), "'")
if (!is.null(samp.rate)) {
cll <- paste(cll, "rate", samp.rate * 1000)
}
if (!is.null(mono)) {
cll <- paste(cll, "remix 1")
}
if (!is.null(bit.depth)) {
cll <- paste(cll, "dither -s")
}
if (Sys.info()[1] == "Windows") {
cll <- gsub("'", "\"", cll)
}
out <- system(cll, ignore.stdout = FALSE, intern = TRUE)
}
# fix_FUN <- if (sox) fix_sox_FUN else fix_bio_FUN
out <- pblapply_wrblr_int(pbar = TRUE, X = fls, FUN = fix_sox_FUN)
return(NULL)
}
##############################################################################################################
#' alternative name for \code{\link{fix_wavs}}
#'
#' @keywords internal
#' @details see \code{\link{fix_wavs}} for documentation. \code{\link{fixwavs}} will be deprecated in future versions.
#' @export
fixwavs <- fix_wavs
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.