Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use :beat-ratio as Dynamic parameter #16

Closed
dandaka opened this issue Dec 7, 2015 · 6 comments
Closed

Can't use :beat-ratio as Dynamic parameter #16

dandaka opened this issue Dec 7, 2015 · 6 comments

Comments

@dandaka
Copy link
Contributor

dandaka commented Dec 7, 2015

This works fine:

(def light-param (params/build-oscillated-param
  (oscillators/sawtooth-beat :beat-ratio 4 :down? true) :max :max-lightness))

(defn light-sawtooth
  "Change light according to sawtooth osc"
  []
  (show/add-effect! :color (global-color-effect
    (params/build-color-param :h :main-hue :s 100 :l light-param))))

This is not working:

; Osc beat ratio
(afterglow.show/set-variable! :osc-beat-ratio 4)

(def light-param (params/build-oscillated-param
  (oscillators/sawtooth-beat :beat-ratio :osc-beat-ratio :down? true) :max :max-lightness))

(defn light-sawtooth
  "Change light according to sawtooth osc"
  []
  (show/add-effect! :color (global-color-effect
    (params/build-color-param :h :main-hue :s 100 :l light-param))))

https://gist.github.com/dandaka/b023cea7d4d4296e85d6

@brunchboy
Copy link
Member

That’s correct. The oscillators are low-level, and optimized to be very efficient. They don’t take variable parameters of any sort, and include only as much code in the functions they return as needed to implement the features they are configured for when you create them.

If you look at the definition of sawtooth-beat, it seems a little long for what it does, but boils down to choosing between and returning one of six different simple one-line functions whose complexity is dictated by the actual arguments you used to create the oscillator.

Oscillated parameters build on oscillators at a higher level of abstraction, and that is where show variables and dynamic values can be introduced, to configure things like the maximum and minimum values by transforming the output of the oscillator.

So unfortunately there is currently no way to do what you are trying to do in the section that doesn’t work.
However, I can definitely see something like that being very useful. And, frankly, one of the reasons that oscillators can’t accept dynamic parameters is simply that dynamic parameters didn’t exist when oscillators were created.

I think it will be possible to add support for dynamic parameters to them, without losing the optimizations that are possible in the cases where you are passing in constant values. That is why I built some of the complexity into the dynamic parameter mechanism, so that code can look at the parameter and determine if its value is going to change between effect frames or not, and optimize based on that.

I will mark this as an enhancement, and try to make it work the way you want when I have a chance. How urgent is it? If you want to learn a lot about how dynamic parameters work, you could take a crack at it yourself, otherwise I might have time tomorrow night.

@brunchboy
Copy link
Member

Although I just realized that this will not be as easy as I hoped. The current way oscillators are called does not give them enough information to evaluate dynamic parameters. I will have to study everywhere they are used and see if it will be possible to add those arguments before we can proceed.

@dandaka
Copy link
Contributor Author

dandaka commented Dec 8, 2015

Another idea is to use spatial-param in oscillators creation like this:

(defn light-sawtooth-phase
  "Change light of fixtures with phase shift. WIP."
  [beat-ratio]
  (let [phase-gradient (params/build-spatial-param  ; Spread a phase shift across fixtures
      (show/all-fixtures)
      (fn [head] (- (:x head) (:min-x @(:dimensions *show*)))) :max 1)]
    (let [light-param (params/build-oscillated-param
      (oscillators/sawtooth-beat :beat-ratio beat-ratio :down? true :phase phase-gradient) :max :max-lightness)]
      (show/add-effect! :color (global-color-effect
        (params/build-color-param :s 100 :l light-param :h :main-hue))
      )
    )
  )
)

I think it fails here: (oscillators/sawtooth-beat :phase phase-gradient)

https://gist.github.com/dandaka/50081ee8f72ff7b9f9ea

Maybe there is another way to achieve this effect?

My goal is simple. I want to spread oscillators phase shift across fixtures on stage. I don't see in your examples anything like this, but I think it is a pretty basic and common effect.

@dandaka dandaka mentioned this issue Dec 8, 2015
@brunchboy
Copy link
Member

All right, the rewriting of oscillators to support dynamic parameters is well underway. It is a sweeping change, and I am taking time as well to fundamentally restructure the way they are written, to get rid of a whole bunch of duplicated code, because I didn’t want to have to change so many copies of it, and because I am a lot better at writing concise, smart Clojure than when I first started this project. So it will probably be another day or two, I don’t have much time for coding on Wednesdays.

@brunchboy
Copy link
Member

I seem to have them all working! I have merged the changes to master. I need to do a little more testing, and update the documentation, but if you are brave you could start trying it based on the API doc, which is updated.

I put in deprecated stubs for backwards compatibility, but you will want to change your code to use the new functions, because the old ones will go away in 0.1.7. build-oscillated-param has moved from afterglow.effects.params to afterglow.effects.oscillators, and the new oscillators/sawtooth replaces sawtooth-beat, sawtooth-bar, and sawtooth-phrase (the same for the other wave shapes triangle, sine, and square). Hopefully your Clojure editor warns you about deprecated functions.

Now every parameter you use in making an oscillator can be dynamic. This was a lot more work than I expected, but I was able to make it a lot more powerful and flexible than I expected, and all without losing any efficiency for the simpler, non-dynamic cases. Woot!

@brunchboy
Copy link
Member

All right, I have updated the documentation to reflect the new, much better, design of oscillators. Thanks for prompting me to upgrade these to fit the flexibility that the rest of Afterglow has developed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants