On Mon, 30 Nov 2009, Thomas Girod wrote:
> That's what I call a good teaser !
>
> Can you elaborate on how you achieved that ?
What details do you like to know?
The final data structure is a lazy storable vector that I write chunk by
chunk to ALSA output. However I try to put as much as possible into a loop
that fills the storable vector. This way I do not need to generate many
temporary storable vectors. I extensively use a structure
(synthesizer-core:Synthesizer.State.Signal), that is essentially a (exists
s. (StateT s Maybe a, s)). It maintains an internal state and generates
one new value per call. It is isomorphic to lists but does not have a
storage. It is like stream-fusion:Data.Stream without the Skip constructor
(because I have no 'filter' functions). I also use arrows
(Synthesizer.Process.Causal) for getting sharing on a per sample basis.
E.g. in
StateSig.zip (StateSig.map f a) (StateSig.map g a)
'a' is also a generator. When writing it this way, then the generator
'a' is run twice, because it does not store anything. I have to write it
this way:
f &&& g :: Causal.T a (b,c)
I think the biggest bottleneck today is, that GHC decides to specialise
functions that are used more than once and then does not inline them,
although I have told it to do so. It's a pity, I can use an oscillator and
it is rendered really fast. When I use the oscillator twice to get an
phaser effect, then the program may become three times slower.
_______________________________________________
haskell-art mailing list
[email protected]
http://lists.lurk.org/mailman/listinfo/haskell-art