Tuesday, August 23, 2011

microphone doesn't do stereo on asus 1001p

The mic on my asus eee 1001p doesn't work correctly under Linux (apparently also on a number of models of the eee). In pulseaudio, it shows up as a stereo mic but the two channels cancel each other out so if you want it to work, you have to adjust one of the channels down to 0 (I use the pulseaudio volume control for this, pavucontrol). However, it's annoying that this doesn't just work. I've looked for solutions since I bought the device and I finally found one this week.

The correct solution is a kernel patch which appears to be on its way to kernel land. But while I'm waiting, I found a suitable workaround using the hda-verb utility. Here's the magic incantation below. Update the /dev/snd/* path to whatever is right for your system and then take the "value" output of the 2nd command and do a bit-wise or of 0x80 (in my case, 0x1800 became 0x1880) and use that as the last argument to the last command below.


# ./hda-verb /dev/snd/hwC0D0 0x20 SET_COEF_INDEX 0x07
nid = 0x20, verb = 0x500, param = 0x7
value = 0x0
# ./hda-verb /dev/snd/hwC0D0 0x20 GET_PROC_COEF 0
nid = 0x20, verb = 0xc00, param = 0x0
value = 0x1800
# ./hda-verb /dev/snd/hwC0D0 0x20 SET_COEF_INDEX 0x07
nid = 0x20, verb = 0x500, param = 0x7
value = 0x0
# ./hda-verb /dev/snd/hwC0D0 0x20 SET_PROC_COEF 0x1880

Wednesday, August 3, 2011

x86_64 versus x86 on ASUS eee

Use x86, hands down. I installed Fedora x86_64 on my ASUS eee 1001p with 1G of RAM and that was a mistake. In hindsight, it makes complete sense: 64-bit addressing makes programs take up lots more space in memory (because the pointers and stored memory addresses are twice as large) which makes systems with not much RAM not work as well. When I reverted back to an x86 Fedora, WOW! Things went much faster. There was oodles more memory available for applications.

Lesson Learned: Don't use x86_64 unless you absolutely need access to more than 4G of memory. And on my ASUS 1001p laptop, that'll never happen (system can only handle 2G I think) so it just doesn't make sense.

Friday, December 31, 2010

volume keys in lxde

gmixer is just not working for me correctly under the Fedora LXDE spins on my Asus EEE laptop. So I hacked together a solution using some suggestions I found across the 'net.

add to the "keyboard" section in ~/.config/openbox/lxde-rc.xml

<keybind key="XF86AudioLowerVolume">
<action name="Execute">
<command>/home/user/bin/vol.sh down</command>
</action>
</keybind>
<keybind key="XF86AudioRaiseVolume">
<action name="Execute">
<command>/home/user/bin/vol.sh up</command>
</action>
</keybind>
<keybind key="XF86AudioMute">
<action name="Execute">
<command>/home/user/bin/vol.sh mute</command>
</action>
</keybind>


/home/user/bin/vol.sh

#!/bin/bash

function dispvolpercentage() {
zenity --progress --text="Volume" --percentage="$1" --no-cancel --timeout=1
}

function getvolume() {
amixer get Master | grep -o -E "[0-9]+%" | head -1 | cut -d '%' -f 1
}

case "$1" in
up)
VAL="`getvolume`"
VAL=$(($VAL+5))
amixer set Master ${VAL}%
dispvolpercentage $VAL
;;
down)
VAL="`getvolume`"
VAL=$(($VAL-5))
amixer set Master ${VAL}%
dispvolpercentage $VAL
;;
mute)
amixer set Master toggle
;;
esac


References
* http://wiki.lxde.org/en/LXDE:Questions#How_do_I_make_my_keyboard_volume_buttons_work.3F
* https://bbs.archlinux.org/viewtopic.php?id=69589&p=1 - I wrote my script based on this one but just using zenity (doesn't look very nice, but works)

Saturday, December 4, 2010

openwrt crashes due to OOM killer

I have an openvpn tunnel running between two OpenWRT-powered routers. One of them is running Kamikaze 7.09 and crashes all the time when transferring lots of data at once. It was getting really annoying (for me and them) having to call the site and have it manually rebooted. I finally discovered that it appears to be dying because it runs out of memory and the OOM killer terminates all the important processes. It'd be nice if the OOM killer would just reboot the thing, but the kernel in Kamikaze 7.09 for this router doesn't support that (I think newer ones do). So I wrote the following watchdog script and installed it in root's crontab to run every 4 minutes. So far, the router hasn't crashed permanently. When memory gets low, it just reboots! Hopefully no more calls to this site...


#!/bin/sh

F="`free | grep Mem | cut -c 37-45`"
if [[ $F -lt 500 ]]; then
logger "Memory Low ($F) - rebooting..."
sleep 5
/sbin/reboot
fi

Thursday, December 2, 2010

I'm a victim of this NetworkManager bug where if it can't reach the dhcp server after some longer amount of time, it gives up. I have a server that is difficult for me to reboot that has gone down because NetworkManager just gives up if something happens to the DHCP server. So, I wrote this watchdog script and put it in my crontab to run every 5 minutes.


#!/bin/bash

if pidof dhclient > /dev/null; then
logger "dhclient is alive"
else
logger "dhclient is dead, restart NetworkManager"
/etc/init.d/NetworkManager restart
fi

Sunday, November 7, 2010

Writing a File Atomically from Python

I wanted to be able to write to a file, but there was a possibility that others could be reading from it while I was writing to it. So I came up with this code below (which I release as public domain) which should guarantee that the file gets written without anyone being able to read it until it is completely written to disk.

import os, os.path
import errno

def write(filename, data, mode=0600):
""" guarantees that noone can read filename with only partial data """
fd = None
seq = 1
dn = os.path.dirname(filename)
bn = os.path.basename(filename)
while fd == None:
try:
fn = os.path.join(dn,".%s.%d"%(bn,seq))
fd = os.open(fn, os.O_CREAT | os.O_EXCL | os.O_WRONLY, mode)
except OSError, e:
if e.errno == errno.EEXIST:
seq += 1
continue
else:
raise

# write data to temporary file
fo = os.fdopen(fd, "w")
fo.write(str(data))
fo.close
#os.close(fd)

# move file into place now that it is written
os.rename(fn, filename)

Outputting HTML5 via XML/XSLT

One of my web applications uses XSLT to transform some XML data into output. For a long time, I was convinced XHTML was the future. But now I've seen the light and HTML5 is the way to go. I want my app to be able to take advantage of all the HTML5 goodness while still retaining the content/view separation that using XML and XSLT has allowed me.

Content With Style had a good blog post highlighting this problem, but it seems that the doctype has since changed. The current HTML5 spec outlines the current accepted doctype including the doctype that XSLT-generated documents can use.

So here's the xsl:output string I needed to use:

<xsl:output method="html"
doctype-system="about:legacy-compat"
indent="yes"/>