I was listening to smj do strange and excellent glitching of
the clash on anon radio as my energy to do inane
email-sending tasks waned. It got me in mind of how I could
form some cyber-appendage capable of grasping the stream.
I think actually-doing-it probably could look kind of like
1. Dump my stream into a wave file
2. Streamingly convert wave file to mp3 file
3. Stream that to stream
(If you know better than the seat of my pants, do say. Maybe
there's a tut.)
So actually-doing-what. I've sorely neglected my sometime
life centre of streaming. Laplace (I like to rhyme this with
hapless) transforms create discrete signals from continuous
signals and then inverse the inverse. A popular one is the
Fourier transform, converting between frequency dirac delta
spikes and sinc sounds (etc). The dirac delta function
is 0 when it's argument is not 0, and has an integral of 1.
The discrete Fourier transform takes surprisingly few
operations/has a low complexity to do called the Fast
Fourier Transform, originally known to Euler. Larger Fast
Fourier Transforms are built up recursively, related to
possible factorisations of the input's size. In practice,
terminating small fast fourier transforms are below size 53,
because above that numbers other than 0 or 1 show up in part
of a split-nesting approach, and numbers other than 0 or 1
suck.
Anyway, I want to stream these. My thinking is to stream
through butterflies of little discrete
decimation-in-frequency ffts [whence to anon radio,
eventually]. The key bit of streaming here is that after
some lead time, output has to start leaving exactly as fast
as new inputs arrive.
It is also fast to compute prime sized discrete Fourier
transforms; you can use a fast fourier transform to do the
maths of a prime sized discrete fourier transform, so the
prime one can be fast as well. It's not known how many
operations it takes in the best case in general.
Let's do the simple definition of plus and minus-i discrete
fourier transforms.
(defun naieve-i (v)
(make-array (length v) :initial-contents
(loop for k below (length v) collecting
(loop for n below (length v) summing
(* (aref v n)
(exp (/ (* #c(0 -1) 2 pi k n)
(length v))))))))
and its undoing (or vice versa), the +i
(defun naieve-i (v)
(make-array (length v) :initial-contents
(loop for k below (length v) collecting
(loop for n below (length v) summing
(* (aref v n)
(exp (/ (* #c(0 +1) 2 pi k n)
(length v))))))))
For a given smallish prime number, we can calculate the
Winograd fft, whose attractive properties I am going to fail
to use here.