Skip to content

Conversation

@krzykos
Copy link

@krzykos krzykos commented Apr 12, 2021

Add additional MOD format support

The classic MOD format is quite straightforward - file has no header and only 15 samples.
As a result, the data offsets are changed. Examples:

The Chiptracker MOD is more complex.
It used patterns per track, so the pattern structures are different. The adapted UI now shows data per song position, not per pattern number.
Also the 4-byte event encoding is much simpler, but on loading it gets encoded back to avoid major rework. Still it contains the same information.
Some resources about this format:

Copy link
Owner

@electronoora electronoora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Tested by playing some of Karsten Obarski's classic SoundTracker tunes - works great!

Copy link
Owner

@electronoora electronoora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested with one of the songs from Dojo Dan and noticed that the looping flute sample sounds a bit odd:

https://mod-staging.haxor.fi/mod.ORIENTALEV3.CHIP

I'm not entirely familiar with the ChipTracker format or libxmp, but it seems like maybe the loop start point is calculated differently.

ChipTracker:
https://github.com/libxmp/libxmp/blob/master/src/loaders/chip_load.c#L130

ProTracker:
https://github.com/electronoora/webaudio-mod-player/blob/master/js/pt.js#L221
https://github.com/libxmp/libxmp/blob/master/src/loaders/mod_load.c#L521

@electronoora
Copy link
Owner

Also - sorry for responding so late. Completely missed that there were open PRs. :)

@electronoora
Copy link
Owner

Seems like SoundTracker format uses also a loop start point in bytes, as opposed to words like in ProTracker. The looped samples here have the same issue as the Dojo Dan song:

https://mod-staging.haxor.fi/mod.amegas

@krzykos
Copy link
Author

krzykos commented Feb 8, 2022

Thanks for the reply!

Tested with one of the songs from Dojo Dan and noticed that the looping flute sample sounds a bit odd:

https://mod-staging.haxor.fi/mod.ORIENTALEV3.CHIP

I totally agree with that issue.
I must have missed it. I remember testing on LEV1 all the time :D

@krzykos
Copy link
Author

krzykos commented Feb 8, 2022

My fork actually got a little bit further - you can check out the master branch, which is deployed to https://music.cryptofolio.live/

I'm afraid I don't have time to work on this PR any more. Besides you've done the analysis, which is most of the work. If you're right, then the fix is trivial :)

My next project is https://gamus.space/ and eats up hell lots of time...
That's why I don't want to get back to this PR.
Feel free to take it and make any changes necessary (in any order, editing allowed)
And let me know if you manage to fix LEV3 :)
BTW. LEV4 has a similar issue - probably the same cause.

@sholwe
Copy link

sholwe commented Feb 9, 2022

FWIW, Gamus doesn't seem to work at all on Chrome/Linux anymore.

@krzykos
Copy link
Author

krzykos commented Feb 23, 2022

@sholwe fixed
Next time please use the bugtracker https://github.com/gamus-space/player/issues

@krzykos
Copy link
Author

krzykos commented Feb 23, 2022

During recent days I've been playing with S3M and I found out that

  • there are some bugs
  • the PR broke displaying notes

Workaround - undoing this change restores proper notes:

diff --git a/js/ui.js b/js/ui.js
index b4ce19a..45f23cc 100644
--- a/js/ui.js
+++ b/js/ui.js
@@ -260,11 +260,11 @@ function updateUI(timestamp)
       $("#odd-channels").html(txt1);
     } else if (window.moduleVis==1) {
       if (oldpos>=0 && oldrow>=0) $(".currentrow").removeClass("currentrow");
-      $("#pattern"+hb(mod.position)+"_row"+hb(mod.row)).addClass("currentrow");
-      $("#pattern"+hb(mod.position)).scrollTop(mod.row*16);
+      $("#pattern"+hb(mod.currentpattern())+"_row"+hb(mod.row)).addClass("currentrow");
+      $("#pattern"+hb(mod.currentpattern())).scrollTop(mod.row*16);
       if (oldpos != mod.position) {
         if (oldpos>=0) $(".currentpattern").removeClass("currentpattern");
-        $("#pattern"+hb(mod.position)).addClass("currentpattern");
+        $("#pattern"+hb(mod.currentpattern())).addClass("currentpattern");
       }
     }

@@ -384,7 +384,7 @@ $(document).ready(function() {
     }

     var pd="";
-    for(p=0;p<this.songlen;p++) {
+    for(p=0;p<this.patterns;p++) {
       var pp, pdata;
       pd+="<div class=\"patterndata\" id=\"pattern"+hb(p)+"\">";
       for(i=0; i<12; i++) pd+="\n";

@krzykos
Copy link
Author

krzykos commented Feb 23, 2022

That's the proper solution to the note problem for S3M and XM:

diff --git a/js/player.js b/js/player.js
index 26d0135..65b0354 100644
--- a/js/player.js
+++ b/js/player.js
@@ -336,13 +336,13 @@ Modplayer.prototype.patterndata = function(pn)
       }
     }
   } else if (this.format=='s3m') {
-    patt=new Uint8Array(this.player.pattern[pn]);
+    patt=new Uint8Array(this.player.pattern[this.player.patterntable[pn]]);
     for(i=0;i<64;i++) for(c=0;c<this.player.channels;c++) {
       if (patt[i*5*this.channels+c*5+3]==255) patt[i*5*this.channels+c*5+3]=0x2e;
       else patt[i*5*this.channels+c*5+3]+=0x40;
     }
   } else if (this.format=='xm') {
-    patt=new Uint8Array(this.player.pattern[pn]);
+    patt=new Uint8Array(this.player.pattern[this.player.patterntable[pn]]);
     for(i=0;i<this.player.patternlen[pn];i++) for(c=0;c<this.player.channels;c++) {
       if (patt[i*5*this.channels+c*5+0]<97)
         patt[i*5*this.channels+c*5+0]=(patt[i*5*this.channels+c*5+0]%12)|(Math.floor(patt[i*5*this.channels+c*5+0]/12)<<4);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants