pmuellr is Patrick Mueller, Senior Node Engineer at NodeSource.

other pmuellr thangs: home page, twitter, flickr, github

Wednesday, July 15, 2009

web beep()

I've blogged before about making use of audible feedback for debugging. One of the things I'd like to eventually get around to doing for WebKit's Web Inspector is to add first class audible breakpoints. Just like you can "click" on a line to add a breakpoint where the debugger will stop the next time that location is reached in your program, an audible breakpoint wouldn't stop, but play a sound clip instead.

There's some infrastructure that needs to be added to Web Inspector before tackling that feature, so I figured I'd go on the cheap instead. Using HTML5's new audio element, I created a beep() function which just plays a sound clip when invoked. Wherever you might put a console.log() invocation, you can put a beep() invocation instead. Actually, I created a boop() function also; a single sound is rather boring.

Of course, having to modify your source for debugging is so 1980's. So my beep() functions can also act as wrappers. Pass them a function, and they'll return a new function you can use as a replacement of the original function. When that new function is invoked, it beeps (or boops, or whatever), then invokes the original function. The new function also contains a reference to the old function, so you can unwrap as needed. Using this, you can augment addressable functions from within your REPL-y JavaScript debugger console, without having to muck with your source.

The sample code is up here: web-beep. Seems to run fine in Safari and FireFox 3.5.


Fred Blasdel said...

You should use a data:// URL for the sound data — then the entire beeper can be self-contained and you don't have to worry about copypasta loading the files from your server.

Patrick Mueller said...

That's probably a great idea for a real-life implementation of this. Presumably use a compress format that the browsers will understand (mp3? aac?). Use shorter standardized clips that might compress better anyway, like a sine wave. There may be enough in the API's for audio that you could have a REALLY short clip that you set to repeat some fixed number of times, almost like a repeated image.

Thanks for the idea!

Fred Blasdel said...

Exactly — use an uncompressed PCM WAV sample just long enough to cover a cycle of samples, and repeat it in a loop for length.

Patrick Mueller said...

I just tried an .mp3 of a sine wave; 0.1 second long, set audio.loop = true, set a timeout to pause after a second. Noticeable delay from the end of the clip to the start again. Looping isn't seamless. That was Safari. On FF 3.5, didn't support mp3. Nor ogg. .wav worked. But didn't loop at all. The file size difference is 10x between the .wav and the .mp3, and 2x between .ogg and .mp3 (mp3 smallest).

We gotta ways to go here. :-)

Fred Blasdel said...

A tenth of a second is still two orders of magnitude longer than necessary :-)

Mozilla kindly neglected to implement loop, though ogg vorbis is supposed to work.

Patrick Mueller said...

heh, yup, especially for a sine wave. The delay is killer though - they must be manually looping; not sure about quicktime, but I know win32 sound api's allow you loop and play and it's seamless.

I was surprised FF didn't seem to play the ogg file, but I'd need to test more; I generated the file out of Audacity, maybe there were some incompatible options used or something. Not surprised it didn't support mp3. And not surprised Safari didn't support ogg. Kinda the same situation as with video. Having wav as the only compatible format blows.