Monday, January 31, 2011

MythTV and network mounts

After setting up a MythTv 0.24 frontend to use a samba share for files from the backend I discovered that I could no longer watch live TV on it. If I tried to watch live TV there would just be a pause and then a "Error opening jump program file buffer" error message. Looking in the output on stdout wasn't much more helpful, with "Error: Took more than 10 seconds to be allowed to read, aborting" being about the only meaningful message.

It took me ages to track down that the problem is with cached IO on the network share. If the CIFS file system is caching the inode information (which includes the size attributes), then the MythTv frontend thinks that no live TV is being streamed and gives up after a while.

The solution to this is to add the 'directio' option when mounting the network partition (e.g. '-o directio' on the command line). If it's an NFS share then an alternative is to use 'forcedirectio' in the /etc/exports on the server (which is useful if you don't want to change all your MythTv frontends).

Friday, January 28, 2011

Upgrading MythTV 0.23 to 0.24 on Ubuntu

I recently upgraded MythTV 0.23 to 0.24 on both my backend (Debian testing) and the various front ends I use (Ubuntu with Mythbuntu auto-builds/MythTV-Updates).

Everything went smoothly until I tried to watch some TV or recordings from within the frontends. The video would playback at about half speed and with no audio.

After a while I managed to figure out that the problem was caused by using the default audio device. To fix this just update the audio device (in the frontend settings) to point to your actual audio device.

Saturday, January 22, 2011

Getting dual tuner KWorld U399 USB DVB-T working on linux 2.6.37

I recently upgraded the kernel version on my MythTV. One side affect of this was that the second tuner for my DVB-T USB stick (an af9015 based KWorld U399) no longer existed in /dev/dvb. In previous versions of the af9015 module it was just a case of explicitly enabling it with a module parameter of dual_mode=1 and possibly suffering some reception issues when both tuners are enabled.

To get the second tuner working it's necessary to use the very latest firmware for the device. So download the firmware file from here and place it in /lib/firmware. From a quick look at the source code for af9015 it looks like the driver now checks a value in the EEPROM to see if dual mode is safe or not. I assume the clever developer for the af9015 driver has worked out that this is what determines if there will be reception issues with both tuners enabled and that the 5.1.0.0 firmware updates this EEPROM in a suitable way.

You'll need to unplug your USB stick and replug it in to get it to use the new firmware, but you should then get two DVB tuners.

Thursday, September 16, 2010

Accidentally installing Grub to /dev/sda on a Mac OS X machine

I managed to accidentally install GRUB to /dev/sda when setting up my MacBookPro to boot Ubuntu, WinXP and Mac OS X. I knew I shouldn't have, but I wasn't paying attention to the installer when it asked me. In my defence I was also slightly rushed as I wanted to get the installation running before I went to the pub...

Anyway after much hunting and not being able to boot Linux or Windows XP, I finally discovered the solution in this blog post. The author had, like me, managed to ignore all the warnings. Luckily recovery is just a simple case of sticking in the Mac OS X install CD, booting off it and running "fdisk -u /dev/rdisk0" in terminal. This will then restore the Mac OS X MBR to it's proper state.

I did get a warning about not being able to find an MBR file, but it still let me update the MBR and it all seems to be working anyway. As well as fixing Linux and Windows XP booting (which previously would just sit there with a blinking cursor in the top left) it also fixed the slightly annoying issue of rEFIT having a 'Boot Linux from HD' option which I couldn't get rid of.

Tuesday, August 24, 2010

Packing is Hard

Recently there has been some talk about a computer science problem and a, possible, proof that P doesn't equal NP. The proof of if P and NP are the same is one which I think that every computer science student must have a vague suspicion that they could prove when they first hear about it in their computational complexity course. Perhaps as a consequence of this, undergrads are told that they're not going to work it out as "lots of very clever people have tried to show it and failed".

Good for one week of backpacking?

As an aside, the work around showing P and NP being different or the same is a great example of the scientific method at it's best: all the experts generally agree that P isn't the same as NP, but that doesn't stop them from going through any proof which concurs with that belief with a fine-tooth comb. There is a such a clear separation of believe and the need for formal proof that there's a $1 million dollar prize available for a proof that shows P is the same as or different to NP.

What's In My Bag - a Photo of the contents of a backpack, including spade and bottle of alcohol

Given that few of us are likely to win that prize, why should everyday people care about if P is the same as NP. The simple answer is that it is applicable to many everyday problems, such as packing a bag. NP stands for 'nondeterministic polynomial time' which is a very complex way of saying that, when given a solution to an NP problem, you can easily show it is a correct solution to the problem. In the case of packing a bag this is as simple as seeing that they've fitted all the items into the bag.

A problem which is 'P' is a 'polynomial time problem', which is to say that finding a solution from scratch is as easy to find as showing that a solution is correct to an NP problem. So if it was to be shown that P problems are not the same as NP problems then it would confirm that it really is sometimes easier to solve a problem when you've got the solution.

On the other hand, showing that P isn't the same as NP doesn't help practical everyday computing. The vast majority of polynomial time problems still take too long to solve with current computing technology, so all a proof would show is that there are very very hard problems as well as very hard problems. Most importantly, showing P isn't the same as NP certainly won't stop your word processor crashing when you've forgotten to save for 10 minutes.

Sunday, May 23, 2010

Last.fm on Ubuntu Lucid Lynx (10.04)

Having recently got a nice shiny new netbook (an HP/Compaq 311c) I was trying to get last.fm to compile on it. My netbook was running a reasonably fresh install of Ubuntu Lucid Lynx (10.04).

So I downloaded the source for last.fm-1.4.2.58240 and unzipped it into my source directory. Knowing that it needed qt4 I then ran:
sudo apt-get install libqt4-dev

With that all installed I tried running ./configure in the source directory and it said everything was fine, so I went ahead and typed make.

After waiting while it compiled I was then greeted by the following error:
make[1]: Entering directory `/home/marvin/src/last.fm-1.4.2.58240/src/libFingerprint/fplib/pro_qmake'
g++ -c -pipe -O2 -w -fPIC -DNBREAKPAD -DLINUX -DNDEBUG -I/usr/share/qt4/mkspecs/linux-g++ -I. -I../../../../src -I../../../../build -I../../../libMoose -I../../../libUnicorn -I../include -I../src -I../../libs/fftw/src/api -I../../../../res/libsamplerate -o ../../../../build/fplib/release/FingerprintExtractor.o ../src/FingerprintExtractor.cpp
../src/FingerprintExtractor.cpp: In member function ‘bool fingerprint::FingerprintExtractor::process(const short int*, size_t, bool)’:
../src/FingerprintExtractor.cpp:445: error: ‘memcpy’ was not declared in this scope
make[1]: *** [../../../../build/fplib/release/FingerprintExtractor.o] Error 1
make[1]: Leaving directory `/home/marvin/src/last.fm-1.4.2.58240/src/libFingerprint/fplib/pro_qmake'
make: *** [sub-src-libFingerprint-fplib-pro_qmake-fplib-pro-make_default-ordered] Error 2
marvin@Anjie:~/src/last.fm-1.4.2.58240$


Knowing that memcpy is part of the standard C library I thought this seemed a little strange. So I opened up last.fm-1.4.2.58240/src/libFingerprint/fplib/src/FingerprintExtractor.cpp and added the following line in bold:
#include <cmath>
#include <string.h>

Then recompiled.

The next error was the following:
g++ -c -pipe -O2 -w -fPIC -DNBREAKPAD -DLINUX -DNDEBUG -I/usr/share/qt4/mkspecs/linux-g++ -I. -I../../../../src -I../../../../build -I../../../libMoose -I../../../libUnicorn -I../include -I../src -I../../libs/fftw/src/api -I../../../../res/libsamplerate -o ../../../../build/fplib/release/OptFFT.o ../src/OptFFT.cpp
../src/OptFFT.cpp: In constructor ‘fingerprint::OptFFT::OptFFT(size_t)’:
../src/OptFFT.cpp:262: error: ‘exit’ was not declared in this scope
make[1]: *** [../../../../build/fplib/release/OptFFT.o] Error 1
make[1]: Leaving directory `/home/marvin/src/last.fm-1.4.2.58240/src/libFingerprint/fplib/pro_qmake'
make: *** [sub-src-libFingerprint-fplib-pro_qmake-fplib-pro-make_default-ordered] Error 2
marvin@Anjie:~/src/last.fm-1.4.2.58240$


Which I fixed by editing last.fm-1.4.2.58240/src/libFingerprint/fplib/src/OptFFT.cpp to include the line in bold:
#include <iostream>
#include <memory.h> // for memcopy
#include <stdlib.h>

And then once again ran make.

The next error was:
g++ -c -pipe -O2 -w -D_REENTRANT -fPIC -DNBREAKPAD -DLINUX -DQT_NO_DEBUG -DQT_SQL_LIB -DQT_XML_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtXml -I/usr/include/qt4/QtSql -I/usr/include/qt4 -I../../src -I../../build -I../libMoose -I../libUnicorn -Ifplib/include -I../src/ -I../../res/mad -I../../build/LastFmFingerprint/release -o ../../build/LastFmFingerprint/release/MP3_Source_Qt.o MP3_Source_Qt.cpp
MP3_Source_Qt.cpp: In function ‘short int f2s(mad_fixed_t)’:
MP3_Source_Qt.cpp:70: error: ‘SHRT_MAX’ was not declared in this scope
MP3_Source_Qt.cpp:72: error: ‘SHRT_MAX’ was not declared in this scope
MP3_Source_Qt.cpp: In member function ‘virtual void MP3_Source::skipSilence(double)’:
MP3_Source_Qt.cpp:379: error: ‘abs’ was not declared in this scope
MP3_Source_Qt.cpp:385: error: ‘abs’ was not declared in this scope
make[1]: *** [../../build/LastFmFingerprint/release/MP3_Source_Qt.o] Error 1
make[1]: Leaving directory `/home/marvin/src/last.fm-1.4.2.58240/src/libFingerprint'
make: *** [sub-src-libFingerprint-make_default-ordered] Error 2


So I opened last.fm-1.4.2.58240/src/libFingerprint/MP3_Source_Qt.cpp and added the lines in bold:
#include <cassert>
#include <stdexcept>
#include <stdlib.h>
#include <limits.h>


And ran make once more.

This time it was a linking error:
g++ -Wl,-O1 -shared -Wl,-soname,libLastFmFingerprint.so.1 -o libLastFmFingerprint.so.1.0.0 ../../build/LastFmFingerprint/release/Sha256File.o ../../build/LastFmFingerprint/release/Sha256.o ../../build/LastFmFingerprint/release/MP3_Source_Qt.o ../../build/LastFmFingerprint/release/Fingerprinter2.o ../../build/LastFmFingerprint/release/FingerprintCollector.o ../../build/LastFmFingerprint/release/FingerprintQueryer.o ../../build/LastFmFingerprint/release/moc_Fingerprinter2.o ../../build/LastFmFingerprint/release/moc_FingerprintCollector.o ../../build/LastFmFingerprint/release/moc_FingerprintQueryer.o -L/home/marvin/src/last.fm-1.4.2.58240/bin -L/home/marvin/src/last.fm-1.4.2.58240/build/LastFmFingerprint/../fplib -L/usr/lib -lMoose -L/home/marvin/src/last.fm-1.4.2.58240/bin -lLastFmTools /home/marvin/src/last.fm-1.4.2.58240/build/fplib/libfplib.a -lsamplerate -lfftw3f -lQtSql -lQtXml -lQtGui -lQtNetwork -lQtCore -lpthread
/usr/bin/ld: cannot find -lsamplerate
collect2: ld returned 1 exit status
make[1]: *** [../../bin/libLastFmFingerprint.so.1.0.0] Error 1
make[1]: Leaving directory `/home/marvin/src/last.fm-1.4.2.58240/src/libFingerprint'
make: *** [sub-src-libFingerprint-make_default-ordered] Error 2
marvin@Anjie:~/src/last.fm-1.4.2.58240$


So I ran sudo apt-get install libsamplerate0 libsamplerate0-dev libfftw3-dev libfftw3-3 libmad0-dev libmad0 libgpod-dev libgpod4 libasound2-dev and then ran make again.

If you're wondering how I came up with all the libraries above, it was just from running make several times and then using apt-cache search to search for the missing libraries. I didn't include these steps as they're a bit tedious.

Having done all that it's possible to run last.fm with bin/last.fm.sh.

Thursday, March 04, 2010

Not all equals are born equal

The relationship between two things is something that we learn early in life. It's quite an important thing to know about, especially for understanding the world we live in.

However the question of 'are these the same' or 'are these equal' is surprisingly tricky. It might immediately seem rather obvious, but in actual fact there is a surprising amount of complex mathematics to do with equality and how you define it. As it turns out there are quite a few ways of saying that things are the same, leading to a description of all the different ways of comparing things being called an Equivalence relationship.

Equivalence relationships have three key properties:

  • Reflexive - That everything is equal to itself.
  • Symmetric - That if object A is equal to thing B then thing B must be equal to object A.
  • Transitive - That if A equals B and B equals C then A must equal C.
All of which might seem rather obvious, but mathematicians like to flip-flop between stating the massively obvious and the painfully complex.

For example consider the following:

Maisy
=
Maisy
Quite clearly, for most sensible definitions of equality these will be the same; mostly due to them being identical.

Where it starts to get tricky is if there is some variation between the two things being compared. Initially the answer to this might appear to be "no, they aren't equal", but consider the following:

Maisy
=
Maisy
If you took a poll of people to ask if these two were equal you'd probably come up with the following options in some proportion:
  • Yes, it's the same image.
  • Yes, apart from one is a bit distorted.
  • No, they look different.
All of which are acceptable answers, it just depends on how you define equality. The first answer assumes the comparison is about the contents of the image rather than how it's presented. The second answer is the middle ground, acknowledging that the images are the same but that there is a different in how they a presented. The final answer is the other extreme, the pictures aren't the same so they're not equal.

This all ties in very deeply with one of the foundations of computer science; the distinction between comparing the concept represented by some data and the data itself. A clearer example of the distinction here would be to use two pictures where the idea of equality is even more fuzzy.

Maisy
=
Maisy

As before the answer to if these two are equal is yes and also no. If the question being asked is "are these the same cat?" then the answer is yes; if the question is instead "are these photos the same?" then the answer is no. Usually it's obvious which of these questions is being asked from the context and generally the question is phrased in the more explicit way.

Computers are no different. Ever since Ada Lovelace realised that numbers could be used to represent ideas, concepts and physical objects there has been the need to distinguish between the two types of equality. It's necessary to explicitly tell the computer if you're asking if the numbers are the same (asking if the photos are the same for the above example) or asking if the thing the numbers represent are the same (asking if it's the same cat).

This distinction between the values and what the values are meant to represent occurs frequently in computer languages. For example in the Java language the operator '==' is used to compare the number representing the object, where as the 'equals()' method is used to compare the concept/item that the object represents.

Some languages complicate this further, such as JavaScript where there is the '==' equality operator and the '===' strict equality operator. The need for this arises because when JavaScript first came into existence the '==' operator was defined in such a way that the number 5 was equal to a sequence of text which is the character 5. This is a little confusing, but for various reasons computers choose to represent the character/digit of 5 as the number 53.

This distinction between a character/digit of 5 and the number 5 (which you get from adding 2 and 3) might seem a little strange, but consider the phrase "I ate 5 strawberries". It's necessary for there to be some way to represent each character/letter as a number and the method of representation that has become standard has the digit 5 represented by the number 53.

Coming back to the difference between '==' and '===', the former will say that "5" is equal to 5, where as the latter will say that they are not equal (due to the internal representation being different). This can be a little confusing when first coming to JavaScript and is the main reason for writing this post. I discovered the difference and thought I should share.

So the next time you're trying to work out if two things are the same, just remember to think what you are wanting to compare.

Creative Commons License
The words and photos on this webpage which are created by Toby Gray are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.0 England & Wales License.