Go back to the home page for this paper.

What if you want to change things in real time?

You can do that. In the FOF example, fundamental frequency is of type float at any given point in time. The ffund argument is of type float vec so fundamental frequency can be controlled at audio rate.

In the real streaming version, it would be of type float ivec. If you don't expect to change it every sample, it could be piecewise constant, float event ivec.

Can't you do all this in [C++ templates, Haskell, Csound]?

The general answer is yes, more or less. This work isn't really about a language, it's about a method: temporal type constructors. The reason I end up talking about a language is that no present language seems to support the method quite satisfactorily. But if you can apply it usefully in any given language, so much the better.

Haskell: any non-strict (lazy) functional language, in fact, gives you the proper semantics for free. The cost is in execution time, which I would expect to be dismal. Trying to do any kind of block computation makes the embedding into Haskell non-trivial.

C++ templates: as mentioned in Section 2 of the paper, you can use templates as if they were type constructors. That C++ lacks a way to build anonymous functions on the fly makes this style of programming awkward, but the real catch is with infinite vectors. Since C++ is strict, the ivec<> template has to build in its own laziness mechanism. The easy way to do this is per-sample; goto Haskell.

Csound: this one's a ringer. Csound, like all unit-generator-based languages I can bring to mind, has no type constructors at all, but just a set of built-in types. You can build in more by dropping down to the implementation language and writing new ugens in C, but that's not the same at all. C is what I'm trying to get away from.


(go to my front-door page) eli+w3@cs.cmu.edu
21 Sep 2004