DRO Trimmer is a cross-platform GUI tool to edit DRO files (DOSBox Raw OPL), which store raw commands for OPL chips (aka OPL2, OPL3, Adlib, Sound Blaster, YM3812, or YMF262), as captured using the DOSBox application. It supports files in the DRO 1 or DRO 2 format.
It includes a built-in player, which can also be run from the command line. It has a command-line tool to render each channel to a separate WAV file. It also contains a conversion tool, dro2to1, that can convert DRO 2 format files to the DRO 1 format. This is handy for using your files in other tools which only support DRO 1, e.g. DRO2MIDI.
The primary use is to delete instructions in the DRO file, or "trim" the song.
Introduction to OPL2/OPL3
The Yamaha OPL2 chip (technically called YM3812) is a frequency modulation synth (FM). It gained popularity in the home computer market, thanks to sound cards like Adlib and the early Sound Blasters.
The Yamaha OPL3 chip (technically called YMF262) is an improved version of the OPL2 chip, adding stereo support and extra waveforms available for synthesis. This is probably the most common chip around, as it was used in sound cards like the Sound Blaster 16.
There are also some models of sound card (such as the Sound Blaster Pro 1.0) that make use of Dual OPL2 chips. This enables the use of stereo support, but does not include the extra waveforms present in the OPL3.
Also, later sound cards like the Sound Blaster AWE64 do support OPL3 playback, but actually uses its own chip, the CT-4390, which uses CQM synthesis. This introduces slightly different sound characteristics.
Synthesis is performed by writing values to registers on the chip. This is quite difficult to write as a musician, so most music would have originally been written in another format (such as a MIDI-based format) and converted to the OPL format by audio drivers. This can lead to poor renditions of orchestral music designed for more traditional sample-based hardware, such as the Roland MT-32. More advanced composers made special use of the OPL chip's synthesis capabilities. This is evident in games like Tyrian, Fuzzy's World of Miniature Space Golf, and Japanese games such as Princess Maker 2.
DOSBox only has visibility on instructions sent to the hardware, so it captures the raw instructions sent to the OPL chip - hence the name, DRO (DOSBox Raw OPL).
Obtaining DRO Trimmer
The latest DRO Trimmer source code can be obtained from the BitBucket repository, using one of these methods:
- Clone the latest code from BitBucket, using Mercurial
- Download the latest code from BitBucket, using its built-in zip packaging (go to the "Source" tab, click the "get source" link in the top right, and choose the zip format of your choice)
Alternatively, all binary and source code releases are packaged and available from here: http://www.jestarjokin.net/apps/drotrimmer/
This link will always give you the latest packaged release of the source code: http://www.jestarjokin.net/apps/drotrimmer/src
There are Windows 32-bit binaries available from that site. The link below will always give you the latest release: http://www.jestarjokin.net/apps/drotrimmer/bin
DRO Trimmer is written in Python. You can run it directly from the source code, since Python is an interpreted language. This is the preferred option for Linux or OS X.
Please ensure you have the following dependencies installed:
Note that you can run DRO Trimmer without the player functionality. This will remove the need for PyOPL and PyAudio, and drops the Python requirement down to version 2.5.
Once you have installed all the dependencies, get the source code and put it in the directory of your choice.
Windows binaries are distributed in a zip file. Just unzip the package to a directory of your choice. It will make a subdirectory called "drotrim", containing all of the application's files.
Run drotrim.exe if using the binaries, or drotrim.py if running from the Python sources.
Open the .dro file you wish to edit. If you are opening a DRO v1 file, some analysis will be done to check if the first instruction is a delay (this is caused by a bug in DOSBox's capturing), and if so it will automatically delete it. It will also verify that the song length noted in the DRO header is the same as the calculated song length.
Once the file is loaded, all of the OPL commands will be visible in a table view, with the following columns:
- Pos.: Short for "position". This is the instruction's position in the song. Starts from 0.
- Bank: Indicates if the low (0) or high (1) chip is used for this instruction. This information is loaded dynamically (see below).
- Reg.: Short for "register". Displays the register that this instruction modifies, in hex.
- Value: The value written to the register, in hex, with the decimal value in parentheses.
- Description: A text description of this instruction. This information is loaded dynamically (see below).
- Description (all register options): A more general description of this instruction, showing all possible functions of the register (see below).
Note that one register can have multiple functions; e.g. register 0x20 can alter the tremolo, vibrato, sustain, envelope scaling, and frequency multiplication factor. The exact functions affected is determined by the value sent to the register, and the previous value of the register. For this reason, the "Bank" and "Description" columns are loaded dynamically, meaning the whole song data must be analysed sequentially to determine what effect the instructions have. This dynamic analysis occurs as soon as a song is loaded, and after instructions are deleted (or when undoing or redoing a deletion). This analysis runs in the background, and the "Bank" and "Description" columns will not be populated until the analysis is finished. Because you may not want to wait for the analysis, the column "Description (all register options)" is provided, which can immediately give you a rough idea of what the instruction does.
Delete any instructions you don't want, using either the button, menu item, or keyboard shortcuts, and then save. You can select multiple instructions at once by holding the "shift" or "control" (or "command") keys while you click on them.
There are three buttons for playback:
- "Play from current pos." will play the song from the currently selected instruction. If you have multiple instructions selected, it will play from the earliest instruction.
- "Stop song" will stop any playback
- "Play last 3 seconds" will play just the last three seconds of the song. Useful for confirming that you've trimmed the end of the file enough. This is referred to as the "tail", and the length can be set in the external configuration file ("drotrim.ini").
You can also use the spacebar on your keyboard to toggle playback on and off (from the currently selected instruction).
There is a "Find Register" screen available from the Edit menu. This lets you quickly search for uses of a particular register. Note that searching for a register will look for instructions that affect both the high or low banks; you can't specify to search in just the low bank (or just the high bank). It can also be used to search for commands used by the DRO file format. These use the special mnemonics below.
- DLYS - short delay (8-bit)
- DLYL - long delay (16-bit)
- DALL - both short and long delays
- BANK - switch to the low or high bank/chip (only available for DRO v1 files)
There is a "DRO Info" screen available from the Edit menu. This will show you some extra information from the DRO file's header, such as the DRO format version (1 or 2), the hardware chip used, and the length of the song in milliseconds. It also displays the calculated length, so you can verify that the header value is the same as the actual length.
You can enable the ability to edit some of the "DRO Info" header information (currently just the hardware type and song length). Do so by setting the configuration option "dro_info_edit_enabled" to "true" in the drotrim.ini file. This functionality is disabled by default, since you should almost never have to use this, unless you are working on a corrupt or invalid DRO file.
The "Goto" option will bring up a dialog where you are able to instantly go to a specific position in the song data.
The "Loop Analysis" option brings up an extra window, where you can trigger analysis of the currently open song. There are multiple analysis methods used, and the results from each method will be displayed on separate tabs. The methods are detailed in the "Loop Analysis" section of this document.
There is a standalone command-line player for DRO files.
To run: dro_player.exe file_to_play.dro or python dro_player.py file_to_play.dro
It only takes one command-line argument: the name of the file to play.
Playback will start immediately. If you want to stop playback, use the Control-C keyboard shortcut to terminate the process.
You can render a DRO song to a WAV file, using the "-r" or "--render" option.
You can also solo particular channels during playback, using the keys from 0 to 9. Switch to low/high banks using the -/+ keys respectively, and press ~ to unmute all channels.
This is another standalone command-line tool, that can render each channel in a DRO song separately, either to WAV files or DRO files.
To run: dro_split.exe file_to_render.dro or python dro_split.py file_to_render.dro
This tool could potentially produce over 20 separate WAV files, so make sure you have enough hard drive space!
There are a few options:
- -d or --dro: Splits each channel to a separate DRO file, rather than WAV. Defaults to false.
- -p or --preserve-panning: outputs each track as a stereo file in order to preserve the channel's panning. Only required for Dual OPL-2 and OPL-3 songs.
- -i or --isolate-percussion: renders each instrument in the percussion channel to a separate file per instrument.
This tool converts DRO files in the DRO 2 format to DRO 1. The only real use is if you have another tool which only supports the DRO 1 format such as DRO2MIDI.
To run: dro2to1.exe file_to_convert.dro [output_file_name.dro] or python dro2to1.py file_to_convert.dro [output_file_name.dro]
You must pass the name of the file to convert as the first argument. You can also specify the file name of the output file. If this is not specified, the default is to add "_1" to the file name before the extension, e.g. "file_to_convert.dro" will become "file_to_convert_1.dro".
If the output file already exists, dro2to1 will abort. You must manually delete or rename the existing file, or specify a different output file name as an argument, and re-run the program.
There is a "drotrim.ini" file available to configure DRO Trimmer.
The "audio" section is used to determine settings for the OPL synthesis and the audio playback.
- bit_depth: The number of bits to use per sample. Defaults to 16.
- buffer_size: How many samples to render per buffer. Defaults to 512.
- frequency: The frequency in Hertz. This is set to 48000 by default. If you want the most accurate simulation, you should use 49716 instead.
- chip_write_delay: When writing to a real OPL2 chip, you need to add a delay of approx 26.6 microseconds after each instruction. OPL3 has much less required delay. You emulate this delay by setting the chip_write_delay value. This can be handy if you're trying to compare speed differences between emulated playback of a song and the same song played on real hardware, or if you just want more authentic playback/rendering. Defaults to 0.
The "ui" section is used to configure particular elements of the user interface.
- tail_length: This specifies the playback length for the "Play last x seconds" button. Must be given in milliseconds. Defaults to 3000 (i.e. three seconds).
- maximize_window: Toggles whether to maximise the DRO Trimmer window when the application launches. Enter a boolean like "true" or "false". Defaults to false.
- dro_info_edit_enabled: Toggles whether to enable edit functionality on the DRO Info screen.
- Shift: Select multiple instructions. Selects all instructions between the previously selected item and the item selected while holding shift and clicking the left mouse button.
- Control: Select multiple instructions. Toggles selection of an instruction while clicking the left mouse button. Keeps any previously selected items.
- Space: Toggles playback of the song from the current position.
- Delete: Deletes the currently selected instructions.
- Backspace: Deletes the currently selected instructions.
- Left Arrow: Goes to the previous delay instruction. (Deselects any currently selected instructions)
- Right Arrow: Goes to the next delay instruction. (Deselects any currently selected instructions)
- Control-F: Opens the "Find Register" dialog.
- Control-H: Opens the "Help" dialog.
- Control-I: Opens the "DRO Info" dialog.
- Control-O: Opens a different DRO file.
- Control-S: Saves the currently open DRO file.
- Control-Shift-S: "Save As". Saves the currently open DRO file, under a different location/file name.
- Control-Y: Redo a previously undone action.
- Control-Z: Undo the last deletion performed.
Note that backspace and delete only work on the main list view, but all other shortcuts will work at any time.
If you are using an Apple keyboard, the "Command" key can be used for any shortcuts that use "Control". (I think!)
Loop Analysis tries to find suspicious portions of data that could represent a loop point in the song. There are 5 methods. Some methods will work better than others, depending on the data it's analysing, how many times the song loops, etc.
Method 1: Earliest end match
Goes through the data backwards. Finds the "earliest" sequence of instructions that matches the sequence of instructions at the end of the song.
From the index second from the end, compare to the last value at the end. If the current value matches the end value, compare all values preceding the current value against all values preceding the end value.
(This is a fairly naive approach.)
[0, 1, 2, 3, 1, 2] ^ ^ [0, 1, 2, 3, 1, 2] ^ ^ [0, 1, 2, 3, 1, 2] ^ ^ [0, 1, 2, 3, 1, 2] ^ ^ [0, 1, 2, 3, 1, 2] ^--/ ^--/ result: section 1: start = 1, end = 2, length = 2 section 2: start = 4, end = 5, length = 2
Method 2: Earliest end match (delays and note on/off only)
The same as Method 1, but it only compares delay and note on/off instructions.
Method 3: Latest start match
Goes through the data from the start. Finds the "latest" sequence of instructions that matches the sequence of instructions at the start of the song, after the first delay and first note on instruction.
Method 4: Longest instruction blocks
Finds the the 15 longest blocks of instructions, separated by delay instructions. Excludes the first block at the beginning of the song (which is usually just register initialization, in DRO 2). Only looks at blocks greater than 10 instructions long.
This will print out the results twice, once sorted by size, then again sorted by the start position of the block (latest first).
Method 5: Sequence matcher
Uses Python's built-in Sequence Matcher functionality. Splits the data into half, and looks for the longest matching block in both halves.
If you're looking for a good place to perform trimming in a looping song, try looking for a section which initializes a large number of registers. The most common registers will handle stuff like note on/off, volume, etc, so you want to look for registers which do things like initialize the sounds/waveforms. (Method 4 of the Loop Analysis will find these sections for you.)
Issues or feature requests can be raised on BitBucket. Make sure to search for any existing issues that might be relevant.
DRO Format specifications:
Programmer's Guide to Yamaha YMF 262/OPL3 FM Music Synthesizer: