ssfrr/AudioIO.jl — pull request #28 by shashi (2014-09-10 20:09:52+00:00)
Title: WIP Lightweight nodes

Nodes now hold exactly the amount of information needed to represent their domain of signals. removed the "Renderer" abstraction in favor of `pull`ing samples from a node. Mostly inlinable `sampleat` function makes `pull` generally fast. pulling for portaudio doesn't allocate a whole lot of memory. Time is consistently better than previous iterations, in most cases. the other cases have a lot of room for improvement.

One can now create signals of AudioNodes (signals as in Reactive.jl) very cheaply (a SinOsc takes 216 bytes), and lift such a signal to play a sound that changes in real time. Using Interact signals and the @manipulate macro, one can do things like:
```julia
mix = @manipulate for f1=110:880, f2=110:880
SinOsc(f1) + SinOsc(f2)
end
lift(play!, mix)
```
removed play and stop in favour of play! and stop!. play! replaces what is being played. to stop a node, simply remove it from the tree and play
the tree again.

This also has `SquareOsc` and `TriangleOsc`

I have tried to keep backward compatibility with the old API in other places though. But it may be worth shortening names in a breaking minor
release. `Sin`, `Square`, `Triangle`, `Mix`, etc. There is currently not a lot of consistency in the names, I feel.

Anyway this is not yet at a state to merge, I will work on some optimizations and get passing tests, would love comments at this point. :) I am also thinking of how this would extend to a sequencing API, note that this removes `end_condition`, for sequencing it's better to rely on [Reactive's timing functions](http://julialang.org/Reactive.jl/api.html#timing). I really love this talk https://www.youtube.com/watch?v=Mfsnlbd-4xQ on the subject.

Some speed and memory allocation comparisions follow, to the left are the old nodes. The measurements were for rendering `44100` (1s) samples. note that this doesn't compare the time taken to instantiate nodes in which this branch easily trumps. timing script: https://gist.github.com/shashi/dbc4a44ede975ac7d8e5
```
NullNode() NullNode()
elapsed time: 0.000807172 seconds (366832 bytes allocated) elapsed time: 0.000668067 seconds (190360 bytes allocated)
WhiteNoise() WhiteNoise()
elapsed time: 0.000464515 seconds (529552 bytes allocated) elapsed time: 0.000385824 seconds (176560 bytes allocated)
LinRamp(0,1,0.75) LinRamp(0,1,0.75)
elapsed time: 7.979e-6 seconds (216 bytes allocated) elapsed time: 0.00022092 seconds (176560 bytes allocated)
SinOsc(220) SinOsc(220)
elapsed time: 0.002422144 seconds (697640 bytes allocated) elapsed time: 0.001769491 seconds (176560 bytes allocated)
AudioMixer([SinOsc(220),LinRamp(0,1,0.75)]) AudioMixer(SinOsc(220),LinRamp(0,1,0.75))
elapsed time: 0.002552697 seconds (697688 bytes allocated) elapsed time: 0.001918074 seconds (353104 bytes allocated)
AudioMixer([SinOsc(220),WhiteNoise()]) AudioMixer(SinOsc(220),SinOsc(343))
elapsed time: 0.003138189 seconds (1227088 bytes allocated) elapsed time: 0.00332737 seconds (353104 bytes allocated)
AudioMixer([SinOsc(220),SinOsc(343)]) AudioMixer(SinOsc(220),SinOsc(343),SinOsc(434))
elapsed time: 0.005157282 seconds (1395176 bytes allocated) elapsed time: 0.005017761 seconds (529616 bytes allocated)
AudioMixer([SinOsc(220),SinOsc(343),SinOsc(434)]) AudioMixer(SquareOsc(220),SinOsc(343),SinOsc(434))
elapsed time: 0.007643713 seconds (2092664 bytes allocated) elapsed time: 0.004874233 seconds (529616 bytes alloc
```
cc ssfrr/AudioIO.jl#27