Closed stevesims closed 1 year ago
There are a few different approaches for envelope support that we could go with.
My inclination is to use 2.
Approach 1 makes for slightly less efficient note playing, and more complex code on the z80 side. Approach 3 may has a slight advantage for reusability, but that is fairly minimal and the extra complexity probably isn't worth it.
The Sustain value described here is very simplistic, and would mean that all sounds played on a channel with such an envelope applied would play back at the sustain value specified and thus be of uniform volume.
There are potentially other ways to interpret sustain...
We could use the sustain value as a modifier. The most simplistic version of that would be to set the actual sustain phase volume level as noteVolume + sustainValue
. Alternatively it could be interpreted as a proportional value, essentially a fraction to apply to the note volume.
Supporting other alternate interpretations of how to deal with sustain will most likely be handled by specifying different envelope types, i.e. different ADSR envelope variants.
Another possibility for different envelope types could be to support different easing functions when transitioning between volume levels (a bit like how transitions/animations can work in CSS)... This idea may be a step too far though. 😁
Something to consider here is the behaviour when setting an envelope on a channel that is already busy playing a sound. Do we want the envelope to be applied immediately, and thus applied to the currently playing sound, or only for the next sound? Or do we just ignore the request as the channel is busy?
My inclination is to support at least "immediate", but also consider supporting "next".
volume envelope now supported.
the volume envelope VDU command accepts a type byte, with zero indicating "none", and 1 to specify a simple ADSR envelope.
for an ADSR envelope the command will then look for additional data as parameters to specify the envelope, which are in order: attack, 16-bit value, time in ms to reach specified volume level decay, 16-bit value, time in ms to go to sustain level sustain, 8-bit value, modifier for sustain volume level, centred on 127 release, 16-bit value, time in ms to release
volume level for the sustain phase is calculated as (baseVolume * sustain)/127 which allows for the sustain phase to potentially be louder than the specified volume level
envelope is always applied on playback when one has been set, which has a few important effects.
firstly when triggering an indefinite note playback (either by playing a note with a duration of -1, or setting a volume level on a silenced channel) the attack and decay phases will happen, and the sound will stay at the sustain level until the volume set to zero, which will trigger the "release" phase. if immediate silencing of a channel is wanted then the envelope should be removed.
secondly the "attack+decay" time becomes a minimum duration for a note. using the "play" command with a duration of zero will therefore no longer be silent.
the "release" phase is not included in the note duration, and is interruptible, i.e. during "release" a new note can be played.
Currently the audio system offered by the VDP is simplistic - a note being played is instantly set to its specified volume, and when the duration is complete the volume is set to zero. This doesn't allow for much character...
It is common for sound generation/synthesis systems to support applying an envelope to the volume of a note. The most common envelope type is ADSR, Attack, Decay, Sustain and Release, named after the phases the volume level goes thru on playback.
Note playback using an ADSR envelope requires four values to specify how playback should proceed:
NB there are many other types of volume envelope used in sound synthesis, ADSR is just the most common. One such example is the variation on ADSR implemented as part of the original BBC Micro's ENVELOPE command where the sustain phase could also ramp the volume level. We should design our volume envelope system to allow for support different types of envelope to be supported in the future.