Introduction

The music package allows you to build, play, and visualize musical scales, chords and chord progressions. You can listen to them using system audio directly within R, plot notes on an ASCII piano plot in the R console, or plot waveforms using R base graphics. There are three build functions available: buildScale, buildChord, and buildProgression. There are three corresponding play functions: playScale, playChord, and playProgression. The other core functions are note2freq, which gives you the frequency of a given note or set of notes, and freq2wave, which will create a waveform for a given frequency. The fourth play function, playWave, will playback one or more waveforms.

Installation

Install from CRAN:

install.packages("music")

or install the latest version from GitHub:

remotes::install_github("egenn/music")

Load library

library(music)
  .:music v0.1.1: Welcome, egenn
  [x86_64-apple-darwin15.6.0 (64-bit)]

Scales

If you run buildScale without arguments, it gives you a list of available scales:

buildScale()
Available scales:
major, minor, dorian, phrygian, lydian, lydianAugmented, acoustic, mixolydian, locrian, majorLocrian, harmonicMajor, harmonicMinor, halfDiminished, minorPentatonic, majorPentatonic, blues, altered, hirajoshi, insen, algerian, hungarian, in 

Define a root note and scale name to build a scale:

buildScale("C4", "minor")
[1] "C4"  "D4"  "Eb4" "F4"  "G4"  "Ab4" "Bb4" "C5" 

On your own system, you can pass argument plot = TRUE to get an ASCII console plot of the scale similar to this:

Let’s try a different scale:

buildScale("B4", "minor", descending = TRUE)
[1] "B5"  "A5"  "G5"  "F#5" "E5"  "D5"  "C#5" "B4" 

On your system, you can specify play = TRUE, which should produce something like this:

Chords

buildChord()
Available chords:
major, minor, sus2, sus4, 7th, major7th, minor7th, 6th, minor6th, diminished, diminished7th, halfDiminished7th, augmented, 7th#5, 9th, 7th#9, major9th, added9th, minor9th, minorAdd9th, 5th, flat5th 
buildChord("A4", "sus2")
[1] "A4" "B4" "E5"

Progressions

buildProgression("G4", "minor")
$G4minor
[1] "G4"  "Bb4" "D5" 

$A4diminished
[1] "A4"  "C5"  "Eb5"

$Bb4major
[1] "Bb4" "D5"  "F5" 

$C5minor
[1] "C5"  "Eb5" "G5" 

$D5minor
[1] "D5" "F5" "A5"

$Eb5major
[1] "Eb5" "G5"  "Bb5"

$F5major
[1] "F5" "A5" "C6"

$G5minor
[1] "G5"  "Bb5" "D6" 

Frequencies

Let’s get the frequencies of the notes in a B4 minor chord:

note2freq(buildChord("B4", "minor"))
      B4       D5      Gb5 
493.8833 587.3295 739.9888 

Note that note2freq defaults to standard tuning where A4 is 440Hz. This can be changed using the A4 argument of note2freq.

Waveforms

Let’s string a few of the previous functions together to build a waveform of three notes, and plot them (will use mplot):

wave <- freq2wave(note2freq(buildChord("B4", "minor")),
                  duration = .05,
                  attack.time = 4,
                  inner.release.time = 5,
                  plot = TRUE)

If you’re a fan of the pipe operator (%>%), it fits naturally here. Combined with the reverse assignment operator, you can do the following:

library(magrittr)
buildChord("B4", "minor") %>% note2freq() %>% freq2wave() -> B4minor_wave

The plot argument in freq2wave plotted the waveforms using mplot. The ends are “tapered” to avoid a popping sound when played through system audio. This is controlled using the attack.time and inner.release.time. Attack time is defined as the duration from Note ON till maximum velocity is reached. We define inner release time such that time at Note OFF minus inner.release.time marks the beginning of the decrease of velocity towards zero. (Regular Release Time is defined as the time from Note OFF till velocity reaches zero. We use “inner release” to keep notes to fixed length defined by duration).

mplot is used to plot the waveforms of single or multiple notes/frequencies. Let’s use it to visualize the effects of experimenting with freq2wave’s parameters. We shall create a short wave, to inspect its shape better.

mplot(freq2wave(note2freq("F4"), duration = .05, attack.time = 5, inner.release.time = 5))

mplot(freq2wave(note2freq("F4"), duration = .05, attack.time = 5, inner.release.time = 5,
                oscillator = "square"))

mplot(freq2wave(note2freq("F4"), duration = .05, attack.time = 5, inner.release.time = 5,
                oscillator = "triangle"))

mplot(freq2wave(note2freq("F4"), duration = .05, attack.time = 5, inner.release.time = 5,
                oscillator = "saw"))