OPL3 emulator usable as a CLI tool or as a library.
Ported from Yamaha YMF262 (OPL3) Emulator by Robson Cozendey.
Install OPL3 emulator as npm install -g opl3
.
OPL3 emulator v0.4.2
Usage: opl3 <input file> [OPTIONS]
Options:
--mp3 Export to MP3/Lame
--wav Export to WAV
--ogg Export to OGG/Vorbis
--opus Export to OGG/Opus
--mid Export to MIDI
--laa Use LAA format
--mus Use MUS format
--dro Use DRO format
--imf Use IMF format
--raw Use RAW format
-h, --help You read that just now
-i, --genmidi Use external GENMIDI lump (only MUS format)
-n, --normalize PCM audio normalization (default on, turn off with -n0)
-p, --play Play after processing
-o, --output Output directory
Examples:
opl3 D_E1M1.mus
Copyright (c) 2016 IDDQD@doom.js
Accepts glob patterns as input file, like opl3 **/*.mus
.
Use OPL3 and a format handler (like LAA) to process:
var fs = require('fs');
var OPL3 = require('opl3').OPL3;
var LAA = require('opl3').format.LAA;
var Player = require('opl3').Player;
var WAV = require('opl3').WAV;
var player = new Player(LAA);
player.load(fs.readFileSync('./laa/dott logo.laa'), function(err, result){
if (err) return console.log(err);
fs.writeFileSync('./dott.wav', new Buffer(WAV(result, 49700)));
console.log('done!');
});
player.on('progress', function(value){
process.stdout.write('.');
});
To convert source (in LAA format) to raw PCM audio, you can use the Readable
stream approach:
var fs = require('fs');
var OPL3 = require('opl3').OPL3;
var LAA = require('opl3').format.LAA;
var Player = require('opl3').Player;
var player = new Player(LAA);
var file = fs.createWriteStream('./dott.pcm');
player.pipe(file);
player.load(fs.readFileSync('./laa/dott logo.laa'));
player.on('progress', function(value){
process.stdout.write('.');
});
Convert source DRO to MP3 using node-lame:
var fs = require('fs');
var lame = require('lame');
var OPL3 = require('./').OPL3;
var LAA = require('./').format.LAA;
var Player = require('./').Player;
var player = new Player(LAA);
var file = fs.createWriteStream('./dott.mp3');
var encoder = new lame.Encoder({
// input
channels: 2, // 2 channels (left and right)
bitDepth: 16, // 16-bit samples
sampleRate: 49700 // 49,700 Hz sample rate
});
player.pipe(encoder);
encoder.pipe(file);
player.load(fs.readFileSync('./laa/dott logo.laa'));
player.on('progress', function(value){
process.stdout.write('.');
});
OPL3 is also available as a Bower package, install with bower install opl3
.
If installed from Bower, include OPL3 client library as:
<script src="bower_components/opl3/dist/opl3.min.js"></script>
OPL3 client library is supporting UMD. When included as a global script, the library is available as window.OPL3
. If WebWorker
support is available in the browser, the library will automatically use a Worker
to process audio in the background. You can find a browser example here.
The OPL3 client library has a built-in realtime playback feature using Web Audio API, see here. See an example here for realtime playback using pico.js.
Player
is a Readable stream, with extra events.
format
<FormatHandler> Any format handler included inopl3
module or a custom format handler.options
<Object$gt; Optional options object.
options
properties are:
- normalization:
true
to enable normalization (not available in realtime), default isfalse
. - bitDepth: set bit depth of output PCM audio (
16
or32
), default is16
. - bufferSize: size of audio chunk buffer for a single channel, default is
64
for realtime playback. - sampleRate: set sample rate of output PCM audio, default is
49700
. - instruments: only supported in MUS format handler, override default GENMIDI instruments. This can be a raw lump file extracted from a WAD file or a JSON exported with WAD Commander.
- prebuffer: prebuffer size in milliseconds for realtime audio playback, default is
200
. Set this value to-1
if you want to disable any prebuffering. - volume: realtime audio playback starting volume, default is
1
. - disableWorker: force processing on main thread.
buffer
<Buffer> | <ArrayBuffer> Source buffercallback
<Function> Optional callback when the audio processing is finished (including normalization if enabled). The result PCM audio buffer is passed to the callback function as anArrayBuffer
.- Return:
Promise
Load source buffer for audio processing and start processing immediately. Result PCM audio buffer is 2-channel (stereo) 16-bit with 49700Hz sample rate.
buffer
<Buffer> | <ArrayBuffer> Source buffer
Start or continue playing source buffer in realtime. Only available if AudioContext is supported.
Pause realtime audio playback.
ms
<number> milliseconds
Seek realtime audio playback to position in milliseconds.
Get position of realtime audio playback in milliseconds.
Get length of realtime audio in milliseconds. Starts at zero and growing to full length while processing source buffer in background WebWorker
.
Get or set audio volume, from 0
to Infinity
- <number>
The 'progress'
event is emitted on audio processing and returns the current position of the audio processing in percentage (from 0 to 100).
- <ArrayBuffer>
The 'midi'
event is emitted only if the format handler supports MIDI conversion. Emitted only once after audio is fully processed. Returns MIDI file buffer as an ArrayBuffer
.
- <number>
The 'normalization'
event is emitted on audio normalization (if enabled) and returns the current current position of the normalization in percentage (from 0 to 100).
- <number>
The 'gain'
event is emitted after normalization and returns the scale of normalization.
- <number>
Emitted on realtime audio playback, returns audio playback position in milliseconds (same as player.position
).
ConvertTo32Bit
is a Transform
stream class, use this to convert 16-bit PCM audio data to 32-bit.
Normalizer
is a Transform
stream class, use this to normalize PCM audio data. Used internally in Player
class.
See more details here. Use this function to generate WAV audio format buffer from PCM audio data.
- LAA: LucasArts music
- MUS: Doom music
- DRO: DosBox RAW OPL
- IMF: Id Music Format
- RAW: Rdos Raw OPL Capture
The OPL3 library includes GENMIDI lump from shareware Doom as the default instrument set. You can override this in the CLI tool and in the Player
class as well.
Use opl3 doom2/*.mus --genmidi DOOM2.OP2
to inject the DOOM2.OP2
GENMIDI lump file into the MUS format handler.
From JavaScript:
new OPL3.Player(OPL3.format.MUS, {
instruments: genmidi // ArrayBuffer or JSON
});
- WAV: PCM audio WAVE
- MP3/Lame: using node-lame
- OGG/Vorbis: using node-vorbis and node-ogg
- OGG/Opus: using node-opus and node-ogg
- MIDI: currently only supported by MUS file format handler
- Audio playback: using node-speaker in node.js and Web Audio API in browser.
MP3, OGG and audio playback support are based on optional dependencies. If a dependency install has failed, the export format won't be available.
By default the command line utility uses peak normalization on the PCM audio result buffer. To turn off this feature, please use -n0
argument.
To enable normalization in the Player class, instantiate the player like:
var player = new Player(LAA, { normalization: true });
- Robson Cozendey, for creating
That Vintage Tone
OPL3 emulator - Paul Radek, for creating the
MUS
format - Vladimir Arnost, for creating
MUSLib
- Nathan Rajlich, for creating the
MP3
,OGG
,Vorbis
andSpeaker
node.js modules