Special offer... Vibratos, everyone, fresh vibratos... Now two channels with vibrato for the price of one!
Vibra is a ZX Spectrum beeper music engine with two tone channels and a
dedicated noise channel. The tone channels support customizable vibrato and
slide effects. The vibrato effect has 7 speed settings, and 255 depth levels.
Effective vibrato speed depends on the note frequency used. Tone channels are
unbalanced, that means the second channel will play at approx. 80% volume of the
first channel.
The noise channel supports 255 pitch levels, and 127 volume levels. Noise
generator is only updated if there is enough free CPU time, so data reads etc.
may affect the noise timbre.
The usual interrupting click drums are absent from this engine, as the available
effects should be sufficient to create drum sounds.
The engine reloads song data on the fly during playback, thus mitigating the
common problem of row transition noises for the most part.
Technical details:
- 12-bit note frequency dividers
- 8-bit noise pitch dividers
- 7-bit noise volume
- 3-bit vibrato speed (relative to note frequency)
- 8-bit vibrato depth
- 8-bit slide speed
- mixing at 7812.5 Hz
download
source (with more detailed comments this time)
No XM converter, sorry. I'll see about getting support for this into MDAL, but I'll probably need to make some adjustments first.
Anyway, aside from the vibrato technique (which is exactly as explained here, the most interesting part might be the use of two (fake) threads, based on Alone Coder's counter-skipping trick. The first updates the channel counters like usual, but also generates "tasks" depending on the state of the counters etc. Tasks are pushed to the stack (if nothing else needs to be done, an "idle" task is pushed). The second thread is switched to with a RET, so it'll execute whatever task is on top of the stack. This can be updating the vibrato/slides, updating the timer, or loading new data. If a given task cannot be completed within the available time frame, another task will be issued (eg. data loading can take up to 6 tasks depending on the situation).
The pitchable noise generator is based on Shiru's noise code, using my el-cheapo, HL-only XOR shift however. Noise quality is a bit weak due to the low mixing rate. There are also some other limitations, namely 1) invalid data can crash the engine and 2) vibratos may cause detune in some (rare) circumstances. Also, a general problem is that the vibrato speed is tied to the note frequency; this makes it impossible to have consistent vibratos across the note range.
Either way, this engine was a major pain in the a*** to write. Been busy with it for almost a whole week, and there's probably still a bug or two in there. Enjoy