Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
;; # Explorations for notating note sequences through numbers in different bases.
;; This sketch explores an API to represent a note via a number of a fixed
;; number of digits in the base of the number of notes in the mode.
;; Examples: 7r030 for C3, 7r072 for E7 (if major mode)
;; This approach has the benefit of equivalence between addition and transposition:
;; `(+ 7r013 7r010) => 7r023` and `(+ 7r011 7r006) => 7r020`
;; ## Special numbers
;; For step sequencing we want ways of notating holds and note
;; offs. We could use the following
;; - 7r000: note off
;; - 7r001: hold
;; Note that the simplest form would be two digits (7r11), but that would limit
;; us to 7 octaves, so the initial demos will use three digits per note.
;; ## Sequences and chords
;; The fixed-length approach allows easy creation of vectors from single
;; numbers. These vectors could either be used for sequencing single streams of
;; notes or for representing chords. For example `7r030032034` would be a simple
;; triad, or `7r010012013014015016017` for a simple run up the mode's scale.
;; ## API
;; The API functions use the convention of suffixing "-intr" for functiona names
;; that apply to int inputs and take a radix argument.
;; We might use the following API functions:
;; ### modal-intr->hz
;; Convert an integer in a given radix to the hz value for the a given mode. Takes arguments [number, radix [, mode, reference-pitch]]
;; Mode implementation TBD, but could be an array of ratios to the tonic.
(def second (* 3/2 3/2 1/2))
(def mode [1 second 5/4 4/3 3/2 5/3 12/7])
(modal-intr->hz 7r035 7 mode [7r030 440]) ; => 2200/3 or 733.33
;; This would also be provided via common radix convenience functions such as
(modal-7r->hz 7r035 mode) ; demonstrates both the convience base 7 function as well as using a default reference.
;; TODO: determine how to best set the default mode. It'd be nice to have a
;; method to set default mode globally and then default to that mode when no
;; mode is provided in the modal-intr->hz call, but that would make it not a
;; pure function.
(modal-intr-set-mode mode)
(modal-7r->hz 7r035)
;; ### splitv-intr
;; This is the simplest form, used to transpose a single number if a given radix
;; to a vector. It takes the arguments [number digits radix], where digits is
;; the "word size" in the base specified.
(splitv-intr 7r010012015 3 7) ; => [7r010 7r012 7r015]
;; For convenience, a few common curried functions could be provided, only
;; taking the number of digits to split at:
(splitv-7r 7r010012015 3) ; for western modes
(splitv-2r 2r01100111 4) ; binary, for gate or beat sequences
(splitv-12r 12r3A3B3033 2) ; base 12, for chromatic
(splitv-0x 0xAFC1 1) ; hex, for hex beats, etc.
;; ### map-splitv-intr
;; For sequences of chords, for instance, we may want a special form of mapping
;; the split, with some conveneiences for holding or sending note-offs for each
;; entire chord.
;; At it's root this would just be an implementation of maping splitv-intr over
;; a sequence of numbers.
(map-splitv-intr [7r031034 7r030035] 3 7) ; => [[7r031 7r034] [7r030 035]]
;; The special cases is that a single "word" within a sequence of digits will be
;; expanded to a hold or note off code for each note in the prior vec. For
;; instance.
(map-splitv-intr [7r031034 7r001 7r030035 7r000] 3 7) ; => [[7r031 7r034] [7r001 7r001] [7r030 7r035] [7r00 7r00]]
;; The same convenience functions as with splitv-intr could be available.
(map-splitv-7r [7r011012 7r013014] 3)
;; ### mtranspose-splitv-intr
;; For ease of sequencing, we could also create a function that produces streams
;; of single note sequences from vectors of ints of a given radix. This is
;; effectively a matrix transposition of the map-splitv-intr output.
(mtranspose-splitv-intr [7r031034 7r001 7r030035 7r000] 3 7) ; => [[7r031 7r001 7r030 7r000] [7r031 7r001 7r030 7r000]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment