[Haskell-beginners] audio generation

Jeremy Shaw jeremy at n-heptane.com
Mon May 2 04:59:16 UTC 2016


You might consider using the pipes library:

http://hackage.haskell.org/package/pipes-4.1.8/docs/Pipes-Tutorial.html

The pipes library will allow you to generate audio and write it to
disk with out having to worry if you are going to suck up all the RAM
accidentally.

It should also help you  decompose your pipeline into smaller pieces.
For example, you would like to be able to decompose your code into
things like:

 1. the code that generates the audio
 2. the code that converts the audio into a format like wav/aiff/etc
 3. the code that writes binary data to disk

And then simply glue those pieces together, while feeling secure that
you don't create a space leak in the process.

It will also allow you to use StateT or IO (or anything other type
with a Monad instance) if you need to.

The pipes library is not trivial to learn. But it is well designed.

Without using the pipes library you have two options:

 1. understand how laziness works and then be very careful to make
sure you never accidentally hold onto data too long and cause a space
leak.

 2. use strict IO functions and write code that generates the output
in little chunks at a time. The concept is, perhaps, easy to
understand. But as your code base grows, the code will become harder
to understand and to modify.

Assuming you chose to use the pipes library, you then also need to
decide what size chunks you want to work with. You could write all
your code to work with one sample at a time. That is to say, you could
always yield/await example one sample. But for better performance you
might decide to use buffers and work with 32, 64, 512, etc samples at
a time. That can provide better performance. However, it could also
make it harder to deal with modulating parameters. For example, if you
are doing a filter sweep, you might only be able to change the cutoff
frequency at the beginning of each buffer. So the sweep would not be
as smooth as it would be if you yielded/await single samples. Though,
in practice, I think you are pretty unlikely to notice the difference
for reasonably sized buffer sizes.

- jeremy

On Fri, Apr 29, 2016 at 10:58 PM, Dennis Raddle <dennis.raddle at gmail.com> wrote:
> I'm writing a program that will use functions to generate audio. The Haskell
> code will write the audio samples to disk---no need for real time playback.
> I see some useful libraries for writing audio files.
>
> My question concerns efficiency when generating several million to 20
> million samples (or even many times more than that if I use high-resolution
> sampling rates). They can be generated one at a time in sequence, so there's
> no need to occupy a lot of memory or postpone thunk evaluation. I'm going to
> need efficient disk writing. Note that I may need some pseudorandom numbers
> in my calculations, so I might want to calculate samples by state monadic
> computations to carry the generator state. What is my general strategy going
> to be for memory and time efficiency? I am pretty confused by Haskell
> "strictness" and normal head form and all that, which often doesn't seem to
> be very strict. Or bang patterns, etc. Is it going to be simple to
> understand what I need?
>
> Dennis
>
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>


More information about the Beginners mailing list