[erlang-questions] Generating sine waves and/or audio stream output

205 views
Skip to first unread message

Ivan Uemlianin

unread,
Mar 24, 2010, 6:28:22 AM3/24/10
to erlang-q...@erlang.org
Dear All

I am learning Erlang and one of the things I'm interested in is
generating sine waves, merging them and streaming them to audio output.

I can kind of imagine how generating and merging would work, with a sine
wave represented as a list of numbers. Is there an Erlang library or
project working with sine waves?

I can't imagine how to stream a list of numbers to audio output. Can
anyone point me to projects/libraries/ideas for that one? Writing the
data to a file would be OK for now, but "live" sound would be much nicer.

With thanks and best wishes

Ivan

--
============================================================
Ivan A. Uemlianin
Speech Technology Research and Development

iv...@llaisdy.com
www.llaisdy.com
llaisdy.wordpress.com
www.linkedin.com/in/ivanuemlianin

"Froh, froh! Wie seine Sonnen, seine Sonnen fliegen"
(Schiller, Beethoven)
============================================================

________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questio...@erlang.org

Willem de Jong

unread,
Mar 24, 2010, 2:34:34 PM3/24/10
to Ivan Uemlianin, Erlang Questions
Hello Ivan,

I have an erlang module that generates sounds. It can generate different wave forms (right now all I need is a saw-like shape and a sinus shape). I am attaching it. It is a bit messy, perhaps, but it should give you an impression of how it can be done.

The synthesize() function uses the sinus() function to create a number of complete waves, and then pastes  these together repeatedly (I assumed that would be more efficient that calculating the sinus() function for each sample).

The syntesize() function returns a couple of sound fragments: an "attaque" bit that starts with an amplitude of zero, a fade-out bit where the volume decreases back to 0, and a long and a short bit of sound with a stable volume. Another module creates a complete sound-fragment of the desired duration by pasting together the attaque, a number of long fragments and short fragments in such a way that it matches the duration (as precisely as possible), and a fade out bit.

As you can see this creates sounds with a fixed pitch and volume (within one sound, that is). Also note that both the length and the pitch of the sound will be approximations.

I created this to generate music for my web-site: http://coria.nl.  You can try the result there, if you want. It is a site that enables me and the other members of my choir (and anyone else who is interested) to practise our music. 

Any comments or suggestions will be quite welcome, 
Good luck,
Willem 
sound.hrl
sound.erl

Ivan Uemlianin

unread,
Mar 25, 2010, 4:51:15 AM3/25/10
to Erlang Questions
Dear Willem

Thanks very much for you email and your code. This looks good.

The functions generate binaries. Do you stream the binaries to audio or
do you write them to a file?

Do you have a function that writes wav files? If not I shall write one
(unless a function to stream to audio will be easier but I don't think
it will be).

Thanks and best wishes

Ivan

> iv...@llaisdy.com <mailto:iv...@llaisdy.com>
> www.llaisdy.com <http://www.llaisdy.com>
> llaisdy.wordpress.com
> <http://llaisdy.wordpress.com>
> www.linkedin.com/in/ivanuemlianin
> <http://www.linkedin.com/in/ivanuemlianin>


>
> "Froh, froh! Wie seine Sonnen, seine Sonnen fliegen"
> (Schiller, Beethoven)
> ============================================================
>
>
>
> ________________________________________________________________

> erlang-questions (at) erlang.org <http://erlang.org> mailing list.

> <mailto:erlang-questio...@erlang.org>

G.S.

unread,
Mar 25, 2010, 5:05:50 AM3/25/10
to Ivan Uemlianin, Erlang Questions
Hello Willem,

Could you also please send me the code if possible? as I am also highly
interested in using Erlang for sound generation.

Regards and thanks,
-Gene

Willem de Jong

unread,
Mar 25, 2010, 3:04:39 PM3/25/10
to Ivan Uemlianin, Erlang Questions
Hmm, I had forgotten about some of the complexities involved. 

I do not have a function that writes wav files. I put the pcm data that is generated by this into a flash file. For wav files you have to do add a header and framing, I believe. 

I added a function that puts together the parts of the sound. You can write it to a file like this:
> file:write_file("sinus.raw", sound:sound(440, 3, 0.5, sinus)).

(440 hertz, 3 seconds, volume 0.5 (50%), sinus wave form).

This file will be in "raw" format (pcm without headers). With the current settings the sample rate is 22050, mono, sample size 16 bits big endian.

Regards,
Willem
sound.erl

Ivan Uemlianin

unread,
Mar 26, 2010, 5:35:21 AM3/26/10
to Willem de Jong, Erlang Questions
You've done all the hard work!

Thanks Willem. I'll write a function to write a wav header and report
back: I've got one I wrote in C somewhere; might be interesting to
compare the two.

I'll also look into streaming to audio (there is esdl, an erlang binding
for sdl, but that looks a bit hefty, and doesn'ty work with smp enabled
erlang).

Best

Ivan

On 25/03/2010 19:04, Willem de Jong wrote:
> Hmm, I had forgotten about some of the complexities involved.
>
> I do not have a function that writes wav files. I put the pcm data
> that is generated by this into a flash file. For wav files you have to
> do add a header and framing, I believe.
>
> I added a function that puts together the parts of the sound. You can
> write it to a file like this:
> > file:write_file("sinus.raw", sound:sound(440, 3, 0.5, sinus)).
>
> (440 hertz, 3 seconds, volume 0.5 (50%), sinus wave form).
>
> This file will be in "raw" format (pcm without headers). With the
> current settings the sample rate is 22050, mono, sample size 16 bits
> big endian.
>
> Regards,
> Willem

--

Ivan Uemlianin

unread,
Apr 2, 2010, 12:08:11 PM4/2/10
to Willem de Jong, Erlang Questions
Dear Willem

This hacky little script (my first in erlang!) will write a sound and
pipe it to audio.

play(Sound) ->
Fn = sinus,
file:write_file(io_lib:format("~p.raw", [Fn]), Sound),
os:cmd(io_lib:format("sox -r ~B -c 1 -w -s ~p.raw ~p.wav",
[?SamplingRate, Fn, Fn])),
os:cmd(io_lib:format("afplay ~p.wav", [Fn])).

sox is a unix tool, here it converts the raw audio file to wav format
file. On a proper unix platform sox can output to audio. On MacOSX you
have to write to a file and use afplay to play the file.

This is not a very nice function. I shall write a function to convert a
raw sound into a wav format binary. It would be v nice to habe
something like an erlang binding for PortAudio. In the meantime, the
function above makes it possible to listen to generated sounds fmor the
erlang shell.

With thanks and apologies

Ivan


On 25/03/2010 19:04, Willem de Jong wrote:

> Hmm, I had forgotten about some of the complexities involved.
>
> I do not have a function that writes wav files. I put the pcm data
> that is generated by this into a flash file. For wav files you have to
> do add a header and framing, I believe.
>
> I added a function that puts together the parts of the sound. You can
> write it to a file like this:
> > file:write_file("sinus.raw", sound:sound(440, 3, 0.5, sinus)).
>
> (440 hertz, 3 seconds, volume 0.5 (50%), sinus wave form).
>
> This file will be in "raw" format (pcm without headers). With the
> current settings the sample rate is 22050, mono, sample size 16 bits
> big endian.
>
> Regards,
> Willem

--

Reply all
Reply to author
Forward
0 new messages