如何使用R播放生日音乐?

Fen*_*ian 81 r

我想用R来演奏音乐.虽然R可能不是最适合这个目的的工具,但它是我熟悉的工具,在这样一个欢乐的场合向其他人展示它的灵活性会很好.

我怎么能做到这一点?

Nic*_*edy 233

如果你真的想这样做:

library("audio")

bday_file <- tempfile()
download.file("http://www.happybirthdaymusic.info/01_happy_birthday_song.wav", bday_file, mode = "wb")
bday <- load.wave(bday_file)
play(bday)
Run Code Online (Sandbox Code Playgroud)

请注意,您需要install.packages("audio")先做.如果您已有特定文件,则需要先将其转换为WAV格式.

如果你想要比播放WAV文件更多的程序,那么这是一个从一系列正弦波产生音调的版本:

library("dplyr")
library("audio")
notes <- c(A = 0, B = 2, C = 3, D = 5, E = 7, F = 8, G = 10)
pitch <- "D D E D G F# D D E D A G D D D5 B G F# E C5 C5 B G A G"
duration <- c(rep(c(0.75, 0.25, 1, 1, 1, 2), 2),
              0.75, 0.25, 1, 1, 1, 1, 1, 0.75, 0.25, 1, 1, 1, 2)
bday <- data_frame(pitch = strsplit(pitch, " ")[[1]],
                   duration = duration)

bday <-
  bday %>%
  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)

tempo <- 120
sample_rate <- 44100

make_sine <- function(freq, duration) {
  wave <- sin(seq(0, duration / tempo * 60, 1 / sample_rate) *
                freq * 2 * pi)
  fade <- seq(0, 1, 50 / sample_rate)
  wave * c(fade, rep(1, length(wave) - 2 * length(fade)), rev(fade))
}

bday_wave <-
  mapply(make_sine, bday$freq, bday$duration) %>%
  do.call("c", .)

play(bday_wave)
Run Code Online (Sandbox Code Playgroud)

有几点需要注意.音符的默认八度音程为八度音阶,其中A4为440 Hz(用于调谐管弦乐队的音符).八度音阶在C处转换,因此C3比B2高一个半音.淡入的原因make_sine在于,没有它,在启动和停止音符时会有可听见的弹出声.

  • @DavidArenburg谢谢.只是为了让事情略显荒谬,我现在添加了一些代码,使用正弦波从第一原理生成调音:) (6认同)
  • @KonradRudolph足够公平.我猜相关的问题是,如果一个`符号`后跟括号,R将始终寻找一个**函数**,即使在搜索路径上还存在另一个`符号`.这允许`c < - 4; c(1,2)`正常工作,而`c < - paste0; c(1,2)`不会使用基``c`.我已经看到由此创建的混乱,有人在他们的代码中非常高兴地调用`c(1,2)`,但是`do.call(c,...)`无法工作.在一天结束时,我不清楚函数是通过名称还是直接提供的. (2认同)