Archive for June, 2007

S/PDIF with the AD1988 HDA codec

June 18th, 2007 by papillon

At first, it was totally easy to get the sound output working. The kernel that Kubuntu 7.04 installs by default already includes the necessary ALSA drivers for Intel HDA and the AD1988 codec, so I did not have to do a thing.


That is only fine for the analog outputs, though. The digital signal that the chips spits out is unusable, since it is totally distorted. It sounds like as if the volume has been set way to high, and even with the volume turned halfway down, the distortion is still slightly noticeable. Since I usually listen to music with headphones that are connected to an external DAC, and I am probably a borderline audiophile type of person, this was clearly not acceptable.

My first foray into the world of ALSA drivers ended with a few lost hairs, some empty bottles of basic bavarian nourishment (a.k.a. beer), and the empty feeling, that I do not have a clue about hardware level programming. After looking at the functional diagram of the AD1988 I had some ideas what might be wrong, but I couldn’t point my finger to the relevant code. I was suspecting that the driver sets the amp gain for the digital out too high, but eventually I gave up. The fact that the output was fine after a complete cold boot and then suddenly began to distort again, did not help my motivation either.

A few days later, I was about to order a PCI soundcard which looked promising (M-Audio Audiophile 2496), but somehow I wanted to take another stab at the ALSA code before hitting the order button. As it turned out, this was a good idea.

After studying the Intel HDA documentation and again looking at the code, I started to at least see the tip of the iceberg and found something interesting. The codec is initialised according to tables in patch_analog.c, and one of the tables takes care of the S/PDIF widget NID:02:

static struct hda_verb ad1988_spdif_init_verbs[] = {
        /* SPDIF out sel */
        {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
        {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
        /* SPDIF out pin */
        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x17}, /* 0dB */
        { }

The input to the widget NID:1D receives input from the PCM stream coming from the computer, and mixes it with input from one of the three ADCs that are connected to line in, microphone, and other input plugs (ADC1 in this case).

Now, according to the output of cat /proc/asound/card0/codec#0, those three ADCs are muted, and thus should not send any input to the 1D widget. Unfortunately, they do, anyway. I am not sure why, but muting everything expect the PCM stream, by changing the fourth entry above, makes the distortions go away:

        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},

Maybe it is a bug in the codec, maybe it is some other bug in the ALSA drivers. Especially how it mutes the ADCs NID:08, 09, and 0F looks fishy:

        /* ADCs; muted */

According to the functional diagram, those have no amp and thus cannot be muted. The audio selectors that input to the ADCs have, but muting these did not solve the problem in my tests.

Note: This change means that you will not get any sound from the inputs back in to your S/PDIF stream any more. Personally, this is an entirely acceptable solution for me. Oh, btw, this has been done with ALSA 1.0.14.

Playing with Jinzora

June 16th, 2007 by papillon

After a couple of hours of organizing my 25 mp3 clips, and ripping some CDs, it occured to me that it would be nice to also add internet radio stations to the mix, integrated into Jinzora.

Basically, this is supported, but it does not work out of the box. You can add a dummy structure to your music collection (i.e. empty folders on your hard disk), and then add so called “link tracks” to that structure (mine looks like Internet Radio – Pop Radio – Various – Radio 1,2,3… and so on), but Jinzora begins to act up when you do this.

After a couple of hours of debugging, I found the root of the problem. Before the change, using the function “add link track” resulted in a PHP error in jukebox.php, and clicking on the newly created link resulted in a playlist that contains all files from the entire collection, which is of course not desireable.

1) Change frontend/blocks/jukebox.php around line 323 like this:

if (is_object($parent)) {
    $artist = ucwords($parent->getName());

Web streams seem to have no parent, so we need to check for a valid object before trying to get the name.

2) In popup.php around line 4646, after

if (isset($_POST['edit_taddress'])) {
 $path = array();
 $path[] = $_POST['edit_tname'];


$path['filename'] = $_POST['edit_tname'];

This effectively adds the link’s name to the two database entries that are generated for a link, i.e. in the tables jz_nodes and jz_tracks, the name is added to the path column. Without the name, Jinzora generates non-unique entries and then simply adds ‘/’ to the playlist, meaning the whole collection…

I don’t really know PHP, I just seem to stumble upon it once in a while, so take this with a grain of salt. Nevertheless, this works fine for me.

Jinzora web interface

June 14th, 2007 by papillon

I have installed my dream team on the new box today: Jinzora and MPD (Music Player Daemon).


Jinzora offers an elegant way of accessing your music collection, and it seems to be a quite mature project. It is compareable to desktop programs like iTunes, but with a twist: Jinzora can be used in two ways. It can either stream the music to your music player over HTTP (essentially, your own private internet radio), or it can be run in Jukebox Mode, with MPD as the backend music player. This means you can take your whole collection music with you, wherever you are, as long as you have internet access. Well, who am I kidding, my whole collection would probably fit on an iPod nano, but hey, I like to have some options for the future, ok ?

Music Server – new project

June 11th, 2007 by papillon

The components for a long planned project of mine finally arrived:

Asus Pundit2
Asus Pundit Barebone

I ordered it with a Core 2 Duo E4300, 1 GB RAM, 250 GB Harddisk, and some silent upgrades. Should be enough for music serving and yet-to-be-defined other tasks. The onboard sound, an Intel HDA with an Analog Devices AD1988 codec, is ok according to the paper specs, but gave me a thourough headache later on, which is another story.

The whole project will be using Linux, specifically Kubuntu. After doing some research, this seems to be the only platform that provides the flexibility that I need for my plans:

  • Headless operation
  • Web interface to music collection
  • Infrared control for basic music control
  • Stable platform for the next 5-7 years
  • Full control from mobile phone, notebook, desktop PCs
  • Basis for later addition of a Squeezebox
  • Good price to value ratio, that makes it viable to buy a new PC just for music serving.

Current state of affairs

June 9th, 2007 by papillon

Long time no update, but of course I haven’t been sitting on my lazy ass since January :-).

Finally, Obsidian Entertainment included special functions for NWNX, that improve the interface between NWN2 and NWNX4 considerably ! The new NWNX4 is not only faster, it is also 100% safe from any future modifications that might ever be done to NWN2, since the dependency on SetLocalString is now gone.

I am currently working on closing some open bugs and getting an installer for 1.08 done.