4 ms·
In PD, the normal thin cables carry control-rate signals. The thicker cables are the audio-rate cables. Objects like "osc~" and "+~" produce audio-rate signals.
by zebproj 8y ago
In PD, the normal thin cables carry control-rate signals. The thicker cables are the audio-rate cables. Objects like "osc~" and "+~" produce audio-rate signals. Objects like "mtof" and "stripnote" produce control-rate signals.
- jancsika 8y ago> Objects like "mtof" and "stripnote" produce control-rate signals. A theoretical "control-rate" "mtof" object would take its input value and compute a frequency value once every block when DSP is turned on. But that's not what "mtof" does. Instead, it computes the frequency for an inputted MIDI value at the time it receives that value. That time could be once every block, once a minute, a single time when I load the program, at random intervals on Tuesday, or even never. The thin line boxes constitute a kind of visual procedural scripting language. Kind of like shell scripting if pipes could have multiple prongs fanning out into multiple destinations.
- zebproj 8y ago> A theoretical "control-rate" "mtof" object would take its input value and compute a frequency value once every block when DSP is turned on. In Sporth, the "mtof" unit-generator does a MIDI to frequency conversion for every audio sample, thus making it audio rate. Perhaps it is better to think of control-rate signals as input signals rather than output signals. The "osc~" object, for instance, will update the frequency at every audio block. This would be the control rate. In Sporth, oscillator frequency values are updated every sample inside the audio block. > But that's not what "mtof" does. Instead, it computes the frequency for an inputted MIDI value at the time it receives that value. That time could be once every block, once a minute, a single time when I load the program, at random intervals on Tuesday, or even never. The important distinction here is that the resolution can't be smaller than the audio-block size, which in turn defines the control-rate.
- jancsika 8y ago> The "osc~" object, for instance, will update the frequency at every audio block. You're just talking about sending a float from a control object to "osc~", right? To be clear: If "osc~" is receiving a float atom from a control object (thin line), then yes, it will implicitly convert that float to an input vector on block boundaries. If "osc~" is receiving signal data from a DSP object (thick line), every sample of the input is used to calculate every sample of the output. If "osc~" is receiving signal data from "vline~", the user can supple subsample accurate frequency changes to "osc~" bound by the precision of float precision, at the expense of performance.
- ssfrr 8y agoI think the issue of control rate in PD is often confusing for folks, because there isn’t any “control rate” that is fundamental to the language. There are audio rate signals that are processed every block, and there are messages that get handled ASAP when they are received, and are decoupled from the audio rate graph. These messages could be once an hour or once per millisecond. The control rate thing comes up because most PD objects (e.g. osc~) only update their parameters on block boundaries, which creates timing jitter (variable delay between when a message is received and when it takes effect). You could definitely have an audio-rate object that took into account the precise timing of the messages it received and scheduled the parameter changes a constant amount of time in the future, which eliminates jitter at the expense of a fixed latency. The vline~ object is useful for generalizing this approach to any object that can take audio-rate parameters, but there’s no reason you couldn’t make a vosc~ object that had the functionality built in. This is different from supercollider (and I think sound), which have an explicit control rate.
- jancsika 8y ago> The control rate thing comes up because most PD objects (e.g. osc~) only update their parameters on block boundaries, which creates timing jitter (variable delay between when a message is received and when it takes effect). Just to reiterate so that people don't get confused: If you give signal input to "osc~"-- let's say `[noise~]--[osc~]`, then "osc~" will update its frequency parameter every sample. If "osc~" didn't do that it would be a lot cheaper (because you'd only need to do one calculation and copy it 64 times at default blocksize), but you would of course immediately hear the loss in quality. What you are describing is what happens when you send a message containing a single floating point number payload to the input of "osc~." In that case Pd treats that number as if it were a vector of samples all with that same value. That's fast and cheap. > there’s no reason you couldn’t make a vosc~ object that had the functionality built in. You can do that. But it's interesting to dissect it a bit: * "vosc~" would only see a performance bump over `[vline~]--[osc~]` in cases where you aren't sending a signal to the input. (Because if you are sending input, the code that does precision timing of control messages is wasted cycles.) So you'd probably want to make the input a control input that can't take signals. * With "vline~", users can control the ramp by putting more objects in between "vline~" and "osc~". But with "vosc~" they'd be stuck either with the default linear interpolation, or a selection of interpolation schemes that you code into the object. In other words, potential functionality moves from userspace to compiled classspace. Edit: remove duplicated thingy