Giter Club home page Giter Club logo

Comments (13)

ojack avatar ojack commented on August 9, 2024 3

I have been letting this sit to see how it works in practice...

In the dev branch of hydra-synth I have included some utility functions for fading and handling arrays of parameters. https://github.com/ojack/hydra-synth/blob/dev/src/timingUtils.js

Now it is possible to do osc([23, 200, 39]).out() and it cycles through the values.
osc([23, 299, 39].fast(2)).out() cycles through them twice as fast.

from hydra.

ojack avatar ojack commented on August 9, 2024 2

What I would like to do is to generalize the idea of modulating a set of parameters with a texture so that ANY parameter can accept a 2d texture (or generator function such as osc()). For example,

src(s0).modulate(s1)

is using the r and g channels of the texture s1 to affect the x and y coordinates of s0.

Instead of that, I would like to be able to use something like:

src(s0).rotate(s1)

Where the colors of s1 would then accept the rotation of s0 (in addition to parameters as numbers or parameters as timing functions).

This requires a substantial refactor of hydra so is a more long-term thing! But just putting it here in case anyone has any thoughts.

from hydra.

jarmitage avatar jarmitage commented on August 9, 2024 2

Continuing this discussion...

Just want to add these for reference of how I am borrowing my Tidal approach to generalising continuous functions.

sin = (min=0,max=1,freq=1) => ({time}) => Math.sin(time*freq) * max + min
sq = (min=0,max=1,freq=1) => ({time}) => ((Math.sin(time*freq) < 0) ? 0 : 1) * max + min
saw = (min=0,max=1,freq=1) => ({time}) => (((time * freq) % 1) * 2 - 1) * max + min 
rand = (min=0,max=1) => Math.random() * max + min

// examples...

osc(10,0,0)
  .rotate(sin(0,0.5,32))
  .out()

noise(sq(5,10,8),0.1).out(o0)

osc(1,1,2).invert(sq(0,1,8)).out(o0)

And also, attempts at porting some Tidal pattern functions...

Choose

// This needs to update using `getBpm()`
choose = (array) => {
  return array[Math.floor(Math.random() * array.length)];
}

shape(choose([2,5,8,12,15,5])).out()

Run

run = (end,step=1,direction=1) => {
    const len = Math.floor(end / step) + 1
    if (direction === 1)
        return Array(len).fill().map((_, idx) => (idx * step))  
    else if (direction === 0)
        return Array(len).fill().map((_, idx) => (idx * step)).reverse()
}

shape(run(5)).out()

shape(run(15,0.66,0)).out()

@ojack suggested function chaining for this sort of thing, e.g.:

shape(run(15,0.66,0).choose().fast()).out()

Another issue (sorry this is a long comment) is how to avoid polluting the global namespace.
Two ideas discussed related to this:

  • Adding the ability to dynamically unload glsl functions where necessary.
  • Encouraging users to curate their own custom-glsl-functions.js or a HydraBoot.js file.

from hydra.

echophon avatar echophon commented on August 9, 2024

In regards to 2. I have found it useful to define functions as variables for reuse. This has some tradeoffs from inline reference that CTRL+Shift+Enter helps with, as changes to the function will now need to be evaluated in multiple places.

x1 = (t)=>(10 * Math.sin(t * 0.1))
x2 = (t)=>(5 * Math.sin(t * 0.1))

o0.osc(x1)
o1.osc(x2)

from hydra.

ojack avatar ojack commented on August 9, 2024

thanks for the feedback! I would like to add a way to evaluate blocks of code for situations like that.

Another one I like is to define an extra function return, to be able to reuse the functions with different variables. i.e.:
x1 = (y)=>(t)=>(y * Math.sin(t * 0.01))

and then use it like:
o0.osc(x1(20))

It makes me wonder if some common functions could be predefined...i.e.

sin = (amplitude, period)=>(t)=>(amplitude* Math.sin(t * period))
o0.osc(sin(20, 0.01))

from hydra.

echophon avatar echophon commented on August 9, 2024

Thanks for this amazing tool! I like the ability to create them on the fly, this will be good for anyone who wants to go beyond the common functions, but having some common functions predefined opens doors & makes things more accessible to newcomers. I think having these available & examples of their use would certainly be beneficial.

I could see a whole class of wave function generators to supplement the set of image functions that you've established. Taking cues from the modular synth world (I think this is a great theme to continue!), these could be quite useful as 'control voltages' of sorts. Sine, triangle, square, saw, etc to start - a lot of complex shapes could be constructed from those simple building blocks

going from your example (I need to try this) It looks like we can get a waveform with a complex period by nesting the function

sin = (amplitude, period)=>(t)=>(amplitude* Math.sin(t * period))
o0.osc(sin(20, sin(0.02, 0.5)))

from hydra.

ojack avatar ojack commented on August 9, 2024

I like the idea of control voltages, and the complex periods is exciting. It doesnt seem to work yet...i think because of the hacky way that i am passing in the time variable.. But I am not totally sure and am going to play around later today.

from hydra.

ojack avatar ojack commented on August 9, 2024

ok, it works if the function takes care of the case where it is passed in a function:

sin = (_amplitude, _period)=>(t)=>{
  let period = _period
  let amplitude = _amplitude
  if(typeof _period == 'function') period = _period(t)
  if(typeof _amplitude == 'function') amplitude = _amplitude(t)
  return amplitude*Math.sin(period*t)
}

o0.osc(sin(20, sin(0.02, 0.5)))

I wonder if there is a nicer syntax for this

from hydra.

echophon avatar echophon commented on August 9, 2024

Ah, this makes sense.

It could also be written with a ternary but I'm not sure this qualifies as nicer syntax. It obfuscates it a bit, but I think this adds weight to the idea of predefining some of these functions. Have proper type checking on the built-ins and let people write quick & dirty functions in the editor.

written as a ternary

sin = (_amplitude, _period)=>(t)=>{
  let period = typeof _period == 'function' ? _period(t) : _period
  let amplitude = typeof _amplitude == 'function' ? _amplitude(t) : _amplitude
  return amplitude*Math.sin(period*t)
}

from hydra.

echophon avatar echophon commented on August 9, 2024

In the dev branch of hydra-synth I have included some utility functions for fading and handling arrays of parameters. https://github.com/ojack/hydra-synth/blob/dev/src/timingUtils.js

Now it is possible to do osc([23, 200, 39]).out() and it cycles through the values.
osc([23, 299, 39].fast(2)).out() cycles through them twice as fast.

I'm just now seeing this & the cycling works great. I also got WebMIDI working from the snippet you posted in #26. I wasn't able to get the fadeIn / fadeOut working, but the concept struck me as similar to a lag processor, which might be a reasonable option to easing curves.

A lag processor is another analog control voltage concept & can help create smooth transitions between values much like an easing curve. It might also be useful with WebMIDI as I'm noticing that changing values creates a lot of abrupt, stepped changes, which is not always desirable.

In the abstract, a lag processor works in code by updating a goal value instead of the actual value. The actual value then continuously moves toward the goal, some amount every frame.

from hydra.

ojack avatar ojack commented on August 9, 2024

Continuing from @jarmitage 's comment I really like the idea of being able to load a set of custom functions (both glsl and utility functions) in a boot file or something similar. I think it is really easy to pollute the global namespace and I like the idea of sharing sets of functions specific to a certain purpose.

from hydra.

ojack avatar ojack commented on August 9, 2024

Also, I haven't had a chance to dig into this example by Charlie running tidalCycles mini-notation inside of Hydra, but it looks promising:

https://twitter.com/gibber_cc/status/1145207647190171653

from hydra.

charlieroberts avatar charlieroberts commented on August 9, 2024

Here's the snippet to mess with the mini-notation: https://gist.github.com/charlieroberts/3aa779329c49e10557a8ca66093eeb0e

from hydra.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.