Getting Started : Sequencing Notes

200 views
Skip to first unread message

phil jones

unread,
Feb 10, 2017, 10:07:15 AM2/10/17
to Overtone
Hi,

I'm just getting started with Overtone.

While there seems to be a really well defined way to generate sound, I'm finding sequencing pretty confusing.

Am I right that there's no official way to define a sequence and schedule it to run in Overtone? Each example I find seems to do it a different way.

I'm wondering if some are older deprecated ways to schedule a sequence and if there's now a modern, definitive way.

I've tried, for example, Leipzig, but when I try to run something like

(def A (phrase [1/4 1/2 1/4] [0 3 5 4]))

(->> A
     
(tempo (bpm 90))
     
(where :pitch (comp scale/C scale/major))
     live
/play)


using c-x c-e  in the Emacs buffer, I get back a Future saying :status :pending, :val nil

And nothing ever plays.

Similarly, I've tried defining a looper based on one of the wiki examples :

(defn looper [nome sound]
 
(let [beat (nome)]
   
(at (nome beat) (sound))
   
(apply-by (nome (inc beat)) looper nome sound [])))


Executing this with (looper a-metronome a-sound) gives me a

ScheduledJob with :desc of "Overtone delayed fn" scheduled? true  


... but again, it doesn't actually play my sound.

I'm assuming this is something like a Future too.

Can someone point me to a simple and up-to-date explanation and example of how to sequence a series of notes that actually works?

Or does this look more like some kind of problem with my setup? It doesn't seem to be a problem with sound. If I just (demo 5 (a-sound)) it plays fine.

cheers

Phil

joa...@verona.se

unread,
Feb 10, 2017, 10:35:43 AM2/10/17
to phil jones, Overtone
phil jones <inte...@gmail.com> writes:

> Hi,
>
> I'm just getting started with Overtone.
>
> While there seems to be a really well defined way to generate sound, I'm finding sequencing pretty confusing.
>
> Am I right that there's no official way to define a sequence and schedule it to run in Overtone? Each example I find seems to do it a different way.
>
> I'm wondering if some are older deprecated ways to schedule a sequence and if there's now a modern, definitive way.
>
> I've tried, for example, Leipzig, but when I try to run something like
>
> (def A (phrase [1/4 1/2 1/4] [0 3 5 4]))
>
> (->> A
> (tempo (bpm 90))
> (where :pitch (comp scale/C scale/major))
> live/play)

I use a metronome base temporal recursive sequencer.

https://github.com/jave/overtone-sylt

If you want to try it, the actual overtone part of it is here:
https://github.com/jave/overtone-sylt/tree/master/sylt-docker/sylt

Maybe its not very user friendly, but I'm having great fun with the thing.

Essentially you set the metronome, define your voices, and a pattern,
then start the sequencer.

(the "il" thing means interleave, which just interleaves the said number
of nops in a sequence. you dont have to use that feature, it mostly
saves from typing "-" a lot)

(drum-set-metro :bpm 200 :il 3)

(drum-set-drums {
:B (fn [x]
(cond
(= 'c x)(electro-kick)
(= 'o x) (dance-kick)
:else (do (electro-kick) (dance-kick)))
)
:H (fn [x] (cond
(= 'c x)(electro-hat)
(= 'o x)(open-hat :amp 1 :t 0.1 :low 10000 :hi 2000 )
:else (open-hat)))
:C (fn [x] (clap))
:E (fn [x] (println x) (cond (= 'e x) (inst-fx! clap fx-echo)
(= 's x) (clear-fx clap)))
})

(drum-set-beat {
:B '[x - ]
{:voice :B :id 3} '[o - ]
:H '[c o ]
; {:voice :H :il 0 :id 0}'[c c ]
;;atm you comment out tracks to mute them
;;atm also you need :id 0, so the keys are unique
{:voice :B :il 5 :id 0} '[c o ]
{:voice :B :il 3 :id 1} '[c o ]
:C '[- - - x]
{:voice :E :il 15 } '[e - - - - s ]
}
)

(play-drums-metro)





>
> using c-x c-e in the Emacs buffer, I get back a Future saying :status :pending, :val nil
>
> And nothing ever plays.
>
> Similarly, I've tried defining a looper based on one of the wiki examples :
>
> (defn looper [nome sound]
> (let [beat (nome)]
> (at (nome beat) (sound))
> (apply-by (nome (inc beat)) looper nome sound [])))
>
> Executing this with (looper a-metronome a-sound) gives me a
>
> ScheduledJob with :desc of "Overtone delayed fn" scheduled? true
>
> ... but again, it doesn't actually play my sound.
>
> I'm assuming this is something like a Future too.
>
> Can someone point me to a simple and up-to-date explanation and example of how to sequence a series of notes that actually works?
>
> Or does this look more like some kind of problem with my setup? It doesn't seem to be a problem with sound. If I just (demo 5 (a-sound)) it plays fine.
>
> cheers
>
> Phil
--
Joakim Verona
joa...@verona.se
+46705459454

phil jones

unread,
Feb 10, 2017, 11:38:35 AM2/10/17
to Overtone, inte...@gmail.com
Thanks Joakim,

that looks interesting, but I'm not in a position to move to Docker at the moment.

And actually I'm trying to do something other than loop-based live-coding. More like sequencing an entire score.

I'm wondering if I have a problem with my metronome though :

>(def m1 (metronome 120))
#'tutorial.core/m1
> (m1)
6
> (m1)
12
> (m1 20)
1.486744099713E12
> (m1 24)
1.486744101713E12



Does this look right for a metronome interaction in Overtone?

What is it that (m1 n) produces? The timestamp of n seconds (or n ticks) ahead of "now" or n ticks ahead of when the metronome was created?

For a program that isn't looping, but just generating a sequence which should be played when I execute the program, how do I know that I'm actually scheduling the events for the future and not, say, the past ...

right now I'm doing something like this :

(doseq [n melody]
       
(at (nome (:start n)) (inst (:pitch n)))
       
(println (nome (:start n)) (nome 0))
       
) )
   
))

but no sound is coming out. So one thing I'm considering is if the timestamps are being generated correctly.

joa...@verona.se

unread,
Feb 10, 2017, 1:05:19 PM2/10/17
to phil jones, Overtone
phil jones <inte...@gmail.com> writes:

> Thanks Joakim,
>
> that looks interesting, but I'm not in a position to move to Docker at the moment.

You dont need docker, thats just for the network audio setup.

>
> And actually I'm trying to do something other than loop-based live-coding. More like sequencing an entire score.

Ok. I'm trying to do that with my sequencer as well. Thats one of the
uses for the interleave. You can have one pattern which does something,
like playing an arpeggio or another sequence, every 64th beat, etc.
But I'm starting to sound like a comercial. I'll stop :)


> I'm wondering if I have a problem with my metronome though :
>
>>(def m1 (metronome 120))
> #'tutorial.core/m1
>> (m1)
> 6
>> (m1)
> 12
>> (m1 20)
> 1.486744099713E12
>> (m1 24)
> 1.486744101713E12
>
> Does this look right for a metronome interaction in Overtone?
>
> What is it that (m1 n) produces? The timestamp of n seconds (or n ticks) ahead of "now" or n ticks ahead of when the metronome was created?
>
> For a program that isn't looping, but just generating a sequence which should be played when I execute the program, how do I know that I'm actually scheduling the events for the future and not, say, the past ...
>
> right now I'm doing something like this :
>
> (doseq [n melody]
> (at (nome (:start n)) (inst (:pitch n)))
> (println (nome (:start n)) (nome 0))
> ) )
> ))
>
> but no sound is coming out. So one thing I'm considering is if the timestamps are being generated correctly.


Heres some tutorial code that maybe explains it.
As an aside, I've tried other approaches than this temporal recursion
aproach, and they dont seem to work well.


(defonce metro (metronome 240))
;; #+END_SRC
;; we use it as follows:
;; #+BEGIN_SRC clojure
(metro) ; current beat number
(metro 3) ; timestamp of beat number 3
;; #+END_SRC
;; if we rewrite loop-beats using a metronome, it would look like
;; this:
;; #+BEGIN_SRC clojure
(defn metro-beats [m beat-num]
(at (m (+ 0 beat-num)) (kick))
(at (m (+ 1 beat-num)) (hat))
(at (m (+ 2 beat-num)) (kick))
(at (m (+ 3 beat-num)) (hat))
(apply-at (m (+ 4 beat-num)) metro-beats m (+ 4 beat-num) [])
)

(comment
(metro-beats metro (metro))
)


Also, I found that rescheduling the actuall voice call improves
jitter. See below.


(defn play-drums-metro2 [m beat-num]
"start playing drums, using m as metro"
;;play drums using a metronome strategy, which has advantages over the periodic strategy
;; 1st reschedule next call to the sequencer
(apply-at (m (+ 1 beat-num))
play-drums-metro2
m
(+ 1 beat-num)
[])
;; 2nd schedule the drum voice
(at (m beat-num)(drum-fn-globalbeat))
;;3d step global counters
(dosync (ref-set *beat-count (inc @*beat-count) ))
)

Chris Ford

unread,
Feb 13, 2017, 4:58:07 AM2/13/17
to over...@googlegroups.com, phil jones
Hi Phil,

When you tried that Leipzig example, did you define a play-note defmethod for your notes? If not, Leipzig won't know how to play them. Leipzig expects that each note will have a :part key that tells it which synth to use. Alternatively if you define a default defmethod then Leipzig will use that for all notes.

If you look at the Leipzig README you can see examples of how to both compose a melody (which your example does) and specify a part.

Cheers,

Chris

+46705459454

--
You received this message because you are subscribed to the Google Groups "Overtone" group.
To unsubscribe from this group and stop receiving emails from it, send an email to overtone+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Johnny Brown

unread,
Sep 30, 2019, 6:59:15 PM9/30/19
to Overtone
Phil,

Expanding on what ctford said, if you change your example to the following you should get some sound

(defmethod lz/play-note :piano3 [{:keys [pitch duration]}]
  (when pitch
    (piano/piano pitch :vel 60 :velcurve 0.1 :decay 0.2)))

(def A (phrase [1/4 1/2 1/4] [0 3 5 4]))

(->> A
     (all :part :piano)

     (tempo (bpm 90))
     (where :pitch (comp scale/C scale/major))
     lz/play)
Reply all
Reply to author
Forward
0 new messages