Compress instrument envelopes without arpeggio
Closed this issue · 1 comments
Sound effect data can be compressed by setting a row period greater than one. This serves two purposes. One is data reduction. The other is priority scaling, allowing another effect to interrupt the long tail of a slowly decaying effect.
Instrument attack envelopes are similar to sound effects but cannot be compressed. I can think of a few cases where might want to: a long volume envelope that covers both the attack and decay phases of (say) a piano that sustains at volume 1, or a long duty sequence for a pulse instrument.
Currently, each frame of an envelope is 16 bits big endian:
- Bits 15-14 store duty.
- Bits 13-12 are unused.
- Bits 11-8 store volume.
- Bits 7-0 store arpeggio as a signed offset from the note's pitch.
Most frames of most instruments have a 0 arpeggio value, making bits 7-0 redundant. So Pently could reserve bits 13-12 for "frame type", where 0 is what we have now (for backward compatibility reasons), 1 omits the arpeggio and assumes its value is 0, and 2 and 3 mean something to be determined later.
Statistics: Among attack phases in instruments in the current musicseq.pently
, there are about 97 frames with zero pitch and 52 frames with nonzero pitch, the latter mostly in an orchestra hit and a few effects used in argument
. (One of these is argdive
, a fake portamento that can probably be optimized out.) This also gives an estimate of how many bytes we have at porta_not_injected
to interpret a compressed attack.
pentlyas: Common substring elimination will need to operate on .byte
values rather than .dbyt
values.
musicseq: As this is an engine and data format change, no changes here are necessary.
The fix took 9 bytes of code. So if the zero-pitch frames in the attack envelopes of a score's instruments total more than 9 frames, it's a net win.