A signal you want to listen to -- a signal you send to dac~
-- must be in the amplitude range from -1.0 to +1.0. Any values exceeding those bounds will be clipped off by dac~
(i.e. sharply limited to 1 or -1). This will cause (in most cases pretty objectionable) distortion of the sound. Some objects, such as cycle~
, output values in that same range by default.
The default output of cycle~ has amplitude of 1
To control the level of a signal you simply multiply each sample by a scaling factor. For example, to halve the amplitude of a signal you simply multiply it by 0.5. (Although it would be mathematically equivalent to divide the amplitude of the signal by 2, multiplication is a more efficient computation procedure than division.
Amplitude adjusted by multiplication
If we wish to change the amplitude of a signal continuously over time, we can supply a changing signal in the right inlet of *~
. By continuously changing the value in the right inlet of *~
, we can fade the sound in or out, create a crescendo or diminuendo effect, etc.
However, a sudden drastic change in amplitude would cause a discontinuity in the signal, which would be heard as a noisy click.
Instantaneous change of amplitude causes a noisy distortion of the signal
For that reason it's usually better to modify the amplitude using a signal that changes more gradually with each sample, say in a straight line over the course of several milliseconds.
If, instead of an instantaneous change of amplitude (which can cause an objectionable distortion of the signal), we supply a signal in the right inlet of *~
that changes from 1.0 to 0.5 over the course of 5 milliseconds, we interpolate between the starting amplitude and the target amplitude with each sample, creating a smooth amplitude change.
Linear amplitude change over 5 milliseconds using line~
object functions similarly to the Max object line
. In its left inlet it receives a target value and a time (in ms) to reach that target. line~
calculates the proper intermediate value for each sample in order to change in a straight line from its current value to the target value.
Technical detail: Any change in the over-all amplitude of a signal introduces some amount of distortion during the time when the amplitude is changing. (The shape of the waveform is actually changed during that time, compared with the original signal.) Whether this distortion is objectionable depends on how sudden the change is, how great the change in amplitude is, and how complex the original signal is. A small amount of such distortion introduced into an already complex signal may go largely unnoticed by the listener. Conversely, even a slight distortion of a very pure original signal will add partials to the tone, thus changing its timbre.
In the preceding example, the amplitude of a sinusoidal tone decreased by half (6 dB) in 5 milliseconds. Although one might detect a slight change of timbre as the amplitude drops, the shift is not drastic enough to be heard as a click. If, on the other hand, the amplitude of a sinusoid increases eightfold (18 dB) in 5 ms, the change is drastic enough to be heard as a percussive attack.
An eightfold (18 dB) increase in 5 ms creates a percussive effect
The example patch uses this combination of *~
to make an adjustable amplifier for scaling the amplitude of the oscillator. The pack
object appends a transition time to the target amplitude value, so every change of amplitude will take 100 milliseconds. A number box
for changing the frequency of the oscillator has also been included.
Oscillator with adjustable frequency and amplitude
Notice that the signal network already has default values before any Max message is sent to it. The cycle~
object has a specified frequency of 1000 Hz, and the line~
object has a default initial value of 0. Even if the *~
had a typed-in argument for initializing its right inlet, its right operand would still be 0 because line~
is constantly supplying it that value.
• Use the Amplitude number box
to set the volume to the level you desire, then click on the toggle
marked Audio On/Off
to start the sound. Use the number box
objects to change the frequency and amplitude of the tone. Click on the toggle
again to turn the sound off.
The combination of line~
also helps to avoid the clicks that can occur when the audio is turned on and off. The and ‘on’ and ‘off’ messages from the toggle
are used to fade the volume up to the desired amplitude, or down to 0, just as the or message is sent to dac~
. In that way, the sound is faded in and out gently rather than being turned on instantaneously.
On and off messages fade audio in or out before starting or stopping the DAC
Just before turning audio off, the toggle
is sent to the pack
object to start a 100 ms fade-out of the oscillator's volume. A delay of 100 ms is also introduced before sending the message to dac~
, in order to let the fade-out occur. Just before turning the audio on, the desired amplitude value is triggered, beginning a fade-in of the volume; the fade-in does not actually begin, however, until the dac~
is started -- immediately after, in this case. (In an actual program, the and message
boxes might be hidden from view or encapsulated in a subpatch in order to prevent the user from clicking on them directly.)
Multiplying each sample of an audio signal by some number other than 1 changes its amplitude; therefore the *~
object is effectively an amplifier. A sudden drastic change of amplitude can cause a click, so a more gradual fade of amplitude -- by controlling the amplitude with another signal -- is usually advisable. The line segment signal generator line~
is comparable to the Max object line
and is appropriate for providing a linearly changing value to the signal network. The combination of line~
can be used to make an envelope
for controlling the over-all amplitude of a signal.
Table lookup oscillator
Audio output and on/off
Linear ramp generator