R/generateTimeShift.R

Defines functions generateTimeShift

Documented in generateTimeShift

#' Generated time-shifted versions of a Wave-like object
#'
#' Given a Wave-like object (or list of Wave-like objects), this function generates
#' time-shifted versions of the object. The time-shifted versions are generated by
#' adding a constant amount of time to the start or end of the object. This is achieved
#' by either inserting silence and truncating the object to the original length, or by
#' rotating the audio within the object.
#' @param wave A Wave-like object or list of Wave-like objects.
#' @param type The type of time-shift to apply. Either "silent" or "rotate".
#' @param where Where to insert silence if `type` is "silent".
#' @param amount Vector of amount of time to shift by (seconds).
#' @param output Return a list.
#' @return A Wave-like object or list of Wave-like objects.
#' @export
generateTimeShift <- function(
    wave,
    type="silent",
    amount=c(1,2),
    where="start",
    output="list"
) {
  if (!type %in% c("silent", "rotate")) {
    stop("Unknown value for type.")
  }
  if(!output %in% c("list")) {
    stop("Unknown value for output.")
  }
  if (is.list(wave)) {
    if (all(sapply(wave, inherits, c("Wave", "WaveMC")))) {
      return(lapply(wave, generateTimeShift, type=type, amount=amount, output=output))
    } else {
      stop("All elements of wave must be Wave-like objects.")
    }
  }
  if (!inherits(wave, c("Wave", "WaveMC"))) {
    stop("All elements of wave must be Wave-like objects.")
  }
  ret <- list()
  if (type == "silent") {
    if (inherits(wave, "Wave")) {
      if (inherits(wave, "Wave")) {
        original.length <- length(wave)
      }
      for (i in 1:length(amount)) {
        insert <- tuneR::silence(
          duration = amount[i] * wave@samp.rate,
          samp.rate = wave@samp.rate,
          bit = wave@bit,
          stereo = wave@stereo,
          pcm = wave@pcm
        )
        if (where %in% c("start", "both")) {
          nwave <- cutws(concat(insert, wave), to=original.length)
          ret <- c(ret, nwave)
        }
        if (where %in% c("end", "both")) {
          nwave <- cutws(
            concat(wave, insert),
            from= length(insert@left)+1
          )
          ret <- c(ret, nwave)
        }
      }
    }
  }
  if (type == "rotate") {
    if (inherits(wave, "Wave")) {
      for (i in 1:length(amount)) {
        offset <- amount[i] * wave@samp.rate
        nwave <- concat(cutws(wave, from=length(wave)-offset+1), cutws(wave, to=length(wave)-offset))
        ret <- c(ret, nwave)
      }
    }
  }
  return(ret)
}
edwbaker/SonicScrewdriveR documentation built on Feb. 14, 2025, 2:45 p.m.