{"_id":"@audio/decode-mod","name":"@audio/decode-mod","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@audio/decode-mod","version":"1.0.0","description":"Decode tracker modules — MOD, XM, S3M, IT, MPTM and more — with libopenmpt WASM","type":"module","main":"decode-mod.js","types":"decode-mod.d.ts","exports":{".":"./decode-mod.js","./audio":{"types":"./audio.d.ts","default":"./audio.js"},"./package.json":"./package.json"},"publishConfig":{"access":"public"},"scripts":{"build":"bash build.sh","prepack":"npm run build","test":"node test.js"},"devDependencies":{"tst":"^9.4.0"},"engines":{"node":">=18"},"keywords":["mod","xm","s3m","it","mptm","tracker","protracker","fasttracker","impulse-tracker","chiptune","audio","decode","decoder","wasm","libopenmpt"],"license":"BSD-3-Clause","author":{"name":"audiojs"},"homepage":"https://github.com/audiojs/decode/tree/main/packages/decode-mod","repository":{"type":"git","url":"git+https://github.com/audiojs/decode.git","directory":"packages/decode-mod"},"bugs":{"url":"https://github.com/audiojs/decode/issues"},"audio":"./audio.js","sideEffects":false,"funding":"https://github.com/sponsors/audiojs","gitHead":"c227363046dc3a0308c95ee112f22795c0ac04ca","_id":"@audio/decode-mod@1.0.0","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-tqLhIFdVgokthJjE6UIwFG/LERqBqpp6iYD5wfRFl5g7AppRJMYNHVOQL8SBEfz79lZdmlmOii+KXGvbym2TNg==","shasum":"80b9f314f70b66c77e16e7bc3ea5ca96975bdc14","tarball":"https://registry.npmjs.org/@audio/decode-mod/-/decode-mod-1.0.0.tgz","fileCount":9,"unpackedSize":1428431,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDKQG6T9kMXY+ZjzxAYaL4/YLmuFgFT1lOhF4/3wog79gIhAILDipoknAPlUTI6VQOalf7xOhsEc1/Z61Oo8bBID7LS"}]},"_npmUser":{"name":"dy","email":"df.creative@gmail.com"},"directories":{},"maintainers":[{"name":"jamen","email":"jamenmarz@gmail.com"},{"name":"dfcreative","email":"df.creative@gmail.com"},{"name":"dy","email":"df.creative@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/decode-mod_1.0.0_1787966900630_0.9963013349062597"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-29T01:28:20.462Z","1.0.0":"2026-08-29T01:28:20.789Z","modified":"2026-08-29T01:28:21.017Z"},"maintainers":[{"name":"jamen","email":"jamenmarz@gmail.com"},{"name":"dfcreative","email":"df.creative@gmail.com"},{"name":"dy","email":"df.creative@gmail.com"}],"description":"Decode tracker modules — MOD, XM, S3M, IT, MPTM and more — with libopenmpt WASM","homepage":"https://github.com/audiojs/decode/tree/main/packages/decode-mod","keywords":["mod","xm","s3m","it","mptm","tracker","protracker","fasttracker","impulse-tracker","chiptune","audio","decode","decoder","wasm","libopenmpt"],"repository":{"type":"git","url":"git+https://github.com/audiojs/decode.git","directory":"packages/decode-mod"},"author":{"name":"audiojs"},"bugs":{"url":"https://github.com/audiojs/decode/issues"},"license":"BSD-3-Clause","readme":"# @audio/decode-mod\n\nDecode tracker modules — MOD, XM, S3M, IT, MPTM, and everything else [libopenmpt](https://lib.openmpt.org/libopenmpt/) reads — to PCM float samples.<br>\n[libopenmpt](https://github.com/OpenMPT/openmpt) compiled to a single-file WASM ES module — no side files, loads from any CDN, Node, workers and AudioWorklets.\n\n[![npm install @audio/decode-mod](https://nodei.co/npm/@audio/decode-mod.png?mini=true)](https://npmjs.org/package/@audio/decode-mod/)\n\n```js\nimport decode, { decoder, info } from '@audio/decode-mod'\n\nlet { channelData, sampleRate } = await decode(modBytes)\n\nlet meta = await info(modBytes)\n// { title, artist, type, typeLong, tracker, message, duration, channels, patterns, orders, instruments, samples }\n```\n\nA tracker module is a small program (samples + patterns + a playback sequence), not raw\naudio — libopenmpt is the mixer that renders it. Render params follow libopenmpt's public\nC API (`libopenmpt/libopenmpt.h`): `openmpt_module_create_from_memory2`,\n`openmpt_module_read_float_{mono,stereo,quad}`, `openmpt_module_set_render_param`. A\nmodule is a whole file, not a stream — there's no meaningful partial parse of a truncated\nMOD/XM/S3M/IT, so `decode()` always needs the complete file. `repeat_count` is fixed at 0\n(play once); `duration` is a render-length cap for songs that loop or whose estimated\nlength is impractically long.\n\n```js\nlet { channelData } = await decode(bytes, {\n  sampleRate: 44100,\n  channels: 1,           // mono / stereo / quad (L,R,RL,RR)\n  duration: 30,           // seconds — cap for endless/looping songs\n  interpolation: 2,       // 0 internal default, 1 hold, 2 linear, 4 cubic, 8 windowed sinc\n  stereoSeparation: 150,  // percent, [0,200]\n  gain: -6,                // dB\n})\n```\n\n| Param | Default | |\n|---|---|---|\n| `sampleRate` | `48000` | Output sample rate, Hz |\n| `channels` | `2` | `1` mono, `2` stereo, `4` quad (L,R,RL,RR) |\n| `duration` | libopenmpt's estimate, capped at 600s | Seconds to render; hard cap for endless/looping songs |\n| `interpolation` | `8` | `OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH` — 0 internal default, 1 zero-order hold, 2 linear, 4 cubic, 8 windowed sinc (8 taps) |\n| `stereoSeparation` | `100` | Percent, `[0,200]` |\n| `gain` | — | Master gain, dB |\n\n## API\n\n### `decode(src: Uint8Array | ArrayBuffer, opts?): Promise<AudioData>`\n\nRender a complete module.\n\n### `info(src: Uint8Array | ArrayBuffer): Promise<ModuleInfo>`\n\nRead title/artist/format/duration/channel-and-pattern counts without rendering audio.\n\n### `decoder(opts?): Promise<ModDecoder>`\n\n`{ decode(chunk), flush(), free() }`. `decode(chunk)` expects (and renders) a complete\nfile in one call — a module can't be parsed from a partial buffer. `flush()` returns\nempty (nothing carries over); `free()` is a no-op (no WASM state outlives a single\n`decode()` call). Matches [@audio/decode-qoa](../decode-qoa)'s whole-file shape.\n\n### `AudioData`\n\n```ts\n{ channelData: Float32Array[], sampleRate: number }\n```\n\n## Notes\n\n- MO3 (a separately-compressed OpenMPT container) is not supported: it needs either an\n  external `unmo3` or the bundled minimp3/stb_vorbis/miniz fallback decoders, none of\n  which ship here (see `build.sh`) to keep the WASM small.\n- No volume-ramping/click suppression beyond libopenmpt's own mixer — that's libopenmpt's\n  job, not this package's.\n- Format reference: [ProTracker MOD](https://www.aes.id.au/modformat.html), [FastTracker II XM](https://github.com/milkytracker/MilkyTracker/blob/master/resources/reference/xm-form.txt), [Scream Tracker 3 S3M](https://www.romhacking.net/documents/[177]S3M%20Format.txt), [Impulse Tracker IT](https://github.com/schismtracker/schismtracker/wiki/ITTECH.TXT); libopenmpt's own [C API docs](https://lib.openmpt.org/doc/).\n\n**Use when:** playing back tracker-format chiptunes/game music in the browser, or converting a `.mod`/`.xm`/`.s3m`/`.it` library to PCM/WAV in bulk.\n\n---\n\nPart of [@audio/decode](https://github.com/audiojs/decode) — the decode family umbrella.\n\n## License\n\n[ॐ](https://github.com/krishnized/license/) · [BSD-3-Clause](./LICENSE), same as the bundled [libopenmpt](./LICENSE.libopenmpt).\n","readmeFilename":"README.md","_rev":"1-00ee9ee8d120a037ceeaf82da2be9a80"}