"add-watch" for buffers?

24 views
Skip to first unread message

Eric Vogler

unread,
May 20, 2013, 9:10:09 PM5/20/13
to over...@googlegroups.com
Is there a default way to trigger an event whenever a value in a buffer changes? Or in general, to trigger events from within synths?

As usual, apologies if I'm missing something obvious.

Thanks,
Eric

Roger Allen

unread,
May 21, 2013, 2:14:51 AM5/21/13
to over...@googlegroups.com
The tap cgen creates an atom that is updated from a synth at a fixed rate.  I believe you could add-watch that atom, but I haven't tried...

The meta-ex code has an example of creating a tap & accessing it here:

Eric Vogler

unread,
May 21, 2013, 4:37:21 AM5/21/13
to over...@googlegroups.com
Thanks for the reply, Roger.

I was able to use a tap to access a ugen's value through an atom, but it doesn't seem to trigger 

Here's my example: 

;; This is based on the voltap example, but I'm tapping mouse-x. 
;; (I also got the same results with "(demand (impulse:kr 1) 0 (dwhite))" as my ugen).
(defsynth mouse-synth []
  (tap "mouse-tap" 10 (mouse-x:kr)))

(def m (mouse-synth))

(def mouse-atom ((:taps m) "mouse-tap"))

(type mouse-atom) ; clojure.lang.Atom

@mouse-atom ; returns the correct, current value of the ugen.  

;; now for the add-watch
(defn watcher [a]
  (add-watch a :key (fn [k r os ns] (print "watcher called." k r os ns)))) 

(watcher mouse-atom) ; wiggle mouse, nothing happens.

;; just to make sure I'm doing add-watch right: 
(def another-atom (atom 0))

(watcher another-atom)

(swap! another-atom inc)  
; watcher called. :key #<Atom@eda1c9d: 1> 0 1


I wonder if I'm missing something here since add-watch is new to me.


Roger Allen

unread,
May 21, 2013, 10:02:06 AM5/21/13
to over...@googlegroups.com
I don't see anything wrong with your code...I wonder if the lack of watch response is related to this:
Var watchers are triggered only by root binding changes, not thread-local set!s.

--Roger
Message has been deleted

Sam Aaron

unread,
May 28, 2013, 4:36:16 PM5/28/13
to over...@googlegroups.com
Hi Eric,

sorry for the late reply - I've been insanely busy of late.


On 21 May 2013, at 02:10, Eric Vogler <ericv...@gmail.com> wrote:

> Is there a default way to trigger an event whenever a value in a buffer changes?

There's currently no system in place to do this for you. The main issue is that buffer changes can happen server-side and there's no hooks in SuperCollider to use to get notifications of buffer modifications.

The only way you can do it is to poll the buffer, read its contents and compare to a stored value and create an event if things have changed.

> Or in general, to trigger events from within synths?

Unfortunately there's no way of directly triggering events from within synths. The only side effects you can enact within a synth is the :action arg of certain ugens which allow for killing the current synth and other defined events. There's no general system for running arbitrary code.

As Roger pointed out, you can tap any arbitrary ugen and get a constant stream of latest values. It is possible to attach watchers to the atoms storing the latest values and your code *does* work - it's just that the println happens on a non-main thread, so the output is wherever the stdout of the lein process is. I tend to start lein manually from a console so I always have a window displaying this output.

> So I was just now looking for a way to trigger an overtone even using onsets. Add-watch would've been one way to do it, but is there another? (Besides polling an atom myself many times /sec)...

What do you mean by "trigger an overtone event using onsets"? Can you give me an example?

Sam

---
http://sam.aaron.name

Eric Vogler

unread,
May 28, 2013, 6:00:48 PM5/28/13
to over...@googlegroups.com
Hi Sam,

You know, I realized today... I was just looking for send-trig.  I was trying to do something like: 

(definst beep []
  (let [e (env-gen (lin-env 0 0.03 0) :action FREE)
        snd (* e (saw 220))] 
      snd))

(defn beeper [e]
  (beep))

(defsynth onset-synth []
  (let [snd (sound-in)
        ons (onsets (fft (local-buf 512) snd))]
    (send-trig ons))) 

(onset-synth)

(on-event "/tr" beeper ::beeper)


That seems like it takes care of it.  For the mouse example, I could send a trigger when the slope of the mouse position becomes positive, etc...

Also, ya, the add-watch was indeed outputting somewhere I wasn't looking.  I should know by now to check for that... :(


Thanks!

Eric
Reply all
Reply to author
Forward
0 new messages