Skip to content
Permalink
Browse files

0.6.0: notes can be expressed via scientific pitch notation

  • Loading branch information
daveyarwood committed Jun 26, 2016
1 parent 44df6df commit 14f8be010ca39b16a124ea7fad63cf7e8383d7ef
Showing with 52 additions and 6 deletions.
  1. +15 −0 CHANGELOG.md
  2. +17 −2 README.md
  3. +4 −3 build.boot
  4. +2 −1 src/mantra/note.cljs
  5. +14 −0 src/mantra/note/pitch.cljs
@@ -1,5 +1,20 @@
# CHANGELOG

## 0.6.0 (6/26/16)

* Added the ability to express the pitch of a note as a string or keyword containing the note (letter) name and octave.

Example usage:

```clojure
(require '[mantra.core :as m])
(def o (m/osc :triangle))
(m/play-notes o [{:pitch "C#5" :duration :quarter}
{:pitch :Ab3 :duration :dotted-half}])
```

## 0.5.4 (2/20/16)

* Fixed a bug in [chronoid](http://github.com/daveyarwood/chronoid) that was affecting mantra to some extent. mantra now uses chronoid 0.1.1, which contains the fix.
@@ -38,15 +38,30 @@ One important difference between Mantra's oscillator models and the Web Audio AP

Mantra also provides an abstraction for musical notes. A note is represented as a map containing the following keys:

* `:pitch` -- the frequency of the note, in Hz
* `:pitch` -- the frequency of the note, either an exact number in Hz or a reference to a frequency in the form of a particular note in a particular octave

* `:duration` (optional) -- the duration of the note. When omitted, the note will sustain until it is stopped explicitly.

Mantra uses [chronoid](http://github.com/daveyarwood/chronoid) for accurate timing of notes, leveraging the accuracy of the Web Audio API's clock, which runs on a separate thread.

#### Pitch

For now, pitch must be a frequency in Hz.
The pitch of a note can be expressed in a couple of different ways:

1. As a number representing the frequency in Hz:

```clojure
{:pitch 440 :duration 1000}
```

1. As a string or keyword containing the note name (e.g. C, C#, Ab) and the octave (according to scientific pitch notation):

```clojure
{:pitch "C4" :duration 1000}
{:pitch "F#3" :duration 1000}
{:pitch :C2 :duration 1000}
{:pitch :Eb5 :duration 1000}
```

#### Duration

@@ -9,13 +9,14 @@
[com.cemerick/piggieback "0.2.1" :scope "test"]
[weasel "0.7.0" :scope "test"]
[org.clojure/tools.nrepl "0.2.12" :scope "test"]
[chronoid "0.1.1"]])
[chronoid "0.1.1"]
[music-theory "0.1.0"]])

(require '[adzerk.bootlaces :refer :all]
'[adzerk.boot-cljs :refer (cljs)]
'[adzerk.boot-cljs-repl :refer (cljs-repl start-repl)])

(def +version+ "0.5.4")
(def +version+ "0.6.0")
(bootlaces! +version+)

(task-options!
@@ -29,7 +30,7 @@

(deftask dev []
(comp (watch)
(speak)
#_(speak)
(cljs-repl)
(cljs)
(target)))
@@ -1,12 +1,13 @@
(ns mantra.note
(:require [mantra.osc :as o]
[mantra.note.duration :as nd]
[mantra.note.pitch :as np]
[chronoid.core :as c]))

(defn- play-note*
[osc-model {:keys [pitch duration volume] :as note-model}]
(let [{:keys [osc-node gain-node clock] :as osc-impl} (o/osc* osc-model)]
(o/freq osc-node (or pitch (:freq osc-model)))
(o/freq osc-node (np/parse-pitch (or pitch (:freq osc-model))))
(o/gain-ramp gain-node (or volume (:gain osc-model) 1))

(o/start-osc osc-impl)
@@ -0,0 +1,14 @@
(ns mantra.note.pitch
(:require [music-theory.pitch :refer (note->hz)]))

(defn parse-pitch
"If given a number (e.g. 440), returns the number, which will be interpreted
as a frequency in Hz.
If given something else (e.g. a string or keyword like \"C#5\" or :C#5),
returns the result of calling `music-theory.pitch/note->hz` on it to get the
frequency in Hz."
[x]
(if (number? x)
x
(note->hz x)))

0 comments on commit 14f8be0

Please sign in to comment.
You can’t perform that action at this time.