Turtle go Beep!
2007-11-22Adding sound to Curly Logo was a bit of a challenge, but it now has a beep command. I’m sorry the beep is not very pleasing; it was easy for me to write a Python program to synthesize the .wav file, and it compresses very well.
The beep command works by creating an HTML embed element that specifies a sound file, then creating a span element to contain the embed element, then displaying the span element. The act of displaying the span causes the sound to play. Without additional styling that also causes a great big ugly span containing an embedded play controller to appear. So I style the span before displaying it:
span.style.position = "absolute" span.style.visibility = "hidden" span.style.top = '0px'
Giving it «position: absolute» removes the span from normal flow, so its appearance doesn’t affect the position of anything else. Giving it «visibility: hidden» makes it invisible. Normally it makes something invisible whilst still preserving their effect on normal flow; that text will still flow around an invisible floating image for example. I use «position: absolute» so the element has no effect on normal flow anyway.
Contrast this with «display: none» which means that the element is not displayed, as opposed to being displayed outside of normal flow and invisible. Whilst this might seem like mere semantics, the difference is crucial. Using «display: none» will not make the sound play, whereas «position: absolute;visibility: hidden» does play the sound.
«top: 0px» avoids a bug in Safari where it expands the drawn area and adds a scrollbar even though it doesn’t draw anything there. Firefox seems to have a similar bug that I haven’t worked round.
Playing the sound again involves a little trick. First I tried «span.style.display=’none’» followed by «span.style.display=’inline’». This works when done “by hand” but fails when put into a function and called. Presumably Gecko needs to trigger a reflow between the two assignments, otherwise it just observes that nothing has changed so no redisplay is necessary. So what I do is throwaway the current span containing the embed element and create a new span. This is a good justification for having the span/embed pair, we can throwaway and recreate a relatively lightweight span, but the more heavyweight embed element is reused.
The original plan was to put the .wav file on the server and refer to it, and fetch it, via HTTP. Currently everything on amberfrog.com is compressed for transfer (”Content-Encoding: x-gzip”) which is a big win for HTML and JavaScript. For most audio formats it wouldn’t be so useful because they’re compressed already, but my current beep.wav file compresses from 41e3 octets to 551 octets. A huge win. Unfortunately embed elements playing sound files don’t work with “Content-Encoding: x-gzip” and I’m too miserly to store and transfer the uncompressed file.
RFC 2397 to the rescue!
I simply encode the entire 41e3 octet .wav file as a “data:” URL and stick it in the JavaScript as a string (I don’t get to gzip my “data:” URLs). It works just fine, despite the RFC’s assertion that «The “data:” URL scheme is only useful for short values». Well, it works just fine in Safari, Firefox doesn’t do RFC 2397 for audio embed elements and that’s bug 404780.
[Update: 2008-01-10: Now I use MIDI not .wav; this is better in several ways. I still use the RFC 2397 encoding.]
Of course I should be using an object element not an embed element, as embed is not standard. Couldn’t get object elements to work in Safari. Hush now.
2007-11-23 at 18:29:55
turtle did not beep for us :(
are we missing something?
2007-11-23 at 20:01:05
At the moment it’s only supposed to work on Safari 3. If you are using Safari 3, tell me more about what version, what OS version, etc etc. Safari 3 on Windows I haven’t tested at all. If you’re using Firefox or Opera, I’d love to make it work, but it doesn’t. You could vote for bug 404780 :)
2007-11-28 at 16:57:15
I tried the beep on Firefox, and then other commands (like fd 100) stopped working, though the console did still show them.
2007-11-28 at 17:48:08
@Ian: Oh. That’s not good. Beep not working I think I just have to live with, but breaking the other commands I guess I should be able to do something about.
What version of Firefox are you using? What operating system are you running it on?
2007-11-29 at 06:12:17
Curly Logo is great in Safari 3!
Given that you provide tooltips on all the words, it would be nice to have a side panel listing all the allowed commands.
2007-11-29 at 10:00:23
@Ian: Maybe. The list is quite short at the moment, but destined to grow longer.
The command
opps
will print out the names of all defined procedures which can then be tooltipped.
Obviously all this falls under the well known outstanding issue of “there should be more help”.
2007-11-29 at 13:32:51
We want variables!
We want variables!
2007-11-29 at 13:47:10
parentheses in arithmetic expressions? Or some other way of achieving the same result?
2007-11-29 at 13:52:55
Better error messages?
2007-11-29 at 15:12:35
@drj11:
Thanks, just a line saying “Type opps for commands” would be helpful. (I’ve long since learned the habit of adding features to the documentation and source simultaneously.)
Is there a reason you obfuscate your .js files? I would consider helping, but I don’t want to submit patches to obfuscated source (not to mention it’s hard to read).
How about a “to-do” page listing Logo features you have yet to add? Also a page of examples demonstrating all the existing features would be welcome. Maybe just expose your unit tests.
(P.S. The link points to my own collection of JavaScriptimplementations for esoteric languages.)
2007-11-29 at 15:40:17
@Ian: yes to all of those. I run my javascript through JsMin purely because I pay per byte. So far Curly Logo has cost me about 2.5 millidollars and would have cost 5 times that if I didn’t pay attention to bandwidth costs.
I intend to publish all the source under some Open Source license.
2007-11-29 at 18:48:09
Instead of a wav file, have you considered a midi file? I ask because those are downright miniscule, and easily generated by a variety of programs (I like abc2midi).
If you don’t feel like generating your own, feel free to use any of the beep sounds used on http://snowplow.org/martin/greasemonkey/lt-cc-musictest.html (they’re written in data: url form there)
There’s also on that page a way to generate a system beep in firefox without any extra file at all - look at the onclick handler for the “last resort” beep.
2007-11-30 at 14:57:54
@Nick: global variables now work. make “x 4
Parentheses in arithmetic expressions not supported yet, but will be. For now use Lisp syntax: (* repcount (+ 1 repcount))
You mean better than “(1 + x) ⇒ Exception: TypeError: Value undefined (result of expression f.apply) is not object.” ? I think I agree.
2007-12-02 at 17:49:34
Thanks for the reply!
Suggestion: run source through toLowerCase() before parsing. Most Logo implementations were case-insensitive, and a lot of existing Logo code is written in upper case.
Also, a page with basic Logo syntax that you can’t get through tooltips would be welcome (”to” syntax, variable reference, types, lists, etc.)
2007-12-02 at 18:10:06
Are parameters supposed to work?
to simple :l
fd :l
end ⇒ simple defined
simple 50 ⇒ I don’t know how to qthing
2007-12-03 at 15:33:13
@Ian: toLowerCase, yes of course. It was already on the list. Ditto the non-noun syntax.
@Ian: parameters do work, but not using traditional syntax. Just drop all your colons. I plan to make traditional syntax work, in a way that I believe is similar to the way UCB Logo does it.
Here’s the star example which defines two procedures, that should get you going.
2008-01-11 at 09:11:59
@Daniel: I had originally thought about MIDI, but at the time I hadn’t investigated generating files. I’ve now updated Curly Logo to use MIDI and it’s better all round. abc2midi looks quite cute, but generating my MIDI files by hand makes them even smaller.