My interactive presentation on digital signal processing (previous post with video) is now available on the web, at visual-dsp.switchb.org! More details, source code, etc. at the site.

(P.S. I'll also be at the next meetup, which is tomorrow, January 21, but I don’t have another talk planned. (Why yes, I did procrastinate getting this site set up until a convenient semi-deadline.))

I have really failed to get around to blogging what I've been doing lately, which is all software-defined radio. Let's start fixing that, in reverse order.

Yesterday, I went to a Bay Area SDR meetup, “Cyberspectrum” organized by Balint Seeber and gave a presentation of visual representations of digital signals and DSP operations. It was very well received. This video is a recording of the entire event, with my talk starting at 12:30.

(I could say some meta-commentary about how I haven't been blogging much and I've made a resolution to get back to it and it'll be good for me and so on, but I think I've done that too many times already, so let's get right to the actual thing...)

When I wrote Cubes (a browser-based “Minecraft-like”), one of the components I built was a facility for key-bindings — that is, allowing the user to choose which keys (or mouse buttons, or gamepad buttons) to assign to which functions (move left, fly up, place block, etc.) and then generically handling calling the right functions when the event occurs.

Now, I want to use that in some other programs. But in order for it to exist as a separate library, it needs a name. I have failed to think of any good ones for months. Suggestions wanted.

Preferably, the name should hint at that it supports the gamepad API as well as keyboard and mouse. It should not end in “.js” because cliche. Also for reference, the other library that arose out of Cubes development I named Measviz (which I chose as a portmanteau and for having almost zero existing usage according to web searches).

(The working draft name is web-input-mapper, which is fairly descriptive but also thoroughly clunky.)

I really haven't been posting very much, have I? It's mostly the job occupying most of my “creative energy”, but I've also been doing a little bit of this and that and not ever finishing something to the point of feeling like writing it up.

On the programming-projects front, I'm attempting to extract two reusable libraries from Cubes for the benefit of other web-based games.

  • Measviz takes performance-measurement data (frames per second and whatever else you want) and presents (in HTML) a compact widget with graphs; my excuse for not announcing it is that the API needs revision, and I haven't thought of a good toy example to put in the documentation-and-demo page I'm writing, but if you're willing to deal with later upgrades it's ready to use now.
  • The other library, currently in need of a good name, is a generalized keybinding library (generalized in that it also handles gamepads/joysticks, which are completely different). You define the commands in your application, and it handles feeding events into them. Commands can be polled, or you can receive callbacks on press and release, with optional independent autorepeat. It's currently in need of a name, and also of API cleanup.

I've been making some sketches towards a redesign of E (list archive pointer: starting here), basically to take into account everything we've learned over the years without being constrained by compatibility, but it hasn't gotten very far, partly because language syntax is hard — all options are bad. (The current E syntax is pretty good for usability, but it has some particularly verbose/sea-of-punctuation corner cases, and I'd also like to see a simpler syntax, with more facilities moved into code libraries.)

The draft-standard Gamepad API allows JavaScript in the browser to obtain input from connected gamepad/joystick devices. This is of course useful for games, so I have worked on adding support for it to Cubes.

This (about) is the only Gamepad API demo that I found that worked with arbitrary gamepads (or rather, the junk one I had around) rather than ignoring or crashing on anything that wasn't a known-to-it devices such as a PS3 or Xbox controller. (It's part of a game framework called Construct 2, but I haven't investigated that further.) It was critical to my early setup in making sure that I had a compatible gamepad and browser configuration.

(There's a reason for libraries having information about specific devices — the Gamepad API just gives you a list of inputs and doesn't tell you what the buttons should be called in the user interface — and these days you're almost expected to have pictures of the buttons, too. But there's no reason not to have a fallback, too. Incidentally, the USB HID protocol which most gamepads use is capable of including some information about the layout/function of buttons, but this information is often incorrect and the Gamepad API does not expose it.)

In order to integrate gamepad support into Chrome, I used Toji's Game Shim library, a very nice lightweight library which only adapts browser-provided interfaces to the current draft standards so that you can use the Gamepad API, as well as requestAnimationFrame, fullscreen, and pointer lock, without making your code full of conditionals or browser-specific prefixes.

Run your program on a platform slow enough that you

  1. care, and
  2. can feel where the problems are.

(Something — I assume a Chrome update — caused Cubes to run more slowly. Over fifteen seconds of startup time is just not fun for debugging, so I went looking for problems. Unfortunately, it wasn't anything straightforwardly bad, but the heaviest thing in the profile was the color-picking while constructing the default blockset, so I optimized that and got the startup down to about six seconds. Still slower than it really ought to be.)

Cubes update

Friday, March 9th, 2012 21:46

Some new features in Cubes:

  • An automated test suite. It’s hardly complete coverage, but at least it exists and so can grow. (I ended up going with Jasmine for in-browser testing. I’m not a big fan of the Englishy syntax, but it does the job reasonably well and has niceties like rerunning individual tests and adequate support for asynchronous tests.)
  • Precise collision against rotated blocks: you can now walk up the slope of those funky pyramid blocks, and so on. Stairs, anyone?
  • Performance monitoring widget with fancy graphs. (If you click the “[-]” to hide it, then it won’t waste CPU time updating itself, either.)

Today I learned that there is a standard-DOM alternative to the convenient IEism element.innerText (a close relative of element.innerHTML): element.textContent.

It is slightly different, according to MDN: .innerText returns the visible text (omitting scripts and CSS-hidden text), whereas .textContent returns everything, more like walking the document tree.

(This information crossed my awareness while working on Caja, but I didn't recognize it as something I could actually make use of until now.)

I’ve uploaded almost all of my published Git repositories (previously hosted on a git-only server on on switchb.org, which is down at the moment) to my account on GitHub. Please update your remote URLs if you have any git clones.

The motivation for this change is simply that GitHub offers better visibility — an automatic web presence for each project, including viewing repository contents. I am not intending to depend on GitHub’s continued existence, of course; I still have local copies of each project, and additionally I plan to arrange so switchb.org automatically mirrors my GitHub repositories.

What I've just uploaded to GitHub also includes a project which I have not previously mentioned, timeline-ui:

A user interface experiment. Multiple types of time-series data, variously static/interactive, historical/future, etc. are displayed in a single view. (This was an idea I had floating around and which I used in 2010 for a class project; there is a lot more that could be done with it.) Written in Java.

I was going to write more about the concept, but I never got around to it; this will have to do.

List of projects just moved to GitHub:

“Tile Game” was a game I wrote in the spring of 2010 as my final project for CI272 Visual Basic at MVCC. It was written in, of course, Visual Basic. I have just finished porting it to JavaScript and you can play it online.

I've written a new topic index page for my site: Games, simulations, and animations. Except for the note about Tile Game, everything on it is something I've already published.

Condensed list of the contents: Tile Game, Fire Worms, Mouse-maze, 15-puzzle, screen savers, Varychase, Linkage, Bouncyworm, Brownian Tree, pendulum animation.

Varychase is a graphics toy I just published. Runs in the browser; wave your mouse around and it makes curly patterns.

I originally wrote the option-less version May 29, 2010; yesterday I finally got around to adding a bunch of stuff, polishing the presentation, and publishing it.

It uses <canvas> for the optional line-drawing (I should compare the performance to using SVG instead, as well as also putting the dots in the canvas), and a few miscellaneous HTML5/CSS3 features for optional refinements. I've tested in Safari, Chrome, and Firefox on Mac.

A data: URL directly contains its content; for example, data:text/plain,Hello%20World!. The main usefulness of this is that you can do things like including images inline in a document. But you can also use it to create 'anonymous' HTML documents, where any link to them or bookmark contains the entire document.

I originally did this in 2006 when I was in need of a URL-encoding tool and did not have one to hand; so I wrote out:

data:text/html,<form action="data:text/plain,"><input id=r>

Properly encoded, that's:

data:text/html,%3Cform%20action=%22data:text/plain,%22%3E%3Cinput%20name=r%3E

This produces a form with a single field which, when submitted, will generate a data URL for a plain text document containing “?r=” and then the text; the URL, then, will contain the entered text URL-encoded after the “?r=”.

Of course, that's a horrible kludge and JavaScript has an encodeURI function...

See my site for the rest of that thought and more examples. (I can't include any actual data URLs in this post because LiveJournal doesn't permit them, for necessary but unfortunate reasons — the origin, in the sense of same-origin policy, of a data URL is the origin of the page containing it.)

I just wrote my first use of that <canvas> thing that everyone's talking about. (If you don't know, this is part of the WHATWG/HTML5 general vicinity of features: an element which creates a bitmap pixmap image that can be drawn on by JavaScript.)

Since LJ doesn't let me embed JavaScript or iframes (a restriction which I'm only just noticing...) I'll have to provide only a link (but your CPU meters will thank me for that):

Brownian Tree

(This is also part of a personal goal to learn more about Modern Web Applications technologies: “Ajax”, jQuery, web frameworks, etc. I used to (a) not have a personal server, and (b) tend to “All web content must be accessible to non-JS and pure-text users” — but I’ve come to realize that while one should still avoid unnecessary dependence on fancy stuff, there is value in using these systems to create what are not so much “web pages” as cross-platform, zero-install applications — they may not be usable by $NON-MAINSTREAM-BROWSER-TYPE but nothing else would be more compatible and still provide the same benefits.)

One bit of advice sometimes given to the novice programmer is don't ever compare floating-point numbers for equality, the reason being that floating-point calculations are inexact, and one should use a small epsilon, allowable error, instead, e.g. if (abs(value - 1.0) < 0.0001).

This advice is actually wrong, or rather, overly strong. There is a situation in which it is 100% valid to compare floats, and that is an cache or anything else which is comparing a float with, not a specific constant (in which case the epsilon notion is appropriate), but rather a previous value from the same source; floating-point numbers may be approximations of exact arithmetic, but that doesn't mean you won't get the same result from the same inputs.

So, don't get any bright ideas about outlawing aFloat == anotherFloat.

Unfortunately, there's a case in which the common equality on floats isn't what you want for previous-value comparison anyway: for most definitions of ==, NaN ≠≠ NaN. This definition makes sense for numerics (and is conformant to IEEE floating point specifications), because NaN is “not a number”; it's an error marker, provided as an alternative to exceptions (or rather, floating point error signals/traps/whateveryoucallit) which propagates to the end of your calculation rather than aborting it and requiring immediate error handling, which can be advantageous in both code simplicity and efficiency. So if you think about calculating within the space of “numbers”, then NaN is outside of that. But if you're working in the space of “results of calculations”, then you probably want to see NaN == NaN, but that may not be what you get.

Mathematically, the floating-point comparison is not an equivalence relation, because it is not reflexive on NaN.

(It's also typically the case that 0 == -0, even though positive and negative zero are distinct values. Oh, and NaNs carry data, but I'm not talking about that.)

What to do about it, in a few languages:

JavaScript

Even the === operator does not compare identities rather than numeric values, so if you want to compare NaN you have to do it as a special case. Google Caja handles it this way:

/**
 * Are x and y not observably distinguishable?
 */
function identical(x, y) {
  if (x === y) {
    // 0 === -0, but they are not identical
    return x !== 0 || 1/x === 1/y;
  } else {
    // NaN !== NaN, but they are identical.
    // NaNs are the only non-reflexive value, i.e., if x !== x,
    // then x is a NaN.
    return x !== x && y !== y;
  }
}
Common Lisp

The = operator generally follows the IEEE comparison (if the implementation has NaN at all) and the eql operator does the identical-object comparison.

E

The == operator is guaranteed to be reflexive, and return false for distinguishable objects, so it is appropriate for the “cache-like” use cases, and the <=> operator does conventional !(NaN <=> NaN), 0.0 <=> -0.0 floating-point comparison.

Late update on Caja-CapTP:

Google Summer of Code is over. I passed based on revised goals, but I'm not happy with the state of the code and I did not complete any significant part of the original plan.

Regarding the items mentioned in my last update:

  • Write more documentation/comments.
  • Commit as much of the work-in-progress as I can.
    • ...including the incomplete CapTPConnection, even though its tests don't pass yet, so that the partial work can be counted.

I committed CapTPConnection, and found and fixed enough infrastructure (whenResolved, CommTable, SwissTable, deSubgraphKit, etc.) bugs that it starts up and can do a basic operation or two. It's not useful for anything, but it's a lot closer to running than it was at the time of my last update.

Also, I removed dependencies on 'window' so in principle it will operate on a non-browser (server) JavaScript implementation. This has not been exercised because there is no browserless driver for the test scripts yet.

I stated that I would continue working on Caja-CapTP past the GSoC work period; however, with the time occupied by schoolwork, I have not had time or brain space to do so yet. I am not going to abandon the project.

Stuff done:

Stuff to do:

  • Write more documentation/comments.
  • Commit as much of the work-in-progress as I can.
    • ...including the incomplete CapTPConnection, even though its tests don't pass yet, so that the partial work can be counted.

A while ago I got the idea to write a “my experiences with JavaScript” post; unfortunately, I’ve forgotten what I was going to put in it. However, yesterday someone said approximately “I need to learn JavaScript in 3 hours, what should I know?”, and I thought of quite a few not-immediately-obvious things to point out.

Brain-dump for the beginning JavaScript programmer )

Had a bit of a breakthrough in debugging facilities: realizing that there's no reason I shouldn't modify my local copy of the Cajita runtime to provide more debug information (and it doesn't matter if it subtly breaks security, even, as long as Caja-CapTP is still compatible with the proper version).

Only a week or so left. I've discussed the matter with MarkM, and he pointed out (again) that I should work toward having useful-to-other-people components even if I haven't finished the one I intended to do.

Toward this end, I am going to work on Data-E (which is already part of the Caja-CapTP project) as a standalone serialization utility (for network and disk) as I understand it will be useful for Shakhar.

Todo items:

  • Implement generic literals (description) to make it more JavaScript-natural.
  • Implement cyclic object graph handling using Ref promise implementation already done.
  • Commit all in-progress work as reasonable changesets (even the tests that don't yet pass).
  • Document what works, design decisions, etc.
  • Continue to work on CapTP itself as time permits.

I intend to continue working on the Caja-CapTP project beyond GSoC; both simply because it is a project of mine, and to mitigate my failure to complete the planned work on schedule. However, for the next few months it will have to compete with my college work rather than my procrastination.

I'm having severe getting-around-to-actually-doing-the-work problems; I am far behind schedule. I think the problem is framing this as “work” rather than just another of the projects that I've found interesting and tinkered with. (I also blame Team Fortress 2 and Rosetta Code for providing attractive distractions...)

I've ported the “Ref” facility from E; this is necessary as CapTP is built on Ref semantics (promises, proxies, broken refs). I hope to very soon get the actual CapTP connection module up, then (as I wrote before) “define, document and implement a CapTP-over-HTTP protocol”.

(I previously mentioned implementing the Surgeon (serialization tool) but I then remembered that that's actually irrelevant to CapTP.)

Also: working without Internet access removes a whole lot of potential distractions — and one’s access to online documentation. Luckily I had some source code around which provided examples.