Using R Programming to make Music

Vaibhav Sawant
3 min readNov 18, 2020

Technology has changed the way people make music. It started with a phonograph in 1877, invented by Thomas Edison that used complex moving parts, and now companies like Hexachords use AI in their software called Orb Producer Suite where all we have to do is click one button. Literally one button and you get everything ready for you, from melodies to chords to drum loops and so on.

Coding has played a major role in the development of music production. Especially languages like R and Python have had a huge impact on the industry. Musicians nowadays learn how to code to create algorithms and software to help optimize their workflow and make better music.

The 2 main things needed to make a song in R:

  • the Notes used in the song
  • the Duration of each note
  • an Audio Library to process the notes and their durations

Rforge provides a large database of different libraries for different purposes, including an audio library.

Composing music

  • Notes go from A to G and are of character strings.
  • Semitones can be creating by adding a “#”(Sharp) or a “b”(flat) after the note, e.g. A# or Bb
  • The default octave for a piano is the 4th. To go lower or higher, add the octave number to the string, e.g. “A3, Bb3, “D5”.
  • The Duration of each note is given as a string of numerical values that will represent the number of beats for a note, e.g. 1, 2.5, 2.25

Example 1: Any random tunes using tuneR library

library(tuneR)        #import the tuneR library
setWavPlayer("audacious")
f=440 #frequency of A4 note
sr=8000
bits=16
secs=2 #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
play(u)

Example 2: Happy Birthday

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)

The code plays the tune by using sine waves. The tempo or speed of the melody is set to 120 beats per minute and sample rate is set as 44100Hz.

The usage of make_sineis to remove any pops or click sounds by fading in the sine waves when we shift from different octaves.

--

--