Drug Half-Life Calculator

Here we go again with some baffling stuff. I wanted to understand the implications of drug (i.e., medicine or medication) half-lives, in particular for drugs taken daily. The half-life calculators that I found were not useful at all, so I created my own (including an interactive graph), for use on a desktop or laptop, with a keyboard and biggish screen:

http://com.hemiola.com/half-life/

This page does not explain the basics of half-lives. There are plenty of other sites that do that.

For drugs with a short half-life (e.g., a few hours), I can see how if taken daily, there is no buildup because the daily residual is negligible. It was intuitively obvious to me that with a long half-life (e.g., a half-day or more), taking the drug daily would cause an overlap and buildup—convergent, but still, you would have more drugs in your system than you take daily, and I wanted to know that number.

The basics

Wikipedia recently instituted a format for its drug entries that includes the drug’s half-life. That makes it easy and convenient to look up the half-life for all the drugs I’ve checked.

There seems to be an assumption that drugs with a long half-life are slower acting. Mathematically, they stabilize in the system at a higher dose than what you take. I find that interesting.

The math

There is the Wikipedia page on biological half-life, but the math there is way beyond me. Here is what was obvious to me:

After x hours with half-life H (in hours) and dose D1, the fractional amount D2 leftover is:

When you take drugs at regular intervals, there might be some nonnegligible amount left over from previous doses. Here is essentially what my calculator is doing, where p is the hours between doses:

The disclaimers

Yes, I realize the real-world implications of drugs and their half-lives are way more complicated than a simple power-of-two equation. Still, I wanted a quick and easy way to compute the oversimplified numbers.

Traverse Facebook Comments by Time

I have written a bookmarklet that facilitates traversing all Facebook comments for a given post in time order. This applies to the full version of the Facebook website.

To install the bookmarklet, click here to bring up a page with the bookmarklet in it, along with some simple instructions.

Also see my Expand All bookmarklet.

Things you must know

To use this bookmarklet, you must have a single post isolated to a browser tab or window. To do this, ctrl-click on the timestamp of the post you are interested in.

Next, you most likely will need to run my “Expand All” bookmarklet to expand all comments and replies. The only comments linked are the comments you can see at the time. By the way, this links comments and replies.

Finally, when you run this “Link Comments” bookmarklet, it will jump to and highlight the last comment made on the post. (If you don’t see a highlighted comment, something went wrong.) To traverse, use the keyboard:

  • Ctrl+up: jump to previous comment (if any).
  • Ctrl+down: jump to next comment (if any).
  • Ctrl+home: jump to first comment.
  • Ctrl+end: jump to last comment.
  • ESC: detach this bookmarklet from the page.
  • Mouse click on a comment: highlight and make that comment the current comment.
    • Ctrl+click: shade all comments newer than the one clicked.

It’s not recommended, but you can also traverse the comments using the mouse by clicking on the older/newer links generated by the bookmarklet.

What does this [not] help with?

This solves a need I had; maybe others will find it useful. Let me describe example scenarios I wrote this for:

  • I care about the post, who comments, and what they say. (Not worthless comment bait, or something posted by a public figure with many throw-away comments that I don’t care about.)
  • I’ve been following the post but am losing track of all the comment threads emerging like tentacles. I don’t want to read from the beginning each time; I just want to see what’s new.

Let me emphasize: if you are freshly coming to a post with many tentacles, you’ll want to read the post in branch-sequence (i.e., how Facebook presents it to you), not time-sequence. It’s only when you’ve watched comments unfold that time-sequence makes any sense, and that’s what this bookmarklet is intended to help with.

Ain’t No Scandal Dire Enough

This song parody reveals my political leanings. Oh, well. That’s actually the point, confirming that I am, in fact, alive. I’ve been a fan of song parodies since reading Mad magazine and listening to Dr. Demento (including “Weird Al”) when I was a young kid.

Sung to the tune of “Ain’t No Mountain High Enough”
Follow along here:
https://www.youtube.com/watch?v=Xz-UvQYAmbg

Ain’t No Scandal Dire Enough

Listen, baby, ain’t no scandal dire,
Ain’t no tale tall, ain’t no story false enough, baby.
If you need me, tweet me; no matter fore or aft,
No matter how daft (don’t worry, baby)
Just tweet my name; tweet some lies in a hurry.
You don’t have to worry.

‘Cause, baby, there ain’t no scandal dire enough,
Ain’t no tale tall enough,
Ain’t no story false enough
To keep me from lying to you, baby.

Remember the day I gushed perjury.
I’m a billionaire; you can always count on me, darling.
From that day on, I made a vow,
I’ll pretend I can be there when you need me,
Some way, somehow.

‘Cause, baby, there ain’t no scandal dire enough,
Ain’t no tale tall enough,
Ain’t no story false enough
To keep me from lying to you, babe.

(Oh, no darling)
Thin skin, small brain,
Toilets of gold can’t stop me, baby (no no, baby).
Just keep burning coal.
If you’re ever in trouble
I’ll say, “You live in a bubble.”
I won’t even pay you (oh baby, ha!)

I live to contrive.
I may not be smart,
Although I can jostle the applecart.
If you ever need a tiny hand,
I’ll be there on the double,
Just as fast as I ‘Klan.’

Don’tcha know that there
Ain’t no scandal dire enough,
Ain’t no tale tall enough,
Ain’t no story false enough
To keep me from lying to you, babe.

Don’tcha know that there
Ain’t no scandal dire enough,
Ain’t no tale tall enough,
Ain’t no story false enough,
Ain’t no scandal dire enough,
Ain’t no tale tall enough

Expand All Facebook Comments

I have written a bookmarklet that expands all comments and replies in Facebook posts. This applies only to the full version of the Facebook website (e.g., www.facebook.com in the U.S.) and not to other web versions or to versions of the mobile app.

Bookmarklets are not the prettiest or best-understood things in the world, but I’m making it available in case people want to use it.

To install or update the bookmarklet, click here to bring up a page with the bookmarklet in it, along with some simple instructions.

Also see my Link Comments bookmarklet.

What does this help with?

This expands Facebook posts so that you can see/read all comments and replies from top to bottom without clicking. This is how I use it, and I use it on posts with usually much fewer than 100 comments and replies.

Others use this to expand complete threads prior to archiving them. That wasn’t my original usage model and can easily hit Facebook limitations on how much it will retrieve (plus, it gets slower the longer it runs), but it’s still better than manually clicking.

To isolate a single post to a browser tab, ctrl-click on the post’s time stamp, which is a permalink URL. Then, run the bookmarklet on the isolated post by clicking on the bookmark. Or, run the bookmarklet on multiple posts (e.g., search results in a private group) and it will expand all posts it finds.

2016-07-09 update. The permalink URL to a public page (for celebrities, businesses, etc.) stopped isolating the post; now the whole news feed is displayed with the post of interest at the top. If a page like this is encountered, this bookmarklet only expands the permalinked post. Facebook has changed how they do this at least twice now; I’m trying to keep up.

Facebook sometimes goes into theater mode (i.e., one post rendered on top of the news feed). This bookmarklet will close theater mode before expanding. For best results, be sure you have isolated the post to a separate tab.

Details of what this does

Output is logged to both a temporary visual text area and to the browser console. The text area goes away when it’s done, so if you want to see a record of what happened after-the-fact, you’ll need to hit F12 and open the browser console. When the script completes, it logs a numerical total of all comments and replies being displayed. New text goes to the top rather than the bottom.

The bookmarklet clicks on the following links, sequentially. That is, it clicks and waits for the new content, which is recursively checked for new links:

  • View more comments
  • View previous replies
  • View more replies
  • View [x] more replies
  • [x] replies
  • [user] replied

After all the comments and replies are obtained, it clicks any and all See More and See Translation links.

It finds links to click by querying on CSS style names and is thus language independent, but see the Warnings ahead.

Please don’t do this

This isn’t recommended on posts that have many thousands of comments:

  1. You probably aren’t really interested in posts with that many comments.
  2. I have found that Facebook stops delivering comments after a certain point; you can click the View more comments link, and nothing happens (visually, anyway). This bookmarklet bumps into the same limitation: it iteratively clicks View more comments links and eventually times out as nothing happens.

Just be aware that eventually Facebook stops delivering comments.

If you want to stop the bookmarklet, hit ESC. If you run it again, it will pick up where it left off (effectively, not literally).

Customizing the bookmarklet

You can customize what the bookmarklet does. You can create multiple bookmarklets, each with a different customization.

When you edit the bookmark (Properties in Firefox), you will see near the very beginning todo=14. You can change the numerical value. With this value, you control four bits of instruction:

  • 1: open Continue Reading links
  • 2: expand comments
  • 4: expand replies
  • 8: click on any translation links

In combination, there are 16 possible values: 0 through 15. Some examples, starting with a value of 14:

  • Add 1 to open Continue Reading links
  • Subtract 4 to not expand replies
  • Subtract 8 to remove the translation step

Note that I only regularly use (hence, test) the default value.

Browser support

I mostly use the Google Chrome browser on a Windows PC, and I don’t use mobile devices. Among the main browsers, bookmarks in Chrome were the easiest and most intuitive to use.

Mozilla Firefox also works, though getting the bookmark bar to show up is slightly more cumbersome.

I tried Microsoft Edge once just to make sure things seem to work there (which they did). Bookmarklets in Edge was a complete hack through the file system; really, not supported.

Why did I do this?

I looked around to see if someone else had done something like this already, and of course I might have missed something, but it became apparent to me that it would be easier to do this myself than to keep looking for something that actually worked.

Warnings and notes

  • This works today based on how Facebook is rendered in HTML today. It might break tomorrow, and I might not be able to fix it.
  • Though the script doesn’t outright parse display text, it attempts to parse integers as a way to avoid clicking Hide links. I have tried about 10 different languages, all of which worked (I think). Please let me know if you find a problematic language, such as where the script shows and hides replies endlessly.
  • You can run the bookmarklet multiple times; it’s harmless. Sometimes it helps to do this if Facebook is slow and timeouts result in an incomplete expansion.
  • If you want to see the bookmarklet’s JavaScript in a readable format, copy-and-paste it into a beautifier such as jsbeautifier.org. In fact, if you know JavaScript, you might want to do this to boost your confidence that I am not trying to hack you with some malicious script.

Troubleshooting

If this bookmarklet used to work and stopped working, chances are Facebook has changed, and I need to change the bookmarklet. I might notice the breakage myself, but it probably won’t hurt to let me know about it. Changes I’ve made are listed here.

If you’ve never seen it work in a situation:

If it doesn’t work for a public Facebook post, send me or post a comment here with the permalink URL in it, and I will look at it.

If all I know is that it doesn’t work for a private post, it can be pure guesswork on my part from there (unless a good description of the problem is given):

  • Bear in mind that this just automates clicking that you would otherwise do. Manually click on what is not working, and assess the situation from there.
  • You can run this bookmark multiple times without penalty. Sometimes doing so can reveal a clue, especially interspersed with your own clicking.
  • I consider myself a regular Facebook user. If there’s something unusual or nonstandard about your situation, feel free to elaborate. For example, I have no idea how to create, see, or show a “hidden comment.”
  • Facebook has limitations. Please read the section titled “Please don’t do this.”

Note: Most of my activity involves closed groups. Closed group search results have been broken in Facebook since the middle of 2017 (it’s 2017-10-16 now). It takes two tries to open each result. I stumbled on an accidental workaround for this on 2017-10-20 and updated the bookmarklet.

Chinese Character Browser

The Chinese Character Browser:

  • Presents Chinese characters in a browsable fashion.
  • Exercises my Chinese Character Web API.
  • Demonstrates a fully keyboard-accessible HTML UI.

If you are in the process of learning Chinese, or if you would like to see an example of a keyboard-accessible HTML UI, then you might find it interesting.

Browsable Chinese characters

One key to browsability is a combination of the usual arrangement by radicals and strokes and not requiring any page navigation. I think the idea of looking up Chinese characters as you would in a dictionary is a valuable skill, and one that improves as you learn more by doing it more. When I started learning the Chinese language, computer support was barely getting off the ground. If I wanted to look up a character whose pronunciation I didn’t know, I had to look it up by radical and strokes.

Nowadays, if you can write a character, however badly, you have more options:

  1. On Windows, you can use the built-in Tablet PC Input Panel, which requires only that you have a tablet input device.
  2. For lookup using the mouse as a drawing device, you can use http://ce.linedict.com/.

And OCR is perhaps becoming an option, though I haven’t tried these:

  1. Maybe Google Goggles?
  2. Pleco Software does live video OCR on an iPhone.

Still, I think you learn a lot and get a lot of satisfaction from looking up a character by radical and strokes. A side benefit of the Chinese Character Browser is that when you see 6,763 characters broken down by radical and strokes, it doesn’t look like so many. It gives your mind a sense of the entirety of what’s before you, if you are setting out to learn as much as you can.

Keyboard accessibility

Another key to browsability is being able to use the keyboard to do everything. There was a time, before the Web, when keyboard support was central to the creation of almost any UI. I think it’s clear now that keyboard support in HTML applications has fallen permanently by the wayside. Even so, I wanted to see what it would be like creating an HTML UI that was fully keyboard-accessible.

One important note here is that even though I created a keyboard-accessible UI, it’s not accessible in the Section 508 sense—at least, I doubt it. Unfortunately, Section 508 compliance is generally equated with working well with specific screen readers. My last look at screen readers a few years ago revealed an almost complete lack of support for dynamic HTML applications. My only goal here was keyboard-accessibility, not compliance with a specific screen reader.

Here’s how the keyboard works in the Chinese Character Browser:

  • Focus is indicated with a focus rectangle, so you can find/follow the focus with your eyes.
  • Tabbing moves the focus from left-to-right and top-to-bottom. Shift+tabbing moves in the opposite direction.
  • When a list has focus, selection is visually indicated and can be changed with the up/down arrows, page-up/down, home/end, and ctrl+home/end. (Home/end operate on the visible items. Ctrl+home/end move to the beginning/end of the list.)

So far, that’s just standard keyboard stuff. I came up with a few “extras” to fit the tool:

  • You can use the left/right arrows to move between lists (tab and shift+tab also work).
  • Ctrl+up/down jumps to next higher/lower stroke count (or additional strokes, depending on which list is focused).
  • Pressing a number key jumps to that stroke count (or additional strokes, depending on which list is focused). To go higher than nine, use shift+#. You can’t go higher than 19 using this method.

There are various ctrl+shift sequences that can be used like keyboard accelerators. These are labeled in the UI:

  • Ctrl+shift+c: toggle between GB2312 and Big5. See the API doc for more information.
  • Ctrl+shift+r: toggle between using kRSKangXi and kRSUnicode for radical/stroke information. See the API doc for more information.
  • Ctrl+shift+f: cycle through the font list.
  • Ctrl+shift+s: toggle the sort order of the main radical list.

Limitations of character-based study

It’s worthwhile acknowledging that studying characters is only part of the whole picture. You will not learn Chinese simply by studying individual characters.

Many characters have different pronunciations depending on how they are used.

This tool simply lists out the different possible pronunciations.

Many characters are pronounced with a neutral tone when they appear at the end of a multi-character term.

It’s challenging enough to remember pronunciation and tone of each character. Additionally, you need to remember if a given term ends in a neutral tone. When you first learn a character in its neutral tone form, you haven’t yet actually learned the character; you can’t yet correctly use the character elsewhere when its tone does matter.

Third-tone characters are often correctly pronounced using a second tone.

When learning-by-listening to third-tone characters that have been spoken with a second tone (sandhi tone modification), you haven’t learned the correct tone of the character. You will, in fact, learn the wrong tone if you learn by listening.

I’d venture to say that every first-day student of Mandarin is bombarded with conflicting and incorrect information about what’s likely the very first character they learn: 你. The teacher says unambiguously that it’s pronounced using the third tone, yet goes on to pronounce it (correctly) using a second tone in 你好, yet never mentions why such a blatant contradiction is occurring.

Seeing Stars

Rating things is all the rage. I suspect that rating scales can influence ratings given and that there are other factors that influence the ratings a person is comfortable giving publicly. Except for the “thumbs up” idea (only occasionally paired with a “thumbs down” to go along with it), there’s been somewhat universal usage of a five-tier rating system, but with no universal definitions of the different ratings. And I’m not sure anyone pays close attention to the definitions anyway.

If you read reviews on (e.g.) Amazon and Yelp, you see ratings given purely as a number of stars, but you don’t see a definition of the ratings. If you post a review, only then are you given a definition of the ratings. The same things apply to Angie’s List, except letter grades are used instead of stars.

Sites seem to not want to try to mess with readers’ perceptions of what it means to be rated one star or five stars; they assume that people just “get it.” However, sites seem to want to help reviewers pick a number of stars for their reviews, as if the reviewers don’t just “get it.” This is odd and asymmetrical.

Amazon

Here are the rating definitions on Amazon, seen only by reviewers (but accessible to anyone who tries):

5 stars I love it
4 stars I like it
3 stars It’s OK
2 stars I don’t like it
1 star I hate it

With Amazon’s scale, you give stars even when you hate something (one star) or don’t like something (two stars). This is the nature of using a star-based system that covers the love-hate spectrum. How many reviews have you read where the reviewer said, “I’d give zero stars if I could”? Reviewers don’t want to give out a star to something they hated, even though that is following the definition. This perhaps shows that some raters don’t know what their rating is defined to mean, or perhaps they are more in-tune with the reader who might neither know (or care) nor have immediate access to how the ratings are defined.

What I like about this scale is its symmetry. If you hate something as much as you could love it, you give it one star. If you dislike something as much as you could like it, you give it two stars.

Angie’s List

Here are the rating definitions on Angie’s List, seen only by reviewers (but accessible to any member who tries):

A Excellent
B Good
C Fair
D Bad
F Lousy

The A-B-C-D-F system feels the most meaningful to me. Perhaps it’s my experience of sixteen years of school in the U.S., but rating something A-B-C-D-F feels more meaningful than rating something one-to-five stars. An A is coveted. A B is still good, but no one wants to get one. A C is really not good and represents failure to many people. D means unacceptably bad but not a complete failure, whereas F means a complete failure. Unfortunately, this grading system is not internationally universal.

Yelp

Here are the rating definitions on Yelp, seen only by reviewers (but accessible to anyone who tries):

5 stars Woohoo! As good as it gets!
4 stars Yay! I’m a fan.
3 stars A-OK.
2 stars Meh. I’ve experienced better.
1 star Eek! Methinks not.

I really dislike these definitions. The difference between four and five stars is “Yay!” vs. “Woohoo!” This just doesn’t connect with me.

A-OK means better than okay. For a restaurant that I found perfectly enjoyable, an A-OK rating sounds perfectly fair and logical. But if I think “just OK” or a C grade, then this turns into a rather insulting rating.

2 stars: This is the “whatever” rating, with only a twinge of negativity. Does this map to “I don’t like it” or a D rating? Not in the slightest.

1 star: This is the only fully negative rating, but it still doesn’t feel as strong as “I hate it” or an F grade.

Yelp, cont.

Many Yelp users register with their real names and pictures, and I think not being anonymous inhibits giving an honest opinion in some cases. This doesn’t apply to restaurants. Many restaurants in my area get hundreds of reviews, so anonymity comes from no one caring who wrote a specific review. Most if not all restaurants that are not terrible (i.e., staying in business) end up with 3.5 stars. My conclusion is that any restaurant that stays in business is liked by enough people to give it a decent rating. Thus, the rating summary for restaurants actually provides essentially no useful information. Every restaurant I’ve looked up in recent memory had about 3.5 stars, regardless of how good it actually was (in my snobbish opinion)—not that a C+ is a very good grade.

You can review anything/anyone on Yelp, and lack of anonymity comes into play for certain categories of reviews. For example, you can rate physicians. It seems that most one-star ratings for physicians are based on someone’s one and only one bad experience. How many Yelp users will publish a five-star rating of their long-term physician? I’d venture to say very few, because most reviewers are reviewing one meal in a restaurant and not the years they’ve been seeing a personal physician. For that matter, who would give their personal physician fewer than five stars and still want to face them during their next visit? Thus, physicians tend to have either no reviews or mostly negative reviews along the lines of, “Stay away!”

The case of the service provider (e.g., someone with a contractor’s license) can be interesting, and I am guilty of this: either I write a five-star review, or I don’t write a review. There’s often no gradation in the reviews. I don’t want to be the first to post less than a five-star review. If I feel the service provider was perhaps unethical or crooked, then I might write a negative review. But the service provider might pester you in return. I’m not just saying this; it happened to me the first week I posted on Yelp.

There are many classics of human nature wrapped up in this. If you had a one-on-one relationship with someone, perhaps starting with an estimate, followed by days or even weeks of working together, and you were unhappy with certain things along the way, society teaches you to always be polite and perhaps let your unhappiness fester under your skin. Now, you have the opportunity to write a negatively tinged review. Will you? Unlikely. If your Yelp persona is in fact yourself, then you’ll still feel the need to maintain being polite. Let’s face it: being polite means, for the most part, being dishonest.

But heaping praise on others, especially publicly, is something strongly encouraged by society.

With contractors, you will often see almost entirely five-star ratings. The value of the ratings, when they are all good, is really about the quantity of them. Knowing that someone was happy is valuable information. A single five-star rating (as the only rating) is not that valuable. Ten five-star ratings lets you know at least ten people were very happy, and that’s good. There were probably some who weren’t entirely happy, but that’s okay. There’s always the risk that things won’t work out perfectly. What I hope for in the reviews (and what I try to give) is plenty of detail.

I think it boils down to this: For people you interacted with just once and had a bad experience with, you are more willing to give them a bad review. For people you interacted with multiple times and had a less than stellar experience with, you will not want to rake them over the coals. Giving praise is easy, but giving criticism is hard, especially when you’re not anonymous.

Epilogue

The problem with averaging star ratings

Understanding online star ratings

Black Mirror, s03e01, “Nosedive”

Polyrhythm Visualizations and Auralizations Using HTML5

The implementation depends on HTML5 canvas and HTML5 audio, is experimental, and works best in Google Chrome (version 10.0 as of this writing).

The experiment, which uses HTML5 features.

Before the HTML version, I wrote a polyrhythm visualizer some time ago as a Java applet, when I was learning a number of the Chopin nocturnes. This was spurred on in particular by Op. 27, No. 2 in D-flat major. It’s in 6/8 time (i.e., two beats per measure), with the left hand playing six sixteenths per beat throughout. The ending involves two beats of: seven notes in the right hand and six notes in the left hand (a ratio of 7/6). Not only was the 7/6 a big challenge, but I started noticing patterns that called for some exploration.

Visualizations

There’s a pattern formed by which notes “fire” closest to each other in each hand.

14 against 5

Lines are drawn between top and bottom to emphasize when notes in the left and right hands are closest. The ebb and flow of the time distance itself has a pattern. In the example above, the left hand increasingly trails the right hand, until the midpoint, and then the left hand decreasingly trails the right hand, until they resynchronize.

One key for handling close ratios is that the midpoint involves an even trade-off between hands.

7 against 6

I didn’t want to draw too many lines between top and bottom, so the closeness visualization trumps the equidistant visualization.

5 against 6

Auralizations

After I rewrote my Java applet using HTML canvas, it seemed I should be able to bring it to life with HTML audio. Because of the precise timing required to render the audio, I wasn’t very optimistic about this in JavaScript, and it’s by no means perfect, but it was successful enough to go public.

Update: I’ve tried this on a few different systems now, and it functions horribly and unacceptably except on my development system. Google Chrome and IE9 RC work very accurately on my development system, I swear it. For now, the auralization is best described as experimental.

Timing in JavaScript, Part #1

To keep things simple and somewhat accurate, I wanted to use window.setInterval(...) rather than try to have sequences of window.setTimeout(...) daisy-chained together. I didn’t know what to expect across browsers. My conclusion is that timers in all browsers are very accurate, with Chrome being the most accurate. Chrome timers are least affected by CPU activity within the browser itself and other processes.

Timing in JavaScript, Part #2

The primary weakness bumped into seems to be that simply playing sequences of Audio elements is susceptible to random delays now and then. That said, Chrome is so reliable, it’s almost completely acceptable for the purpose here—essentially a metronome. IE9 RC is also very reliable. Firefox 3.6 is perhaps just under the threshold of acceptability. I found Opera to be too erratic.

Safari 5.0 on Windows delays the playing of all audio elements, thus the UI and the audio are totally out of sync.

Sequencing Audio elements

There are three things worth noting here:

  1. I didn’t find any problems with playing multiple Audio elements simultaneously. The sounds played okay and blended okay.
  2. The biggest hurdle was in realizing that I couldn’t get away with replaying the same Audio element each time it was needed. I needed to create pools of identical Audio elements and cycle through the pools.
  3. I found that repeatedly calling play() on an Audio element sounded erratic, as if the sound got queued up to play but didn’t necessarily play immediately. In fact, I’d venture to say this is the primary weakness of all browsers. A big improvement here, at least for Chrome, was to call play() only when playing the sound for the first time, and using currentTime = 0.0 to play it again later.

To expound on #2: If you play with the demo, you’ll notice there are only three different sounds. I spent a lot of time trying to get three Audio elements to play and replay and blend acceptably. This was a losing battle. The result was almost random noise.

Rather than work with three Audio elements, I’ve created three pools of ten Audio elements. (Choosing ten was arbitrary; a much smaller number would probably work just as well.) For example, playing ten hits of the hi-hat has played ten instances of the same sound (and playing twenty hits has played each sound twice). Using this approach cleaned up the sound tremendously.

Timing in JavaScript, Part #3

As I’ve tried more browsers on more systems, I see that the audio performance varies wildly. It seems that performance is irreparably bad on old, slow hardware. But even on faster, newer hardware, performance varies a lot. I’ve implemented two different approaches to playing audio, and which approach is used can be selected at run time:

  1. The default choice is to load the sounds once and replay them when needed. This seemed like the obvious approach to me, but this often results in random delays playing the sounds.
  2. I’ve found that on some systems, performance is better if a new Audio element is created and loaded (and played) each time a sound is needed. (Note: only reloading the audio did not make a noticeable difference. Creating a new Audio element each time is what made the difference.)

Relevant Links

The Great void of JavaScript

In JavaScript, you often see code like this:

// 1

(function() {
    a bunch of code;
})();

The code in the function runs immediately and allows you to avoid namespace collisions with other code. If the code includes (inner) functions, those functions are essentially private. In fact, they will go away if there are no references to them when the code completes.

People seem to prefer the above syntax, though the code is equivalent to:

// 2

(function () {
    a bunch of code;
}());

When I first felt the need to do this sort of thing, I tried the more intuitive syntax:

// 3

function () {
    a bunch of code;
}();

That is what one would expect to work. It makes intuitive and syntactic sense. It clearly creates an anonymous function and then invokes it. However, it causes a syntax error because, according to here, a statement that begins with the function token must be a function declaration (as opposed to an invokable function expression).

Noting first that the following works without complaint:

// 4

var discard = function () {
    a bunch of code;
}();

I then arrived at this:

// 5

void function () {
    a bunch of code;
}();

Note that void is a unary operator in JavaScript that discards its operand and evaluates to undefined. It is neither a function, as has been misreported, nor a data type, nor the absence of a data type, as it is in Java.

To me, #5 is more readable than #1 and #2. What I don’t like about #5 is that it’s still a bit cryptic. It may be cryptic, but I think it’s less syntactically disconcerting than #1 and #2, where I really don’t like the mysterious outer parentheses.

In case you missed it

Cases #1, #2, and #5 are equivalent. To me, #5 looks the simplest and the least prone to errors. I do wonder if there any insidious differences deep under the hood of any browsers.

Encapsulation? Or clean air?

This is a technique in JavaScript commonly used to avoid namespace pollution, and it’s often referred to as encapsulation, even though it’s really not. Booch defines encapsulation as “serving to separate the contractual interface of an abstraction and its implementation.” To this end, in Java and ActionScript, we have the interface. In JavaScript, we don’t.

Notes

  • 2012-11-20. Douglas Crockford refers to case #1 as “dog balls” here and prefers case #2.