keithclark / ZzFXM

A super small music generator for use in size-limited JavaScript productions
https://keithclark.github.io/ZzFXM/
MIT License
416 stars 33 forks source link

Tracker - arpeggio, vibrato, tremolo? #16

Open elliot-nelson opened 3 years ago

elliot-nelson commented 3 years ago

The zzfxm lib and tracker are both amazing projects, but I think they are missing classic tracker effects (particularly slide and arpeggio) if we want to be able to craft classic chiptune sounds.

This might be considered more than one ticket, we can break it up if need be, but this is what I'd love to see:

  1. Add support for channel effects to the zzfxm music player. If these features add significant space, maybe it could be crafted as an add-in (if you don't include zzfxm-effects.js, then your song would still play but no effects would do anything, for example). That way people can opt for the tiniest possible zzfxm or the slightly larger zzfxm.

  2. Add support for effects in the Tracker. What I would like to see is updating the controls more like a classic tracker where pressing left/right arrow keys moves between two columns per channel (Note and Effect). So, if you are sitting on the note C-2, you can tap right arrow to move to the Effect and then type "A47" to play a CEG arpeggio. Pressing "DEL/Backspace" should delete the effect if on the effect column, or the note if under the note column. Etc. etc.

I'd also be willing to chip in a bit, if you think there's room to do so!

keithclark commented 3 years ago

I'm open to any improvements/suggestions that make ZzFXM or the tracker better. The only thing to keep in mind is this is targeted at size limited productions, such as JS13kGames, which is why it only offers a limited set of features.

Perhaps the best place to begin is to explore how to add the additional data required to get these effects working to the format without over inflating the size of song data?

As for chipping in, go for it!

elliot-nelson commented 3 years ago

According to the current spec in the README, decimal values 1-36 are considered notes. Probably the easiest thing to do is allow values 100+ to mean "note effects", and whenever the player encounters one of these values, it modifies the next note the player will process. (This means it is stored in reverse of the way you'd read it on the Tracker screen, but I suspect this will make the Player code much simpler.)

So for example, this classic song would still be valid:

[
    13,
    13.5,
    14,
    13,
    0.5,
    0,
    13
]

But now you could add various effects:

[
    137, 13,
    13.5,
    137, 14,
    204, 13,
    0.5,
    0,
    137, 13
]

I think this has the benefit that existing songs will play without changes in the new version, and, the only change to the existing code would be to ensure it ignores notes higher than 99. (This would allow all the "effect processing" to be add-on modules, potentially even per-effect, so the user only needs to include code for the effects they actually use!)

As far as the effects themselves, I'd base the formatting on something like http://famitracker.com/wiki/index.php?title=Effect_list (but probably fewer effects)... I think the big tickets are Arpeggio, Slide Up/Down, Volume Slide Up/Down, Vibrato, Tremolo, and maybe Portamento. So maybe 147 would mean "the next note is arpeggio with +4 and +7", and 806 would mean "automatic portamento with speed 06" (I have no idea what speed 06 means, I'll need to dig on existing tracker implementations to see what this is actually supposed to sound like and try to mimic it).