Skip to content

Commit ae3f316

Browse files
authored
Modfile fixes (#6)
- REMOVED: modules that do not play correctly yet from the playlist - FIXED: channel.cmd wasn't reset after loading a new mod - FIXED: if channel.length == 2 length seems to be ignored by players (Agony) - FIXED: very old mod files with 15 samples had wrong offsets for patterns/positions (Silkworm) - FIXED: oops, fixed channel swapping in compatibility mode - ADDED: build instructions - ADDED: note about Xbox One special case
1 parent 547fe36 commit ae3f316

File tree

7 files changed

+219
-17
lines changed

7 files changed

+219
-17
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
node_modules
2+
dist

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ ModPlayer JS makes use of the following piece of software:
4242

4343
I also heavily used [MilkyTracker](https://milkytracker.titandemo.org/) and [webaudio-mod-player](https://mod.haxor.fi/) - which plays lot of module formats with high fidelity - to track down some timing bugs.
4444

45+
# Building modplayer-js
46+
47+
modplayer-js only needs a webserver, which can be installed by typing `npm install` and then `http-server`.
48+
49+
If you want to use modplayer-js on an Xbox One, you'll also need to type `npm run build`: this will generate an ES5 version of the `mod-processor.js` file.
50+
51+
This is because for some unknown reason, on Xbox One Edge, the audioworklet polyfill refuses to execute ES6 code.
52+
4553
# Module background
4654

4755
Modules are like MIDI files but with custom sound samples instead of builtin synth files.

js/main.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
var moduleList = [
22
{ file: 'https://api.modarchive.org/downloads.php?moduleid=91286#faggots_universe.mod', author: 'Deelite' },
3-
{ file: 'https://api.modarchive.org/downloads.php?moduleid=168739#neurodancer_-_quasar.mod', author: 'Neurodancer' },
4-
{ file: 'https://api.modarchive.org/downloads.php?moduleid=183672#tax_haven_dry_hump.mod', author: 'Curt Cool' },
53
{ file: 'https://api.modarchive.org/downloads.php?moduleid=182057#h0ffman_-_drop_the_panic.mod', author: 'h0ffman' },
64
{ file: 'https://api.modarchive.org/downloads.php?moduleid=168122#prodigy_-_downtown.mod', author: 'prodigy of oops' },
75
{ file: 'https://api.modarchive.org/downloads.php?moduleid=172266#hoffman_-_the_hunter.mod', author: 'h0ffman' },
86
{ file: 'https://api.modarchive.org/downloads.php?moduleid=65280#variations.mod', author: 'jogeir-liljedahl' },
9-
{ file: 'https://api.modarchive.org/downloads.php?moduleid=166686#wiklund_-_bonfire.mod', author: 'Wiklund' },
7+
// { file: 'https://api.modarchive.org/downloads.php?moduleid=166686#wiklund_-_bonfire.mod', author: 'Wiklund' },
108
{ file: 'https://api.modarchive.org/downloads.php?moduleid=55058#pinball_illusions.mod', author: 'Olof Gustafsson' },
119
{ file: 'https://api.modarchive.org/downloads.php?moduleid=167668#vinnie_-_sweet_dreams.mod', author: 'vinnie/spaceballs' },
1210
{ file: 'https://api.modarchive.org/downloads.php?moduleid=172271#subi-king_of_boggle.mod', author: 'Subi/DESiRE' },
13-
{ file: 'https://api.modarchive.org/downloads.php?moduleid=171416#bass-1107.mod', author: 'Noiseless (cm/ao)' },
11+
// { file: 'https://api.modarchive.org/downloads.php?moduleid=171416#bass-1107.mod', author: 'Noiseless (cm/ao)' },
1412
{ file: 'https://api.modarchive.org/downloads.php?moduleid=168110#punnik_-_drum_bass.mod', author: 'punnik' },
15-
{ file: 'https://api.modarchive.org/downloads.php?moduleid=171616#dan_-_childs_philozophy.mod', author: 'dan / picco' },
13+
// { file: 'https://api.modarchive.org/downloads.php?moduleid=171616#dan_-_childs_philozophy.mod', author: 'dan / picco' },
1614
{ file: 'https://api.modarchive.org/downloads.php?moduleid=119303#boesendorfer_p_s_s.mod', author: 'romeoknight' },
17-
{ file: 'https://api.modarchive.org/downloads.php?moduleid=170637#ghost_in_the_cli.mod', author: 'h0ffman' },
18-
{ file: 'https://api.modarchive.org/downloads.php?moduleid=158057#alf_-_no-mercy.mod', author: 'alf/vtl' },
15+
// { file: 'https://api.modarchive.org/downloads.php?moduleid=170637#ghost_in_the_cli.mod', author: 'h0ffman' },
16+
// { file: 'https://api.modarchive.org/downloads.php?moduleid=158057#alf_-_no-mercy.mod', author: 'alf/vtl' },
1917
{ file: 'https://api.modarchive.org/downloads.php?moduleid=105709#trans_atlantic.mod', author: 'Lizardking'},
2018
{ file: 'https://api.modarchive.org/downloads.php?moduleid=124303#agony_intro.mod', author: 'Tim Wright' },
19+
{ file: 'https://api.modarchive.org/downloads.php?moduleid=168739#neurodancer_-_quasar.mod', author: 'Neurodancer' },
20+
{ file: 'https://api.modarchive.org/downloads.php?moduleid=183672#tax_haven_dry_hump.mod', author: 'Curt Cool' },
2121
{ file: 'https://api.modarchive.org/downloads.php?moduleid=98051#big_time_sensuality.mod', author: 'ISO/Axis Group' },
2222
{ file: 'https://api.modarchive.org/downloads.php?moduleid=34568#CANNONFO.MOD', author: 'John Hare' },
2323
{ file: 'https://api.modarchive.org/downloads.php?moduleid=68835#desert_strike.mod', author: 'Jason Whitley' },

js/mod-processor-es5.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/mod-processor.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ class PTModuleProcessor extends AudioWorkletProcessor{
4646
// pattern data always starts at offset 1084
4747
super();
4848
this.port.onmessage = this.handleMessage.bind(this);
49-
this.patternOffset = 1084;
5049
this.patternLength = 1024;
5150
}
5251

@@ -195,7 +194,8 @@ class PTModuleProcessor extends AudioWorkletProcessor{
195194
vspeed: 0,
196195
vpos: 0,
197196
loopInitiated: false,
198-
id: i
197+
id: i,
198+
cmd: 0
199199
};
200200
if (!this.channels[i]) {
201201
this.channels[i] = channel;
@@ -240,6 +240,12 @@ class PTModuleProcessor extends AudioWorkletProcessor{
240240
// but we stick to good old ST/NT modules
241241
const str = BinUtils.readAscii(this.buffer, 4, 1080);
242242
this.maxSamples = str.match("M.K.") ? 31 : 15;
243+
244+
if (this.maxSamples === 15) {
245+
this.patternOffset = 1080 - 480;
246+
} else {
247+
this.patternOffset = 1084;
248+
}
243249
}
244250

245251
/**
@@ -278,11 +284,12 @@ class PTModuleProcessor extends AudioWorkletProcessor{
278284
this.tick();
279285
for (let chan = 0; chan < this.channels.length; ++chan) {
280286
const channel = this.channels[chan];
281-
const buffer = this.audioWorkletSupport ? outputs[chan][0] : outputs[0][outputChannel];
282287
// select left/right output depending on module channel:
283288
// voices 0,3 go to left channel, 1,2 go to right channel
284289
outputChannel = outputChannel ^ (chan & 1);
285290

291+
const buffer = this.audioWorkletSupport ? outputs[chan][0] : outputs[0][outputChannel];
292+
286293
// TODO: check that no effect can be applied without a note
287294
// otherwise that will have to be moved outside this loop
288295
if (this.newTick && channel.cmd) {
@@ -472,6 +479,10 @@ class PTModuleProcessor extends AudioWorkletProcessor{
472479
// Existing mod players seem to play a sample only once if repeatLength is set to 2
473480
if (sample.repeatLength === 2) {
474481
sample.repeatLength = 0;
482+
// some modules seems to skip the first two bytes for length
483+
if (sample.length === 2) {
484+
sample.length = 0;
485+
}
475486
}
476487

477488
if (sample.repeatLength > sample.length) {
@@ -487,7 +498,8 @@ class PTModuleProcessor extends AudioWorkletProcessor{
487498

488499
getPatternData() {
489500
// pattern data always starts at offset 950
490-
const uint8buffer = new Uint8Array(this.buffer, 950);
501+
const offset = this.maxSamples === 15 ? 470 : 950;
502+
const uint8buffer = new Uint8Array(this.buffer, offset);
491503
this.songLength = uint8buffer[0];
492504
let position = 2;
493505
let max = 0;
@@ -515,7 +527,8 @@ class PTModuleProcessor extends AudioWorkletProcessor{
515527
for (let i = 0; i < this.samples.length; ++i) {
516528
const length = this.samples[i].length,
517529
data = new Float32Array(length),
518-
pcm = new Int8Array(this.buffer, offset, length);
530+
maxLength = (offset + length) > this.buffer.byteLength ? this.buffer.byteLength - offset : length,
531+
pcm = new Int8Array(this.buffer, offset, maxLength);
519532

520533
// convert 8bit pcm format to webaudio format
521534
for (let j = 0; j < length; ++j) {
@@ -524,7 +537,7 @@ class PTModuleProcessor extends AudioWorkletProcessor{
524537

525538
this.samples[i].data = data;
526539

527-
offset += length;
540+
offset += maxLength;
528541
}
529542
}
530543

0 commit comments

Comments
 (0)