Skip to content

a11599/tmodplay

Repository files navigation

This is

Therapy MOD player (tmodplay)

a 32-bit protected mode DOS player for MOD music format

  • Multichannel support
  • Optimized 16-bit mixers
  • Variable amplification with clipping
  • Various sample interpolation methods
  • Stereo crossfade for hard panned (Amiga) MODs
  • Real stereo mode for MODs utilizing panning commands
  • 640x480 graphical user interface with scopes and RMS meters

Primer

This is the modern remake of a multichannel MOD player I wrote back in the mid-90's for retro PC platforms. Why? Because programming for limited hardware with direct control over it is a challenging, but rewarding fun. Also this old modplayer of mine was lost back in the day in a sad hard drive accident and burned a hole in my heart. So it was about time to rebuild it and make it even better than it ever was to heal my wounds finally.

Screenshot playing dope.mod

It requires a 386 or above running MS-DOS or Windows 9x/ME, or an emulator such as DOSBox. It is written in full assembly using PMI, a 32-bit protected mode host and mod, a MOD player library for PMI. The MOD player supports ProTracker format and its close derivates up to 32 channels on the following sound cards:

  • PC speaker up to 29 kHz sample rate
  • LPT DAC variants (single, dual, stereo) up to 44.1 kHz sample rate
  • Sound Blaster, Pro and 16 up to 22/44.1 kHz sample rate (depending on actual model)

An extremely optimized software wavetable with 16-bit mixing, optional linear and trilinear Watte interpolation upsampling is included for non-wavetable sound cards (all of them for now, but at least GUS support is planned in the future). Stereo is supported with hard pan or 75% crossfeed. True stereo panning via 8xx and E8x MOD commands is also available.

The main development platform is a modern PC with DOSBox-X, but the result is always tested (also some parts are developed) on the following retro hardware: Abit BX6 2.0 (Intel 440BX chipset), Intel Pentium II 350 MHz, Sound Blaster 16 Vibra16S (CT2800) ISA, Serdaco CVX4 (LPT DAC), PicoGUS v2.0 and nVidia Geforce 440MX 64 MB AGP running Windows 98 SE and MS-DOS 7.0.

Usage

Type tmodplay /h to display help on command line arguments. Press F1 during playback to show the supported keyboard commands. Refer to tmodplay.txt for further details.

Building from source

Pre-requisites

The app can be built under DOS and Windows. The build uses the following toolchain:

  • NASM to compile assembly source code to linkable objects.
  • Open Watcom to make the project and link the executable binary.
  • (optional) DOSBox-X to test the build on a modern PC.

The build toolchain is also available for Linux, but the build system only supports DOS and Windows.

Download and install the dependencies, then:

  • Copy makeinit.sam to makeinit and set the following parameters:
    • nasm_dir: Path to directory containing nasm.exe (NASM binary).
    • watcom_dir: Path to directory containing Open Watcom platform-dependent binaries.
    • If both of them are added to system PATH, you don't need to create a makeinit file.
  • Copy test_bat.sam to test.bat and adjust file and args environment variables according to your testing requirements. file should point to a MOD file and args contains parameters to the player. Run tmodplay /h to display the available command line parameters or refer to tmodplay.txt.
  • (optional) When using DOSBox-X for development on a modern PC, copy emu\env_bat.sam to emu\env.bat and adjust the path of dosbox-x.exe in the file to your actual install directory.
  • Download PMI, extract it into the same parent as of tmodplay and run wmake dist in the PMI folder.
  • Download mod, and extract it into the same parent as of tmodplay.
  • Create the mod directory under tmodplay and copy some MOD files into this folder for testing.

The folder structure should look like this:

  |
  +-- pmi
  |   |
  |   +-- build
  |   +-- dist
  |   +-- emu
  |   +-- lib
  |   +-- src
  |       ...
  |
  |
  +-- mod
  |   |
  |   +-- src
  |       ...
  |
  +-- tmodplay
      |
      +-- emu
      +-- src
      +-- mod      <- copy your MOD files here
          ...

Building the application

In the project root directory, run wmake to create a debug build to build\debug\tmodplay.exe. Run wmake build=release to create a release build to build\release\tmodplay.exe. Building tmodplay will automatically rebuild mod for the same build target (debug or release).

The following wmake targets are also available (append after wmake or wmake build=release):

  • wmake clean: Remove compiled binaries in build\debug or build\release directory.
  • wmake full: Force a full recompilation (compilation by default is incremental, only changed source code is recompiled).
  • wmake dist: Create a binary distribution package to dist directory.

To speed up the development process, two simple batch files are also provided:

  • make.bat: Invokes wmake to create an incremental debug build and executes test.bat to test the executable. Requires MS-DOS, or Windows 9x/ME DOS box.
  • makedb.bat: Invokes wmake to create an incremental debug build and executes test.bat using DOSBox-X to test the executable.

To start DOSBox-X with the same environment as makedb.bat, run emu\dosbox.bat. You can then manually test the build by running test.bat or executing build\debug\tmodplay.exe with your custom parameters.

Why 386 and why protected mode?

This project originally targeted the 286 which was very challenging. However it was soon realized that:

  • The 286 is not really suitable for 16-bit mixing, and it's just not fast enough for acceptable (32 kHz+) sample rates unless it's a higher clock rate (12 MHz+) model anyways.
  • There are large MODs (especially those made on PCs and later expanded Amigas) out there and the 640 KB limit of conventional memory quickly became a bottleneck.
  • There are also a few MODs with samples larger, than 64 KB and supporting this with segment:offset arithmetic (especially for loops) was annoying and slow.

I wanted this player to have better sound quality and more compatibility than contemporary players with similar CPU usage and my goals just didn't seem to work out with the 286. And if the 286 is not good enough, why bottleneck 386 and later with 16-bit instructions?

Why protected mode? For some time, tmodplay used flat real mode and it was working fine, but I eventually ran into several issues:

  • The audio mixer code, which uses most of the CPU had a lot of 32-bit registers and addressing, thus generating operand and/or address size prefixes for almost every instruction. This consumed a significant amount of CPU cycles: after converting to protected mode, CPU usage was almost halved with Watte interpolation on a Pentium CPU.
  • It was not compatible with EMM386. Although it could be made to work with it, it would have lost the simplicity and appeal of flat real mode.
  • It would have never worked under Windows. While it was not a big concern and it was never a goal of this project, being compatible with Windows 9x DOS box is a nice thing to have.