Open dy opened 7 years ago
hmm...
i like the idea of being able to pass in either a parameter value or a "stream of parameter values". so in a pure functional approach the "Alternative way" makes the most sense, it's basically a source stream. but if we think AudioParam is a good way to be a source stream i can imagine we accept that as a parameter too.
@mmckegg do you have any thoughts here?
Have had nothing but problems with AudioParam
in Loop Drop. I don't think it solves the problem very well.
I would suggest a setter that accepts Number
values or Stream
, and adapts accordingly. If you passed it a stream, it would buffer up frame lengths and pass this to the audio function (then the function can choose k-rate or a-rate). You'll be able to use existing audio generator/transforms and plumbing to create the automations. The only shared state (or implicit knowledge) needed would be the sample rate.
I am pretty sure using the sample rate for synchronisation would work, but yeah, without a central clock, things could be a little floaty and non-deterministic... needs to be experimented with.
That’s interesting - to use other audio sources for creating params automation, that allows for easy modulations. In that, params may take sync source form, like audio-oscillator, -generator etc. I guess if we add audio-adsr and audio-sequence/MIDI stream, we cover most of the modular synthesis cases. Like
let lfo = Sine({
frequency: 1.08
});
let osc = Sine({
frequency: 440,
detune: lfo
});
//...pipe oscillator to output etc
Induced by https://github.com/audiojs/audio-gain/pull/9.
Many streams take in params for processing:
How do we change these params during processing?
There are a couple of points to consider. First off, param value can be fixed for a frame (a-rate) or per sample (k-rate). In case of gain, fixing volume for a frame may cause noticeable steps if volume changes significantly next frame, because unlike biquad filter, it has no "elasticity". At the same time making it k-rate would cause overhead if user liked to smoothly fade-in or fade-out, for example. It would force him to automate each value of volume manually.
Web-Audio-API guys use AudioParam for that, and there is nice pseudo-audio-param for that purpose (it is tiny!). It may solve the problem of setting/automating params, as well as add smoothing to their change, which would make audio behave more naturally.
How should we expose params?
We could set them as a returned function’s property, like now it is done with
end
method:The problem with this approach is that it forces us tracking
time
within streams. It would be nice to avoid some audio-context mediator, following "independent" packages approach. Audio-generator, for example, trackstime
from the moment of the first frame sent. We can set thattime
property straight on AudioBuffer.Another possible option - passing AudioParam instance to options of a stream. In that case components do not depend on pseudo-audio-param and can operate in "static" mode, like they do now. If user wants to change some param, he should pass AudioParam instance.
Alternative way
Third, and really easier way - just passing a function as a param value to options, like
That leaves time tracking, automation etc up to user.
Really appreciate your thoughts guys @audiojs/devs