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.
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).
The latest DRO Trimmer source code can be obtained from the BitBucket repository, using one of these methods:
Alternatively, all binary and source code releases are packaged and available from here:
This link will always give you the latest packaged release of the source code:
There are Windows 32-bit binaries available from that site. The link below will always give you the latest release:
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:
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:
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.
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.
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.
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:
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.
dro2to1.exe file_to_convert.dro [output_file_name.dro]
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.
The "ui" section is used to configure particular elements of the user interface.
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.
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
The same as Method 1, but it only compares delay and note on/off instructions.
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.
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).
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: