Classlib: Simplify Function:plot 'dur' redundancy
Purpose and Motivation
See https://scsynth.org/t/why-are-the-multiple-plots-in-a-routine-affected-by-the-last-plot-duration-when-using-a-single-function-defined-as-a-variable/8836
(
s.waitForBoot {
var freq = 440, sig = { SinOsc.ar };
sig.plot(freq.reciprocal * 9, bounds: Rect(0, 250, 400, 250)); // plot 1.
sig.plot(freq.reciprocal, bounds: Rect(0, 530, 400, 250)) // plot 2.
}
)
You would expect the durations of the two plots to be independent, but in fact, the signal of the longer plot (plot 1) is truncated.
- Plot 1: Graph covers 20 ms but only the first 2.2 ms show a signal.
- Plot 2: Graph covers 2.2 ms and is fully populated.
Analysis
Function:asBuffer redundantly encodes the plot duration twice: once in the buffer size, and again in a Line with doneAction: 2. The latter is hardcoded as a constant in the SynthDef. Because it's hardcoded, you would need two distinct SynthDefs to render both plots correctly. However, the SynthDefs are named after the function's hash. There is only one function object, so both SynthDefs have the same name. Therefore, the last SynthDef to be sent clobbers the earlier ones. Then you end up with the last-requested plot duration being applied to all the buffers, even if those buffers are not the same size.
So it's a classic case of redundancy in the code design coming back to bite you.
The Line is unnecessary, because the synth already knows the duration, from the buffer. So it's better to delete the Line, and just apply doneAction: 2 to the RecordBuf.
Types of changes
- Bug fix
To-do list
- [x] Code is tested
- [x] All tests are passing
- ~~[ ] Updated documentation~~
- [x] This PR is ready for review
Nice catch! Looks good. I'll circle back around and approve in a few days if there aren't any concerns raised in the meantime...