Digital Rights Management on the web

I strongly dislike Digital Rights Management (DRM), and often refuse to buy certain things simply on the grounds of them having DRM. So, what I do have against DRM? For the sake of clarity, I’ll assume we’re talking about videos/films (but all these arguments apply to any kind of content):

  • Any platform (= “device” or “operating system”) not supported by the producer will not have a legal way to watch the video: as DRM needs special video players (that enforce certain conditions, like not allowing you to share the film with other people), you can only watch the film if there’s a player for your platform.
  • Because of the point above, free software is left out almost by definition (eg. under Linux, DVDs have their protection cracked in order to watch them because there’s no legal player; this is not only cumbersome, but illegal in some countries even if you have bought the DVD; Netflix is not officially available on Linux, although there are workarounds).
  • It gives unnecessary control to the producers of the content (eg. Amazon can delete books you have bought from your Kindle; you maybe not be able to lend the film/book to a friend; many DVDs don’t allow you to watch the film directly without watching the trailers first).
  • It’s often inconvenient for the paying customer, plus it doesn’t even work to fight piracy (music examples / film examples).

So, can’t you just not buy any DRM-”protected” films/books if you don’t like DRM? That’s more or less what I do, but I’m worried now that the w3c is planning on introducing DRM as part of the web, which will encourage more companies to use DRM. And I said “encourage”, not “allow”, because it’s perfectly possible to do so now (eg. Netflix does it). As I’m opposed to DRM, I think it’s ok that’s it’s painful or awkward to implement: there’s no need to make something bad easier and more common.

Some pro-DRM people seem to have this misconception that people who oppose DRM want the content to be free of charge. That’s ridiculous. I want to pay for the content, I just want to watch/read that content in whatever way is comfortable for me, and in whatever devices/operating systems I happen to use. In fact, I do spend a lot of money on music (but only when it’s DRM-free).

The only pro-DRM arguments I could take seriously were brought by the BBC (hat-tip to Bruce Lawson for sending me the link). They have very good points in the sense that in many cases it’s not even their choice to offer unlimited access. The thing is, again, that:

  1. If we agree that DRM (eg. limiting the content to certain kinds of devices) is bad, why make it easier? It’s already possible, let’s not make that the default if we think it’s bad. Keeping thing that are bad-but-necessary-right-now hard, but possible, sounds like a good strategy to me…
  2. Non-supported platforms would be excluded, why make it easier to have content on the web that discriminates against certain people (eg. people who have non-mainstream devices, free software)?

Finally, the EFF has a page about owning vs. renting that talks about other reasons why I don’t like DRM.

Making comics

Almost one year ago now I finished reading “See What I Mean” (summary part 1, part 2), the book that got me started making comics. Now I’m reading the excellent “Drawing Words & Writing Pictures” and I’m learning much more about techniques and visual language. The first book I recommend if you are intrigued by the idea of making comics but always thought you couldn’t because you can’t draw, and also if you are intrigued by the idea of using comics at work (eg. see my comics explaining different use cases for my project RoboHydra). The second I recommend if you have some artistic background and/or after reading the first.

I thought it would be fun to document the way I’m making comics now, hence this post.

Idea

You start with an idea of what you want to tell, then divide it in pages. So far I’ve worked knowing the amount of pages beforehand, but I guess you could just fill pages until you’re done telling the story. The key here is that you have to think of pages because you need to know how they begin and end (eg. you don’t normally end a page in the middle of some action), and because the last page has to be full, you can’t finish halfway!

In this example, I wrote down the story and divided the scenes into the six pages I was going to use. This is also the time to design the characters, but I didn’t do it until after the thumbnails because I only discovered I could draw after I had finished them. What I did do was quick studies for the locations:

locations

Thumbnails

Once you have the story divided in pages, you need to design every page: decide the amount, shape and position of the panels, the action, the text, etc. This serves several different purposes:

  1. Confirms that you can tell the story the way you thought.
  2. Gives you a way to check the rhythm of the story and see if it works.
  3. Lets you play with the shape and size of the panels (in this case I went with a pretty conservative grid; the only exception is the title).
  4. Sets the more or less final text in each panel.
  5. Gives you a way to decide the art for each panel (composition, perspective, etc) before you spend a lot of time making the final art.

As this is the first time I worked with thumbnails, some things are not quite right: the text is sometimes quite different from the final version, some panels on the first page are quite different (I realised they didn’t work in the thumbnails and instead of reworking them I made the changes directly in the final version), and the art is completely different. This last bit is actually due to the fact that I originally planned to make this comic with stick figures, but after finishing the thumbnails I realised that I could draw better and decided to give it a go.

You can see all the thumbnails here:

squash1 squash2 squash3 squash4 squash5 squash6

Final comic

When you’re happy with the thumbnails, you’ll have a pretty good idea of how the comic is, and the only step left is to make the final art. I use a Wacom Bamboo drawing tablet and I don’t have high standards for the final result (as you’ll see *grin*), but for people making “real” comics the process is a bit more involved, as they need to do pencils first, then ink.

You can see the final result of my comic here:

sc1 sc2 sc3 sc4 sc5 sc6

You can compare each page between the thumbnail and the final result, for fun, to see how much it has changed. However, remember that the difference between thumbnails and final comic should not be that big! The only reason why the thumbnails are stick figures and the final comic it better is that I realised too late that I could draw better than stick figures.

In any case, I hope you enjoyed this post. As I said, if you’re interested in making comics but thought you couldn’t do it, go read “See What I Mean”.

Book summary: Coding Freedom

These are my notes for “Coding Freedom“, a sociology/anthropology book that analyses the free software community. You can download it for free from its website, or buy a paper version. These notes cover only the history of free software, which I found very interesting even if I basically knew it already.

1970-1984: The commodification of software

During the 1960s and part of the 1970s, most hardware was sold with software and there was no software patent or copyright protection. Programmers in university labs routinely read and modified the computer source code of software produced by others.

In 1976, just as companies began to assert copyrights over software, Gates wrote a letter to a group of hobbyists chastising them for, as he saw it, stealing his software: they had freely distributed copies of Gates’ BASIC interpreter at one of their meetings.

In the late 1970s and early 1980s the US software industries dominated internationally. Amid fears of losing ground to foreigners, US legislators launched an aggressive campaign to develop and fund the high-tech and knowledge economic sector and encountered little friction when accepting software patents in 1980.

1984-1991: Hacking and its discontents

In the late 1970s and the 1980s, corporations started to deny university-based hackers access to the source code to their corporate software, even if the hackers only intended to use it for personal or noncommercial use. This infuriated Richard Stallman, who became a “revenge programmer” (whole, fascinating story in p.68) and ultimately founded the Free Software Foundation in 1985 and then wrote the first draft of the General Public License in 1989. In 1984 he actually said “I am the last survivor of a dead culture. And I don’t really belong in the world anymore. And in some ways I feel like I ought to be dead”.

1991-1998: Silent Revolutions

Trade groups intensified their efforts to change intellectual property law largely through international treaties. They worked with law enforcement to strike against “pirates”, pursued civil court remedies against copyright infringers, launched moral education campaigns about the evils of piracy, and pushed aggressively for the inclusion of intellectual property provisions in the multilateral trade treaties of the 1990s. For example, through TRIPS, patents had to ultimately be open to all technological fields.

In the meantime, Linux would gain momentum in companies: managers would say they were not using Linux, but techies would say “yes… but don’t tell my boss”.

1998-2004: Triumph of open source and ominous DMCA

The term “open source” (less philosophical and more technical) was created and won, and the DMCA was passed, which criminalised all attempts to circumvent access control measures (ie. DRM), practically giving copyright owners technological control over digitized copyright material.

Misc final notes

For most developers, acceptance of free software rarely led to political opposition producers of proprietary software, but made them develop a critical eye toward practices such as abuse of intellectual property law and tendency to hide problems from costumers: “Free software encourages active participation. Coporate software encourages consumption”.

One of the most profound political effects of free software has been to weaken the hegemonic status of intellectual property law; copyright and patents now have company.

And that’s it. I hope you enjoy it. Go download the book if it sounds interesting or you want to learn more about hacker culture and free software.

Learning Clojure

I have always had a thing for functional programming. Not so much for functional languages maybe, but definitely for functional programming principles. I had learned a tiny bit of Lisp at the uni and have fond memories of reading “On Lisp” by Paul Graham, but I never really tried to learn any Lisp for real. Or, I tried to learn Common Lisp again by reading “Land of Lisp” but gave up very quickly. I have tried to learn other functional languages with varying degrees of success (ranging from “read a tutorial or two and got the general idea” to “solved a couple of exercises and/or write trivially small programs”), but for some reason none of them really stuck.

One of those times that I decided I would try to learn a new language, I tried Clojure. I had read some hype about it but remembered Common Lisp as annoying so I was sceptical. Although this is probably extremely unfair, and I don’t really have any experience with any Lisp that is not Common Lisp (and then again that was only a bit of uni stuff), I got this impression that Clojure had all the good bits of Lisp while avoiding a lot of stuff that really bothered me.

So, in case you have avoided Clojure because you (think you) hate Lisp, you should know that:

  • Clojure makes the syntax a bit easier to scan (because it uses other characters, like [] and {}, for some data structures) while keeping all the advantages of “code = data”.
  • Another way it which Clojure feels more modern is function names: let*, setf, car, cdr, and others I hated are not there. To be fair this is both subjective and might be exclusive of Common Lisp.
  • As it runs on the JVM, there are many, many things you can take for granted, like available libraries, and well-known, documented and relatively sane way to install new libraries and figure out what is available.
  • Leiningen is a really nice tool for “project management” (run the project, install dependencies, run tests, etc.), so don’t be afraid if you hate Maven/Ant, the authors of Leinigen did, too *grin*
  • Clojure really insists on using immutable data structures, and has some very, very cool implementation for all the basic data structures that allow immutability while having excellent performance (in a nutshell, different copies share all the common items). Of course you do have mutable versions of those data structures for special cases, but they’re rarely needed.
  • There is a thing called ClojureScript, which is a language very, very similar to Clojure (exactly the same for most stuff) that compiles to Javascript, so you can use Clojure for both the front- and back-end of web applications. This is actually one of the reasons that convinced me to try Clojure, although I haven’t really used ClojureScript yet.
  • My impression is that it has more IDEs to choose from that the average Lisp: apart from VIM and Emacs, you have Eclipse, Lighttable, and many others.

If you’re interested in learning Clojure, the book I used was Clojure Programming, which I found really nice and informative, and I totally recommend. Although I haven’t completely groked all the concepts yet because I haven’t had the chance to use them in real settings, I have a basic understanding of most Clojure stuff and I know I can go back to the book and re-read parts I need.

And while I haven’t really written anything big in Clojure yet, I have had some fun learning it making two (very) small projects:

  • cludoku, a simple sudoku solver made to learn more than anything.
  • clj-flickr-memories, a small utility that fetches pictures from Flickr and sends them via e-mail. The idea is that is picks photos that were taken several years ago, “on a day like this”.

I’m looking forward to using and learning more Clojure, and hopefully using it at work someday…

Personal groupware

Oh, wow. It has been a long while since I wrote anything on this blog. Hopefully I’ll get back in shape soon. This time I wanted to write about groupwares for personal use. As you may know, I had already written a personal wiki, and several weeks ago I started thinking that it would be cool to have my own place to keep my calendar and my contacts, and use exactly the same list in any e-mail/calendaring program I use, regardless of the device.

After looking around a bit, I chose SOGo. Firstly, because I managed to get it to work (I had tried and failed with Kolab first); secondly, because it seemed simple/small enough to be appropriate for personal use. In my case, I’m using the version that comes with Debian Wheezy (1.3), but I don’t think it will be very different to install in other environments.

Installing SOGo

The installation itself is kind of long, and although it’s documented, the installation and configuration guide doesn’t give a straightforward list of steps to install. Instead, you have to read it and understand how the whole system is put together. This post is a reminder for myself, as well as documentation for others that might want to install SOGo in their own servers.

The first step is to install the Debian packages “sogo”, “postgresql” and “apache2″. Then, copy /usr/share/doc/sogo/apache.conf into /etc/apache2/sites-available/, and tweak x-webobjects-server-{port,name,url}. Then, enable Apache modules “proxy”, “proxy_http”, “headers” and “rewrite” and enable the new site with the following commands:

# a2enmod proxy proxy_http headers rewrite
# a2ensite sogo
# /etc/init.d/apache restart

The next step is to configure PostgreSQL. First, add this line at the end of /etc/postgresql/9.1/main/pg_hba.conf (or the equivalent for your PostgreSQL version):

host sogo sogo 127.0.0.1/32 md5

Then create a PostgreSQL user “sogo” and a database “sogo” with the following commands (remember the password you set for the “sogo” user, you’ll need it later):

# createuser --encrypted --pwprompt sogo --no-superuser --no-createdb --no-createrole
# createdb -O sogo sogo

Then connect to the database with psql -U sogo -h 127.0.0.1 sogo and create a table “sogo_custom_auth” with this SQL:

CREATE TABLE sogo_custom_auth (
  c_uid varchar(40) CONSTRAINT firstkey PRIMARY KEY,
  c_name varchar(40) NOT NULL,
  c_password varchar(128) NOT NULL,
  c_cn varchar(128),
  mail varchar(80)
);

Then calculate the MD5 for whatever password you want for your user (eg. with echo -n 'MY PASSWORD' | md5sum -) and connect again to the database with psql, this time inserting the user in the database:

insert into sogo_custom_auth values ('myuser', 'myuser', '<PASSWORDMD5SUM>', 'User R. Name', 'myuser@mydomain.org');

Now you have to configure SOGo so that (1) it can connect to the database you just created, and (2) it looks for users in that database. You do (1) by editing /etc/sogo/sogo.conf to set the correct username and password for the PostgreSQL database; you do (2) by adding the following lines to your /etc/sogo/sogo.conf:

SOGoUserSources = (
  {
    type = sql;
    id = directory;
    viewURL = "postgresql://sogo:@127.0.0.1:5432/sogo/sogo_custom_auth";
    canAuthenticate = YES;
    isAddressBook = YES;
    userPasswordAlgorithm = md5;
  }
);

Finally you’ll have to restart the “sogo” service with /etc/init.d/sogo restart so it uses the updated configuration.

Importing contacts

It’s easy to import contacts if you have them in vCard format. Just login to SOGo (should be https://<YOURSERVER>/SOGo/), go to Address Book, right click on Personal Address Book and select “Import cards”.

If you want to import the contacts in your Google account, go to GMail, click on the “GMail” menu at the top left (just below the Google logo), and select “Contacts”. From there, you have a menu “More” with an “Export…” option. Make sure you select vCard format.

Clients

Of course, the whole point of setting all this up is making your e-mail/calendaring applications use this as a server. I think there are several formats/protocols SOGo can use, but WebDAV/CardDAV works out of the box without any special tweaking or plugins so I went for that. I have only tried contacts, mind you, but I imagine that calendar information should work, too. I haven’t tried having my e-mail in SOGo because I don’t care :-)

I have briefly tried with two different clients: Evolution running on Ubuntu Raring, and Android. Both seem to be able to get data from SOGo, but here are some things to note:

  • The WebDAV/CardDAV URL for the contacts should be something like: https://<YOURSERVER>/SOGo/dav/<YOURUSERNAME>/Contacts/personal/. The Android application seemed to have enough with https://<YOURSERVER>/SOGo/ or https://<YOURSERVER>/SOGo/dav/(can’t remember which one), though, so maybe it’s Evolution that can’t autodiscover the URL and needs the whole thing spelled out.
  • Evolution seems to have a problem with HTTPS CardDAV servers that don’t use port 443. If yours runs in a different port, make sure you make the WebDAV URLs available through port 443 (with a proxy or similar).
  • Certain contact editing operations seem to crash Ubuntu Raring’s version of Evolution. A newer version seemed to work fine on Fedora 15′s live CD and an older version seemed to work on some Debian I had around.
  • Android doesn’t seem to support CardDAV natively, but there’s a set of applications to add support for it. I have tried “CardDAV-Sync free beta” for contact synchronisation and at least it seems to be able to read the contacts and get updates. I have only tried the “read-only” mode of operation, I don’t know if the other one works.

In conclusion, this post should contain enough information to get you started installing SOGo on your own server and having some e-mail clients use it as a source for contacts. Feel free to report success/failure with other clients and platforms. Good luck!

Javascript for n00bs

Recently a friend asked me for an easy way to learn JavaScript. I can’t remember how I learned myself, but I do remember some things that were surprising coming from other languages, or that I had guessed wrong or took me a while to understand for whatever reason, despite not really being complicated at all.

As I wrote the list for her anyway, I figured it could be useful for other people, too, so here it goes, somewhat edited:

  • It’s object-oriented, but it doesn’t have classes (instead, it’s prototype-based). The Java-like syntax often makes you think it’s a normal object-oriented language, but it’s not.
  • What are called “objects” in Javascript are hashes, really. It just happens that the values for some of the keys are functions. Related: object.prop and object['prop'] are equivalent.
  • The for (x in obj) { ... } statement is strictly an object (not an array) thing. If you need to traverse an array with a “for” loop, you have to use the C-style form: for (var i = 0, len = obj.length; i &lt; len; i++) { ... }.
  • There are no methods in the sense of other programming languages. When you do object.blah(...) in JS, you’re simply calling the blah function with the “context” (ie. the value of the reserved word “this”) set. For example, you could do var f = obj.blah; f(...). That would (a) be perfectly legal, and (b) set “this” inside that function call to be undefined, not obj. The “call” function allows you to set that binding explicitly, like so: f.call(obj, ...).
  • This implies something that I find ugly: if you have two levels of functions, you need to save the value of the this of the outer function in some variable if you want to use it in the inner function. See example below:
  • JavaScript has functional language features: functions are first class citizens, and higher-order functions are possible and even common.
  • You should use the operators === and !== instead of == and != (the latter are too liberal with type casting).
  • You should get used to always using semicolon at the end. Although the interpreter adds them in most cases, in some other cases it might be a big surprise.
  • Also, JavaScript is full of small design problems and quirks. Learn them, learn how to avoid them, and you use tools like “jshint” or “jslint“. That way it’s much easier to enjoy the language :-)
  • Maybe I’m weird, but I have always found programming “inside” the browser to be awkward and clunky. To fool around with the language, you might want to use Node instead.

Example of two levels of functions:

// Imagine this function is a method
function foo(widgetList) {
    // Save the value of "this" for later
    var that = this;
    widgetList.forEach(function() {
        // Here, "this" points to widgetList. If we need
        // the object the "foo" method was called on, we
        // need to refer to "that", saved above
    }, widgetList);
}

Resources (that I haven’t read myself, but seem useful):

Book summary: See What I Mean (II)

This is the second half of my summary of “See What I Mean“, by Kevin Cheng. It covers from chapter 6 until the end. See the first half on this blog.

Laying out the comic

Once the script is ready, you sketch the comic storyboard to answers these questions:

  • Composition of each panel (where characters go). See example on p.108. Tips: rule of thirds, writing speech bubbles first to use space better, avoid intersecting lines in foreground and background.
  • Perspective (how the audience will look at the characters). Use and be aware of perspective and distance (where the camera is). For inspiration, have a look at Wally Wood’s “22 panels that always work”.
  • Flow & progression (change of locations, how time passes, …). What happens between panels should be obvious. Take care of small details like which hand is used, or the side of something.

Drawing and refining

Resources to make higher-quality art, faster:

  • Reference materials: tracing over stuff is easy, quick and gives good results (eg. photographs, incl. made by yourself for the purpose, or avatar generators like IMVU or XBox).
  • Templates: a couple available on the net, but tend to be limiting. Create your own templates?
  • Comic creation software: several, seem too complex and/or expensive.
  • Online creation tools: websites like bitstrips.com and pixton.com seem interesting.

Applying comics

Possible uses of comics:

  • Requirements/vision: documents don’t get read, and if they do, they’re ambiguous. Comics are easy to read and explaining requirements through real use-cases often works better.
  • Good start for projects/companies: comics help you validate your ideas before you build anything, or decide exactly what to build. In these cases, make the person read the comic on her own, then explain with her own words as she reads again. That way, misunderstandings are easier to spot. Also, make people say how it relates to them: if they or someone they know would use it.
  • Marketing materials. Explaining your product, or why it’s special, through comics.
  • Certain kinds of documentation.

It’s generally easier to get people to read comics than to read text descriptions of the same content.

Breaking Down the Barriers

When convincing bosses to approve the use of comics, there’s usually less resistance than what people think. That said, understand who you’re convincing and what arguments to use (eg. some designers think that comics take relatively little time compared to alternatives, or the evidence suggesting that words + pictures help in understanding and memory). Fidelity and polish in comics (and any other medium) needs to be higher for certain audiences, eg. bosses or corporate clients.

Useful templates and references

The appendix has ideas about how to show someone in front of a computer, interesting panels, gesture dictionary and a facial expression dictionary:

Facial expression dictionary

Book summary: See What I Mean (I)

Oh, boy. It’s been a while, hasn’t it? This is the first post of the year, and it will be about the first book I’ve finished, “See What I Mean” by Kevin Cheng (which, by the way, I got from O’Reilly’s Blogger Review Program). It’s a book about using comics “for work”, to communicate ideas like product concepts, user stories, and such, more effectively.

This post will cover about half the book, from chapters 2 to 5. These notes are much more useful if you have the book to refer to the pictures, but hey, this is mostly for me ;-)

Properties of comics

Basic vocabulary for the anatomy of comics:

Anatomy of a comic

Properties of comics:

  1. Communication: comics don’t need words, or can express a lot without them (p. 23). They’re universal!
  2. Imagination: characters with few features make more readers relate. This can be applied to UI mockups/sketches, too: people focus less on design if it’s abstract (p. 25,26).
  3. Expression: give interpretation to words (“I’m sorry”/”Thank you” examples with different facial expressions on p.27). When combining text and pictures, the sum is bigger than the parts.
  4. Time: comics can express time passing by using empty or repeated panels. Also, via words in “narration” and reference objects (like burning candles, clocks, or day/night).

Drawing 101

Drawing faces is easy! Eyebrows and mouth go a long way to express mood. Body language helps quite a bit, too, and it’s easy to represent. See examples of combinations of eyebrows and mouths on p.47, 48. In faces, eyes go in the middle, and dividing the bottom half in three gives bottom of nose and mouth. Also see http://www.howtodrawit.com for tips on how to draw different things.

Approx. proportions for a person are two heads for torso, 1 for hips/groin, and 3 for the legs. Body language basic guidelines: leaning forward shows interest, concentration or anger (depends on arm position and context; curling the spine works, too); arm position can tell a lot (lifting one or both, on chin, in front of body); head positions don’t change much, but facial expressions or where the person is looking, does. When drawing body language, try to imagine the situation and exaggerate it. It often helps to start with a stick figure, then add detail.

Steps to create a comic

There’s no single correct way to create a comic. One possible approach:

  1. What’s your comic about? Why you’re using comics, what to include, who’s the product and comic for. This chapter is about this step.
  2. Writing the story: create scripts in words, an outline, define characters, setting and dialogue.
  3. Laying out the comic: plan each panel, what to show and how much of it.
  4. Drawing/refining the comic.

What’s your comic about?

Don’t approach the question broadly and vaguely, break it down! Define goals (what to accomplish), length (3-8 panels encouraged; should fit on site homepage, a postcard or e-mail; if longer, consider physical prints), audience (expertise level, context), and representative use case (help your readers understand why they should care).

Writing the story

When writing a script, you can use a similar format as that of film scripts. Each panel’s needs four primary elements:

  1.  Setting (defined up front, usually in bold). It can be time of day, location, or maybe what happens in the background. It depends heavily on the audience. The first panel can help with the setting (“establishing shot”). There are different graphical ways to convey a setting: the description of it describes a concrete way (eg. exterior of coffee shop vs. interior of coffee shop vs. close-up of coffee cup being served).
  2. Characters (all caps, bold). There are several types: target audience, people who interfact with them, and objects/locations that play a significant role (eg. the solution). Target audience is typically based on personas, go make them if you don’t have them already.
  3. Dialogue (regular font). It’s defined by more than the text itself: fonts, sizes, colours, bubble shapes or the split into different bubbles are very important, too! The text can be hard to get right: make it fit the character, keep it realistic (avoid marketing jargon and overly enthusiastic conversation). Captions can communicate time, setting, action, and even dialogue, but don’t add unnecessary information in them, and always try to speak from the character’s voice.
  4. Actions (usually italics). It’s what characters do, depicted in the panel art.

How to tell a story: remove all unnecessary. You can combine several points in a single panel. Show, don’t tell. See examples on p.98-100.

And that’s it for today. In a few days I’ll publish the rest of the summary.

Writing music, printing .gpx files

UPDATE 2012-10-27: I have updated the .gpx viewer to recognise silences! Download the updated version.

Note: if you’re only interested in printing .gpx files, download guitarpro-printer.zip and follow the instructions in the README.txt file.

I have been playing with my last band for over half a year now. From the beginning the idea was to write and play our own material, but actually we had been mostly doing song covers. After some time practising and after having our first gig, we decided to start focusing more on writing our own songs. That’s something I had never done, so it sounded intriguing, challenging and a bit scary (as I essentially don’t know any music theory, and I don’t even own a guitar or keyboard, it seemed extra difficult for me to come up with ideas for new songs). So I decided to try it out, and that meant looking for a way to try it out ideas and record them.

I tried many different programs both for Linux and for Android (I even tried a couple of Windows programs under emulation, but they seemed terribly complex), but nothing was really satisfactory. After searching a lot, I found Guitar Pro for Android (a tablature editor). It wasn’t really what I was thinking about at first, but I found that it was actually the best for my needs: thinking in terms of tabs is easier for me, as I don’t really know music but I have played a bit of guitar. Guitar Pro for Android is supposed to be mostly a tab viewer, but it does have a small feature for “notes”. The idea is that you’re on the bus or whatever, and come up with some musical idea: in that case, Guitar Pro allows you to quickly write it down. As you can listen to what you’re writing, I don’t need an actual guitar/bass to check if what I’m writing really sounds like I think.

Guitar Pro for Android works fairly well for my needs, but something really bugged me: you can only export the music you have written to the .gpx format, which didn’t seem supported by any open source program I knew of. That really pissed me off because it looked like I would be forced to buy Guitar Pro for Linux in order to print the music I had written (I wanted to do so in order to distribute it to my bandmates). After searching the net for a while I found the excellent alphaTab library, but it seemed to not recognise many of the parts I had written, which was a disappointment. See below for the nerdy details, but long story short I improved slightly alphaTab to support Guitar Pro mobile’s .gpx files so now I can print all the music I write, w00t! You can download a little Guitar Pro file viewer/printer I wrote using alphaTab. It’s basically a webpage that can show Guitar Pro files, see the README.txt for details.

Now on to the technical details. You can skip the rest of the blog post if you’re not interested ;-) alphaTab is an open source library that can read several Guitar Pro formats. It can play them, render them in the browser, and do other things. It’s written in a language called Haxe, which compiles to, among others, Javascript. If you download the alphaTab distribution you’ll get a Javascript version of the software that you can use directly in your browser, which is really cool and already does a bunch of stuff, but there were two changes I wanted to do: fix the bug that made it not understand most of the files Guitar Pro mobile produced, and add an option to upload files from the browser (instead, the example programs read tabs directly from a path relative to the programs).

For the first, I debugged a bit and quickly realised that the problem was that alphaTab was being too strict: Guitar Pro mobile was producing some “empty” notes and beats, and that made alphaTab consider the file corrupt and not show it at all. Adding some code to ignore those empty notes seemed enough to make alphaTab render the file. I filed bug #31 on GitHub and added the ugly patch I made :-)

For the second, as the alphaTab API needed a URL to load the tablature file, I had to learn a bit more about the Javascript File API and be a bit creative, replacing the file loader in alphaTab with something that would load the local file using the FileReader object, as you can see here:

function handleFileSelect(evt) {
  // Fake the getLoader function so make it support data
  // URIs: apparently jQuery can't make an Ajax request to
  // a data URI so this was the best I could think of.
  alphatab.platform.PlatformFactory.getLoader = function() {
    return {
      loadBinary: function(method, file, success, error) {
        var reader = new FileReader();
        reader.onload = function(evt) {
          var r = new alphatab.platform.BinaryReader();
          r.initialize(evt.target.result);
          success(r);
        };
        reader.readAsBinaryString(file);
      }
    };
  };
  document.getElementById('files').style.display = 'none';
  $('div.alphaTab').alphaTab({file: evt.target.files[0]});
}

With these two changes, alphaTab finally does what I need, so I don’t need to buy Guitar Pro for Linux just to print tabs. I might buy it anyway for other reasons, but it’s nice to not be forced to do so ;-)

I hope this code and small program is useful to someone. If not, at least I have solved a pretty annoying problem for myself.

Exceptions in Node

Whoa, boy. It seems I haven’t written for a good while now. Let’s fix that. One of the things I had in my list of possible posts was my experiments (and frustrations) with Javascript exception classes under Node, so here we go:

I needed to have several exception classes in Javascript (concretely, for RoboHydra, which works under Node). My first attempt looked something like this:

function NaiveException(name, message) {
 Error.call(this, message);
 this.name = name;
 this.message = message;
}
NaiveException.prototype = new Error();

That seemed to work well, except that the stacktrace generated by such a class doesn’t contain the correct name or the message (notice how I even try to set the message after inheriting from Error, to no avail). My second-ish attempt was to try and cheat in the constructor, and not inherit but return the Error object instead:

function ReturnErrorException(name, message) {
    var e = Error.call(this, message);
    e.name = name;
    return e;
}
ReturnErrorException.prototype = new Error();

That did fix the stacktrace problem, but breaks instanceof as the object will be of class Error, not ReturnErrorException. That was kind of a big deal for me, so I kept trying different things until I arrived at this monster:

function WeirdButWorksException(name, message) {
    var e = new Error(message);
    e.name = name;
    this.stack = e.stack;
    this.name = name;
    this.message = message;
}
WeirdButWorksException.prototype = new Error();

This is the only code that seems to do what I want (except that the stack trace is slightly wrong, as it contains an extra line that shouldn’t be there). I tried in both Node 0.6 and Node 0.8 and the behaviour seems to be the same in both. In case you’re interested, here’s my testing code showing the behaviour of the different approaches:

// NO WORKY (breaks stacktrace)
function NaiveException(name, message) {
    Error.call(this, message);
    this.name = name;
    this.message = message;
}
NaiveException.prototype = new Error();
 
// NO WORKY (breaks instanceof; also stacktrace w/ 2 extra lines)
function ReturnErrorException(name, message) {
    var e = Error.call(this, message);
    e.name = name;
    return e;
}
ReturnErrorException.prototype = new Error();
 
// WORKS (but has extra stacktrace line)
function WeirdButWorksException(name, message) {
    var e = new Error(message);
    e.name = name;
    this.stack = e.stack;
    this.name = name;
    this.message = message;
}
WeirdButWorksException.prototype = new Error();
 
[NaiveException,
 ReturnErrorException,
 WeirdButWorksException].forEach(function(eClass) {
    var e = new eClass('foo', 'bar');
 
    console.log(e.stack);
    console.log(e instanceof eClass);
    console.log(e instanceof Error);
});

It feels really strange to have to do this to get more or less proper exceptions under Node, so I wonder if I’m doing anything wrong. Any tips, pointers or ideas welcome!