Generating Sound
Tracks generate waveforms or play samples. Instruments can be used to create envelopes and effects can be enabled to animate certain track attributes.
Volume
The attribute BK_MASTER_VOLUME
defines the volume at which the audio data is written into the audio buffer (mix volume). It is 0 after initialization and has to be set explicitly. BK_VOLUME
is used to set the loudness of notes and is at its maximum after initialization.
Actually, the two values are interchangable, as they are multiplied by each other.
Playing Notes
A track can only play one note at once. The BK_NOTE
attribute sets the track’s note which is a fixed-point number that allows to use fractional notes.
The constants BK_C_0
to BK_C_8
are values between 0 and 96 and used for readability. Of course, their equivalent integer values can be used as well.
To unset the note, it can either be set to BK_NOTE_RELEASE
or BK_NOTE_MUTE
. The latter has a different behaviour when using instruments; it does not play the envelopes’ release part and mutes the note immediately.
The release constants BK_NOTE_RELEASE
and BK_NOTE_MUTE
must not be multiplied by BK_FINT20_UNIT
.
Generating Audio Data
Audio data is generated by requesting an arbitary number of frames from the generator function BKContextGenerate, which fills a provided buffer with the requested frames, or its variant BKContextGenerateToTime, which outputs the frames to a provided callback.
A call to one of this functions advances each attached track’s time by running its render function. The generated audio data of each tracks is then merged into the audio buffer. Subsequent calls to the generator functions generate the next requested number of frames.
Multiple channels are interleaved into the provided buffer. Which means that the first frame of the left channel is at frames[0]
, the first frame of the right channel at frames[1]
and so on.
Creating a Beat
The context object runs a master clock which has a default tick rate of 240 Hz. Ticks are the heartbeat for effects, instruments and arpeggio notes.
It is recommended to use a beat that is synchronized with the master clock. For this purpose, there are BKDivider objects. They reduce the tick rate of a clock by a given factor and call a provided callback at the specified interval.
For example, initializing a divider object with a value of 24, will call its callback at every 24th tick of the master clock.
The callback function receives two arguments: the first one is an information struct that also contains the divider object, the second one is the user defined pointer given at initialization. The function should always return 0, as there are no other values defined at the moment.
Every clock and divider also has a 0th
tick at the very beginning, which can be used to initialize the track’s values for the first time.
Attributes
The attributes of the track object.
- BK_NOTE
-
Sets the note. The value is a fixed-point number that ranges from
BK_MIN_NOTE
toBK_MAX_NOTE
.To unset the note, it can either be set to
BK_NOTE_RELEASE
orBK_NOTE_MUTE
. The latter has a different behaviour when using instruments; it does not play the envelopes' release part and mutes the note immediately.The release constants
BK_NOTE_RELEASE
andBK_NOTE_MUTE
must not be multiplied byBK_FINT20_UNIT
. - BK_WAVEFORM
-
Sets a waveform.
A custom waveform can be set with the pointer setter function:
- BK_DUTY_CYCLE
-
Sets the duty cycle of the square wave
BK_SQUARE
. The value ranges from 1 to 15. Default is 4. - BK_VOLUME
-
Sets the note volume. The value ranges from 0 to
BK_MAX_VOLUME
. - BK_MASTER_VOLUME
-
Sets the mix volume. The value ranges from 0 to
BK_MAX_VOLUME
. - BK_PANNING
-
Pans the volume to the left if the value is negative, or to the right if the value is positive, respectively. This attribute has only an effect if the context was initialized with exactly 2 channels. The value ranges from
-BK_MAX_VOLUME
toBK_MAX_VOLUME
. - BK_INSTRUMENT
-
Sets the track's instrument.
- BK_SAMPLE
-
Sets the sample to play. It is required, that the track is already attached to a context, otherwise
BKSetPtr
will returnBK_INVALID_STATE
when setting the sample. - BK_PITCH
-
Sets the track's pitch.
Permanently raises or lowers the track's pitch. The value is added to the
BK_NOTE
attribute. Default is 0. - BK_PHASE_WRAP
-
Sets the number of phases at which the waveform is reset.
This is especially interesting for the noise waveform
BK_NOISE
. Other waveforms may sound distorted.The value is reset when a new waveform is set.
- BK_SAMPLE_RANGE
-
Sets the frame range of the sample to play.
This is an array of two integers, in which the first value defines the start offset, and the second one the end offset. The end offset itself is not included in the range.
If an offset is negative, it will be relative to the sample end + 1. So a value of -1 for the range end is sample length itself.
The range is reset when a new sample is set.
The sample is played backwards by switching the two range offsets:
- BK_SAMPLE_REPEAT
-
Loops the sample indefinitely as long as the note is set. If set to
BK_REPEAT
, the sample is reset to the range start when it ends. If set toBK_PALINDROME
, the play direction is reversed when the range boundary is reached. Default isBK_NO_REPEAT
. - BK_SAMPLE_PITCH
-
Sets the sample's pitch. The value is added to the
BK_NOTE
attribute. Default is 0.When setting a new sample object, the
BK_SAMPLE_PITCH
attribute is copied to the track attribute.