Waveforms
Waveforms consist of a certain number of phases (amplitude steps). Each phase is a value in the range from -BK_MAX_VOLUME
to +BK_MAX_VOLUME
. When playing a note, the waveform and with it its phases are scaled so that they are in the correct pitch. Tracks have predefined waveforms which are typical for old sound chips.
Square Wave
BK_SQUARE
has 16 phases. The duty cycle attribute BK_DUTY_CYCLE
defines the length of the wave peak. This value is 4 by default, which accords to a duty cycle of 25%. The value can range from 1 to 15:
Triangle Wave
BK_TRIANGLE
has 32 phases and is the only waveform which is not affected by the volume. It is either 0 or at its maximum for values greater than 0. This is because some sound chips also had no volume setting for triangle waves.
The waveform is shifted to the left by 8 phases. This is done to use negative amplitudes as well to reduce potential amplitude overflows when mixing the tracks.
To enable the volume attribute’s normal behaviour anyway, the attribute BK_TRIANGLE_IGNORES_VOLUME
can be set to 0:
Noise
Noise is a square wave whose phase amplitudes are randomly either 0 or at their maximum volume. This is controlled by a 16 bit random generator, which means that the noise pattern is repeated after 65536 phases. This can be heard on high notes.
Interestingly, the random pattern contains a part which could be identified as a ghost voice. 👻
Sawtooth Wave
BK_SAWTOOTH
has 7 phases.
TODO
Sine Wave
BK_SINE
has 32 phases.
TODO
Custom Waveforms
Custom waveforms can have an arbitary number of phases, but an absurd high number could create unwanted effects. Numbers around 8 and 32 are optimal. The number of phases does not affect the pitch. However, the waveform itself could contain overtones which would increase the pitch.
The following is an example waveform that sounds like the vocal “A”. It has 13 phases and, for simplification, its amplitude has only a resolution of 4 positive and negative values.
Custom waveforms are wrapped into BKData
objects. These objects can then be set to multiple tracks as BK_WAVEFORM
pointer attributes.
Like all BKData
objects, they must exist as long as some tracks are using them. In the code below the declaration is on the stack only for demonstration. They should be declared globally or wrapped into other objects which exist outside of the stack.
BKDataNormalize
is used to expand the amplitudes to their maximum values of BK_MAX_VOLUME
and -BK_MAX_VOLUME
, respectively. Otherwise the waveform is not audible or the volume range cannot be used completely.
Of course, the phases could already be declared with their maximum amplitudes; this is only for readability.
Unsetting Waveforms
A waveform cannot be unset from a track, instead it has to be set to another one. This could be another custom waveform or a default one: