This page is a crash course for purescript-wags
, the web audio library that powers wags.fm
and wagsi
.
Let's start with a single hi-hat.
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal (make, s)
wag :: AFuture
wag = make 0.8 { earth: s "hh:0" }
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal (make, s)
wag :: AFuture
wag = make 0.8 { earth: s "hh:0" }
main :: Player
main = player (tdl wag)
To listen to this and all other examples, click or press the Play button below the player.
Wags is written in PureScript, but you don't need to know PureScript in order to use wags. In the example above, change hh:0
to bd:0
(bass drum), stop it, and start it again. Change it to realclaps:0
(clap), stop it, and start it again. You can change to any of the sounds from the Amazing SuperDirt Sample Library. Much of the Wags syntax is heavily inspired by Tidal Cycles, so if you know Tidal, you should feel at home.
If you're coming from wags.fm, you can copy this and all other examples into the blank slate track and they will work out of the box.
When you add more samples like bd:0
or hh:0
to the string, they are played in series. The example below has four different samples. Try adding and removing some to see what happens.
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (make, s)
import WAGS.Lib.Tidal.Types (AFuture)
wag :: AFuture
wag = make 0.8 { earth: s "bd:0 notes:5 hh:0 chin:0" }
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (make, s)
import WAGS.Lib.Tidal.Types (AFuture)
wag :: AFuture
wag = make 0.8 { earth: s "bd:0 notes:5 hh:0 chin:0" }
main :: Player
main = player (tdl wag)
Let's make our loop faster. The example below is the same as the one above but plays at twice the speed. This is because the first value passed to make
is 0.4
, or half of the value used above.
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal (make, s)
wag :: AFuture
wag = make 0.4 { earth: s "bd:0 notes:5 hh:0 chin:0" }
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal (make, s)
wag :: AFuture
wag = make 0.4 { earth: s "bd:0 notes:5 hh:0 chin:0" }
main :: Player
main = player (tdl wag)
Silence is golden! Use a tidla (~
) to add silence in place of a note.
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (make, s)
import WAGS.Lib.Tidal.Types (AFuture)
wag :: AFuture
wag = make 0.8 { earth: s "bd:0 notes:5 ~ chin:0" }
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (make, s)
import WAGS.Lib.Tidal.Types (AFuture)
wag :: AFuture
wag = make 0.8 { earth: s "bd:0 notes:5 ~ chin:0" }
main :: Player
main = player (tdl wag)
Sometimes, you want two samples to play at the same time. You can do this by putting square brackets ([
and ]
) around them and separating them with a comma. More than two samples? No problem, just add more commas.
In the example below, we use three quotation marks to open and close a multiline string.
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (make, s)
import WAGS.Lib.Tidal.Types (AFuture)
wag :: AFuture
wag = make 0.8
{ earth: s
"""
[bd:0,notes:7] [notes:5,notes:12,notes:0]
[hh:0,insect:0] [chin:0,notes:4]
"""
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (make, s)
import WAGS.Lib.Tidal.Types (AFuture)
wag :: AFuture
wag = make 0.8
{ earth: s
"""
[bd:0,notes:7] [notes:5,notes:12,notes:0]
[hh:0,insect:0] [chin:0,notes:4]
"""
}
main :: Player
main = player (tdl wag)
To create internal subdivisions like 16th-notes (aka semiquavers), use square brackets ([
and ]
) without a comma. You can also use an asterisk (*
) to create subdivisions of a single sample.
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (make, s)
import WAGS.Lib.Tidal.Types (AFuture)
wag :: AFuture
wag = make 0.8
{ earth: s
"""
bd:0 [notes:5 notes:10]
hh:0 chin:0*3
"""
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (make, s)
import WAGS.Lib.Tidal.Types (AFuture)
wag :: AFuture
wag = make 0.8
{ earth: s
"""
bd:0 [notes:5 notes:10]
hh:0 chin:0*3
"""
}
main :: Player
main = player (tdl wag)
You can combine subdivisions and simultaneous samples to create polyrhythms. Let's listen to 3 on 4.
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal (make, s)
wag :: AFuture
wag = make 0.8
{ earth: s
"""
[notes:4 notes:5 notes:8 notes:12],
hh:0*3
"""
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal (make, s)
wag :: AFuture
wag = make 0.8
{ earth: s
"""
[notes:4 notes:5 notes:8 notes:12],
hh:0*3
"""
}
main :: Player
main = player (tdl wag)
Hearing the same loop over and over again is boring. Spice it up with branching. Each time the cycle loops, a different branch will be chosen.
Branches multiply, so something that branches two times, then three times, and then four times will be 2 × 3 × 4 = 24 cycles long!
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal (make, s)
wag :: AFuture
wag = make 0.8
{ earth: s
"""
<bd:0 tabla:5> [notes:5 <notes:10 notes:14>]
<hh:0 hh:2> chin:0*3
"""
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal (make, s)
wag :: AFuture
wag = make 0.8
{ earth: s
"""
<bd:0 tabla:5> [notes:5 <notes:10 notes:14>]
<hh:0 hh:2> chin:0*3
"""
}
main :: Player
main = player (tdl wag)
Up until now, we've only used one voice called earth
. Let's add a new voice called wind
. The three possible voices are earth
, wind
, and fire
. Different voices are helpful when you're doing a wagsi
jam session, as different DJs can work on different areas of a single document. They're also useful if you want to add effects (we'll add effects later).
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (make, s)
import WAGS.Lib.Tidal.Types (AFuture)
wag :: AFuture
wag = make 0.8
{ earth: s "pluck:3 pluck:5 pluck:10 pluck:12 pluck:16"
, wind: s "[bd,hh] hh [clap,hh] hh"
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (make, s)
import WAGS.Lib.Tidal.Types (AFuture)
wag :: AFuture
wag = make 0.8
{ earth: s "pluck:3 pluck:5 pluck:10 pluck:12 pluck:16"
, wind: s "[bd,hh] hh [clap,hh] hh"
}
main :: Player
main = player (tdl wag)
To add a drone, you can use the air
or heart
voice followed by the drone
function with the sample you wish to use. The sample will loop.
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal (drone, make, s)
wag :: AFuture
wag = make 5.0
{ earth: s "birds:0 birds:4"
, air: drone "padlong:0"
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal (drone, make, s)
wag :: AFuture
wag = make 5.0
{ earth: s "birds:0 birds:4"
, air: drone "padlong:0"
}
main :: Player
main = player (tdl wag)
You can add new samples by providing an object to the sounds
field of the top-level record. sounds
takes an object of BufferUrl
-s, and we can construct it using standard PureScript functions like /\
, <<<
and fromFoldable
.
module Main where
import Prelude
import Data.Tuple.Nested ((/\))
import Foreign.Object (fromFoldable)
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (make, s)
import WAGS.Lib.Tidal.Types (AFuture, BufferUrl(..))
wag :: AFuture
wag = make 4.0
{ earth: s "lowhit highhit"
, sounds: fromFoldable $
(map <<< map)
( BufferUrl
<<< append "https://media.graphcms.com/"
)
[ "lowhit" /\ "I54aFAuRoq05CHlcK4aj"
, "highhit" /\ "1fLcZIK9Twq8scW2Pv2G"
]
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import Data.Tuple.Nested ((/\))
import Foreign.Object (fromFoldable)
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (make, s)
import WAGS.Lib.Tidal.Types (AFuture, BufferUrl(..))
wag :: AFuture
wag = make 4.0
{ earth: s "lowhit highhit"
, sounds: fromFoldable $
(map <<< map)
( BufferUrl
<<< append "https://media.graphcms.com/"
)
[ "lowhit" /\ "I54aFAuRoq05CHlcK4aj"
, "highhit" /\ "1fLcZIK9Twq8scW2Pv2G"
]
}
main :: Player
main = player (tdl wag)
You can give any note a tag using a semi-colon (;
). Then, use the onTag
function to grab the note and changeVolume
to change the volume. A couple additional things to note:
const
is a PureScript function that returns constant values.parse_
must be used to end a chain of one or more onTag
.module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (changeVolume, make, onTag, parse, s)
import WAGS.Lib.Tidal.Types (AFuture)
wag :: AFuture
wag = make 0.8
{ earth: s
$ onTag "d0" (changeVolume $ const 0.3)
$ onTag "d1" (changeVolume $ const 0.1)
$ parse "bd:0 bd:0;d0 bd:0;d1"
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Tidal (changeVolume, make, onTag, parse, s)
import WAGS.Lib.Tidal.Types (AFuture)
wag :: AFuture
wag = make 0.8
{ earth: s
$ onTag "d0" (changeVolume $ const 0.3)
$ onTag "d1" (changeVolume $ const 0.1)
$ parse "bd:0 bd:0;d0 bd:0;d1"
}
main :: Player
main = player (tdl wag)
You can use changeRate
to change the rate of a note.
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal (changeRate, make, onTag, parse, s)
wag :: AFuture
wag = make 0.8
{ earth: s
$ onTag "d0" (changeRate $ const 1.5)
$ onTag "d1" (changeRate $ const 0.6)
$ parse "bd:0 bd:0;d0 bd:0;d1"
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal (changeRate, make, onTag, parse, s)
wag :: AFuture
wag = make 0.8
{ earth: s
$ onTag "d0" (changeRate $ const 1.5)
$ onTag "d1" (changeRate $ const 0.6)
$ parse "bd:0 bd:0;d0 bd:0;d1"
}
main :: Player
main = player (tdl wag)
It's often useful to work with functions of time. You can modify both rate and volume as a function of time. There are many different representations of time, so choose wisely! The example below uses:
clockTime
to change the volumesampleTime
to change the rateIt also uses a Low Frequency Oscillator (lfo
). Lastly, it uses the >>>
operator to pipe values from left-to-right. Because we're making heavy use of the WAGS.Lib.Tidal.Tidal
module, we'll use a qualified import and rename it T
.
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Learn.Oscillator (lfo)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal as T
wag :: AFuture
wag = T.make 4.0
{ earth: T.s
$ T.onTag "pad"
( T.changeRate
( _.sampleTime
>>> mul 1.3
>>> add 1.0
>>> min 1.2
)
)
$ map
( T.changeVolume
( _.clockTime
>>> lfo
{ phase: 0.0
, freq: 4.0
, amp: 0.4
}
>>> add 0.4
)
)
$ T.parse "pad:2 pad:2;pad"
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Learn.Oscillator (lfo)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.Tidal as T
wag :: AFuture
wag = T.make 4.0
{ earth: T.s
$ T.onTag "pad"
( T.changeRate
( _.sampleTime
>>> mul 1.3
>>> add 1.0
>>> min 1.2
)
)
$ map
( T.changeVolume
( _.clockTime
>>> lfo
{ phase: 0.0
, freq: 4.0
, amp: 0.4
}
>>> add 0.4
)
)
$ T.parse "pad:2 pad:2;pad"
}
main :: Player
main = player (tdl wag)
Other types of time you can use include:
littleCycleTime
: the time since the branch of a cycle started. For example, if you have a cycle that lasts 4 seconds with 5 branches and you just started branch 3, the value will be 0.0
.bigCycleTime
: the time since the last cycle started. For example, if you have a cycle that lasts 4 seconds with 5 branches and you just started branch 3, the value will be 12.0
.You can add aribtrary effects chains to voices. Effect chains must end with an output called goodbye
and optionally use an input called hello
. Discarding the input is useful if you want to create purely synthetic effects.
Let's add a high-pass filter to create a sweeping effect. The function ff
here creates a small control-rate delay that smooths over the rapid changes in the filter's frequency, which could cause clicks or pops on some devices.
module Main where
import Prelude
import WAGS.Create.Optionals (highpass)
import WAGS.Graph.Parameter (ff)
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Learn.Oscillator (lfo)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.FX (fx, goodbye, hello)
import WAGS.Lib.Tidal.Tidal (addEffect, make, s)
wag :: AFuture
wag = make 4.0
{ earth:
map
( addEffect
( fx
<<< goodbye
<<< flip highpass hello
<<< ff 0.1
<<< pure
<<< lfo
{ phase: 0.0
, amp: 2500.0
, freq: 2.0
}
<<< add 2750.0
<<< _.clockTime
)
) $ s "pad:1"
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Create.Optionals (highpass)
import WAGS.Graph.Parameter (ff)
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Learn.Oscillator (lfo)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.FX (fx, goodbye, hello)
import WAGS.Lib.Tidal.Tidal (addEffect, make, s)
wag :: AFuture
wag = make 4.0
{ earth:
map
( addEffect
( fx
<<< goodbye
<<< flip highpass hello
<<< ff 0.1
<<< pure
<<< lfo
{ phase: 0.0
, amp: 2500.0
, freq: 2.0
}
<<< add 2750.0
<<< _.clockTime
)
) $ s "pad:1"
}
main :: Player
main = player (tdl wag)
Let's now try a pan.
module Main where
import Prelude
import WAGS.Create.Optionals (pan)
import WAGS.Graph.Parameter (ff)
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Learn.Oscillator (lfo)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.FX (fx, goodbye, hello)
import WAGS.Lib.Tidal.Tidal (addEffect, make, s)
wag :: AFuture
wag = make 4.0
{ earth:
map
( addEffect
( fx
<<< goodbye
<<< flip pan hello
<<< ff 0.1
<<< pure
<<< lfo
{ phase: 0.0
, amp: 1.0
, freq: 1.0
}
<<< _.clockTime
)
) $ s "pad:1"
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Create.Optionals (pan)
import WAGS.Graph.Parameter (ff)
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Learn.Oscillator (lfo)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.FX (fx, goodbye, hello)
import WAGS.Lib.Tidal.Tidal (addEffect, make, s)
wag :: AFuture
wag = make 4.0
{ earth:
map
( addEffect
( fx
<<< goodbye
<<< flip pan hello
<<< ff 0.1
<<< pure
<<< lfo
{ phase: 0.0
, amp: 1.0
, freq: 1.0
}
<<< _.clockTime
)
) $ s "pad:1"
}
main :: Player
main = player (tdl wag)
Let's add a few sine-wave oscillators.
module Main where
import Prelude
import WAGS.Create.Optionals (gain, sinOsc)
import WAGS.Graph.Parameter (AudioParameter, ff)
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Learn.Oscillator (lfo)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.FX (fx, goodbye, hello)
import WAGS.Lib.Tidal.Tidal (addEffect, make, s)
import WAGS.Lib.Tidal.Types (AFuture)
myLFO
:: Number
-> Number
-> Number
-> Number
-> Number
-> AudioParameter
myLFO phase freq amp clockTime offset =
ff 0.1 $ pure $
lfo
{ phase
, freq
, amp: amp * 0.5
}
clockTime + (offset * 0.5)
wag :: AFuture
wag = make 4.0
{ earth:
map
( addEffect
( \{ clockTime: ct } -> fx
$ goodbye
$ gain 1.0
{ wave0: gain
(myLFO 0.0 2.0 0.3 ct 0.4)
(sinOsc 220.0)
, wave1: gain
(myLFO 0.1 4.0 0.1 ct 0.15)
(sinOsc 440.0)
, wave2: gain
(myLFO 2.0 6.0 0.25 ct 0.3)
(sinOsc 660.0)
, wave3: gain
(myLFO 2.0 2.0 0.05 ct 0.12)
(sinOsc 880.0)
, wave4: gain
(myLFO 0.0 16.0 0.03 ct 0.09)
(sinOsc 1100.0)
, original: hello
}
)
) $ s "bd"
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Create.Optionals (gain, sinOsc)
import WAGS.Graph.Parameter (AudioParameter, ff)
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Learn.Oscillator (lfo)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.FX (fx, goodbye, hello)
import WAGS.Lib.Tidal.Tidal (addEffect, make, s)
import WAGS.Lib.Tidal.Types (AFuture)
myLFO
:: Number
-> Number
-> Number
-> Number
-> Number
-> AudioParameter
myLFO phase freq amp clockTime offset =
ff 0.1 $ pure $
lfo
{ phase
, freq
, amp: amp * 0.5
}
clockTime + (offset * 0.5)
wag :: AFuture
wag = make 4.0
{ earth:
map
( addEffect
( \{ clockTime: ct } -> fx
$ goodbye
$ gain 1.0
{ wave0: gain
(myLFO 0.0 2.0 0.3 ct 0.4)
(sinOsc 220.0)
, wave1: gain
(myLFO 0.1 4.0 0.1 ct 0.15)
(sinOsc 440.0)
, wave2: gain
(myLFO 2.0 6.0 0.25 ct 0.3)
(sinOsc 660.0)
, wave3: gain
(myLFO 2.0 2.0 0.05 ct 0.12)
(sinOsc 880.0)
, wave4: gain
(myLFO 0.0 16.0 0.03 ct 0.09)
(sinOsc 1100.0)
, original: hello
}
)
) $ s "bd"
}
main :: Player
main = player (tdl wag)
To create a feedback loop, use the delay
effect as well as ref
, which is a reference to another node in the graph. In this case, ref
refers to mymix
, which is the gain node that we created elsewhere in the graph.
module Main where
import Prelude
import WAGS.Create.Optionals (delay, gain, highpass, ref)
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.FX (fx, goodbye, hello)
import WAGS.Lib.Tidal.Tidal (addEffect, make, s)
wag :: AFuture
wag = make 1.0
{ earth:
map
( addEffect
( const $
fx
( goodbye $ gain 1.0
{ mymix: gain 1.0
{ ipt: highpass 2000.0 hello
, fback: gain 0.8
{ del:
delay 0.1 { mymix: ref }
}
}
}
)
)
)
$ s "bd"
}
main :: Player
main = player (tdl wag)
module Main where
import Prelude
import WAGS.Create.Optionals (delay, gain, highpass, ref)
import WAGS.Lib.Learn (Player, player)
import WAGS.Lib.Tidal (tdl)
import WAGS.Lib.Tidal.Types (AFuture)
import WAGS.Lib.Tidal.FX (fx, goodbye, hello)
import WAGS.Lib.Tidal.Tidal (addEffect, make, s)
wag :: AFuture
wag = make 1.0
{ earth:
map
( addEffect
( const $
fx
( goodbye $ gain 1.0
{ mymix: gain 1.0
{ ipt: highpass 2000.0 hello
, fback: gain 0.8
{ del:
delay 0.1 { mymix: ref }
}
}
}
)
)
)
$ s "bd"
}
main :: Player
main = player (tdl wag)
Almost all of the effects from the WebAudio API are reproducible using this method. For example, to use an allpass filter instead of a highpass, import allpass
instead of highpass
. All importable functions can be found in this module.
wags
is heavily indebted to the Tidal Cycles project, which inspired its mini-notation. It also makes heavy use of:
You could:
#music
channel of the PureScript Discord server.purescript-wags-lib
for more advanced use cases, including using TensorFlow.js to create markov models (code here) and controlling the music with a mouse (code here).I wish you lots of satisfaction as you play with Wags to create music, noise, or whatever makes your ears perk up. Happy wagging!