Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion deps.edn
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
{:paths ["src" "test" "dev"]
:deps {org.clojure/clojure {:mvn/version "1.11.1"}
org.clojure/clojurescript {:mvn/version "1.11.60"}
org.clojure/core.async {:mvn/version "1.3.618"}
com.google.javascript/closure-compiler-unshaded {:mvn/version "v20221102"}
org.clojure/math.combinatorics {:mvn/version "0.3.0"}
com.taoensso/timbre {:mvn/version "4.10.0"}
quil/quil {:mvn/version "4.0.0-SNAPSHOT"}
metosin/malli {:mvn/version "0.19.1"}
com.gfredericks/exact {:mvn/version "0.1.11"}
org.clojure/tools.namespace {:mvn/version "1.3.0"}
table/table {:mvn/version "0.5.0"}
Expand All @@ -13,4 +15,8 @@
:extra-deps {io.github.cognitect-labs/test-runner
{:git/tag "v0.5.1" :git/sha "dfb30dd"}}
:main-opts ["-m" "cognitect.test-runner"]
:exec-fn cognitect.test-runner.api/test}}}
:exec-fn cognitect.test-runner.api/test}
:codox {:extra-deps {codox/codox {:mvn/version "0.10.8"}}
:exec-fn codox.main/generate-docs
:codox {:output-path "codox"}
:exec-args {:source-paths ["src"]}}}}
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
{
"name": "@diegovdc/erv",
"version": "0.0.8",
"version": "0.0.14",
"description": "Calculations and other algorithmic treatments of some of [Erv Wilson's](http://anaphoria.com/wilson.html) music scale theories.",
"scripts": {
"release:lib": "shadow-cljs release lib; sed -i '' 's/global/globalThis/g' dist/lib.js",
"watch:lib": "shadow-cljs watch lib",
"prepublishOnly": "npm run release:lib"
},
"main": "dist/lib.js",
"files": [
"dist/"
],
"keywords": [
"microtonality",
"music theory"
Expand Down
45 changes: 30 additions & 15 deletions src/erv/constant_structures/brute_force.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"Find constant structures by brute force"
(:require
[clojure.math.combinatorics :refer [combinations]]
[erv.constant-structures.core :refer [analyze maybe-round]]
[erv.constant-structures.core :refer [analyze maybe-rationalize]]
[erv.utils.conversions :as conv]
[erv.utils.core :refer [interval]]
[erv.utils.ratios :refer [ratios->scale]]
Expand Down Expand Up @@ -92,7 +92,7 @@
(let [[deg1 deg2] (sort deg-pair)
a (:bounded-ratio (nth scale deg1))
b (:bounded-ratio (nth scale deg2))]
(maybe-round (interval a b))))
(maybe-rationalize (interval a b) 10)))

(def ^:private memoized-deg-combinations
(memoize (comp #(map sort %)
Expand All @@ -102,22 +102,35 @@

(def ^:private conj-set (fnil conj #{}))

(defn- invert-interval [interval period]
(* period (/ 1 interval)))

(defn- quick-check-cs?
[deg-combinations scale]
(reduce
(fn [data deg-pair]
(let [[deg1 deg2] deg-pair
steps (- deg2 deg1)
interval (get-interval scale deg-pair)
updated-data (update data interval conj-set steps)
interval-steps (updated-data interval)]
(if (> (count interval-steps) 1)
(reduced {})
updated-data)))
{}
deg-combinations))
(let [period (-> scale first :bounding-period)
size (count scale)]
(reduce
(fn [data deg-pair]
(let [[deg1 deg2] deg-pair
steps (- deg2 deg1)
interval (get-interval scale deg-pair)
inversion-steps (- size steps)
inversion (invert-interval interval period)
updated-data (-> data
(update interval conj-set steps)
(update inversion conj-set inversion-steps))
interval-steps (updated-data interval)]
(when (> inversion period)
(timbre/error "Error in calculation, `inversion` cannot be larger than period"))
(if (> (count interval-steps) 1)
(reduced {})
updated-data)))
{}
deg-combinations)))

(defn quick-cs-subsets
"Calculate all CS subset of the given sizes.
FIXME only really works for JI scales."
[cs-sizes scale]
(eduction
(mapcat #(combinations (range (count scale)) %))
Expand All @@ -128,7 +141,9 @@
(when (seq (quick-check-cs? deg-pairs subscale))
(map #(nth scale %) degs-combination)))))
cs-sizes))

(comment
(require '[clojure.math.combinatorics :as combo])
(combo/count-combinations (range 31) 22))
(defn take-quick-cs-subsets
"Takes n-items after dropping n-items. Takes an `eduction` as returned by `quick-cs-subsets`.
NOTE this code is a general solution, but has specific names for documentation purposes.
Expand Down
27 changes: 19 additions & 8 deletions src/erv/constant_structures/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,33 @@
(round2 6 n))
:cljs (round2 6 n)))

(defn maybe-rationalize
[n decimals]
#?(:clj (if (rational? n)
n
(rationalize (round2 decimals n)))
;; TODO implement
:cljs (round2 6 n)))

(defn get-intervals
[note-pair]
[scale-size note-pair]
(->> note-pair
((fn [[a b]]
{(maybe-round (interval (:bounded-ratio a)
(:bounded-ratio b)))
{:steps #{(- (:index b)
(:index a))}
:intervals [[a b]]}}))))
(let [period (:bounding-period a)
intvl (maybe-round (interval (:bounded-ratio a)
(:bounded-ratio b)))
inversion (* period (/ 1 intvl))]
{intvl {:steps #{(- (:index b) (:index a))}
:intervals [[a b]]}
inversion {:steps #{(- scale-size (- (:index b) (:index a)))}
:intervals [[b a]]}})))))

(defn analyze
[scale]
(let [interval-data (->> (combo/combinations
(map-indexed #(assoc %2 :index %1) scale)
2)
(map get-intervals)
(map (partial get-intervals (count scale)))
(apply merge-with (partial merge-with concat))
(map (fn [[interval data]]
{interval (update data :steps (partial into #{}))}))
Expand Down Expand Up @@ -64,7 +75,7 @@
(:scale (cps/make 2 [11 13 5 7]))))

(:constant-structure? (analyze
(:scale (cps/make 2 [1 3 5 7 9]))))
(:scale (cps/make 2 [1 3 5 7]))))
(:constant-structure? (analyze
(:scale (edo/from-pattern [2 2 1 2 2 2 1]))))
#_(:non-cs-intervals (analyze
Expand Down
1 change: 0 additions & 1 deletion src/erv/constant_structures/graphics.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@
(q/arc 0 0 (+ i* (- radius 100))
(+ i* (- radius 100)) start end)))))) ;; Draw a circle at x y with the correct diameter


(defn make-state
[scale added-notes]
(let [scale+added-notes* (scale+added-notes scale added-notes)
Expand Down
13 changes: 3 additions & 10 deletions src/erv/cps/cycles.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
(:require [clojure.set :as set]
[erv.utils.core :as utils]))



(defn get-next-nodes [graph cycle]
(->> (graph (-> cycle :seq first))
(reduce
Expand Down Expand Up @@ -33,13 +31,11 @@
:status :open})))
())))


(defn update-finder-state [previous-state new-interation-result]
(let [{:keys [open closed]} (group-by :status new-interation-result)]
{:open open
:closed (into (:closed previous-state) closed)}))


(defn init-state [graph]
{:open (mapv (fn [node]
{:seq (list node)
Expand Down Expand Up @@ -73,9 +69,8 @@
(if (-> acc :set (contains? cycle*))
acc
{:set (apply conj (:set acc) (utils/get-all-rotations cycle*))
:cycles (conj (:cycles acc) cycle*)}
))
)
:cycles (conj (:cycles acc) cycle*)})))

{:set #{} :cycles []}
cycles)))))
(comment
Expand Down Expand Up @@ -152,6 +147,4 @@
{:seq (#{7 5} #{1 3} #{7 1}), :set #{#{7 1} #{7 5} #{1 3}}, :status :open}
{:seq (#{7 3} #{1 3} #{7 1}), :set #{#{7 1} #{7 3} #{1 3}}, :status :open}
{:seq (#{1 5} #{1 3} #{7 1}), :set #{#{7 1} #{1 5} #{1 3}}, :status :open}
{:seq (#{1 3} #{7 1}), :set #{#{7 1} #{1 3}}, :status :closed}))

)
{:seq (#{1 3} #{7 1}), :set #{#{7 1} #{1 3}}, :status :closed})))
17 changes: 9 additions & 8 deletions src/erv/cps/cycles/v2.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,13 @@
(str/join " - ")))
(str/join "\n")
(spit "eikosany-harmonic-triad-cycles-of-A.B.C.txt")))
(comment

(->> hexany
:meta
:cps/factors
(map-indexed
(fn
[i fac]
{fac (str (char (+ 65 i)))}))
(into {}))
(->> hexany
:meta
:cps/factors
(map-indexed
(fn
[i fac]
{fac (str (char (+ 65 i)))}))
(into {})))
12 changes: 4 additions & 8 deletions src/erv/cps/similarity.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
[erv.utils.core :as utils]
[clojure.string :as str]))



(defn twelvulate [scale]
(map #(-> % (/ 100) float (Math/round) (* 100)) scale))

Expand Down Expand Up @@ -42,7 +40,6 @@
813.6862861351651
933.1290943962624))


(defn +cents [cps]
(assoc cps :cents (->> cps
:scale
Expand Down Expand Up @@ -83,11 +80,10 @@
%1 %2)))))

(+euclidean-distance {:cents '(0 204 316 519 702 1018)})
(sort (map #(-> % (- 182) (mod 1200)) '(0 182 386 498 701 884) ))
(sort (map #(-> % (- 182) (mod 1200)) '(0 182 386 498 701 884)))
(defn +gens [factors cps]
(assoc cps :factors factors))


(comment
(require '[clojure.math.combinatorics :as combo]
;; '[clojure.data.csv :as csv]
Expand Down Expand Up @@ -122,9 +118,9 @@
(with-open [writer (io/writer "3oo7-similarity-to-12edo-scales-up-to-23.csv")]
(csv/write-csv writer
(->> #_cps-sorted-by-euclidean-distance
#_cps-sorted-by-euclidean-distance-up-to-53
cps-sorted-by-euclidean-distance-up-to-23
(mapv (juxt :factors :mode :cents :closest-12-edo :euclidean-distance ))
#_cps-sorted-by-euclidean-distance-up-to-53
cps-sorted-by-euclidean-distance-up-to-23
(mapv (juxt :factors :mode :cents :closest-12-edo :euclidean-distance))
(mapv (fn [data]
(mapv #(cond
(= java.lang.Long (type %)) %
Expand Down
25 changes: 11 additions & 14 deletions src/erv/cps/utils.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@
{})))

(comment
(make-degree->note (erv.cps.core/make 2 [1 3 5 7]))
)
(make-degree->note (erv.cps.core/make 2 [1 3 5 7])))

(defn make-set->degrees-map
[{:keys [scale] :as _cps}]
Expand All @@ -68,7 +67,6 @@
(reduce (fn [m [deg set]] (update m deg (fnil conj #{}) set))
{})))


(defn- set-d1-intersection?
[set1 set2]
(= 1 (count (set/difference set1 set2))))
Expand All @@ -86,15 +84,14 @@
(map #(set (conj % degree-set)))
(filter #(->> (combo/combinations % 2)
(map (partial apply set-d1-intersection?))
(every? true?)) )
(every? true?)))
set)))

(comment
(harmonic-sets (erv.cps.core/make 3 [1 3 5 7 9 11])
4
0)))


(defn harmonic-set-degrees
"Returns a list of harmonic sets (as degrees) for a specific degree of a cps
A harmonic set is a set where all notes are connected with any other by all of its factors except one."
Expand All @@ -104,16 +101,16 @@
(sort (map (comp #(into [] %)
sort
(partial map set->degrees))
sets))))=
sets)))) =

(comment
(=
[#{#{#{7 5} #{3 5} #{7 3}}
#{#{7 5} #{3 5} #{1 5}}
#{#{7 1} #{7 5} #{7 3}}
#{#{7 1} #{7 5} #{1 5}}}
[#{#{#{7 5} #{3 5} #{7 3}}
#{#{7 5} #{3 5} #{1 5}}
#{#{7 1} #{7 5} #{7 3}}
#{#{7 1} #{7 5} #{1 5}}}
'((0 1 4) (0 1 5) (0 2 4) (0 2 5))]
(let [cps (erv.cps.core/make 2 [1 3 5 7])
set-size 3]
[(harmonic-sets cps set-size 0)
(harmonic-set-degrees cps set-size 0)])))
(let [cps (erv.cps.core/make 2 [1 3 5 7])
set-size 3]
[(harmonic-sets cps set-size 0)
(harmonic-set-degrees cps set-size 0)])))
9 changes: 4 additions & 5 deletions src/erv/edo/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
(def submosi (make-all-submos (mos 6) 5))
(do)
(def submos) (-> submosi #_(->> (filter :true-submos?))
#_ #_ (nth 0) :submos
#_ #_ (nth 1) :mos)
#_#_(nth 0) :submos
#_#_(nth 1) :mos)
(demo! (:scale (from-pattern submos)) :note-dur 200 :direction :down)
(demo! (:scale (from-pattern [3,5,2,5,3,5,4])) :note-dur 200 :direction :down)
(demo! (:scale (from-pattern[6, 3, 4, 3, 7, 4, 3, 1] 2)) :note-dur 200 :direction :up ))
(demo! (:scale (from-pattern [6, 3, 4, 3, 7, 4, 3, 1] 2)) :note-dur 200 :direction :up))

(defn from-pattern
"For use with `mos` patterns or other custom intervalic patterns, i.e. [3 2 3 2 2]"
Expand All @@ -47,5 +47,4 @@
:bounding-period period})
degrees)})))


(from-pattern [ 2, 2, 5, 2, 5, 2, 5, 2, 2, 5, 2, 5, 2, 5, 2, 5])
(from-pattern [2, 2, 5, 2, 5, 2, 5, 2, 2, 5, 2, 5, 2, 5, 2, 5])
12 changes: 0 additions & 12 deletions src/erv/math/pascals_triangle.clj

This file was deleted.

Loading
Loading