Thanks for the memory

When Hyperion Entertainment announced in a 2014 blog article that AmigaOS4 was going to get support for accessing memory beyond the 2 GB limit, the reactions were mixed. Predictably, the most abrasive comments came from people who had never owned an OS4 system; but the camp of supporters didn’t seem over the moon, either. Perhaps the title of the article (“Breaking the Memory Barrier”) sounded too promising, and the reality couldn’t live up to the raised expectations. But there would likely have been less disappointment if people didn’t read too much into the title and, instead, took the feature for what it actually is. Because Extended Memory Objects – or ExtMem, as the feature is popularly called – was never advertised as more than a stopgap. Or did anyone seriously expect that AmigaOS would somehow miraculously adopt 64-bit memory addressing?

However, stopgaps in AmigaOS have a tendency to silently become permanent features (take AHI, for example), so eight years after the Hyperion announcement, we still don’t have a better solution. Worse, the adoption of the feature appears to have been quite slow: the system RAM Disk (adapted for ExtMem by Colin Wenzel) and Andy Broad’s SketchBlock are the only real-world applications of the feature that I’m aware of. The main reason why programmers don’t rush to use it is probably the inherent limitations because, as the critics like to reiterate, ExtMem is basically a return to the old practice of bank switching we know from the microcomputer era. Corny and technologically inane, right?

Like most audio software, my Rave sound editor can get quite memory-intensive. Popular compressed formats such as MP3 and the practice of streaming have taken our attention away from the fact that today’s audio data can easily take hundreds of megabytes when you decompress it into the computer’s memory. This may be a problem on a 32-bit system such as the Amiga. So I was naturally curious if ExtMem could help me with some of the challenges I was facing. And it didn’t take me long to start looking in one particular direction.

After I released the first version of Rave, the user feedback I received showed quite clearly that the number one wanted feature was Undo – the possibility to revert changes you’ve made to the waveform. Not a great surprise: honestly, if I were in my users’ shoes, I’d be among the first to point out the omission of such an important feature! But it’s interesting to see how much we’ve now come to take Undo for granted because, believe it or not, an Amiga sound editor with such functionality is far from being a given. I recently fired up a number of audio manipulation programs that were popular back in the day. I was curious how my new-born baby Rave compares with them, and I specifically wanted to see how they implement Undo, hoping to find some inspiration.

Aegis Audiomaster and Digital Sound Studio were my go-to sample editors in the 1990s.

The results of my little research were surprising, to say the least. Of the ten programs I looked at, only three featured a dedicated Undo – and only one of the undo implementations I’d call useful. To cut a long story short, I’ve summarized my findings in a table:

PROGRAMVERSIONYEARUNDO IMPLEMENTATION
Aegis Audiomaster IV1.01991No undo.
Megalosound1.351993Single-step undo, the data is stored in RAM.
GVP Digital Sound Studio3.0d1994No undo.
Samplitude Opus3.5 R9-51997No undo.
SoundProbe2.111998Single-step undo, the data is stored in RAM.
SampleE4.082000No undo.
SoundFX4.32004No real undo: modified samples are stored as new projects (which is memory-intensive and increases screen clutter).
Samplemanager1.62005Unlimited undo, the data is stored on disk as temporary files.
AmiSoundEd0.122009No undo.
SampleZ0.15 alpha2021No undo.
Undo implementation in various Amiga sound editors.

And the winner is (drum roll): Samplemanager by Thilo Köhler!

While I don’t feel like showing this table to my PC friends, the results cheered me up because I’ve realized that many of my predecessors scratched their heads over the same thing as me. They also confirmed my little theory that the implementation of Undo is not actually straightforward from the developer’s point of view. The user may think that all you have to do is dump the sample data into a memory buffer and recall it when needed, but it’s really not as easy as that, especially if you want to do it right.

On the other hand, I knew that I was in a different position with the next-generation hardware possibilities. I was thinking: if it worked for Samplemanager on a Classic Amiga seventeen years ago, why should I be worried on an OS4 system with a much faster memory and disk access?

Thilo Köhler’s Samplemanager, a companion to the author’s HD-Rec sequencer.

Preliminary tests on both of my Amiga systems, an X5000 and a Sam440ep-Flex, showed that a disk-based solution would be more than adequate, so I decided to go that way. I ruled out the idea that the Undo function would store data in regular system memory. Imagine a session with ten high-definition audio projects opened, each keeping a separate editing history, each eating a chunk of RAM every time you make a destructive change. Just thinking about the memory footprint makes me shudder! (Of course I could limit the history to, say, ten steps to prevent things getting out of hand. Surely a great improvement compared to having no Undo at all, but as I try to make a strong case for AmigaOS4 and its software, I have little mercy for half-baked solutions.)

Still, with 4 GB of RAM installed in the X5000 I was intrigued to try out ExtMem because what I had read in the documentation sounded encouraging, despite the “ugly” limitations that spoil the party for the purist. What are they, actually? By nature, AmigaOS cannot address more than four gigabytes of RAM, leaving roughly 2 GB of addressable space for application use. The ExtMem framework allows applications to store more data than that, by dividing the data into blocks (ExtMem Objects) that are stored in the physical memory beyond the addressing limit. The trade-off is that not all of the memory blocks will be available at one particular time. This is because such a block first needs to be mapped in the system memory, acquiring an address within the 2 GB range for the time the block is being used. If there’s not enough RAM to map the other blocks, they have to remain unmapped (and inaccessible) in the electronic void.

I wasn’t really bothered by this limitation because due to the way Undo works, only one piece of data is needed for each step back. In fact, as Andy Broad explained to me, the key to using ExtMem efficiently is to make sure that a memory block is never mapped unless it’s immediately needed for reading or writing. So the programmer must think ahead and keep memory things organized and prioritized.

Knowing this I had all the information I needed to write two analogical pieces of Undo code, one for ExtMem and the other involving disk storage. The result is a dual system, which brings several advantages. Above all, AmigaOS4 users with more than 2 GB of RAM installed in their computer can make use of the extra memory, which would otherwise remain a dead place. They also gain some speed increase because although mapping an ExtMem Object comes with an overhead, it is still faster than writing to disk. At the same time, the disk-based solution is good enough and provides unlimited Undo even on low-end systems such as the Sam440. It also works as a fallback in situations when saving into extended memory fails because there’s not enough free RAM to map the block: in such a case Rave will simply store the data on disk.

So now with version 1.3 out in the wild, I wish you all happy undo-ing! Also, I hope that the ExtMem framework will get more real-life use to prove its potential, and that OS4 programmers will find ways to usefully adopt it in their programs. I think it’s time to dispel the fallacy that there’s no software to make use of the extra power and resources found in machines such as the AmigaOne X1000 or X5000. Now there is, and I’m sure more will be coming in the future.