The class, while handy and efficient, is somewhat specialized and for many of the applications described in this chapter we need something more general. Patch B03.tabread4.pd (Figure 2.13) demonstrates the timbre stretching technique discussed in section 2.4. This is a simple example of a situation where would not have sufficed. There are new classes introduced here:
:
wavetable lookup. As in
, the table is read using
4-point interpolation. But whereas
takes a frequency
as input and automatically reads the waveform in a repeating pattern, the
simpler
expects the table lookup index as input.
If you want to use it to do something repetitious, as in this example, the
input itself has to be a repeating waveform. Like
(and all the other table reading and writing objects),
you can send messages to select which table to use.
:
record an audio signal into a wavetable. In this example the
is used to display the output (although later
on it will be used for all sorts of other things.) Whenever it receives a
``bang" message from the button icon above it,
begins
writing successive samples of its input to the named table.
Patch B03.tabread4.pd shows how to combine a and a object to make a wavetable oscillator. The 's output ranges from 0 to 1 in value. In this case the input wavetable, named ``waveform12", is 131 elements long. The domain for the object is thus from 1 to 129. To adjust the range of the accordingly, we multiply it by the length of the domain (128) so that it reaches between 0 and 128, and then add 1, effectively sliding the interval to the right by one point. This rescaling is accomplished by the and objects between the and the .
With only these four boxes we would have essentially reinvented the class. In this example, however, the multiplication is not by a constant 128 but by a variable amount controlled by the ``squeeze" parameter. The function of the four boxes at the right hand side of the patch is to supply the object with values to scale the by. This makes use of one more new object class:
:
compose a list of two or more elements. The creation arguments establish the
number of arguments, their types (usually numbers) and their initial values.
The inlets (there will be as many as you specified creation arguments) update
the values of the message arguments, and, if the leftmost inlet is changed
(or just triggered with a bang
message), the message is output.
In this patch the arguments are initially 0 and 50, but the number box will
update the value of the first argument, so that, as pictured, the most recent
message to leave the object was ``206 50". The effect of this
on the line~
object below is to ramp to 206 in 50 milliseconds; in
general the output of the line~
object is an audio signal that smoothly
follows the sporadically changing values of the number box labeled ``squeeze".
Finally, 128 is added to the ``squeeze" value; if ``squeeze" takes non-negative values (as the number box in this patch enforces), the range-setting multiplier ranges the phasor by 128 or more. If the value is greater than 128, the effect is that the rescaled phasor spends some fraction of its cycle stuck at the end of the wavetable (which clips its input to 129.) The result is that the waveform is scanned over some fraction of the cycle. As shown, the waveform is squeezed into 128/(128+206) of the cycle, so the spectrum is stretched by a factor of about 1/2.
For simplicity, this patch is subtly different from the example of section
2.4 in that the waveforms are squeezed toward the beginning
of each cycle and not toward the middle. This has the effect of slightly
changing the phase of the various partials of the waveform as it is stretched
and squeezed; if the squeezing factor changes quickly, the corresponding phase
drift will sound like a slight wavering in pitch. This can be avoided by
using a slightly more complicated arrangement: subtracting 1/2 from the
phasor~
, multiply it by 128 or more, and then add 65 instead of one.