Undervolting: what and why?

Fan noise is always annoying. Even more so for those of us who use them in audio-related tasks, where it can interfere with the work we are trying to accomplish.

Some CPU families, normally high-end ones, are programmed to operate at what is considered a safe voltage level, but allow to be configured by the end user to work at even lower voltages.

This means the CPU consumes less power and dissipates less heat. Less heat means less need for fans to cool down the CPU so, besides the noise reduction, we get a second source of power saving.

By undervolting our CPU we achieve less power consumption, longer battery life and shorter bursts of fan noise.

We can combine this with other power-saving techniques like CPU frequency management or CPU throttling to achieve silent or near-silent operation under light CPU load conditions, depending on the environment temperature and the thermal features of our laptop.

However, there is a caveat: if we lower down too much the operation voltage the CPU may become unstable, which normally translates into a system freeze needing a hard reset of our computer.

I have been happily undervolting my CPU through different kernels in the same computer for more than 4 years and I haven’t had any problems with it. But, if incorrectly used, undervolting can provoke computer freezes. So, once again:

Undervolting makes your CPU operate outside manufacturer specifications and can make your computer unstable: use at your own risk!

Undervolting: how?

For the Linux world the Linux-PHC project provides a patch to the kernel module acpi-cpufreq that allows the user to adjust the operating voltage of his CPU via a /sys filesystem interface.

Since undervolting may provoke unstability I think it is extremely unlikely that PHC will ever be incorporated to the main kernel source or to any distribution official repositories. Therefore, we will usually have to resort to build and install it on our own.

Assuming our machine is running the kernel we intend to patch, the general procedure to get this nifty piece of software working is:

  1. Get the latest stable linux-phc version for our CPU architecture and kernel version.
  2. Get the appropriate acpi-cpufreq.c file for our CPU architecture and kernel version.
  3. Patch it with the PHC patch.
  4. Build a patched module for your kernel.
  5. Install the patched module.
  6. Unload the original module (if loaded) and load the patched one.
  7. Find the optimal operating voltage for every frequency of your CPU by trial-and-error.
  8. Load your voltage table on startup.

For Ubuntu users: recent versions of the Ubuntu kernel don’t build acpi-cpufreq as a module, but integrate it in the monolithic bunch loaded at boot time :-/. Therefore, this procedure won’t work there: you will have to either rebuild a full kernel (perhaps you can skip module building) or download a pre-compiled user-contributed version from this PPA. The good news in the latter case is that you don’t have to mess around with compilations if you just want the PHC addition. The bad news is that it will make it more difficult for you to combine PHC with other features, like the RT patch. You can find more information about this at the PHC website.

I will describe here the steps I follow for my particular audio-oriented setup:

  • CPU: Intel Pentium-M 1.6 MHz.
  • Distribution: Fedora Core 11.
  • Kernel: 2.6.29.6-1.rt23.4.fc11.ccrma.i586.rt, a realtime enhanced kernel created by the fine people at PlanetCCRMA.
  • PHC version: phc-intel-0.3.2-9.

The procedure I outline here should not be too different for other kernels or CPUs (AMD, multicore, etc.) Please, check out the PHC page if you need advice on this.

Get the latest stable linux-phc version for our CPU architecture and kernel version

The Linux-PHC patch is distributed as a tarball. At the PHC website we will find a “PHC Downloads” subforum and inside it a “Releases” thread. There are several versions there; we will download the one that best fits our CPU architecture and contains a patch for the kernel version we are using. Since I have an Intel CPU and intend to patch 2.6.29 and 2.6.30 kernels, the appropriate choice for me is phc-intel-0.3.2-9.tar.gz.

After downloading it we will unzip it in a folder of our choice. We will find its contents are:

  • A collection of patches for different versions of the vanilla kernel.
  • The unpatched version of the vanilla kernel acpi-cpufreq.c file so, if we are lucky and it wasn’t modified for the kernel version we use, we won’t need your full kernel sources, just the headers.
  • Some build scripts to streamline the module compilation procedure.

Get the appropriate acpi-cpufreq.c file for our CPU architecture and kernel version

The PHC tarball bundles already the acpi-cpufreq.c file for a number of vanilla kernel versions, big emphasis in the “vanilla” qualifier. Few distributions bundle a pure vanilla kernel, as distributed by www.kernel.org: most of them modify different parts of it with a series of patches. If we are lucky these distribution-specific patches won’t include modifications to acpi-cpufreq.c, so we will be able to use the one provided by the PHC tarball.

To find out if we have been lucky or not, jump below to the following section, titled “Patch acpi-cpufreq.c with the PHC patch”. If you don’t get any error there you will probably be fine and can safely ignore the rest of this section. Otherwise, come back here and learn how to get hold of the proper version you need.

In my case I found out that I can use the bundled file with no problem for Fedora’s stock kernel 2.6.30.10-105.fc11.i586, but not for PlanetCCRMA’s realtime version 2.6.29.6-1.rt23.4.fc11.ccrma.i586.

For the latter, thus, I needed to get hold of the patched acpi-cpufreq.c for that kernel and hope that the corresponding PHC patch can be applied to it. The best way to do this is to install that kernel RPMS, bring it to the preparation stage and get the file from there.

To work with RPMS packages we need a series of tools, bundled within the aptly-named rpmdevtools package. So we will install it and its dependencies, and then execute the command:

rpmdev-setuptree

This will create the subtree rpmbuild in our home directory.

Then we install the kernel RPMS with the following command:

rpm -i http://ccrma.stanford.edu/planetccrma/mirror/fedora/linux/planetcore/11/SRPMS/kernel-2.6.29.6-1.rt23.4.fc11.ccrma.src.rpm

This will deploy a bunch of files at rpmbuild/SOURCES and a spec file at rpmbuild/SPECS.

Now we launch the kernel RPM build process up to the ‘prepare’ stage, which will unzip the kernel tarball and apply all the patches at rpmbuild/BUILD.

rpmbuild -bp --target i686 ~/rpmbuild/SPECS/kernel.spec

We can now overwrite the vanilla acpi-cpufreq.c file bundled with the PHC tarball with the one found in our kernel sources. We go to the folder where we unzipped PHC and execute:

cp ~/rpmbuild/BUILD/kernel-2.6.29/linux-2.6.29.i686/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c inc/2.6.29/acpi-cpufreq.c

Patch acpi-cpufreq.c with the PHC patch

For this stop to work we need to install the package that provides our kernel headers. Since we want to build a module for the kernel provided by the kernel-rt package we will need to install kernel-rt-devel too. The patching script supplied by PHC is not too sophisticated, so if we forgot to install the headers it will stop at a certain point and we will have to terminate it with Ctrl+C. Other packages that we may need, if they are not already installed, are gcc, patch and make.

We launch the patching procedure from the folder where we unzipped the PHC tarball with the command:

make prepare

This will locate the acpi-cpufreq.c best suited to our kernel version, rename it to linux-phc.c and patch it.

The patching procedure may succeed, perhaps warning about some “fuzz” (which shouldn’t be too worrying if the compilation goes well later on) or may fail. In the latter case you will have to review carefully the source/patch combination that it is being used and perhaps ask for help at the PHC message board.

Build a patched module for your kernel

This is where the real compilation takes place. We simply run:

make

If the build isn’t successful again we may not be using the proper acpi-cpufreq.c or the proper patch. Review the previous steps and, if in doubt, seek help at the PHC forum (be sure to search its contents before posting a question, you may not be the first person with that particular problem.)

Install the patched module

If the build was successful we must now install our new module. We need root permissions to do this, so we will have to use our preferred mechanism to acquire superuser powers (sudo, su…) The command to install it is:

make install

This will copy phc-intel.ko to the appropriate place in /lib/modules. It will also copy the file phc-intel.modprobe as /etc/modprobe.d/phc-intel.conf, which will ensure that in future boot-ups the phc-intel module is loaded instead of acpi-cpufreq.

Unload the original module and load the patched one

Next, still as root, we unload the acpi-cpufreq module and load our new phc-intel:

rmmod acpi-cpufreq
modprobe phc-intel

If all has gone as expected, we will now be able to access all PHC-related information at a new set of files that will have appeared at /sys/devices/system/cpu/cpu0/cpufreq. These files start with the prefix “phc_”.

Find the optimal operating voltage for every frequency of your CPU by trial-and-error

To configure properly your CPU voltages you need to understand the concept of VIDs and FIDs. VID means voltage identifier and FID frequency identifier. Those numbers identify the multipliers that are allowed for your CPU voltage and frequency.

For my CPU, the following formulas apply, it may be different for yours:

F = FID * 133.3 MHz

V = 0.700 + VID * 0.016 V

We can see the available FIDs at /sys/devices/system/cpu/cpu0/cpufreq/phc_fids:

cat /sys/devices/system/cpu/cpu0/cpufreq/phc_fids
12 10 8 6

This means my CPU can run at 1600, 1333, 1066 and 800 MHz.

We can access the manufacturer configured voltages at /sys/devices/system/cpu/cpu0/cpufreq/phc_default_vids:

cat /sys/devices/system/cpu/cpu0/cpufreq/phc_default_vids
38 32 25 18

This means Intel guarantees the operation of my Pentium-M at the following combinations of frequency/voltage:

  • 1600 MHz / 1.308 V
  • 1333 MHz / 1.212 V
  • 1066 MHz / 1.100 V
  • 800 MHz / 0.988 V

To lower down our CPU voltages at each frequency we must write a full set of VIDs to the file /sys/devices/system/cpu/cpu0/cpufreq/phc_controls like this:

echo "12:14 10:8 8:3 6:0" > /sys/devices/system/cpu/cpu0/cpufreq/phc_controls

With this I am telling my CPU to operate at these combinations of frequency/voltage:

  • 1600 MHz / 0.924 V
  • 1333 MHz / 0.828 V
  • 1066 MHz / 0.748 V
  • 800 MHz / 0.700 V

These are the minimum voltages I found out my CPU can tolerate without becoming unstable. It doesn’t mean they work for any other CPU, even if it is the exact same model. At the PHC site some users have posted the values that work for them for a range of CPUs; we can use them as a guideline, but we must always look for our own.

To find out what voltages work for our particular CPU we must proceed by trial and error. First of all, make sure to set up your CPU to always operate at a fixed frequency. I use the cpufreq-set command from the cpufrequtils package, but there are other possibilities:

cpufreq-set -d 800000 -u 800000

Then gradually lower down the VID for that particular frequency until you find the lowest stable value. The fastest method should be proceeding by binary search, dividing the available voltage range in two, discarding one of the halves as too low or too high, dividing the remaining one in two, and so on.

Test the stability of that voltage with some CPU intensive program, like those which calculate prime numbers or the digits of pi. Let it “burn” your CPU for a couple of minutes. If your system freezes you will have to hard-reset it and try with a higher VID. If it doesn’t, try a lower one until you find the limit.

Repeating these steps for all our available frequencies will give us a list of minimal voltages, one for each frequency.

Load your voltage table on startup

The simplest way of ensuring the voltages we have found are loaded at boot time is to add a line like this to /etc/rc.local:

if [ -f /sys/devices/system/cpu/cpu0/cpufreq/phc_controls ]; then
    echo "12:14 10:8 8:3 6:0" > /sys/devices/system/cpu/cpu0/cpufreq/phc_controls
fi

Conclusion

Learning to undervolt a CPU takes some time, but it is well worth the effort if you appreciate silence, low power consumption and extended battery life. It is both practical an environment-friendly. Give it a try!

 Posted by at 07:39 PM
 

xjadeo logoxjadeo is a software video player that displays a video-clip in sync with an external time source (MTC, LTC or JACK-transport). It is useful in soundtrack composition, video monitoring or any task that requires to synchronizing movie frames with audio events.

xjadeo supports a multitude of video file formats, display libraries and sync sources. It includes an optional GUI called qjadeo that provides setup options, file history, video import/transcoding and control of Xjadeo’s run-time parameters.

Primarily developed for the GNU/Linux operating system, there are also binaries available for Win32 and OSX.

The first version of xjadeo dates back to 2005, when I was commissioned the soundtrack for a short video clip and I found out there was no easy way to synchronize my audio software with a video player in Linux.

Some time later, hacker extraordinaire Robin Gareus jumped in and took the lead of the project, taking it to unprecedented levels of excellence and functionality. Since then I have side-stepped to a secondary role, but I still like to contribute to the project to the extent my available time allows me.

 Posted by at 07:19 PM
 

The project

“True Evil: Tale Of The Necromancer” was the working title for a 3D RPG game in the line of the Zelda or the Final Fantasy series.

This ambitious academic cooperation project combined the talents of several students from different institutions in Rotterdam: graphic designers from the Willem de Kooning Academie, programmers from the Zadkine Academie and yours truly, at the time student in the former Rotterdams Hogeschool voor Muziek en Dans, nowadays known as Codarts, Hogeschool voor de Kunst.

The scope of the project and the available resources were such that the actual completion of the game was out of the question. Nevertheless, the team managed to produce a small demo using the Unreal Engine.

As a curious side note, one of my jobs was to put music to a cut scene. At that time (2005), there wasn’t around any tool to visually synchronize audio and video for Linux, so I was forced to code my own. Thus was born xjadeo, my first foray in the field of Linux audio applications development.

To produce the soundtrack I used mainly MusE, fluidsynth, some soundfonts and LADSPA plugins. Since they never went beyond the draft stage the mixes are not too polished. The style is very mainstream, Nobuo Uematsu’s influence is all over the place.

Second Thoughts (cut scene)
Milenia’s Guard
Milenia’s Sewers (ambience)
Battle
Defeat
 

This article describes some of the existing infrastructure for Linux applications and/or audio processing modules to exchange audio and MIDI data. It reflects the personal experience of the author, so it is necessarily not exhaustive and may contain some subjective bias.

A first distinction must be made between data transport between different applications and data transport inside one application.

Data transport between applications

In this case there are at least two different applications, each one having its own independent execution environment (process). These applications can exchange data via an external service, normally some kind of third party transport daemon running in parallel.

Most of the external transport services take the form of an audio server (daemon) offering an API to its client applications that includes, among other functions:

  • Registering the application with the service as a client.
  • Registering one or more data input/output ports.
  • Managing connections between any existing compatible ports registered with the server.

Transport services also provide built-in ports for the hardware devices found in the system, like any audio or MIDI channels detected in the installed soundcards.

Some simple client applications will connect their ports automatically to sensible defaults as a convenience. For instance, many media players will automatically connect their audio output ports to the hardware playback ports (note the distinction between capture/playback, input/output or read/write ports: for instance, hardware audio playback channels -which ultimately output sound to speakers- are actually audio input ports from the point of view of the transport server, since other applications can write data on them coming from their output ports.)

Some applications also provide some kind of interface so the user can choose where to connect the ports it provides.

Finally, there are third party applications that act as a patchbay. A patchbay role is to let the user manage connections between the different existing ports. Some examples are:

  • qjackctl: the “Audio”, “MIDI” and “ALSA” tabs in the connection dialog provide patchbays for the jack-audio, jack-midi and alsa-seq services, respectively.
  • aconnect: is a CLI utility that lets the user manage connections between alsa-seq ports.

Audio transport between applications

Nowadays most audio production applications use jack, the Jack Audio Connection Kit, to route audio from one to another. jack provides a callback-based API. Every “jackified application” has to register with the jack daemon (jackd) as a jack client and provide one or several callback functions that will be called by the jackd process when appropriate.

jack callbacks should be carefully designed according to a number of guidelines so they don’t hog the computer resources and play nice with the rest of the jack clients. This is especially important when jackd is running with real time privileges, so audio processing and routing takes precedence over any other process running in the system to guarantee a glitch-free audio stream within the capabilities of the hardware. A badly behaved client could render the system unusable.

jack clients register input and output ports with the jackd server that can then be connected to other jack ports. This routing can be handled in the application itself or via a external patchbay, like qjackctl.

The jackd server also provides ports to the audio hardware devices using different backends depending on the hardware driver. Available back-ends (hardware drivers) may include: alsa, dummy, freebob, firewire, net, oss or sun.

+-------------------------------+
|             jack              |
+------+------------------+-----+
| ALSA | firewire (FFADO) | ... |
+------+------------------+-----+

MIDI transport between applications

At the date of this writing, MIDI routing is a bit less streamlined than audio. There are three external MIDI routing APIs popular with MIDI software authors:

  • alsa-seq: at this moment this is probably the most widely used. This API provides timestamped MIDI event handling. alsa-seq clients register themselves with the system and provide a number of input and/or output ports. Ports are routed from the client applications or via a external patchbay like qjackctl or aconnect. alsa-seq provides ports to the available MIDI hardware devices.
  • alsa-raw: this API provides raw MIDI event handling (thus no timestamping.) It is used for very specific applications that access the hardware ports directly, but not for connecting one application to another.
  • jack-midi: the jack server can also provide sample-accurate timestamped MIDI event handling. Again the routing can be done from the client application or using a external patchbay like qjackctl. jack-midi can use alsa-seq or alsa-raw as a backends. The FFADO project provides jack-midi ports for MIDI fireware devices.

It is worth mentioning a2jmidid, which is a daemon that creates a bridge between alsa-seq ports and jack-midi ports, allowing alsa-seq applications to be used in a jack-midi setup.

Data transport between applications and “The Session Issue”

External mechanisms of audio and MIDI data transport between applications are a very convenient framework for developers to allow communication while keeping applications very independent. This is especially relevant because of “The GUI Toolkit Issue”, discussed later in this document.

However, it is not the most convenient framework for the user: a complex project can consist of several applications working together. For instance: a sequencer, a FX plugin rack, a couple of virtual instruments… all of them interconnected in a possibly complex way, including perhaps hardware audio and MIDI ports, too. Every time the user wants to work on that project he has to repeat the painstaking job of launching all those applications and recreate the connections among them.

There are some solutions to ease this task:

  • Patchbay configuration files: patchbays like those in qjackctl provide a mechanism to store all the connections for a session in a file, so after the user has launched all the involved applications he/she can recreate the connections by loading this file.
  • Audio session managers: daemons like lash, ladish or, very recently, jackd itself provide a mechanism so clients can register their configuration with a session server. This session can then be stored and later retrieved, so the session manager will take care of launching the clients and recreate their connections. For this to work, all the applications involved in a project must include support for the session protocol in question. The main problem with this approach is that many popular applications don’t include support for session management yet. It is also necessary to introduce a new application, the session manager, which provides the user interface to construct the session, store it and retrieve it.
  • Internal data transport: the third solution would be to do away with the need for different applications, resulting in sessions that use just one host and one or several plugins. The host will load and connect all the plugins configured for the project. This only works if all the modules used by the session can be loaded by the host as plugins, but the fact is that many modules are not available as plugins because they are too complex to fit within one of the available plugin standards or because of “the GUI Toolkit Issue.”

Data transport within one single application

In this case, an application called host can extend its audio processing/generating capabilities by dynamically loading external libraries (plugins) and the routing among modules is handled internally by the application, thus using the external infrastructure only for accessing hardware devices.

Plugins are dynamically loadable libraries that comply with a certain standard that must also be supported by the host. Plugins provide input and/or output ports, control ports and processing functions that are called by the host.

The most widely used audio plugin standards in Linux are:

  • LADSPA: roughly equivalent to VST in Windows, this standard doesn’t provide MIDI data handling, so it is only used in audio processing or generation. LADSPA doesn’t provide any support for custom GUIs, so the host must programmatically generate a generic one.
  • DSSI: roughly equivalent to VSTi, DSSI is aimed at virtual instruments. Designed as an extension to LADSPA, it provides among other features MIDI event handling, MIDI-controller automation of control ports and off-process GUIs using OSC as IPC method. The DSSI specification doesn’t support multi-channel instruments.
  • LV2: an evolution of LADSPA, LV2 is an extensible specification. The core specification is equivalent to LADSPA. Some of the available extensions include: MIDI ports, in-process GUIs, off-process GUIs, string ports, port grouping… If a plugin requires one or more of these extensions the host must also support them in order to be able to run the plugin. As of this writing LV2 core is not yet supported by many of the most popular host applications. There are two plugin racks: lv2rack for audio effects and zynjacku for virtual instruments.

Audio plugins and “The GUI Toolkit Issue”

A plugin GUI is a dialog containing widgets that display the values of the plugin contol ports and allows the user to change them.

Any GUI host can use the port description information provided by a plugin to algorithmically create a generic GUI assigning a suitable widget to every control port. However these generic GUIs tend to be badly organized and change from host to host.

Most users will find more practical that the plugin author provides also a custom GUI so its layout is optimized, practical and remains consistent accross different hosts.

There are two main approaches to plugin GUIs in Linux:

  • Embedded (in-process) GUIs: the plugin GUI is created and executed by the host process and is included in the host GUI event loop. For this to be possible both plugin and host must use the same GUI toolkit (there is actually some talk about the possibility of mixing toolkits in one event loop, but no one has come up with a workable solution yet.) And herein lies the problem: in Linux there are many GUI toolkits available: the most widely used ones are Qt and Gtk, but there are many more: wxWidgets, FLTK, Motif, FOX, Tk… each with its own particular focus and strengths. This allows every developer to choose the toolkit that suits better his/her technical needs and programming style, but mixing up toolkits in one single application is very complicated, if at all possible. Two solutions for this predicament are:
    • Do as VSTgui, decide on one of the existing toolkits or create yet another one and mandate every plugin and host author to use it. This is not likely to go down very well in a community built around the concepts of freedom and choices.
    • Define an abstract GUI description language and create a parser and renderer for every different toolkit out there. The problem in this solution is how to determine the capabilities of this hypothetical language so it is powerful and open enough to allow arbitrarily complex GUIs without making the implementation of the renderer library an unmaintainable nightmare.
  • External (off-process) GUIs: the GUI is a stand-alone application with its own process and event loop that communicates with the host via some IPC mechanism. This is the approach used by DSSI, which uses the OSC protocol as transport. External GUIs solve the toolkit problem, since they allow developers to use whichever toolkit they wish, but have their own set of problems: each GUI is its own independent top-level window, which some people find disorganized, they consume more resources, are less responsive, etc.

Summarizing, many clever people have dedicated a long time to think this problem through and discuss different possibilities, but the fact is that there is no perfect solution to it that every single developer can agree upon.