furnace icon indicating copy to clipboard operation
furnace copied to clipboard

Arpeggio Scheme

Open 0x5066 opened this issue 2 years ago • 7 comments

Forks of FamiTracker (starting with 0CC I believe) have this "Scheme" feature in it's Arpeggio section, where you could input 0 0 x x y y or 0 0 12+x x y y or 0 0 -12+x x y y as a valid command, which would take whatever 0xy parameter was in the tracker view, skipping the arpeggio's own implementation, screenshot attached for clarity:

image

0x5066 avatar Mar 12 '22 00:03 0x5066

Wooooooow that will require a rewrite of the playback routine, dropping Defle compatibility in the process. I might implement it using another way, but this looks too difficult.

tildearrow avatar Mar 12 '22 02:03 tildearrow

It's important to note that, for 0cc compatibility (#478), implementing arp schemes is necessary.

Deflemask compatibility could be maintained, but since Defle doesn't support arp schemes, files using the feature would need to consider this fact when attempting a dmf export.

Files with arp schemes would have to convert each use of the arps into a separate instrument, which would use many extra instruments; convert itself into a 1-speed dmf, which brings up more issues; or simply not allow dmf export when arp schemes are used.

Toonlink8101 avatar May 27 '22 19:05 Toonlink8101

The problem with arp schemes is that it would require a restructuring of the way macros are stored in order to make space for a "formula" value, and it would require me to add a formula (or even script/Lisp?) parser to Furnace...

tildearrow avatar Jun 06 '22 04:06 tildearrow

@tildearrow, I had trouble finding the code that handles the parsing of macros in the source code, but from what I can discern from the software itself, it seems that Furnace already supports some parsing of non-integer values. For example, the looping and release commands are already represented (and stored?) in the macro as a '|' and '/' symbol respectively. If this is the case, parsing characters such as 'x', 'y', or '+' should also be possible.

'+' is probably the easiest of these as the parser only needs to check ahead by one slot to see if a '+' is present. Then, if it is present, it just needs to add the values before and after the '+' and pass that on to whatever executes the macro's values.

For the 'x' and 'y', it would be a bit harder to discern feasibility without seeing the source. Depending on the current implementation of arpeggio macros, it might be possible to have the parser check the values of the current arpeggio effect command and store those values so that it can replace any occurrence of 'x' or 'y' to match the current arpeggio effect.

Or, a more passive approach might be to have the stored replacement values of 'x' or 'y' be set by the effect command handler. That way, the values only need to be reset when an arpeggio effect command is made.

Again, I couldn't find the code that currently parses the arpeggio macro, so I can't speak with much certainty.

Is something like this possible, or have I made false assumptions about the engine?

Toonlink8101 avatar Jun 06 '22 19:06 Toonlink8101

Storage. Furnace represents the loop and release positions as variables in a DivInstrumentMacro:

// this is getting out of hand
struct DivInstrumentMacro {
  String name;
  int val[256];
  unsigned int mode;
  bool open;
  unsigned char len;
  signed char loop;
  signed char rel;

  // the following variables are used by the GUI and not saved in the file
  int vScroll, vZoom;


  explicit DivInstrumentMacro(const String& n, bool initOpen=false):
    name(n),
    mode(0),
    open(initOpen),
    len(0),
    loop(-1),
    rel(-1),
    vScroll(0),
    vZoom(-1) {
    memset(val,0,256*sizeof(int));
  }
};

Macros are stored in raw format rather than an MML string when saving to a file.

The problem here is how would we store a formula? This would require changes to the format which may bring huge slowdowns to the engine (see yky.fur).

tildearrow avatar Jun 07 '22 01:06 tildearrow

Additionally, we run into another issue: differing arpeggio macro implementations. Furnace treats most macros equally - the same code is used to run these and they don't take any parameters. What 0CC is doing requires binding the macro interpreter close to the playback driver, but this is not how Furnace works.

I should rephrase that. Furnace is able to run both arpeggio effect (00xy) and arpeggio macro at the same time. The arpeggio is handled by the DivEngine (sending DIV_CMD_LEGATO to the dispatch) and the arpeggio macro is handled by the DivDispatch. On the other hand, 0CC-FamiTracker apparently cannot run arpeggio effect and arpeggio macro concurrently, which means.... arpeggio macro overrides arpeggio effect...

Implementing arpeggio schemes the 0CC way would require a complete rewrite of the dispatch strategy, breaking DefleMask (and old Furnace) compatibility in the process, and potentially making things messier.

The only way to implement arp schemes in Furnace would be by storing these in the song rather than in the instrument, and adding an effect to select the current arp scheme, but then this is not how 0CC works...

tildearrow avatar Jun 07 '22 01:06 tildearrow

@tildearrow Firstly, thank you for taking the time to thoroughly explain things. I know that some people would rather be dismissive than have to explain everything.

So, from what I understand, it seems that full 0CC compatibility is off the table, at least to the same extent as Deflemask. With this being the case, it might be more feasible and even more practical to instead add an 0CC import*, similar to the current mod file support.

The only way to implement arp schemes in Furnace would be by storing these in the song rather than in the instrument, and adding an effect to select the current arp scheme, but then this is not how 0CC works...

If arp schemes were implemented in this way, as an effect with some kind of separate interface, similar to wavetables or samples, then 0CC files could be converted into Furnace. Since 0CC (and all versions of Famitracker) only support four effects columns, one of the additional columns supported by Furnace could be used to call the arp scheme command as necessary.

Would this be possible?

*Sidenote: it might be more practical to do the same for other file formats, such as ftm and dnm, or even crazier formats like ahx, midi, xm, or s3m. But, I'm getting ahead of myself...

Toonlink8101 avatar Jun 07 '22 15:06 Toonlink8101

Firstly, thank you for taking the time to thoroughly explain things. I know that some people would rather be dismissive than have to explain everything.

It's rather difficult for me to explain but I try.

So, from what I understand, it seems that full 0CC compatibility is off the table, at least to the same extent as Deflemask. With this being the case, it might be more feasible and even more practical to instead add an 0CC import*, similar to the current mod file support.

Actually, worse than DefleMask. Full DefleMask compatibility is one of Furnace's goals, whereas other tracker compatibility is not. .0cc import is definitely possible (just like .ftm import), but will have its limitations due to drastic differences, like the previously discussed arp schemes.

If arp schemes were implemented in this way, as an effect with some kind of separate interface, similar to wavetables or samples, then 0CC files could be converted into Furnace. Since 0CC (and all versions of Famitracker) only support four effects columns, one of the additional columns supported by Furnace could be used to call the arp scheme command as necessary.

This could be a possibility, but then 0CC's arp schemes have loop and release points (which Furnace's won't).

Would this be possible?

Partially.

*Sidenote: it might be more practical to do the same for other file formats, such as ftm and dnm, or even crazier formats like ahx, midi, xm, or s3m. But, I'm getting ahead of myself...

This is technically already done by MOD and Future Composer import.

tildearrow avatar Aug 22 '22 20:08 tildearrow

Whoops

tildearrow avatar Aug 22 '22 20:08 tildearrow

I am going to close this suggestion as won't fix because I am changing the arpeggio code in a way that may or may not be further incompatible with 0CC's arp schemes.

Apologies.

tildearrow avatar Aug 22 '22 20:08 tildearrow