I'm trying to make music with the overtone library of clojure. To produce interesting sounds, additive synthesis is useful, that means that I take sinus oscillators of several frequencies and simply add them. In overtone, to create a synthesizer, which realizes that, I can write:
(definst myinst [freq 100]
(* 0.2 (reduce + (map sin-osc [101.0 100 99.0]))))
To be a bit more reusable, I write a function, which takes a frequency and returns a list with all these frequencies, you can see in the code snippet:
(defn split-freq [freq]
(apply vector (map #(* freq %) [1.01 1 0.99])))
When executing (split-freq 100)
, the REPL gives me the following:
[101.0 100 99.0]
which is exactly the same as the input, I provided the map function above. In fact, I copied the result. Now, I try this:
(definst myinst [freq 100]
(* 0.2 (reduce + (map sin-osc (split-freq freq)))))
Unfortunately, the REPL tells me, that I'm doing wrong:
CompilerException java.lang.ClassCastException:
overtone.sc.machinery.ugen.sc_ugen.ControlProxy cannot be cast to java.lang.Number,
compiling:(form-init1807789563491679853.clj:1)
But this code works fine:
(definst myinst [freq 100]
(* 0.2 (reduce + (map sin-osc (apply vector (map #(* freq %) [1.01 1 0.99]))))))
although, I simply put in the function definition.
I think I have a principal lack of understanding. I thought, that if one of those version work, the others must work, too.
My questions are: Why does my 'improved' version does not work? Why does the first snippet work? How can I circumvent this behavior?
Clojure 1.3.0
Overtone 0.8
(use 'overtone.core)