Skip to content

Instantly share code, notes, and snippets.

@nbqx
Created May 21, 2013 23:12
Show Gist options
  • Save nbqx/5624032 to your computer and use it in GitHub Desktop.
Save nbqx/5624032 to your computer and use it in GitHub Desktop.
(ns yes
(:use [overtone.live]
[clojure.data.json :only [read-json]])
(:require [echonest-api.core :as echonest]
[http.async.client :as client]))
;; Kierra "Kiki" Sheard - Yes (2006)
;; http://www.youtube.com/watch?v=4LgXAWeGqDE
(def mp3 "data/yes.mp3")
(def wav "data/yes.wav")
(echonest/set-api-key! "API-KEY")
;; (def song (echonest/analyze-response (echonest/upload-song mp3 :query {:filetype "mp3"} :wait-response true)))
(def clap (sample (freesound-path 183103)))
(def ^:dynamic *clap* false)
(defn clapping [bool]
(alter-var-root (var *clap*) (fn [_] bool)))
(defn- req [url]
(with-open [client (client/create-client)]
(let [res (client/GET client url)]
(-> res
client/await
client/string))))
(defprotocol AudioProperty
(samp-rate [this])
(bpm [this])
(beats [this])
(bars [this]))
(deftype Audio [data]
AudioProperty
(samp-rate [this] (:sample_rate (:meta data)))
(bpm [this] (:tempo (:track data)))
(beats [this] (:beats data))
(bars [this] (:bars data)))
(defn get-audio-data [id]
(let [res (echonest/basic-query "track" "profile" :query {:id id :bucket "audio_summary"})
profile (echonest/analyze-response res)
data (read-json (req (:analysis_url (:audio_summary (:track (:response profile))))))]
(->Audio data)))
(def my-audio (get-audio-data "TRTDSDW13EC1146B96"))
(defn- get-pos-info [beat]
(let [samp (samp-rate my-audio)
start-pos (:start beat)
duration (:duration beat)]
(vector :start (int (* samp start-pos))
:size (int (* samp duration)))))
(defn- sample-fn [beat]
(let [pos (get-pos-info beat)]
(apply sample (concat [wav] pos))))
(defn get-sample
([] (sample-fn (rand-nth (beats my-audio))))
([n] (sample-fn (nth (beats my-audio) n))))
(defn get-samples
([] (let [beats (beats my-audio)
s (rand-int (count beats))
sqs (take 4 (nthnext beats s))]
(map #(sample-fn %) sqs)))
([n] (let [beats (beats my-audio)
sqs (take 4 (nthnext beats n))]
(map #(sample-fn %) sqs)))
([n len] (let [beats (beats my-audio)
sqs (take len (nthnext beats n))
sqs (take 4 (cycle sqs))]
(map #(sample-fn %) sqs))))
(def s1* (get-sample 2))
(def s2* (get-sample 3))
(def s3* (get-sample 5))
(def s4* (get-sample 6))
(def s1 (get-sample 78))
(def s2 (get-sample 79))
(def s3 (get-sample 80))
(def s4 (get-sample 81))
(def sq (atom [s1 s2 s3 s4]))
;; (reset! sq (repeat 4 s1))
;; 122,123
(def metro (metronome (bpm my-audio)))
(defn looper [beat]
(let [c (mod beat 4)
f (nth @sq c s1*)]
(at (metro beat) (apply f []))
(if (and (odd? c) *clap*)
(at (metro beat) (clap)))
(apply-at (metro (inc beat)) #'looper (inc beat) [])))
(defn stop-looper []
(stop))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment