Making some noise with elixir
Getting Started
To produce sound waves with elixir - and be able to listen to them - we're going to use the library synthex alongside with Sound eXchange, or sox.
First, let's be sure we have sox installed and it's configured in your PATH:
For mac, just run the following homebrew command and you're good to go.
brew install sox
For Windows, the easiest option is install it using chocolatey.
If you're a Debian/Ubuntu user, you can run:
sudo apt-get install sox libsox-fmt-all
For more 'sox' references, check out their official page
Elixir
Let's create a simple module:
mix new noisemaker
Let's also add the synthex lib as dependency in mix.exs:
# file: mix.exs
defp deps do
[{:synthex, "~> 0.0.1"}]
end
Remember to run
mix deps.getafter adding the library.
Synthex: A signal synthesis library for elixir
This is a very simple library, but can be used to do some great audio synthesis. It also comes with a few examples that can we can use to validate our environment. The following script is the simplest example provided: a sine wave with a fixed frequency (A4 in this case: 440 Hz ).
defmodule Sine do
alias Synthex.Context
alias Synthex.Output.SoxPlayer
alias Synthex.Generator.Oscillator
@rate 44100
def run(duration, frequency) do
{:ok, writer} = SoxPlayer.open(rate: @rate, channels: 2)
context =
%Context{output: writer, rate: @rate}
|> Context.put_element(:main, :osc1, %Oscillator{algorithm: :sine, frequency: frequency})
Synthex.synthesize(context, duration, fn (ctx) ->
Context.get_sample(ctx, :main, :osc1)
end)
SoxPlayer.close(writer)
end
end
Sine.run(5, 440)
You can obviously copy and paste this code inside the file noisemaker/lib/noisemaker.ex and then run mix run to be able to listen the first noise we made with elxir. Remember to lower the volume down.
Changing a bit
Ok. This is the sound of a sinewave of 440 Hz. Let's try to produce this same note using square waves. To achieve this with synthex, just change the algorithm used by the Oscillator:
context =
%Context{output: writer, rate: @rate}
|> Context.put_element(:main, :osc1, %Oscillator{algorithm: :pulse, frequency: frequency})
Before running this, be sure to decrease the volume from your computer.
The sound produced by a square wave with the frequency of 440 Hz is a bit disturbing, isn't it? Besides, why does the volume seem to be higher?
Well, square waves have more then the base frequency inside it. Unlike a sinewave, a square wave needs higher frequencies to sharpen the rising and falling edges, besides it's fundamental frequency (of 440 hz). Theoretically, they have have infinite bandwidth.
That's why they sound different, because they really should, as square waves uses more higher harmonics.
The volume of a square wave is also higher, but we din't change the amplitude of the signal. Well, a square wave is this library has it's amplitude fixed in 1, which is the maximum value of a pure sinewave.
Cool stuff. Let's make some sound with Synthex and Elixir then.
Talk soon,
Victor FulgĂȘncio.
