I tend to think of sound in terms of the spectrum (the continuous Fourier transform) whenever it makes sense so I regard the impulse train as the second simplest* waveform after the pure sine wave. Most of the practical waveforms lie between these two extremes and the simplest way to go between them is integration.
Starting with the impulse train:
Blit220 by frostburn
if we simply integrate we will get something like this:
which isn't a periodic waveform. It's actually the floor function. What we need to do is to DC-block our wave forms before integration to keep the integral from "blowing up". So we subtract 1 from the impulse train, integrate and end up with:
saw(t) = 2(t - floor(t + 0.5))
Saw220 by frostburn Subtracting two saws 180° apart gives us a square wave:
Square220 by frostburn
Integrating this we get a triangle wave:
Triangle220 by frostburn
We could also subtract two saw waves with different phase shifts to get different kinds of rectangular waves. In terms of normalization there are two ways that make sense. The simpler one is
pulse(t, duty) = bool(t - floor(t) < duty),
a wave that is 1 for the duty cycle and 0 otherwise:Pulse08 220 by frostburn
The second normalization is DC-blocked and maintains the loudness of the signal, that is the energy, that is the integral of the square of the signal over time:
square(t, duty) = sqrt( (1 - duty)/duty ) if t - floor(t) < duty
-sqrt( duty/(1 - duty) ) otherwise
Unfortunately the loudness normalized version blows up when duty approaches zero or unity. In some cases it may make more sense to just use the difference of two saw waves to get a DC-blocked well behaving square wave.The width modulated triangle wave is an easier case because it maintains loudness and peak amplitude at the same time:
triangle(t, width) = 2x/width if x < width/2
-2y/(1 - width) otherwise,
where x = t - floor(t + 0.5),
y = t - floor(t) - 0.5.
Triangle08 220 by frostburn As an interesting detail this definition of triangle reduces to saw at width=1. Now if the square waves integral deserves to be called basic then so does the integral of the saw wave, the parabolic wave:
par(t) = 1/2 - 6 (x - floor(x + 0.5))2,
where x = t - 1/sqrt(12) is shifted so that par(0)=0 and I've already normalized the integral to have unity peak amplitude.Par220 by frostburn
Integrating and normalizing once more we get the cubic oscillator:
cub(t) = sqrt(27) x(1 - 4x2),
where x = t - floor(t + 0.5).
Cub220 by frostburnWe can go on like this forever and once we're done we have the sine wave:
sine(t) = sin(2π t)
Sine220 by frostburnWhile these waveforms are simple and pretty straightforward to implement and use they suffer from aliasing. Aside from the impulse train I rendered the sound clips at 352800 Hz sampling rate and resampled them down to 44100 Hz in Audacity. The careful listener may still be able to pick up a few sampling artifacts even at 8x oversampling.
In the next post we'll learn a little trick to reduce aliasing while also avoiding the Gibbs phenomenon.
*) One might even say that the impulse train is the simplest wave form because its Fourier transform is another impulse train in terms of the spectrum.
No comments:
Post a Comment