Saturday, December 27, 2008

Getting more quality from onboard sound

Onboard high-definition audio chips are very common now. From the viewpoint of software, they support unbelievable quality of sound reproduction: 24 bits of precision at the 192 kHz sampling rate. The reality is in fact worse, as there is always noise in the analog output that the headphones are connected to.

I am not talking about the thermal noise or 1/f noise that is created intrinsically by every electronic device and sounds like a soft "shshsh...". These kinds of noise are important in radio receivers or tape recorders that have a high-gain amplifier needed to recover a weak incoming signal, but not in computers.

I am talking about the interference, where the signal in one wire (not intended to be played as sound) propagates into the other wire located nearby or to another circuit connected to the same badly-filtered power supply. The exact sound of such interference depends on what the computer is doing. If the computer is doing something periodically (e.g., drawing a scene on the screen 60 times a second, or filling a sound buffer in JACK 500 times a second), this unwanted sound becomes a tone, and thus becomes easily noticeable. Here are the steps that helped me to reduce it in my desktop computer based on the Intel DG965SS motherboard.

First, the wire that picks up a lot of interference is the wire that connects the front headphone socket to the motherboard. It is better to avoid using the front socket at all, and plug the headphones (if the cord is long enough) into the green socket on the back of the motherboard. This way, the cord is screened from the noisy components inside the computer by the metallic case.

Second, it may be a good idea to reduce the time variations of the power consumption of various components in the computer.

E.g., the processor draws a lot of power when it is busy, but consumes less power when it is idle. When it switches between the busy and idle states periodically, it creates a tone in the power line, and that tone ultimately gets to the sound chip output. So, to suppress the tone, one solution would be to keep the processor always busy. This is what the "idle=poll" Linux kernel parameter does. Note that a busy processor runs hot (in my computer, at 47.0°C), so think twice before using this option. A less dragonian solution would be to pass the "max_cstate=3" parameter to the "processor" module. (A big "thanks" goes to Robert Hancock and Sitsofe Wheeler who suggested these parameters.)

The other component of the computer that periodically draws a lot of power is the video card. But it is easier to keep it mostly idle, not busy. The most common desktop process that keeps the GPU busy is a compositing window manager (kwin or compiz). So, disable desktop effects, and enjoy better sound quality.

Saturday, December 13, 2008

JPEG quality is a meaningless number

Suppose that a web designer tells you:

Your task is to make a script that creates images for this web page. The images should be in JPEG format, have such-and-such dimensions, and their quality should be this number of percent.


Ignore the bit about the desired quality, especially if the web designer uses Adobe Photoshop and has tested his page only with images made with Photoshop. The reason is that the same number yields different quality in different applications. Let me demonstrate this using this original image.

The image has been resized to 400x300 pixels using Photoshop (that contains Adobe's own JPEG encoder) and GIMP (that uses libjpeg from IJG, as many web scripts do). Here are the screenshots of the corresponding settings.

Photoshop:
Photoshop setup

GIMP:
GIMP setup

As you see, both programs are set to optimization of Huffman tables, no smoothing, no chroma subsampling, and 60% quality according to their scales. Here are the resulting images.

Photoshop:
Parrots, compressed with Adobe Photoshop

GIMP:
Parrots, compressed with GIMP

As you can see, the image created by Adobe Photoshop is almost perfect, while on the image created with GIMP there are visible artifacts in the form of double contours around the parrots in the top row. This is not what the web designer wanted.

Here are some statistics. The image made with Photoshop takes 46 KB, while the image made with GIMP takes only 26 KB.

The quantization tables stored in the JPEG files are also different. If you don't know how to interpret numbers in them: the bigger the number is, the more precision is lost. The closer the number is to the right or bottom, to finer horizontal or vertical details it corresponds.

Photoshop:

Luminance Chrominance
6 4 4 6 9 11 12 16 7 7 13 24 26 31 31 31
4 5 5 6 8 10 12 12 7 12 16 21 31 31 31 31
4 5 5 6 10 12 14 19 13 16 17 31 31 31 31 31
6 6 6 11 12 15 19 28 24 21 31 31 31 31 31 31
9 8 10 12 16 20 27 31 26 31 31 31 31 31 31 31
11 10 12 15 20 27 31 31 31 31 31 31 31 31 31 31
12 12 14 19 27 31 31 31 31 31 31 31 31 31 31 31
16 12 19 28 31 31 31 31 31 31 31 31 31 31 31 31


GIMP:

Luminance Chrominance
13 9 8 13 19 32 41 49 14 14 19 38 79 79 79 79
10 10 11 15 21 46 48 44 14 17 21 53 79 79 79 79
11 10 13 19 32 46 55 45 19 21 45 79 79 79 79 79
11 14 18 23 41 70 64 50 38 53 79 79 79 79 79 79
14 18 30 45 54 87 82 62 79 79 79 79 79 79 79 79
19 28 44 51 65 83 90 74 79 79 79 79 79 79 79 79
39 51 62 70 82 97 96 81 79 79 79 79 79 79 79 79
58 74 76 78 90 80 82 79 79 79 79 79 79 79 79 79


So indeed, Photoshop saves more details than GIMP at the indicated settings. The meaningless quality percentages match, the actual quality settings don't. In order to achieve in GIMP (and thus in web scripts that use the same libjpeg library from IJG) what the web designer actually meant, one would need to use quality=85% or so.

Saturday, December 6, 2008

A way to lose a file

The ln command from GNU coreutils warns when the source and the destination of the attempted hardlink are the same file, and does nothing:

$ echo 123 >testfile
$ ls -l testfile
--rw-r--r-- 1 aep aep 4 Dec 6 15:08 testfile
$ ln testfile testfile
ln: creating hard link `testfile': File exists
$ ln -f testfile testfile
ln: `testfile' and `testfile' are the same file
$ ls -l testfile
--rw-r--r-- 1 aep aep 4 Dec 6 15:08 testfile


Its counterpart from FreeBSD, however, doesn't warn. Instead, it erases the file.

$ echo 123 >testfile
$ ls -l testfile
--rw-r--r-- 1 aep aep 4 Dec 6 15:08 testfile
$ ln testfile testfile
ln: testfile: No such file or directory
$ ls -l testfile
ls: testfile: No such file or directory

Fixes

Some time ago, I mentioned in this blog some bugs that annoyed me. Some of them got fixes:
  • Speaker-test fails with pcsp: fixed in ALSA Git.
  • Kernel panic due to iwlwifi: fixed in linux-2.6.27.6
  • Internal compiler error in GCC-4.3 on proprietary code: fixed in GCC SVN, the fix will be a part of GCC-4.4.