A Crash Course on Wags

This page is a crash course for purescript-wags, the web audio library that powers wags.fm and wagsi.

A single hi-hat

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.

More samples

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)

Faster loops

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

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)

Simultaneous samples

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)

Subdivisions

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)

Polyrhythms

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)

Branching cycles

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)

Voices

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)

Drones

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)

Working with new samples

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)

Changing the volume of a note

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:

  1. const is a PureScript function that returns constant values.
  2. 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)

Changing the rate (pitch) of a note

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)

Working with functions of time

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 volume
  • sampleTime to change the rate

It 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.

Adding effects

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.

High-pass filter

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)

Pan

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)

Synthetic sounds

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)

Delays and feedback

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)

Other effects

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.

Inspiration

wags is heavily indebted to the Tidal Cycles project, which inspired its mini-notation. It also makes heavy use of:

What next?

You could:

I wish you lots of satisfaction as you play with Wags to create music, noise, or whatever makes your ears perk up. Happy wagging!