Hi!
There are a couple of simple answers, and also some thoughts about interpolation that you might not need to worry about right now (but you might).
If the number of points in your time series is a power of 2, you can convert the time series to wavetable format and use the Osc family:
s.boot;
// small amount of white noise
~samples = Signal.fill(16, { 1.0.rand2 });
b = Buffer.sendCollection(s, ~samples.asWavetable, 1);
a = { |bufnum|
var freq = MouseX.kr(50, 500, 1);
(Osc.ar(bufnum, freq) * 0.1).dup
}.play(args: [bufnum: b]);
a.free;
The Osc family:
- Osc: Single wavetable oscillator with linear interpolation.
- COsc: Chorusing wavetable oscillator (linear interpolation).
- VOsc: Crossfading among a series of wavetables (linear interpolation).
- VOsc3: 3 wavetable oscillators at different frequencies, that can crossfade across multiple wavetables (linear interpolation).
- Note: The crossfade in VOsc and VOsc3 means that you have to have at least two wavetables – they cannot be used with a single buffer.
Now the concern:
The built-in wavetable oscillators use linear interpolation. Depending on the wavetable’s spectrum, this could introduce noise (maybe more than you expected). My example above is kind of a worst case for this, where the wavetable has a lot of high frequencies. We can contrast linear vs cubic interpolation with the same wavetable samples.
If it looks like the lower plot will sound smoother, in fact, that’s exactly how it sounds.
The built-in wavetable oscillators can’t be switched to use cubic interpolation, but you can make a cubic interpolation oscillator by running the phase yourself, and BufRd-ing a non-wavetable-format buffer. (Osc requires .asWavetable; the Phasor/BufRd approach is incompatible with .asWavetable.)
c = Buffer.sendCollection(s, ~samples, 1);
a = { |bufnum|
var freq = MouseX.kr(50, 500, 1);
var phase = Phasor.ar(0, freq * SampleDur.ir, 0, 1);
var frames = BufFrames.kr(bufnum);
(BufRd.ar(1, bufnum, phase * frames, interpolation: 4) * 0.1).dup
}.play(args: [bufnum: c]);
a.free;
Osc uses less CPU and sounds worse – in the 2000-aughts, saving CPU cycles made a big difference. Modern CPUs are fast enough that I just go directly to cubic interpolation at this point.
If your time series isn’t a power of two number of samples, then you’d have two choices: 1/ resample it to a power of two (resamp1) and use the Osc family; or 2/ use the Phasor/BufRd approach.
hjh