CSS3, jQuery(), and musicology: Another “circle” for understanding Western notes….

May 13, 2011

On my personal page, I have an experiment in CSS and jQuery and musicology: The page represents the default key of C Major, using a clock-like representation of the notes of the scale. C – the root, or I degree of the scale – is represented at “noon”, and each note follows 1 or 2 “hours” later depending on the number of semi-tones separating the notes.

Associated with the IV and vii degrees (Fa and Ti) are functions to change key: In any key, sharpening IV/Fa moves the key forward by a fifth, e.g., from C Major to G Major. Likewise, flattening vii/Ti moves the key backward by a fifth, e.g., from C Major to F Major. (Minor keys are always the vi degree of the major scale, i.e., the La note, e.g., A minor in the case of C Major… …and that’s all we need to know about minor keys for now.)

The idea of the circle is to represent visually what happens in any key: The major chords are always in the 12 o’clock, 5 o’clock, and 7 o’clock positions, the minors in 2, 4, and 9, and the diminished in 11. Always. That’s kind of cool.

The idea of the clock comes from the fact that we use a 12 hour clock and there are 12 semi-tones in the Western scale. Isn’t that conveeeenient!

The CSS part of the experiment is using CSS3 to draw the circle and position the notes. That part works fine. But the associated flatten/sharpen functions aren’t getting placed properly, and even when they are, they don’t work as expected: Clicking the underlined word is supposed to move the key forward or backward.

For some reason, this only works in the Linear version – below the circle is an underlined function to switch from a circular view to a linear view and everything works fine in the linear view: One can switch to linear, change the key, then switch back to circular to see where the notes now live. Fixing this is problem #1.

The Javascript/jQuery experiment is doing all the heavy lifting (changing keys, sharpening/flattening notes, etc.) from within Javascript, mostly using jQuery(). This includes switching from Linear to Circular view, which is done by toggling the CSS file in use, and storing the current CSS type – line or circle – in the class of the div that is used to toggle the CSS. That’s kind of cool.

There are a lot of inefficiencies in the Javascript. For example, there is a lot of DOM access and many DOM updates, and each update will cause a page reflow. This isn’t a big problem for such a small page, nor is it a problem on a powerful device, but on a larger, more complex page or on a mobile device this might be unacceptable.

Another problem is that there may or may not be a memory leak in the use of the temporary newKey object in some of the Javascript. Again, not a huge concern in a small page that is likely shortlived, but in a long-lived app on a mobile device, this might be problematic. If this problem exists, it is because of my still having a “C like” concept of scope – lexical scope – and not having adjusted to how scoping is different in languages like perl and Javascript, which use dynamic scope. So I may be creating stack objects and leaving them orphaned.

One note about the use of objects Vs arrays: I’m using objects instead of arrays because it was simply easier to declare and define them, e.g., the natural notes in C Major object, but this does lead to some awkwardisms:

  • When a new object is created, I have to iterate through the existing object and initialize each element of the new object, since there is no “copy object” function/method, at least not as far as I can tell. (Setting “newKey = oldKey;” just makes newKey a reference to oldKey, meaning changes to newKey affect oldKey, not what I wanted. See comments above re orphaning.)
  • No slice() method for making the copy/initialize operation simpler. A lot of other arrayisms that might have been handy are also missing (but maybe this forced to me sort out presentation and content a little more clearly).

What’s next? Well….

  • It would be nice to get the accidental functions working in the circular view, but this might be an FF 3.6 thing (I don’t have FF 4, so I’ve not tried it yet to see if it does the CSS3 circle thing any better (my fave extensions aren’t available under FF 4 – yet – and I don’t like the change in status bar, so I’m sticking with 3.6 and the Meerkat). Next step is to try this under Safari and some mobile devices and see if it works there. If so, FF bug (maybe); if not, bug in my knowledge.
  • A definite bug in my knowledge is CSS positioning – it’s still quite mysterious to me, which is why the accidental function labels are not where there should be in the circular view. (My first attempt had them as child div of the IV and vii degree divs, which worked great, but that made updating the notes difficult and made hiding them after -7/+7 difficult (and also mixed function content with real content and broke the presentation/content barrier, sort of, I think). I might be able to play with $().empty(), $().append(), and $().replace() some more to do this, e.g., by having the labels as child divs and replacing only the sibling content, but that is more advanced DOM walking/updating than I know how to do yet. Maybe later.)
  • (If I were to figure out that last bit, I might add degree labels to the notes, e.g., “I: C”, especially in the linear view, and maybe even have the degree outside the circle in circular view. Cool idea. No idea how to get there yet.)
  • The two CSS files have overlap, which means maintenance headaches, having to change things in two places. Having three files (common, line, circle) would be more elegant, and perhaps simpler to maintain, but changing this now would violate the IIABDFI principle. I violated said principle two weekends ago, and spent the next week restoring my main laptop to a functional state. I keep saying I don’t believe in patching working systems – not practicing what I preach really, really hurt. But at least I got to see how ugly the Narwhal is. Sigh. Happy to be back with the Meerkat, thank you.
  • It would be nice to animate the transition, so that notes slide clockwise or counterclockwise, with the accidentals appearing/disappearing appropriately. But this would likely mean abandoning the use of CSS3 to draw the circle. I think. Unless I played games with incrementing the rotation angle for the degrees, which would then require resettig the degrees once they’d hit their new positions. Ugh.
  • I’m fixing the degrees, i.e., I == noon, ii == 2, iii == 4, etc., and moving the notes, but another way to draw the circle would be to use the notes as id for their elements instead of degree, then use something like the animation described above to move things around. I think that’s kind of nasty, as it seems to be break good practice associated with separating presentation and content: Right now, the “content” is the set of notes, while degrees are used to control how they are presented (by fixing the location of the degree, which makes sense, because degree is fixed), and degree is also used as the key in the note hashes (again, this makes sense because degree is fixed and notes are variable). But structuring based on notes might make animation easier. I might try it just to learn something.
  • Testing on other browsers (Safari, iDevices, Android). Forget about IE, I fully expect IE CSS3 shog of epic proportions.
  • Counting accidentals then hiding the appropriate function feels like a kludge, but I cannot think of more elegant way of doing it.
  • Understanding how jQuery scope works: It took a while for me to get functions ordered and nested appropriately within $().ready() so that I could call showKey() to do the display work, and I still don’t fully get that. More experiments will help.

Give credit where credit is due. I was inspired to do this after seeing the CSS3 clock created by Keran McKenzie, so props to him. Thanks!

The jQuery() team deserve massive praise for their work (and not just praise). The following pages were helpful in figuring out how to do specific bits:

A cool trick: add blog headlines to any page using MagpieRSS, PHP, and SSI

August 2, 2009

I wanted headlines from my blogs to appear on my personal page. And I didn’t want to do a lot of work. Solution?

MagpieRSS to get the headlines, server-side includes to invoke the PHP. First, SSI and PHP.

I’m running apache, so getting SSI required:

a2enmod include
/etc/init.d/apache2 reload

That enables SSI in general.

Next, I added “+Includes” to the appropriate Options line in the sites-enabled file, and added the “XbitHack On” directive. I used XbitHack as a simpler way of enabling SSI instead of renaming files or mapping extensions.

Finally, I added the following code to the personal page (index.html):

<p><!--#include virtual="edgeblog.php" -->

and made index.html executable,

chmod +x index.html

The file edgeblog.php does the not-so-heavy-lifting:

<?php

$path = '/usr/share/php/magpierss';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);

include( 'rss_fetch.inc');

$url = 'http://edgekeep.wordpress.com/feed/';

$rss = fetch_rss($url);

foreach ($rss->items as $item ) {
 $title = $item[title];
 $url   = $item[link];
 echo "<a href=$url>$title</a></li><br>
";
}
?>

Installing and using MagpieRSS wasn’t as straightforward as I’d hoped. For whatever reason, I could not install it using apt-get directly, so here are the commands in a nutshell, no explanations provided:

wget http://mirrors.kernel.org/ubuntu/pool/universe/m/magpierss/magpierss_0.72-4_all.deb
apt-get install libphp-snoopy
dpkg -i magpierss_0.72-4_all.deb

You’ll notice that edgeblog.php explicitly adds the magpierss directory to the PHP include path. I don’t know if this is strictly necessary, but I could not (quickly) figure any other way to have my PHP installation notice the existence of Magpie.

In the end, this all required a couple of hours (tops!) research and a couple of minutes execution. Very slick. Probably about the same time as composing this post. :->

An epiphany! Freemind+GTD!

July 17, 2009

I’d heard of this GTD thing, and it seemed to have its strengths, but it also seemed to be just more lists and bits of paper to create and keep up-to-date. I have the same problem with all such things: how do you manage the inevitable intra-relationships (between GTD items) and inter-relationships (between GTD items and the information required to complete them, e.g., contact information in your address book)?

I’d heard of mind-maps, and seen some pretty amazing ones (yes, Leah, I am referring to the one you had on your whiteboard years ago – wow), but I’d not used them extensively – I’d scratch them on paper, then run into the same sorts of limits as GTD.

Despite these known difficulties, today I decided I absolutely needed a mindmap for something fairly complex I’m working on. I wanted a flexible piece of software that I could get started with fairly easily under Linux. It didn’t take long to find freemind, labyrinth, and a few other things.

And along the way I found this about getting things done with freemind! Wow! Be warned:

  1. The image quality is a little dicey, especially full screen – it’s tough to read the labels, and
  2. The site is, um, experiencing technical difficulties just now. You can get the presentation directly from Youtube.

With any luck, the site will be back real soon now  – it died whilst I was trying to post my comments on the presentation. Getting them posted was the motivation for this blog post, so here they are:

Thank you so much for creating this presentation and making it available on-line – like you, I had an epiphany while watching.

I’m new to the concept of mind-mapping (raised and trained on paper lists, which were almost always out of date as soon as they were written). While watching this integration of mind-mapping and GTD I was struck by one very powerful thought: “That’s how I keep things in my head! That’s how I organize things mentally! And my tools just don’t match what’s in my mind!”

Gotta go, I have a mind-map to create!

YMMV, IANAPMM, but this looks good!

Warning: If you are an Ubuntu user (or user of any other Debian-based distro), the current version of freemind available does not include the “attributes” feature mentioned in the video. If you really want that version, you need to take a few steps to get it – and you need to be comfortable working with Synaptic or with command-line package management. If enough people ask, I’ll post the instructions – but I hesitate to do so because they require:

  1. Adding an untrusted repository;
  2. Running quite a bit of beta code; and
  3. Downgrading and pinning a particular library to the version in the untrusted repository.

If these things make you nervous, best bet is to use the existing version and wait for the upgrade to hit the mainstream. If you’re OK with untrusted repos, beta code, and pins, leave a comment indicating that you are among the few, the proud, the perpetually beta-ready, and that you accept all risks knowingly and unreservedly, and I’ll add the instructions.

Defining moments – Marked by Achmed, part 1

April 29, 2009

All families have their expressions, household memes that no else would understand. Some are odd, some peculiar, some downright weird. Odder, more peculiar and weirder still are where they come from – and how they endure.

Two of ours are “Avec, avec!” and “Le qué pouf!” The first might not seem so unusual, given the linguistic nature of our family: One fluently bilingual francophone, one francoanglophone (two mother tongues), and one fluently bilingual anglophone, all of whom also speak bits and pieces of up to half a dozen languages more.

So “Avec, avec!” (literally, “With, with!”) might seem normal. Except that it is meaningless. “Avec, avec” has as much meaning in French as “with, with” in English. No literal meaning, no metaphoric meaning, no idiomatic meaning. None. “Le qué pouf” is even odder, since not only does it lack meaning of any kind, it isn’t even remotely grammatically sensible. Leaving aside the fact qué isn’t a French word, the closest literal translation would be “The what puff”. Hmm….

If you recognize these at all, you were raised on Pépé le Pew. This is more or less Warner Brothers mock French – mock-fake, not mock-mocking: My blatant assertion is that they loved France, French, and the French, likely as a result of some of their more pleasant experiences in and around City of Lights ’round about WW2. No freedom fries for the WB.

And yes, we – well, two of us – are big Bugs fans. “We are the boys in the chorus”, “Hello my baby”, and “Quit steamin’ up my tail” are also common currency. But they don’t have the meaning, the power, the visceral oomph of “Avec, avec” and “Le qué pouf”.

For that, we need a side trip to Wisconsin via the Carribean.

Several years ago we took our first and only cruise. We learned a few things. First, we’re not cruise people – too regimented, too planned, too organized. We like to make sure we have places to stay then wing it. Much more interesting getting inland, eating with locals, riding in frightening taxis.

Second, who you dine with can make or break your cruise. We were lucky. Our family of three was seated with a family of five with whom we got along fabulously. So well, in fact, we went to visit them in Wisconsin a few months later. (Dinners are set: You get a table, a seating time, and that’s that. Perhaps you can change if unhappy with your arrangements, but we never even considered inquiring, so well did we get along. Breakfasts are general admission, sit where you can with whomever. And some of the whomevers were pretty dim. Call me an elitist pig, but being able to switch languages made for pleasant isolation.)

Third, politics and religion don’t matter squat if there is a heart connection. Let’s just say that when we got to Wisconsin and I noticed the Bush-Cheney sticker on the back of John’s brand-new black Suburban, I whispered to Sylvie “don’t talk about the election!” It wouldn’t have mattered, I’m sure. We just got along.

So how do we get from Wisconsin to mock France? John’s Dad didn’t speak a lick of French but “Avec, avec” and “Le qué pouf” were two of his expressions. And John’s telling of how that came to be and how funny it was that they now had real French-speaking friends so marked us that they entered our vocabulary. (It’s John story to tell, so no more soup for you.)

These expressions mean much more to us than Pépé, as adorable as he may be. Heck, Sylvie gave me a Pépé doll a while ago that says “You are the corned beef to me, I am ze cabbage to you” and other expressions when you squeeze his little paw. Adorable.

But not enough to account for the popularity, the meaning of “Avec, avec” and “Le qué pouf”.

As funny as the frog is, “Hello my baby” are just words. But “Avec, avec” is history. Its meaninglessness is sometimes the most meaningful possible response. Sort of a warm fuzzy combination of “duh” and “whatever”. Or sometimes “hurry up you and I both know I don’t need to tell you that because you are hurrying but you’re stressing me out and I know that you know but we’re going to be late…  Avec, avec!”

That’s a lot of weight for meaningless words. With them come stories and shared experiences and happiness and memories one of the most pleasant vacations we’ve ever had, one that just happened to involve a cruise but wasn’t because of the cruise. Weightier still.

To “Avec, avec” and “Le qué pouf” we now add “I kiiilll you”, “Holy Crap”, and “You racist bastard”.

This trip isn’t quite as interesting. In fact, you can take a good part of it.

Watch this.

Then watch this.

Then watch this space for part 2.

Wanted – A good, inexpensive Canadian ISP

April 28, 2009

Is it too much to ask? I want to put up a few pages under specific domain names (one or two business ideas, one or two open source projects, and yes, a vanity page). In all likelihood, technical requirements will be modest: limited disk space, low transfer rates, etc.

Pretty much all ISPs meet these requirements, and pretty much all seem to offer all of the add-on services I can reasonably foresee wanting: blog and wiki software, shopping carts, etc., etc.

However! I do have some specific requirements that, taken together, no one seems to meet. For example….

Server location: I want a Canadian ISP with servers located in Canada. The otherwise attactive Toronto-based Fused Networks locates their servers in Chicago.

Price: A few dollars a month and low-cost domain registration. The otherwise attractice Teksavvy, based in Richmond Hill, charges $39.95/year for domains!

Payment: Must be in Canadian dollars. Fused Networks, for examples, appears to let me pay only in USD (I have a call into them about this.)

Slickatude/growthability/changedness: OK, this one’s a little more qualitative and visceral-like. Things may change. One or more sites may take off, my technical requirements may change, etc. I’d like the happy fuzzy feeling that whomever I choose will be able to meet my unknown future needs.

How do the players I know about stack up on slickatude?

Teksavvy’s web site is so bare bones that I cannot help but think that a) their real target market is DSL service (no complaints there, I’ve been a happy customer for years and they resolve technical and billing problems ASAP) and b) their hosting caters more to those wanting bare metal. So no real slickatude at all.

On the plus side, I’m pretty sure that Teksavvy is never going to become a boxstore ISP: So big – or so bad – that if you don’t fit into one of their predefined boxes they don’t have a place for you. But the $39.95/year for domain registrations leaves a bad taste. Do I get $29.95/year of additional value, what with domains being in the $10 range elsewhere?

Host Papa starts off looking slick – ooo, videos – but when you poke a little deeper, well, technical content is lacking in the knowledge base, their reasons for not permitting SSH don’t wash, and the videos are at the “See Jane show Dick how to move a mouse” level, so while they have visual slickness, I get the impression that the man behind the curtain is all flash and smoke, no real wizardry. But $10 domains and $5/month hosting is attractive.

Fused Networks looks very slick: Strong technical details, good marketing sizzle. They seem to know what they are about. Too bad about the servers in Chicago. And the $10 domains and monthly hosting charges are in USD and I’d rather not pay the exchange rate.

iWeb, based in Montreal, is somewhere in the middle. They seem to have sizzle and depth. My big concern is that they seem to be on their way to becoming a boxstore. I have no problems with companies growing, but growth has to make business sense and make sense to customers. If “getting big” is a primary objective, then customer service will likely fall aside.

Then there’s my current business provider. My site was with Magma until they sold themselves to Primus. Primus is definitely a boxstore. Prices are a little steep ($10/month plus $240/year for my current package). And they are an American company, so I don’t think I have any real guarantee as to where my server lives.

Any suggestions? Are you using a Canadian ISP and getting good value? That is, are you satisfied with service and price? And, most importantly, do they have slickatude? Let me know!

(Maybe I really should consider rolling my own. Then I just need a recommendation for a good low-cost registrar that either allows me to manage DNS or that supports DynDNS reliably. Any suggestions there?)


Follow

Get every new post delivered to your Inbox.