It’s possible to build Clang from SVN in Ubuntu 12.04 LTS (Precise Pangolin), but you need to build GNU C++ 4.8 first, because the version that’s provided with Ubuntu 12.04 (GNU C++ 4.6) isn’t new enough to build it!

Firstly, install some build dependencies:

sudo apt-get install libmpfr-dev libgmp3-dev libmpc-dev flex bison

You might also need to do:

sudo apt-get build-dep gcc

Then build and install GNU C++ 4.8.2 to /opt/gcc-4.8.2/:

mkdir $HOME/src
cd $HOME/src

wget http://ftp.gnu.org/gnu/gcc/gcc-4.8.2/gcc-4.8.2.tar.bz2
tar xvf gcc-4.8.2.tar.bz2

cd gcc-4.8.2
mkdir build
cd build

../configure --disable-checking --enable-languages=c,c++ --enable-multiarch \
  --enable-shared --enable-threads=posix --program-suffix=4.8 \
  --with-gmp=/usr/local/lib --with-mpc=/usr/lib --with-mpfr=/usr/lib \
  --without-included-gettext --with-system-zlib --with-tune=generic \
  --prefix=/opt/gcc-4.8.2

make -j8

sudo make install

“make -j8″ above runs a parallel build, where multiple parts of the code are compiled concurrently. This speeds up the build process on multi-core CPUs provided a few GBs of free memory is available. If you find you’re running out of memory during the build, you can change this to “make -j4″ or instead simply use “make” without the -j option to disable concurrent compilation.

Once GNU C++ 4.8.2 is installed, you can optionally free up disk space with:

rm -rf $HOME/src/gcc-4.8.2/

The version of Clang in SVN also requires a newer version of CMake than what’s provided in the Ubuntu 12.04 repositories (CMake 2.8.7). We’ll build and install CMake 2.8.12.2, but to make things interesting, we’ll use CMake 2.8.7 and our newly installed GNU C++ 4.8.2 to build CMake 2.8.12.2:

sudo apt-get install cmake

mkdir $HOME/src
cd $HOME/src

wget http://www.cmake.org/files/v2.8/cmake-2.8.12.2.tar.gz
tar xvf cmake-2.8.12.2.tar.gz
cd cmake-2.8.12.2
mkdir build
cd build

cmake -DCMAKE_INSTALL_PREFIX:PATH=/opt/cmake-2.8.12.2 \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_C_COMPILER=/opt/gcc-4.8.2/bin/gcc4.8 \
  -DCMAKE_CXX_COMPILER=/opt/gcc-4.8.2/bin/g++4.8 ..

make -j8
sudo make install

Finally we can focus on building Clang from SVN.

As per the previous blog post where we built Clang under Arch Linux, we need to install Subversion and Python 2.7 first:

sudo apt-get install subversion python

Now we do an SVN checkout of all the required components:

mkdir $HOME/src

cd $HOME/src
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm 

cd $HOME/src/llvm/tools 
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang 

cd $HOME/src/llvm/tools/clang/tools 
svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk extra 

cd $HOME/src/llvm/projects
svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt

Finally we can begin building Clang:

mkdir $HOME/src/llvm/build
cd $HOME/src/llvm/build

/opt/cmake-2.8.12.2/bin/cmake -DCMAKE_INSTALL_PREFIX:PATH=/opt/clang-svn \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_C_COMPILER=/opt/gcc-4.8.2/bin/gcc4.8 \
  -DCMAKE_CXX_COMPILER=/opt/gcc-4.8.2/bin/g++4.8 ..

make -j8
sudo make install

After writing all of that, it’s possible I’ve missed some steps, particularly any build prerequisites. They should be fairly self-explanatory though. For example, I don’t recall if wget is installed by default in Ubuntu, so obviously you might need to run “sudo apt-get install wget” before you can use wget.

 

Clang is a compiler front end for the C, C++, Objective-C and Objective-C++ programming languages, and can often be used as a drop-in replacement for the GNU C & C++ compilers. Clang uses LLVM as its back end. It is possible to checkout the latest version of Clang from the LLVM SVN repository:

mkdir $HOME/src

cd $HOME/src
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm 

cd $HOME/src/llvm/tools 
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang 

cd $HOME/src/llvm/tools/clang/tools 
svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk extra 

cd $HOME/src/llvm/projects
svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt

Arch Linux is a Linux-based operating system for i686 and x86-64 computers. It uses a rolling release model. To build Clang under Arch you’ll first need to install a few prerequisites, including cmake, make, gcc, subversion and python2.

To build Clang with GCC:

#!/bin/sh

BUILD=$HOME/src/llvm/build
rm -rf $BUILD
mkdir $BUILD
cd $BUILD

cmake -DCMAKE_INSTALL_PREFIX:PATH=/opt/clang -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=/bin/gcc \
-DCMAKE_CXX_COMPILER=/bin/g++ \
-DPYTHON_EXECUTABLE:PATH=/usr/bin/python2 ..

make

Then run “make install” as root to install Clang to /opt/clang/.

You can also install an older version of Clang from the Arch repositories to build the SVN version of Clang. This should speed up the build process compared to using GNU C++. It takes roughly an hour to build on an Intel Core 2 Duo.

#!/bin/sh

BUILD=$HOME/src/llvm/build
rm -rf $BUILD
mkdir $BUILD
cd $BUILD

cmake -DCMAKE_INSTALL_PREFIX:PATH=/opt/clang -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=/bin/clang \
-DCMAKE_CXX_COMPILER=/bin/clang++ \
-DPYTHON_EXECUTABLE:PATH=/usr/bin/python2 ..

make

Again, run “make install” as root to install Clang to /opt/clang/.

Lastly, you can build Clang from SVN with the version of Clang you just installed to /opt/clang/.

#!/bin/sh

BUILD=$HOME/src/llvm/build
rm -rf $BUILD
mkdir $BUILD
cd $BUILD

cmake -DCMAKE_INSTALL_PREFIX:PATH=/opt/clang -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=/opt/clang/bin/clang \
-DCMAKE_CXX_COMPILER=/opt/clang/bin/clang++ \
-DPYTHON_EXECUTABLE:PATH=/usr/bin/python2 ..

make

Finally, run “make install” as root to install Clang over itself to /opt/clang/.

 

On February 7, the SBS digital television channels in Melbourne (Mount Dandenong transmitter) moved from UHF 536.625 MHz to VHF 184.5 MHz. SBS now use the old analogue VHF channel 7 that was made available when all the analogue stations were finally switched off late last year. Currently the only station remaining on the UHF band is C31, at 557.625 MHz.

Below is a newly-updated channels.conf, suitable for use with mplayer.

ABC News 24:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2314:2315:560
ABC1:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:561
ABC2:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2307:2308:562
ABC1:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:563
ABC3:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2311:2312:564
ABC Dig Music:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2317:566
ABC Jazz:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2318:567

7 Digital:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:769:770:1328
7 Digital 1:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:769:770:1329
7TWO:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:801:802:1330
7mate:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:817:819:1331
TV4ME:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:881:882:1335
Fresh Ideas TV:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:897:898:1336

Nine Digital:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:519:720:1072
GO!:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:517:700:1074
GEM:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1073
EXTRA:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:520:730:1075
EXTRA 2:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:521:740:1076

ONE HD:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:672:1585
TEN Digital:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1589
ELEVEN:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:516:681:1592
TVSN:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:518:690:1590
SpreeTV:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:520:700:1593

C31:557625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QPSK:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:101:102:3585

SBS ONE:184500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:785
SBS TWO:184500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:162:83:786
SBS 3:184500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:787
NITV:184500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:164:87:788
SBS HD:184500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:102:103:789
SBS Radio 1:184500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:201:798
SBS Radio 2:184500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:202:799
SBS Radio 3:184500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:203:800
 

Recently I’ve been evaluating Elementary OS, a Linux distribution based on Ubuntu Precise (12.04 LTS). Despite the Elementary desktop looking like they’ve cloned parts of the Apple OS X desktop a little too well I appreciate what they’re trying to achieve.

With Ubuntu itself, after about 10.10, their desktop environment started heading in a strange direction, trying to cater for a certain type of “modern” user, and doesn’t sit well with me. Personally I don’t want my desktop looking like a touch device and prefer a more “traditional” environment.

I’d go into this further (and less vaguely) but ultimately it’s just personal preference. I’m sure stock Ubuntu suits some people just fine.

The actual point of this post is that the current release of Elementary OS doesn’t support using software RAID from the installation CD. Apparently the Elementary installer is based on the graphical Precise installer which doesn’t support software RAID either.

One solution is to install stock Ubuntu Precise from the “alternate install” CD. The alternate installer runs in text mode, but does allow installing to a software RAID device. You can then add the Elementary OS repos to /etc/apt/sources.list.d/, and then using apt-get to install all the Elementary OS packages. When I tried this it appeared to work fairly cleanly, but for some reason still left me with somewhat broken desktop environment. Despite having an entirely empty $HOME directory (initially), some apps icons were missing from the Elementary dock that are normally visible on a regular Elementary OS install, and the window theme was still the Precise theme, not the Elementary theme.

elementary-os-1

I’m sure there are simple ways of fixing the above, but there might still be other problems behind the scenes caused by running a “hybrid” distro in this way.

A much simpler and less error-prone method is to install Elementary OS to a single drive initially, then install and run Raider. Raider converts a regular single-disk Linux installation to use software RAID, and pretty much just involves running ‘raider -R1′ (for a RAID1 setup), powering off the system, physically swapping the disks, then powering on again and running ‘raider –run’. You can then uninstall Raider if necessary; it is no longer required.

For the record I used Raider on a system running from an XFS partition (rather than the usual ext3 or ext4 format) and it worked perfectly.

elementary-os-2

elementary-os-3

 

I suspect future versions of Elementary OS (eg. the next version based on the upcoming Ubuntu 14.04) will support software RAID from the installer, but even so, using Raider should still be a viable alternative.

Obviously Raider can also be used to convert other existing Linux installations to a RAID configuration. Make sure you create a backup first though, just in case! (I recommend CloneZilla for that.)

 

Using the SQLite Integration 1.4 plugin on a newly-installed WordPress 3.6.1 site, if I post a new article with the following text:

Between foo and bar.

The text of the post is deleted (eaten) after I click Publish.

It is saved as a Draft post, with a title but no text.

Other articles are posted correctly, provided they don’t have the words “between” & “and” in close proximity, although I’m not sure what is going on there exactly.

This seems specific to the SQLite plugin, as I can’t replicate the bug using MySQL.

kjmtsh has patched the current development version of the SQLite Integration plugin to fix this bug. You can download it from here:

http://wordpress.org/plugins/sqlite-integration/developers/

Click on the “Development Version” link. This link may also work.

Replacing your existing query.class.php with the new version should be all that is necessary.

This is a summary of the bug report I submitted to the WordPress support site.

I imagine the fix will also be in a future 1.5 release of the plugin.

Update: This was fixed in the 1.4.1 release.

 

About four years ago when I ran Windows XP on my main desktop PC I used a small bit of software named Middle Mouse Button. It reassigns the middle button of a mouse to act as a left double-click (or right double-click if you use a left-handed mouse). On modern computer mice the middle button is usually part of the scroll wheel, ie. you press the wheel down to use it. I forgot about this feature after I switched to Ubuntu.

I also bought a Logitech TrackMan Marble a short while after switching to Ubuntu. The Marble was okay, but quite bulky. It has several buttons, but no middle button, and no scroll wheel. Scrolling web pages up and down required holding a button down then using the trackball, which wasn’t ideal, and which isn’t the default in Ubuntu. It took me a bit of Googling to work out how to configure that behaviour. The commands I ran at startup were:

xmodmap -e "pointer = 1 8 3 4 5 6 7 2 9"

xinput set-int-prop "Logitech USB Trackball" "Evdev Wheel Emulation Button" 8 8
xinput set-int-prop "Logitech USB Trackball" "Evdev Wheel Emulation" 8 1

Lately one of the Marble’s buttons started to become unresponsive, so I bought a Logitech MK270 wireless keyboard & mouse. The mouse has a middle button on the scroll wheel, which reminded me of my old mouse setup in XP. I wondered if I could use the middle button to double-click Ubuntu. Some Googling later, I came across the Mouse Customizations page on the Ubuntu Help site.

To cut a long story short, in Terminal, run the following command:

sudo aptitude install x11-utils xbindkeys xautomation

Then run:

xev

Move cursor to xev’s window, hold the mouse still, click in the window using the button you want to reassign, and look at output in the Terminal:

ButtonPress event, serial 36, synthetic NO, window 0x3a00001,
    root 0x112, subw 0x0, time 405119162, (103,107), root:(106,165),
    state 0x0, button 8, same_screen YES

ButtonRelease event, serial 36, synthetic NO, window 0x3a00001,
    root 0x112, subw 0x0, time 405119311, (103,107), root:(106,165),
    state 0x0, button 8, same_screen YES

On the third line xev is telling me it’s “button 8“.

Now edit ~/.xbindkeysrc:

gedit $HOME/.xbindkeysrc

and add the following lines:

"/usr/bin/xte 'mouseclick 1' 'mouseclick 1' &"
b:8 + Release

Here, b:8 means button 8, to match the xev button above.

Finally, run xbindkeys:

xbindkeys

You need to run this each time you start Ubuntu. You can do this manually (if you remember), or configure it to run automatically from System > Preferences > Startup Applications.

The above should also work on non-Ubuntu Linux distros as well as FreeBSD, etc. with some minor modifications.

Lastly, on my system this xbindkeys setting is also active within all my virtual machines in VirtualBox, as well as over Remote Desktop. Very handy.

Say goodbye to double-clicking.

 

I’ve belatedly switched my blogging software from Pyblosxom to WordPress (with a SQLite backend). Pyblosxom is elegant in its simplicity but WordPress makes it much easier to add or update posts remotely, among other things.

I’ll be manually migrating old posts across as time permits.

Two things made me delay the process. One is that I’m not a big fan of MySQL, which is normally used by WordPress. Fortunately there’s now a SQLite plugin for WordPress.

The other (relatively minor) issue is I needed to configure some subdomains for files that shouldn’t be managed by the blog. I could’ve used .htaccess files with redirection/rewrite exceptions but didn’t want to make things more complicated than necessary. Subdomains (eg. dl.ozzmosis.com) make it much easier to isolate the blog from everything else (photos, software, etc).

Evidently I’d been running Pyblosxom since November 2005, and Blosxom before that since September 2004. That’s a pretty solid run.

Update: All posts have been migrated. There was only one small hiccup with the content of one or two posts causing posts not to publish. The bug doesn’t appear in a test WordPress blog I set up with a MySQL backend, so for now I’m going to assume it’s the SQLite plugin’s fault. More on that in a future post.

 

A short addendum to my previous post…

I forgot to explain the reason I decided to write my own scheduler. I could’ve used cron or atd, but those daemons aren’t the most user-friendly to quickly set schedules for. cron may be standard on Linux and BSD systems but the format is arcane, error-prone and non-intuitive. It’s not horrible but I’m a bit surprised something more sensible hasn’t replaced it. atd is more human, but I wanted a configuration file where I didn’t have to know the date when a show began to record it – only the weekday. Then the script would figure out what date that weekday fell on and act accordingly.

Actually it turns out you can sort of do this with atd, although it’s not documented, at least not on the man page, and the time and weekday are reversed. To run a command at 7pm on the upcoming Wednesday:

$at 19:00 Wed << END
? echo Hello world.
? END
warning: commands will be executed using /bin/sh
job 7 at Wed Sep  4 19:00:00 2013

$ atq
7       Wed Sep  4 19:00:00 2013 a ozzmosis

The other advantage is the configuration of my scheduler accepts an end time, which allows it to calculate the recording duration and display it to the user.

The other issue with the cron and atd daemons is that you don't get to see the output of the command in realtime. Instead you get an email after the command has completed, which isn't always ideal for doing scheduled recordings. There are probably a few ways around that, but I'm not keen on them.

Due to the script requiring the Python interpreter, and it never actually terminating (unless you hit Ctrl+C), there is a small amount of memory overhead from having Python loaded in memory all the time. On modern PCs this is trivial, though. There is also no measurable CPU overhead from having the script continuously running in the background - the call to time.sleep() takes care of that.

Lastly, the source code to the script is released to the public domain. You are free to do what you want with it and credit me if you feel like it (or not). I'm sure it has other uses.

 

Recently for various reasons my blog has become a very low priority, but I should belatedly fulfil a promise I made in the last post where I mentioned a Python script for recording digital television in Linux.

To run the script the only system requirements are a working DVB device (eg. PCI or USB tuner) that tzap can talk to, and a recent version of Python 2.x. Python 2.6.5 works fine on my system running Ubuntu Lucid 10.04. You will need to have tzap working correctly beforehand. See my previous blog post.

I had intended to clean up the code a little but never got around to it. I’m not proud of the date parsing code in it. Looking at it now I can barely understand what it’s doing, but I’ve been using it for a long time now without problems. Anyway, you can download it from here:

http://dl.ozzmosis.com/tvsched.py

The script looks for ~/etc/tvsched.conf and puts the recorded streams in /media/xfs/vidcap. Those paths are hard-coded in the script - obviously you’ll need to change them to suit your system.

tvsched.conf is a comma-separated value (CSV) formatted file with a list of TV shows to record. Comments are allowed if they are prefixed with ‘#’ at the start of the line. Blank lines are allowed, and ignored.

# day, start, end, channel, show-name
Sat, 22:50, 08:00, ABC1, rage-DATE
Sun, 9:30p, 2:00am, TEN Digital, f1-2013-belgium-race

The format should be fairly self-explanatory, with the following comments:

Days of the week can begin with any unambiguous form of the English day of the week. Two letters is enough to be unambiguous, therefore ”Mo” is accepted for “Monday”, “Tues” is accepted as “Tuesday”, etc.

The start and end times can be in either 12-hour or 24-hour format, specifying hours and minutes. If using 12-hour format, “a”, “am”, “p” and “pm” are acceptable.

The start and end times can cross midnight.

The channel name should match a channel in the channels.conf file that tzap is using. This is case insensitive – “abc1″ is the same as “ABC1″ as far as tzap is concerned.

The show name can be any name but should not have spaces in it, otherwise the recorded file will end up in the wrong place. The script doesn’t actually check for that, so be careful.

The string ‘DATE’ in the show name is automatically replaced with the current date in YYYY-MM-DD format.

The script automatically creates a directory under /media/xfs/vidcap/ to store the recorded .mpg file. The .mpg file itself has the format “capture-YYYY-MM-DD-hhmmss.mpg”.

The script re-parses the tvsched.conf roughly every 20 seconds and shows the parsed output to the screen. It will show the start date, start time, end time, recording duration, channel, and the show name you’ve provided.

An unusually long recording duration could mean that you’ve made a mistake entering the start or end time – usually by accidentally mixing up 12 and 24 hour time.

You can lower this 20 second refresh value if you like, but the screen will scroll faster with the parsed output.

The script will abort if tvsched.conf cannot be parsed correctly.

Over a single weekend, the above tvsched.conf file would result in two recordings:

/media/xfs/vidcap/rage-2013-08-24/capture-2013-08-24-225000.mpg
/media/xfs/vidcap/f1-2013-belgium-race/capture-2013-08-25-213000.mpg

The filenames are approximate, since the script only wakes up 20 seconds, therefore the ‘seconds’ part of the filename may not be zeroed.

I run the script under GNU Screen, so it can be detached. You could also use tmux.

 

About two years ago I switched operating systems from Windows XP to Ubuntu Linux on my main desktop PC. One of the things I wanted to do was watch digital free-to-air (FTA) TV using this setup. I have a Twinhan Alpha USB DVB receiver which is recognised by Ubuntu automatically, so it was just a matter of chosing the right software. Initially looked at MeTV, Kaffeine and MythTV. MeTV was probably the least difficult to configure. Kaffeine was OK, albeit with a more cumbersome user interface. MythTV seemed overkill for what I wanted, with an odd user interface, too many dependencies (notably MySQL) and too many features I didn’t need.

I’d long been a user of the Windows port of MPlayer, and after a bit of web searching I discovered that MPlayer in Linux could also play video directly from the DVB receiver, provided you had a channels.conf (valid for your reception area) in your $HOME/.mplayer/ directory. This is mine, for digital TV reception in Melbourne, Australia:

$HOME/.mplayer/channels.conf:

ABC News 24:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2314:2315:560
ABC1:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:561
ABC2:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2307:2308:562
ABC1:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:563
ABC3:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2311:2312:564
ABC Dig Music:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2317:566
ABC Jazz:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2318:567
7 Digital:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:769:770:1328
7 Digital 1:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:769:770:1329
7TWO:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:801:802:1330
7mate:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:817:819:1331
Nine Digital:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:519:720:1072
GO!:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:517:700:1074
GEM:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1073
ONE HD:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:672:1585
TEN Digital:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1589
ELEVEN:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:516:681:1592
SBS ONE:536625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:785
SBS TWO:536625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:162:83:786
SBS 3:536625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:787
SBS 4:536625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:788
SBS HD:536625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:102:103:789
C31:557625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QPSK:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:101:102:3585

With some exceptions, the above file was generated from running the following command:

scan /usr/share/dvb/dvb-t/au-Melbourne > $HOME/.mplayer/channels.conf

The exceptions are:

(1) there seems to be a bug in the ‘scan’ command that prevents it from selecting the correct audio channels on the HD channels, eg. the last three numbers for ONE HD are reported as “514:0:1585″ rather than “514:672:1585″. For the HD channels (ABC News 24, 7mate, GEM, ONE HD & SBS HD) I had to use an external set-top box to find the middle number for the correct audio channel. It’s possible more recent versions of ‘scan’ may have corrected this.

(2) in Ubuntu Lucid 10.04 the /usr/share/dvb/dvb-t/au-Melbourne file is missing the entry for community television Channel 31 that began broadcasting on digital TV recently. The complete file is:

/usr/share/dvb/dvb-t/au-Melbourne:

# Australia / Melbourne (Mt Dandenong transmitters)
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
# ABC
T 226500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Seven
T 177500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Nine
T 191625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Ten
T 219500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# SBS
T 536625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
# C31
T 557625000 7MHz 3/4 NONE QPSK 8k 1/16 NONE

Now you can test it!

mplayer 'dvb://Nine Digital'

Rather than typing this command each time I have several tcsh aliases configured for each channel:

$HOME/etc/dvb-aliases:

alias mplayer-dvb "mplayer -cache 1024 -framedrop -x 688 -y 384"
alias mplayer-dvb-lq "mplayer -cache 2048 -framedrop -x 688 -y 384 -vfm ffmpeg -lavdopts lowres=1:fast:skiploopfilter=all:threads=2"

alias onehd "mplayer-dvb-lq 'dvb://ONE HD'"
alias 11sd "mplayer-dvb 'dvb://ELEVEN'"
alias tensd "mplayer-dvb 'dvb://TEN Digital'"
alias 10sd tensd

alias ninesd "mplayer-dvb 'dvb://Nine Digital'"
alias 9hd ninehd
alias 9sd ninesd
alias gosd "mplayer-dvb 'dvb://GO!'"
alias gem "mplayer-dvb-lq 'dvb://GEM'"

alias 7sd "mplayer-dvb 'dvb://7 Digital'"
alias 7two "mplayer-dvb 'dvb://7TWO'"
alias 7mate "mplayer-dvb-lq 'dvb://7mate'"

alias abc24 "mplayer-dvb-lq 'dvb://ABC News 24'"
alias abc1 "mplayer-dvb 'dvb://ABC1'"
alias abc2 "mplayer-dvb 'dvb://ABC2'"
alias abc3 "mplayer-dvb 'dvb://ABC3'"

alias sbs1 "mplayer-dvb 'dvb://SBS ONE'"
alias sbs2 "mplayer-dvb 'dvb://SBS TWO'"
alias sbs sbs1
alias sbshd "mplayer-dvb-lq 'dvb://SBS HD'"
alias ch31 "mplayer-dvb 'dvb://C31'"
alias c31 ch31

In $HOME/.tcshrc I have added the following command to load the above aliases automatically whenever I start tcsh:

source $HOME/etc/dvb-aliases

You’ll notice initially that there are ‘mplayer-dvb’ and ‘mplayer-dvb-lq’ aliases called by the aliases further down:

‘mplayer-dvb-lq’ is for viewing HD channels on an older PC. Currently
I’m using a 3.4 GHz IBM ThinkCentre, and mplayer can’t quite keep-up
with decoding full 1080i MPEG2 HD broadcasts in real time. Using the
“-vfm ffmpeg -lavdopts lowres=1:fast:skiploopfilter=all:threads=2″
mplayer switches lowers the resolution so it can be viewed in real
time without excessive CPU overhead. There are occasional visual
artefacts, and obvious degradation in video quality, but the end
result is still quite watchable.

‘mplayer-dvb’ is for viewing SD channels.

In the past where I’ve had poor reception, setting a small (1024 KB) cache (-cache 1024) seemed to prevent mplayer from prematurely dying whenever there was no signal. Note that the larger the cache, the more delayed your programme will be – time-shifted by a few seconds or more. For HD broadcasts I have a 2048 KB cache, due to their higher bitrate. You could experiment with these cache sizes or perhaps leave them out entirely.

The -framedrop option tells mplayer to “skip displaying some frames to maintain A/V sync on slow systems”. Even on fast systems this option may be useful where the CPU is overloaded by other tasks, eg. video encoding.