I'm just getting started with Overtone, but I want to keep things somewhat organised from the start.
project.clj:
(defproject overtone-sketchbook "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.5.1"]
[overtone "0.9.1"]])
src/overtone_sketchbook/synths.clj:
(ns overtone-sketchbook.synths
(:use [overtone.live]))
(definst pluck-saw [f 800 d 3]
(* (saw (+ 100 (* 200 (saw d))))
(pluck (* (white-noise)
(env-gen (perc 0.001 2) :action FREE))
1 3 (/ 1 f))))
> lein repl
nREPL server started on port 52425
REPL-y 0.2.0
Clojure 1.5.1
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
user=> (use 'overtone.live)
--> Loading Overtone...
**********************************************************
WARNING: JVM argument TieredStopAtLevel=1 is active, and may
lead to reduced performance. This happens to currently be the
default lein setting:
https://github.com/technomancy/leiningen/pull/1230
If you didn't intend this JVM arg to be specified, you can turn
it off in your project.clj file or your global
~/.lein/profiles.clj file by adding the key-val
:jvm-opts ^:replace []
**********************************************************
--> Booting internal SuperCollider server...
Found 0 LADSPA plugins
*** ERROR: open directory failed '/Users/ilya/Library/Application Support/SuperCollider/synthdefs'
Number of Devices: 2
0 : "Built-in Input"
1 : "Built-in Output"
"Built-in Input" Input Device
Streams: 1
0 channels 2
"Built-in Output" Output Device
Streams: 1
0 channels 2
SC_AudioDriver: sample rate = 44100.000000, driver's block size = 512
--> Connecting to internal SuperCollider server...
--> Connection established
_____ __
/ __ /_ _____ _____/ /_____ ____ ___
/ / / / | / / _ \/ ___/ __/ __ \/ __ \/ _ \
/ /_/ /| |/ / __/ / / /_/ /_/ / / / / __/
\____/ |___/\___/_/ \__/\____/_/ /_/\___/
Collaborative Programmable Music. v0.9.1
Hey Ilya, I feel something magical is only just beyond the horizon...
nil
user=> (demo overtone-sketchbook.synths/pluck-saw)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom (RT.java:505)
user=> (use 'overtone-sketchbook.synths)
nil
user=> (demo overtone-sketchbook.synths/pluck-saw)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom (RT.java:505)
user=> (demo pluck-saw)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom (RT.java:505)
user=> (require 'overtone-sketchbook.synths)
nil
user=> (demo pluck-saw)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom (RT.java:505)
user=> (demo overtone-sketchbook.synths/pluck-saw)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom (RT.java:505)
user=> Bye for now!
> lein repl
nREPL server started on port 52100
REPL-y 0.2.0
Clojure 1.5.1
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
user=> (use 'overtone-sketchbook.synths)
--> Loading Overtone...
**********************************************************
WARNING: JVM argument TieredStopAtLevel=1 is active, and may
lead to reduced performance. This happens to currently be the
default lein setting:
https://github.com/technomancy/leiningen/pull/1230
If you didn't intend this JVM arg to be specified, you can turn
it off in your project.clj file or your global
~/.lein/profiles.clj file by adding the key-val
:jvm-opts ^:replace []
**********************************************************
--> Booting internal SuperCollider server...
Found 0 LADSPA plugins
*** ERROR: open directory failed '/Users/ilya/Library/Application Support/SuperCollider/synthdefs'
Number of Devices: 2
0 : "Built-in Input"
1 : "Built-in Output"
"Built-in Input" Input Device
Streams: 1
0 channels 2
"Built-in Output" Output Device
Streams: 1
0 channels 2
SC_AudioDriver: sample rate = 44100.000000, driver's block size = 512
--> Connecting to internal SuperCollider server...
--> Connection established
_____ __
/ __ /_ _____ _____/ /_____ ____ ___
/ / / / | / / _ \/ ___/ __/ __ \/ __ \/ _ \
/ /_/ /| |/ / __/ / / /_/ /_/ / / / / __/
\____/ |___/\___/_/ \__/\____/_/ /_/\___/
Collaborative Programmable Music. v0.9.1
Hello Ilya, may algorithmic beauty pour forth from your fingertips today.
nil
user=> pluck-saw
#overtone.studio.inst.Inst{:name "pluck-saw", :params ({:value #<Atom@24fc9cde: 800.0>, :name "f", :default 800.0, :rate :kr} {:value #<Atom@449ec5ca: 3.0>, :name "d", :default 3.0, :rate :kr}), :args ("f" "d"), :sdef {:name "overtone-sketchboo96d/pluck-saw", :constants [0.0 0 2.0 3.0 0.5 1.0 50.0 100.0 200.0 1 2 -99 -4 5 0.001], :params (800.0 3.0), :pnames ({:name "f", :index 0} {:name "d", :index 1}), :ugens ({:n-inputs 0, :args nil, :outputs ({:rate 1} {:rate 1}), :name "Control", :rate 1, :n-outputs 2, :rate-name :kr, :inputs (), :special 0, :id 280} #<sc-ugen: saw:ar [1]> #<sc-ugen: binary-op-u-gen:ar [2]> #<sc-ugen: binary-op-u-gen:ar [3]> #<sc-ugen: saw:ar [4]> #<sc-ugen: white-noise:ar [0]> #<sc-ugen: env-gen:kr [0]> #<sc-ugen: binary-op-u-gen:ar [2]> #<sc-ugen: binary-op-u-gen:kr [1]> #<sc-ugen: pluck:ar [5]> #<sc-ugen: binary-op-u-gen:ar [11]> #<sc-ugen: out:ar [12]>)}, :group #<synth-group[live]: Inst pluck-saw Container 31>, :instance-group #<synth-group[live]: Inst pluck-saw 32>, :fx-group #<synth-group[live]: Inst pluck-saw FX 33>, :mixer #<synth-node[live]: overtone.stu547/mono-inst-mixer 34>, :bus #<audio-bus: No Name, mono, id 50>, :fx-chain [], :volume #<Atom@6e9cebcc: 1.0>, :pan #<Atom@3cd6d0: 0.0>, :n-chans 1}
user=> (demo pluck-saw)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: demo in this context, compiling:(NO_SOURCE_PATH:1:1)
user=> (overtone.live/demo pluck-saw)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom (RT.java:505)
user=> Bye for now!
Am I missing something very basic?
firstly, it would help hugely if you could make your question much simpler and succinct so that it's easy to identify possible solutions.
Also, thanks for giving Overtone a try - sorry that things aren't immediately clear. There's a lot going on here, so expect to ask a few questions on your way :-)
However, looking at your two REPL excerpts it's clear that you don't yet fully understand three things:
Let me briefly discuss each of these, and hopefully they'll shed some light on what's going on.
Firstly, Overtone's use of Clojure's namespaces. When you use
overtone.live
what Overtone is doing is importing all of Overtone's public API functions into your current namespace. This means that once this operation is completed, all of the public API will be available to you - i.e. demo
, defsynth
, sin-osc
etc.
In your second REPL example, the first thing you try to do is: (demo overtone-sketchbook.synths/pluck-saw)
which won't work because Clojure doesn't yet know what demo
is and has no ideas about your namespace overtone-sketchbook.synth
. For it to know about these, you need to either use
or require
the namespaces. For more information, read up about Clojure's ns
macro.
Secondly, Overtone's synths are designed by calling functions which represent parts of a synth (called ugens). Examples of ugens are saw
, sin-osc
, lpf
. You can see a complete list of the available ugens in the Overtone cheatsheet: https://github.com/overtone/overtone/raw/master/docs/cheatsheet/overtone-cheat-sheet.pdf
demo
is a macro that allows you to pass in a (partial) synthdef and to play it:
(demo (sin-osc))
(demo (sin-osc 440))
Note that ugens are functions in order to allow you to pass parameters to modify their behaviour (such as the 440 hz param to the sin-osc
ugen).
It's also important to note that ugens cannot (currently) be treated the same as synths. A ugen is a component of a synth, a synth is a tree of ugens. Which leads me on to the third issue - you were trying to demo
the pluck-saw
synth. This is a synth which has already been designed and may only be triggered. To trigger a synth, simply call it as a function:
(pluck-saw)
You can also pass params (if the design permits them) to the synth trigger function.
So to summarise:
ns
macros load external namespaces, and pull in functions to make them available. For Overtone's default API you need to pull in either overtone.live
or overtone.core
(the first boots a server if one isn't already booted).demo
and defsynth
. You can pass arguments to the ugen functions to specify their behaviour.Finally, do come and join us on the mailing list - we'd love to see what you're doing (and planning to do) with Overtone and share our passion with you: