Strongly Typed Proxies in AS3
October 30, 2008 on 4:00 am | In Flex, Programming | 10 CommentsSomething I’ve often wanted in AS3 is a strongly typed proxy: an object that implements a known interface with typed methods, but where every method results in the invocation of some method like invokeMethod(methodName:String, args:Array). AS3 does have a Proxy class, but unlike Java’s class of the same name, an AS3 Proxy doesn’t implement any particular interface. One can extend Proxy into a subclass that has an interface, but by that time the Proxy superclass isn’t delivering any real value. The AS3 Proxy has been designed for loose, dynamic typing — which after all is one of the strengths of the ActionScript/ECMAScript languages.
Why use a strongly typed proxy? A common use of such a proxy is to create a “smart wrapper” around some underlying object with a known interface that looks and acts (and code-hints) exactly like the underlying thingamabob, but does some other stuff around every method call or property access. You might want a smart wrapper that logs or records all the function calls (as well as executing them). You might want a wrapper that does a try/catch around every call. You might want a wrapper that serializes the call over a stream to some remote destination.
(If this sounds like what some call “aspect-oriented programming”, well, it is similar to one aspect of aspect oriented programming :-)
Anyway, we can’t use AS3’s Proxy to solve this problem, so what to do? We’ll start with a simple approach, but make it more general. If our interface looked like this:
public interface ISmashable
{
function smash(force:Number):String;
}
and we wanted to create a smart wrapper that logged all function calls around any ISmashable implementation, we might create something like this:
public class SmashableLoggingProxy implements ISmashable
{
private var _smashable:ISmashable;
public function SmashableProxy(smashable:ISmashable)
{
_smashable = smashable;
}
public function smash(force:Number):String
{
trace("smash():", force);
var result:String = _smashable.smash(force);
trace(" result:",result);
return result;
}
}
Then, if we did something like var proxy:ISmashable = new SmashableProxy(realSmashable); we could treat the resulting proxy as an ISmashable everywhere in our application, Every time we called, say smash(5) method on proxy, not only would realSmashable.smash(5) be called but we’d see some nice trace output as well.
If you have the time to create a lot of wrapper methods like this (or write a fancy code generator to save the trouble), that’s fine. Another way to go, however would be to create a “generic” smart wrapper base class: [Continued...]
Controlling Audio Latency in Flash 10
October 15, 2008 on 12:04 pm | In Flex, Music, Programming | 13 CommentsAdobe threw a slight curve ball with the long-awaited release of Flash Player 10 today. The release itself wasn’t the curve ball (although not everyone expected it to happen on thisdate). The surprise was the audio latency using the new dynamic sound generation APIs.
Audio latency, for programs that synthesize sound on the fly, is roughly defined as the amount of time between the program creating a sound and the computer’s audio output actually playing that same sound. Latency is important because it affects the user experience. If a user hits a “play” button and waits 1 second before hearing anything, that can be annoying. If a user types a note into a music notation editor and has to wait 1 second before hearing anything, that’s downright maddening.
Latency isn’t all bad, though. The higher the latency, the more “give” the sound output pipeline has, and the more resistant it is to disruption by other processes running in your browser and on your computer. Ideally you want to strike a balance between latency and robustness in your sound output.
In Noteflight, the latency on Mac OS X had been at a comfortable 30 milliseconds — about a 30th of a second — using the Flash 10 beta. But in the released production version, Noteflight’s audio latency suddenly jumped to about 850 milliseconds. Other folks with audio synthesis apps reported other numbers, all of them different. Whoa! What happened? (Before going further, let me say that our latency is now back at 250 milliseconds, so things aren’t as bad as they first seemed.)
Adobe introduced a new behavior into the released player, where the latency depends on the number of samples you provide to SampleDataEvent. If you provide 2048 samples per callback, your latency will be the minimum available on the platform (30 ms on Mac, ~250 on Windows). If you provide 8192 samples per callback, on the other hand, your latency will be in the neighborhood 1000 milliseconds. The amount of latency for in-between sample block sizes is a complex function of this number. Tinic Uro will hopefully publish more information about that function, which apparently involves a power-law nonlinear function of the block size combined with the native sound driver buffer size, but experimentally I have seen these numbers on Mac OS X:
block size latency (ms)
2048 30
3072 170
4096 250
8192 850
This is good stuff to know, and it’s something of a surprise to us all. I notched the sample size in Noteflight back down to 4096 in a hurry, and latency is acceptable once again. Or, semi-acceptable. I’d like to get it even lower, but I don’t want to do that in too much of a hurry without adequate testing and tuning of the synthesis pipeline.
[Important footnote (10/16/08): You might think that by adjusting the sample block size dynamically, you can change the latency on the fly for a single Sound object that is streaming samples. The answer is... sort of, but not in a useful way. You can make the latency increase by making the sample block size larger, but if you make it smaller again, the latency will not go back down: it will stay at the higher value. What is reported to work, but I haven't tried it yet, is to output sound using more than one Sound object, each with its own block size (and hence its own latency value). The usefulness of that approach is also not clear.]
Noteflight: An Online Music Notation Editor
October 6, 2008 on 5:46 am | In Flex, Music, Programming | 18 CommentsIt’s my great pleasure to make an introduction: Noteflight, please say hello to the world. World, there’s something I’d like you to meet: Noteflight. I’m really pleased to be able to finally write this, because it’s been a long journey to get to this point!
Noteflight is a new kind of tool for musicians, composers and educators: an online music notation editor. With Noteflight, anyone can create, share and publish musical scores using nothing more than a web browser. This ease of editing, sharing and publishing are what make Noteflight so different from other notation editors: music notation can finally be used on the Web in as natural and flexible a way as text, images or videos.
Here’s an example of a score that was created in Noteflight, shared, and embedded in this post:
This isn’t just a picture of music, but an interactive music display; for example, you can select and listen to individual notes and measures. Click the logo to see the full-page score, which can be printed. To get a sense of how the score above was created using the Noteflight score editor, please watch this video:
Scores are saved on the Noteflight server, so you and anyone you share them with can access them from anywhere on the Web. The music can be heard as well as seen: Noteflight has its own integrated audio playback, that sounds consistent on every computer. And Noteflight keeps track of all the past versions of your scores, so you can always go back and see where you’ve been.
The Noteflight beta is free and we’re accepting signups. As with all beta software, Noteflight is constantly being improved and extended; this blog is the best place to find out what’s happening (and what’s going to happen next) with Noteflight. Besides filling out the score editing features of Noteflight, we are planning additional services and capabilities for sharing music and organizing content.
There will be more posts coming up here about the development and internals of Noteflight — I’ve had to wait on many of those because the product wasn’t officially launched yet! A few quick techie observations:
- The Noteflight score editor was built with Adobe Flex 3.0.1 and Flash CS3
- The Noteflight server side was built with Ruby on Rails 2, Apache and MySQL and is hosted on Amazon EC2 and S3.
- The Moccasin open-source editing framework (see previous post) is a distillation of many of the music-independent aspects of the Noteflight score editor.
- The StandingWave audio library, previously discussed here (but not yet open-source), is used by the music synthesizer internal to Noteflight.
Entries and comments feeds.
Valid XHTML and CSS.
All content copyright (c) 2006-2007 Joseph Berkovitz. All Rights Reserved.