How can I play birthday music using R?
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.
Is it possible to code music in R and play it back? (Mac OS X)
For the moment, this is the best that I've come up with:
library("audio")
library(tuneR) #import the tuneR library
for (i in 1:10) {
yo=abs(round(rnorm(1,400,500)))
f=yo #frequency of A4 note
sr=1000000
bits=116
secs=5 #length of the note set to 2
amp=1
t=seq(0, secs, 1/sr)
y= amp*sin(2*pi*f*t) #make a sinewave with above attributes
s=floor(2^(bits-2)*y) #floor it to make it an integer value
# u=Wave(s, samp.rate=sr, bit=bits) #make a wave structure
u=audioSample(x = s, rate = sr,bits = bits)
audio::play(u)
}
We could experiment with setWavPlayer('/usr/bin/afplay')
That's my modern random canon.
library(tuneR)
setWavPlayer('/usr/bin/afplay')
muss = NULL
nbnotes = 100
for (i in 1:nbnotes) {
yo = abs(round(rnorm(nbnotes,400,200)))
lengthhtime = abs(rnorm(nbnotes,0.5,0.1))
f=yo[i] #frequency of A4 note
titi = lengthhtime[i]
sr=1000
bits=16
secs=titi
amp=1
t=seq(from = 0, to = secs, by = 1/sr)
y= amp*sin(2*pi*f*t)
s=floor(2^(bits-2)*y)
muss = c(muss,s)
}
u=Wave(left = muss,right = rev(muss), samp.rate=sr, bit=bits) #make a wave structure
tuneR::play(u)
Here is a function I created to generate a random melody:
melodymachine <- function(nbnotes, seed = NULL) {
if(!is.null(seed)){set.seed(seed)}
muss = NULL
for (i in 1:nbnotes) {
yo = abs(round(rnorm(nbnotes,400,200)))
lengthhtime = abs(rnorm(nbnotes,0.0,0.2))
f=yo[i] #frequency of A4 note
titi = lengthhtime[i]
sr=1000
bits=16
secs=titi #length of the note set to 2
amp=0.99
t=seq(from = 0, to = secs, by = 1/sr)
y= amp*sin(2*pi*f*t) #make a sinewave with above attributes
s=floor(2^(bits-2)*y) #floor it to make it an integer value
muss = c(muss,s)
}
return(muss)
}
Here is an example of it:
mel1 = melodymachine(6,seed = 1)
mel2 = melodymachine(6,seed = 1)
mel3 = melodymachine(6,seed = 1)
mel4 = melodymachine(6,seed = 1)
mel5 = melodymachine(6,seed = 1)
u=Wave(left = c(mel1,mel2,mel3,mel4,mel5),
right = rev(c(mel1,mel2,mel3,mel4,mel5)),
samp.rate=sr, bit=bits) #make a wave structure
tuneR::play(u)
You can take a look at the wave here:
plot(u,
info = TRUE,
xunit = c("time"),
ylim = NULL, main = "My random melody",
sub = "made by me",
xlab = NULL, ylab = NULL,
simplify = FALSE, nr = 2500,
axes = TRUE, yaxt = par("yaxt"),
las = 1,
center = TRUE)
Update:
Below are a couple of function that will help you get started playing chords in R.
library(audio)
library(tuneR)
testit <- function(x)
{
p1 <- proc.time()
Sys.sleep(x)
proc.time() - p1 # The cpu usage should be negligible
}
full.scale = function(root = 440, dist.notes = 2^(1/12), nb.notes=12) {
all.notes = NULL
for (k in 1:nb.notes) {
if(k==1){all.notes = c(all.notes, root)}
my.note = root*(dist.notes)^k
all.notes = c(all.notes, my.note)
}
return(all.notes)
}
fq.gen <- function(f = 440,
octave = 2,
secs=1/2, sr=100000,
bits=116, amp=0.1,
play = FALSE) {
octave.select = 2^c(0:6)
t = seq(0, secs, 1/sr)
y = amp*sin(pi*octave.select[octave]*f*t) #make a sinewave with above attributes
(by = round(2/3*pi*(1/(f*octave.select[octave])),5))
s=floor(2^(bits-2)*y) #floor it to make it an integer value
u = audioSample(x = s, rate = sr,bits = bits)
if (play) {
audio::play(x = u)
}
return(list(u = u, y= y, t =t, by = by, secs=secs))
}
all.notes.from.western.scale = full.scale(root = 16.35,dist.notes = 2^(1/12), nb.notes = 107)
note.name = rep(c("c","cs","d","ds","e","f","fs","g","gs","a","as","b"),9)
octave.note = rep(seq(0,(length(all.notes.from.western.scale)/12-1), by =1), each = 12)
data.notes.wstrn = data.frame(note = note.name,
octv = octave.note,
fq = all.notes.from.western.scale,
note.otv = paste0(note.name,octave.note))
a.scale = full.scale(root = 440,dist.notes = 2^(1/12), nb.notes = 12)
c.scale = full.scale(root = 523.25)
cs.scale = full.scale(root = 554.37)
# Major chord
for (i in 1) {
secs = 2
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "a4","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "cs4","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "e4","fq"],octave = 2, secs = secs,play = T)
}
# Minor chord
for (i in 1) {
secs = 2
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "a4","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "c4","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "e4","fq"],octave = 2, secs = secs,play = T)
}
# augmented chord
for (i in 1) {
secs = 2
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "a4","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "cs4","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "f4","fq"],octave = 2, secs = secs,play = T)
}
# Diminished chord
for (i in 1) {
secs = 2
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "a4","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "c4","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "ds4","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "fs4","fq"],octave = 2, secs = secs,play = T)
}
# Resolution!
for (i in 1) {
secs = 2
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "g4","fq"],octave = 1, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "b4","fq"],octave = 1, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "d5","fq"],octave = 1, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "g5","fq"],octave = 1, secs = secs,play = T)
}
# C13 chord
for (i in 1) {
secs = 4
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "g4","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "b4","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "d5","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "f5","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "a5","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "c6","fq"],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = data.notes.wstrn[data.notes.wstrn$note.otv == "e6","fq"],octave = 2, secs = secs,play = T)
}
for (i in 1:length(a.scale)) {
secs = 1/5
datadf = fq.gen(f = a.scale[i], secs = secs,play = T)
datadf = fq.gen(f = a.scale[i],octave = 3, secs = secs,play = T)
datadf = fq.gen(f = a.scale[i],octave = 4, secs = secs,play = T)
datadf = fq.gen(f = a.scale[i],octave = 5, secs = secs,play = T)
datadf = fq.gen(f = a.scale[i],octave = 6, secs = secs,play = T)
datadf = fq.gen(f = a.scale[i],octave = 7, secs = secs,play = T)
datadf.col = do.call(what = cbind, datadf)
total = which(round(datadf.col[,"t"],5) == fq.gen()$by)
datadf.col[which(round(datadf.col[,"t"],5) == fq.gen()$by),]
testit(datadf$secs-.08)
}
for (i in 1:length(a.scale)) {
secs = 1/5
datadf = fq.gen(f = a.scale[i], secs = secs,play = T)
datadf = fq.gen(f = cs.scale[i],octave = 2, secs = secs,play = T)
datadf = fq.gen(f = a.scale[i],octave = 3, secs = secs,play = T)
datadf = fq.gen(f = a.scale[i],octave = 3, secs = secs,play = T)
datadf = fq.gen(f = cs.scale[i],octave = 3, secs = secs,play = T)
datadf = fq.gen(f = a.scale[i],octave = 5, secs = secs,play = T)
datadf.col = do.call(what = cbind, datadf)
total = which(round(datadf.col[,"t"],5) == fq.gen()$by)
datadf.col[which(round(datadf.col[,"t"],5) == fq.gen()$by),]
testit(datadf$secs-.08)
}
Making a random tone-sequence in R
Here is a package to analyze music, that might help.
Here is an example you can try out.
Replicating something similar like the answer to this questions is maybe rather what you want. There the OP requests code to play the happy-birthday song in R. They code in the answer has, notes, pitch and duration, that you can easily define by yourself and sample randomly from to generate a song.
I think that it might be simpler to do most of these things in python.
Hope this helps!
How can I play birthday music using R?
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.
Can I make one function for all activity, to play, pause music
I can see two options:
- Make
MediaPlayer
static object. - Consider implementing Single Activity approach. You will have two fragments and shared
ViewModel
in which you can accessMediaPlayer
.
The correct way to play short sounds Android?
You can use SoundPool
. It fits what you want to do perfectly.
You'll just need a way to store the sound effect IDs corresponding to each image (or button).
Perhaps extend Button to store associated sound effect ID. And use a common SoundPool to play the sound effect associated to the id when the button is touched.
You can read more about SoundPool here.
Related Topics
Sources on S4 Objects, Methods and Programming in R
How to Extract Fitted Splines from a Gam ('Mgcv::Gam')
How to Add an Inset (Subplot) to "Topright" of an R Plot
Multiply Many Columns by a Specific Other Column in R with Data.Table
Include Data Examples in Developing R Packages
Does Converting Character Columns to Factors Save Memory
Meaning of Objects Being Masked by the Global Environment
How to Plot Ellipse Given a General Equation in R
R Shiny Conditionalpanel Output Value
How to Play Birthday Music Using R
Diagnosing R Package Build Warning: "Latex Errors When Creating PDF Version"
How to Compute Roc and Auc Under Roc After Training Using Caret in R
How to Reference the Local Environment Within a Function, in R
Package Dependencies When Installing from Source in R
In R, Extract Part of Object from List
Trying to Use Dplyr to Group_By and Apply Scale()
Explanation of R: Options(Expressions=) to Non-Computer Scientists