Вы можете попробовать пакет audio
.
Императорский марш Звездных войн с R
Давайте запишем некоторые заметки и длительности:
p <- "A3
A3 A3 A3 F3 C3# A3 F3 C3# A3
F4 F4 F4 F4# C3# G3 F3 C3# A3"
d <- c(2,
1, 1, 1, 0.75, 0.25, 1, 0.75, 0.25, 2,
1, 1, 1, 0.75, 0.25, 1, 0.75, 0.25, 2)
Сделайте аудиоwave dataframe:
w <- make_wave(pitch = p, duration = d, tempo = 120, sample_rate= 44100)
Это использует слегка адаптированную версию Призрачной функции Ника Кеннеди .
... и воспроизводит ее прямо из консоли:
audio::play(w)
Объяснение
В основном вам нужна таблица с частотами и продолжительностью.Это также может быть достигнуто с помощью таблицы поиска.Если у вас есть частоты и длительности каждой ноты, вы можете легко превратить ее в звуковую волну с помощью make_sine()
и воспроизвести ее.
Внимание: tuneR также имеет функцию под названием play()
, которая работает по-разному и может привести к ошибкам из-за маскировки.
Функция
make_wave <- function(pitch, duration, tempo, sample_rate){
# Credit to Nick Kennedy
require(dplyr)
notes <- c(A = 0, B = 2, C = 3, D = 5, E = 7, F = 8, G = 10)
# remove leading, trailing, and consecutive spaces (and some line breaks)
pitch <- gsub("\n", " ", pitch)
pitch <- gsub("(?<=[\\s])\\s*|^\\s+|\\s+$", "", pitch, perl=TRUE)
# split notes, add duration
x <- data_frame(pitch = strsplit(pitch, " ")[[1]],
duration = duration)
# calculate frequency
x <-
x %>%
mutate(octave = substring(pitch, nchar(pitch)) %>%
{suppressWarnings(as.numeric(.))} %>%
ifelse(is.na(.), 4, .),
note = notes[substr(pitch, 1, 1)],
note = note + grepl("#", pitch) -
grepl("b", pitch) + octave * 12 +
12 * (note < 3),
freq = 2 ^ ((note - 60) / 12) * 440)
# create fade to remove clipping
fade <- seq(0, 1, 50 / sample_rate)
# turn frequency and duration into sound
make_sine <- function(freq, duration) {
# create audio wave
wave <- sin(seq(0, duration / tempo * 60, 1 / sample_rate) *
freq * 2 * pi)
# apply fade to audio wave
wave * c(fade, rep(1, length(wave) - 2 * length(fade)), rev(fade))
}
# create waveform
wave_df <-
mapply(make_sine, x$freq, x$duration) %>%
do.call("c", .)
return(wave_df)
}