Nothing
# play.R
# ::music::
# 2019 E.D. Gennatas lambdamd.org
#' Minimal "Polyphonic" Wave Player
#'
#' Play one or more waveforms at the same time using \code{audio::play}
#'
#' @param wave Matrix or vector of waveforms. If a matrix, each column should be a waveform to be played
#' simultaneously
#' @param sample.rate Integer: Sample rate. Default = 44100
#' @param plot Logical: If TRUE: plot wave using \link{mplot}.
#' @examples
#' \dontrun{
#' playWave(freq2wave(440))
#' }
#' @export
#' @author E.D. Gennatas
playWave <- function(wave,
sample.rate = 44100,
plot = FALSE) {
if (is.null(dim(wave))) wave <- matrix(wave, ncol = 1)
n.notes <- NCOL(wave)
for (i in seq(n.notes)) audio::play(wave[, i], rate = sample.rate)
if (plot) mplot(wave)
} # music::playWave
#' Play frequency
#'
#' @param frequency Numeric, Vector: Frequency / frequencies to play
#' @param oscillator String: "sine", "square", "saw". Default = "sine"
#' @param duration Float: Note duration in beats. Default = 1
#' @param BPM Integer: Beats per minute. Default = 120
#' @param sample.rate Integer: Sample rate. Default = 44100
#' @param attack.time Integer: Attack time. Default = 50 (Helps prevent popping)
#' @param inner.release.time Integer: Release time, that ends on note OFF (instead of beginning at note OFF).
#' Default = 50 (Also helps prevent popping)
#' @param plot Logical: If TRUE, plot waveform
#'
#' @examples
#' \dontrun{
#' playFreq(440)
#' }
#' @export
#' @author E.D. Gennatas
playFreq <- function(frequency,
oscillator = "sine",
duration = rep(1, length(frequency)),
BPM = 120,
sample.rate = 44100,
attack.time = 50,
inner.release.time = 50,
plot = FALSE) {
wave <- unlist(c(mapply(freq2wave,
frequency,
oscillator,
duration,
BPM,
sample.rate,
attack.time,
inner.release.time)))
if (plot) mplot(wave)
playWave(wave)
} # music::playFreq
#' Play Note
#'
#' @inheritParams playFreq
#' @inheritParams note2freq
#' @param note String, Vector: Note(s) to be played, e.g. c("Ab4", "B4")
#' @param plot Logical: If TRUE, plot notes using \link{cplot.piano}. This support only two octaves;
#' do not try plotting if your notes span more than two octaves.
#' @param ... Additional arguments to pass to \link{note2freq}
#' @examples
#' \dontrun{
#' playNote("B4")
#' }
#' @export
#' @author E.D. Gennatas
playNote <- function(note,
oscillator = "sine",
duration = rep(1, length(note)),
BPM = 120,
sample.rate = 44100,
attack.time = 50,
inner.release.time = 50,
A4 = 440,
plot = FALSE, ...) {
freqs <- note2freq(note,
A4 = A4, ...)
if (plot) cplot.piano(note)
playFreq(freqs,
oscillator = oscillator,
duration = duration,
BPM = BPM,
sample.rate = sample.rate,
attack.time = attack.time,
inner.release.time = inner.release.time)
} # music::playNote
#' Play Chord
#'
#' @inheritParams playNote
#' @param chord String, vector: Notes making up chord. e.g. c("A4", "C5", "E5").
#' e.g. output of \link{buildChord}
#' @param type String: "harmonic", "ascending", "descending". Default = "harmonic"
#' @param plot Logical: If TRUE, plot chord using \link{cplot.piano}
#' @export
#' @return The constructed waveform (invisibly)
#' @examples
#' \dontrun{
#' playChord(buildChord("E4", "minor"))
#' }
#' @author E.D. Gennatas
playChord <- function(chord,
type = c("harmonic", "ascending", "descending"),
oscillator = "sine",
duration = 1,
sample.rate = 44100,
attack.time = 50,
inner.release.time = 50,
A4 = 440,
plot = FALSE, ...) {
type <- match.arg(type)
wave <- lapply(chord, function(i) freq2wave(note2freq(i, A4 = A4, ...),
oscillator = oscillator,
duration = duration,
sample.rate = sample.rate,
attack.time = attack.time,
inner.release.time = inner.release.time))
wave <- switch(type,
harmonic = do.call(cbind, wave),
ascending = do.call(c, wave),
descending = do.call(c, rev(wave)))
if (plot) cplot.piano(chord)
playWave(wave)
invisible(wave)
} # music::playChord
#' Play Progression
#'
#' @inheritParams playNote
#' @param progression List of string vectors: Each element of the list is a chord.
#' e.g. output of \link{buildProgression}
#' @param plot Logical. If TRUE, plot each chord in the progression using \link{cplot.piano}
#' @export
#' @examples
#' \dontrun{
#' playProgression(buildProgression("G4", "minor"))
#' }
#' @author E.D. Gennatas
playProgression <- function(progression,
oscillator = c("sine", "square", "saw", "triangle"),
duration = 1,
BPM = 120,
sample.rate = 44100,
attack.time = 50,
inner.release.time = 50,
A4 = 440,
plot = FALSE, ...) {
oscillator <- match.arg(oscillator)
wave <- lapply(progression, function(i)
do.call(cbind,
lapply(i, function(j) freq2wave(note2freq(j, A4 = A4, ...),
oscillator = oscillator,
duration = duration,
BPM = BPM,
sample.rate = sample.rate,
attack.time = attack.time,
inner.release.time = inner.release.time))))
wave <- do.call(rbind, wave)
playWave(wave)
if (plot) {
for (i in seq(progression)) {
cplot.piano(progression[[i]])
cat("\n")
}
}
} # playProgression
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.