pinobatch / pently

Scalable music engine for NES games
zlib License
72 stars 4 forks source link

Compress instrument envelopes without arpeggio #20

Closed pinobatch closed 6 years ago

pinobatch commented 6 years ago

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:

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.

pinobatch commented 6 years ago

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.