Sunday, May 31, 2009

Quick and dirty image creation in Fortran

Well, maybe not dirty image creation. Let's make that "quick and easy" image creation instead.

When you're analyzing tons of data, Gnuplot is an indispensable tool. But sometimes you just want to create an image quickly and easily. Gnuplot is also very fussy about the format of its data for 3D plots and its not always practical to reformat your data to fit Gnuplot's needs. The PPM format is in ASCII, which makes reading and writing it extremely straightforward. An example PPM file might be:

P3
2 3
255
255 0 0
0 0 0
0 255 0
128 128 128
0 0 255
255 255 255


-The first line sets the format of the PPM file to be ASCII.
-The second line sets the image to be 2 columns wide and 3 rows tall.
-The third line sets the largest color to 255.
-Each line after is an RGB triplet defining one pixel.

And it looks something like this:



I've blown this image up by a factor of 100 in each direction.

A quick Fortran program which creates this image is:

        program view

open(unit=8, file="image.ppm")

write(8,100) "P3"
write(8,100) "2 3"
write(8,100) "255"
write(8,101) 255, 0, 0
write(8,101) 0, 0, 0
write(8,101) 0, 255, 0
write(8,101) 128, 128, 128
write(8,101) 0, 0, 255
write(8,101) 255, 255, 255

close(8)

100 FORMAT(a)
101 FORMAT(3(i3,1x))

end program


One other quick note: I used Image Magick's "convert" command to convert from the PPM format to GIFs. To simply convert from PPM to GIF (or JPG, etc), do this:

convert image.ppm image.gif


To hard scale it:

convert -scale 200x300 image.ppm image.gif


And you can also soft scale it:

convert -geometry 200x300 image.ppm image.gif


Which produces a final product that looks like this:

Tunneling VNC through SSH

VNC is great for accessing remote machines, but it is inherently insecure. By tunneling through SSH, you can get the security of SSH with almost all of the speed of VNC.

1. Create the tunnel:

ssh -L 5901:localhost:5901 USER@SERVER_ADDRESS -C


This will open up a new ssh session. Use this session to start the VNC server. The first 5901 is the port to use on the local machine and the second 5901 is the port to use on the remote machine. The -C switch turns on compression; without it, the VNC session is intolerably slow.

2. Start the VNC viewer:

vncviewer localhost:1


You're telling the VNC client to connect to your own machine. But the VNC port on your machine has been forwarded to the remote server, so the connection is made.

Saturday, May 30, 2009

Use VNC to view remote desktops

Normally, SSH is a great tool to administer a remote computer. However, if you need access to X programs, you have to use the -X switch which is terribly slow, even over broadband.

VNC isn't super-fast, but it is usable. It can be sped up somewhat by minimizing the size and color depth of the desktop window you use.

Fortunately, openSUSE 11.1 includes a VNC server and client under Applications | System | Remote Access. Unfortunately, the VNC server is severely buggy and incorrectly reproduces the server's desktop. It is bad enough to be unusable.

However, it is easy to start and connect to a VNC server from the console. For this walkthrough, the server is the remote computer you want to connect to and the client is your computer.

1. Install the necessary software on both machines. In this case, you''ll need TightVNC. It is usually installed by default. Check this using:

rpm -qa | grep tightvnc


If nothing comes up then install it using:

sudo zypper install tightvnc



2. You need to open TCP port 5901 on the server and every router/modem it is behind. For example, your connection might look like this:

client---client's router---cable modem---internet---dsl modem---server's router---server

You need to open 5901/TCP on the dsl modem, the server's router, and the server. To do this on the dsl modem and the router, you'll need to refer to the manuals that came with those products. For the server you can do this through the appropriate YaST module:

sudo /sbin/yast firewall


3. Start the vncserver on the server.

vncserver


The first time you do this you'll be prompted to enter a password (read my note on VNC security at the end first). You'll also be asked if you want to setup a view-only password; choose 'no'.

4. Start the vncviewer on the client. You'll need the IP address of the server. Here, I'm assuming its 192.168.1.50:

vncviewer 192.168.1.50:1


Enter the password and you'll be connected to the server.



A few notes on this:

-VNC does not use encryption by default. If you're going to use the above setup unmodified, then keep in mind that your password should not be the same as your root password. It could be easy for an attacker to capture that password and then connect remotely to the system, so make sure that you shut down the VNC immediately after you're finished using it. Also, start the VNC server not as root.

-You can shutdown the VNC on the server by using:

vncserver -kill :1


-The ":1" is the desktop number. If you start multiple VNC servers, each one will have a different number. vncserver by default starts with 1 and increments up. The port for each desktop is 5900+number. So that's why we needed port 5901 for desktop number 1.

-You can speed things up by sending a smaller desktop across the connection. Try this vncserver command instead of the one in step #3.

vncserver -depth 8 -geometry 800x600

Friday, May 29, 2009

Faster Ubuntu performance on Celeron Eee Pc 700's and 900's

The Netbook remix of Ubuntu 9.04 tends to run a little slow on Celeron-based Eee PCs, which includes almost all Eee PCs released prior to May 2008. On the 700 and the 900, you can speed up performance by installing a custom, optimized kernel.

1. Get the .deb files:

wget http://people.ubuntu.com/~apw/lp349314-jaunty/linux-headers-2.6.28-11-generic_2.6.28-11.43~lp349314apw5_i386.deb
wget http://people.ubuntu.com/~apw/lp349314-jaunty/linux-image-2.6.28-11-generic_2.6.28-11.43~lp349314apw5_i386.deb


2. Install them:

sudo dpkg -i linux-headers-2.6.28-11-generic_2.6.28-11.43~lp349314apw5_i386.deb linux-image-2.6.28-11-generic_2.6.28-11.43~lp349314apw5_i386.deb


3. Reboot.



The system should now feel more responsive. Here's a link to the bug page describing why the default kernel performance is slow:

https://bugs.edge.launchpad.net/linux/+bug/349314

Thursday, May 28, 2009

Sed for Blogger

Blogger/Blogspot has an unfortunate error that if you type a list like this:

test1
test2
test3

directly into a <pre> block, it looks something like this:

test1

test2

test3


As you can see, Blogger likes to mangle the newlines, effectively double-spacing the text. The solution is to remove all of the newlines and then replace them with <br> tags. There are a couple of online tools to do this, but its even easier using this sed command line:

sed 's/</\&lt;/g' INPUT_FILE | sed 's/>/\&gt;/g' | sed ':a;N;$!ba;s/\n/<br>/g'


The first sed converts < to the HTML-equivalent &lt;. The second sed does the same thing for >. The third one removes all newlines and replaces each one with <br>. The result is a single line that can be embedded in a pre and that will show up correctly in Blogger (or anywhere else, newline bug or not):

test1
test2
test3

Wednesday, May 27, 2009

TV Tuner playback for netbooks

Realtime playback of HDTV may not be an option on netbooks because of the large amount of data in the HDTV stream and the low processing power of a netbook. If realtime playback isn't an option, it's fairly easy to watch the program by:

1. Record the broadcast
2. Convert the broadcast to a lower bitrate
3. Watch the conversion

Steps:

1. You'll need two console windows open. In the first console window, change the tuner to the correct channel using:

azap -c channels2.conf -r -a 0 "WGN-DT"

where "0" is the number of your tuner (it's zero, unless you have multiple tuners) and "WGN-DT" is the channel you want to watch. The channel name can be found in the channel.conf file. If you don't have a channels.conf file, generate one now using:

scan /usr/share/dvb/atsc/us-NTSC-center-frequencies-8VSB -o zap -a 0 | tee ~/channels.conf

Again, "-a 0" specifies the tuner you're using. Error messages about "tuning failed" are normal.

2. In the second console window, record the program:

cat /dev/dvb/adapter0/dvr0 > Input.mpg

If you have multiple tuners, replace adapter0 with the appropriate adapter.

3. Convert the video to something reasonable using ffmpeg:

ffmpeg -i Input.mpg -s 720x480 -b 800k -vcodec mpeg2video -ac 2 -ab 128k -acodec libmp3lame Output.mpg

If you get a "could not find codec parameters" error, then install the Packman version of ffmpeg.

4. Play the video back:

mplayer Output.mpg

Although you could get better results by matching the resolution to the aspect ratio, if you get it wrong, mplayer will stretch the video appropriately to compensate.

Tuesday, May 26, 2009

Sabrent TV-DGUSB

Woot recently sold the Sabrent TV-DGUSB USB HDTV (ATSC) Tuner for $30. This card/dongle has horrible support. A Google for it turns up almost no pages and I couldn't even find it on Sabrent's own website. Here's the information I do have on it:

Product: Sabrent TV-DGUSB
ID: 05e1:0480
lsusb says: Syntek Semiconductor
Chips: Auvitek au0828
Chips: Auvitek au8524

A similar card with id 05e1:0400 is supported with code from LinuxTV.org. The cards differ in that this one has the au8524 and the driver supported one has a au8522. It turns out that the difference is minimal enough that we can use the driver from one for the other.

Steps to get it working in openSUSE 11.1:

1. Add the Packman repositories.
2. Get the kernel-source, dvb, and vlc packages.
3. Get http://linuxtv.org/hg/~mkrufky/teledongle/archive/tip.tar.bz2.
4. Unbzip it.
5. Change line 222 of linux/drivers/media/video/au0828/au0828-cards.c from 0x0400 to 0x0480. Build it with "make" and "make install" as root.
6. Reboot (yes, its necessary).
7. Plug in the card. You can verify everything is working by making sure the blue light on the unit is on, the au0828 module is installed ("lsmod | grep au0828"), or "dmesg | tail" should read:


usb 2-6: new high speed USB device using ehci_hcd and address 9
usb 2-6: configuration #1 chosen from 1 choice
Manufacturer ID= 0xff, Chip ID = ffff. It is not a TEA5761
tuner' 9-0042: chip found @ 0x84 (au0828)
tda9887 9-0042: creating new instance
tda9887 9-0042: tda988[5/6/7] found
tuner' 9-0043: chip found @ 0x86 (au0828)
tda9887 9-0043: creating new instance
tda9887 9-0043: tda988[5/6/7] found
tuner' 9-004a: chip found @ 0x94 (au0828)
tda9887 9-004a: creating new instance
tda9887 9-004a: tda988[5/6/7] found
tuner' 9-004b: chip found @ 0x96 (au0828)
tda9887 9-004b: creating new instance
tda9887 9-004b: tda988[5/6/7] found
Chip ID is not zero. It is not a TEA5767
tuner' 9-0060: chip found @ 0xc0 (au0828)
tuner' 9-0061: chip found @ 0xc2 (au0828)
tuner' 9-0062: chip found @ 0xc4 (au0828)
tuner' 9-0063: chip found @ 0xc6 (au0828)
tuner' 9-0064: chip found @ 0xc8 (au0828)
tuner' 9-0065: chip found @ 0xca (au0828)
tuner' 9-0066: chip found @ 0xcc (au0828)
tuner' 9-0067: chip found @ 0xce (au0828)
tuner' 9-0068: chip found @ 0xd0 (au0828)
tuner' 9-0069: chip found @ 0xd2 (au0828)
tuner' 9-006a: chip found @ 0xd4 (au0828)
tuner' 9-006b: chip found @ 0xd6 (au0828)
tuner' 9-006c: chip found @ 0xd8 (au0828)
tuner' 9-006d: chip found @ 0xda (au0828)
tuner' 9-006e: chip found @ 0xdc (au0828)
tuner' 9-006f: chip found @ 0xde (au0828)
au0828: i2c bus registered
tda18271 9-0060: creating new instance
TDA18271HD/C2 detected @ 9-0060
DVB: registering new adapter (au0828)
DVB: registering adapter 1 frontend 0 (Auvitek AU8522 QAM/8VSB Frontend)...
Registered device AU0828 [Syntek Teledongle [EXPERIMENTAL]]
usb 2-6: New USB device found, idVendor=05e1, idProduct=0480
usb 2-6: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 2-6: Product: USB 2.0 Video Capture Controller
usb 2-6: Manufacturer: Syntek Semiconductor

8. You'll need a list of valid channels to use. In the USA, use (not as root):

scan /usr/share/dvb/atsc/us-NTSC-center-frequencies-8VSB -o zap -a 0 | tee ~/channels.conf

You will get a lot of messages about "tuning failed". Ignore these. It just means that there is no station on that channel. If you have multiple TV tuners in your system (I did), then you'll need to tell the scan command which one to use using the "-a" switch. 0 is the first tuner, 1 is the second and so on.

When this is done, channels.conf should have a few (or many) lines, each one corresponding to a local TV channel.

9. Start VLC:

vlc --color --ttl 12 --dvb-adapter=0 channels.conf

Again, if you have multiple adapters, tell vlc which one to use with the "dvb-adapter" switch. The next and previous buttons change the channels.



If all went well, then you're watching live high definition TV. If the video is blocky or cutting out then either your processor is too slow (more on this in a moment) or your signal is not sufficient. The antenna that comes with the tuner is pretty small. I found that sometimes putting the antenna on its side improves the reception significantly.

On my 2.2GHz 4-year-old processor, watching the broadcast full screen took 25% of the processor time (using top). This is pretty good and better than BlazeVideo (the Windows software that comes with the card) that took closer to 50%. This means HDTV should be doable on just about every recent computer, maybe even netbooks. I'll try that next and report back.

I should note that some channels use more processing power than others. On my laptop (a five-year-old Sempron at 1.8GHz), the processor usage per channel is constant, but from channel to channel to varies from 15% to 80%.

Here are some websites that I found helpful. The device pictured in the first link is the previous chip version of this one, the au8522:

http://www.linuxtv.org/wiki/index.php/Sabrent_TV-USBHD
http://linuxtv.org/hg/~mkrufky/teledongle
http://forum.videolan.org/viewtopic.php?f=13&t=38890
http://forums.opensuse.org/applications/multimedia/405117-sabrent-digital-hdtv-atsc-analog-usb.html
http://linuxtv.org/wiki/index.php/ATSC_USB_Devices

GPS on openSUSE 11.1

Getting a gps to work on Linux is actually fairly easy. The devices usually have an integrated usb-to-serial adapter, so they show up in /dev/ as a serial device. Upon plugging in a BU-353 (which is available on Amazon and I fully recommend), there is a /dev/ttyUSB0.

The steps I used to get the GPS up and fully working were:

1. Install two packages as root:

yast -i gpsd gpsdrive

2. Modify /etc/sysconfig/gpsd. Change GPSD_STARTBYUDEV="no" to "yes".
(If you don't do this, you will have to manually start gpsd every time you plug in the gps. You can do so with "gpsd /dev/ttyUSB0" as root.)

3. Start gpsdrive. Give the GPS a minute or so to achieve a lock. The BU-353 gets a lock usually in 30 seconds and even quicker if it was recently used (it has some onboard short-term memory).