File suffix:






NinjaTrackerPlus (NTP) is a music player for the Apple IIGS. It plays tracked music that can be converted from MOD files. It is a complete rewrite of our existing music player, NinjaTracker.

Use the convert function above to convert files from MOD to NTP.


The SoundSmith/NinjaTracker file format has some limits. It can't handle more than 15 instruments and it always stores 14 tracks. Also, the notes are played slightly different and many effects are not implemented correct. NinjaTrackerPlus solves all of these issues.

Where Download here.



For musicians

Use the upload form above to see if your MOD can be converted. If there are conversion problems, you'll get tips what you probably should change.

The Apple IIGS has a number of constraints:

15 tracks
... and beyond

You can use up to 31 tracks to store notes. OpenMPT and other trackers support this variation of the MOD format.

In general, each track of a module requires two of the 32 oscillators (voices) of the sound chip. One oscillator is required for music playback, which means that you can play modules with 15 tracks.

However, some samples only need one oscillator (see "tips" below). If the converter finds out that all instruments on a track need one oscillator, that track is switched to a one-oscillator-track. In theory, you can have up to 31 tracks this way.

Furthermore, there is the optional "channel doubling" feature. It can be enabled when playing music and it will double the amount of oscillators each track uses. Each voice gets an extra voice on the other channel with half the volume, making playback sound much nicer, especially on headphones.

TL;DR You can use 15 tracks.

classic Protracker

NTP is handling effects with the same quirks as classic Protracker.

Also, while NTP supports 6 octaves, it is probably best to keep to the 3 octaves of the Amiga frequency limits.

64k sound ram

Yes, the Apple IIGS has only 64k of sound memory. Samples that don't fit into sound ram have to be streamed. Depending on your use case, you can:

a) Forbid streaming. All samples have to fit into sound ram. Use this option when you need as much spare CPU time as possible. Modules that have too much sample data will fail to convert.

b) Allow streaming. The converter will put as many samples in sound ram as possible, and stream the others.

c) Enforce streaming. All samples will be streamed.

sample boundaries

Samples that go into the 64k sound memory cannot be placed anywhere. Instead, they have to be aligned to certain boundaries. These are: 256, 512, 1024, 2048, 4096, 8192, 16384 and 32768 bytes. The converter will take care of sample alignment, but this constraint further reduces the memory that you have available.

Streamed samples are not affected by sample boundaries.

sample sizes

Like the boundaries above, ideal sample sizes are 256, 512, 1024, 2048, 4096, 8192, 16384 and 32768 bytes.

Other sample sizes are always possible, but they are wasting space due to the boundaries. So if your sample is 2060 bytes, it is treated like a 4096 byte sample. Try to remove some bytes to fit it into 2048 bytes.

Also, if your sample is not of an ideal size, 8 stopper bytes have to be appended, which may push the sample's size over the adjacent boundary.

Streamed samples can be of any size.

looped samples

If your sample is looped, it has to be split into 2 samples: Header and loop. This is done by the converter automatically. But this means that to each, the sample size contraints from above apply.

Attention: There is a bug in the IIGS sound hardware that can create nasty clicks in a loop if they are not of an ideal size. NTP does some wild stunts to minimize the effect, but if you can, make sure the loop has an ideal sample size!

Streamed samples are not split.


Keep your samples small so that they fit in 64k.

Make sure that the loops of your samples are exactly 256, 512, 1024, 2048, 4096, 8192, 16384 or 32768 bytes long. This will result in the best sound quality.

If you need more than 15 tracks, try to make one-oscillator tracks in your module. One-Oscillator tracks are tracks where every instrument on the track is both:

  • located in sound ram (see above)
  • either not looped or consists only of a loop with an exact size of 256, 512, 1024, 2048, 4096, 8192, 16384 or 32768 bytes

Using the 8 command, you can send sound from the track to one of 8 output channels that the Apple IIGS supports:

0= Front left
1= Front right
2= Surround left
3= Surround right
4= Front height left
5= Front height right
6= Surround back left
7= Surround back right

The 4soniq card supports all output channels.

On stereo systems, all "left" channels are sent to the left speaker. All "right" channels are sent to the right speaker.

On mono systems, all channels are sent to the one speaker available.

By default, the converter will set the tracks to use the classic output channels in this fashion:
Track 1 - Front right
Track 2 - Front left
Track 3 - Front left
Track 4 - Front right
-repeat for the remaining tracks-

channel doubling

The channel doubling feature can be enabled when starting music playback. When active, everything that is sent to one speaker (left for example) will also be sent to the other speaker (right) but with half the volume. It will make the playback sound nicer, especially on headphones.

Keep in mind that this will double the amount of oscillators used. In general, one track uses 2 oscillators and 4 with channel doubling. In that scenary, you can have only 7 tracks in your module. Tracks that use only 1 oscillator will use 2 with channel doubling.

supported effects

You probably know all Protracker effects. Most are supported by NTP:

[0]: Arpeggio
[1]: Slide up
[2]: Slide down
[3]: Slide to note
[4]: Vibrato
[5]: Continue 'Slide to note', but also Volume slide
[6]: Continue 'Vibrato', but also Volume slide
[7]: Tremolo
[8]: IIGS panning
[9]: Set sample offset (only streamed samples)
[10]: Volume slide
[11]: Position Jump
[12]: Set volume
[13]: Pattern Break
[14][0]: NOT SUPPORTED: Set filter on/off
[14][1]: Fineslide up
[14][2]: Fineslide down
[14][3]: Set glissando on/off
[14][4]: Set vibrato waveform
[14][5]: Set finetune value
[14][6]: Loop pattern
[14][7]: Set tremolo waveform
[14][8]: -- Unused --
[14][9]: Retrigger sample
[14][10]: Fine volume slide up
[14][11]: Fine volume slide down
[14][12]: Cut sample
[14][13]: Delay sample
[14][14]: Delay pattern
[14][15]: Invert loop
[15]: Set speed


For programmers

Example code, the full source for the player and the converter as well as example music files are available in the download section.

  • The player is written in assembly with Merlin 32.
  • The converter is written in PHP.
  • The 2MG disk image features example music.
  • Read the ninjatrackerplus.s source code to learn about the interface.
  • The music player uses the sound interrupt for timing purposes. Do not block interrupts for longer periods or the music will "hang".
  • If the music uses looped samples where the loops are not of an ideal sample size, additional interrupts are created. If you can, ask the musician to use loops of an ideal size (see tips above).
  • Streaming samples cost a lot of processor time. There may be a limit of how many tracks can use streaming at the same time. It works fine for the normal 4 tracks of normal modules.
  • For streaming, each track requires a 512 byte buffer in sound ram.
  • Have a look at the conversion information. It will give you an overview of the module, which parts of the sound ram are used, and which oscillators are used.
  • If you need to play sounds while music is playing, you can either place them in the free areas of the sound ram, or stream sounds from normal ram. For playing from sound ram, you have to write your own code. For streaming, take a look at the NTPStreamsound call.
  • The player is backwards compatible; it can play NTPs version 0, 1 and 2.


Comparison with NinjaTracker

NinjaTrackerPlus is a music player written from scratch. It features:

  NinjaTrackerPlus NinjaTracker
max. number of instruments 255 15
number of tracks 1-31 always 14
support for 4soniq card(s) yes yes
number of Protracker effects supported
(out of 31)
30 18 (and with bugs)
support Protracker note table yes no
support both Protracker tempo and speed both tempo only
improve quality with ideal samples
(256, 512, 1024, ...)
yes no
rotate loops to minimize DOC swap bug yes no
stream samples optional no
double channels optional no
oscillator usage 1-4 per track always 2 per track
file format .NTP .SSM and .W ( like SoundSmith)




September 9, 2018 Initial release.
September 16, 2018 Bug fix:
+ The player now uses the system volume.
November 25, 2019

Version 1.0

Bug fixes:
+ MODs with 1/2/3 or 15 channels were not converted correctly
+ The converter now rotates loops near a zero-crossing to reduce the swap bug

February 8, 2020

Version 1.1

Bug fix:
+ portamento effects 1 and 2 no longer start at first tick

April 8, 2021

Version 1.2

Added the ability to set volume during playing.
Bug fixes:
+ Some notes where not stopped resulting in "skipped" notes
+ Octaves 0 and 4 had wrong values

January 2, 2022

Version 1.3

Added support to stream samples, allowing to play modules with large samples. Newly generated NTP files are version 1 (previously version 0).
Added effect [9] sample offset (for streamed samples only).
Added effect [14][15] invert loop.
Added option for channel doubling.
Bug fixes:
+ Instruments where not played correctly when there was only one pattern
+ Effect [11]: Position jump did not reset position in the pattern when jumping
+ Effect did not work: [14][9]: Retrigger sample
+ Effect did not work: [14][12]: Cut sample
+ Effect did not work: [14][13]: Delay sample
+ NTPsetplayvolume did not calculate volumes correct

January 16, 2022

Version 1.4

Added option to make use of more oscillators for music with up to 31 tracks.
Song name and instrument names are now included in NTP files.
Added call NTPstreamsound for streaming SFX.

February 5, 2022 Updated Tool 222 to use version 1.4 of NTP.
Bug fixes:
+ Converter checks if too many oscillators are used
+ Converter assigns stream buffers only to tracks which require streaming