Crawling back to life

If there ever was an annus horribilis in my life, it was 2023 – and the year had started so well! I had updated the Rave audio editor to version 1.6 in February, and began planning new features soon after the release. But unpredictable as it can be, life decided otherwise. In the summer my marriage suddenly collapsed for reasons I’m still trying to fathom, and all of my Amiga activities went on the back burner. I did spend two refreshing weeks in Dublin where I met the wonderful George “Walkero” Sokianos, but for the rest of the year I wasn’t really in a state to enjoy my hobbies. The fact that I had to sell most of my studio gear to finance the settlement with my wife didn’t improve my mood any further.

Nevertheless, turning fifty in December I had a good reason to act like a big boy, so our marital split wasn’t acrimonious in the end. Things got a bit more levelled, so I thought it was high time I fired up the Amiga again. I managed to port the latest version of Protrekkr around Christmastime, adding a serious contender to the roster of music trackers available on AmigaOS4. But although the program is very cool, I realized there’s only so much love I can give to other people’s projects, and I wanted to start working on Rave again.

Naturally, I didn’t aim very high with the new version. It takes some time and effort to reacquaint with source code you last saw almost a year ago, so I knew version 1.7 would only get a few new features. I felt it was more important to show signs of life rather than put out a big update. Above all, I wanted to address a silly bug that sneaked into the previous version, in which I added (among other things) the Pause button. The bug would make a paused Rave unresponsive upon triggering sample preview playback in the file requester. Not a situation that occurs very often, but I’m glad to report that the bug is now fixed!

For quite a while I’d been meaning to improve the main menu with a list of recently opened files, allowing you to reopen them quickly, without the need to browse through the file requester. But I never got to it because I thought the implementation would be so easy that I could do it anytime; one of the many paradoxes in software development. In fact, I believed no implementation was necessary because I planned to use the Application Library, which provides functionality for creating recent lists. According to the available documentation, such lists can be kept system-wide as well as on the application level, and their creation boils down to passing a tag to the respective library function. Child’s play!

However, although I was able to get a system-wide recent list working with no trouble, using an analogical library function for an application-specific list never brought the same result. After pulling out most of my thinning hair I came to the conclusion that the feature must be broken in the Application Library (which would explain why I couldn’t find any real-life code examples demonstrating the usage). Given the current state of AmigaOS4 development, I didn’t hold out much hope for a quick fix, so once again I was left to my own devices. Nevertheless, the poor library still proved helpful. Although I had to write my own recent-list management routines, the library’s PrefsObjects API spared me a lot of work when it came to loading and saving the list data. The screenshot below shows the final result:

The new Open Recent submenu.

One of the few ideas I had explored last year, before Rave development went on hiatus, were improvements in the file requester. My sample collection had grown very large, with audio material scattered across dozens of directories and sub-directories, and I began to lose track of where things were stored. I had also realized that I’d been using certain sample packs more often than others, so I decided it was about time I implemented a list of favourites, i.e. shortcuts to frequently used places on my disk.

This required a redesign of the file requester’s Access Panel. The original panel used tabs showing a list of volumes and assigns, respectively, but there was no room for another tab to display the list of favourites: the panel would simply grow too wide. I took inspiration from a PC music program called Geist, which uses a hierarchical browser with foldable sections. So that’s what I unashamedly imitated in Rave’s new file requester, using the Listbrowser Gadget from the standard ReAction toolkit:

The file requester with the new Access Panel on the left.

One thing I like about this solution is that you can have more lists displayed at the same time, whereas with the old file requester you would have to flip between tabs. The lists that you don’t need can easily be folded to save space (as shown in the screenshot above). For instance, I no longer have to make dedicated DOS assigns now that I can define favourites, so I keep that section folded to make room for the other lists. For convenience, the default panel display is configurable from the program Settings window:

The Access Panel settings.

And that’s about all I was able to put into version 1.7, which has just been released and can be downloaded from the usual place. I have a lot of plans for further development, but you know that the words “Amiga” and “plans” don’t easily go together, so we’ll see what the near future brings. This year AmigaOS4 is turning 20 years old, and I hope I’ll be able to join in the anniversary celebrations bringing the best possible present: quality software to keep Amiga users productive.

Some like it raw

When you develop software, more often than not you face what is called an “implementation dilemma”: a crossroads type of situation where you have to decide which way to go next. What makes the situation tricky is that, unlike Dean and Sal from Jack Kerouac’s On the Road, you’re not free to make an arbitrary choice. Bad design decisions always have consequences, often unforeseen and usually bigger than smaller. Take a wrong step, and you end up in a lot of rewriting!

One day I got to the point that the Rave audio editor needed proper sample loading and saving (to replace the tentative datatypes-based code I’d used for testing). I had been developing the program with modularity in mind, aiming at a lean main executable that offloads the grunt work onto external modules, so keeping the loading/saving stuff outside of the main program was a matter of course. The question was how exactly that should be done – as usual, the devil is in the detail. One possible way was to develop a dedicated loader/saver module or plugin for each file format; an approach not foreign to Amiga audio software as it has been used in SoundFX and AmiSoundEd, among others. And indeed, going for this solution sounded logical, especially as I knew I could reuse or adapt the I/O plugin infrastructure of AmiSoundEd (the source code of which is freely available).

Me, having an implementation dilemma.

But given the number of audio file formats I meant to support, the prospect of having to develop, maintain and test a multitude of separate modules didn’t exactly fill me with enthusiasm. So in the end I went for a monolithic approach: a single program module that handles the loading and saving in all file formats. Because there’s only so much time I can devote to reinventing the wheel, I based the module on libsndfile, a cross-platform audio library that had also been ported to AmigaOS4. Regular readers will remember that I mentioned it in one of my previous progress reports. Choosing the library (which by the way serves popular software such as Adobe Audition or Audacity) was a decision I now thank myself for every day. Not always do implementation dilemmas have such good endings!

Of the thirty or so file types and formats libsndfile can handle, Rave provides a healthy selection that has recently been upped to twenty. Now that’s what I call being spoilt for choice! And perhaps this abundance of available formats was the reason why few people noticed that Rave didn’t support raw audio in its first few releases. I didn’t consider it a priority because raw is not exactly sought for these days. Or at least it doesn’t get much use in music-making and the recording industry, where unformatted data doesn’t bring any advantage. True, I have read a few forum posts where musicians across computer platforms were trying to recreate the “classic Amiga sound” by importing samples from the old SoundTracker sample disks, many of which came in the raw format. But then again, most of these legendary (or should I say infamous?) sounds have already been converted to WAV and shared online, so why bother with raw import?

My opinion changed after I bought a sample pack from Glitchedtones, a sample provider that focuses on sound effects, cinematic sounds and ambience recordings. The sample pack, aptly named Data Disruption, was created solely by taking various digital files – program binaries, documents, bitmap graphics and the like – and importing them as raw data into an audio editor for further processing. This gave them such wonderful quirky glitch sounds that I wanted to be able to make my own, using Rave of course. And so it happened that raw support jumped up the to-do list and soon I began working on it.

The raw import window.

A typical raw file is headerless and there is no standard suffix to identify the format (.raw is often used but is not mandatory). Therefore, an audio program has no way of knowing how to recognize the file and, more importantly, how to interpret the data contained within: properties such as sample rate or the number of channels need to be provided by the user. Starting from Rave 1.6, any file type the program doesn’t recognize can now be loaded, with the help of the import window shown above. The hidden beauty of raw is that importing the same file with different properties will produce a different waveform, so it opens ground for experimentation. The result is often weird noise and it can take a lot of attempts to discover something distantly musical or percussive, so brace yourself with patience. Your reward will be an interesting and unique sound that may be worth adding to your sample collection.

You’ll no doubt notice that most new features and improvements in version 1.6 are related to loading and saving files. Apart from adding raw data import and export, I’ve also completely rewritten the IFF-8SVX saver. During testing it turned out that the IFF files produced by libsndfile were seen as corrupted by several audio programs, namely OctaMED Soundstudio, MilkyTracker and AmiSoundEd. I have no idea why this was the case because libsndfile is otherwise very reliable, tested by thousands of users around the world every day. The situation was the worst with MilkyTracker because while the other two programs simply displayed an error message, the tracker would hang in an endless loop when trying to load the sample. As Milky is currently my main composing tool on the Amiga and I’ve been recommending it quite a bit, you can imagine how eager I was to fix the problem.

So I sat down and wrote my own IFF saver code that bypasses libsndfile, and I’m happy to report that the resulting files now open successfully in all of the three programs mentioned above. The new implementation also comes with a little bonus: IFF-8SVX files can finally be saved in stereo! This was impossible previously because the IFF format organizes stereo data in a way libsndfile is not designed for. I personally don’t have much use for these files, but the IFF format has such a strong connection with the Amiga that it was unthinkable to leave it half-supported.

Done! You’ll never see this error message again.

For some time I had also been trying to enable saving in the Ogg Vorbis format (to provide an alternative to MP3 and FLAC) but for reasons then unknown to me it always invited the Grim Reaper. During a recent, more serious attempt at making it work I managed to pinpoint the location of the crash: it appeared to be a problem in one of the ported libraries. But inspecting the source code I couldn’t quite see what the offending library function was doing wrong. Luckily, Fredrik Wikström – who had ported most libraries that Rave makes use of – offered to take a look at both the code and the crashlog. For me, reading a Reaper crashlog is like reading Heidegger but Fredrik is way more experienced, and so it didn’t take him long to discover that the function drained my stack by making some rather adventurous memory allocations. Because AmigaDOS doesn’t have automatic stack enlargement, such a situation will unfortunately end up in a crash. Of course I could just increase the program stack size, but Fredrik had a better idea: he rewrote the relevant code to make it more “Amiga-friendly”, and sent me a new build of the library. Lo and behold – Ogg Vorbis saving worked without a hitch!

The Ogg Vorbis saver configuration window.

Time to wrap up I guess; my favourite time. No epidemic of blindness has been reported of late, so I’m sure Amiga users have noticed the string of Rave releases since the program’s first public introduction nine months ago. Although the development gobbles up most of my free time, I’d like to continue this trend: I prefer not to hoard new features and, instead, release as soon as I have something useful to show. Now, I think I’ve put in enough to call it an update, so I’d better brush up the documentation, prepare the distribution package and get version 1.6 out of the door!

All I want for Christmas is Rave

In September, having made three public releases of the Rave audio editor within three months, I felt I needed a little break from programming. I used the self-imposed leisure time to catch up with my reading, and so I finally managed to get through the latest issues of Amiga Future and Amiga Addict, which had piled up in my room since earlier this year. I also visited and had a lot of fun at the Amiga37 party in Germany as I reported previously.

But with the festive season approaching, I thought it would be nice of me to prepare a Christmas release. In AmigaOS4 quarters, there’s always a lot of eager expectation around Christmastime, and with operating system updates no longer being a given, the focus of attention has shifted towards software releases. The developer has inadvertently become some sort of Santa figure, so I didn’t want to disappoint and leave my users’ stockings empty. My only problem was which features I could realistically implement within the relatively limited time frame. After some thinking I opted for two main new features to form the core of the 1.4 update, which I scheduled for 25 December (of course).

One particular feature that didn’t make it into the initial releases of Rave is resampling – that is, changing the sample rate (a.k.a. sampling frequency) of the audio data. I didn’t consider it top priority because the typical sound material of today is no longer a mixed bag of data formats and properties as it was in the 1990s. Music software like Audio Evolution or MilkyTracker will happily import sounds available from major sample providers such as Loopmasters, which makes resampling somewhat redundant. But as one user rightly pointed out in a forum comment, oldschool tracker musicians will be less thrilled because Amiga programs of the ProTracker kind often use audio data sampled somewhere between 8 and 16 kHz. I had to agree that producing “tracker samples” from modern-day sound libraries can be a challenge in the absence of a dedicated resampling function.

My readers will know that I develop Rave with the aim of bringing innovation to audio editing on the Amiga. Therefore, I’m on the lookout for whatever industry standards and good practices can be brought over from major platforms, rather than trying to invent my own half-baked solutions. For resampling, I had my eye on libsamplerate, a platform-independent C library that is known to provide high-quality sample rate conversions. I even found an old OS4 port of the library done by Varthall in 2008, but I got discouraged seeing that in order to use it I would have to either pay a licence fee of 1000 Australian dollars (ouch!) or release Rave under GPL (ouch! ouch!). Luckily, when I visited the author’s website I discovered that the licence had changed in the meantime, so I no longer had to worry about restrictions. The unstoppable Fredrik Wikström was quick to provide a fresh port, and in early December I started working on the implementation.

The Resample window.

I wrote the Rave resampler as an independent program module, which can perform sample rate as well as bit depth conversions. I find this convenient because if you have, for example, a 24-bit / 44.1 kHz sample that you want to convert to 8 bits at 16 kHz, you can do this from a single GUI window (see above). The sample rate conversion supports both downsampling and upsampling, and libsamplerate really shines here. Unlike in most other Amiga audio editors, upsampling in Rave can actually improve the sound quality, as the library’s interpolation filters try to reconstruct the signal that would have been obtained by sampling at a higher rate.

There are four quality options to choose from, affecting the accuracy and speed of the conversion. “Best” is what it says on the tin, but it is really very slow: on a full-length audio track the operation can take several minutes, even on an AmigaOne X5000! On the other hand, the “Low” option (which triggers a converter based on simple linear interpolation) is very fast but sacrifices quality. The default setting is “Good” – a reasonable compromise between quality and speed. I should also add that the resampler module works asynchronously and doesn’t block the editor, so if the conversion takes longer than you would like it to, you can always switch to another project and edit it in the meantime.

Concurrently, I was also working on the other feature that I had slated for inclusion in the 1.4 update. My aim was to rework and improve the Fade plugin. “Wait a minute,” some of you will now say, “what on Earth can be improved about fading? I thought it was just a simple function that produces a gradual rise or fall in the signal level?”

You’re right, you don’t have to be a seasoned sound engineer to have practical experience with fading. Whether you needed to remove that nasty click at the beginning of a sample, or wanted to give your song a nice smooth ending, chances are that you launched your favourite audio editor and used the Fade In / Fade Out function. If you used your Amiga to do this, I’m pretty sure that your editor produced a linear fade, leaving you with a signal curve that increases or decreases in a perfectly regular fashion. Something like this:

A Moog Mother-32 oscillator sample with linear fades created in AmiSoundEd.

The problem is that while regularity will please a mathematician, the human ear may be less impressed. Have you ever felt that the fade-outs you apply at the end of your tunes sound a little too fast or abrupt, compared to songs you hear on albums? This is because your ears play a little trick on you. If you increase or decrease the signal level (which we perceive as volume) along a linear curve, the ear will hear it as if the sound level changes exponentially. Digital audio editors need to compensate for it if they want their fades to sound naturally. But do they – on the Amiga, I mean? Unless I’m mistaken, the only editor that lets you configure the fade curve is SoundFX, by way of applying a modulator:

Fading in SoundFX: the Amplify command with a modulation curve.

But this is all rather technical and clumsy to set up; I wanted something a bit more intuitive and easier to use. To start with, I introduced two pre-defined non-linear fade curves to complement the existing linear one. My favourite is the “Cosine bell”, which applies half of the Hann window function to the signal, producing a smooth transition between zero and full amplitude. An alternative is the “Sine lobe” (based on the Riemann window) with a slightly slower onset and more straightforward progression. I can imagine that in the future I’ll add a few more options, or even better, a control element to finetune the slope of the fade curve. But for the time being I’d say that the plugin does the job quite nicely – see the image below, which shows three different types of Fade Out applied to the same sample:

Fade Out options. Left: “Linear”, middle: “Cosine bell”, right: “Sine lobe”.

One more thing. As I wanted the new Fade plugin to be user-friendly, I thought it would be nice if the plugin window also provided a visualization of the fade curve, to give the user a better idea about the result. For this I wrote a custom BOOPSI gadget that displays simple shapes and curves. Nothing fancy at the moment, but I still find it a welcome addition. As Rave receives more functions and plugins, I expect the gadget to get more use in the program; for example, it could display various oscillator curves in future plugins that will generate sound through synthesis, or the like.

The new Fade plugin.

As any software developer will tell you, writing computer applications can often take unexpected twists and turns. So just when I though I had all the hay in the barn for version 1.4, I got a feature request from one of my users. Now, past experience has taught me to be very careful with feature requests and not try to please everyone. Because if you do, the development will soon lose focus and get out of hand. New features improve your program, but they also bring more work, add overhead, and postpone release dates. So I always try to ask myself first if a particular feature is really going to contribute and improve the workflow.

Moreover, users sometimes end up not using the features they have asked for. A software engineer once told me to beware of what he called “paratroopers” – random users who come out of nowhere urgently asking for a feature, only to disappear and forget that your program exists within a week. I made my own experience with a “paratrooper” years ago when I was working on the ADRipper CD converter, which I had taken over from its original author CentaurZ. A user I didn’t know asked for a new feature that required a great deal of rewriting of the program and its inner workings. I got burnt out in the process, the planned release had to be postponed by a year, and when I finally got it out the door the guy was no longer an Amiga user. A great lesson learned!

This time, the request was to add a timer that would measure and display how long it took to load or save a file. Despite seeing the potential benefit, I meant to dismiss the request for the time being because I didn’t want to jeopardise the Chrismas Day release. But the user, Mikael, promptly sent a donation through my Ko-fi page to show me that he was serious about it, and we started discussing the feature on Discord. The implementation of the timer wasn’t a problem; the problem was where exactly to display the reading in the program GUI. Mikael suggested an information requester but that wouldn’t work because Rave is asynchronous. In a multi-project session, operations can take place simultaneously in the background, so a requester could cause confusion about which project it actually refers to. But I promised to give the matter some more thought. The following day I came up with the idea that each project would keep an activity log to register all operations (not just loading and saving), including the completion time. The Project Information window seemed to be the most logical place to put the log in, so this is where it went after a quick redesign:

The Activity Log in the Project Information window.

And I must say that I grew to like the new feature soon! It’s very handy for testing and comparing the program performance on different OS4 systems – I wonder why I never thought of it before and instead bothered with a stop-watch?

Anyway, it’s past 7pm now and it’s high time I uploaded Rave 1.4 on OS4depot. I hope you’ll enjoy the new version, and I wish you all a very happy Christmas! Stay tuned for more updates in the new year!

The last five per cent

In management circles, there is a running joke that the last five per cent of a project takes 95 per cent of the entire completion time. If you’re a software developer, this funny paradox may ring some bells because it is in fact well rooted in experience. Your project proceeds quickly until it reaches a point where it is almost finished, save for a few little things that make it unsuitable for release. These “few little things” can turn the final phase of the project into a nightmare that will drag for months, if not years.

I learned my own lesson when I was working on my first AmigaOS4 application, the WordNet dictionary, back in 2009. I had only recently rediscovered the Amiga passion after nine years of solely using a PC, and I was very excited about developing for a community where every new piece of software seemed to make a difference. I had a rough version of the program going in about two weeks, with GUI and all – and then I spent two more months polishing WordNet and getting it to release state! One of the reasons was that I had to learn some OS4 specifics as well as brush up on things I had forgotten. But in all honesty, it was my poor planning that caused most delay. The notion of the minimum viable product completely escaped me at the time, and I kept adding feature after feature until I was overtaken by fatigue and frustration.

It may appear that I fell into a similar trap with the Rave project, especially if you remember that in my previous blog post I was hoping to be able to release the program before the end of March. But the reason was different this time, and I can honestly say that the release would have happened if only things didn’t get the better of me again.

While stress-testing Rave in early spring I realized a design flaw in the program’s project management system that made it difficult to reliably and safely abort an operation in progress. As re-designing the inner workings of Rave would take a considerable amount of time (which I didn’t have), I thought I’d release the program as it was and improve it later. However, towards the end of March the school I work for informed me that I’d be supervising a group of students during their internship in Germany, which was supposed to take place in May. The idea of spending a whole week free of parenting pressures clicked with me in an instant, because it smelled like an opportunity to have a closer look at the problem.

The internship was in Chemnitz, a city in Saxony formerly known as Karl-Marx-Stadt. It soon became obvious that my students’ training was organized with the proverbial German thoroughness and efficiency, which rendered me virtually useless as a supervisor because everything had been taken care of. So I had even more time on my hands than I had expected, and (with the exception of an occasional sightseeing stroll) I spent most of the week in my room chasing bits and bytes on my trusty laptop.

With Karl Marx and my students.

The ability to concentrate on Rave for several hours a day made a world of difference, compared to my weary late-night sessions at home. I remember a forum post in which a well-meaning Amiga user tried to motivate developers by telling them to try and sit down to programming every day, even if for five minutes only. But this is not how it works, unfortunately. In reality a programmer can do little work in an hour, let alone five minutes – especially when working on a large project. In this regard the week in Chemnitz turned out to be a heaven sent. Diving in with full focus allowed me to completely rewrite the project management system including the plugin API and the I/O module; something that otherwise might take months to achieve. The result is a simpler design that is more reliable and requires less communication between the individual program components.

Among other things, it is now easier to create a plugin because the main program and the plugin master module have newly been entrusted with certain common chores. The plugin architecture surely needs more work: currently only processing plugins are supported, i.e. ones that take audio data and modify it. This is suitable for applying effects, but I’d also like to introduce plugins that generate sound, or simply analyze the data and display information about it. It’s going to take quite some time before the architecture becomes good enough, but when it does I’ll open it up so that other people can develop plugins for Rave if they feel like it.

And of course: the problem that started it all is now gone, so as I’ve already told people who follow me on Facebook or Ko-fi, any operation in progress – that includes loading, saving and processing – can now be safely aborted by pressing the Escape key. I actually think that Rave handles aborting better than SoundForge Audio Studio 16, which is my go-to editor on the PC. When you abort an operation in SoundForge, the program displays a confirmation requester but the operation continues uninterrupted. So if you take your time and don’t click on the “OK” button right away, the operation may have already finished in the meantime. I don’t find this very useful (or logical), to be honest. In Rave, the operation waits until you deal with the requester, and then it either continues or stops. This, I believe, is the expected behaviour, and it’s one of the benefits of my rewrite.

Aborting in the middle of a level change operation.

Most importantly, the program is now ready to hit the world. During the past year there were moments when I seriously doubted I’d ever be able to say it, but: I’m happy to report that the last five per cent of the project have been completed, and that the initial version of the Rave editor can finally be downloaded from OS4depot. Saying it feels so great that I’m tempted to say it again, which is plain silly but you can imagine how happy I am now that the weight is off my chest. It feels like dropping a stone the size of the Karl Marx head in Chemnitz!

Raving on: Part 3

Christmas 2021 was approaching fast and it was clear to me that I’d miss the magic release date again. Sigh. I had been working on the Rave audio editor for well over two years, and you can imagine how frustrated I was that I still wasn’t ready to put out a working version, with all the features I had envisioned for the initial public release. Worse: I began to fear that – despite documenting the development process on this blog and posting screenshots on Facebook – some of my followers might have got sceptical enough to believe that the program is nothing but vaporware! Luckily, around the same time I got an e-mail from Roman ‘kas1e’ Kargin, one of the driving forces behind several exciting AmigaOS4 developments. Roman’s message read along the lines of “Hey, how about you send me a demo and I’ll make a video of it, showing the program in action?”

I hadn’t thought about making a video myself because, first, I lack the skills and experience to do so and, second, such a task would only eat more of my precious time for Amiga programming. But I knew that a video is worth a thousand screenshots, so I gladly accepted Roman’s offer and waited eagerly for the outcome. He released the video on Boxing Day, and as it appears now, I couldn’t have hoped for better timing. The festive period always brings a lot of expectations in the Amiga camp, so there was a chance that some big news would steal all the attention. But last year’s Christmas was rather short on major OS4 releases, so I was happy to see that the video got noticed all right. In case you haven’t seen it:

Now that Roman’s video has shown that Rave is alive and well, you may be wondering what the actual hold up is. In all honesty, the main culprit is my perfectionist self. I know the advantages of the “release early and improve later” approach, but that’s not how I work. I hate to release something that I don’t consider good enough, and while I understand that the notion of “good enough” is relative and subjective, this is simply how I felt about Rave towards the end of the year. Not that the program suffered from major quirks, but there was one missing feature that – if the editor got released – would surely attract negative comments, making Rave look worse than it is. That missing feature was MP3 support.

“No MP3 you say? Unthinkable!” The reason why Rave wasn’t ready to handle the popular format is that it wasn’t supported by libsndfile, the audio library used by my editor’s I/O module. At that point, Fraunhofer’s MPEG audio patents had already expired but although the main obstacle was gone, the author of the library didn’t seem to care. I was contemplating writing my own MP3 handling routines when a forum post mentioned that one of the new libsndfile maintainers had finally started looking into it. This sounded like good news! A new public version was finally released in January 2021, and guess what – MP3 support was still missing. “Never mind, it’ll come later in the year,” I thought. And then suddenly Christmas was around the corner, and it was clear that Rave would unfortunately have to stay on the back burner a little longer.

Nevertheless, the positive feedback I received after Roman’s video appeared on his YouTube channel gave me a little push. Shortly after New Year’s Day I contacted Fredrik Wikstrom and asked if he could port the latest non-public version of libsndfile for me. I estimated my chances as rather slim because Fredrik, on top of being a core AmigaOS4 developer, is busy working on his own projects. Well, he got back to me three days later and didn’t even bother to say “yes” – he sent me the ported library right away! It wasn’t the first time Fredrik had helped me, so I didn’t hesitate to visit his website again and use the Donate button at the bottom of the page. Really, it’s people like Fredrik who embody the wonderful Amiga spirit, and I’m eternally grateful to them for keeping the boat afloat.

Using a non-public, under-tested version of a library written for a different operating system was, naturally, a bit of a gamble. But I’m happy to say that things went smoother than I had expected. Now that the last missing piece was in place, adding MP3 support in the editor was just a matter of a few lines of code. One great thing about using a library like libsndfile is that when a new audio file type is added, Rave will automatically benefit from the addition. The version sent by Fredrik also came with an unexpected bonus: the Opus format (a relatively new member of the Ogg family), and MP3’s less successful predecessor MPEG Audio Layer II, better known as MP2. So after a simple re-compile of my I/O module, Rave added three new audio formats in one go! The current number of supported file types is nineteen – I wonder if there’s an Amiga editor that could top that?

The file requester showing the current list of supported audio formats.

So what’s left to be done, and how far are we from getting the thing out of the door?

There are a few things I’m working on at the moment. First of all, saving needs configuration code and GUI for the individual formats, which I’ve been adding one by one. Only major audio formats are going to be supported in the initial versions of the program; saving in less common formats will come at a later point if there’s interest. Tracker musicians will probably be pleased to hear that saving in the legacy IFF-8SVX format is already implemented, though only in mono for the time being. (Given the cherished image of the Amiga as “the world’s first multimedia computer”, it is hard to believe that Electronic Arts’ original IFF specification didn’t consider stereo waveforms – support for them was only added later by a third party. Unfortunately, IFF files store stereo data in a non-standard way that libsndfile doesn’t support, so I need to write my own saver. Oh bother!)

To add insult to injury, one of my testers has reported certain memory-related problems on his Sam460, which we’re currently looking into. To this end I’ve dug up my old Sam440ep-Flex from storage and re-installed it so that I have one more machine for testing; I really want Rave to work plausibly across the OS4 hardware range. With its low specs the Sam is more suitable for simulating dire memory conditions (you simply run out of RAM more quickly) compared to my X5000, and I’ve already fixed an out-of-memory problem that my trusty old computer helped reveal. So things are looking up and if no more roadblocks come in the way, the Rave editor should hit the wild in a couple of weeks. As usual: stay tuned and watch this space.

Raving on: Part 2

It’s six weeks into the summer holidays – although this year, the word holidays rings a bit ironic to me because I don’t remember ever being so busy during summertime. Thank goodness, my current workload is not related to my day job, so paradoxical as it may sound, I’m getting a lot of enjoyment from sweating my guts out in this hot weather. Yes yes yes, I’m finally back on track, trying to catch up with my Amiga projects! And because I last published a progress report four months ago, I think it’s now time to take a little break from programming and bring my readers up to speed. So what’s the latest on the Rave audio editor?

The majority of work I did in the past weeks related to the sample editing functions and improving clipboard support. What I see as my main achievement is that all editing operations are now asynchronous. So when you, for example, copy a large chunk of audio data into the clipboard (which can take some time, especially on low-end systems), you can continue working on another sample. Sounds easy but in a multi-project environment, making things asynchronous involves much more than just disengaging the window’s busy pointer! As each project runs on a separate DOS process, you need to design an underlying system that manages the operation of the program components and synchronizes access to shared resources. Rave has had such a system from Day 1, but asynchronous editing required making it more sophisticated and robust. Think of building a house: you really want it to stand on solid foundations, otherwise things will start falling apart as the construction continues!

In a program where certain functionality is provided by components running on separate processes, the first thing you need to ensure is that no “stray” processes are left running when the program ends. AmigaOS4 makes this easier thanks to certain new features in the DOS Library. One of the many great additions brought by the OS4 DOS is that processes can be put in a parent–child relation. In other words: when you start a sub-process that serves the main program process, you can identify the sub-process as a “child” that is resource-dependent on its “parent”. Unlike in older AmigaOS releases, the parent process cannot quit while its children are still running about. To help synchronize process ending, the OS4 DOS has introduced “death messages”, through which child processes can notify their parent that they’re about to quit. Implementing death messages in Rave represented one step towards solidifying the program’s project management system.

Other steps were aimed at better organizing project activity and safeguarding access to shared program resources. To that end, Rave utilizes a simple but effective message-passing mechanism that boils down to the following. Whenever some kind of interaction takes place between the main program and a child component (a module or a plugin), the one that initiates this interaction sends a message and waits for a reply confirming that everything is OK: an operation has started, data has been received, and so on. Only after receiving the confirmation message is the main program or the component allowed to continue. This helps keep things in line and avoid all sorts of potential collisions and race conditions. A welcome “side effect” is that, by imposing order on what the individual program parts do and when they do it, the confirmation messages also help in arbitrating access to shared resources. Together with mutex protection (another new feature brought by OS4), they represent an additional layer of robustness contributing to a greater stability of the program.

I got a little technical here to give you an idea of what kind of work has been done under the hood, and I’ll now focus on things that are hopefully more “visible”, or at least less abstract to describe.

Asynchronous editing quite logically led to another improvement: support for multiple clipboard units. I say logically because Cut, Copy or Paste operations wouldn’t really be asynchronous if the project needed to wait for another project to finish using the clipboard. I’ve mentioned above that a clipboard operation involving a large portion of data can take quite some time on the Amiga. (Ever tried copying 20 minutes of high-definition audio? Be my guest!) During this time the current clipboard unit is busy, but Rave now allows you to switch between units 0-2 on the fly, making it possible to have up to three operations accessing the clipboard concurrently if needed. The default unit can of course be configured in the settings. During program runtime, unit selection is done from the main menu, or through keyboard shortcuts which – as the screenshot below shows – cannot possibly be more mnemonic:

Selecting clipboard units from the menu.

Speaking of this, I should probably explain – at the risk of getting technical again – how Rave stores the clipboard data. AmigaOS specifies that data in the clipboard needs to comply with the Interchange File Format (IFF). However, this specification is not good enough for modern audio applications because the original IFF standard only accounts for 8-bit audio data. Unlike MorphOS, which said goodbye to this legacy and wisely adopted the much more versatile AIFF container for sound clips, AmigaOS4 hasn’t dared to go this far yet. Without an updated official specification clearly saying how to put 16-, 24- or 32-bit sounds in the clipboard, the actual implementation is pretty much left up to the developer. Which is never a good thing, considering the legendary creativity of Amiga programmers.

To be on the safe side, I have used the same hybrid solution that Fredrik Wikstrom devised for his AmiSoundEd editor: 8-bit audio data is stored in the old IFF-8SVX format to make clipboard exchange backwards compatible, whereas anything above 8 bits is formatted as AIFF. To be honest, I’d much rather go the MorphOS route and do away with 8SVX altogether (especially as there is practically no audio software worth striving for compatibility with). My code is perfectly ready for the change, but unless OS4 adopts a new standard, things will stay this way.

Because in real use it’s easy to lose track of what you’ve put in the clipboard, I have implemented a simple information window that displays the properties of the data stored in each clipboard unit. The images below show the current contents of the three supported units:

The Clipboard Information window.

And as you will no doubt find it useful to have similar information about the projects you are working on, I have added a window that shows detailed project properties. The Project Information window is accessible from the menu as well as from the program toolbar. The window also incorporates a Metadata section, in which you can view and edit some common metadata strings to be stored together with the audio file:

The Project Information window.

Well, that’s about all I can share at this point – I think I’d better get back to work now. I’ll post another progress update in a few weeks, during which I hope to revisit and update Rave‘s plugin framework (or whatever will call for attention). Stay tuned and watch this space!

Raving on

“April is the cruelest month,” says T. S. Eliot in the opening of his most famous poem, The Waste Land. Well, I sincerely hope this year will be an exception because I’d say that March was tough enough. The Covid-19 pandemic got a little out of hand here in the Czech Republic, resulting in another hard lockdown, so I really wouldn’t like to see April compete in cruelty with its predecessor!

I had every intention to release a beta preview of the Rave audio editor before the end of the month, as I had announced in my December post. But given the circumstances, I just couldn’t get to the finish line. With daycare facilities closed as of 1 March, my wife and I became full-time teachers, activity leaders and cooks on top of our daily jobs, and although our five-year-old is a great little fellow, having him around 24/7 doesn’t leave one with much time and energy for programming. I normally enjoy my late-night Amiga sessions, but with so much to do during the day I often struggled to stay awake past 8pm. So, quite understandably, March has seen much less progress than I had planned and hoped for. To add insult to injury, at the time of this writing I still haven’t got the foggiest idea when the lockdown will be lifted and I’ll be able to pick up speed again.

Ironically enough, March was an exceptionally good month for AmigaOS4, with some major releases seeing the light of day. The cross-platform multimedia-oriented programming language Hollywood went up to version 9, bringing the biggest update in six years (see this link for a non-exhaustive list of new features). A few days later we saw the much-anticipated Release 2 of the Enhancer Software pack, the undisputed high point of which is hardware-accelerated video playback and various improvements to the graphic subsystem. My favourite media player AmigaAmp also got updated in March, and as if it were not enough, on the very last day of the month Harald Kanning made a surprise release of a new AHI driver. Amiga platforms (classic or next-gen) don’t see AHI drivers released very often, so the choice of OS4-compatible sound cards has until now been rather limited. What Harald’s driver brings to the party is cards compliant with the Intel HD Audio specification, which are cheap and easy to come by. This means that one no longer has to resort to older models, which often can only be sourced second-hand.

So it’s not that AmigaOS4 users have no new toys to play with at the moment – quite on the contrary. But given my inability to add to the string of happy releases I feel it would at least be fair to give some news on Rave. So this is a brief development progress report and a summary of what I managed to do in the past month or so.

First, my old friend Jan designed a logo for Rave and also provided me with some additional graphics for the program. Jan and I have collaborated on various projects since the early 1990s when we both were in the demoscene, and although he’s now a busy professional lad (and probably looks upon my continuing Amiga passion with a benevolent smile), he has never turned me down when I needed his skills. Thanks to his contribution I was able to implement a simple splash screen that indicates the progress of the program start-up:

I also found some spare time to extend the program’s Edit menu and add several new functions to control sample range selection and manipulation. On top of the usual Cut, Copy and Paste combo, I have implemented the highly useful Trim (only keeps the selected range and removes everything else) along with Clear (sets the selected sample data to zero), Delete (same as Cut but does not copy the data into the clipboard) and Grab (creates a new project containing data copied over from the selected range). The new Paste Special sub-menu extends your pasting options with some handy functions for specifying the position at which the clipboard data should be inserted. Furthermore, in order to make range selections easier, a few related commands have been added to the Edit menu as well. All this means that although the initial version of Rave will be relatively basic and limited (especially as regards the number of effect plugins), it should at least get you covered for reasonably comfortable waveform editing.

The Edit menu.

Nevertheless, the program component that has lately received the most attention is the file requester module. One of the early screenshots I published shows that Rave utilizes a custom file requester, instead of the standard one provided by the system via the ASL Library. While this may sound unnecessary, there are good reasons why I decided to go to such lengths. Above all, the ASL requester falls very short when it comes to customizing it for the needs of more complex software. For example, in a modern audio editor you will expect to be able to enquire about sample properties, possibly even preview your sounds before you load them. Similarly, when you save audio files you’ll want to configure the output format from the file requester rather than via a separate configuration window (as is typically the case in Amiga sound editors). This leaves the ASL requester out of the question: you need to develop your own.

In Rave, file selection is handled by a separate program module implemented as a private BOOPSI class. The initial idea was to make it streamlined for audio use, focusing particularly on the features my editor needed. The result was a requester that did its job (except for audio preview, planned to be implemented later) but lacked some of the ASL features. Certain properties such as file display order were not configurable, the requester did not support DOS links (because audio files are rarely linked), and there were no functions for file management such as Create New Drawer or Rename. But after some time, second thoughts crept in. I realized that with the ASL requester being so ubiquitous in AmigaOS, many users would take its features for granted and might consider my custom replacement half-baked. Therefore I took to adding more functionality, as the March situation permitted, to get closer to the original. And I think the current result is a very good compromise: it retains a lot of the ASL look and feel, while being tailored for the program’s needs and closer to what you see in professional audio software on other platforms.

The file requester (with the Control menu open).

So the good news is that although the plan to march on in March kind of fell through and the beta version will need some more time to get completed, Rave has still received quite a lot of love and the development is certainly going on. Which reminds me of the old I Ching that says: “Going on means going far” – I really like the sound of that!