How can I play birthday music using R? [closed]
Asked Answered
R

1

86

I would like to play music using R. While R may not be the best tool for this purpose, it is the tool that I am familiar with and it would be nice to demonstrate to others its flexibility on such a joyous occasion.

How could I accomplish this?

Rapids answered 3/8, 2015 at 8:22 Comment(15)
Why would you want to play BD music via R? R is a statistical programming language, Im sure there are better platforms for such tasks.Batwing
@DavidArenburg that's certainly true, but take a look at page 33 of this file tinyurl.com/odlurth (it's Paul Murrell's "R Graphics"). The fact that there are better programs to do something shouldn't prevent us from trying to help Feng Tian (probably something new in the process)Cooee
@Cooee The fact that R might be able to play audio shouldn't prevent us to advice there are better tools for this.Publicness
@Cooee a programmer can use a various set of tools in order to achieve different tasks in the most efficient manner. Each language has its pros and cons, and R is not an exception. I'm sure you wouldn't advise anyone to create a video game using R.Batwing
@Pascal I think that your observation could refer (at most) at a halved answer. It's certainly true, but it doesn't help Feng Tian (and I'm pretty sure that he doesn't have to explain us why he wants to perform such a task to obtain a sensible answer)Cooee
@DavidArenburg I would not advise anyone to do that for a living. This doesn't mean that trying to create a videogame using R couldn't be worth a try, at least to verify its limits and to be creative (that is, thinking outside of the box). And as I think that Feng Tian isn't a professional musician I'd still try to help him, if I could.Cooee
@Feng Tian, try to take a look at this file google.com/…Cooee
IMHO, there may be some merit to that question. Sound analysis (2) is a legitimate analytical tasks so it's possible to envisage a situation where the one may be willing to organoleptically verify sound samples while undertaking analytical work. Having said that, the birthday music in title is rather odd.Cyrenaic
Yes, sound analysis is a legitimate field where R might be useful.Publicness
@Cooee Thanks very much! I do this just out of curiosity.Rapids
@FengTian you are welcome. That's one of the most powerful drivers of human progress, and one of the most enjoyable as well.Cooee
Don't encourage these kind of questions because there may be a chance of asking I would like to play video using R.Ealdorman
@AvinashRaj interestingly I'd thought of that as a follow-on :) in all seriousness, the options would probably either be trivial (launch an external program), pointless (reimplementing a video player in external code) or unusable (using R code to decode a video stream and rasterImage to render each frame)Smoulder
and as a plus: you now can play your R-HappyBirthday song in public without getting sued: (cnbc.com/2015/09/23/…)Debrief
I'm here because I wanted to know how to use R for signals analysis. I think this question should be reopened because it and its answer provide valuable insight into using R for for signals. If MATLAB can, so can R!Outstrip
S
248

If you really wanted to do this:

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)

Note you'll need to install.packages("audio") first. If you already have a specific file, you'll need to convert it to WAV format first.

If you wanted something a bit more programmery than playing a WAV file, here's a version that generates the tune from a series of sine waves:

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)

There's a few points to note. The default octave for the notes is octave 4, where A4 is at 440 Hz (the note used to tune the orchestra). Octaves change over at C, so C3 is one semitone higher than B2. The reason for the fade in make_sine is that without it there are audible pops when starting and stopping notes.

Smoulder answered 3/8, 2015 at 8:46 Comment(10)
@DavidArenburg Thanks. Just to make things slightly more ridiculous, I've now added some code that generates the tune from first principles using sine waves :)Smoulder
Awesome answer. I learned something new: I didn’t know about the fading, and a recent experiment of mine had this exact problem. Nitpick: no reason to quote c in do.call, and the last assignment in make_sine is unnecessary.Unbacked
@KonradRudolph thanks. I tend to always quote the function name in do.call. It's all too easy to fall into the trap of having done something like a <- 1; b <- 2; c <- 3 along the way, and in that situation do.call(c, ...) will fail, while c(1, 2, 3) won't. Completely agree with the latter point though, and have removed the unnecessary assignment!Smoulder
@NickKennedy In that situation do.call('c', …) will also fail. At any rate, I argue that, except when used with match.fun, quoting function names is fundamentally nonsense: a string is not a function. The fact that R allows us to treat them like this is a terrible flaw and should not be relied on.Unbacked
@KonradRudolph Actually do.call("c", ...) will work. Try c <- 4; do.call("c", list(1, 2)). R is reasonably consistent in that in most cases an argument that accepts a function will accept either the function itself or the name of the function. In some cases (e.g. lapply), this is via match.fun, whereas in others, e.g. do.call, getMethod, the implementation is in the C code (for the latter via a call to C_R_getGeneric). I can see why stylistically you might prefer to pass the function rather than its name, but the latter behaviour is well-documented.Smoulder
@NickKennedy I tried that and was actually surprised that it didn’t work (turns out, I had made a typo). The reason for this working is, of course, that do.call uses match.fun (or similar) internally. I agree that the behaviour is consistent. Still, I maintain that it’s bad.Unbacked
@KonradRudolph Fair enough. I guess the related issue is that R will always look for a function if a symbol is followed by parentheses, even if another symbol exists further up the seach path. This allows c <- 4; c(1, 2) to work as normal, while c <- paste0; c(1, 2) will not use the base c. I've seen confusion created by this where someone has been quite happily calling c(1, 2) in their code, but then do.call(c, ...) fails to work. At the end of the day, I don't feel strongly about whether functions are provided by name or directly.Smoulder
We use to program birthday tune in FoxPro (for DOS) and Clipper as well for our fellow-programmer friend during someone's birthday and it was fun. But I never know that you can do it in R, wow! Just, wow! I like the programmy tune though and tried it on my R-Studio. ;-)Exquisite
This is awesome. Could someone comment the code to explain how it works please ? And I guess changing the value of freq changes the key, but is there any way to be able to play with two ranges at once ?Ardeth
hai dude! can we play audio songs in R instead of birthday song!Kellogg

© 2022 - 2024 — McMap. All rights reserved.