tag:blogger.com,1999:blog-77185653307482646672024-03-13T14:22:08.868-07:00Dynamic ThinkingDannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.comBlogger59125tag:blogger.com,1999:blog-7718565330748264667.post-72675095338230348972012-08-18T12:34:00.001-07:002012-08-18T14:21:00.780-07:00iPod/iPhone Video Encoding with ffmpeg and mplayer<p>Up until fairly recently, I've been transcoding videos for playback on my (ancient, 1st-gen) iPod Touch <a href="http://dynamic-thinking.blogspot.co.uk/2010/08/encoding-x264-video-for-ipod-touch-with.html">using mencoder</a>. But it's less than ideal. mencoder is, by admission of core mplayer devs, an unsupported, unmaintained piece of software that may or may not work at any given moment, and which isn't particularly high on the fixit list. When it comes to transcoding, ffmpeg is the better platform.</p>
<p>
Almost.
</p>
<p>
ffmpeg isn't too great with subtitles, and I watch a great deal of subtitled content. So what's really required is something that's as good at playback and subtitle rendering as <a href="http://www.mplayerhq.hu/design7/news.html">MPlayer</a>, but with <a href="http://ffmpeg.org/index.html">FFmpeg</a>'s encoding capabilities. So the answer really is to use both: mplayer to write raw video frames to a pipe, and ffmpeg to transcode from that pipe. As a final step, package the encoded video in an iPod-ready <code>m4v</code> file and copy the audio stream(s) from the original source:</p>
<p>
<div style="margin-left: 3em; font-family:monospace;">mkfifo <span style="color:red;">a-named-pipe.fifo</span></div>
</p>
<p>
<div style="margin-left: 3em; font-family:monospace;">mplayer <span style="color:orange;">a-source-file.mkv</span> -noconfig all -vf-clr -nosound -benchmark -ass -vf scale=480:-10 -vo yuv4mpeg:file=<span style="color:red;">a-named-pipe.fifo</span></div>
</p>
<p>
This will block immediately, as there's nothing reading from the pipe that mplayer is writing to, and the pipe only has a small buffer. In another terminal (in the same directory), run this to pull video frames from the pipe into ffmpeg:
</p>
<p>
<div style="margin-left: 3em; font-family:monospace;">ffmpeg -i <span style="color:red;">a-named-pipe.fifo</span> -vcodec libx264 -b:v 768k -flags +loop+mv4 -cmp 256 -partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 -me_method hex -subq 7 -threads auto -trellis 1 -refs 5 -bf 0 -coder 0 -me_range 16 -profile:v baseline -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qmin 10 -qmax 51 -qdiff 4 -y <span style="color:blue;">video-only-file.avi</span></div>
</p>
<p>
Once mplayer terminates at end-of-file, you'll have <span style="color:blue;">video-only-file.avi</span>, a silent-movie AVI encapsulating a video stream that's iPod-ready. If you had subtitles, they're burned into the video. You can discard <span style="color:red;">a-named-pipe.fifo</span>. Now, you just need to take the encoded video in the AVI, splice in an AAC version of the audio stream from the original source, and pack it into an M4V container that your device can work with.
</p>
<p>
<div style="margin-left: 3em; font-family:monospace;">ffmpeg -i <span style="color:orange;">a-source-file.mkv</span> -i <span style="color:blue;">video-only-file.avi</span> -acodec libfaac -b:a 128k -ac 2 -vcodec copy -f ipod -map 0:a -map 1:v -metadata title=My Video -y <span style="color:green;">output-video.m4v</span></div>
</p>
<p>
Once you've checked that <span style="color:green;">output-video.m4v</span> is good, you can discard the intermediate <span style="color:blue;">video-only-file.avi</span>.
</p>
<p>Now, this all looks like a lot of hassle (and it kind of is), but it's far more resilient and reliable than the <code>mencoder</code>-only version. It even gives you chapters and multiple audio streams, if they were in the source.</p>
<p>If all that's a bit too fussy, I've wrapped it up in a Perl script hosted on <a href="https://github.com/dannywoodz/ipod-encode">GitHub</a>, meaning that you can do everything with just:</p>
<p>
<div style="margin-left: 3em; font-family:monospace;">
perl ipod-encode.pl --title='My Video Title' --standalone input-video.mkv
</div>
</p>
<p>Feedback and improvement suggestions are always welcome.</p>Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com3tag:blogger.com,1999:blog-7718565330748264667.post-46503704465419206712012-07-22T03:52:00.000-07:002012-07-22T04:38:15.219-07:00Emacs: Speeding Up Loading Your .emacs File<p>One of the best things about Emacs is its extensibility. The bulk of its editing functions are written in the same language as the editor itself, Emacs Lisp, which you, the user, can program inside the editor itself.</p>
<p>Experienced Emacs users invariably find packages on the Web, maybe from <a href="http://emacswiki.org/">EmacsWiki</a> or <a href="https://github.com/">github</a>, and stuff them into their <code>.emacs</code> file, loading them with <code>(require)</code>. For a small number of small packages, this can often work well, but eventually you're going to either stumble across a large package like <a href="http://orgmode.org/">Org Mode</a>, or for the polyglot programmer, load the major modes for half a dozen or more languages.</p>
<p>All those <code>(load)</code> and <code>(require)</code> calls will slow down the time taken to load your <code>.emacs</code> file considerably. If you want to see how long it takes, <code>M-x emacs-init-time</code> will give you the answer. Personally, I consider load times in excess of one or two seconds to be unacceptable for development-class hardware.</p>
<h3>Loading What You Need, When You Need It</h3>
<p>So how do you speed up loading of your init file, but at the same time keep everything that makes Emacs work for you? Simple: <code>autoload</code> and <code>eval-after-load</code>.</p>
<p><code>autoload</code> tells Emacs that a function is defined in a specific file, <em>but doesn't actually load that file until it's explicitly asked for</em>, e.g:</p>
<p><code>(autoload 'ruby-mode "ruby-mode")</code></p>
<p>This tells Emacs that the function <code>ruby-mode</code> is in the file ruby-mode.el (or ruby-mode.elc, if appropriate). When the function is invoked, the path elements in <code>load-path</code> are checked in order to find ruby-mode.el, which is then loaded on-demand.</p>
<h3>Automatically Using the Right Mode for a File</h3>
<p>So, how does <code>ruby-mode</code> get called? Well, it's either explicitly (<code>M-x ruby-mode</code>), or by specifying that it should be invoked when you load an appropriate file, like this:</p>
<code>(add-to-list 'auto-mode-alist '("\\.rb$" . ruby-mode))</code>
<p>This says that Emacs should enter <code>ruby-mode</code> whenever a file with the ".rb" extension is loaded. When it is, <code>ruby-mode</code> is started, and the <code>autoload</code> ensures that it is loaded from the appropriate file if required.</p>
<h3>Customising Just-Loaded Code</h3>
<p>But what happens if you want to do more than just load the major mode when .rb files are loaded? Maybe you also want to load <code><a href="https://github.com/capitaomorte/yasnippet">yasnippet</a></code>, <code><a href="http://www.emacswiki.org/emacs/AceJump">ace-jump</a></code> or other modules?</p>
<p>You've got two choices: a mode hook, or <code>eval-after-load</code>. The former is cleaner, but the latter is more flexible, and available in the event that there's no mode hook variable for your language (e.g. <code>scala-mode-hook</code> isn't available until after <code>scala-mode</code> is loaded).</p>
<p><code>eval-after-load</code> takes an Emacs Lisp form <em>as an unevaluated list</em> and only evaluates it once the specified file has been loaded, e.g.:</p>
<p><code>(eval-after-load "ruby-mode" '(setup-autocompletion))</code></p>
<p>The time-saver here comes from the fact that the quoted form is evaluated after load, so it can potentially result in quite a lot of work getting done when it's loaded, and you'll only feel the effects when you enter that specific mode.</p> In this case, the same effect can be achieved by adding a function to <code>ruby-mode-hook</code>:</p>
<p><code>(add-to-list 'ruby-mode-hook #'setup-autocompletion)</code></p>
<p>Here, I'm assuming that <code>(setup-autocompletion)</code> has already been defined and, as in my case, is referred to by multiple programming modes (nb: that function is one I've written myself; it's not part of Emacs, so you won't have it unless you've written one with the same name!). The form can be atribrarily complex, but it must be a single form. Multiple forms can be wrapped in a <code>(progn)</code> to compose them. Here's an example for <code>cperl-mode</code> that's more involved, setting some defaults, defining some Perl-specific functions, and doing that <code>(setup-autocompletion)</code> again.</p>
<pre>
(eval-after-load "cperl-mode"
'(progn
(setq
cperl-merge-trailing-else nil
cperl-continued-statement-offset 0
cperl-extra-newline-before-brace t)
(defun installed-perl-version ()
(interactive)
(let ((perl (executable-find "perl")))
(if perl
(shell-command-to-string (concatenate 'string perl " -e '($v = $]) =~ s/(?<!\\.)(?=(\\d{3})+$)/./g; print $v;'")))))
(defun use-installed-perl-version ()
(interactive)
(let ((perl-version (installed-perl-version)))
(if perl-version
(save-excursion
(beginning-of-buffer)
(let ((case-fold-search nil))
(re-search-forward "^use [a-z]" (point-max) t)
(beginning-of-line)
(open-line 1)
(insert (concatenate 'string "use v" perl-version ";"))))
(message "Couldn't determine perl version"))))
(setup-autocompletion)))
</pre>
<p><code>eval-after-load</code> isn't limited to programming modes. Here's an example of how you can auto-load your credentials when loading <a href="http://www.gnus.org/">GNUS</a>:</p>
<pre>
(eval-after-load "gnus"
'(setq
nntp-authinfo-file "~/.authinfo"
gnus-nntp-server *my-nntp-server*))
</pre>
<h3>Summary</h3>
<p>So, there you have it:</p>
<ul>
<li><code>auto-mode-alist</code> allows you to enter specific modes based on file extension</li>
<li><code>autoload</code> allows you to <em>not</em> not load that mode until it's actually required by opening a file of that type</li>
<li><code>eval-after-load</code> and/or <code>(add-to-list {mode}-mode-hook)</code> can be used for mode customisation or setup, again only when the mode actually loads</li>
</ul>
<p>As much as possible, ensure that your .emacs file makes minimal use of non-deferred <code>(require)</code> or <code>(load)</code> calls, although <code>(require 'cl)</code> is an exception. It's also fair to load code/minor modes that you use all the time, since there's no point in deferring them just to load them the first time you do anything!</p>Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-294622126470565082012-06-07T12:06:00.001-07:002012-06-10T14:27:56.767-07:00Perl: 'my' vs. 'local'There's often a lot of confusion among new Perl hackers as to what the difference between <code>my</code> and <code>local</code> tags on variables. Unfortunately, many reach for the wrong one because the language that they're used to working with has local variables, and the words are deceptively familiar...<br />
<br />
<b>If you've just Google'd for a quick answer, you almost certainly want to be using <code>my</code>.</b><br />
<br />
However, <code>local</code>'s got to be there for a reason, right? Read on...<br />
<br />
Here's a sample program that declares a variable, <code>$global</code>, that's visible to all of the subs beneath it. There's a function, <code>print_global</code> that displays its value, and two functions <code>my_variable</code> and <code>local_variable</code> that call it.
<br />
<br />
<pre>our $global = 'global';
sub print_global { print "\$global='$global'\n" }
sub my_variable {
my $global = 'lexical';
print_global;
}
sub local_variable {
local $global = 'local';
print_global;
}
my_variable();
local_variable();</pre>
<pre> </pre>
The last two lines actually call the declared subs.<br />
<br />
<code>my_variable</code> behaves exactly as you'd expect if you're coming from Java, C or a similar language. It's got a variable with the name <code>$global</code> in it, but when <code>print_global</code> is called, it's the the top-level <code>$global</code> (the string 'global') that gets displayed, as that's the one that's visible to that function. In this case, the variable called <code>$global</code> in <code>my_variable</code> isn't used anywhere and is wasted.<br />
<br />
<code>my</code> variables are <i>lexically</i> scoped.<br />
<br />
<code>local_variable</code> paints a different picture. <code>local</code> eclipses or <i>shadows</i> the globally visible <code>$global</code>, so that any function that subsequently asks for its value sees the shadowing value, not the previous value. This can happen repeatedly, so that there are a stack of shadowed values, with a single visible value. So, the call to <code>print_global</code> from <code>local_variable</code> displays the string 'local'.<br />
<br />
<code>local</code> variables are <i>dynamically</i> scoped.<br />
<br />
Now, it's up to you to determine which you need. But if you're reading this, I'll bet that it's <code>my</code> :-)Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-15137052897657623342012-03-04T05:47:00.002-08:002012-03-04T09:13:50.946-08:00Ruby: Exceptions and ContinuationsYears ago, I stumbled across <a href="http://groups.csail.mit.edu/haystack/documents/papers/2003/uist2003-uicont.pdf">a paper describing user interface continuations</a>. At the time, the concept of continuations seemed like nothing short of wizardry: the program would be at one place, processing instructions, and then would suddenly be somewhere else to collect a piece of data, and the back at the original place, with that collected data available to the computation that was happening originally.<br />
<br />
<br />
A nice theoretical exercise, but that could never be useful, right?<br />
Well, since then, I've learned Common Lisp, and then its sibling, Scheme. Continuations aren't a part of Common Lisp, but they're readily available in Scheme and, looking back, CL's <a href="http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html">awesome condition system</a> starts to look like a regular exception framework with continuations thrown in for some fun.<br />
<br />
<br />
So far, this is all sounding somewhat academic: papers and arcane languages don't have anything to do with what programmers do on a day to day basis, right?<br />
<br />
<br />
<a href="http://www.ruby-lang.org/">Ruby</a> is a modern scripting language, and supports continuations out of the box: they're built right into the <a href="http://ruby-doc.org/core-1.9.3/Kernel.html">Kernel</a> module as the <a href="http://ruby-doc.org/core-1.9.3/Kernel.html#method-i-callcc">callcc</a> method (the method name has been lifted from Scheme, where it's called call/cc, or call-with-current-continuation, if you like typing).<br />
<br />
<br />
This method takes a one-arg block, where the argument is supplied by the system and represents the current continuation, which is a representation of where the program is at the moment that it is created. So what can you do with that? Well, Continuations can be <code>call</code>'ed, and when they are the value of the <code>callcc</code> call becomes the value that the continuation is <code>call</code>'ed with, <i>regardless of where in the program the call was made</i>. The continuation is a regular object that can be stored in data structures, passed around, etc., but when it's invoked, program flow resumes from the site of the <code>callcc</code>.<br />
<br />
<br />
This needs an example.<br />
<br />
<br />
I mentioned Common Lisp's condition system earlier. It's analagous to the exception mechanism in languages like Java and Python, with one notable difference: when a condition is signalled, the stack is not unwound to an enclosing exception handler. Instead, the stack is searched for a handler, which then gets to look at the condition and, if it determines that there is remedial action that can be taken, can provide information to the exception site that can tell the code there how to proceed. These are called restarts.<br />
<br />
<br />
Where would this be useful?<br />
A simple example from Peter Seibel's <a href="http://www.gigamonkeys.com/book/">Practical Common Lisp</a> is a log file parser. Imagine you're writing this, and you've sensibly layered the different functions: from the abstract 'parse a log file with this filename', through 'process all log entries in the file', into 'extract a single log entry', and then 'analyse a single log entry'.<br />
<br />
<br />
But what if something goes wrong at the analysis level? What do you do with a malformed entry? If you're working with functions, you just have to pass something into the function that tells it how to handle that. If it's an object, set some property on the object for this situation. But what if it is, as in this case, several layers down from the application's interface? Well, you can pass some property dictionary or other miscellaneous contextual information into either the intervening functions or objects.<br />
<br />
<br />
This kind of action indicates a break in reasoning: you're setting or passing properties on something that really <i>shouldn't need to care</i> about their existence. This kind of clutter makes maintenance programming difficult, as objects and functions are littered with things that they don't use themselves, but instead are made aware of for the sole purpose of handing over to something else. This has adverse effects upon reusability, as it's now assumed that these objects are part of a particular call chain.<br />
<br />
<br />
Looking at it, the only layers that need to know about the problem are the bottom one, where the problem occurs, and the top one, where the business logic lives.<br />
<br />
<br />
With continuations, we can make this happen. Here's an example.<br />
<br />
<br />
<pre>
class Condition < Exception
attr_accessor :continuation, :payload
def initialize(continuation, payload)
self.continuation = continuation
self.payload = payload
end
def continue(value)
@continuation.call(value)
end
end
def topLevel
begin
intermediateLayer1
rescue Condition => c
c.continue(0 - c.payload)
end
end
def intermediateLayer1
intermediateLayer2
end
def intermediateLayer2
intermediateLayer3
end
def intermediateLayer3
fragileLayer
end
def fragileLayer
(1..5).each { |i|
i = callcc { |cc|
begin
processEntry(i)
rescue Exception
raise Condition.new(cc,i)
end
}
puts i
}
end
def processEntry(entry)
(entry % 2 == 1) ? (raise "Can't deal with odd numbers!") : entry
end
topLevel()</pre>
<br />
<br />
The purpose of this program is quite simple: a top-level caller gets some work done (in this case, printing the numbers from 1 to 5) by asking a lower layer. The intermediate layers exist to demonstrate that there's no direct linkage between the raiser of the exception and its handler.<br />
<br />
<br />
In this example, the bottom layer refuses to work with odd numbers, and raises an exception when given one. This is caught, but the decision as to what to do next is not appropriate for that low level: the business logic needs to make that decision, but it's several layers up in the stack.<br />
<br />
<br />
At this point, a continuation is captured with callcc, and a new <code>ContinuableException</code> is raised. There's nothing special about these objects: they just encapsulate the continuation and the data that caused the error.<br />
<br />
<br />
Normally, an exception propagating up the stack causes the intermediate stack frames to become inaccessible and therefore eligible for garbage collection. However, the continuation captured in the exception that's just been thrown refers the stack frame in which it was created, so the stack remains live, even if control flow is being unwound through it.<br />
<br />
<br />
Now, the wizardry: the top level handler has access to the continuation and the problematic value, so it can decide what to do next. It can re-raise the exception, or <i>it can provide a new value to the original source of the exception to be used in its place</i>. Continuations can be <code>call</code>'ed, and they take a value to treat as the return value of the <code>callcc</code> call. Lower-level processing can continue as though it hadn't been interrupted; the intermediate layers are not unwound or invoked again.<br />
<br />
<br />
The output of the above is just:<br />
<br />
<pre>
-1
2
-3
4
-5</pre>
<br />
<br />
Now, there's no need to follow this precise pattern. The value that's returned could instead be a <code>Symbol</code> that indicates which of a range of choices should be executed. It could be a <code>Proc</code>, which the receiver is expected to <code>call</code>.<br />
Pretty neat, huh?Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-64439831547964453672012-02-25T01:22:00.004-08:002012-02-25T01:32:53.206-08:00Visual Studio 11's New LookMicrosoft recently unveiled a proposal for <a href="http://blogs.msdn.com/b/visualstudio/archive/2012/02/23/introducing-the-new-developer-experience.aspx">a new look on Visual Studio 11</a>. Now, I'm hardly a graphic designer, but one thing repeatedly strikes me as a bit bonkers in software written in the past ten years, and it's not restricted to Visual Studio: the 'save' and 'save all' icons.<br /><br /><a href="http://1.bp.blogspot.com/-W1_xZDMliv0/T0ipRXe9NhI/AAAAAAAAAOk/aspyPMJbSMg/s1600/vs-11-save-icons.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 46px; height: 27px;" src="http://1.bp.blogspot.com/-W1_xZDMliv0/T0ipRXe9NhI/AAAAAAAAAOk/aspyPMJbSMg/s200/vs-11-save-icons.png" alt="" id="BLOGGER_PHOTO_ID_5713002243146200594" border="0" /></a><br />Do you see that? They're<span style="font-style: italic;"> floppy disks.</span> I don't know if their continued representation is maybe indicative of an aging population of computer programmers, but floppy disks haven't been relevant since the turn of the millenium.<br /><br />I wonder if new up-and-coming programmers even know what they're clicking?Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-57147934181736040782012-02-18T09:23:00.003-08:002012-04-19T12:00:14.897-07:00Mac DVDRipper ProI have a Mac mini under my TV, with an NFS mount to 2TB of RAID-1 space on the other end of a gigabit ethernet home network. So it makes perfect sense to get rid of physical DVDs, putting them in a box in the loft after ripping them into digital form. So I've been looking for software that does this well, and stumbled across <a href="http://www.macdvdripperpro.com/">Ma</a><a href="http://www.macdvdripperpro.com/">c DVD Ripper Pro</a> a few days ago. It even managed to rip/transcode some troublesome DVDs that seem to resist other means of doing the same.<br />
<br />
MDRP offers an on-the-fly transcode feature which looks to be built on <a href="http://handbrake.fr/downloads2.php">HandBrakeCLI</a>.<br />
<br />
<a href="http://2.bp.blogspot.com/-GDK5D-bQwm4/Tz_geZfzyhI/AAAAAAAAAOU/L7W5icl4Ga0/s1600/mdrp-activity-monitor.tiff"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5710529665374079506" src="http://2.bp.blogspot.com/-GDK5D-bQwm4/Tz_geZfzyhI/AAAAAAAAAOU/L7W5icl4Ga0/s400/mdrp-activity-monitor.tiff" style="cursor: hand; cursor: pointer; display: block; height: 101px; margin: 0px auto 10px; text-align: center; width: 400px;" /></a><br />
All things considered, it's a pretty good converter: simple, slick and reliable. That said, I'm not sure how its proprietary license works with the GPL'd HandBrake underneath it.<br />
<br />
<strong>Update 19-Apr-2012</strong>: I ended up not really bothering with transcoding my DVDs: the storage on the NAS is such that I could avoid the re-coding overhead and just rip the VOBs directly with <a href="http://www.mplayerhq.hu/" title="MPlayer project page">MPlayer</a>:<br />
<br />
<code>mplayer dvd://1//dev/sr0 -dumpstream -dumpfile "Some DVD Title.ps"</code>
<br />
<br/>
This way, I get all the audio and subtitle streams, and with the help of <code>lsdvd</code> can pick out just the movie track (which MDRP can do as well).
<br/>
One potential gotcha is to remember, particularly with subtitled/multi-audio movies, is to grab the <code>.INF</code> files from the DVD, too. They contain the names of the tracks and the palette used in rendering the subs; the subs <em>may</em> render strangely without this information.
<br />Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-86089657314737301682012-02-12T07:28:00.001-08:002012-02-12T07:45:37.056-08:00Shell Scripting: Counting Occurences of a CharacterI recently found myself needing to know the occurrences of a letter in a line from a shell script. I was working with a delimited file, and needed to know how many columns were in a given line (it would be consistent within the same file, but could differ between files, depending upon the version of the code that produced it).<br /><br />Surprisingly, it took a bit more digging than I thought would be needed for such a simple task. Counting lines is easy, but characters within a line? It's not a difficult thing to do in Perl or awk, but launching their respective interpreters seemed a bit heavyweight.<br /><br /><code>tr</code> to the rescue. This under-used command line utility translates from one character set to another (a set can just be a single character). It can also delete characters from its input and, using the <code>-c</code> (complement) switch, can work on a set that's the inverse of the one specified. Tying those loose threads together, you end up with this to pick out occurrences of the letter 'e':<br /><br /><pre><br />danny@khisanth ~ [2] % echo one two three four five | tr -cd 'e'<br />eeee% </pre><br /><br />That % is my shell indicating that the line didn't terminate with a newline, so it was just the 'e's. Once you have those, <code>wc -c</code> can do the rest:<br /><br /><pre><br />danny@khisanth ~ [3] % echo one two three four five | tr -cd e | wc -c<br /> 4<br /></pre><br /><br />Annoyingly, <code>wc</code> on some Unixes indents its output, so if you just want the number itself, you might need to play with your shell's string manipulation functions to get something neater. e.g., in zsh:<br /><br /><pre><br />danny@khisanth ~ [4] % echo ${$(echo one two three four five | tr -cd e | wc -c)// /}<br />4<br /></pre>Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com1tag:blogger.com,1999:blog-7718565330748264667.post-59799317920195225682011-06-29T13:28:00.000-07:002011-06-30T01:40:01.564-07:00Gran Turismo 5 (eventually, I'm assuming)I'm occasionally a bit behind the curve when it comes to gaming. Given the appalling state of some titles on release day, I've found that it's quite often sensible to wait a while until the first few patches have come out to address the glaring problems that the initial 'gold' build shipped with regardless.<br /><br />So it's not until today that I got a copy of Gran Turismo 5 for the PS3 (pre-owned). I shove the disk in, and immediately have to download the better part of three quarters of a gigabyte of patches. As soon as this non-backgroundable download starts, I fire up the PS2, switch to component input, restore a save of Shadow of the Colossus, and then spend the next half hour beating the 9th colossus. I save that game, and switch back to the PS3 on HDMI in. The patches still haven't finished downloading, so I switch to DVI in and boot the Linux box, do some simple updates and routine administration, then check in on the PS3 again. Hey, all the patches are down! Maybe I'll get the play the game.<br /><br />Or maybe not: right at the start, the game carries the advice that installing 8GB to hard disk can speed up loading times. Now, if the game developers <em>felt the need to admit that</em>, you know that there are going to be problems, so I click 'yes', and see an estimated time of a paltry 14 seconds. Good! Oh, wait: that's the <em>preparation</em> time before it can <em>start</em> installing: the actual estimate is more like 30 minutes.<br /><br />So, I take the time to write this blog post, and it's still installing.<br /><br />What the hell happened to console gaming?Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-90136319254899837922011-06-25T15:07:00.001-07:002011-06-25T15:32:20.902-07:00Console Gaming, RebootedI've become a bit disillusioned with console gaming over the past few years. Many hours of my late teens were spent on the original PlayStation on classics like Final Fantasy VII & VIII and the various incarnations of Resident Evil. The upgrade to the PlayStation 2 in my early twenties was a foregone conclusion, offering much the same experience, but with better graphics and DVD playback as an added bonus. But the PS3 has never quite captured me in the same way. Part of that is undoubtedly me simply getting older. I'm married, have a daughter, and run my own consultancy company: it's only natural that some of the less important things like computer games slip a bit.<br /><br />Still, throughout each generation of console, I've always had at least a background flirtation with PC games. Some games (first person shooters springing immediately to mind) are just out-and-out <em>better</em> on a PC. Something a simple as mouse vs. control pad become critically important when you want to be able to turn quickly to find out what's shooting you. Other games (RPGs like Dragon age) are again just better on a PC largely because navigating the intricate menu systems of such games with a d-pad is infuriatingly slow. Thus, while games like Infamous and God of War 3 on the PS3 are undoubtedly best on their home platforms, the shiny black console spent most of its time languishing unused under the TV, while its forgotten dad, the PS2, was in a damp-proof box with its games in the attic.<br /><br />Anyway, I bought a new <a href="http://www.amazon.co.uk/gp/product/B001NEI7E8/ref=oss_product">monitor/TV</a> earlier this week: finally time to retire the 4:3, 1280x1024 and catch up with the 1920x1080 high-def kids. One of the major selling points for this particular monitor was the sheer number of connectivity offerings on its back. My PC displays via DVI; I have a small, VIA-based server that has a VGA port for the occasional time (i.e. backups) when I need local terminal access; and there's an HDMI port for the aforementioned PS3. But there's also component input, which made me think of the old PS2. Indeed, why not hook both it and the PS3 up to the same display, just for kicks?<br /><br />Well, since I've done that, I've played the PS2 more than its younger, more powerful offspring, and it's reminded me of why console gaming used to be fun: it was just so <em>simple</em>. Shove in the disk, and go.<br /><br />With the PS3, turning it on assaults you with a menu of menus, each of which contains a dizzying number of options. If you're an infrequent player like me, it seems like you're being prompted for a firmware update just about every time you turn the damn thing on, and if you play a game that you've not touched in a while, there's every possibility that you'll be looking at anything been 100MB and 1GB of patches to fix the problems caused by rushing the original version out the door.<br /><br />One of the great things about the PS1 and PS2 is that they didn't have internet connectivity, so game studios had to be very, very sure that the software they committed to CD or DVD was as bug free as possible. With the PS3 (and Xbox360—don't think I'm picking on the PS3 in particular), just about any old crap can be thrown together, to be patched later when the early adopters—devoted fans that a studio should treat <em>especially</em> well—are used as unpaid acceptance testers.<br /><br />So I'm holding off on purchasing Infamous 2 for the PS3, and instead having fun with Shadow of the Colossus on the PS2. I think I should be able to get through that and Silent Hill 2 before I see if I can stomach the hassles of modern console gaming, or whether I just ditch the platform and stick to the PC.Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-82162555460097743302011-03-10T09:50:00.000-08:002011-03-10T10:02:24.490-08:00Continuously Learning LispI like to think that I 'know' Perl. I also 'know' C, Java, Smalltalk, Ruby and a handful of other languages. But Lisp is the only one that continually makes me feel like a newbie. Just when you think you've got it pegged... BLAM— you read something that shows you a completely new dimension.<br /><br />A good example of this for me is Nikodemus Siivola's post on <a href="http://random-state.net/log/3507968044.html">"Optimizing Lookup Functions Using LOAD-TIME-VALUE"</a>, basically demonstrating a way of altering the language such that hash table lookups with keys that are known to be constant at compile time have <em>no</em> lookup overhead at runtime.<br /><br />I feel like I have a whole lot to learn, and it's good :-)Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-41496359047000072492010-11-22T10:36:00.001-08:002010-11-22T10:36:51.831-08:00Apple device fragmentationApple's Steve Jobs went on an <a href="http://www.businessinsider.com/steve-jobs-epic-5-minute-anti-google-rant-2010-10">anti-Android rant</a> earlier this year, focussing in particular on market fragmentation. Apparently, there are so many configurations of Android device that it's writing software for the platform is next to impossible. This came as a surprise to <a href="http://androidheadlines.com/2010/10/tweetdecks-ceo-contradicts-steve-jobs-on-android-fragmentation.html">people who actually develop for it</a>.<br /><br />Apple, on the other hand, dodge the issue of fragmentation completely. iOS is a completely unified platform, with only one catch: you must be up-to-date with the latest shiny toys. The new <a href="http://www.apple.com/pr/library/2010/11/22ios.html">iOS 4.2 is now available</a>, with the following small caveat:<br /><br /><div class="quotation"><br />Availability<br /><br />The iOS 4.2 update is available today to download to iPad, iPhone and iPod touch by syncing the device with iTunes 10.1. iOS 4.2 is compatible with iPad, iPhone 3G, iPhone 3GS, iPhone 4, second and third generation iPod touch (late 2009 models with 32GB or 64GB) and new iPod touch. Some features may not be available on all products. For example, Multitasking requires iPhone 3GS, iPhone 4, third generation iPod touch (late 2009 models with 32GB or 64GB) or later. <br /></div><br /><br />So, as with recent OS updates, it won't work with my first generation iPod Touch (or second gens, for that matter). Owners of those devices are left with older versions of iOS, with no upgrade path that doesn't require a hardware purchase.<br /><br />Meaning that, if you're an application developer looking to target the broadest user base, you're hit with platform fragmentation...Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-55363571898712718892010-11-21T04:31:00.001-08:002010-11-21T04:31:04.279-08:00Apple's 'Restart your computer' U-TurnOnce upon a time, Mac users could chuckle heartily at Windows users. After every Windows Update, you'd get that prompt to restart your computer, and it was annoying. If you're the kind of person who thinks that computers should serve rather than be served, you've probably got about a half dozen or more applications open, each containing reference material or partially completed work.<br /><br />Damn, those restarts were annoying.<br /><br />However, it's almost every other week that there's some update to Quicktime, Safari or iTunes, each adding more features that I don't care about (<a href="http://www.apple.com/itunes/ping/">Ping</a>? Yet another social network, but one that's only accessible via the locked-down iTunes ecosystem? Seriously..?) I don't need my iTunes to support the latest devices from Apple: I haven't bought anything from them since my first-generation iPod touch (which still works superbly, by the way: I have no intentions of replacing it).<br /><br />Going back to that 'once upon a time', apps used to run <em>on top</em> of Mac OS. Now, Apple does what got Microsoft into so much hot water at the turn of the millennium: integrating home-grown apps into the operating system (otherwise known as 'gaining unfair advantage over competitors'). So, after updating to Mac OS 10.6.5 and restarting (ok, operating system updates <em>require</em> restarts), I find that iTunes and Safari are both needing updated, also nagging for a restart.<br /><br />Well done, Apple. You are the new Microsoft. Enjoy the bubble.Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-57741139607200779482010-10-30T01:36:00.000-07:002010-10-30T02:30:28.074-07:00The Ultimate Programmers' KeyboardA professional in any craft needs quality tools, and for a computer programmer, the primary interface between the human and the computer is the keyboard. End users of mass market software may be convinced that touch screen devices are the way forward, but for a programmer, nothing looks to be a serious threat to keyboards in the near to mid future.<br /><br />A quick <a href="http://www.google.co.uk/#sclient=psy&hl=en&q=best+programmer+keyboard&aq=f&aqi=&aql=&oq=&gs_rfai=&pbx=1&fp=3dd9e71350957573">google for 'best programmer keyboard'</a> turns up the prime candidates: the <a href="http://www.microsoft.com/hardware/mouseandkeyboard/productdetails.aspx?pid=043">Microsoft Ergonomic 4000</a>; <a href="http://www.daskeyboard.com/">das keyboard</a>; the <a href="http://en.wikipedia.org/wiki/Model_M_keyboard">IBM Model M</a>; and the uniquely shaped <a href="http://www.kinesis-ergo.com/">keyboards from Kinesis</a>.<br /><br />The <a href="http://www.logitech.com/en-us/keyboards/keyboard/devices/3498">Logitech G15</a> seems to be popular among high-end users, but it's primarily a gaming keyboard, so I'm not including it here.<br /><br />My requirements are pretty simple:<br /><br /><ol><br /> <li>it must be durable and sturdy</li><br /> <li>it must be amenable to team-based working</li><br /> <li>and—most importantly—it must have a standard UK layout, with absolutely no dicking around with the positions of keys that are important to programmers, including the hash key (#, to the left of the large Enter key, shared with ~), the back-quote (‘, top-left key on the main key cluster) and the pipe (|, shared with the backslash, between left-shift and the Z key)</li><br /></ol><br /><br />Anything from Apple is right out. Even on their 'UK' keyboards, the double-quote (") is where the @ should be, and vice-versa. <br /><br />I immediately ruled out anything with the <a href="http://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard">Dvorak layout</a>. Yes, I'm familiar with the statistics about how it's a superior layout for computers, but it's simply not widespread enough for point 2. I have a colleague on my current contract who has a <a href="http://www.typematrix.com/">typematrix Dvorak keyboard</a>, and he's very happy with it, but when it comes to a paired session or showing how to do something, it's a total pain. The fastest way to get anything done is leave all the typing to him.<br /><br />Partly for point 2, I also ruled out anything with an extreme ergonomic layout (basically anything from Kinesis). Also, while less-deformed ergonomic keyboards are good for a single user typing for a long time, paired programming is often about quickly shoving the keyboard over to a partner or grabbing it briefly to type a few lines, and ergonomic keyboards are obviously designed for someone sitting directly in front of them. It's like you have to re-align yourself at the beginning of every switchover, which I find interrupts the flow.<br /><br />So, from my original list, I'm left with the Model M and Das Keyboard, both distinctly traditional in their non-ergonomics. But then, from a front-page review endorsement on their <em>own website</em>, <cite>"Das Keyboard compares to the legendary IBM Model M."</cite> So, which to go for? The imitation or the original?<br /><br />Unsurprisingly, I'm typing this blog entry on my Model M. The sticker on the bottom dates it from 1991, made in Greenock, Scotland—about a half-hour's drive from where I live. It's got all its key caps, has that satisfying two-stage click for each key press, and is solid enough to be used as a not-insignificant weapon if anyone breaks into my house.<br /><br />I simply can't find a better keyboard anywhere, and I'm beginning to think that there isn't one.Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com3tag:blogger.com,1999:blog-7718565330748264667.post-6002419646668547862010-09-26T01:15:00.001-07:002010-09-26T01:15:48.749-07:00More Homophobic Lunacy from the Catholic Church<div class="quotation"><br />"I admire the gays and lesbians. They're small in number. But they're well-organised."<br /><br />"They've persuaded our legislators that the supreme moral values of the day are freedom and equality. Well they're not."<br /><br />"The supreme moral values are truth and goodness, and if you forget that, you end up with the mess we're in today."<br /><div class="quoter">Bishop of Motherwell, Joseph Devine, in an <a href="http://news.bbc.co.uk/1/hi/programmes/from_our_own_correspondent/9031680.stm">interview with the BBC</a></div><br /></div><br /><br />Once again, we see the catholic persecution complex in action: they're being systematically attacked by a 'well organised' group. It's as though the church thinks that there's some kind of gay hierarchy, with lay-gays, event-organising gays and maybe even leader-gays, all plotting against the church and its bronze age values.<br /><br />Bollocks.<br /><br />There is simply a group of people who have human rights, voting power and a voice, qualities the church has traditionally abhorred.<br /><br />And isn't it convenient that the moral values of the day are unquantifiable and subject to varying definition? There's little ambiguity about freedom and equality; it's obvious when one is being stomped on. But 'truth' and 'goodness'? The church defines what those are for its members, freeing them from the need to think about them, to make their own decisions. Because that's the last thing the church needs its people doing—<em>thinking</em>.<br /><br />And why, when asked "can a loving relationship between two people of the same sex not be true and good?"<br /><br />"Because it's not creative".<br /><br />I'm assuming that he means pro-creative here, not just generally creative: the love shared between two people of the same sex is on even par with any other, and is creative in way that it enriches their lives and the lives of those around them. But he's right, it's not <em>pro</em>-creative: it doesn't bring new life into the world. But then, neither does a heterosexual marriage where one side or the other is sterile—does he propose nullifying such marriages, tearing such couples apart? Surely if <em>one</em> of them is capable of reproduction, it's a sin against god and humanity if that person doesn't find a fertile mate?<br /><br />Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-81701968650979449952010-09-19T09:54:00.001-07:002010-09-19T10:51:17.387-07:00Crazy ProselytisingThere were a few street preachers in Argyle Street in Glasgow today. You know, the ones who brandish a bible and shout loudly about how <em>you</em> can be <em>saved</em>. The lead of the small group—a surprisingly young looking gentleman—was busy proclaiming how morally corrupt society is today, filled as it is by people who live by the creed of "if it feels good and no one gets hurt, then it's ok". While I was puzzling over exactly what the problem with that viewpoint is, he continued that we should return to the "moral certainty of the old days".<br /><br />Would those be the days when we stoned people for disobedience, I wonder? Burned them at the stake for witchcraft? Or seared them with irons for blasphemy?<br /><br />Throughout all this, the placard by his side read:<br /><br /><div class="quotation">I am the way and the truth and the life. No one comes to the Father except through me — John 14:6</div><br /><br />This passage, more than just about any other in the bible, highlights the "we're right, everyone else is wrong" mentality of Christianity that belies talk of unity with other religions.<br /><br />I could only chuckle as I walked past.Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-27901490223609526652010-09-17T11:20:00.000-07:002010-09-19T02:56:08.171-07:00The Pope Slanders Free Thinkers<style type="text/css">div.quotation { margin-right: 3em; margin-left: 3em; padding: 1em; background-color: #eee; }</style><p>The Pope was in my nearest city of Glasgow yesterday, offering his sermon in Bellahouston Park, just south of the River Clyde. His message was at once one of optimistic hope for his faithful flock and an out-and-out slanderous attack against the largely secular, non-theistic people of the UK.</p><div class="quotation"><cite>Even in our own lifetimes we can recall how Britain and her leaders stood against a Nazi tyranny that wished to eradicate God from society and denied our common humanity to many, especially the Jews, who were thought unfit to live.As we reflect on the sobering lessons of atheist extremism of the 20th century, let us never forget how the exclusion of God, religion and virtue from public life leads ultimately to a truncated vision of man and of society and thus a reductive vision of a person and his destiny.</cite><div align="right"><em>Pope Benedict XVI, Bellahouston Park, Glasgow, 16-Sep-2010</em></div></div><p>Umm... excuse me? Hitler was a Catholic. The Catholic church, while refusing to back the Nazi party of Germany, similarly refused to condemn it. Hitler's attack was against the entire Jewish race, not entirely unmotivated by the church's own hatred of the race thanks to the <a href="http://en.wikipedia.org/wiki/Jewish_deicide">charge of decide</a> that was only lifted in the 1960s (which has always slightly confused me: if Jesus's defining sacrifice is what frees us all from sin, surely he <em>had to die</em> in order to rise, ascend into heaven, etc.).</p><p>"Oh, no", whine the apologists. "Hitler wasn't Catholic. He just used religion to control the people". Is that so? Well, in order to control the people with religion, what religion would those people have to follow? So, given that Hitler didn't personally murder millions of Jews,what's their excuse?</p><p>And how about this little gem from the megalomaniacal 'atheist' dictator?</p><div class="quotation"><cite>The Government, being resolved to undertake the political and moral purification of our public life, are creating and securing the conditions necessary for a really profound revival of religious life</cite></p><div align="right"><em>Adolf Hitler, in a speech to the Reichstag onMarch 23, 1933</em></div></p></div><p>Do those sound like the words of an atheist to you?</p><p>Stepping away from the distortions of the past that the Pope seems to enjoy, we find that his view of the present is no less warped:</p><div class="quotation"><cite>There are some who now seek to exclude religious belief from public discourse, to privatise it or even to paint it as a threat to equality and liberty. Yet religion is in fact a guarantee of authentic liberty and respect, leading us to look upon every person as a brother or sister.<div align="right"><em>Pope Benedict XVI, Bellahouston Park, Glasgow, 16-Sep-2010</em></div></cite></div><p>Again... excuse me? Doesn't the Catholic church tell us that women are not fit to be priests, and therefore cannot be part of the church's own heirarchy except at the lowest levels? Doesn't it teach us that gays are abominations in the sight of god, and forever damned unless they 'repent' for making that 'choice'? All this from a church that refuses even to discuss the possibility of ordaining women, forbidding it from being mentioned.</p><p>The church is an open <em>threat</em> to liberty and respect, not its guardian.</p>Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-54129497403402580282010-08-28T00:31:00.001-07:002010-08-28T00:31:53.976-07:00Online Stalking: it's not the ISPs Fault.The BBC is <a href="http://www.bbc.co.uk/news/uk-11118152">running an article</a> about how ISPs are 'thwarting' a crackdown on online stalking. Apparently, they should not only deliver Internet connectivity (their job), they should also police it (not their job). It's like saying that the makers of paper should be responsible for what's written on it, or that the makers of envelopes should be responsible for what's delivered in them.<br /><br />Of course, what's barely mentioned is that you should be very careful about personal details that you post online. Do NOT post details of your current location, places where you can often be found, your home address, your phone number, etc. Doing so is just asking for trouble, and blaming the ISP—even when social networking sites (still <em>not</em> the ISP) encourage you to yield such information—is equivalent to blaming manufacturers of junk food for <em>forcing</em> you to eat rubbish by making appealing adverts.<br /><br />The <em>last</em> thing we want is ISPs policing Internet access according to a private set of rules formed by a mob committee. I'm even wary of the Law of the Land applying to the <em>delivery</em> of content (the hosting is another matter). It's a slippery slope when your government gets used to being able to filter content that it finds objectionable.Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-29393945631628011222010-08-27T11:57:00.001-07:002010-08-27T11:58:25.603-07:00h264 is not FreeWith news of the sudden <a href="http://arstechnica.com/media/news/2010/08/mpeg-la-counters-google-webm-with-permanent-royalty-moratorium.ars">royalty free amendment to the h264 license by the MPEG LA</a> sweeping the web, it's easy to forget that this actually changes very little, indeed. You now won't ever be charged for viewing free video on the Internet.<br /><br /><strong>You will <em style="font-style: normal; text-transform: uppercase">still</em> be charged for distributing an h264 encoder or decoder</strong>.<br /><br />This means that if you're someone like the <a href="http://www.mozilla.org">Mozilla</a> group, you can't include h264 support for the HTML5 <video> tag without paying hefty royalties for the privilege. You might wonder what the problem is: surely it's right that one company licenses the right to distribute the technology of another? No. Not when it comes to the Web and the standards that underpin it (such as HTML5). Paying a royalty to take part in the Web defeats the entire point of an open internet, where ideas can be freely exchanged using the promise that the base standards are available to everyone on a royalty-free basis.<br /><br />There's some sanity on this 'sweeping change' from the MPEG LA at <a href="http://createdigitalmotion.com/2010/08/apple-centric-observers-get-the-facts-wrong-h-264-still-isnt-free-for-firefox/">Create Digital Motion</a>.<br /><br />H264 is not the only codec out there. You can distribute the encoders, decoders and content with WebM/VP8 and Ogg/Theora without restriction.<br /><br />Use 'em.Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-56367462977240769292010-08-25T07:06:00.001-07:002010-08-25T07:06:40.504-07:00Being an Ex-Catholic Atheist at a Catholic FuneralMy gran died last Thursday. At 88 years old and of frail health, her increasingly common mental lapses meant that it wasn't unexpected when it happened, but nothing quite prepares you for that phonecall.<br /><br />Her funeral was today, attended by the two generations behind her—probably the best turnout at a family gathering for many years. Religiously, my family is traditionally Catholic, at least in name. We traditionally only see the inside of a church at funerals, with weddings being secular affairs and not much interest in baptising our children. Still, if you were to ask my sisters, aunts, uncles or cousins what religious affiliation they belong to, it'd be Catholic.<br /><br />As far as I know, I'm the only openly declared atheist. Before going on, the reason I left the church is simply because I couldn't reconcile my beliefs about how to live a good life with what I was reading and being taught. I have no stories about abusive priests, psychological trauma induced by images of hell, or any of the stuff that commonly makes it into the Reasons to Hate the Catholic Church™.<br /><br />So the ceremony itself was a little weird. Having gone through Catholic education, I knew exactly what to say at what times, and when to stand, sit or kneel. It's slightly odd that I remembered the prayers: they must have been burned into my brain when I was a boy.<br /><br />But, aside from standing and sitting and that shaking of hangs thing they do prior to communion, I didn't <em>do</em> any of it. I didn't recite or respond to the prayers, sing hymns, bless myself with water, bow my head or press my hands together in front of me. While the priest was asking people to honour god, I was instead remembering my gran.<br /><br />When I was paying attention to what the priest was saying, the thing that generally struck me was the occasional reminder that we're born sinners, achieving grace <em>only</em> through Christ. There was even a dig at non-believers in the reading from the book of 'Wisdom', where we are collectively labelled as 'fools' for believing that death is the end of a persons life.<br /><br />As a foolish non-believer, what I found very odd was the tinkling of bells by the altar boy when the priest blessed and raised the bread and wine, a process which—according to believers—transubstantiates them into the actual body of blood of Jesus Christ. The communion itself seemed similarly strange, with people treating these little, mass-produced flecks of unleavened bread with such incredible solemnity. Knowing that most of the congregation in front of him probably hadn't communed in years, and bearing in mind the Catholic no-no about taking communion with a sin-stained soul, the priest offered blessings to those who remembered enough of the dogma to stay away because of that.<br /><br />With with mass almost at its end, all that remained was to sprinkle 'holy' water over the coffin and wreath it with smoke from burning incense. This done, the coffin was taken to the cemetery and interred alongside my granddad, laid to rest seventeen years earlier.<br /><br />After all this, what I'm most shocked with is myself. For quite an extended period of time, I <em>believed</em> this stuff. I took part in the rites and rituals, saw value in the prayers and songs and material paraphernalia. And it wasn't even that long ago: I was a practising Catholic up until about ten years ago, a lapsed one for about five years after that, finally moving on to agnosticism and finally atheism over the course of the following two or three years. Not coincidentally, all of this happened alongside actually <em>reading</em> the bible, learning about its origins, learning about other religions, and seeing the harm inflicted by the church thanks to its views on contraception, sex education, and homosexuals.<br /><br />How times change.Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-40850844896678925242010-08-21T07:02:00.001-07:002010-08-25T06:06:41.628-07:00Net-Connected Consoles with Hard Drives Deliver Poor Quality GamesA while ago, I bought <a href="http://www.unchartedthegame.com/U2AT/">Uncharted 2</a> for the PS3. Unfortunately, with the arrival of my daughter into the world, it was one of those titles that barely got loaded at first.<br /><br />Today, I put the disk into the console, and then BAM!, several hundred megabytes of updates are required before I can play the game. It would appear that there have been one or two bugs in the shipped version.<br /><br />Which got me wondering: why, with the console's predecessors, was this never an issue? The answer is kinda obvious: you've got a network, a hard drive and a very competitive market. With previous generations of console, you had to make damn sure that what you burned onto that CD for shipping was a quality product. Your update channel amounted to a return of the physical medium for a fixed copy. Not very attractive. Now, however, you can ship with any half-arsed, bug-ridden product and patch it later.<br /><br />One thing that console games used to have over their PC siblings was that they <em>just worked</em>. Stick the disk in and go. No configuring audio and video drivers, no checking the specs of your machine against the overly optimistic listings on the side of the box (only to find out that the screen shots on the packaging must have been taken from some next-generation video hardware), and <em>no patching shoddy software with updates to fix problems that should never have made it through testing</em>.<br /><br />EDIT: apparently, a couple of hundred megabytes of patches aren't enough. It took only a half hour of playing (in the raid on the museum in Instanbul) to be bitten by this glitch:<br /><br /><div style="text-align:center;"><img src="http://lh4.ggpht.com/_woBmp3G-OW8/TG_n47FlwjI/AAAAAAAAAFU/ZVfyAEYSW9M/uc2-bug.jpg?imgmax=800" alt="uc2-bug.jpg" border="0" width="640" height="403" /></div>Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-71838587696855422662010-08-01T02:45:00.001-07:002012-08-18T12:38:29.515-07:00Encoding x264 Video for the iPod Touch with mencoder<p><strong>Update, 18-Aug-2012</strong>: I've changed to using an ffmpeg/mplayer combo to do this, as it's much more reliable and stable. See my <a href="http://dynamic-thinking.blogspot.co.uk/2012/08/ipodiphone-encoding-with-ffmpeg-and.html">new post</a> for a breakdown.</p>
I tend to view a lot of video content on my first-generation iPod Touch. It's great for travelling, with its these-days-paltry 16GB capacity able to store well over a dozen half hour episodes of whatever I'm following at the time.<br /><br />While there are some wonderful graphical encoders out there (<a href="http://handbrake.fr/">HandBrake</a> springs to mind), what I was looking for was something I could script. I know that HandBrake has a <a href="https://trac.handbrake.fr/wiki/CLIGuide">command line interface</a>, but I prefer <a href="http://www.mplayerhq.hu/design7/news.html">mencoder</a>'s support for embedded subtitle streams, which is something I use often.<br /><br />If you're on a fairly recent SVN of mplayer (say >= r31363), you'll find that mencoder now supports a <code>profile</code> in <code>x264encopts</code>. <strong>This is important!</strong> The default is <em>high</em>, which the <a href="http://www.apple.com/ipodtouch/specs.html">iPod explicitly doesn't support</a>. What you need is <em>baseline</em>, leading to something like this:<br /><br /><style><br />td { border-bottom: 1px solid black }<br /></style><br /><table><br /><tr><td colspan="3">mencoder INPUT-FILE -o OUTPUT_FILE</td></tr><br /><tr><td> </td><td>-vf scale=480:-10,harddup</td><td># resize the video to whichever height is suitable for the max 480px width</td></tr><br /><tr><td> </td><td>-sws 9</td><td># Choose a really good scaler (lanczos)</td></tr><br /><tr><td> </td><td>-of lavf</td><td># use lavf for output</td></tr><br /><tr><td> </td><td>-lavfopts format=mp4</td><td># specifically, mp4</td></tr><br /><tr><td> </td><td>-oac faac</td><td># AAC audio for output</td></tr><br /><tr><td> </td><td>-faacopts mpeg=4:object=2:raw:br=128</td><td># Audio coding parmeters</td></tr><br /><tr><td> </td><td>-mc 0 -noskip</td><td># Really work at keeping A/V sync</td></tr><br /><tr><td> </td><td>-ovc x264</td><td># x264 video</td><br /><tr><td> </td><td>-x264encopts nocabac: bframes=0: level_idc=30: global_header: threads=auto: subq=5: frameref=6: partitions=all: trellis=1: chroma_me: me=umh: bitrate=768: <strong>profile=baseline</strong></td><td>Video coding parameters. Note the <strong>baseline</strong></td></tr><br /><tr><td> </td><td>-aid 0 -sid 0</td><td># Audio and subtitle tracks</td></tr><br /><tr><td> </td><td>-subfont-text-scale 4</td><td># Better subtitle scaling for an iPod sized device</tr><br /></table><br /></pre><br /><br />(or, for a more cut n' paste friendly version:<br /><br /><code>mencoder INPUT-FILE -o OUTPUT-FILE -vf scale=480:-10,harddup -sws 9 -of lavf -lavfopts format=mp4 -oac faac -faacopts mpeg=4:object=2:raw:br=128 -mc 0 -noskip -ovc x264 -x264encopts nocabac:level_idc=30:bframes=0:global_header:threads=auto:subq=5:frameref=6:partitions=all:trellis=1:chroma_me:me=umh:bitrate=768:profile=baseline -aid 0 -sid 0 -subfont-text-scale 4</code>)<br /><br />This transcodes the source in a single pass. Lots of people strongly advocate two-pass encoding, but really, I find the quality of a single pass encode good enough for the iPod screen. There's no denying that two-pass is higher quality, but the extra time to encode disposable content just isn't worth it in my opinion.Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com1tag:blogger.com,1999:blog-7718565330748264667.post-514151056583844162010-06-05T13:43:00.000-07:002010-06-05T13:59:39.313-07:00Netgear's Broken FirmwaresI bought a Netgear DG834G from <a href="http://www.amazon.co.uk">Amazon</a> earlier this week. It arrived on Friday, and promptly replaced the crash-tastic BT Home Hub that preceded it. Having been using Netgear products for years, I quickly set up and secured my wireless LAN, made a couple of DHCP reservations for servers on my home network, forwarded ports for various services from the Internet to those servers, hooked up to my <a href="http://www.dyndns.org">DynDNS</a> account, and was content. Then I noticed that the forwarded ports weren't forwarding: my web and mail servers were inaccessible. Much tinkering later, and I decide that the unit is defective, and arrange to return it to Amazon (who, it must be said, have a superbly streamlined returns process).<br /><br />But I still didn't want to go back to the BT Home Hub—the frequent crashes were just too frustrating. So I dig out an old Netgear router that I found in The Pile in the bits n' pieces cupboard, and find that it still works. And hey, port forwarding even works!<br /><br />Feeling good about it, I let the old kit do its thing, stable and reliable. So why not treat it to a firmware upgrade? I grab the latest (v1.03.22) from <a href="http://kb.netgear.com/app/products/model/a_id/2328">the Netgear product page</a>, re-flash the unit, <em>and port forwarding stops working!</em> Crawling around some forums, I find that <a href="http://forum1.netgear.com/showthread.php?t=50568">I'm not alone</a>. It would appear that Netgear have broken something as fundamental as port forwarding in their recent firmwares!<br /><br />Incredulous, I download v1.02.19. Still doesn't work (and almost bricks my unit in the re-flashing process). By now more than a little annoyed, I resort to v1.02.13, which I <em>think</em> was the original version. And you know what? It works.<br /><br />Not all upgrades are upgrades, it would seem.Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-47615760540806947942010-05-05T05:45:00.000-07:002010-05-05T05:52:56.664-07:00h264 shenanigans<a href="http://www.engadget.com/">Engadget</a> has an <a href="http://www.engadget.com/2010/05/04/know-your-rights-h-264-patent-licensing-and-you">excellent article</a> that attempts to clarify the muddy waters of licensing and patents surrounding the h264 video codec. One of the snippets from the article, important enough that they list it in a side-box, is <cite>"using H.264 to distribute free internet video to end users doesn't cost a thing, and won't cost anything until at least 2015. After that, it's up in the air, and that's a bridge we'll have to cross when we come to it — there's a chance the MPEG-LA could start charging a royalty for free video in five years."</cite><br /><br />Two parts of that sentence should cause any sane person cause for concern:<br /><br /><dl><br /><dt>...won't cost anything until at least 2015.</dt><br /><dd>That's only five years away. Just enough time to generate an awful lot of content that would take a lot of effort to get away from.</dd><br /><dt>After that, it's up in the air...</dt><br /><dd>That's not exactly something to be happy about. There's no point making extensive use on h264 and then hoping that it'll turn out ok, especially when there are perfectly workable alternatives.</dd><br /></dl><br /><br />The article does do a good job of dispelling a lot of the scaremongering that's been going on, but what's left is still distinctly unpleasant.Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-36134765233251474882010-05-04T02:43:00.000-07:002010-05-04T02:49:27.325-07:00Labour Promote Political SabotageNow that it's blindingly obvious that the UK Labour Party is going to lose the General Election later this week, they've resorted to <a href="http://news.bbc.co.uk/1/hi/uk_politics/election_2010/8658694.stm">abusing the voting system</a> in order to prevent their long term rivals, the Conservatives, from winning a complete victory. In areas where the Liberal Democrats are a larger threat to the Tories than Labour themselves, the advice is to vote Lib Dem in order to prevent them gaining the seat.<br /><br />Does anyone else think that the system is broken?Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0tag:blogger.com,1999:blog-7718565330748264667.post-60498702762752094932010-05-02T06:01:00.001-07:002010-05-03T04:24:19.142-07:00Apple's vision of an 'open' webApple are certainly 'thinking different' when it comes to the definition of 'open'. In their spat with Adobe regarding Flash on Apple's mobile products, Steve Jobs responded <a href="http://www.apple.com/hotnews/thoughts-on-flash/">almost convincingly</a> about why Flash isn't on the Apple mobile product line. The primary reason? Openness. Flash is a closed platform, whereas JavaScript, CSS and HTML 5 are all open.<br /><br />The 'but' here comes from the HTML 5 part, which includes a <code><video></code> tag that essentially renders Flash video obsolete, with decode and render available natively in the browser, rather than through a plugin. The standards committee overseeing HTML 5 still hasn't agreed on what <em>format</em> that video should be delivered in. The de-facto standard of <a href="http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC">h264</a>, a high-quality, industry-driven standard that's nevertheless mired in patent and licensing issues that are <a href="http://www.fsf.org/licensing/h264-patent-license">really sticky</a>. Or <a href="http://xiph.org">Xiph's</a> <a href="http://www.theora.org/">Theora</a>, which has been designed to avoid using techniques covered by patents, and is available royalty-free (which most of us think of when we think 'free').<br /><br />When it comes to browser support, <a href="http://www.microsoft.com" title="Microsoft">the</a> <a href="http://www.apple.com" title="Apple">big</a> <a href="http://www.google.com" title="Google">three</a> unsurprisingly lend their weight to h264. Mozilla's <a href="http://www.firefox.com">Firefox</a>—distinct from the others in being the only organisation that's an actual <em>browser</em> company and also non-profit—throws its weight behind Theora, with that crazy idea that participating in the web shouldn't involve licensing fees just to <em>access</em> it.<br /><br />Of the corporations, Google has interestingly <a href="http://www.webmonkey.com/2010/04/report-google-will-release-vp8-video-codec-under-an-open-source-license/">promised to open source the VP8 codec</a> and, since they own <a href="http://www.youtube.com">YouTube</a>, could theoretically swing the balance by offering VP8 support in Chrome and VP8 YouTube videos, especially if Firefox supported the same.<br /><br />But, back to Apple.<br /><br />Steve Jobs reckons that <a href="http://blogs.fsfe.org/hugo/2010/04/open-letter-to-steve-jobs/comment-page-1/#sjobs">there's no such thing as a free video codec</a>. Furthermore, he issues a threat to Xiph over Theora (without including useful specifics, which relegates it to FUD).<br /><br />So Steve: get a grip. The i-whatever ecosystem is locked down tight, and you're free to do that to whatever extent your customers are willing to put up with, but don't hide behind a wall of righteousness when dissing other technologies. Your 'open' arguments are empty with a platform and environment that is <a href="http://daringfireball.net/2010/04/why_apple_changed_section_331">increasingly developer hostile</a>.<br /><br />As for me, I've owned a G4 PowerBook and am typing this on a two year old Macbook Pro. With each statement from Jobs regarding criticism of his closed platform, I find it increasingly unlikely that I'll buy a third. So hey, Apple marketing-types: your CEO's statements are costing you a £1500 sale, and most likely not just from me.<br /><br /><strong>Edit:</strong><br /><br />Apparently <a href="http://xml.coverpages.org/AppleComputerPatentStatement.html">Apple once believed in a royalty-free Web</a>, too. However, despite the original having lived <a href="http://www.apple.com/about/w3c/">here on apple.com</a> for years, it's recently been pulled.<br /><br />Thankfully, George Orwell's <a href="http://en.wikipedia.org/wiki/Memory_hole">Memory Holes</a> are a difficult thing to accomplish with an open Web.<br /><br />Hat-tip to <a href="http://news.ycombinator.com/item?id=1314446">ZeroGravitas</a> on <a href="http://news.ycombinator.com">Hacker News</a> for the info (and to Create on the comments page for the Memory Hole reference).Dannyhttp://www.blogger.com/profile/15763567497153080240noreply@blogger.com0