Skip to content

Instantly share code, notes, and snippets.

@devn

devn/core.clj Secret

Created December 30, 2019 02:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devn/5ffa260ef0384580a498d4b44d2b6669 to your computer and use it in GitHub Desktop.
Save devn/5ffa260ef0384580a498d4b44d2b6669 to your computer and use it in GitHub Desktop.
improvos hackery
(ns improvos.core
(:require [overtone.live :as o.live]
[overtone.inst.piano :as p]
[overtone.music.pitch :as pitch]
[overtone.music.time :as time]
[clojure.math.combinatorics :as c]
[clojure.set :as set]
[clojure.string :as str]))
(def intervals
[:1 :b2 :2 :b3 :3 :4 :b5 :5 :b6 :6 :b7 :7])
(def INTERVAL-LOOKUP
(zipmap intervals (range 0 12)))
(def all-combinations
(conj (map #(cons :1 %) (rest (c/subsets (rest intervals)))) [:1]))
(def combinations-by-length (group-by count all-combinations))
(defn build-formula [starting-note length]
(map #(+ % (pitch/note starting-note))
(let [rand-formula (rand-nth (get combinations-by-length length))]
(for [x rand-formula]
(get INTERVAL-LOOKUP x)))))
(defn find-matching-formula [starting-note formula-length match-length]
(let [formula (build-formula starting-note formula-length)
scale-pattern (reduce (fn [m [note1 note2]]
(conj m (- note2 note1)))
[]
(partition 2 1 formula))
formula-start (take match-length scale-pattern)]
{:matched-scales (->> pitch/SCALE
(filter #(= formula-start
(take match-length (val %))))
(into {}))
:formula formula
:scale-pattern scale-pattern}))
(defn search
[starting-note formula-length match-length]
(loop [tries 1000]
(let [{:keys [matched-scales formula]
:as result} (find-matching-formula starting-note
formula-length
match-length)]
(if (= tries 0)
::none-found
(if (>= (count matched-scales) 1)
result
(recur (dec tries)))))))
(defn play-formula [starting-note formula-length match-length]
(loop [notes (let [{:keys [formula scale-pattern matched-scales]} (search starting-note formula-length match-length)
[root & notes :as all] formula
;; shuffled (cons root (shuffle notes))
]
(println "Notes:" (mapv #(pitch/find-note-name %) all))
(println "Formula:" (pr-str formula))
(println "Matched scales:" (pr-str matched-scales))
(println "Scale pattern:" (pr-str scale-pattern))
#_shuffled
all)
offset 0]
(if (seq notes)
(do
(o.live/at (+ (time/now)
(* 200 offset))
(p/piano (first notes)
:release 0
:sustain 0
:decay 0))
(recur (rest notes) (inc offset))))))
(play-formula :D4 5 4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment