JavaScript player for SoundTracker/Noisetracker mod files using the webaudio AudioWorklet API.
For a demo, head over here.
modplayer-js requires a browser that supports the ScriptProcessNode API and will make use of the new AudioWorklet API if it's detected (as I'm publishing it only Chrome supports it).
The native AudioWorklet
API is used in these browsers:
- Chrome 70 (OSX, Windows)
Modplayer-js will fall back to the deprecated ScriptProcessorNode
API in these browsers:
- Safari 11.1.2 (OSX & iOS)
- Firefox 62.0 (OSX)
- Edge 42.17134.4071.0 (Xbox One, stuttering audio)
- Edge 42 17134.1.0 (Windows 10, stuttering audio)
- Amiga 4 channel Sountracker/Noisetracker mod files with 4 channels and 15-31 instruments
- Stereo playback (channels 0 & 3 goes to the left chan, 1 & 2 to the right, just like on a real Amiga)
- LowPass filter (not sure it sounds right)
- Individual Spectrum vizualizers for each channel (AudioWorklet mode only)
- Ability to mute any of the 4 module channels (AudioWorklet only)
- 26 great modules of various styles and times are downloaded from The Mod Archive
Most note effects should be supported, including extended ones.
ModPlayer JS makes use of the following piece of software:
- The User Interface is built using Material Design Lite
- The AudioWorklet polyfill is used to stay compatible with browsers that do not support the audio render thread API
- Spectrum display is based on Audio DSP Background by @Acarabott
- get-float-time-domain-data was written by github.com/mohayonao (needed for Safari)
I also heavily used MilkyTracker and webaudio-mod-player - which plays lot of module formats with high fidelity - to track down some timing bugs.
modplayer-js only needs a webserver, which can be installed by typing npm install
and then http-server
.
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.
This is because for some unknown reason, on Xbox One Edge, the audioworklet polyfill refuses to execute ES6 code.
Modules are like MIDI files but with custom sound samples instead of builtin synth files.
Modules produce sound by playing included samples at a specific rate: this simulates the concept of note. Even though included sounds are encoded at a specific rate, this information isn't saved into the module file.
Instead of playing at a specific rate, a period
is used during which the same sample is played. This is directly reminiscent of the Amiga's hardware and more specfically the Paula sound chip which is responsible for playing sound in the Amiga.
To reproduce the original sound the mod creator has to play it at the note which would play it at the same rate as it was encoded.
Soundtracker modules have 4 voices which can be independently played with a specific period and volume.
In addition to the notion of period, there is a speed at which tracks are played which was again close to the Amiga's hardware because it was synced to the monitor's refresh rate: 50hz for PAL and 60hz for NTSC.
This formula gives the speed:
7093789.2 / ((period * 2) * mixingRate)
Original Soundtracker mod files only supported 4 channels and 15 instruments. Sample length was limited to 9,999 bytes and sample resolution was only 8bit but it was quickly extended to support 31 instruments and no special limit on sample length.
With the advent of PC sound cards with better sound capabilites (Gravis Ultra Sound could mix as many as 32 channels in hardware in 1993), the mod format was extended with more channels, more effects, 16 bit samples...
New formats were also created: S3M, IT,...
Even though its use is very limited today thanks to virtually unlimited computing power and storage size, it's amazing what can be done with only module files.
That's why it's still in use today: mostly in the demo scene
, and in some rare games.
The original Sountracker format is quite simple: it starts by listing the mod's title, padded to 20 ASCII characters: there isn't even a magic number.
Then samples information is stored:
Offset | Information | Size (bytes) |
---|---|---|
0 | Sample name | 22 |
22 | Sample Length | 2 |
24 | Finetune | 1 |
25 | Volume | 1 |
26 | Repeat Start | 2 |
28 | Repeat End | 2 |
Then comes the patterns data: first the list of positions and then each patterns information which is encoded: each note information takes 4 bytes. Since there are 64 rows and 4 channels, this means a pattern takes exactly 64 * 4 * 4 = 1024 bytes
.
Last but not least, sample data is stored, uncompressed in LPCM 8bit format.
More information can be found in the original specs file (which was written in 1988: ouch!).
No file is hosted in GitHub, all modules are downloaded from The Mod Archive and are licensed under the Mod Archive Distribution License
- agony.mod: music from Amiga game Agony by Tim Wright
- bigtime.mod: Björk Big Time Sensuality remix from 1994 by ISO from Axis group, appeared in the Big Time Sensuality demo
- cannonfodder.mod: music from Cannon Fodder Amiga game by John Hare / Richard Joseph
- desert_strike.mod: music from Desert Strike Amiga game by Jason Whitley
- LotusII.mod: music from Lotus II game by Barry Leitch
- projectx.mod: music from Project-X Amiga game by Allister Brimble
- silkworm.mod: music from Silkworm Amiga game by Barry Leitch