Amiga implementation

Tracker 4.44

## 8.10: Peculiarities of the Amiga implementation: tracker versus Delitracker ?

In fact, this title is a joke... tracker doesn't compare with Delitracker at all. The purpose of the two programs is quite different, and Delitracker is most certainly the best at what it does.

Anyway, tracker yields some very interesting features, probably unique.

- it's written entirely in C.
- it's portable.
- it goes through the OS for everything (except the audio filter toggling, but that's not provided for right now).
- you can steal audio from under it without any trouble!
- it reads archive files (like lha or zoo).
- it buffers its sound output, so that it runs at about the same pace on every machine without needing any kludge.

The old version used the timer `WAIT_EBLANK` unit for all its timings and assumed everything was done fast enough that the new audio commands would fall on the right beat.

This new version uses a two tasks model: task 1 fills messages telling what to do at a given time until it has no messages left and sends them to task 2. Task 2 peeks at the messages it received, waits for the right time to act on them, performs the sound changes, and sends the message back to task 1.

This offers lots of advantages.

- time-critical code is bundled in one simple routine that basically only has to wait for the right instant and send very simple events to the audio device. I've upped the priority of this task to 90 since it waits most of the time.
- tracker modules do not always need the same amount of processing power, the load might even vary (and does vary) during one given module. Using buffering means you equalize the load and you can then play very complex modules on a small Amiga even with unoptimized code. For instance, scrolling output with ``scroll`' works on almost any Amiga and any module unless you really need too much processing power for it to work.[1]
- because of the buffer, we do know about the samples we'll have to play with some look-ahead. It should be feasible to load them from normal ram to chip without much trouble....

and some drawbacks too:

- even though sas/c tries and help you, it's still difficult to debug multithreaded programs. I've circumvented that difficulty by adding conditional code that splits tracker into two distinct programs.
- handshaking is easy to get wrong. Forgetting to take some messages into account can lead you to lose some, and end up with a deadlock when no message is left.
- since audio output is buffered, the interface tends to react with some delay unless you program things carefully. Part of the problem is alleviated by using `ReadEClock()` to get some feedback in the necessary buffer.

Another stupid problem I got in while programming the Amiga support was using the standard `WAIT` unit of the `timer.device`, the one based on `VBLANK`. This was very stupid: using a timer unit of the same resolution (or about so) as the events I was wanting to measure. Since I got unlucky, it appeared to work correctly for quite some time... I'm usually looking at a rock-solid ntsc 60Hz display.

Some new add-ons: the event handling is completely decentralized. See ``events.c`'. This is an interesting way to bridge the gap between the usual programming model and the event-driven model.

There is some problem with arq not recognizing requesters built through `BuildEasyRequest()` instead of using `EasyRequestArgs()` directly, but it enables us to add a filerequester (the `reqtools` one since Amigados `asl`'s doesn't support truly asynchronous operation... Yet another blunder from Commodore).

I haven't put any iconifying possibility in the main window. I feel that Menufy/Iconify provide very nicely for it... and they work for me, so why should I care. Already tracker weighs in at 60 K bytes, that's a true monster of a player program!

In the future, I will try to add more controls to the user interface. After all, I've got an incredible amount of data and switches about a module that I don't use at the time:

- global volume,
- volume on a per-instrument basis,
- volume on a track per track basis,
- non-linear volume scaling,
- on-the-fly transposition,
- switching instruments on/off...

obviously, the most difficult part is to write the interface itself. All of this is possible today!

[1] This means that, once again, thinking a lot about how to code things wins hands down over the brute force approach. Assembly, no-system hackers, eat your hearts out! Tracker does not use any assembly code, is probably badly optimized in places, but what do we care ? It runs on anything at a decent pace.