<?xml version="1.0" encoding="utf-8"?>
<!-- generator="wordpress/2.0.12-alpha" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Remosi's Rants</title>
	<link>http://coders.meta.net.nz/weblog</link>
	<description>babblings!</description>
	<pubDate>Thu, 20 Mar 2008 10:26:13 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.0.12-alpha</generator>
	<language>en</language>
			<item>
		<title>Things you probably never wanted to know about MP3 files</title>
		<link>http://coders.meta.net.nz/weblog/2008/03/20/things-you-probably-never-wanted-to-know-about-mp3-files/</link>
		<comments>http://coders.meta.net.nz/weblog/2008/03/20/things-you-probably-never-wanted-to-know-about-mp3-files/#comments</comments>
		<pubDate>Thu, 20 Mar 2008 10:26:13 +0000</pubDate>
		<dc:creator>Isomer</dc:creator>
		
		<category>General</category>

		<category>Programming</category>

		<guid isPermaLink="false">http://coders.meta.net.nz/weblog/2008/03/20/things-you-probably-never-wanted-to-know-about-mp3-files/</guid>
		<description><![CDATA[I&#8217;ve been playing around with the mp3&#8217;s I&#8217;ve got here, trying to automatically find the ones that are broken and need to be reripped from my original CD&#8217;s.  Some have been truncated over the years, some are just encoded at horrible bitrates that make your ears bleed, and some are missing tracks from the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing around with the mp3&#8217;s I&#8217;ve got here, trying to automatically find the ones that are broken and need to be reripped from my original CD&#8217;s.  Some have been truncated over the years, some are just encoded at horrible bitrates that make your ears bleed, and some are missing tracks from the album.  Some have ID3v1 tags, some have ID3v2 tags, some have both but they disagree on the information.  Some don&#8217;t have any tags, some are just named wrong.</p>
<p>So I thought I would write a script using a nice library to find out the length of the song, and pull out all the metadata from the ID3v1 and ID3v2 tags and look the data up in <a href="http://musicbrainz.org/doc/Database">The musicbrainz database</a> to check for accuracy.  Then write out nice clean mp3 files with consistant ID3v1 and ID3v2 tags (annoyingly some older hardware mp3 players can only read ID3v1 tags, but ID3v1 is so crappy you really want to use ID3v2 where you can). I thought this should be a nice straight forward evenings work.  Oh boy was  I wrong.</p>
<p>None of the libraries I looked at would tell me the length of a track.  Most of them would decode the ID3v2 and ID3v1 tags, but most would only give you the ID3v2 information if there was an ID3v2 tag and ignore the ID3v1 information (so I couldn&#8217;t easily make sure both tags were consistant).  Most didn&#8217;t appear to give me the option to write out a ID3v2 and a ID3v1 tag into the same file.  Now I expect there probably are libraries out there that do this, but it was disheartening enough that I decided to write my own mp3 parser library.  I&#8217;m glad I did, I learnt a lot of interesting things along the way.</p>
<p>I started off reading the <a href="http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm">mp3 frame header specification</a>.  An mp3 file is basically a series of frames.  Each frame begins with the &#8220;frame sync&#8221;.  If a frame sync isn&#8217;t found, you skip until you find one.  This allows recovering from a corrupt datastream.  Then each header has information about how this frame was compressed.  (In general) Each frame is independant and can be considered in isolation. An mp3 file is just a series of these frames one after another.  So my program started out by parsing all these headers keeping note of how long each frame is so I could calculate the total duration of the mp3 file.</p>
<p>Now, if an mp3 decoder doesn&#8217;t find an mp3 frame where it expects one, it just skips over the data in the file until it does find a valid frame sync.  This means you can put arbitary data into an mp3 file and mp3 decoders will ignore it.  So what happens?  Every man and his dog decides it&#8217;s a great idea to squirrel some data away in mp3 files.</p>
<p>The most obvious of these is the <a href="http://www.id3.org/ID3v1">ID3v1</a> tag.  The ID3v1 tag is the last 128 bytes of an mp3 file and starts with the characters &#8220;TAG&#8221;.  It then has some fixed length fields for the artist, album name, title, comment etc.  There is also a &#8220;Genre&#8221; field that has a possible 80 fields, latter extended by winamp to 125.  A varient of this tag (ID3v1.1) also has a track number by borrowing bytes from the comment field.</p>
<p>Because the ID3v1 tag is annoying in oh so many ways (limited length fields that a large propotion of songs exceed, limited number of fields, the tag being at the end of the file making getting the information when you are streaming a file impossible until the files entirely copied etc), <a href="http://id3.org/Developer_Information">ID3v2</a> was invented to solve these issues.  ID3v2 tags go at the beginning of the file, they have an arbitary number of tags that are of dynamic length.  Yay! You&#8217;d think.</p>
<p>Except there are <a href="http://id3.org/id3v2-00">ID3v2.2</a> tags (the original ID3v2 format &#8212; I have no idea what happened to ID3v2.0 or ID3v2.1),<a href=" http://id3.org/id3v2.3.0">ID3v2.3</a> which is what a lot of the software I&#8217;ve seen today means when it says &#8220;ID3v2&#8243;, and then theres <a href="http://id3.org/Developer_Information">ID3v2.4</a> which not many people seem to implement yet.</p>
<p>So now my library parses ID3v1, ID3v2.3 tags (I fortunately didn&#8217;t find any ID3v2.2 or ID3v2.3 tags in my collection), and can give me summary statistics on the mp3 stream (duration, histogram of bitrates used, average bitrate, total number of frames etc).  Running this over my collection starts turning up all kinds of interesting things.  A large proportion of the mp3 files appear to have random data that can&#8217;t be attributed to the MP3 stream, nor the ID3v1 or ID3v2 tags.</p>
<p>Further investigation discovers that people put <a href="http://www.id3.org/Lyrics3v2">Lyrics 3 v2</a> tags in mp3 files.  Not because they want lyrics, but because it was a convenient places to put the full version of the artist/album/title if the ID3v1 tag was too short to support it.  So I implemented a Lyrics3 v2 parser.</p>
<p>I also discovered that MP3 renormalisation software puts undo information into the file in a tag format called &#8220;APEv2&#8243; which has <a href="http://wiki.hydrogenaudio.org/index.php?title=APEv2_specification">a very poor specification</a>.  APEv2 isn&#8217;t recommended for MP3 files because it uses &#8220;APETAGEX&#8221; as it&#8217;s header/footer marker, which means it can coincidently end up with &#8220;TAG&#8221; in just the right place in the file for it to be mistaken as an ID3v1 tag.  Chances of this is very slim, and its impossible if there is a valid ID3v1 tag there anyway.  APEv2 is very similar to ID3v2.</p>
<p>But still theres data in the mp3 files I can&#8217;t attribute to any of the mp3 stream, ID3v1, ID3v2.2, Lyrics3v2, or APEv2 headers.  So then I discovered the completely obscure <a href="http://publicsvn.songbirdnest.com/browser/vendor/id3lib/current/doc/musicmatch.txt">music match</a> tagging format.  At this point I gave up.  Theres obviously more tagging formats in use than I really care for.  The other one that would be worth investigating would be the Vorbis/Flac comment structure, but I&#8217;ve not seen any evidence of them being used in any of the .mp3 files I&#8217;ve found to test on.  Not that I expect this to have stopped someone from deciding it was a great idea and doing it anyway.  Sigh.</p>
<p>Theres still quite a bit data that is left over even if I ignroe the musicmatch tags, which I looks like it is compressed data that for some reason doesn&#8217;t have a valid mp3 syncronisation header on it.  I&#8217;ve not found an adequate explaination yet as to what this data is doing there.</p>
<p>So now I have a long list of mp3 files that are inconsistant with their tagging, have obviously silly things going on with their tagging (eg trailing whitespace), have data I can&#8217;t attribute to the bitstream or any known tag, or have bizarre or crazy frame headers (eg have some frames that aren&#8217;t mpeg version 1 layer 3, and albums that are broken (eg two files that claim to have the same track number, or no file claiming track &#8220;2&#8243; on a 5 track album).</p>
<p>I decide to compare this to the musicbrainz database to see what things &#8220;should&#8221; be like.  Musicbrainz database isn&#8217;t perfect, but it&#8217;s at least reasonably internally consistant and well maintained and free for download.  Immediately I discover that there are regularly <a href="http://musicbrainz.org/search/textsearch.html?query=%22a+kind+of+magic%22&#038;type=release&#038;limit=25&#038;adv=on&#038;handlearguments=1">multiple versions</a> of the same CD.  Urgh.  I swear the entire music industry is out to get me.  So now I compare the number of tracks, and the track lengths that I have vs musicbrainz and pick the one that appears closest to the version I have, and compare them for accuracy.  It appears that based on the cdripper used, you get slightly different lengths, presumably due to different ideas of when the cd leadin/leadout times begin.  </p>
<p>So I start reripping CD&#8217;s that I think need to be sorted out, using cdparanoia.  At the same time I decide it would be useful to write out the TOC so I can do a CDDB lookup later, and so I can include the TOC data in the ID3v2.3 tag which allows later offline processing to determine which exact version of a CD a track came from, and what the length of the track should be vs the length of the mp3.  But apparently ripping a TOC is a complicated business.  Noone actually just writes out the subcode &#8220;Q&#8221; data.  So I use cdrdao to generate me a TOC file, which is near enough.  This however means cdrdao rips the CD <i>again</i> to verify track leadin/leadout times.  cdrdao can be used to rip the cd itself (using libcdparanoia), but when it does so it writes out one single file instead of one file per track.  Arrrggghh.  So while I&#8217;m writing this I&#8217;m waiting for CD&#8217;s to rip &#8212; twice for each CD.</p>
<p>Then I discover that CD&#8217;s can have a <a href="http://www.ifpi.org/content/section_resources/grid.html">GRiD</a> (aka Catalog) number which uniquely identifies the contents of the CD!  Yay!  Surely this would be more reliable than CDDB?  Ahh, but as far I can see there is no publically available GRiD&lt;-&gt;information database on the Internet.  There are (sometimes) also <a href="http://www.ifpi.org/content/section_resources/isrc.html">ISRC</a> numbers for each track which identifies the recording.  This sounds like a very useful thing until you realise that it can change if the recording is retouched or slightly different, but might not be modified if the song is for instance remixed. But still a set of ISRC&#8217;s in a specific order would be a good identifier for a CD, but again there appears to be no publically useable database on the Internet of ISRC&#8217;s.  I guess if a CD has GRiD or ISRC information then generally it contains CDTEXT on the CD itself with the name of the tracks.  Still it would be an interesting database to trawl.</p>
<p>Other bizarre things that you might have never known.  Number of unique versions of a CD according to musicbrainz:</p>
<table>
<tr>
<th>Artist</th>
<th>Album</th>
<th>Number of versions</th>
</tr>
<tr>
<td>Roberto Carlos</td>
<td>Roberto Carlos</td>
<td style="text-align: right">26</td>
</tr>
<tr>
<td>James Earl Jones</td>
<td>The Bible</td>
<td style="text-align: right">17</td>
</tr>
<tr>
<td colspan="3" style='text-align: center">&#8230;</td>
</tr>
</table>
<p>James Earl Jones is the author of the bible?  Who knew? &lt;grin;&gt;</p>
<p>Feel free to  experiment with my <a href="http://source.meta.net.nz/svn/mp3parser/trunk/parsemp3.py">mp3parser</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coders.meta.net.nz/weblog/2008/03/20/things-you-probably-never-wanted-to-know-about-mp3-files/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Lost Technologies of the Linux world</title>
		<link>http://coders.meta.net.nz/weblog/2007/04/02/lost-technologies-of-the-linux-world/</link>
		<comments>http://coders.meta.net.nz/weblog/2007/04/02/lost-technologies-of-the-linux-world/#comments</comments>
		<pubDate>Sun, 01 Apr 2007 12:35:53 +0000</pubDate>
		<dc:creator>Isomer</dc:creator>
		
		<category>Linux</category>

		<guid isPermaLink="false">http://coders.meta.net.nz/weblog/2007/04/02/lost-technologies-of-the-linux-world/</guid>
		<description><![CDATA[Linux (and Unix in general) has a long and (imho) interesting history.  It&#8217;s always evolving, always continuing to change.  However in the rush there are some interesting things that things that have been buried and all but lost.  Some of these are abominations that should have never ever seen the light of [...]]]></description>
			<content:encoded><![CDATA[<p>Linux (and Unix in general) has a long and (imho) interesting history.  It&#8217;s always evolving, always continuing to change.  However in the rush there are some interesting things that things that have been buried and all but lost.  Some of these are abominations that should have never ever seen the light of day (eg, <a href="http://www.die.net/doc/linux/man/man3/gets.3.html">gets(3)</a>), but many of them were a good idea that&#8217;s got lost somewhere along the way, and often naively reinvented and all the knowledge that was gained the first time around has been lost.</p>
<p>I&#8217;m not saying that all of these technologies should be revived wholesale, many have been buried for good reason, but there are lessons to be learnt here.  I refer to Linux and glibc here since thats what I know, much of this applies equally to any Unix.</p>
<p>Lets start with the fact on a modern Linux system you&#8217;d be hard pressed to realise that the GUI is network transparent.  There is no dialog box &#8220;Run [application [v]] on host [hostname [v]] as user [username [v]].&#8221;  Yet it was very common 10 years ago to be running xterm&#8217;s on a variety of boxes, executing cpu intensive commands on machines with cycles to spare.  Today people are surprised when you explain that you&#8217;re running your web browser on a machine thats seperate to the machine you&#8217;re logged into.  X11 doesn&#8217;t work well over high latency links I&#8217;ll admit, but over a local network it&#8217;s nearly impossible to tell that even a heavy application like a word processor isn&#8217;t running locally.  Theres none of the blocky loading like you get with VNC.  Yet this is becoming less and less well known.</p>
<p>Thin client Xterminals would speak &#8220;<a href="http://tldp.org/HOWTO/XDMCP-HOWTO/index.html">XDMCP</a>&#8221; to query for which machines were the least loaded for you to login to.  You could select from a list, selecting ones that were lightly loaded, but contained the resources you needed to get your work done, and being thin clients it didn&#8217;t matter which mchine you used.  The support is all still there, but mostly disabled by default because of network security issues, a story that repeats itself further through the article.</p>
<p>Because there were only a few of these big machines, everyone would be logged into them.  Commands like &#8220;ps&#8221; and &#8220;who&#8221; would show you what other people were doing.  Since there were probably multiple computers around you could use <a href="http://www.die.net/doc/linux/man/man1/rwho.1.html">rwho(1)</a> and <a href="http://www.die.net/doc/linux/man/man1/rusers.1.html">rusers(1)</a> to find out where someone was logged into.  You could talk to any user that hadn&#8217;t disabled it, with <a href="http://www.die.net/doc/linux/man/man1/write.1.html">write(1)</a>, or <a href="http://www.die.net/doc/linux/man/man1/talk.1.html">talk(1)</a>.  People would write blog-like entries in their .plan which you could read with <a href="http://www.die.net/doc/linux/man/man1/finger.1.html">finger(1)</a>.  Contrary to popular belief, Mirabilis didn&#8217;t invent &#8220;<a href="http://www.icq.com/info/icqstory.html">Instant Messenging</a>&#8221; in 1996, Mirabilis just made a limited form what Unix users had been doing for years available to non-Unix users. (No possibility to be logged into multiple places, no .plan/blog, having to run a seperate program to announce your presence, no rwall(1))   Almost all of these protocols have been disabled as being insecure, and have never been reimplemented in more secure ways.   </p>
<p><a href="http://www.die.net/doc/linux/man/man3/rcmd.3.html">rcmd(3)</a> is still a function in glibc which allows programmers to run a command on an another machine.  While <a href="http://www.die.net/doc/linux/man/man3/rcmd.3.html">rsh(1)</a>/<a href="http://www.die.net/doc/linux/man/man1/rexec.1.html">rexec(1)</a>/<a href="http://www.die.net/doc/linux/man/man1/rlogin.1.html">rlogin(1)</a> have all been replaced with <a href="http://www.die.net/doc/linux/man/man1/ssh.1.html">ssh(1)</a>, rcmd(3) has never been upgraded and remains a forgotten relic from when the Internet was a more trusting place.</p>
<p>Unix machines have always been multiuser boxes, although with the rapid increase in computing power in PC&#8217;s, this is becoming less common.   Unix machines have files called <a href="http://www.die.net/doc/linux/man/man5/utmp.5.html">utmp(5)</a> and <a href="http://www.die.net/doc/linux/man/man5/wtmp.5.html">wtmp(5)</a> that log who&#8217;s currently logged in and who has been logged in, in the past.  These files are nearly forgotten, and rarely are even written to unless someone opens an <a href="http://www.die.net/doc/linux/man/man5/wtmp.5.html">xterm(1)</a>.  The sense of community that went with using a large multiuser system has disappeared.</p>
<p>It&#8217;s not just the community orientated commands mentioned above that made Unix machines truely part of the network rather than boxes that just use the network.  With yp/NIS/NIS+ you could trivially enable large groups of machines to share critical databases with ease.  Not only were <a href="http://www.die.net/doc/linux/man/man5/passwd.5.html">passwd(5)</a>, <a href="http://www.die.net/doc/linux/man/man5/shadow.5.html">shadow(5)</a> and <a href="http://www.die.net/doc/linux/man/man5/group.5.html">group(5)</a> shared, but other information like <a href="http://www.die.net/doc/linux/man/man5/services.5.html">services(5)</a>, <a href="http://www.die.net/doc/linux/man/man5/networks.5.html">networks(5)</a>, <a href="http://www.die.net/doc/linux/man/man5/hosts.5.html">hosts(5)</a>, <a href="http://www.die.net/doc/linux/man/man5/ethers.5.html">ethers(5)</a>, <a href="http://www.die.net/doc/linux/man/man5/rpc.5.html">rpc(5)</a> and probably others were also copied.  To enable this you&#8217;d edit one or two lines and everything was set, extensive customisation was possible via netgroups.  Compare to a more &#8220;modern&#8221; LDAP setup which requires a lot more effort to setup and maintain.  Once again yp/NIS/NIS+ were horribly insecure, and LDAP at least can deliver it&#8217;s data securely over SSL, but is LDAP really an improvement?</p>
<p>You could tell a well administered network, as every machine had an up to date, and useful /etc/networks and often a useful /etc/ethers too.  However it&#8217;s been years since I&#8217;ve heard of anyone even mention these files.  Now days <a href="http://www.die.net/doc/linux/man/man5/hosts.5.html">hosts(5)</a> is mostly used as a kind of weird outbound firewall to prevent software talking to hosts you don&#8217;t like.</p>
<p>Networked file systems are also another interesting part of the story.  NFS is remarkably easy to setup under Unix, it integrates well.  It supports the unix semantics well, and with newer versions (eg NFSv4) supports running over a single easily (un?) firewalled port and avoiding the reliance on UIDs being identical between multiple machines.</p>
<p>Then there are other really interesting things that have gone on in the space like Kerberos and AFS/Coda.  It&#8217;s a pity that they&#8217;re not quite so nicely integrated as YP/NIS/NIS+/NFS etc.</p>
<p>Old command line applications such as <a href="http://www.die.net/doc/linux/man/man1/ftp.1.html">ftp(1)</a> and the various r* tools supported <a href="http://www.die.net/doc/linux/man/man5/netrc.5.html">netrc(5)</a>, a file that could contain usernames and passwords as well as aliases for machines and even would support macros to run.  Programs such as <a href="http://www.die.net/doc/linux/man/man1/curl.1.html">curl(1)</a> and <a href="http://www.die.net/doc/linux/man/man1/wget.1.html">wget(1)</a> still support this, but this feature is rarely if ever used, and I&#8217;d doubt would be implemented in many new applications.</p>
<p>In fact, most config files were executable, or scriptable in some way.  When you logged into a machine various scripts would run which could determine based on all kinds of criteria how to configure your setup.  You could decide not to use the high colour wallpaper on the old machine that only had 256 colours (oooh! flashies! remember them?), you could dim the colours your window manager used if you logged in after dark.  Your $PATH could be setup based on hardware platform, OS version or even if directories existed or not.  Window manager menus would be tweaked based on if this computer had a two or three button mouse, or may decide between several different programs depending on what was installed.  A &#8220;Run Xterm on&#8230;&#8221; menu might be populated from /etc/hosts.equiv.  Because the majority of users prefer not to program a lot of this kind of functionality has been removed.  Now if you use the same config from multiple computers you&#8217;d better aim for the lowest common denominator.</p>
<p>You used to be able rely on every machine being able to store mail locally, all kinds of programs still look in $MAIL to check if you have new mail.  Programs used to assume they can send you email if they had something non urgent to tell you.  Mail clients would check the local mail spool for your messages.  Anyone remember having <a href="http://www.die.net/doc/linux/man/man1/bash.1.html">bash(1)</a> tell you that you had new mail?</p>
<p>The current trend with SOAP and XMLRPC is also amusing, given that glibc still contains all the sunrpc xdr encoding systems.  These are solved problems.  ASN.1 is another encoding scheme thats been around for ages.  Neither appears to have any real problems (other than they don&#8217;t have standardised methods of passing them over HTTP, although that&#8217;s perhaps more a feature than a bug).  Yet people still insist on reinventing them.</p>
<p>There are other weird features in libc that are there for one reason or another <a href="http://www.die.net/doc/linux/man/man3/strfry.3.html">strfry(3)</a> and <a href="http://www.die.net/doc/linux/man/man3/memfrob.3.html">memfrob(3)</a> being amusing examples.  Other examples include <a href="http://www.die.net/doc/linux/man/man3/hsearch.3.html">hsearch(3)</a>, <a href="http://www.die.net/doc/linux/man/man3/lsearch.3.html">lsearch(3)</a>, <a href="http://www.die.net/doc/linux/man/man3/tsearch.3.html">tsearch(3)</a>, <a href="http://www.die.net/doc/linux/man/man3/insque.3.html">insque(3)</a>, <a href="http://www.die.net/doc/linux/man/man3/dbopen.3.html">dbopen(3)</a> etc&#8230;  None of these as far as I&#8217;m aware are part of any standard.</p>
<p>X11 has had several other interesting ideas that have been often overlooked. Window managers were always extremely extensible, and supported all kinds of interesting features.  Virtual Desktops and Workspaces are something that everyone has needed to support to be even considered (and I really wish the other OS&#8217;s would pick up.  I really feel cramped without my virtual workspaces!).  Lots of interesting things have been done with window managers that are being slowly forgotten.  Focus follows mouse is about as close to &#8220;focus follow eyes&#8221; as you can get vs Click to focus&#8217;s &#8220;is it safe to click on that part of the window right now or will that cause something to execute now?&#8221; issues.  Meta-LeftClick to raise, Meta-RightClick to bury, Meta-RightDrag to resize, and Meta-LeftClick to move all being fairly standard, but modern window managers are starting to ignore.  Window Manages</p>
<p>X has a &#8220;resource database&#8221; which has a standard config for everything.  Want to change the font size of some random little bit of text?  Easy.  Want to change the colour of something?  Simple.  Want to make all your xterms use visual bells?  These are per X server (&#8221;Display&#8221;), and thus applications running remotely will pick up the local styling, even if your /home is not shared between the two.  However modern toolkits ignore that,</p>
<p>On the flipside modern desktop &#8220;environments&#8221; are doing really well at looking really pretty (ooh! cubes!).  however you can find lots of people using window managers that are eye burningly highlighter blue because they support the way they work.</p>
<p>There have been some great ideas in unix that have been discarded for one reason or another, and often even &#8220;reinvented&#8221; with all the lessons of the past doomed to be reinvented.</p>
<p><small>(Postscript: In editing this post to link all the stuff I wanted to link I realised I could have used a <a href="http://www.die.net/doc/linux/man/man5/regex.5.html">regex(5)</a> to link all the manpages, but my browser doesn&#8217;t do regex searches let alone regex search and replace!  Why the hell not?!)</small>
</p>
]]></content:encoded>
			<wfw:commentRss>http://coders.meta.net.nz/weblog/2007/04/02/lost-technologies-of-the-linux-world/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Visual Studio</title>
		<link>http://coders.meta.net.nz/weblog/2007/03/01/visual-studio/</link>
		<comments>http://coders.meta.net.nz/weblog/2007/03/01/visual-studio/#comments</comments>
		<pubDate>Wed, 28 Feb 2007 12:40:12 +0000</pubDate>
		<dc:creator>Isomer</dc:creator>
		
		<category>Programming</category>

		<guid isPermaLink="false">http://coders.meta.net.nz/weblog/2007/03/01/visual-studio/</guid>
		<description><![CDATA[So, I&#8217;ve been doing some work on a network visualisation program called BSOD (Don&#8217;t ask), cleaning up code here,  tweaking some stuff from there.   Anyway I&#8217;ve got it running well under Linux.  The final thing to do before a new version is released is compile it under windows.
Now, I&#8217;ve not seriously [...]]]></description>
			<content:encoded><![CDATA[<p>So, I&#8217;ve been doing some work on a network visualisation program called BSOD (Don&#8217;t ask), cleaning up code here,  tweaking some stuff from there.   Anyway I&#8217;ve got it running well under Linux.  The final thing to do before a new version is released is compile it under windows.</p>
<p>Now, I&#8217;ve not seriously used Windows since about 1995.  When Windows 95 was released my current computer more or less defined the minimum requirements, and through various events ended up using Linux.  So this experience with programming under Windows was&#8230;.. educational.  I&#8217;m not unbiased in this;  I&#8217;m used to doing things under Linux.  I&#8217;ve been using Visual Studio 2005 under XP.</p>
<p>So, what was the experience like?  Well, it wasn&#8217;t my favourite experience.  Some things don&#8217;t work as I expect (Every time I try to use the middle click to paste I realise that no&#8230; I have to explicitly copy and paste it).  Things are different so thats ok.  What did bug me was Visual Studio.  People explain to me how great Visual Studio is, but my experience was somewhat&#8230; different.</p>
<p>Solutions and Projects confused me.  Does a solution hold projects, or do projects hold solutions?  Why can&#8217;t I have multiple solutions open at once?  One for building an external library and one for building the main program?  Given two checkouts on the same machine, how can I tell what the path is to the file I have open in any obvious way? (I assume theres some way to find out).</p>
<p>Window&#8217;s weird ideas about files being open not being able to be touched is annoying.  Especially when visual studio suggests that this is probably due to me using version control (wtf?).</p>
<p>Visual Studio recommends poor programming practises.  Wizards produce bad code.  One example is the skeleton code it produces when you generate a new console application:<br />
<code>int _tmain(int argc, _TCHAR* argv[])</code><br />
This uses &#8220;_tmain&#8221;.  Now in C/C++ identifiers that begin with an &#8220;_&#8221; are reserved for the standard library.  Programs should avoid ever using identifiers that start with a &#8220;_&#8221; so that the standard library can use them for symbols that shouldn&#8217;t be leaked into the application. For instance &lt;ctypes.h&gt; on MacOS defines almost every single letter variable with a _ in front of it.</p>
<p>Visual studio doesn&#8217;t really try to be a C compiler.  But it&#8217;s almost insulting to have the compiler tell me that my C program doesn&#8217;t conform to the ISO C++ specification.  It makes me angry to have the compiler suggest changing portable functions (eg strdup()/snprintf()) to less portable versions. C99 was released 8 years ago, yet Microsoft don&#8217;t even mention &lt;inttypes.h&gt; / &lt;stdint.h&gt;.  These headers are important for portability for applications that deal with integers of fixed length.  Sure VS has it&#8217;s own non-portable ways of specifing these, but that just makes the oversight more annoying.  The solution so far has been to implement our own &lt;inttypes.h&gt; and &lt;stdint.h&gt; for windows and ship them.  Frustrating.</p>
<p>Linux doesn&#8217;t really have any one elegant way to describe where the library path, library name(s), and header files are for installed library.  Two that spring to mind are pkgconfig, and *-config programs.  However despite these rather obvious flaws, I don&#8217;t see any way to deal with this in Visual Studio eitherrather you have to add the library name(s), the header search paths, and the library search paths.  And surprisingly library names aren&#8217;t selectable.  Plan9&#8217;s solution is to have a &#8220;#pragma&#8221; that specifies the library to link against.  Thus if you #include a header, you automatically end up linking against any library that they use.</p>
<p>Microsoft have said in the past that Linux is based on 30 year old technology.  Under Linux things have been tried and tested.  If they were found lacking then they have been replaced.  Windows however appears to have managed to accumulated bizarre limitations directly inherited from the 16bit days.  One example which bit me in the butt was that I can&#8217;t malloc()  in my program, and then free() it in a library.  Why?  Because in the 16bit world malloc() allocates out of a pool of memory per DLL and a seperate one from the main program.  But the limitations is annoying.</p>
<p>DirectX stuff appears to be complicated and rapidly changing.  The code I&#8217;ve been playing with was written against DirectX 8.  DirectX 8 however appears deprecated.  (The documentation discusses it&#8217;s support for the new and upcoming &#8220;whistler&#8221; operating system!).  However now it appears difficult to compile code against DirectX 8 now, newer SDK&#8217;s are geared more towards DirectX9 and DirectX10.</p>
<p>Many of the key combos I remember from my  Turbo C++ days still work.  The debugger works much the same way.  I enjoyed playing with &#8220;Run to Cursor&#8221; again after all these years.  I find using &#8220;bt full&#8221; from gdb to be much more useful than the annoying &#8220;watches&#8221;/&#8221;call stack&#8221;/&#8221;locals&#8221; interface, which appears to be more limited than I remember it being when I was using IDE&#8217;s in DOS.</p>
<p>I miss the flexibility I feel I lose moving to VS.   VS seems to want things done in it&#8217;s preferred way.  Sure you can override it, but you&#8217;re swimming against the current.  I miss regular expressions, grep, and sed.  For example &#8220;Find all references&#8221; doesn&#8217;t show any context, how do I know which one is the one I want?  Why can&#8217;t I compare two files to see how they differ like I can with diff(1)?</p>
<p>I feel like I&#8217;m in Beijing and I don&#8217;t speak the language.</p>
]]></content:encoded>
			<wfw:commentRss>http://coders.meta.net.nz/weblog/2007/03/01/visual-studio/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hostnames, Domain names, and &#8220;Official&#8221; host names</title>
		<link>http://coders.meta.net.nz/weblog/2007/01/16/hostnames-domain-names-and-official-host-names/</link>
		<comments>http://coders.meta.net.nz/weblog/2007/01/16/hostnames-domain-names-and-official-host-names/#comments</comments>
		<pubDate>Tue, 16 Jan 2007 00:11:24 +0000</pubDate>
		<dc:creator>Isomer</dc:creator>
		
		<category>General</category>

		<guid isPermaLink="false">http://coders.meta.net.nz/weblog/2007/01/16/hostnames-domain-names-and-official-host-names/</guid>
		<description><![CDATA[Due to regular arguments I&#8217;ve had with people about this I thought I should document this somewhere for people to see:
Host names
The syntax for a hostname was defined waay back in RFC 952. it&#8217;s defined as:

      &#60;hname&#62; ::= &#60;name&#62;*["."&#60;name&#62;]
      &#60;name&#62;  ::= &#60;let&#62;[*[&#60;let-or-digit-or-hyphen&#62;]&#60;let-or-digit&#62;]

(if you prefer [...]]]></description>
			<content:encoded><![CDATA[<p>Due to regular arguments I&#8217;ve had with people about this I thought I should document this somewhere for people to see:</p>
<p><strong>Host names</strong><br />
The syntax for a hostname was defined waay back in <a href="http://coders.meta.net.nz/~perry/rfc/?rfc=952">RFC 952</a>. it&#8217;s defined as:</p>
<pre>
      &lt;hname&gt; ::= &lt;name&gt;*["."&lt;name&gt;]
      &lt;name&gt;  ::= &lt;let&gt;[*[&lt;let-or-digit-or-hyphen&gt;]&lt;let-or-digit&gt;]
</pre>
<p>(if you prefer as a regex  /[a-z]([a-z0-9-]*[a-z0-9])?(\.[a-z]([a-z0-9-]*[a-z0-9])?)*/.)</p>
<p>RFC 952 also says a computer has an &#8220;official&#8221; hostname and zero or more &#8220;nicknames&#8221; or aliases, but are discouraged.</p>
<p><strong>Domain names</strong><br />
A domain name is something that&#8217;s in DNS.  A Domain name is much less strict on what it allows.  This is used in <a href="http://coders.meta.net.nz/~perry/rfc/?rfc=2782">RFC 2782</a> to avoid collisions with hostnames by requiring that SRV records have a &#8220;_&#8221; prepended to them since no valid hostname can have a _.</p>
<p><strong>Implications</strong><br />
Other premsises:</p>
<ul>
<li> RFC 821 says in section 3.7:
<pre>
      Whenever domain names are used in SMTP only the official names are
      used, the use of nicknames or aliases is not allowed.
</pre>
</li>
<li> RFC 1123 says:
<pre>
      5.2.5  HELO Command: 

         The sender-SMTP MUST ensure that the &lt;domain&gt; parameter in a
         HELO command is a valid principal host domain name for the
         client host.
</pre>
</li>
<li> RFC 2181 Section 10.3:
<pre>
                                      [...] Thus, if an alias is used as the value
   of an NS or MX record, no address will be returned with the NS or MX
   value.  This can cause extra queries, and extra network burden, on
   every query.  It is trivial for the DNS administrator to avoid this
   by resolving the alias and placing the canonical name directly in the
   affected record just once when it is updated or installed.
</pre>
</li>
<li> RFC 2821 Section 4.3.1
<pre>
   Note: all the greeting-type replies have the official name (the
   fully-qualified primary domain name) of the server host as the first
   word following the reply code.
</pre>
</li>
</ul>
<p>Therefore:</p>
<ul>
<li> You cannot have a &#8220;_&#8221; in your <tt>HELO</tt>/<tt>EHLO</tt>.  Even tho microsoft windows machines love to do this.  Expect your mail to be dropped.
 </li>
<li> MX&#8217;s should point to the &#8220;official&#8221; (canonical) name of the mail server, which should in theory be the same as the name produced in the 220 banner.
</li>
</ul>
<p><strong>Updated:</strong> With Aristotles fixed regex.  Ooops! My bad.
</p>
]]></content:encoded>
			<wfw:commentRss>http://coders.meta.net.nz/weblog/2007/01/16/hostnames-domain-names-and-official-host-names/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Back in my day</title>
		<link>http://coders.meta.net.nz/weblog/2006/11/27/back-in-my-day/</link>
		<comments>http://coders.meta.net.nz/weblog/2006/11/27/back-in-my-day/#comments</comments>
		<pubDate>Sun, 26 Nov 2006 12:30:35 +0000</pubDate>
		<dc:creator>Isomer</dc:creator>
		
		<category>Programming</category>

		<guid isPermaLink="false">http://coders.meta.net.nz/weblog/2006/11/27/back-in-my-day/</guid>
		<description><![CDATA[It occured to me how much knowledge is being lost since I taught myself to program.  Programmers today &#34;know&#34; some of the low level details of how a machine works in theory, but really, how much do they know?
When I started teaching myself to code it was on an IBM XT with DOS.  [...]]]></description>
			<content:encoded><![CDATA[<p>It occured to me how much knowledge is being lost since I taught myself to program.  Programmers today &quot;know&quot; some of the low level details of how a machine works in theory, but really, how much do they know?</p>
<p>When I started teaching myself to code it was on an IBM XT with DOS.  Now, if you&#39;re somoene who&#39;s never really used DOS (or CP/M or&#8230;) except in &quot;DOS Box&quot;&#39;s, then you really don&#39;t know what it means to run a non multitasking, non protected mode machine.   DOS is not very much more than a way to load programs into memory and run them.  It provides only very basic abstraction from the hardware, and most of it is extremely slow and limited.  the DOS API&#39;s were generally only ever used to read/write files.  DOS was essentially treated a filesystem driver.</p>
<p>The realmode x86 chips had a weird memory model called &quot;segmentation&quot;.  Each segment was 64k, and segments overlapped with each other offset by 16 bytes.  So offset 0010 in segment 0000 was the same as offset 0000 in segment 0001.  You&#39;d write these addresses as segment:offset.  Programmers would regularly directly access addresses in memory that they knew contained things.  I can still remember a lot of interesting addresses off by heart.</p>
<ul>
<li>0000:0000 was/is the interrupt vector table</li>
<li>0000:7c00 - the bootsector was loaded into memory</li>
<li>A000:0000 - the VGA Framebuffer was located.</li>
<li>B000:0000 - the monocrome textmode display was located</li>
<li>B800:0000 - the colour textmode display</li>
<li>C000:0000 - this was &quot;Adaptor ROM&quot;, or where network cards (and other things) put their stuff</li>
<li>F000:FA6E - this was the VGA ROM BIOS Font</li>
</ul>
<p>You talked directly to the hardware.  If you wanted to hook an IRQ, go for it, overwrite the address it would use in the interrupt vector table, and remember to acknowledge the interrupt when it came time to return.</p>
<p>I remember to change the VGA palette you write the pallete entry you want to change to io port 0&#215;3c8, then write the red value to 0&#215;3c9, green to 0&#215;3c9, then blue to 0&#215;3c9.  They could be from 0 to 63.</p>
<p>In fact, I remember you could poll an IO port (I must admit I&#39;ve forgotten which one, 0&#215;3CA?) and see if a horizontal or vertical retrace was in effect.  Depending on the screen mode there were only 16 or 256 or whatever palette entries.  Most of the time this meant that you could only have 256 colours on the screen at once.  If you modified the palette while the video card was drawing on the screen you&#39;d get &quot;Snow&quot;.</p>
<p>Snow was caused when the video card tried to read a value that the host CPU was in the process of modifying.  It would normally read out 0xFF or some other weird value instead so you&#39;d get &quot;white&quot; in random places across the screen causing what looked like &quot;Snow&quot;.</p>
<p>But you had enough time to modify about 4 entries during the horizontal blanking time (on my hardware at least) before it started painting the line and therefore avoiding the snow.  This meant you could use 256*4+242 colours on the screen at once (on  a 256 scanline resolution).   Often this was used to change just the background colour, usually in a nice smooth gradient.  This was called coppering.</p>
<p>By investigating what the other video registers were used for people discovered lots about how video cards worked.  Video cards were only allocated 64k of address space, so to fit higher resolutions or higher bit depths in they used &quot;planes&quot; (or banks) that you switched into the 64k address space, wrote your updates to it, and then flipped in the next plane.   Lots of interesting tricks could be pulled using these techniques.  A lot of video modes were &quot;chained&quot;.  A write to video memory would write the same value to all planes simultaniously.  These modes were fast and easy to program for, but they were stuck at very low resolutions.  But by programming some of these low resolution modes and turning off the &quot;chained&quot; bit in the video card you could effectively create your own unsupported, undocumented video modes.  These modes were collectively called &quot;Mode X&quot;.</p>
<p>Because the machines were so slow, you spent a lot of time working on optimising code.  Often you&#39;d end up rewriting tight loops in assembly code.  Even then you&#39;d look at how you could optimise your assembly code.</p>
<p>x86 instructions are of dynamic length.  There minimum length is 1 byte.  Their maximum length was something like 6 bytes.  I suspect on a modern x86_64 machine it&#39;s probably closer to 12 bytes by now.</p>
<p>Your bus was 8 or 16bits wide, and you had to wait for bus transactions to complete, so you&#39;d want to choose the shortest opcode you could.  Also memory was at a premium, every byte saved was going to be useful somewhere else.  xor ax, ax was better than mov ax,0&#215;0000 because xor ax,ax is a 1 byte opcode, where as mov ax,0&#215;0000 was 3 bytes.</p>
<p>Unlike the RISC machines you get taught on at universities where everything is nice and simple and elegant, and instructions take a fixed number of cycles, on x86 they can take different amounts of time.   xor ax,ax might take one cycle.  a multiply or a divide might take a few hundred cycles. A sin or cos might take a small iceage. So sometimes you wanted to use more opcodes because they were faster but the achieved the same result.<br />
One popular VGA video mode was mode 0&#215;13.  (&quot;mode thirteen&quot;).  It was 320&#215;200x256.  To code a putpixel you needed to do (A000:0000 + Y*320 + X).    But that had a nasty multiplication in it.  Remember how you were taught to do multiplication at primary school?</p>
<pre>32
 *320
 ----
    0
+ 64
+96
-----
10240</pre>
<p>Imagine doing this in binary:</p>
<pre>0000 0000 0001 0000
          *0000 0001 0010 0000
           -------------------
           0000 0000 0000 0000
         0 0000 0000 0000 000
        00 0000 0000 0000 00
       000 0000 0000 0000 0
      0000 0000 0000 0000
    0 0000 0000 0010 000
   00 0000 0000 0000 00
  000 0000 0000 0000 0
 0000 0000 0001 0000
&lt;snip&gt;
 ----------------------------------</pre>
<pre>0000 0000 0001 0010 0000</pre>
<p>The thing to note is where there is a zero in the second argument to &#39;*&#39;, there is a line of all 0&#39;s in the working, and where there is a 1, the first number is copied entirely shifted left by the position of the bit.  So to multiply by 320 you could instead do res=(y&lt;&lt;5)+(y&lt;&lt;8).  This was faster, significantly so. I remember benchmarking it</p>
<p>Other quirks of the x86 architecture were things like you could do complex addressing modes like [bx+4*ax+3].  this was handy when you needed to find the address of a member of a structure in a array.  There is an opcode called LEA.  Load effective Address.  This instruction takes an address as it&#39;s argument and loads that address (not the value at that address) into some other register.  The fun thing was that LEA was a single cycle opcode (and quite short 1 or 2 bytes IIRC). This meant that you could do a shift by a power of two, and an addition in one opcode instead of two.  And not only that it wouldn&#39;t use the ALU to do the arithmetic so another opcode could be busy using the ALU.</p>
<p>One of my greatest &quot;hacks&quot; was a program I wrote that used one of the &quot;Mode X&quot;&#39;s I mentioned above to create a 256&#215;256x256 video mode.  Most monitors hated this mode as it was effectively square, and they were 4:3, but with some protesting they&#39;d do it.   I created a subdivision style &quot;plasma&quot;.  Then each vertical refresh I&#39;d blit onto the screen a tunnel going off to infinity with this plasma textured onto it.</p>
<p>Originally I wrote this in Pascal (Turbo Pascal v7 for DOS was a brilliant language, compiler, and IDE).  Except it was slow.  Glacially slow.  So I started rewriting chunks of it in assembler.  But I soon ran into the problem that intel machines don&#39;t have many registers. So I stored all the registers in the code segment (writable code segments yay!), and then used all the registers (including the stack pointer &#8212; which is why I couldn&#39;t store them on the stack) as general purpose registers.</p>
<p>It still wasn&#39;t fast enough.  One of the reasons for this was I only had a handful of segment registers.  Now when you&#39;re addressing memory in x86 realmode, you give an offset into one of the segment registers (CS (code segment), DS (Data segment), ES (Extra Segment), SS (Stack Segment) and I needed to access 4 buffers (vga buffer, texture, and x/y data for my tunnel).</p>
<p>So, I did some research and found the opcodes for the new 386 instructions, and tried using them.  But turbo pascal&#39;s internal assembler didn&#39;t know about these opcodes.  Now when it comes to x86 assembler there are prefixes for changing some characteristic about the next opcode.  for instance a &quot;ES:&quot; prefix would modify the address in the instruction to be relative to the ES (Extra segment) instead of the DS (Data segment).  If you used 32bit registeres in real mode the assembler would automatically output a prefix saying to use 32bit values/registers instead of 16 bit ones for the next opcode.  This assembler didn&#39;t know how to do that.  So I would use &quot;db 0&#215;66 ; mov ax, sp&quot; to make the instruction &quot;mov eax, esp&quot;.  But then I discovered that the 386 had introduced another couple of segment registers (gs/fs). howeve there was no prefix for them, I had to hand assemble and insert the raw hex values for them into my program.</p>
<p>So now I had a program that I had hand assembled to make run, and now it ran fast enough to be useful on my machine, and it looked sweet!</p>
<p>But around the time of the release of ID&#39;s game &quot;Doom&quot; all of this disappeared.  Compilers didn&#39;t produce  completely moronic code anymore, and processesors were fast enough that you could afford to waste a few cycles here or there.  The program I&#39;d painstakingly hand optimised above I showed to a friend.  He wrote the entire thing in C and it ran fine on his pentium computer.  (his version however didn&#39;t run at all reasonably on my 386).</p>
<p>Doom was written almost entirely in C, including the 3d raycaster.  Only the dissolve between missions was written in assembler.  Soon computers were coming with 3d accelerated video cards and everyone forgot how to write assembler, except for the fringe lunatics and people who write compilers.</p>
<p>You might think that this is progress.  No more do people spend a week painstakingly hand assembling code to get things to run as fast as humanly possible.  But, the skills I learnt over 10 years ago when I taught myself to program are still useful today.  Knowing the layout of a bootsector means I can correctly identify a lot more problems people have with disk images.  Knowing assembly language in far more detail than anyone thinks is necessary helps with debugging obscure problems in programs.</p>
<p>You tell people today about hand assembling programs to get them to run at speed and they just won&#39;t believe you. :)
</p>
]]></content:encoded>
			<wfw:commentRss>http://coders.meta.net.nz/weblog/2006/11/27/back-in-my-day/feed/</wfw:commentRss>
		</item>
		<item>
		<title>&#8220;Or&#8221; considered harmful.</title>
		<link>http://coders.meta.net.nz/weblog/2006/10/30/or-considered-harmful/</link>
		<comments>http://coders.meta.net.nz/weblog/2006/10/30/or-considered-harmful/#comments</comments>
		<pubDate>Mon, 30 Oct 2006 03:16:33 +0000</pubDate>
		<dc:creator>Isomer</dc:creator>
		
		<category>General</category>

		<guid isPermaLink="false">http://coders.meta.net.nz/weblog/2006/10/30/or-considered-harmful/</guid>
		<description><![CDATA[On the weekend we decided that &#34;or&#34; (as used in the english language) is ambiguous and leads to confusion.  We decided that instead we should use three terms:

&#34;andor&#34; (to mean &#34;are any of these true?&#34;)
&#34;xor&#34; or &#34;either-or&#34; or &#34;exclusive-or&#34; (to mean &#34;are only one of these true?&#34;)
&#34;ewok&#34; (to mean &#34;which of these are true?&#34;)

Some [...]]]></description>
			<content:encoded><![CDATA[<p>On the weekend we decided that &quot;or&quot; (as used in the english language) is ambiguous and leads to confusion.  We decided that instead we should use three terms:</p>
<ul>
<li>&quot;andor&quot; (to mean &quot;are any of these true?&quot;)</li>
<li>&quot;xor&quot; or &quot;either-or&quot; or &quot;exclusive-or&quot; (to mean &quot;are only one of these true?&quot;)</li>
<li>&quot;ewok&quot; (to mean &quot;which of these are true?&quot;)</li>
</ul>
<p>Some examples:</p>
<ul>
<li>Is it wet outside ewok is it fine? (&quot;it&#39;s wet outside&quot;), Is it wet outside andor is it fine (&quot;yes&quot;), Is it wet outside xor is it fine (&quot;yes&quot;).</li>
<li>Am I mad ewok have small furry animals invaded this conversation? (&quot;You are both mad, and small furry animals have invaded this conversation&quot;), Am I mad andor have small furry animals invaded this conversation? (&quot;Yes&quot;), Am I mad xor have small furry animals invaded this conversation? (&quot;No&quot; both are true).</li>
<li>Would you like green eggs and ham on a plane ewok on a train? (&quot;Mu&quot; &#8212; I don&#39;t want green eggs on either).  Would you like green eggs and ham on a plane andor on a train? (&quot;No&quot;), Would you like green eggs and ham on a plain xor on a train? (&quot;No&quot;).</li>
<li>Should this be blue ewok green ewok red? (&quot;Green&quot;), Should this be blue andor green andor red (&quot;yes&quot;), Should this be blue xor green xor red (&quot;Yes&quot;).</li>
</ul>
<p>so, in closing, I Think we should stop using &quot;or&quot; in every day conversation and instead use &quot;andor&quot;, &quot;xor&quot; and &quot;ewok&quot; instead to be more precise about what question we&#39;re asking.
</p>
]]></content:encoded>
			<wfw:commentRss>http://coders.meta.net.nz/weblog/2006/10/30/or-considered-harmful/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Home theatre and the IP Revolution?</title>
		<link>http://coders.meta.net.nz/weblog/2006/10/10/home-theatre-and-the-ip-revolution/</link>
		<comments>http://coders.meta.net.nz/weblog/2006/10/10/home-theatre-and-the-ip-revolution/#comments</comments>
		<pubDate>Mon, 09 Oct 2006 12:09:32 +0000</pubDate>
		<dc:creator>Isomer</dc:creator>
		
		<category>Networking</category>

		<guid isPermaLink="false">http://coders.meta.net.nz/weblog/2006/10/10/home-theatre-and-the-ip-revolution/</guid>
		<description><![CDATA[So recently I was setting up an home theatre system.  TV, DVD Player, Sky, PS/2, etc. and an AMP/Reciver. After dealing with S/Video, Component, Composite, RF, Scart, HDMI, DVI, and VGA as well as power and speaker cables, I came to the conclusion that convergance couldn&#8217;t happen fast enough. 
Imagine having all your components [...]]]></description>
			<content:encoded><![CDATA[<p>So recently I was setting up an home theatre system.  TV, DVD Player, Sky, PS/2, etc. and an AMP/Reciver. After dealing with S/Video, Component, Composite, RF, Scart, HDMI, DVI, <i>and</i> VGA as well as power and speaker cables, I came to the conclusion that convergance couldn&#8217;t happen fast enough. </p>
<p>Imagine having all your components plug in via ethernet.  They could be anywhere in the house, audio video could be streamed over IP.  Devices could be discovered via mDNS.  No need for limited numbers of inputs, want 6 DVD players?  Sure, no problem.  Want 4 SKY decoders?  No issue.</p>
<p>Your reciever would have one ethernet uplink, and terminals for your speakers, maybe preamp outputs.  It would decode whatever codecs are the current fads (much as it does now).  Assuming enough bandwidth it may even use 802.11 wireless reducing the need for even more cables.  Other components (DVD, TV, Sky etc) would all also take power and ethernet as their ownly source.</p>
<p> You could converge your home theatre with your phone (video conferencing?  why not!), when your phone rings your DVD (or DVR) pauses the current output, and brings up a nice overlay with the callerID.<br />
 Your remote control could be 802.11, which while it might chew through batteries could easily detect all your components and provide a consistant interface to them anywhere in the house.</p>
<p> If people really care about DRM (personally I think it hurts everyone more than it helps, but I could be wrong&#8230;), then all of this can be easily authenticated/encrypted by IPsec and X.500 certificate CA&#8217;s. </p>
<p>HDMI is close.  It provides an integrated point-to-point audio/video connector which sends uncompressed video and encoded audio.  It has no theoretical maximum cable length although it has a pracatical limitation of about 15m. compared to 100m for Ethernet.  You can get HDMI repeaters, you can get ethernet switches.  Ethernet lets you address multiple devices on the same subnet allowing you to have multiple sources (eg DVD/CD/sky/etc) and sinks (TV&#8217;s/recievers/etc) on the same network.  HDMI has i<sup>2</sup>C to do autodetection of devices (eg for EDID), and supports AV Link for remote control features for multirooming etc.  IP has a wide variety of protocols that could be used for this.  Ethernet is well established and things such as ethernet switches/cables/etc are all mature products.</p>
<p> So, I wish everything spoke Ethernet, it would rock.   I guess I&#8217;ll just have to wait until more than just DVD players have HDMI to get close.
</p>
]]></content:encoded>
			<wfw:commentRss>http://coders.meta.net.nz/weblog/2006/10/10/home-theatre-and-the-ip-revolution/feed/</wfw:commentRss>
		</item>
		<item>
		<title>python, ctypes, and debugging symbols.</title>
		<link>http://coders.meta.net.nz/weblog/2006/09/02/python-ctypes-and-debugging-symbols/</link>
		<comments>http://coders.meta.net.nz/weblog/2006/09/02/python-ctypes-and-debugging-symbols/#comments</comments>
		<pubDate>Fri, 01 Sep 2006 14:16:36 +0000</pubDate>
		<dc:creator>Isomer</dc:creator>
		
		<category>Programming</category>

		<guid isPermaLink="false">http://coders.meta.net.nz/weblog/2006/09/02/python-ctypes-and-debugging-symbols/</guid>
		<description><![CDATA[there is a python module called ctypes. This module lets you make calls to various functions inside a dynamically linked library without having to explicitly write wrapper code for it.&#160; But you must specify the complete type of the function you&#39;re calling before you call it, so that the ctypes library knows arguments to push [...]]]></description>
			<content:encoded><![CDATA[<p>there is a python module called <tt>ctypes</tt>. This module lets you make calls to various functions inside a dynamically linked library without having to explicitly write wrapper code for it.&nbsp; But you must specify the complete type of the function you&#39;re calling before you call it, so that the ctypes library knows arguments to push onto the stack and what order etc.</p>
<p>This always seemed to be a silly restriction, in an strong, but dynamically typed language such as python having to forward declare things seems to defeat the entire purpose.&nbsp; And besides, when you compile something, you can compile it with full debugging symbols, which has the full type information about everything in your program anyway.</p>
<p>So, you could write a program to parse the debugging symbols out of an .so, and generate a python module with all the various type definitions and functions exported from the library, and you could do all of this on the fly.</p>
<p>And thus, I wrote it.</p>
<p>foo.c</p>
<pre>struct function2_return_t {
        int a;
        int b;
};

struct function2_return_t function2(int a)
{
        struct function2_return_t ret;
        ret.a=a;
        ret.b=a+1;

return ret;
}</pre>
<p>And the example usage:</p>
<pre>&gt;&gt;&gt; import ct
&gt;&gt;&gt; ct.load(&quot;foo.so&quot;)
&gt;&gt;&gt; import foo
&gt;&gt;&gt; ret=foo.function2(1)
&gt;&gt;&gt; print ret
&lt;ct.function2_return_t object at 0x2aefd8f12650&gt;
&gt;&gt;&gt; print ret.a
1
&gt;&gt;&gt; print ret.b
2</pre>
<p>It&#39;s all still very prototypeish, it doesn&#39;t deal with pointers or strings yet. As you can see it deals with structs (as if they were classes), and could fairly easily deal with arrays and pointers to structs (although once you get into pointers, you get into &quot;who owns this memory&quot;, perhaps requiring a .free() method on classes).&nbsp; Strings should also be fairly straight forward if you can figure out who actually owns the memory (should it be freed?).</p>
<p>At the moment I run and parse the output of readelf to get the debugging information, and I don&#39;t properly hook the &quot;import&quot; mechanism to make it all completely transparent, but as a prototype I thought it was pretty cool.&nbsp;
</p>
]]></content:encoded>
			<wfw:commentRss>http://coders.meta.net.nz/weblog/2006/09/02/python-ctypes-and-debugging-symbols/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Woot!  My Filesystem workish!</title>
		<link>http://coders.meta.net.nz/weblog/2006/08/03/woot-my-filesystem-workish/</link>
		<comments>http://coders.meta.net.nz/weblog/2006/08/03/woot-my-filesystem-workish/#comments</comments>
		<pubDate>Thu, 03 Aug 2006 10:49:56 +0000</pubDate>
		<dc:creator>Isomer</dc:creator>
		
		<category>Linux</category>

		<category>Programming</category>

		<category>Networking</category>

		<guid isPermaLink="false">http://coders.meta.net.nz/weblog/2006/08/03/woot-my-filesystem-workish/</guid>
		<description><![CDATA[So as you may remember, I&#39;ve been thinking about (and quietly implementing) a distributed filesystem.&#160; Tonight I got as far as it mostly working, and since everyone around here is sick of me telling them about it I thought I&#39;d tell you all about it instead :)
It uses the 9p protocol to talk to the [...]]]></description>
			<content:encoded><![CDATA[<p>So as you may remember, I&#39;ve been thinking about (and quietly implementing) a distributed filesystem.&nbsp; Tonight I got as far as it mostly working, and since everyone around here is sick of me telling them about it I thought I&#39;d tell you all about it instead :)</p>
<p>It uses the 9p protocol to talk to the kernel (although I&#39;m using the 9p python client for testing).&nbsp; I use the chimera DHT for indexing, and libnpfs for dealing with the low level details of the 9p protocol.&nbsp; I&#39;ve managed to find bugs in all of these pieces of software so far :)</p>
<p>&nbsp;Anyway, onto the interesting part of the show:</p>
<pre>9p&gt; ls
foo/
9p&gt; cd foo
9p&gt; ls
readme
9p&gt; cat readme
Hello World
9p&gt; mkdir sample
9p&gt; ls -l
-rw-r--r-- perry perry 0        readme
drwxr-xr-x perry perry 0        sample
9p&gt; cd sample
9p&gt; ls -l
9p&gt; put testfile
9p&gt; ls -l
-rw-r--r-- perry perry 0       testfile
9p&gt; cat testfile
This file is a test
9p&gt;&nbsp;</pre>
<p>You may notice that the file sizes are all 0, even though most of them seem to contain data, this is coz I&#39;ve not finished implementing <a href="http://www.wlug.org.nz/stat(2)" title="stat system call">stat(2)</a> yet.&nbsp; Permissions etc are kinda implemented (they&#39;re stored, but not read off disk yet, although libnpfs appears to verify them for me).</p>
<p>There&#39;s a bit of polishing off to do before the &quot;local&quot; part of the filesystem is mostly viable. Then I <i>just</i> have to hook all the distributedness together and I should have a fully functional prototype! (yeah right&#8230;)
</p>
]]></content:encoded>
			<wfw:commentRss>http://coders.meta.net.nz/weblog/2006/08/03/woot-my-filesystem-workish/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Fragmenting IP</title>
		<link>http://coders.meta.net.nz/weblog/2006/07/17/fragmenting-ip/</link>
		<comments>http://coders.meta.net.nz/weblog/2006/07/17/fragmenting-ip/#comments</comments>
		<pubDate>Mon, 17 Jul 2006 02:31:59 +0000</pubDate>
		<dc:creator>Isomer</dc:creator>
		
		<category>General</category>

		<category>Networking</category>

		<guid isPermaLink="false">http://coders.meta.net.nz/weblog/2006/07/17/fragmenting-ip/</guid>
		<description><![CDATA[When fragmenting IP packets, you usually split the packets up into &#34;n-1&#34; pMTU sized packets, and 1 packet of the remainder.&#160; Now with wireless networks the larger the packet is the more likely it is to be lost/corrupted.&#160; I suspect it would make more sense to fragment packets into equal sized pieces, so totlen/n bytes [...]]]></description>
			<content:encoded><![CDATA[<p>When fragmenting IP packets, you usually split the packets up into &quot;<tt>n-1</tt>&quot; pMTU sized packets, and <tt>1</tt> packet of the remainder.&nbsp; Now with wireless networks the larger the packet is the more likely it is to be lost/corrupted.&nbsp; I suspect it would make more sense to fragment packets into equal sized pieces, so <tt>totlen/n</tt> bytes each.&nbsp; Most routing overhead is per packet, and the total number of packets hasn&#39;t been changed.&nbsp; Also this would tend to avoid so many pMTU issues as your packets are probably going to less than pMTU sized.
</p>
]]></content:encoded>
			<wfw:commentRss>http://coders.meta.net.nz/weblog/2006/07/17/fragmenting-ip/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
