Supex (supex v0.2.0)

View Source

Hex.pm API docs Hex Downloads Last Updated GitHub stars

Supex = SuperCollider + Elixir

An Elixir wrapper for the music live-coding language SuperCollider. Supex communicates with SuperCollider's sclang tool, letting you generate and control sound directly from Elixir.

  • 🎧 Play basic oscillators with a clean, pipeable syntax
  • 🔤 Send raw SuperCollider code when needed
  • ⛔ Stop sounds by name

Built for musicians, coders, and live performers who want to use Elixir for audio synthesis.

Installation

The package can be installed by adding supex to your list of dependencies in mix.exs:

def deps do
[
  {:supex, "~> 0.2.0"}
]
end

Note on v0.2.0

The library is now fully refactored with a clear structure and consistent naming. The sound naming issue in v0.1.0 has been fixed.

⚙ Requires sclang to be installed

Install with sudo apt install supercollider-language or sudo apt install supercollider on Ubuntu. For all platforms, see SuperCollider's installation guide.

🔍 Learn SuperCollider basics

https://doc.sccode.org/Tutorials/Getting-Started/00-Getting-Started-With-SC.html

🟢 Start the SuperCollider sclang server

iex> Supex.Sclang.start_link(:ok)

💡 Examples

▶ Play a sine oscillator at 269 Hz and name it "y", pan to center; then stop it:

iex> import Supex
iex> sin() |> freq(269) |> pan |> play("y")
iex> stop("y")

▶ Modulate volume of a sine wave using another sine as LFO:

iex> import Supex
iex> sin() |> mul(sin() |> freq(2) |> mul(0.4) |> add(0.5) |> lfo) |> pan |> play
iex> stop()

▶ Modulate a pulse wave's frequency and width:

iex> import Supex
iex> pulse() |> freq(saw() |> freq(0.1) |> mul(100) |> add(100) |> lfo) |> width(sin() |> freq(6) |> mul(0.5) |> add(0.5) |> lfo) |> pan |> play
iex> stop()

🔤 Send a raw SuperCollider expression:

iex> import Supex
iex> "RLPF.ar(Pulse.ar([100, 250], 0.5, 0.1), XLine.kr(8000, 400, 5), 0.05)" |> pan |> play
iex> stop()

or

iex> import Supex
iex> execute("play{LFCub.ar(LFSaw.kr(LFPulse.kr(1/4,1/4,1/4)*2+2,1,-20,50))+(WhiteNoise.ar(LFPulse.kr(4,0,LFPulse.kr(1,3/4)/4+0.05))/8)!2}")
iex> stop()

⚠️ Disclaimer

SuperCollider and Supex can produce loud, sudden sounds. Use volume control and a limiter to protect your ears. Avoid hearing damage.

🛠️ Note

Supex is in early development. Expect API changes.

Summary

Functions

Add the value to the signal.

Executes a raw SuperCollider command on the sclang server.

Tune the frequency of an oscillator.

Sets the output level.

Transforms a "normal" oscillator to a LFO to use it as a modulator.

Multiplication of the signal.

osc() deprecated

Create an oscillator.

osc(atom) deprecated

Pans the mono signal in the stereo spectrum.

The phase of a sinus wave.

Play the composed oscillator, or a raw SuperCollider's command (as a string).

Play the composed oscillator, or a raw SuperCollider's command (as a string), and naming it for referencing.

Pan position -1.0 = left, 0 = center, 1.0 = right

Create a pulse oscillator.

Create a saw oscillator.

Creates a sine oscillator.

Stop playing all SuperCollider sounds.

Stop playing a SuperCollider command by name.

stop_playing() deprecated

Stops all sound playing.

The pulse width of a pulse wave oscillator.

Functions

add(ugen, add)

(since 0.1.0)
@spec add(
  struct(),
  integer() | float() | binary() | struct()
) :: struct()

Add the value to the signal.

Values can be 0.1 or 1 for example.

examples

iex> import Supex
iex> pulse() |> add(0.3) |> pan |> play("y")
iex> stop("y")

execute(sc_command)

(since 0.1.0)
@spec execute(binary()) :: %Supex.Sclang{
  last_command_executed: term(),
  port: term(),
  sc_server_booted: term()
}

Executes a raw SuperCollider command on the sclang server.

Must be a string.

example

iex> import Supex
iex> execute("play{LFCub.ar(LFSaw.kr(LFPulse.kr(1/4,1/4,1/4)*2+2,1,-20,50))+(WhiteNoise.ar(LFPulse.kr(4,0,LFPulse.kr(1,3/4)/4+0.05))/8)!2}")
iex> stop()

freq(ugen, freq)

(since 0.1.0)
@spec freq(
  struct(),
  integer() | float() | binary() | struct()
) :: struct()

Tune the frequency of an oscillator.

examples

iex> import Supex
iex> pulse() |> freq(369) |> pan |> play("y")
iex> stop("y")

level(ugen, pos)

(since 0.2.0)
@spec level(
  struct(),
  integer() | float() | binary() | struct()
) :: struct()

Sets the output level.

example

iex> import Supex
iex> sin() |> freq(269) |> pan |> level(0.5) |> play

lfo(ugen)

(since 0.1.0)
@spec lfo(struct()) :: struct()

Transforms a "normal" oscillator to a LFO to use it as a modulator.

It uses kr (control rate) instead of ar(audio rate), cf. https://doc.sccode.org/Tutorials/Getting-Started/05-Functions-and-Sound.html

examples

Modulate the volume of a sine wave with another sine wave as an LFO:

iex> import Supex
iex> sin() |> mul(sin() |> freq(3) |> mul(0.5) |> add(0.5) |> lfo) |> pan |> play
iex> stop()

iex> import Supex
iex> pulse() |> mul(sin() |> freq(2) |> mul(0.4) |> add(0.5) |> lfo) |> freq(saw() |> freq(0.2) |> mul(100) |> add(100) |> lfo) |> pan |> play
iex> stop()

mul(ugen, mul)

(since 0.1.0)
@spec mul(
  struct(),
  integer() | float() | binary() | struct()
) :: struct()

Multiplication of the signal.

Choose values between 0.1 and 1 for not hurting your ears.

examples

iex> import Supex
iex> pulse() |> mul(0.2) |> pan |> play("y")
iex> stop("y")

osc()

(since 0.1.0)
This function is deprecated. Use Supex.sin/0 instead..
@spec osc() :: struct()

Create an oscillator.

type can be:

:sin (sinus wave) :saw (saw wave) :pulse (pulse wave, aka square wave)

Defaults to :sin.

osc(atom)

(since 0.1.0)
This function is deprecated. Use Supex.sin/0, Supex.saw/0, or Supex.pulse/0 instead.
@spec osc(atom()) :: struct()

pan(ugen)

(since 0.2.0)
@spec pan(struct()) :: %Supex.Ugen.Pan2{in: term(), level: term(), pos: term()}

Pans the mono signal in the stereo spectrum.

Defaults to centering the signal.

Use pos/2 for panning the position (-1.0 = left, 0 = center, 1.0 = right).

Use level/2 for scaling the output level.

example

iex> import Supex
iex> sin() |> freq(269) |> pan |> pos(0.69) |> play

phase(ugen, phase)

(since 0.1.0)
@spec phase(
  struct(),
  integer() | float() | binary() | struct()
) :: struct()

The phase of a sinus wave.

examples

iex> import Supex
iex> saw() |> freq(369) |> pan |> play("y")
iex> stop("y")

play(ugen)

(since 0.1.0)
@spec play(struct() | binary()) :: %Supex.Sclang{
  last_command_executed: term(),
  port: term(),
  sc_server_booted: term()
}

Play the composed oscillator, or a raw SuperCollider's command (as a string).

By default, the SuperCollider command will be referenced with the variable "x". For example, you can stop playing it with stop("x")

example

iex> import Supex
iex> sin() |> freq(269) |> play

play(ugen, name)

(since 0.2.0)
@spec play(struct() | binary(), binary()) :: %Supex.Sclang{
  last_command_executed: term(),
  port: term(),
  sc_server_booted: term()
}

Play the composed oscillator, or a raw SuperCollider's command (as a string), and naming it for referencing.

The SuperCollider command will be referenced with the given name. You can stop it using stop/1.

While SuperCollider only accepts single characters as global variables (e.g., "x", "y", "z"), longer names can be used as environment variables and will be declared accordingly.

examples

iex> import Supex
iex> sin() |> freq(269) |> pan |> play("y")
iex> stop("y")

iex> import Supex
iex> pulse() |> freq(269) |> pan |> play("sound")
iex> stop("sound")

pos(ugen, pos)

(since 0.2.0)
@spec pos(
  struct(),
  integer() | float() | binary() | struct()
) :: struct()

Pan position -1.0 = left, 0 = center, 1.0 = right

example

Pan a sound slightly to the right:

iex> import Supex
iex> sin() |> freq(269) |> pan |> pos(0.69) |> play

pulse()

(since 0.2.0)
@spec pulse() :: %Supex.Ugen.Pulse{
  add: term(),
  freq: term(),
  lfo: term(),
  mul: term(),
  width: term()
}

Create a pulse oscillator.

Uses the SuperCollider Pulse wave generator, see https://doc.sccode.org/Classes/Pulse.html

freq frequency in Hertz,

width pulse width ratio from zero to one (0.5 makes a square wave)

mul output will be multiplied by this value,

add this value will be added to the output.

For setting these values use freq/2, width/2, mul/2, add/2, and lfo/1.

examples

iex> import Supex
iex> pulse() |> pan |> play
iex> stop("x")

iex> import Supex
iex> pulse() |> freq(369) |> width(0.6) |> mul(0.2) |> add(0.3) |> pan |> play("y")
iex> stop("y")

saw()

(since 0.2.0)
@spec saw() :: %Supex.Ugen.Saw{add: term(), freq: term(), lfo: term(), mul: term()}

Create a saw oscillator.

Uses the SuperCollider Saw wave generator, see https://doc.sccode.org/Classes/Saw.html

freq frequency in Hertz,

mul output will be multiplied by this value,

add this value will be added to the output.

For setting these values use freq/2, mul/2, add/2, and lfo/1.

example

iex> import Supex
iex> saw() |> pan |> play
iex> stop("x")

iex> import Supex
iex> saw() |> freq(369) |> mul(0.2) |> add(0.3) |> pan |> play("y")
iex> stop("y")

sin()

(since 0.2.0)
@spec sin() :: %Supex.Ugen.SinOsc{
  add: term(),
  freq: term(),
  lfo: term(),
  mul: term(),
  phase: term()
}

Creates a sine oscillator.

Uses the SuperCollider SinOsc sine wave generator, see https://doc.sccode.org/Classes/SinOsc.html

freq frequency in Hertz,

phase phase in radians (should be within the range +-8pi),

mul output will be multiplied by this value,

add this value will be added to the output.

For setting these values use freq/2, phase/2, mul/2, add/2, and lfo/1.

examples

iex> import Supex
iex> sin() |> pan |> play
iex> stop("x")

iex> import Supex
iex> sin() |> freq(369) |> phase(0.1) |> mul(0.2) |> add(0.3) |> pan |> play("y")
iex> stop("y")

stop()

(since 0.2.0)
@spec stop() :: %Supex.Sclang{
  last_command_executed: term(),
  port: term(),
  sc_server_booted: term()
}

Stop playing all SuperCollider sounds.

Use stop/1 to stop sound named with play/2.

example

iex> import Supex
iex> sin() |> pan |> play()
iex> pulse() |> pan |> play()
iex> stop()

stop(name)

(since 0.1.0)
@spec stop(binary()) :: %Supex.Sclang{
  last_command_executed: term(),
  port: term(),
  sc_server_booted: term()
}

Stop playing a SuperCollider command by name.

play/1 defaults to "x".

Use play/2 to set a name.

example

iex> import Supex
iex> sin() |> pan |> play()
iex> stop("x")

iex> import Supex
iex> sin() |> pan |> play("y")
iex> stop("y")

stop_playing()

(since 0.1.0)
This function is deprecated. Use Supex.stop/0 instead.
@spec stop_playing() :: %Supex.Sclang{
  last_command_executed: term(),
  port: term(),
  sc_server_booted: term()
}

Stops all sound playing.

width(ugen, width)

(since 0.1.0)
@spec width(
  struct(),
  integer() | float() | binary() | struct()
) :: struct()

The pulse width of a pulse wave oscillator.

width should be a value between 0.01 and 0.99.

examples

iex> import Supex
iex> pulse() |> width(0.6) |> pan |> play("y")
iex> stop("y")