Confessions of an Audioholic

blog_devThe HDAudio driver has recently been released to AmigaOne X1000 owners. This driver supports the built in “high definition audio” chip used in this computer.

I am the last coder to work on this driver, but like a relay race, much of the hard work was done before it was passed to me. Davy Wentzler, Alex Carmona, and René W. Olsen did a lot of the heavy lifting before I started on the project.

As far as I know, this is the first AmigaOS 4 driver to support the High Definition Audio standard. this is a new specification from Intel, destined to replace the older AC97 standard. This new standard includes lots of improved specifications in audio fidelity.

We can now play sound out the back and the front headphone at the same time. This has led to having “All” as an option when choosing an output.

It is possible to signal the software when a plug is inserted or removed. And it’s even possible to do a quick “impedance check” when a device is plugged in, and then make a good guess about whether it is a microphone (low level), stereo feed (line level) or the output from an MP3 player (higher level).

The HDAudio standard offers us a lot of new features that we will be exploring for a while to come.

The process of “bringing up” this driver included a few good challenges.

AHI reads a “modefile” that describes the basic features of the sound driver. It opens the driver and asks it to go looking for a matching sound card. If one is found, the driver / card is added to the system.. but when sound gets played it gets more interesting..

AHI specifies to the driver how many channels, how many bits per sample, and how rapidly the samples are about to start coming in. The driver needs to set up the sound chip for this, but it really NEVER talks directly to that chip! Instead it sets up the SB600 (Southbridge) with details about buffer sizes and all the other info that AHI just provided. It also builds up a “command buffer” for talking to the sound chip, and a “response buffer” that lets the chip answer. So we now have the southbridge set up to carry sound for us, and to also handle all our control communications with the sound chip as well.. Easy, right?

Imagine how overwhelmed I was on the first day of reading all this code!


Amiga 1000

Fortunately the ground work was well done already. I started by just testing the ability to send commands and get responses. Looking over the documents, I see a command to tell the chip to “beep” all by itself, without any audio data. That was the first success! Not too fancy, but it’s proof that we can talk to the sound chip. Alex Carmona picked up that code, and used it to make a “boot sound” for X1000 owners that sounds a LOT like the original Amiga 1000.

Next up, I separated the AHI part from the SB600/sound chip part. My thinking was that it’s easier to divide and conquer. Then I worked hard on opening the audio path to the sound chip. Before too long, I had noise, but it never sounded quite right. It turned out that the buffers feeding in to the sound chip had to be handled a bit differently. I’ll try to explain:

The normal way to feed a constant stream is called double-buffering. The idea is simple. While the audio chips are playing buffer A, I’ll be filling the next sounds into buffer B. Once the player moves into buffer B, I’ll fill more into A, and keep on going. Simple, right?

Of course it is never as easy as it sounds.. A bit of digging and I learned that instead of two separate buffers, the SB600 really wants one continuous block of memory! Simple enough, I’ll just get one big block, and draw an imaginary line halfway through it.

Now to keep things simple, I start by asking AHI what size it’s buffers will be, then I make the SB600 buffers the same size. Really one big buffer the size of BOTH AHI buffers combined.. but the sound wasn’t right yet. Keep digging.. AHI gets the buffer size it wants, the SB600 gets one big buffer, which looks to AHI like two buffers side-by-side.

Now it turns out that the sound chip has buffer size limits too, and they are a LOT smaller than any of the previous buffer sizes!

The final result is one big memory block for the SB600, split into two buffers, each sized to match what AHI wants, with each of those buffers split into as many smaller “segments” at or below the max size that can be handled by the sound chip. Wow. One block of memory divided up three different ways, depending on which way you look at it.


Not the KISS principle

I’ll mention here that I was looking for ANY way to make it simpler.. and all of this “memory geometry” would change with every change in sound settings! So the K.I.S.S. principle took over. I decided to configure everything AFTER AHI to ALWAYS run in 8 channel 32 bit quality. Running that way, I can easily “upsample” ANY sound format coming out of AHI to one stable format. If AHI sends me mono, I copy it to left and right, and zero the other six. If it sends stereo, the last six stay muted too. If it sends me 16 bit audio, I just shift it to the high word of the 32 bit samples.

Once all that buffer stuff was wrestled into submission, we finally got good sound coming out!! Success!!!

The modefile that came with the driver had only ONE mode. Not really a good way to show off such powerful audio chips. But the previous modefiles were created with tools that we don’t have, and I could find NO documentation.. So I got to spend a day or two studying the modefiles. Once I got a good idea of how they worked, I wrote a program called “makemode” that converts a text file to a working modefile. If you need a tool, write it! This expanded our driver capability to as many modes as I choose to support (currently 3, including 7.1 audio). And as a side benefit, new modefiles can be created as quickly as they can be described. The sample rates have been increased as well. This chipset and driver support up to 192kHz, that’s about four times higher than the old “normal”.

The Beta test team has been a HUGE help in finding the little bugs that I missed. These last few versions have been pretty well behaved. If you are reading this then a public release must be “real soon”. We still have more to do, S/PDIF optical output and sound recording are still on the “to do” list. But the sound is playing, and that’s not a bad place to be today.

It has been a big team effort. Davy, Alex, René, the Beta team, and Steven for taking ENDLESS emails when I ran out of hair to pull out.

If you really read all the way to here, you get a special bonus tip: When you open SYS:Prefs/AHI to adjust the driver settings, you might try dragging the prefs window a LOT wider. The rear-panel connections for line out, line in, and microphone in are all described with the color of the correct connector listed. With six color coded jacks on the back, this might be helpful to get it into the right hole in one try. 🙂

Now that X1000 owners have an open PCI slot, what will be the most popular new “toy” to play with ?

Comments are closed.