CommandTracker: Mostly ideas for a music tracker sparse file format
CommandTracker: Mostly ideas for a music tracker sparse file format
Given VERAsound will now replace the SAA1099, and given some other conversations on the forums (such as the conversation about envelopes in this post), I opted to take another look at my proposed tracker file format, which you can find here:
https://gitlab.com/m00dawg/commander-x16-programs/-/blob/master/command_tracker/index.md
I've talked about this before on the FB group, but I've opted to stop using FB and thought it would be a better conversation had here anyway.
The main issue is that there are 26 channels so to optimize for storage on playback, a sparse format is probably worth the extra complexity in playback routines. I had the idea of supporting multiple effects since this is a common feature in modern trackers (even FamiTracker has this). That may go by the wayside, but even if each channel only had single volume and effect columns, I came up with 5 bytes per channel for VERASound and FM and 3 bytes for DPCM. So a single row would be 126 bytes and a 64 row pattern would be 8064 bytes! The file format I came up with can support multiple effects per channel, and when you include these it balloons to a staggering 41.6k if I did my math right.
But given even complicated patterns have empty space in them, by using a sparse format these requirements go down considerably. Only rows which have data are defined and, within that, only channels which have data are defined. So a row can be as few as 3 bytes if there's only one channel playing on that row with no effects.
I made an attempt to show the proposal row format here but I can't find a way to insert code blocks and it was really hard to read without a monospace font. So I recommend looking at the link (specifically the sparse patterns link)
The trade-off is a playback routine has to track a lot more things as opposed to just reading a pattern row by row. I don't think it would be too terrible since there could be a row counter and if the current row read is greater than the counter, nothing is done. When the counter equals the current row, it then can parse out the row to do the things. This ignores envelopes and some automatic commands (like how the volume slide works in Famitracker as compared to how it works in Impulse Tracker) as those could be firing while there is no row data.
Figuring out how to efficiently edit pattern data is another task entirely though. If one adds data to a previously empty row, the sparse file would have to be reorganized. The best solution here is having a non-sparse pattern buffer - which would be fine for a dedicated tracker where we have room to move about. But given the space requirements, it means patterns would span multiple pages and that could get interesting when adding in things like envelope tables and things.
I should say I'm not an awesome assembly programmer - just a musician who is very excited about the prospects of a tracker, but given the vast sound capabilities of the X16, it feels like it will take some thought to do well given the "limited" space (which is itself far more than the 8-bit systems of yesteryear). That's why I thought it might be good to try and start the conversation by coming up with at least something that can serve as talking points.
Author of Dreamtracker (https://www.dreamtracker.org/)
Check Out My Band: https://music.victimcache.com/
Check Out My Band: https://music.victimcache.com/
CommandTracker: Mostly ideas for a music tracker sparse file format
Nice. Will do gui, icons etc.
CommandTracker: Mostly ideas for a music tracker sparse file format
4 hours ago, m00dawg said:
I made an attempt to show the proposal row format here but I can't find a way to insert code blocks and it was really hard to read without a monospace font.
The CODE tag here is broken. You can use the BBCODE tag, but blank lines cause weird indentation.
line 1
line 2
line 3
I've taken to just attaching code as text files.
CommandTracker: Mostly ideas for a music tracker sparse file format
Ah thanks for the info! Yeah valid workaround, although the Markdown files are the easiest to see I think. Hopefully interested folk are compelled to click on those since there's support for rendering tables and things. Although Markdown was meant to look "good enough" when viewing as text, so I suppose attaching the raw markdown would work too!
Author of Dreamtracker (https://www.dreamtracker.org/)
Check Out My Band: https://music.victimcache.com/
Check Out My Band: https://music.victimcache.com/
CommandTracker: Mostly ideas for a music tracker sparse file format
1 hour ago, m00dawg said:
Ah thanks for the info! Yeah valid workaround, although the Markdown files are the easiest to see I think. Hopefully interested folk are compelled to click on those since there's support for rendering tables and things. Although Markdown was meant to look "good enough" when viewing as text, so I suppose attaching the raw markdown would work too!
Except I don't know of any commonly-used PC programs that render markdown properly. If you're going to go to those lengths, you might post it on GitHub or something and link to it.
CommandTracker: Mostly ideas for a music tracker sparse file format
36 minutes ago, TomXP411 said:
Except I don't know of any commonly-used PC programs that render markdown properly. If you're going to go to those lengths, you might post it on GitHub or something and link to it.
You mean like the link in my initital post? ? It's Gitlab, but basically the same thing:
https://gitlab.com/m00dawg/commander-x16-programs/-/blob/master/command_tracker/index.md
I actually found out today, kinda by accident, that Atom has a Markdown preview and it seems to work rather well!
Author of Dreamtracker (https://www.dreamtracker.org/)
Check Out My Band: https://music.victimcache.com/
Check Out My Band: https://music.victimcache.com/
- kliepatsch
- Posts: 247
- Joined: Thu Oct 08, 2020 9:54 pm
CommandTracker: Mostly ideas for a music tracker sparse file format
Hi @m00dawg and others,
just as a heads up, I am preparing to publish an early version of my PSG sound engine in the next week or two. I know we are maybe going for slightly different routes because you are really into the tracker format, whereas I am more into the modern style DAW. So there may be a couple of things that probably won't fit into your concept, but if you take my code it may be more a matter of rearranging stuff rather than rewriting everything from scratch. I have made things like multitimbrality, envelopes, volume rescaling and pitch slides (for portamento in my case).
I know it may be more fun to make all this by yourself (it's why I did it in the first place) but if you want some starting point you can take what I made. I will be willing to explain my code and discuss how things would need to be rearranged to suit your needs.
As a clarification: I am currently talking only about the sound engine, NOT the playback mechanism. You can provide the playback mechanism. There an API for using the sound engine. Triggering and stopping notes. It still needs to be extended to support things like volume slides or pitch slides which I would definitely want to be possible with it.
CommandTracker: Mostly ideas for a music tracker sparse file format
Actually on the contrary, while it may be fun to do all this myself, that's a pretty big lift! And the ultimate goal for me is having a tracker on the X16 so I can make music with it. Once there is a MIDI interface, perhaps in tandem with a modern DAW; but I'm looking forward to the offline isolation of a dedicated tracker running right off the X16. I suppose there's a small part of Nostalgia at work there but not much as I do find using my modern DAW can be pretty distracting. Even if I just unplug the damn network cable, Windows still wants to make sure that I know that my online account isn't sync'd just in case I changed my mind, in addition to myriad of other nonsense. So yeah, anything that gets the closer to the finish line I'm all about!
The portmento in particular is something I didn't know quite how to implement. I assumed it was similar to what I was thinking a pitch slide would be (in the tracker case, it's a shift and offset is how I thought about it, though I haven't yet looked at, say, Famitracker, to see how it does it) but with a end frequency to shoot for (namely the note that was played).
In any case, when you get down to it, what makes a tracker is mostly the UI and approach. I think the only thing potentially special about a sound engine for it is, like we discussed previously, channels are typically hard set to particular hardware voices where the composer decides how to use what channels. This has benefits for being of being able to saturate channels more. I like I could use PSG channel 1 for both a chip bassdrum, hi-hat, and maybe an arpeggiator within the same track.
The above is no longer true some modern trackers, like Renoise but in the case of the X16 is how I was going to approach it as it's still sort of "standard" when looking at say Famitracker or Deflemask and this makes the file format more straightforward. This concept doesn't really save any screen real-estate either - I think in the case of Renoise, being largely a sampler at the end of the day (though it has VST and MIDI support), it makes a lot of sense, especially with its out of tracker automations it can do.
Not sure how familiar you are with trackers so forgive me if I'm rehashing what you already know, but essentially you define notes and effects on a piano roll using, typically, a concept of instruments. The instruments would set up defaults and be where you might define a default envelope, etc. They make more sense for FM but even with the PSG make sense - you can setup a "pluck" sound that has a short volume envelope on it, optionally along with a PWM envelope to give it a nice timbre for the pluck. Then you might have a bassdrum which is a fast pitch slide down also with a volume envelope.
Then in the patterm data, I tell it what note, octave, instrument, and optional effects I want. Something like:
| VeraSound 01 | V02 | ... | F1 | FM 2 | ... | PCM |
## | -------------------- | --> | | --> | ------------- | | --> |
00 | ... .. .. .. ... ... | C-1 02 | | G-3 | D#2 01 FF M01 | | C-4 |
01 | ... .. .. .. ... ... | C-1 03 | | ... | ... .. .. ... | | ... |
02 | C-4 01 .. .. A37 ... | D#1 02 | | ... | ... .. .. ... | | ... |
03 | ... .. .. 20 ... ... | D-1 02 | | ... | ... .. 50 ... | | ... |
04 | D#4 01 L. 20 A00 V10 | D#1 03 | | D#3 | --- .. .. ... | | ... |
05 | D#4 01 .R 10 D04 V1A | G-1 03 | | ... | ... .. .. D0A | | ... |
06 | ^^^ .. .. .. ... ... | D#1 02 | | ... | ... .. .. ... | | ... |
...
06 | ... .. .. .. ... ... | C-1 .. | | ... | ... .. .. ... | | ... |
My current file format definition allows multiple effects, so there could be D04, G37, ... I'm not sure if I will keep that yet as another way to do combination effects is with macros (or instruments with their own automation if the effects don't need to be modulated). I also though about allow different envelopes to be selected on the tracker data but I need to see how that might fit into the effect column while trying to keep the pattern data small.
I said all that to say a tracker could surely use a sound engine probably without too many modifications? I wonder if any modifications that would be needed might be something that can be added to the engine. It would be pretty amazing if both an X16 tracker and DAW used the same engine. In fact that might not be the only thing that can be shared - a MIDI solution could be one that might be shared by both. A tracker tends to be a little more limited here - one could set it up to output MIDI but that seems like a bit of an odd solve on the X16. It could read incoming MIDI as an alternative means to edit patterns. Primarily for me, I'd like MIDI sync so I can use the X16 is sort of another instrument in my greater orchestra as it were.
I'm super rambling sorry haha I thing long story short, it makes a ton of sense to me for really all the music and sound applications to be able to reuse and share as much code as possible. A tide lifts all boats kinda thing. So yeah I'd be quite interested in learning more about your engine, absolutely!
Author of Dreamtracker (https://www.dreamtracker.org/)
Check Out My Band: https://music.victimcache.com/
Check Out My Band: https://music.victimcache.com/
CommandTracker: Mostly ideas for a music tracker sparse file format
Overriding my previous comment as I made sort of a BIG change which I think could help reduce the amount of bytes for non-zero rows:
| If Note Flag Set | If Vol Flag Set | If Effect Flag Set |
Channel : N/V/E Flags | Note : Octave : Inst | Pan : Vol | Next Effect Flag : Effect # : Effect Data |
5-bits : 3-bits | Nibble : Nibble : Byte | 2-bits : 6-bits | 1-bit : 7-bits : Byte |
So now instead of an effect length, there's flags that explain what the next bytes are. N is note, V is vol, and E is effect. his allows for having rows that are just manipulating notes, volume, effects or all these. So say if we're just manually changing volume, that would only require 2 bytes. Order matters in that, if we have all 3 flags set, the next byte after the flag is the note data, followed by the volume column, then at least one effect (could be more, see below).
Here is where it gets interesting. If the effect flag is set, we know there will be at least one effect, but now there is an effect flag that says if there is another effect defined. This means there could be, in theory, N-effects but the storage requirements are the same - it just means there are now "only" 127 definable effects. That seems like way too many, even with macros, since effects can be unique per sound-chip, though many effects would be common to at least VeraSound and FM (like volume slides, portamento, arpeggiation, etc.).
Author of Dreamtracker (https://www.dreamtracker.org/)
Check Out My Band: https://music.victimcache.com/
Check Out My Band: https://music.victimcache.com/
- kliepatsch
- Posts: 247
- Joined: Thu Oct 08, 2020 9:54 pm
CommandTracker: Mostly ideas for a music tracker sparse file format
5 hours ago, m00dawg said:
I suppose there's a small part of Nostalgia at work there but not much as I do find using my modern DAW can be pretty distracting. Even if I just unplug the damn network cable, Windows still wants to make sure that I know that my online account isn't sync'd just in case I changed my mind, in addition to myriad of other nonsense. So yeah, anything that gets the closer to the finish line I'm all about!
Not so much the distraction for me, but the sheer size/quantity of the tools available. Anyway, seems we're headed in a similar direction there.
Thanks for your explanations of a tracker. I have actually played around with a couple of trackers from the DOS era in order to get an idea what it is like to use one. I didn't finish anything with them but I sort of know the concept of the "effects" and the general feel of a tracker. But it's good to read anyway, so I know that it's exactly that what you are after.
5 hours ago, m00dawg said:
In any case, when you get down to it, what makes a tracker is mostly the UI and approach. I think the only thing potentially special about a sound engine for it is, like we discussed previously, channels are typically hard set to particular hardware voices where the composer decides how to use what channels. This has benefits for being of being able to saturate channels more. I like I could use PSG channel 1 for both a chip bassdrum, hi-hat, and maybe an arpeggiator within the same track.
I think I have mentioned in the other thread that the layout for the synth engine is channel-based, so it is indeed suited for the stuff that you are mentioning. But it won't be a one-to-one representation of the 16 PSG channels. We would be giving away *huge* potential if we would let people only define instruments using 1 oscillator at a time. I mean -- what would you do with 16 independent voices, unless you are going for an orchestra? In my opinion, the 16 voices of the PSG are more than enough to combine several PSG voices into one sound and thereby vastly increase the palette of sounds available.
5 hours ago, m00dawg said:
I said all that to say a tracker could surely use a sound engine probably without too many modifications? I wonder if any modifications that would be needed might be something that can be added to the engine. It would be pretty amazing if both an X16 tracker and DAW used the same engine. In fact that might not be the only thing that can be shared - a MIDI solution could be one that might be shared by both. A tracker tends to be a little more limited here - one could set it up to output MIDI but that seems like a bit of an odd solve on the X16. It could read incoming MIDI as an alternative means to edit patterns. Primarily for me, I'd like MIDI sync so I can use the X16 is sort of another instrument in my greater orchestra as it were.
It's really nice to read that you think it could work!
The same overall engine for a tracker and a piano roll DAW would not be possible. Simply because of the timing differences (piano roll allowing for more flexible timing) and the data format made up of rows and "cells", and the concept of effects. Those would overcomplicate the matter.
However, a shared synth engine seems useful. Sounds could be shared between the platforms (much like presets for NI Massive can be used by both FL Studio users and Renoise users). This would be possible I think.
In its current state, the synth engine doesn't allow for a lot of real-time modulation (such as tracker effects), but it is a high priority for me. My idea is to make pitch bend one channel for modulation that is always available (per voice), and to provide a second channel (much like Modwheel) that can be freely mapped to one of the parameters in the synth engine - and even be remapped during playback, but only one parameter at a time per voice.
This freely available modulation parameter could then be used by the tracker effects to achieve whatever they do.
In other words, e.g. if we have a vibrato effect, the tracker would automatically map the "Modwheel" to vibrato depth and apply the correct values to it. That's how I am currently imagining it.
Or we leave the abstraction layer of classical "tracker effects" away and simply do something like:
bit 7 - pitchbend or modwheel
bit 6 - set level or slope
bit 5 - remap modwheel destination
bits 4 to 0 - data
EDIT: one bit should also tell us whether there will be another modulation statement after this. (Much like in your post above). Both slopes and levels should be able to be set at the same time.
Additional bytes for more data as needed by the settings in bits 7 to 5 (e.g. pitchbend setting should be accurate. And I don't know how many bytes a remapping of the modwheel would take, yet)
I don't know how that would suit a proper tracker user ?
Technically, there is nothing that holds us back from adding more modulation complexity, but it will quickly become CPU intensive. That's when we need to decide: do we want a software that keeps running smoothly under all possible circumstances, or do we tell the user: "Use at your own risk" -- don't modulate too much at the same time, or playback stuttering might become an issue. I have done the math. 16 voice playback seems possible at 8 MHz, even with some modulation going on. But we have to be clever...
5 hours ago, m00dawg said:
The portmento in particular is something I didn't know quite how to implement. I assumed it was similar to what I was thinking a pitch slide would be (in the tracker case, it's a shift and offset is how I thought about it, though I haven't yet looked at, say, Famitracker, to see how it does it) but with a end frequency to shoot for (namely the note that was played).
That's it! The details depend on whether you want a constant rate or a constant time portamento. In any case, you will keep sliding until you hit the target and then disable the slide.